diff options
Diffstat (limited to 'Master/texmf-dist/tex/luatex/markdown/markdown.lua')
-rw-r--r-- | Master/texmf-dist/tex/luatex/markdown/markdown.lua | 202 |
1 files changed, 172 insertions, 30 deletions
diff --git a/Master/texmf-dist/tex/luatex/markdown/markdown.lua b/Master/texmf-dist/tex/luatex/markdown/markdown.lua index 85900563718..eb68cc175d5 100644 --- a/Master/texmf-dist/tex/luatex/markdown/markdown.lua +++ b/Master/texmf-dist/tex/luatex/markdown/markdown.lua @@ -58,12 +58,12 @@ -- those in the standard .ins files. -- local metadata = { - version = "2.10.1", + version = "2.11.0-0-g4505824", comment = "A module for the conversion from markdown to plain TeX", author = "John MacFarlane, Hans Hagen, Vít Novotný", copyright = {"2009-2016 John MacFarlane, Hans Hagen", "2016-2021 Vít Novotný"}, - license = "LPPL 1.3" + license = "LPPL 1.3c" } if not modules then modules = { } end @@ -97,6 +97,7 @@ defaultOptions.headerAttributes = false defaultOptions.html = false defaultOptions.hybrid = false defaultOptions.inlineFootnotes = false +defaultOptions.jekyllData = false defaultOptions.pipeTables = false defaultOptions.preserveTabs = false defaultOptions.shiftHeadings = 0 @@ -105,6 +106,7 @@ defaultOptions.smartEllipses = false defaultOptions.startNumber = true defaultOptions.stripIndent = false defaultOptions.tableCaptions = false +defaultOptions.taskLists = false defaultOptions.texComments = false defaultOptions.tightLists = true defaultOptions.underscores = true @@ -2346,19 +2348,6 @@ function M.writer.new(options) if not self.is_writing then return "" end return "\\markdownRendererHorizontalRule{}" end - local escaped_chars = { - ["{"] = "\\markdownRendererLeftBrace{}", - ["}"] = "\\markdownRendererRightBrace{}", - ["$"] = "\\markdownRendererDollarSign{}", - ["%"] = "\\markdownRendererPercentSign{}", - ["&"] = "\\markdownRendererAmpersand{}", - ["_"] = "\\markdownRendererUnderscore{}", - ["#"] = "\\markdownRendererHash{}", - ["^"] = "\\markdownRendererCircumflex{}", - ["\\"] = "\\markdownRendererBackslash{}", - ["~"] = "\\markdownRendererTilde{}", - ["|"] = "\\markdownRendererPipe{}", - } local escaped_uri_chars = { ["{"] = "\\markdownRendererLeftBrace{}", ["}"] = "\\markdownRendererRightBrace{}", @@ -2369,20 +2358,37 @@ function M.writer.new(options) ["{"] = "\\markdownRendererLeftBrace{}", ["}"] = "\\markdownRendererRightBrace{}", ["%"] = "\\markdownRendererPercentSign{}", - ["#"] = "\\markdownRendererHash{}", ["\\"] = "\\markdownRendererBackslash{}", + ["#"] = "\\markdownRendererHash{}", } local escaped_minimal_strings = { ["^^"] = "\\markdownRendererCircumflex\\markdownRendererCircumflex ", + ["☒"] = "\\markdownRendererTickedBox{}", + ["⌛"] = "\\markdownRendererHalfTickedBox{}", + ["☐"] = "\\markdownRendererUntickedBox{}", + } + local escaped_chars = { + ["{"] = "\\markdownRendererLeftBrace{}", + ["}"] = "\\markdownRendererRightBrace{}", + ["%"] = "\\markdownRendererPercentSign{}", + ["\\"] = "\\markdownRendererBackslash{}", + ["#"] = "\\markdownRendererHash{}", + ["$"] = "\\markdownRendererDollarSign{}", + ["&"] = "\\markdownRendererAmpersand{}", + ["_"] = "\\markdownRendererUnderscore{}", + ["^"] = "\\markdownRendererCircumflex{}", + ["~"] = "\\markdownRendererTilde{}", + ["|"] = "\\markdownRendererPipe{}", } - local escape = util.escaper(escaped_chars) + local escape = util.escaper(escaped_chars, escaped_minimal_strings) local escape_citation = util.escaper(escaped_citation_chars, escaped_minimal_strings) local escape_uri = util.escaper(escaped_uri_chars, escaped_minimal_strings) + local escape_minimal = util.escaper({}, escaped_minimal_strings) if options.hybrid then - self.string = function(s) return s end - self.citation = function(c) return c end - self.uri = function(u) return u end + self.string = escape_minimal + self.citation = escape_minimal + self.uri = escape_minimal else self.string = escape self.citation = escape_citation @@ -2556,6 +2562,15 @@ function M.writer.new(options) function self.emphasis(s) return {"\\markdownRendererEmphasis{",s,"}"} end + function self.tickbox(f) + if f == 1.0 then + return "☒ " + elseif f == 0.0 then + return "☐ " + else + return "⌛ " + end + end function self.strong(s) return {"\\markdownRendererStrongEmphasis{",s,"}"} end @@ -2576,6 +2591,88 @@ function M.writer.new(options) local name = util.cache(options.cacheDir, s, nil, nil, ".verbatim") return {"\\markdownRendererInputFencedCode{",name,"}{",i,"}"} end + function self.jekyllData(d, t, p) + if not self.is_writing then return "" end + + local buf = {} + + local keys = {} + for k, _ in pairs(d) do + table.insert(keys, k) + end + table.sort(keys) + + if not p then + table.insert(buf, "\\markdownRendererJekyllDataBegin") + end + + if #d > 0 then + table.insert(buf, "\\markdownRendererJekyllDataSequenceBegin{") + table.insert(buf, self.uri(p or "null")) + table.insert(buf, "}{") + table.insert(buf, #keys) + table.insert(buf, "}") + else + table.insert(buf, "\\markdownRendererJekyllDataMappingBegin{") + table.insert(buf, self.uri(p or "null")) + table.insert(buf, "}{") + table.insert(buf, #keys) + table.insert(buf, "}") + end + + for _, k in ipairs(keys) do + local v = d[k] + local typ = type(v) + k = tostring(k or "null") + if typ == "table" and next(v) ~= nil then + table.insert( + buf, + self.jekyllData(v, t, k) + ) + else + k = self.uri(k) + v = tostring(v) + if typ == "boolean" then + table.insert(buf, "\\markdownRendererJekyllDataBoolean{") + table.insert(buf, k) + table.insert(buf, "}{") + table.insert(buf, v) + table.insert(buf, "}") + elseif typ == "number" then + table.insert(buf, "\\markdownRendererJekyllDataNumber{") + table.insert(buf, k) + table.insert(buf, "}{") + table.insert(buf, v) + table.insert(buf, "}") + elseif typ == "string" then + table.insert(buf, "\\markdownRendererJekyllDataString{") + table.insert(buf, k) + table.insert(buf, "}{") + table.insert(buf, t(v)) + table.insert(buf, "}") + elseif typ == "table" then + table.insert(buf, "\\markdownRendererJekyllDataEmpty{") + table.insert(buf, k) + table.insert(buf, "}") + else + error(format("Unexpected type %s for value of " .. + "YAML key %s", typ, k)) + end + end + end + + if #d > 0 then + table.insert(buf, "\\markdownRendererJekyllDataSequenceEnd") + else + table.insert(buf, "\\markdownRendererJekyllDataMappingEnd") + end + + if not p then + table.insert(buf, "\\markdownRendererJekyllDataEnd") + end + + return buf + end self.active_headings = {} function self.heading(s,level,attributes) local active_headings = self.active_headings @@ -2660,16 +2757,16 @@ function M.writer.new(options) } end function self.set_state(s) - previous_state = self.get_state() - for key, value in pairs(state) do + local previous_state = self.get_state() + for key, value in pairs(s) do self[key] = value end return previous_state end function self.defer_call(f) - state = self.get_state() + local previous_state = self.get_state() return function(...) - state = self.set_state(state) + local state = self.set_state(previous_state) local return_value = f(...) self.set_state(state) return return_value @@ -2764,7 +2861,6 @@ parsers.spnl = parsers.optionalspace * (parsers.newline * parsers.optionalspace)^-1 parsers.line = parsers.linechar^0 * parsers.newline parsers.nonemptyline = parsers.line - parsers.blankline - parsers.commented_line_letter = parsers.linechar + parsers.newline - parsers.backslash @@ -2803,7 +2899,9 @@ parsers.commented_line = Cg(Cc(""), "backslashes") + parsers.percent -- comment * parsers.line * parsers.optionalspace) -- leading tabs and spaces - + C(parsers.newline)) + + #(parsers.newline) + * Cb("backslashes") + * C(parsers.newline)) parsers.chunk = parsers.line * (parsers.optionallyindentedline - parsers.blankline)^0 @@ -2843,6 +2941,16 @@ parsers.bullet = ( parsers.bulletchar * #parsers.spacing + parsers.space * parsers.space * parsers.space * parsers.bulletchar * #parsers.spacing ) + +local function tickbox(interior) + return parsers.optionalspace * parsers.lbracket + * interior * parsers.rbracket * parsers.spacechar^1 +end + +parsers.ticked_box = tickbox(S("xX")) * Cc(1.0) +parsers.halfticked_box = tickbox(S("./")) * Cc(0.5) +parsers.unticked_box = tickbox(parsers.spacechar^1) * Cc(0.0) + parsers.openticks = Cg(parsers.backtick^1, "ticks") local function captures_equal_length(s,i,a,b) @@ -3309,6 +3417,11 @@ parsers.BacktickFencedCode * Cs(parsers.fencedline(parsers.backtick)^0) * parsers.fencetail(parsers.backtick) +parsers.JekyllFencedCode + = parsers.fencehead(parsers.dash) + * Cs(parsers.fencedline(parsers.dash)^0) + * parsers.fencetail(parsers.dash) + parsers.lineof = function(c) return (parsers.leader * (P(c) * parsers.optionalspace)^3 * (parsers.newline * parsers.blankline^1 @@ -3797,6 +3910,19 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline expandtabs(code)) end + larsers.JekyllData = P("---") + * parsers.blankline / 0 + * #(-parsers.blankline) -- if followed by blank, it's an hrule + * C((parsers.line - P("---") - P("..."))^0) + * (P("---") + P("...")) + / function(text) + local tinyyaml = require("markdown-tinyyaml") + data = tinyyaml.parse(text) + return writer.jekyllData(data, function(s) + return parse_blocks(s) + end, nil) + end + larsers.Blockquote = Cs(larsers.blockquote_body^1) / parse_blocks_toplevel / writer.blockquote @@ -3830,6 +3956,15 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline / writer.plain larsers.starter = parsers.bullet + larsers.enumerator + if options.taskLists then + larsers.tickbox = ( parsers.ticked_box + + parsers.halfticked_box + + parsers.unticked_box + ) / writer.tickbox + else + larsers.tickbox = parsers.fail + end + -- we use \001 as a separator between a tight list item and a -- nested list under it. larsers.NestedList = Cs((parsers.optionallyindentedline @@ -3847,14 +3982,14 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline larsers.TightListItem = function(starter) return -larsers.HorizontalRule - * (Cs(starter / "" * larsers.ListBlock * larsers.NestedList^-1) + * (Cs(starter / "" * larsers.tickbox^-1 * larsers.ListBlock * larsers.NestedList^-1) / parse_blocks) * -(parsers.blanklines * parsers.indent) end larsers.LooseListItem = function(starter) return -larsers.HorizontalRule - * Cs( starter / "" * larsers.ListBlock * Cc("\n") + * Cs( starter / "" * larsers.tickbox^-1 * larsers.ListBlock * Cc("\n") * (larsers.NestedList + larsers.ListContinuationBlock^0) * (parsers.blanklines / "\n\n") ) / parse_blocks @@ -3981,7 +4116,10 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline Blank = larsers.Blank, + JekyllData = larsers.JekyllData, + Block = V("ContentBlock") + + V("JekyllData") + V("Blockquote") + V("PipeTable") + V("Verbatim") @@ -4105,8 +4243,8 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline syntax.InlineNote = parsers.fail end - if not options.smartEllipses then - syntax.Smart = parsers.fail + if not options.jekyllData then + syntax.JekyllData = parsers.fail end if options.preserveTabs then @@ -4117,6 +4255,10 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline syntax.PipeTable = parsers.fail end + if not options.smartEllipses then + syntax.Smart = parsers.fail + end + local blocks_toplevel_t = util.table_copy(syntax) blocks_toplevel_t.Paragraph = larsers.ToplevelParagraph larsers.blocks_toplevel = Ct(blocks_toplevel_t) |