[OCaml] Mobile-friendly clone of cgit.
refactor extract shared list-item classifiers into prose_format
Move unordered_item, ordered_item, and is_boundary_common from prose_markdown.ml and prose_org.ml into prose_format.ml. Both format parsers now delegate to the shared implementations. The Org parser extends is_boundary_common with its definition_item check.
lib/prose/prose_format.ml
@@ -67,6 +67,47 @@
67
67
| line :: rest when close line -> (List.rev collected, rest)
68
68
| line :: rest -> take_until close (line :: collected) rest
69
69
70
Added:
(* {1 Shared list-item classifiers} *)
71
Added:
72
Added:
(** Recognise an unordered list item ([-], [+], or indented [*]). *)
73
Added:
let unordered_item line =
74
Added:
let length = String.length line in
75
Added:
let trimmed = String.trim line in
76
Added:
let tlen = String.length trimmed in
77
Added:
if tlen >= 2 && List.mem trimmed.[0] [ '-'; '+' ] && trimmed.[1] = ' ' then
78
Added:
Some (String.sub trimmed 2 (tlen - 2) |> String.trim)
79
Added:
else if
80
Added:
tlen >= 2
81
Added:
&& trimmed.[0] = '*'
82
Added:
&& trimmed.[1] = ' '
83
Added:
&& length > 0
84
Added:
&& (line.[0] = ' ' || line.[0] = '\t')
85
Added:
then Some (String.sub trimmed 2 (tlen - 2) |> String.trim)
86
Added:
else None
87
Added:
88
Added:
(** Recognise an ordered list item ([1.], [2)], etc.). *)
89
Added:
let ordered_item line =
90
Added:
let trimmed = String.trim line in
91
Added:
let tlen = String.length trimmed in
92
Added:
let rec digits i =
93
Added:
if i < tlen && trimmed.[i] >= '0' && trimmed.[i] <= '9' then digits (i + 1)
94
Added:
else i
95
Added:
in
96
Added:
let d = digits 0 in
97
Added:
if d = 0 || d >= tlen then None
98
Added:
else if
99
Added:
(trimmed.[d] = '.' || trimmed.[d] = ')')
100
Added:
&& d + 1 < tlen
101
Added:
&& trimmed.[d + 1] = ' '
102
Added:
then Some (String.sub trimmed (d + 2) (tlen - d - 2) |> String.trim)
103
Added:
else None
104
Added:
105
Added:
(** True when a line starts a new block (blank, or a list item). *)
106
Added:
let is_boundary_common line =
107
Added:
String.trim line = ""
108
Added:
|| Option.is_some (unordered_item line)
109
Added:
|| Option.is_some (ordered_item line)
110
Added:
70
111
(* {1 Anchor generation} *)
71
112
72
113
let new_anchor () =
lib/prose/prose_markdown.ml
@@ -26,37 +26,9 @@
26
26
( level,
27
27
String.sub line (level + 1) (length - level - 1) |> trim_end_hashes )
28
28
29
Removed:
let unordered_item line =
30
Removed:
let length = String.length line in
31
Removed:
let trimmed = String.trim line in
32
Removed:
let tlen = String.length trimmed in
33
Removed:
if tlen >= 2 && List.mem trimmed.[0] [ '-'; '+' ] && trimmed.[1] = ' ' then
34
Removed:
Some (String.sub trimmed 2 (tlen - 2) |> String.trim)
35
Removed:
else if
36
Removed:
tlen >= 2
37
Removed:
&& trimmed.[0] = '*'
38
Removed:
&& trimmed.[1] = ' '
39
Removed:
&& length > 0
40
Removed:
&& (line.[0] = ' ' || line.[0] = '\t')
41
Removed:
then Some (String.sub trimmed 2 (tlen - 2) |> String.trim)
42
Removed:
else None
29
Added:
let unordered_item = Prose_format.unordered_item
30
Added:
let ordered_item = Prose_format.ordered_item
43
31
44
Removed:
let ordered_item line =
45
Removed:
let trimmed = String.trim line in
46
Removed:
let tlen = String.length trimmed in
47
Removed:
let rec digits i =
48
Removed:
if i < tlen && trimmed.[i] >= '0' && trimmed.[i] <= '9' then digits (i + 1)
49
Removed:
else i
50
Removed:
in
51
Removed:
let d = digits 0 in
52
Removed:
if d = 0 || d >= tlen then None
53
Removed:
else if
54
Removed:
(trimmed.[d] = '.' || trimmed.[d] = ')')
55
Removed:
&& d + 1 < tlen
56
Removed:
&& trimmed.[d + 1] = ' '
57
Removed:
then Some (String.sub trimmed (d + 2) (tlen - d - 2) |> String.trim)
58
Removed:
else None
59
Removed:
60
32
let fence line =
61
33
let line = String.trim line in
62
34
if String.length line < 3 then None
@@ -72,10 +44,7 @@
72
44
73
45
(* {1 Block parsing} *)
74
46
75
Removed:
let is_boundary_common line =
76
Removed:
String.trim line = ""
77
Removed:
|| Option.is_some (unordered_item line)
78
Removed:
|| Option.is_some (ordered_item line)
47
Added:
let is_boundary_common = Prose_format.is_boundary_common
79
48
80
49
let parse_blocks lines =
81
50
let is_boundary line =
lib/prose/prose_org.ml
@@ -96,37 +96,9 @@
96
96
( min 6 level,
97
97
String.sub line (level + 1) (length - level - 1) |> String.trim )
98
98
99
Removed:
let unordered_item line =
100
Removed:
let length = String.length line in
101
Removed:
let trimmed = String.trim line in
102
Removed:
let tlen = String.length trimmed in
103
Removed:
if tlen >= 2 && List.mem trimmed.[0] [ '-'; '+' ] && trimmed.[1] = ' ' then
104
Removed:
Some (String.sub trimmed 2 (tlen - 2) |> String.trim)
105
Removed:
else if
106
Removed:
tlen >= 2
107
Removed:
&& trimmed.[0] = '*'
108
Removed:
&& trimmed.[1] = ' '
109
Removed:
&& length > 0
110
Removed:
&& (line.[0] = ' ' || line.[0] = '\t')
111
Removed:
then Some (String.sub trimmed 2 (tlen - 2) |> String.trim)
112
Removed:
else None
99
Added:
let unordered_item = Prose_format.unordered_item
100
Added:
let ordered_item = Prose_format.ordered_item
113
101
114
Removed:
let ordered_item line =
115
Removed:
let trimmed = String.trim line in
116
Removed:
let tlen = String.length trimmed in
117
Removed:
let rec digits i =
118
Removed:
if i < tlen && trimmed.[i] >= '0' && trimmed.[i] <= '9' then digits (i + 1)
119
Removed:
else i
120
Removed:
in
121
Removed:
let d = digits 0 in
122
Removed:
if d = 0 || d >= tlen then None
123
Removed:
else if
124
Removed:
(trimmed.[d] = '.' || trimmed.[d] = ')')
125
Removed:
&& d + 1 < tlen
126
Removed:
&& trimmed.[d + 1] = ' '
127
Removed:
then Some (String.sub trimmed (d + 2) (tlen - d - 2) |> String.trim)
128
Removed:
else None
129
Removed:
130
102
let definition_item line =
131
103
let trimmed = String.trim line in
132
104
let tlen = String.length trimmed in
@@ -177,10 +149,7 @@
177
149
(* {1 Block parsing} *)
178
150
179
151
let is_boundary_common line =
180
Removed:
String.trim line = ""
181
Removed:
|| Option.is_some (unordered_item line)
182
Removed:
|| Option.is_some (ordered_item line)
183
Removed:
|| Option.is_some (definition_item line)
152
Added:
Prose_format.is_boundary_common line || Option.is_some (definition_item line)
184
153
185
154
let parse_blocks lines =
186
155
let is_boundary line =