feat(inline): footnote parser
This commit is contained in:
parent
38806c4d03
commit
8e17a8f94c
|
@ -33,7 +33,7 @@
|
||||||
:sp-chars ["#" "-"]
|
:sp-chars ["#" "-"]
|
||||||
:any-space true
|
:any-space true
|
||||||
:continue-until-no-match true
|
:continue-until-no-match true
|
||||||
:regex "%s*[%-%#].-\n"}
|
:regex "[^%[][%-%#].-\n"}
|
||||||
{:name "Footnote"
|
{:name "Footnote"
|
||||||
:sp-chars ["::\n"]
|
:sp-chars ["::\n"]
|
||||||
:regex "%s*::%s-\n"
|
:regex "%s*::%s-\n"
|
||||||
|
|
51
inline.fnl
51
inline.fnl
|
@ -18,8 +18,12 @@
|
||||||
:Link (fn link-fn [str current]
|
:Link (fn link-fn [str current]
|
||||||
(let [patterns {:In-Link "%[%[(.-)%]%]"
|
(let [patterns {:In-Link "%[%[(.-)%]%]"
|
||||||
:Named-In-Link "%[%[(.-)%|(.-)%]%]"
|
:Named-In-Link "%[%[(.-)%|(.-)%]%]"
|
||||||
:Out-Link "%[(.-)%]%((.-)%)"}
|
:Out-Link "%[(.-)%]%((.-)%)"
|
||||||
next-char (string.sub str current (+ 1 current))]
|
:Footnote "%[(.-)%]%_"}
|
||||||
|
(find-char _) (string.find str "%[")
|
||||||
|
next-char (string.sub str (+ 1 find-char) (+ 1 find-char))]
|
||||||
|
(_G.pp (.. "find-char " find-char))
|
||||||
|
(_G.pp (.. "next-char " next-char))
|
||||||
(if (= next-char "[")
|
(if (= next-char "[")
|
||||||
(if (not (= nil (string.match str (. patterns :Named-In-Link) current)))
|
(if (not (= nil (string.match str (. patterns :Named-In-Link) current)))
|
||||||
(let [(start end filename title) (string.find str (. patterns :Named-In-Link) current)]
|
(let [(start end filename title) (string.find str (. patterns :Named-In-Link) current)]
|
||||||
|
@ -32,11 +36,27 @@
|
||||||
:title filename
|
:title filename
|
||||||
:destination filename}
|
:destination filename}
|
||||||
end)))
|
end)))
|
||||||
(let [(start end title destination) (string.find str (. patterns :Out-Link) current)]
|
; If it's not a [[ type link
|
||||||
(values {:type "Link"
|
; We need to check the next char after the ]
|
||||||
:title title
|
; if it's _ it's a footnote
|
||||||
:destination destination}
|
; if it's ) it's an out-link
|
||||||
end)))))})
|
(let [(_ close-bracket) (string.find str "%]" current)
|
||||||
|
next-close-char (string.sub str (+ 1 close-bracket) (+ 1 close-bracket))]
|
||||||
|
(_G.pp "we think it's not a in-link")
|
||||||
|
(_G.pp (.. "next-close-char " next-close-char))
|
||||||
|
(match next-close-char
|
||||||
|
"(" (let [(start end title destination) (string.find str (. patterns :Out-Link) current)]
|
||||||
|
(values {:type "Link"
|
||||||
|
:title title
|
||||||
|
:destination destination}
|
||||||
|
end))
|
||||||
|
"_" (let [(start end footnote-number) (string.find str (. patterns :Footnote) current)]
|
||||||
|
(_G.pp "In footnote")
|
||||||
|
(_G.pp (.. "end " end))
|
||||||
|
(values {:type "Footnote-Link"
|
||||||
|
:number footnote-number}
|
||||||
|
end))
|
||||||
|
_ (values nil next-close-char))))))}) ; Could not parse type of link, just skip it
|
||||||
; :Spoiler
|
; :Spoiler
|
||||||
; :Censor})
|
; :Censor})
|
||||||
|
|
||||||
|
@ -46,8 +66,11 @@
|
||||||
(var lexed [])
|
(var lexed [])
|
||||||
(while (and (not (= nil current)) (> (length contents) current))
|
(while (and (not (= nil current)) (> (length contents) current))
|
||||||
(let [found (string.find contents (. grammar :match-first) current)]
|
(let [found (string.find contents (. grammar :match-first) current)]
|
||||||
|
(_G.pp (.. "current " current))
|
||||||
|
(_G.pp (.. "found " found))
|
||||||
(if (not (= nil found))
|
(if (not (= nil found))
|
||||||
(let [char (string.sub contents found found)]
|
(let [char (string.sub contents found found)]
|
||||||
|
(_G.pp (.. "char " char))
|
||||||
(if (> found 1)
|
(if (> found 1)
|
||||||
(table.insert lexed {:type "raw-text"
|
(table.insert lexed {:type "raw-text"
|
||||||
:contents (string.sub contents current (- found 1))}))
|
:contents (string.sub contents current (- found 1))}))
|
||||||
|
@ -85,6 +108,8 @@
|
||||||
; ((. contents-grammar :Bold) "*This* other thing" 1)
|
; ((. contents-grammar :Bold) "*This* other thing" 1)
|
||||||
; (contents-lexer "*This* is a paragraph.")
|
; (contents-lexer "*This* is a paragraph.")
|
||||||
|
|
||||||
|
; (contents-lexer "Some footnote string [#]_")
|
||||||
|
|
||||||
(fn list-rule [str ?regex]
|
(fn list-rule [str ?regex]
|
||||||
(let [regex (or ?regex "(%s*)%-%s*(.-)\n")]
|
(let [regex (or ?regex "(%s*)%-%s*(.-)\n")]
|
||||||
(var list-elems [])
|
(var list-elems [])
|
||||||
|
@ -100,7 +125,8 @@
|
||||||
(key val) (string.match str regex)]
|
(key val) (string.match str regex)]
|
||||||
{:type "Metadata"
|
{:type "Metadata"
|
||||||
: key
|
: key
|
||||||
: val}))}
|
: val
|
||||||
|
:is-metadata true}))}
|
||||||
:Code { :rule (fn code-rule [str ?regex]
|
:Code { :rule (fn code-rule [str ?regex]
|
||||||
(let [regex (or ?regex "{{{(.-)\n(.-)}}}\n")
|
(let [regex (or ?regex "{{{(.-)\n(.-)}}}\n")
|
||||||
(hint code) (string.match str regex)]
|
(hint code) (string.match str regex)]
|
||||||
|
@ -124,14 +150,16 @@
|
||||||
(let [regex (or ?regex "::%s-\n%s*(.-)\n::\n")
|
(let [regex (or ?regex "::%s-\n%s*(.-)\n::\n")
|
||||||
list (string.match str regex)]
|
list (string.match str regex)]
|
||||||
{:type "Footnotes"
|
{:type "Footnotes"
|
||||||
:elements (. (list-rule list) :elements)}))}
|
:elements (. (list-rule list) :elements)
|
||||||
|
:is-metadata true}))}
|
||||||
:Tag {:rule (fn tag-rule [str ?regex]
|
:Tag {:rule (fn tag-rule [str ?regex]
|
||||||
(let [regex (or ?regex "%:(.-):")]
|
(let [regex (or ?regex "%:(.-):")]
|
||||||
(var tags [])
|
(var tags [])
|
||||||
(each [tag (string.gmatch str regex)]
|
(each [tag (string.gmatch str regex)]
|
||||||
(table.insert tags tag))
|
(table.insert tags tag))
|
||||||
{:type "Tag"
|
{:type "Tag"
|
||||||
:tags tags}))}
|
:tags tags
|
||||||
|
:is-metadata true}))}
|
||||||
:Quote {:rule (fn quote-rule [str ?regex]
|
:Quote {:rule (fn quote-rule [str ?regex]
|
||||||
(var total "")
|
(var total "")
|
||||||
(let [regex (or ?regex "%s*>%s*(.-)\n")]
|
(let [regex (or ?regex "%s*>%s*(.-)\n")]
|
||||||
|
@ -143,9 +171,6 @@
|
||||||
{:type "Paragraph"
|
{:type "Paragraph"
|
||||||
:contents (contents-lexer str)})}})
|
:contents (contents-lexer str)})}})
|
||||||
|
|
||||||
; TODO
|
|
||||||
; All :contents entries must go through the contents parser
|
|
||||||
|
|
||||||
(fn inline-lexer [blocks grammar]
|
(fn inline-lexer [blocks grammar]
|
||||||
(var lexed [])
|
(var lexed [])
|
||||||
(var section [])
|
(var section [])
|
||||||
|
|
2
main.fnl
2
main.fnl
|
@ -4,7 +4,7 @@
|
||||||
(local blocks (require :block))
|
(local blocks (require :block))
|
||||||
(local inline (require :inline))
|
(local inline (require :inline))
|
||||||
|
|
||||||
(local test-input "= Big Test File =\n%title Some Title\n:note:\n*This* is a paragraph.\n- This\n- List\n- Should\n- Be One\n-----\n= A new Section Title =\n![Has an Image](file:///link-to-image.png)\n> With some quoted matieral\n>Across multiple lines\n > and different indents\n\n{{{python \n def file(arg, other):\n rturn rg + other\n}}}\n\nMore Paragraphs\n-----\n:: \n\n- This is the first note\n-This is the second\n::\n")
|
(local test-input "= Big Test File =\n%title Some Title\n:note:\n*This* is a paragraph.\n- This\n- List\n- Should\n- Be One\n-----\n= A new Section Title =\n![Has an Image](file:///link-to-image.png)\n> With some quoted matieral\n>Across multiple lines\n > and different indents\n\n{{{python \n def file(arg, other):\n rturn rg + other\n}}}\n\nMore Paragraphs\n-----\n\nThis has a footnote [#]_ \n\n:: \n\n- This is the first note\n-This is the second\n::\n")
|
||||||
|
|
||||||
(-> test-input
|
(-> test-input
|
||||||
(blocks.lexer blocks.grammar)
|
(blocks.lexer blocks.grammar)
|
||||||
|
|
24
render.fnl
24
render.fnl
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
(fn render-contents [contents])
|
(fn render-contents [contents])
|
||||||
|
|
||||||
(local renderer
|
(local render-grammar
|
||||||
{:Header (fn render-header [{: contents : size}]
|
{:Header (fn render-header [{: contents : size}]
|
||||||
(let [header-type (tostring size)
|
(let [header-type (tostring size)
|
||||||
header (.. "h" header-type)
|
header (.. "h" header-type)
|
||||||
|
@ -50,5 +50,25 @@
|
||||||
; Need to look into pygments or whatever see how that works
|
; Need to look into pygments or whatever see how that works
|
||||||
; Or find some sort of minimal js solution?
|
; Or find some sort of minimal js solution?
|
||||||
; Not really sure
|
; Not really sure
|
||||||
:Code ""})
|
:Code ""
|
||||||
|
; Also not sure what to do about footnotes
|
||||||
|
; We need to link footnotes from inline parsing
|
||||||
|
; (which I'm just realizing I've forgotton to do... )
|
||||||
|
; And then link them here
|
||||||
|
:Footnote ""})
|
||||||
|
|
||||||
|
(fn render [blocks grammar]
|
||||||
|
(var rendered "")
|
||||||
|
(var metadata {})
|
||||||
|
(each [_ section (ipairs blocks)]
|
||||||
|
(each [_ block (ipairs section)]
|
||||||
|
(let [rule-set (. grammar (. block :type))]
|
||||||
|
(if (. block :is-metadata)
|
||||||
|
(set metadata (rule-set block metadata)) ; Handle metadata, TODO this doesn't handle sections for metadata semantics
|
||||||
|
(set rendered (.. rendered (rule-set block)))))) ; Write to the rendered string
|
||||||
|
(set rendered (.. rendered "\n<break/>\n"))) ; TODO Section "rendering"
|
||||||
|
; Should each section be returned seperately?
|
||||||
|
; Then we can add metadata to it easily.
|
||||||
|
; Final section
|
||||||
|
rendered)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue