diff options
-rw-r--r-- | rst_context.lua | 11 | ||||
-rw-r--r-- | rst_parser.lua | 67 |
2 files changed, 66 insertions, 12 deletions
diff --git a/rst_context.lua b/rst_context.lua index 6ace513..05ed14f 100644 --- a/rst_context.lua +++ b/rst_context.lua @@ -501,15 +501,16 @@ function rst_context.section (...) -- TODO general cleanup; move validity local tab = { ... } -- checking to parser. local section, str = true, "" local adornchar + local ulen = unicode.utf8.len if #tab == 3 then -- TODO use unicode length with ConTeXt adornchar = tab[1]:sub(1,1) - section = tab[1] == tab[3] and #tab[1] >= #tab[2] - section = get_line_pattern(adornchar):match(tab[1]) ~= nil and section + section = ulen(tab[1]) >= ulen(tab[2]) + --section = get_line_pattern(adornchar):match(tab[1]) ~= nil and section str = string.strip(tab[2]) else -- no overline adornchar = tab[2]:sub(1,1) - section = #tab[1] <= #tab[2] - section = get_line_pattern(adornchar):match(tab[2]) ~= nil and section + section = ulen(tab[1]) <= ulen(tab[2]) + --section = get_line_pattern(adornchar):match(tab[2]) ~= nil and section str = tab[1] end @@ -527,6 +528,8 @@ function rst_context.section (...) -- TODO general cleanup; move validity ref = get_context_reference (str) str = string.format("\n\\\\%s[%s]{%s}\n", sectionlevels[level], ref, str) + else + return [[{\\bf fix your sectioning!}\\endgraf}]] end return section and str or "" diff --git a/rst_parser.lua b/rst_parser.lua index 0901de4..a83209a 100644 --- a/rst_parser.lua +++ b/rst_parser.lua @@ -57,6 +57,7 @@ state.currentindent = "" -- used in definition lists and elsewhere state.previousindent = "" -- for literal blocks included in paragraphs to restore the paragraph indent state.currentwidth = 0 -- table layout state.currentlayout = {} -- table layout +state.previousadorn = nil -- section underlining and overlining state.footnotes = {} state.footnotes.autonumber = 0 @@ -67,6 +68,32 @@ state.footnotes.symbol = {} state.addme = {} +do + local first_adornment = "" + local valid_adornment = P{ + [1] = "adorncheck", + adorncheck = V"check_first" * V"check_other"^1 * -P(1), + + -- check_first = Cg(V"adornment_char", "first"), -- This *should* work but but due to some heavenly + -- intervention the governing rules of the universe + -- have been altered so as to annoy everybody + -- trying to deploy it. + + check_first = Cmt(V"adornment_char", function(_,_, first) + first_adornment = first + return true + end) + , + check_other = Cmt(V"adornment_char", function(_,_, char) + local prev = first_adornment + return char == prev + end) + , + adornment_char = S[[!"#$%&'()*+,-./:;<=>?@[]^_`{|}~]] + P[[\\]], + } + state.valid_adornment = valid_adornment +end + local enclosed_mapping = { ["'"] = "'", ['"'] = '"', @@ -910,17 +937,41 @@ local parser = P{ -- Sectioning -------------------------------------------------------------------------------- - section_adorn = C(V"adornment_char"^1) * V"space"^0 * V"eol", + section_adorn = V"adornment_char"^1, + + section = V"section_before"^-1 + * V"section_text" + * V"section_after" + * (V"eol" + V"end_block") + / rst.section + , -- The whitespace handling after the overline is necessary because headings -- without overline aren't allowed to be indented. - section = (V"section_adorn" * V"whitespace"^0)^-1 - * C((1 - V"whitespace") * (1 - V"eol")^1) - * V"eol" - * V"section_adorn" - * V"eol"^-1 - / rst.section, -- validity checking done by the formatter. Now, if - -- this ain't lazy then I don't know … + section_before = C(Cmt(V"section_adorn", function(s,i, adorn) + state.previousadorn = adorn + warn ("sec-f", state.valid_adornment:match(adorn), adorn:sub(1,2) .. "...", "", i) + return state.valid_adornment:match(adorn) + end)) + * V"whitespace"^0 + * V"eol" + * V"whitespace"^0 + , + + section_text = C((1 - V"space" - V"eol")^1) * V"eol", + + section_after = C(Cmt(V"section_adorn", function(s,i, adorn) + local tests = false + tests = state.valid_adornment:match(adorn) and true + if state.previousadorn then + tests = tests and adorn == state.previousadorn + end + warn ("sec-o", tests, adorn:sub(1,2) .. "…", "", i) + state.previousadorn = nil + return tests + end)) + * V"whitespace"^0 + , -------------------------------------------------------------------------------- -- Target Blocks |