refactor centralize string utilities into String_util module

Extract lstrip, rstrip, and strip into a shared String_util module. Remove duplicate implementations from prescan.ml and lexer.ml.

Commit
e3530b1d25a4a0eee96cc1d62c9298b10f8441bc
Author
Kiro (high) <noreply@kiro.dev>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
lib/lexer.ml
index d3763b86..a4c1ceb3 100644..100644
@@ -99,14 +99,7 @@
99 99 in
100 100 loop 0
101 101
102 Removed: (** Strip trailing \r and whitespace from a string. *)
103 Removed: let rstrip s =
104 Removed: let len = String.length s in
105 Removed: let i = ref (len - 1) in
106 Removed: while !i >= 0 && (s.[!i] = ' ' || s.[!i] = '\t' || s.[!i] = '\r') do
107 Removed: decr i
108 Removed: done;
109 Removed: if !i = len - 1 then s else String.sub s 0 (!i + 1)
102 Added: let rstrip = String_util.rstrip
110 103
111 104 (** Affiliated keyword names per Org spec defaults. *)
112 105 let affiliated_keywords = [ "CAPTION"; "DATA"; "HEADER"; "HEADERS"; "NAME"; "PLOT"; "RESULTS" ]
lib/prescan.ml
index 223a241f..633ec8c2 100644..100644
@@ -5,26 +5,8 @@
5 5 These declarations may appear anywhere in the file and affect
6 6 how headings are interpreted. *)
7 7
8 Removed: (** Strip leading whitespace from a string. *)
9 Removed: let lstrip s =
10 Removed: let len = String.length s in
11 Removed: let i = ref 0 in
12 Removed: while !i < len && (s.[!i] = ' ' || s.[!i] = '\t') do
13 Removed: incr i
14 Removed: done;
15 Removed: if !i = 0 then s else String.sub s !i (len - !i)
16 Removed:
17 Removed: (** Strip trailing whitespace from a string. *)
18 Removed: let rstrip s =
19 Removed: let len = String.length s in
20 Removed: let i = ref (len - 1) in
21 Removed: while !i >= 0 && (s.[!i] = ' ' || s.[!i] = '\t' || s.[!i] = '\r') do
22 Removed: decr i
23 Removed: done;
24 Removed: if !i = len - 1 then s else String.sub s 0 (!i + 1)
25 Removed:
26 Removed: (** Strip both leading and trailing whitespace. *)
27 Removed: let strip s = lstrip (rstrip s)
8 Added: let lstrip = String_util.lstrip
9 Added: let strip = String_util.strip
28 10
29 11 (** Parse a TODO keyword line value into a todo_sequence.
30 12 Format: "KEYWORD1 KEYWORD2 | DONE1 DONE2"
lib/string_util.ml
index 00000000..796edd39 000000..100644
@@ -0,0 +1,25 @@
1 Added: (** Shared string utility functions.
2 Added:
3 Added: Centralizes whitespace handling to avoid duplication
4 Added: across prescan, lexer, and normalization modules. *)
5 Added:
6 Added: (** Strip leading whitespace (spaces and tabs). *)
7 Added: let lstrip s =
8 Added: let len = String.length s in
9 Added: let i = ref 0 in
10 Added: while !i < len && (s.[!i] = ' ' || s.[!i] = '\t') do
11 Added: incr i
12 Added: done;
13 Added: if !i = 0 then s else String.sub s !i (len - !i)
14 Added:
15 Added: (** Strip trailing whitespace (spaces, tabs, and carriage returns). *)
16 Added: let rstrip s =
17 Added: let len = String.length s in
18 Added: let i = ref (len - 1) in
19 Added: while !i >= 0 && (s.[!i] = ' ' || s.[!i] = '\t' || s.[!i] = '\r') do
20 Added: decr i
21 Added: done;
22 Added: if !i = len - 1 then s else String.sub s 0 (!i + 1)
23 Added:
24 Added: (** Strip both leading and trailing whitespace. *)
25 Added: let strip s = lstrip (rstrip s)