summaryrefslogtreecommitdiff
path: root/macros/generic/markdown/markdown.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/generic/markdown/markdown.dtx')
-rw-r--r--macros/generic/markdown/markdown.dtx344
1 files changed, 197 insertions, 147 deletions
diff --git a/macros/generic/markdown/markdown.dtx b/macros/generic/markdown/markdown.dtx
index da5159498c..0434cf5be6 100644
--- a/macros/generic/markdown/markdown.dtx
+++ b/macros/generic/markdown/markdown.dtx
@@ -1051,7 +1051,10 @@ local lpeg = require("lpeg")
%
% \end{markdown}
% \begin{macrocode}
-local ran_ok, unicode = pcall(require, "unicode")
+local unicode
+(function()
+ local ran_ok
+ ran_ok, unicode = pcall(require, "unicode")
% \end{macrocode}
% \begin{markdown}
%
@@ -1060,9 +1063,10 @@ local ran_ok, unicode = pcall(require, "unicode")
%
% \end{markdown}
% \begin{macrocode}
-if not ran_ok then
- unicode = {["utf8"]={char=utf8.char}}
-end
+ if not ran_ok then
+ unicode = {["utf8"]={char=utf8.char}}
+ end
+end)()
% \end{macrocode}
% \par
% \begin{markdown}
@@ -1178,34 +1182,8 @@ local md5 = require("md5")
%</latex-themes-witiko-dot,latex-themes-witiko-graphicx-http,latex-themes-witiko-tilde>
% \fi
% \begin{markdown}
-% a \TeX{} engine that extends \Hologo{eTeX}, all the plain \TeX{}
-% prerequisites (see Section <#sec:texprerequisites>), and the following
-% \Hologo{LaTeX2e} packages:
-%
-% \pkg{keyval}
-%
-%: A package that enables the creation of parameter sets. This package is
-% used to provide the \mref{markdownSetup} macro, the package options
-% processing, as well as the parameters of the \envmref{markdown*} \LaTeX{}
-% environment.
-%
-% \end{markdown}
-% \begin{macrocode}
-\RequirePackage{keyval}
-% \end{macrocode}
-% \par
-% \begin{markdown}
-%
-% \pkg{xstring}
-%
-%: A package that provides useful macros for manipulating strings of tokens.
-%
-% \end{markdown}
-% \begin{macrocode}
-\RequirePackage{xstring}
-% \end{macrocode}
-% \par
-% \begin{markdown}
+% a \TeX{} engine that extends \Hologo{eTeX}, and all the plain \TeX{}
+% prerequisites (see Section <#sec:texprerequisites>):
%
% The following packages are soft prerequisites. They are only used to provide
% default token renderer prototypes (see sections
@@ -2061,8 +2039,7 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces.
{
\tl_set:Nn
\l_tmpa_tl
-% TODO: Replace with \str_uppercase:n in TeX Live 2020.
- { \str_upper_case:n { #1 } }
+ { \str_uppercase:n { #1 } }
\tl_set:Nx
#2
{
@@ -7826,7 +7803,7 @@ defaultOptions.underscores = true
% \end{figure}
% \begin{macrocode}
-HELP_STRING = [[
+local HELP_STRING = [[
Usage: texlua ]] .. arg[0] .. [[ [OPTIONS] -- [INPUT_FILE] [OUTPUT_FILE]
where OPTIONS are documented in the Lua interface section of the
technical Markdown package documentation.
@@ -7838,7 +7815,7 @@ result of the conversion will be read from the standard input.
Report bugs to: witiko@mail.muni.cz
Markdown package home page: <https://github.com/witiko/markdown>]]
-VERSION_STRING = [[
+local VERSION_STRING = [[
markdown-cli.lua (Markdown) ]] .. metadata.version .. [[
Copyright (C) ]] .. table.concat(metadata.copyright,
@@ -7879,14 +7856,14 @@ for i = 1, #arg do
% \end{markdown}
% \begin{macrocode}
elseif arg[i]:match("=") then
- key, value = arg[i]:match("(.-)=(.*)")
+ local key, value = arg[i]:match("(.-)=(.*)")
% \end{macrocode}
% \begin{markdown}
% The \luamref{defaultOptions} table is consulted to identify whether \meta{value}
% should be parsed as a string or as a boolean.
% \end{markdown}
% \begin{macrocode}
- default_type = type(defaultOptions[key])
+ local default_type = type(defaultOptions[key])
if default_type == "boolean" then
options[key] = (value == "true")
elseif default_type == "number" then
@@ -14308,8 +14285,7 @@ following text:
{
\tl_set:Nn
\l_tmpa_tl
-% TODO: Replace with \str_uppercase:n in TeX Live 2020.
- { \str_upper_case:n { #1 } }
+ { \str_uppercase:n { #1 } }
\tl_set:Nx
#2
{
@@ -14651,8 +14627,16 @@ pdflatex --shell-escape document.tex
%
% \markdownEnd
% \begin{macrocode}
-\newcommand\markdownSetup[1]{%
- \setkeys{markdownOptions}{#1}}%
+\ExplSyntaxOn
+\cs_new:Nn
+ \@@_setup:n
+ {
+ \keys_set:nn
+ { markdown/latex-options }
+ { #1 }
+ }
+\let\markdownSetup=\@@_setup:n
+\ExplSyntaxOff
% \end{macrocode}
% \begin{markdown}
%
@@ -14873,16 +14857,35 @@ would use the following code in the preamble of your document:
\newif\ifmarkdownLaTeXLoaded
\markdownLaTeXLoadedfalse
\AtEndOfPackage{\markdownLaTeXLoadedtrue}
-\define@key{markdownOptions}{theme}{%
- \IfSubStr{#1}{/}{}{%
- \markdownError
- {Won't load theme with unqualified name #1}%
- {Theme names must contain at least one forward slash}}%
- \StrSubstitute{#1}{/}{_}[\markdownLaTeXThemePackageName]%
- \edef\markdownLaTeXThemePackageName{%
- markdowntheme\markdownLaTeXThemePackageName}%
- \expandafter\markdownLaTeXThemeLoad\expandafter{%
- \markdownLaTeXThemePackageName}{#1/}}%
+\ExplSyntaxOn
+\tl_new:N \markdownLaTeXThemePackageName
+\cs_new:Nn
+ \@@_set_latex_theme:n
+ {
+ \str_if_in:NnF
+ { #1 }
+ { / }
+ {
+ \markdownError
+ { Won't load theme with unqualified name #1 }
+ { Theme names must contain at least one forward slash }
+ }
+ \tl_set:Nn \markdownLaTeXThemePackageName { #1 }
+ \str_replace_all:Nnn
+ \markdownLaTeXThemePackageName
+ { / }
+ { _ }
+ \edef\markdownLaTeXThemePackageName{
+ markdowntheme\markdownLaTeXThemePackageName}
+ \expandafter\markdownLaTeXThemeLoad\expandafter{
+ \markdownLaTeXThemePackageName}{#1/}
+ }
+\keys_define:nn
+ { markdown/latex-options }
+ {
+ theme .code:n = { \@@_set_latex_theme:n { #1 } },
+ }
+\ExplSyntaxOff
% \end{macrocode}
% \begin{markdown}
%
@@ -14910,7 +14913,10 @@ beginning of a \LaTeX{} document.
%<*latex>
% \fi
% \begin{macrocode}
-\@onlypreamble\KV@markdownOptions@theme
+\ExplSyntaxOn
+\@onlypreamble
+ \@@_set_latex_theme:n
+\ExplSyntaxOff
% \end{macrocode}
% \iffalse
%</latex>
@@ -15201,18 +15207,24 @@ various options locally.
%<*latex>
% \fi
% \begin{macrocode}
-\define@key{markdownOptions}{snippet}{%
- \markdownIfSnippetExists{#1}%
- {%
- \expandafter\markdownSetup\expandafter{%
- \the\csname markdownLaTeXSetupSnippet%
- \markdownLaTeXThemeName#1\endcsname}%
- }{%
- \markdownError
- {Can't invoke setup snippet #1}%
- {The setup snippet is undefined}%
- }%
- }%
+\ExplSyntaxOn
+\keys_define:nn
+ { markdown/latex-options }
+ {
+ snippet .code:n = {
+ \markdownIfSnippetExists{#1}
+ {
+ \expandafter\markdownSetup\expandafter{
+ \the\csname markdownLaTeXSetupSnippet
+ \markdownLaTeXThemeName#1\endcsname}
+ }{
+ \markdownError
+ {Can't~invoke~setup~snippet~#1}
+ {The~setup~snippet~is~undefined}
+ }
+ }
+ }
+\ExplSyntaxOff
% \end{macrocode}
% \iffalse
%</latex>
@@ -15298,28 +15310,23 @@ The following ordered list will be preceded by roman numerals:
{ g_@@_ #1 _option_types_prop }
{ #2 }
\l_tmpa_tl
- \str_if_eq:VVTF
- \l_tmpa_tl
- \c_@@_option_type_boolean_tl
+ \keys_define:nn
+ { markdown/latex-options }
{
- \define@key
- { markdownOptions }
- { #2 }
- [ true ]
- {
- \@@_set_option_value:nn
- { #2 }
- { ##1 }
- }
+ #2 .code:n = {
+ \@@_set_option_value:nn
+ { #2 }
+ { ##1 }
+ },
}
+ \str_if_eq:VVT
+ \l_tmpa_tl
+ \c_@@_option_type_boolean_tl
{
- \define@key
- { markdownOptions }
- { #2 }
+ \keys_define:nn
+ { markdown/latex-options }
{
- \@@_set_option_value:nn
- { #2 }
- { ##1 }
+ #2 .default:n = { true },
}
}
}
@@ -15405,8 +15412,7 @@ The following ordered list will be preceded by roman numerals:
{
\tl_set:Nn
\l_tmpa_tl
-% TODO: Replace with \str_uppercase:n in TeX Live 2020.
- { \str_upper_case:n { #1 } }
+ { \str_uppercase:n { #1 } }
\tl_set:Nx
#2
{
@@ -15417,15 +15423,16 @@ The following ordered list will be preceded by roman numerals:
}
\cs_new:Nn \@@_latex_define_renderer:nNn
{
- \define@key
- { markdownRenderers }
- { #1 }
+ \keys_define:nn
+ { markdown/latex-options/renderers }
{
- \cs_generate_from_arg_count:NNnn
- #2
- \cs_set:Npn
- { #3 }
- { ##1 }
+ #1 .code:n = {
+ \cs_generate_from_arg_count:NNnn
+ #2
+ \cs_set:Npn
+ { #3 }
+ { ##1 }
+ },
}
}
\cs_generate_variant:Nn
@@ -15480,15 +15487,16 @@ The following ordered list will be preceded by roman numerals:
}
\cs_new:Nn \@@_latex_define_renderer_prototype:nNn
{
- \define@key
- { markdownRendererPrototypes }
- { #1 }
+ \keys_define:nn
+ { markdown/latex-options/renderer-prototypes }
{
- \cs_generate_from_arg_count:NNnn
- #2
- \cs_set:Npn
- { #3 }
- { ##1 }
+ #1 .code:n = {
+ \cs_generate_from_arg_count:NNnn
+ #2
+ \cs_set:Npn
+ { #3 }
+ { ##1 }
+ },
}
}
\cs_generate_variant:Nn
@@ -15662,7 +15670,6 @@ texexec --passon=--shell-escape document.tex
% \begin{macrocode}
local upper, gsub, format, length =
string.upper, string.gsub, string.format, string.len
-local concat = table.concat
local P, R, S, V, C, Cg, Cb, Cmt, Cc, Ct, B, Cs, any =
lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Cg, lpeg.Cb,
lpeg.Cmt, lpeg.Cc, lpeg.Ct, lpeg.B, lpeg.Cs, lpeg.P(1)
@@ -15709,7 +15716,7 @@ function util.cache(dir, string, salt, transform, suffix)
local name = util.pathname(dir, digest .. suffix)
local file = io.open(name, "r")
if file == nil then -- If no cache entry exists, then create a new one.
- local file = assert(io.open(name, "w"),
+ file = assert(io.open(name, "w"),
[[could not open file "]] .. name .. [[" for writing]])
local result = string
if transform ~= nil then
@@ -18879,9 +18886,7 @@ parsers.spacing = S(" \n\r\t")
parsers.nonspacechar = parsers.any - parsers.spacing
parsers.optionalspace = parsers.spacechar^0
-parsers.specialchar = S("*_`&[]<!\\.@-^")
-
-parsers.normalchar = parsers.any - (parsers.specialchar
+parsers.normalchar = parsers.any - (V("SpecialChar")
+ parsers.spacing
+ parsers.tightblocksep)
parsers.eof = -parsers.any
@@ -19052,7 +19057,7 @@ parsers.unticked_box = tickbox(parsers.spacechar^1) * Cc(0.0)
% \begin{macrocode}
parsers.openticks = Cg(parsers.backtick^1, "ticks")
-local function captures_equal_length(s,i,a,b)
+local function captures_equal_length(_,i,a,b)
return #a == #b and i
end
@@ -19075,7 +19080,7 @@ parsers.inticks = parsers.openticks * parsers.space^-1
%
% \end{markdown}
% \begin{macrocode}
-local function captures_geq_length(s,i,a,b)
+local function captures_geq_length(_,i,a,b)
return #a >= #b and i
end
@@ -19100,10 +19105,10 @@ end
parsers.fencedline = function(char)
return C(parsers.line - parsers.fencetail(char))
/ function(s)
- i = 1
- remaining = fenceindent
+ local i = 1
+ local remaining = fenceindent
while true do
- c = s:sub(i, i)
+ local c = s:sub(i, i)
if c == " " and remaining > 0 then
remaining = remaining - 1
i = i + 1
@@ -19486,7 +19491,7 @@ function M.reader.new(writer, options, extensions)
% \end{markdown}
% \begin{macrocode}
local function iterlines(s, f)
- rope = lpeg.match(Ct((parsers.line / f)^1), s)
+ local rope = lpeg.match(Ct((parsers.line / f)^1), s)
return util.rope_to_string(rope)
end
% \end{macrocode}
@@ -19546,7 +19551,7 @@ function M.reader.new(writer, options, extensions)
return line
end
line = util.expand_tabs_in_line(line)
- prefix = lpeg.match(C(parsers.optionalspace), line)
+ local prefix = lpeg.match(C(parsers.optionalspace), line)
local prefix_length = #prefix
local is_shorter = min_prefix_length == nil
is_shorter = is_shorter or prefix_length < min_prefix_length
@@ -19750,7 +19755,7 @@ function M.reader.new(writer, options, extensions)
parsers.Str = (parsers.normalchar * (parsers.normalchar + parsers.at)^0)
/ writer.string
- parsers.Symbol = (parsers.specialchar - parsers.tightblocksep)
+ parsers.Symbol = (V("SpecialChar") - parsers.tightblocksep)
/ writer.string
parsers.Ellipsis = P("...") / writer.ellipsis
@@ -20184,8 +20189,24 @@ function M.reader.new(writer, options, extensions)
EscapedChar = parsers.EscapedChar,
Smart = parsers.Smart,
Symbol = parsers.Symbol,
+ SpecialChar = parsers.fail,
}
-
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% Define a hash table of all characters with a special meaning that can be
+% escaped and add method `reader->add_special_character` that extends the
+% hash table and updates the \acro{peg} grammar.
+%
+% \end{markdown}
+% \begin{macrocode}
+ local special_characters = {"*", "`", "[", "]", "<", "!", "\\"}
+ self.add_special_character = function(c)
+ table.insert(special_characters, c)
+ self.syntax.SpecialChar = S(table.concat(special_characters, ""))
+ end
+ self.syntax.SpecialChar = S(table.concat(special_characters, ""))
% \end{macrocode}
% \par
% \begin{markdown}
@@ -20199,6 +20220,10 @@ function M.reader.new(writer, options, extensions)
extension.extend_reader(self)
end
+ if options.underscores then
+ self.add_special_character("_")
+ end
+
if not options.codeSpans then
self.syntax.Code = parsers.fail
end
@@ -20207,6 +20232,8 @@ function M.reader.new(writer, options, extensions)
self.syntax.DisplayHtml = parsers.fail
self.syntax.InlineHtml = parsers.fail
self.syntax.HtmlEntity = parsers.fail
+ else
+ self.add_special_character("&")
end
if options.preserveTabs then
@@ -20215,6 +20242,8 @@ function M.reader.new(writer, options, extensions)
if not options.smartEllipses then
self.syntax.Smart = parsers.fail
+ else
+ self.add_special_character(".")
end
if not options.relativeReferences then
@@ -20542,6 +20571,9 @@ M.extensions.citations = function(citation_nbsps)
local Citations = TextCitations + ParenthesizedCitations
syntax.Citations = Citations
+
+ self.add_special_character("@")
+ self.add_special_character("-")
end
}
end
@@ -20584,15 +20616,15 @@ M.extensions.content_blocks = function(language_map)
% \end{markdown}
% \begin{macrocode}
else
- kpse = {lookup=function(filename, options) return filename end}
+ kpse = {lookup=function(filename, _) return filename end}
end
local base, prev, curr
for _, filename in ipairs{kpse.lookup(language_map, { all=true })} do
local file = io.open(filename, "r")
if not file then goto continue end
- json = file:read("*all"):gsub('("[^\n]-"):','[%1]=')
+ local json = file:read("*all"):gsub('("[^\n]-"):','[%1]=')
curr = (function()
- local _ENV={ json=json, load=load } -- run in sandbox
+ local _ENV={ json=json, load=load } -- luacheck: ignore _ENV
return load("return "..json)()
end)()
if type(curr) == "table" then
@@ -20794,7 +20826,7 @@ M.extensions.definition_lists = function(tight_lists)
local dlchunk = Cs(parsers.line * (parsers.indentedline - parsers.blankline)^0)
- local function definition_list_item(term, defs, tight)
+ local function definition_list_item(term, defs, _)
return { term = self.parser_functions.parse_inlines(term),
definitions = defs }
end
@@ -20859,7 +20891,7 @@ M.extensions.fenced_code = function(blank_before_code_fence)
local syntax = self.syntax
local writer = self.writer
- local function captures_geq_length(s,i,a,b)
+ local function captures_geq_length(_,i,a,b)
return #a >= #b and i
end
@@ -20884,10 +20916,10 @@ M.extensions.fenced_code = function(blank_before_code_fence)
local fencedline = function(char)
return C(parsers.line - fencetail(char))
/ function(s)
- i = 1
- remaining = fenceindent
+ local i = 1
+ local remaining = fenceindent
while true do
- c = s:sub(i, i)
+ local c = s:sub(i, i)
if c == " " and remaining > 0 then
remaining = remaining - 1
i = i + 1
@@ -20921,6 +20953,7 @@ M.extensions.fenced_code = function(blank_before_code_fence)
syntax.FencedCode = FencedCode
+ local fencestart
if blank_before_code_fence then
fencestart = parsers.fail
else
@@ -21016,6 +21049,8 @@ M.extensions.footnotes = function(footnotes, inline_footnotes)
/ writer.note
syntax.InlineNote = InlineNote
end
+
+ self.add_special_character("^")
end
}
end
@@ -21031,7 +21066,7 @@ end
% \begin{macrocode}
M.extensions.header_attributes = function()
return {
- extend_writer = function(self)
+ extend_writer = function()
end, extend_reader = function(self)
local parsers = self.parsers
local syntax = self.syntax
@@ -21202,9 +21237,9 @@ M.extensions.jekyll_data = function(expect_jekyll_data)
local JekyllData
= Cmt( C((parsers.line - P("---") - P("..."))^0)
- , function(s, i, text)
+ , function(s, i, text) -- luacheck: ignore s i
local data
- local ran_ok, error = pcall(function()
+ local ran_ok, _ = pcall(function()
local tinyyaml = require("markdown-tinyyaml")
data = tinyyaml.parse(text, {timestamps=false})
end)
@@ -21433,50 +21468,50 @@ function M.new(options)
%
% \end{markdown}
% \begin{macrocode}
- extensions = {}
+ local extensions = {}
if options.citations then
- citations_extension = M.extensions.citations(options.citationNbsps)
+ local citations_extension = M.extensions.citations(options.citationNbsps)
table.insert(extensions, citations_extension)
end
if options.contentBlocks then
- content_blocks_extension = M.extensions.content_blocks(
+ local content_blocks_extension = M.extensions.content_blocks(
options.contentBlocksLanguageMap)
table.insert(extensions, content_blocks_extension)
end
if options.definitionLists then
- definition_lists_extension = M.extensions.definition_lists(
+ local definition_lists_extension = M.extensions.definition_lists(
options.tightLists)
table.insert(extensions, definition_lists_extension)
end
if options.fencedCode then
- fenced_code_extension = M.extensions.fenced_code(
+ local fenced_code_extension = M.extensions.fenced_code(
options.blankBeforeCodeFence)
table.insert(extensions, fenced_code_extension)
end
if options.footnotes or options.inlineFootnotes then
- footnotes_extension = M.extensions.footnotes(
+ local footnotes_extension = M.extensions.footnotes(
options.footnotes, options.inlineFootnotes)
table.insert(extensions, footnotes_extension)
end
if options.headerAttributes then
- header_attributes_extension = M.extensions.header_attributes()
+ local header_attributes_extension = M.extensions.header_attributes()
table.insert(extensions, header_attributes_extension)
end
if options.jekyllData then
- jekyll_data_extension = M.extensions.jekyll_data(
+ local jekyll_data_extension = M.extensions.jekyll_data(
options.expectJekyllData)
table.insert(extensions, jekyll_data_extension)
end
if options.pipeTables then
- pipe_tables_extension = M.extensions.pipe_tables(
+ local pipe_tables_extension = M.extensions.pipe_tables(
options.tableCaptions)
table.insert(extensions, pipe_tables_extension)
end
@@ -22545,12 +22580,10 @@ end
print(convert(input:gsub("\r\n?", "\n") .. "\n"))}%
% \end{macrocode}
% \begin{markdown}
-% If we are finalizing the frozen cache, increment \Opt{frozenCacheCounter}.
+% In case we were finalizing the frozen cache, increment \Opt{frozenCacheCounter}.
% \end{markdown}
% \begin{macrocode}
- |markdownIfOption{finalizeCache}{%
- |global|advance|markdownOptionFrozenCacheCounter by 1|relax
- }%
+ |global|advance|markdownOptionFrozenCacheCounter by 1|relax
}%
|endgroup
}%
@@ -22947,13 +22980,23 @@ end
%
% \end{markdown}
% \begin{macrocode}
-\define@key{markdownOptions}{renderers}{%
- \setkeys{markdownRenderers}{#1}%
- \def\KV@prefix{KV@markdownOptions@}}%
-\define@key{markdownOptions}{rendererPrototypes}{%
- \setkeys{markdownRendererPrototypes}{#1}%
- \def\KV@prefix{KV@markdownOptions@}}%
-\define@key{markdownOptions}{code}{#1}%
+\ExplSyntaxOn
+\keys_define:nn
+ { markdown/latex-options }
+ {
+ renderers .code:n = {
+ \keys_set:nn
+ { markdown/latex-options/renderers }
+ { #1 }
+ },
+ rendererPrototypes .code:n = {
+ \keys_set:nn
+ { markdown/latex-options/renderer-prototypes }
+ { #1 }
+ },
+ code .code:n = { #1 },
+ }
+\ExplSyntaxOff
% \end{macrocode}
% \par
% \begin{markdown}
@@ -23178,8 +23221,15 @@ end
%
% \end{markdown}
% \begin{macrocode}
+\ExplSyntaxOn
\def\markdownLATEXStrongEmphasis#1{%
- \IfSubStr\f@series{b}{\textnormal{#1}}{\textbf{#1}}}
+ \str_if_in:NnTF
+ \f@series
+ { b }
+ { \textnormal{#1} }
+ { \textbf{#1} }
+}
+\ExplSyntaxOff
\markdownSetup{rendererPrototypes={strongEmphasis={%
\protect\markdownLATEXStrongEmphasis{#1}}}}
% \end{macrocode}