summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/markdown/markdown.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/luatex/markdown/markdown.lua')
-rw-r--r--Master/texmf-dist/tex/luatex/markdown/markdown.lua196
1 files changed, 147 insertions, 49 deletions
diff --git a/Master/texmf-dist/tex/luatex/markdown/markdown.lua b/Master/texmf-dist/tex/luatex/markdown/markdown.lua
index aac73da3c9f..161a0d39a29 100644
--- a/Master/texmf-dist/tex/luatex/markdown/markdown.lua
+++ b/Master/texmf-dist/tex/luatex/markdown/markdown.lua
@@ -20,7 +20,7 @@
-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--
--- Copyright (C) 2016-2021 Vít Novotný
+-- Copyright (C) 2016-2022 Vít Novotný
--
-- This work may be distributed and/or modified under the
-- conditions of the LaTeX Project Public License, either version 1.3
@@ -58,11 +58,11 @@
-- those in the standard .ins files.
--
local metadata = {
- version = "2.13.0-0-g1f680a8",
+ version = "2.14.0-0-g9635d76",
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ý"},
+ "2016-2022 Vít Novotný"},
license = "LPPL 1.3c"
}
@@ -102,6 +102,7 @@ defaultOptions.inlineFootnotes = false
defaultOptions.jekyllData = false
defaultOptions.pipeTables = false
defaultOptions.preserveTabs = false
+defaultOptions.relativeReferences = false
defaultOptions.shiftHeadings = 0
defaultOptions.slice = "^ $"
defaultOptions.smartEllipses = false
@@ -2527,15 +2528,28 @@ function M.writer.new(options)
local contents = util.intersperse(buffer,"\n")
if tight and options.tightLists then
return {"\\markdownRendererOlBeginTight\n",contents,
- "\n\\markdownRendererOlEndTight "}
+ "\n\\markdownRendererOlEndTight "}
else
return {"\\markdownRendererOlBegin\n",contents,
- "\n\\markdownRendererOlEnd "}
+ "\n\\markdownRendererOlEnd "}
end
end
function self.inline_html_comment(contents)
return {"\\markdownRendererInlineHtmlComment{",contents,"}"}
end
+ function self.block_html_comment(contents)
+ if not self.is_writing then return "" end
+ return {"\\markdownRendererBlockHtmlCommentBegin\n",contents,
+ "\n\\markdownRendererBlockHtmlCommentEnd "}
+ end
+ function self.inline_html_tag(contents)
+ return {"\\markdownRendererInlineHtmlTag{",self.string(contents),"}"}
+ end
+ function self.block_html_element(s)
+ if not self.is_writing then return "" end
+ local name = util.cache(options.cacheDir, s, nil, nil, ".verbatim")
+ return {"\\markdownRendererInputBlockHtmlElement{",name,"}"}
+ end
local function dlitem(term, defs)
local retVal = {"\\markdownRendererDlItem{",term,"}"}
for _, def in ipairs(defs) do
@@ -2593,8 +2607,23 @@ function M.writer.new(options)
return {"\\markdownRendererInputFencedCode{",name,"}{",i,"}"}
end
function self.document(d)
- return {"\\markdownRendererDocumentBegin\n", d,
- "\\markdownRendererDocumentEnd"}
+ local active_attributes = self.active_attributes
+ local buf = {"\\markdownRendererDocumentBegin\n", d}
+
+ -- pop attributes for sections that have ended
+ if options.headerAttributes and self.is_writing then
+ while #active_attributes > 0 do
+ local attributes = active_attributes[#active_attributes]
+ if #attributes > 0 then
+ table.insert(buf, "\\markdownRendererHeaderAttributeContextEnd")
+ end
+ table.remove(active_attributes, #active_attributes)
+ end
+ end
+
+ table.insert(buf, "\\markdownRendererDocumentEnd")
+
+ return buf
end
function self.jekyllData(d, t, p)
if not self.is_writing then return "" end
@@ -2678,51 +2707,100 @@ function M.writer.new(options)
return buf
end
- self.active_headings = {}
- function self.heading(s,level,attributes)
- local active_headings = self.active_headings
+ self.active_attributes = {}
+ function self.heading(s, level, attributes)
+ attributes = attributes or {}
+ for i = 1, #attributes do
+ attributes[attributes[i]] = true
+ end
+
+ local active_attributes = self.active_attributes
local slice_begin_type = self.slice_begin:sub(1, 1)
local slice_begin_identifier = self.slice_begin:sub(2) or ""
local slice_end_type = self.slice_end:sub(1, 1)
local slice_end_identifier = self.slice_end:sub(2) or ""
- while #active_headings < level do
- -- push empty identifiers for implied sections
- table.insert(active_headings, {})
+ local buf = {}
+
+ -- push empty attributes for implied sections
+ while #active_attributes < level-1 do
+ table.insert(active_attributes, {})
end
- while #active_headings >= level do
- -- pop identifiers for sections that have ended
- local active_identifiers = active_headings[#active_headings]
- if active_identifiers[slice_begin_identifier] ~= nil
+ -- pop attributes for sections that have ended
+ while #active_attributes >= level do
+ local active_identifiers = active_attributes[#active_attributes]
+ -- tear down all active attributes at slice end
+ if active_identifiers["#" .. slice_end_identifier] ~= nil
+ and slice_end_type == "$" then
+ for header_level = #active_attributes, 1, -1 do
+ if options.headerAttributes and #active_attributes[header_level] > 0 then
+ table.insert(buf, "\\markdownRendererHeaderAttributeContextEnd")
+ end
+ end
+ self.is_writing = false
+ end
+ table.remove(active_attributes, #active_attributes)
+ if self.is_writing and options.headerAttributes and #active_identifiers > 0 then
+ table.insert(buf, "\\markdownRendererHeaderAttributeContextEnd")
+ end
+ -- apply all active attributes at slice beginning
+ if active_identifiers["#" .. slice_begin_identifier] ~= nil
and slice_begin_type == "$" then
+ for header_level = 1, #active_attributes do
+ if options.headerAttributes and #active_attributes[header_level] > 0 then
+ table.insert(buf, "\\markdownRendererHeaderAttributeContextBegin")
+ end
+ end
self.is_writing = true
end
- if active_identifiers[slice_end_identifier] ~= nil
- and slice_end_type == "$" then
- self.is_writing = false
+ end
+
+ -- tear down all active attributes at slice end
+ if attributes["#" .. slice_end_identifier] ~= nil
+ and slice_end_type == "^" then
+ for header_level = #active_attributes, 1, -1 do
+ if options.headerAttributes and #active_attributes[header_level] > 0 then
+ table.insert(buf, "\\markdownRendererHeaderAttributeContextEnd")
+ end
end
- table.remove(active_headings, #active_headings)
+ self.is_writing = false
end
- -- push identifiers for the new section
- attributes = attributes or {}
- local identifiers = {}
- for index = 1, #attributes do
- attribute = attributes[index]
- identifiers[attribute:sub(2)] = true
+ -- push attributes for the new section
+ table.insert(active_attributes, attributes)
+ if self.is_writing and options.headerAttributes and #attributes > 0 then
+ table.insert(buf, "\\markdownRendererHeaderAttributeContextBegin")
end
- if identifiers[slice_begin_identifier] ~= nil
+
+ -- apply all active attributes at slice beginning
+ if attributes["#" .. slice_begin_identifier] ~= nil
and slice_begin_type == "^" then
+ for header_level = 1, #active_attributes do
+ if options.headerAttributes and #active_attributes[header_level] > 0 then
+ table.insert(buf, "\\markdownRendererHeaderAttributeContextBegin")
+ end
+ end
self.is_writing = true
end
- if identifiers[slice_end_identifier] ~= nil
- and slice_end_type == "^" then
- self.is_writing = false
- end
- table.insert(active_headings, identifiers)
- if not self.is_writing then return "" end
+ if self.is_writing then
+ table.sort(attributes)
+ local key, value
+ for i = 1, #attributes do
+ if attributes[i]:sub(1, 1) == "#" then
+ table.insert(buf, {"\\markdownRendererAttributeIdentifier{",
+ attributes[i]:sub(2), "}"})
+ elseif attributes[i]:sub(1, 1) == "." then
+ table.insert(buf, {"\\markdownRendererAttributeClassName{",
+ attributes[i]:sub(2), "}"})
+ else
+ key, value = attributes[i]:match("(%w+)=(%w+)")
+ table.insert(buf, {"\\markdownRendererAttributeKeyValue{",
+ key, "}{", value, "}"})
+ end
+ end
+ end
local cmd
level = level + options.shiftHeadings
@@ -2741,7 +2819,11 @@ function M.writer.new(options)
else
cmd = ""
end
- return {cmd,"{",s,"}"}
+ if self.is_writing then
+ table.insert(buf, {cmd, "{", s, "}"})
+ end
+
+ return buf
end
function self.note(s)
return {"\\markdownRendererFootnote{",s,"}"}
@@ -2758,7 +2840,7 @@ function M.writer.new(options)
function self.get_state()
return {
is_writing=self.is_writing,
- active_headings={table.unpack(self.active_headings)},
+ active_attributes={table.unpack(self.active_attributes)},
}
end
function self.set_state(s)
@@ -2920,12 +3002,12 @@ parsers.css_identifier = (parsers.hash + parsers.period)
* (parsers.css_identifier_char
- parsers.digit)
* parsers.css_identifier_char^0))
-parsers.attribute_name_char = parsers.any - parsers.space
+parsers.attribute_key_char = parsers.any - parsers.space
- parsers.squote - parsers.dquote
- parsers.more - parsers.slash
- parsers.equal
-parsers.attribute_value_char = parsers.any - parsers.dquote
- - parsers.more
+parsers.attribute_value_char = parsers.any - parsers.space
+ - parsers.dquote - parsers.more
-- block followed by 0 or more optionally
-- indented blocks with first line indented.
@@ -3375,11 +3457,6 @@ end
parsers.in_matched_block_tags = parsers.less
* Cmt(#parsers.openelt_block, parse_matched_tags)
-parsers.displayhtml = parsers.htmlcomment / ""
- + parsers.emptyelt_block
- + parsers.openelt_exact("hr")
- + parsers.in_matched_block_tags
- + parsers.htmlinstruction
parsers.hexentity = parsers.ampersand * parsers.hash * S("Xx")
* C(parsers.hexdigit^1) * parsers.semicolon
parsers.decentity = parsers.ampersand * parsers.hash
@@ -3446,7 +3523,7 @@ parsers.defstart = ( parsers.defstartchar * #parsers.spacing
parsers.dlchunk = Cs(parsers.line * (parsers.indentedline - parsers.blankline)^0)
parsers.heading_attribute = C(parsers.css_identifier)
- + C((parsers.attribute_name_char
+ + C((parsers.attribute_key_char
- parsers.rbrace)^1
* parsers.equal
* (parsers.attribute_value_char
@@ -3845,6 +3922,14 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline
"mailto:"..email)
end
+ larsers.AutoLinkRelativeReference
+ = parsers.less
+ * C(parsers.urlchar^1)
+ * parsers.more
+ / function(url)
+ return writer.link(writer.escape(url), url)
+ end
+
larsers.DirectLink = (parsers.tag / parse_inlines_no_link) -- no links inside links
* parsers.spnl
* parsers.lparent
@@ -3901,12 +3986,12 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline
larsers.EscapedChar = parsers.backslash * C(parsers.escapable) / writer.string
- larsers.InlineHtml = parsers.emptyelt_any
+ larsers.InlineHtml = parsers.emptyelt_any / writer.inline_html_tag
+ (parsers.htmlcomment / parse_inlines_no_html)
/ writer.inline_html_comment
+ parsers.htmlinstruction
- + parsers.openelt_any
- + parsers.closeelt_any
+ + parsers.openelt_any / writer.inline_html_tag
+ + parsers.closeelt_any / writer.inline_html_tag
larsers.HtmlEntity = parsers.hexentity / entities.hex_entity / writer.string
+ parsers.decentity / entities.dec_entity / writer.string
@@ -3916,7 +4001,12 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline
* parsers.contentblock_tail
/ writer.contentblock
- larsers.DisplayHtml = parsers.displayhtml
+ larsers.DisplayHtml = (parsers.htmlcomment / parse_blocks)
+ / writer.block_html_comment
+ + parsers.emptyelt_block / writer.block_html_element
+ + parsers.openelt_exact("hr") / writer.block_html_element
+ + parsers.in_matched_block_tags / writer.block_html_element
+ + parsers.htmlinstruction
larsers.Verbatim = Cs( (parsers.blanklines
* ((parsers.indentedline - parsers.blankline))^1)^1
@@ -4180,6 +4270,7 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline
+ V("Code")
+ V("AutoLinkUrl")
+ V("AutoLinkEmail")
+ + V("AutoLinkRelativeReference")
+ V("InlineHtml")
+ V("HtmlEntity")
+ V("EscapedChar")
@@ -4200,6 +4291,7 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline
+ V("Code")
+ V("AutoLinkUrl")
+ V("AutoLinkEmail")
+ + V("AutoLinkRelativeReference")
+ V("InlineHtml")
+ V("HtmlEntity")
+ V("EscapedChar")
@@ -4221,6 +4313,8 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline
Code = larsers.Code,
AutoLinkUrl = larsers.AutoLinkUrl,
AutoLinkEmail = larsers.AutoLinkEmail,
+ AutoLinkRelativeReference
+ = larsers.AutoLinkRelativeReference,
InlineHtml = larsers.InlineHtml,
HtmlEntity = larsers.HtmlEntity,
EscapedChar = larsers.EscapedChar,
@@ -4278,6 +4372,10 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline
syntax.Smart = parsers.fail
end
+ if not options.relativeReferences then
+ syntax.AutoLinkRelativeReference = parsers.fail
+ end
+
local blocks_toplevel_t = util.table_copy(syntax)
blocks_toplevel_t.Paragraph = larsers.ToplevelParagraph
larsers.blocks_toplevel = Ct(blocks_toplevel_t)