Initial commit
John Smith

John Smith commited on 2021-309 22:15:30
Showing 2 changed files, with 76 additions and 0 deletions.


All that exists so far is
* `example.rec`: an example of the Rec-based format to be used in Memoire
* `recparse.lua`: a Lua module to parse Recfiles
... ...
@@ -0,0 +1,9 @@
1
+PromptText: paper size: {A4} = {210 mm} x {297 mm}
2
+LastReview: 1636245675
3
+LastDelay: 65536
4
+LastReview: 1636245679
5
+LastDelay: 65536
6
+LastReview: 1636245683
7
+LastDelay: 65536
8
+
9
+
... ...
@@ -0,0 +1,67 @@
1
+--[[
2
+    a Recfile is (to simplify) a sequence of records
3
+    a record is a sequence of fields
4
+    a field is a label-value pair
5
+    a label is an identifier
6
+    a value is a string
7
+]]
8
+
9
+--[[
10
+    maps text from a Recfile into a sequence of records
11
+    returns (on success) a table of tables of tables of two strings (label and value)
12
+    returns (on failure) nil
13
+]]
14
+local function text2recs(str)
15
+    local ret = {}
16
+    local cr = {}
17
+    local cl = nil
18
+    local cv = nil
19
+    -- Rec is line-based
20
+    for line in str:gmatch "([^\n]*)\n" do
21
+        -- continuation lines
22
+        if cv and cv:sub(-1) == "\\" then
23
+            cv = cv:sub(1, -2) .. line
24
+        elseif line:sub(1, 1) == "+" then
25
+            cv = cv .. "\n" .. line:gsub("^%+ ?", "")
26
+        -- blank lines separate records
27
+        elseif line:match "^%s*$" then
28
+            -- add field to record if non-empty
29
+            if cl then
30
+                table.insert(cr, { k = cl, v = cv })
31
+            end
32
+            cl = nil
33
+            cv = nil
34
+            -- add record to return value if non-empty
35
+            if next(cr) then
36
+                table.insert(ret, cr)
37
+            end
38
+            cr = {}
39
+        -- lines starting with # are comments
40
+        elseif line:sub(1, 1) == "#" then
41
+            if cl then
42
+                table.insert(cr, { k = cl, v = cv })
43
+            end
44
+            cl = nil
45
+            cv = nil
46
+        -- new field
47
+        else
48
+            if cl then
49
+                table.insert(cr, { k = cl, v = cv })
50
+            end
51
+            cl, cv = line:match "^([%a%%][%w_]*):%s(.*)"
52
+            -- no match? bad field
53
+            if not cl then
54
+                return nil
55
+            end
56
+        end
57
+    end
58
+    if cl then
59
+        table.insert(cr, { k = cl, v = cv })
60
+    end
61
+    if next(cr) then
62
+        table.insert(ret, cr)
63
+    end
64
+    return ret
65
+end
66
+
67
+return text2recs
0 68