cripslock

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 91c4682213b744607086b213158246bdf05c0eeb
parent 28712970d0ebdd8c88c9318a5891230a84b64569
Author: Daniel Barlow <dan@telent.net>
Date:   Tue, 15 Jul 2025 23:16:36 +0100

beginnings of inline markup

Diffstat:
Mtextile.fnl | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+), 0 deletions(-)

diff --git a/textile.fnl b/textile.fnl @@ -46,4 +46,77 @@ (let [(t b) (tag-and-body "bq. blockquoted")] (expect= [t b] [:blockquote "blockquoted"]))) +;; from https://github.com/jgarber/redcloth?tab=readme-ov-file#label-Quick+Phrase+Modifiers : +;; +;; _emphasis_ +;; __italicized__ +;; *strong* +;; **bold** +;; ??citation?? +;; -deleted text- +;; +inserted text+ +;; ^superscript^ +;; ~subscript~ +;; @code@ +;; %(classname)span% + + +;; walk the string from left to right. on encountering +;; any recognised opening token for inline markup, find the +;; matching closing token, and recursively walk the bit in the +;; middle. we have to find the first occurence of _any_ opening +;; token instead + +(fn scan-tok [endtok tag] + (fn [f str] + (let [(s e) (string.find str endtok 2 true)] + (values + (doto (f (string.sub str 2 (- s 1))) + (table.insert 1 tag)) + (string.sub str (+ e 1)))))) + +(local inline-tokens { + "_" (scan-tok "_" :em) + "*" (scan-tok "*" :strong) + "@" (let [s (scan-tok "@" :code)] + (fn [_ str] (s (fn [x] [x]) str))) + }) + +(local inline-token-pattern + (.. "([" + (accumulate [chrs "" + c _ (pairs inline-tokens)] + (.. (string.sub c 1 1) chrs)) + "])")) + + +(fn inline-markup [str] + (if (= str "") + nil + (case (string.find str inline-token-pattern) + (start end tok) + (let [(during after) ((. inline-tokens tok) inline-markup (string.sub str end))] + [ + (string.sub str 1 (- start 1)) + during + (inline-markup after) + ]) + _ [str]))) + +(define-tests :inline-markup + (expect= (inline-markup "foo") ["foo"]) + (expect= (inline-markup "foo _emph_") ["foo " [:em "emph"] ]) + (expect= (inline-markup "foo @1+2+3@") ["foo " [:code "1+2+3"] ]) + ;; markup in code blocks is ignored + (expect= (inline-markup "foo @1+_2_+3@") ["foo " [:code "1+_2_+3"] ]) + + (expect= (inline-markup "foo *strong*") ["foo " [:strong "strong"]]) + (expect= (inline-markup "foo *strong _em_*") + ["foo " [:strong "strong " [:em "em"]]]) + ) + + + + + {}