package kkmarkdown

  1. Overview
  2. Docs

Source file BlockRuleCode.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
module Make (M : sig
  val is_safe : bool
  val c : char
end) =
struct
  let is_safe = M.is_safe
  let first_char = FirstChar.One M.c
  let force_construct = true

  type state = { len : int; classes : string list }

  let prefix = Format.sprintf "\\(%c%c%c+\\)" M.c M.c M.c
  let classes = "[ \t]*{\\(.*\\)}"
  let postfix = "[ \t]*$"
  let re_with_classes = Str.regexp (prefix ^ classes ^ postfix)
  let re_without_classes = Str.regexp (prefix ^ postfix)

  let start line : state BlockRule.res =
    let re = if is_safe then re_without_classes else re_with_classes in
    if Str.string_match re line 0 then
      let len = String.length (Str.matched_group 1 line) in
      let classes =
        if is_safe then [] else Str.matched_group 2 line |> Utils.read_classes
      in
      Go { state = { len; classes }; handle_line = `Discard }
    else Die

  let continue ({ len; classes } as state) line : state BlockRule.res =
    if Str.string_match re_without_classes line 0 then
      if len = String.length (Str.matched_group 1 line) then
        Stop { state; handle_line = `Discard }
      else Go { state; handle_line = `Keep }
    else Go { state; handle_line = `Keep }

  let construct _ { classes } lines =
    if is_safe then Typ.CodeBlock lines
    else Typ.UnsafeCodeBlock { cb = lines; classes }
end

module Backquote = Make (struct
  let is_safe = true
  let c = '`'
end)

module Tilde = Make (struct
  let is_safe = true
  let c = '~'
end)

module UnsafeBackquote = Make (struct
  let is_safe = false
  let c = '`'
end)

module UnsafeTilde = Make (struct
  let is_safe = false
  let c = '~'
end)

module Indent = struct
  let is_safe = true
  let first_char = FirstChar.OneOf [ ' '; '\t' ]
  let force_construct = true

  type state = unit

  let re = Str.regexp "    \\|\t"

  let start line : state BlockRule.res =
    if Str.string_match re line 0 then Go { state = (); handle_line = `Keep }
    else Die

  let continue () line : state BlockRule.res =
    if Str.string_match re line 0 then Go { state = (); handle_line = `Keep }
    else Stop { state = (); handle_line = `Left }

  let remove_indent line =
    match line.[0] with
    | ' ' -> Str.string_after line 4
    | '\t' -> Str.string_after line 1
    | _ -> assert false

  let construct _ () lines = Typ.CodeBlock (List.map remove_indent lines)
end
OCaml

Innovation. Community. Security.