[OCaml] Org mode parser.
refactor remove Prescan from public API; add optional ?config to parse
Prescan is internal plumbing that consumers don't need. It moves to Org.Private.Prescan for test access. Org.parse and Org.parse_with_diagnostics now accept an optional ?config parameter for advanced use cases where the caller wants to supply custom TODO keyword configuration.
Changed files
lib/org.ml
@@ -14,7 +14,6 @@
14
14
15
15
module Ast = Ast
16
16
module Config = Config
17
Removed:
module Prescan = Prescan
18
17
module Diagnostic : sig
19
18
(** Severity levels for diagnostics. *)
20
19
type severity = Diagnostic.severity =
@@ -42,9 +41,9 @@
42
41
module Lexer = Lexer
43
42
module Parse_bridge = Parse_bridge
44
43
module Raw_ast = Raw_ast
44
Added:
module Prescan = Prescan
45
45
end
46
46
(**/**)
47
Removed:
48
47
(** {1 Parsing entry points} *)
49
48
50
49
let version = "0.1.0"
@@ -59,9 +58,15 @@
59
58
60
59
Malformed input degrades gracefully — the parser always
61
60
produces a best-effort document without raising exceptions
62
Removed:
for syntax errors. *)
63
Removed:
let parse input =
64
Removed:
let config = Prescan.scan input in
61
Added:
for syntax errors.
62
Added:
63
Added:
@param config Optional document configuration. When omitted,
64
Added:
the input is pre-scanned for #+TODO declarations automatically. *)
65
Added:
let parse ?config input =
66
Added:
let config = match config with
67
Added:
| Some c -> c
68
Added:
| None -> Prescan.scan input
69
Added:
in
65
70
let raw = Parse_bridge.parse ~config input in
66
71
Normalize.normalize config raw
67
72
@@ -73,6 +78,6 @@
73
78
Note: diagnostic collection is not yet wired through the
74
79
parsing pipeline. This currently always returns an empty
75
80
diagnostic list. *)
76
Removed:
let parse_with_diagnostics input =
77
Removed:
let doc = parse input in
81
Added:
let parse_with_diagnostics ?config input =
82
Added:
let doc = parse ?config input in
78
83
(doc, [])
test/test_main.ml
@@ -4,13 +4,13 @@
4
4
(* Prescan tests *)
5
5
6
6
let test_prescan_default () =
7
Removed:
let config = Org.Prescan.scan "" in
7
Added:
let config = Org.Private.Prescan.scan "" in
8
8
let kws = Org.Config.all_todo_keywords config in
9
9
Alcotest.(check (list string)) "default keywords" [ "TODO"; "DONE" ] kws
10
10
11
11
let test_prescan_custom_todo () =
12
12
let input = "#+TODO: NEXT WAITING | DONE CANCELLED\n" in
13
Removed:
let config = Org.Prescan.scan input in
13
Added:
let config = Org.Private.Prescan.scan input in
14
14
let kws = Org.Config.all_todo_keywords config in
15
15
Alcotest.(check (list string)) "custom keywords"
16
16
[ "NEXT"; "WAITING"; "DONE"; "CANCELLED" ] kws
@@ -20,14 +20,14 @@
20
20
"#+TODO: TODO | DONE\n\
21
21
#+TODO: OPEN | CLOSED\n"
22
22
in
23
Removed:
let config = Org.Prescan.scan input in
23
Added:
let config = Org.Private.Prescan.scan input in
24
24
let kws = Org.Config.all_todo_keywords config in
25
25
Alcotest.(check (list string)) "multiple sequences"
26
26
[ "TODO"; "DONE"; "OPEN"; "CLOSED" ] kws
27
27
28
28
let test_prescan_seq_todo () =
29
29
let input = "#+SEQ_TODO: NEXT ACTIVE | DONE\n" in
30
Removed:
let config = Org.Prescan.scan input in
30
Added:
let config = Org.Private.Prescan.scan input in
31
31
Alcotest.(check bool) "NEXT is todo" true
32
32
(Org.Config.is_todo_keyword config "NEXT");
33
33
Alcotest.(check bool) "DONE is todo" true
@@ -37,14 +37,14 @@
37
37
38
38
let test_prescan_case_insensitive_key () =
39
39
let input = "#+todo: BUG FIX | RESOLVED\n" in
40
Removed:
let config = Org.Prescan.scan input in
40
Added:
let config = Org.Private.Prescan.scan input in
41
41
let kws = Org.Config.all_todo_keywords config in
42
42
Alcotest.(check (list string)) "case insensitive key"
43
43
[ "BUG"; "FIX"; "RESOLVED" ] kws
44
44
45
45
let test_prescan_no_bar () =
46
46
let input = "#+TODO: TODO DOING DONE\n" in
47
Removed:
let config = Org.Prescan.scan input in
47
Added:
let config = Org.Private.Prescan.scan input in
48
48
let seqs = config.todo_sequences in
49
49
let seq = List.hd seqs in
50
50
Alcotest.(check (list string)) "all active" [ "TODO"; "DOING"; "DONE" ]