commit 9976cabf8811f4d3cb46bd7e212403e3ee917115
parent 65f371b74d87cf201af7c1c4b0b7cd6edb05148e
Author: Szymon Mikulicz <szymon.mikulicz@posteo.net>
Date: Wed, 10 Jun 2026 19:43:26 +0200
mnt parser now with printing
Diffstat:
| M | src/mnt.janet | | | 117 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
1 file changed, 80 insertions(+), 37 deletions(-)
diff --git a/src/mnt.janet b/src/mnt.janet
@@ -10,50 +10,55 @@
(peg/compile
~{:location (% (* (constant "at [") (line) (constant ":") (/ (column) ,dec) (constant "]: ")))
- :check_indent (+ (error (* " " (% (* :location (constant "Invalid indent, try ") (backref :col))))) true)
- :check_empty (+ (error (* 1 (% (* :location (constant "Stray characters at the end"))))) true)
- :key_invalid (+ "- " "> " ": " "[" "{" "#")
- :check_key (+ (error (* (<- :key_invalid :invalid)
- (% (* :location
- (constant "Keys cannot start with: '")
- (backref :invalid)
- (constant "'")))))
- true)
-
- :check_nl (+ (error (* "\n" (% (* :location (constant "Keys can't contain newlines"))))) true)
-
- :setcol (only-tags (* (/ (column) ,dec :col) (constant false :firstcol)))
- :colprefix (lenprefix (backref :col) " ")
- :firstprefix (* (backmatch :firstcol) :colprefix (any " "))
- :resetfirst (only-tags (constant "" :firstcol))
-
- :indent (+ (* :firstprefix :setcol) :colprefix)
-
- :increase (only-tags (/ (backref :col) ,inc :col))
-
- :string (* :indent ">" :val)
- :strings (% (unref (* :resetfirst :string (any (+ :comment (* (constant "\n") :string))))))
-
- :list (* :indent "-" :val)
- :lists (group (unref (* :resetfirst :list (any (+ :comment :list)))))
-
- :val (* " " (<- (to (+ "\n" -1 ))) (+ -1 (some "\n")))
- :key (* :check_indent :check_key (<- (to (+ "\n" (* (any " ") ":")))) :check_nl (any " "))
- :map (group (* :indent :key ":" (+ (* -1 :nil) :val (unref (* (some "\n") :increase :all)))))
- :maps (/ (group (unref (* :resetfirst :map (any (+ :comment :map))))) ,from-pairs-check)
+ :invalid_key_start (+ "- " "> " ": " "[" "{" "#")
+
+ :check_indent (+ (error (* " " (% (* :location
+ (constant "Invalid indentation, try ")
+ (backref :indent)
+ (constant " spaces"))))) true)
+ :check_eof (+ (error (* 1 (% (* :location
+ (constant "Stray characters at the end of file"))))) true)
+ :check_key_start (+ (error (* (<- :invalid_key_start :key_start)
+ (% (* :location
+ (constant "Keys cannot start with: '")
+ (backref :key_start)
+ (constant "'"))))) true)
+ :check_key_end (+ (error (* "\n" (% (* :location
+ (constant "Keys can't contain newlines"))))) true)
+
+ :indent_init (only-tags (constant 0 :indent))
+ :indent_save (only-tags (* (/ (column) ,dec :indent) (constant false :indent_new)))
+ :indent_saved (lenprefix (backref :indent) " ")
+ :indent_if_new (* (backmatch :indent_new) :indent_saved)
+ :indent_set_new (only-tags (constant "" :indent_new))
+ :indent_inc (only-tags (/ (backref :indent) ,inc :indent))
+ :indent (+ (* :indent_if_new (any " ") :indent_save) :indent_saved)
+
+ :value (* " " (<- (to (+ "\n" -1 ))) (+ -1 (some "\n")))
+ :key (* :check_indent :check_key_start (<- (to (+ "\n" (* (any " ") ":")))) :check_key_end (any " "))
+ :map (group (* :indent :key ":" (+ (* -1 :empty) :value (unref (* (some "\n") :indent_inc :any)))))
+ :maps (/ (group (unref (* :indent_set_new :map (any (+ :comment :map))))) ,from-pairs-check)
+
+ :string (* :indent ">" :value)
+ :strings (% (unref (* :indent_set_new :string (any (+ :comment (* (constant "\n") :string))))))
+
+ :list (* :indent "-" :value)
+ :lists (group (unref (* :indent_set_new :list (any (+ :comment :list)))))
:comment (* (any " ") "#" (to (+ "\n" -1)) (? "\n"))
+ :comments (any :comment)
- :nil (constant "")
-
- :all (* (any :comment) (+ :strings :lists :maps :nil))
+ :empty (constant "")
- :init (only-tags (constant 0 :col))
+ :any (* :comments (+ :strings :lists :maps :empty))
- :main (* :init (any :comment) :maps :check_empty)
+ :main (* :indent_init :comments :maps :check_eof)
}))
-(defn parse [str] ((peg/match peg str) 0))
+(defn parse [str]
+ (if-let [matched (peg/match peg str)]
+ (matched 0)
+ (error "Unable to parse the string as minimal nested text")))
(defn parsefile [path]
(def f (file/open path :rn))
@@ -61,3 +66,41 @@
(file/close f)
p)
+(defn- print_mnt [buf indent &opt key sep value]
+ (buffer/push-string buf (string
+ (string/repeat " " indent)
+ (if (nil? key) "" key)
+ (if (nil? sep) ":" sep)
+ ;(if (nil? value) [] [" " value])
+ "\n")))
+
+(defn unparse [dict &opt opt_dif opt_cur]
+ (if (not (dictionary? dict))
+ (error "The first argument to unparse must be a table"))
+
+ (def cur (if (nil? opt_cur) 0 opt_cur))
+ (def dif (if (nil? opt_dif) 2 opt_dif))
+ (def nxt (+ cur dif))
+ (def buf @"")
+ (loop [[key val] :pairs dict]
+ (if (not (string? key))
+ (error "The keys in the table can only be strings"))
+ (cond
+ (dictionary? val)
+ (do
+ (print_mnt buf cur key)
+ (buffer/push-string buf (unparse val dif nxt)))
+ (array? val)
+ (do
+ (print_mnt buf cur key)
+ (each el val
+ (print_mnt buf nxt nil "-" el)))
+ (string? val)
+ (if (nil? (string/find "\n" val))
+ (print_mnt buf cur key ":" val)
+ (do
+ (print_mnt buf cur key)
+ (each el (string/split "\n" val)
+ (print_mnt buf nxt nil ">" el))))
+ (error "The table can only contain strings, arrays and tables")))
+ (buffer/popn buf 1))