Skip to content

Commit

Permalink
Add pattern_name arg to reader->insert_pattern, update api_version
Browse files Browse the repository at this point in the history
  • Loading branch information
Witiko committed Oct 3, 2022
1 parent 82683cb commit b8e8123
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 31 deletions.
91 changes: 62 additions & 29 deletions markdown.dtx
Original file line number Diff line number Diff line change
Expand Up @@ -1653,12 +1653,17 @@ local walkable_syntax = {
% \begin{markdown}
%
% The \luamref{reader->insert_pattern} method inserts a \acro{peg} pattern into
% the grammar of markdown. The method receives two arguments: a selector string
% in the form `"`\meta{left-hand side terminal symbol} \meta{`before`, `after`,
% or `instead of`} \meta{right-hand side terminal symbol}`"` and a \acro{peg}
% pattarn to insert. For example. if we'd like to insert `pattern` into the
% grammar between the `Inline -> Emph` and `Inline -> Link` rules, we would
% call \luamref{reader->insert_pattern} with `"Inline after Emph"` (or `"Inline
% the grammar of markdown. The method receives two mandatory arguments: a
% selector string in the form `"`\meta{left-hand side terminal symbol}
% \meta{`before`, `after`, or `instead of`} \meta{right-hand side terminal
% symbol}`"` and a \acro{peg} pattern to insert, and an optional third argument
% with a name of the \acro{peg} pattern for debugging purposes (see the
% \Opt{debugExtensions} option). The name does not need to be unique and shall
% not be interpreted by the Markdown package; you can treat it as a comment.
%
% For example. if we'd like to insert `pattern` into the grammar between the
% `Inline -> Emph` and `Inline -> Link` rules, we would call
% \luamref{reader->insert_pattern} with `"Inline after Emph"` (or `"Inline
% before Link"`) and `pattern` as the arguments.
%
% The \luamdef{reader->add_special_character} method adds a new character with
Expand Down Expand Up @@ -4556,7 +4561,7 @@ defaultOptions.eagerCache = true
%
% ``` lua
% local strike_through = {
% api_version = 1,
% api_version = 2,
% grammar_version = 1,
% finalize_grammar = function(reader)
% local nonspacechar = lpeg.P(1) - lpeg.S("\t ")
Expand All @@ -4571,7 +4576,8 @@ defaultOptions.eagerCache = true
% lpeg.V("Inline"), doubletildes, doubletildes
% ) / function(s) return {"\\st{", s, "}"} end
%
% reader.insert_pattern("Inline after Emph", read_strike_through)
% reader.insert_pattern("Inline after Emph", read_strike_through,
% "StrikeThrough")
% reader.add_special_character("/")
% end
% }
Expand All @@ -4590,7 +4596,7 @@ defaultOptions.eagerCache = true
%<*lua>
% \fi
% \begin{macrocode}
metadata.user_extension_api_version = 1
metadata.user_extension_api_version = 2
metadata.grammar_version = 1
% \end{macrocode}
% \iffalse
Expand Down Expand Up @@ -4620,7 +4626,7 @@ Using a text editor, create a text document named `strike-through.lua` with the
following content:
``` lua
local strike_through = {
api_version = 1,
api_version = 2,
grammar_version = 1,
finalize_grammar = function(reader)
local nonspacechar = lpeg.P(1) - lpeg.S("\t ")
Expand All @@ -4635,7 +4641,8 @@ local strike_through = {
lpeg.V("Inline"), doubletildes, doubletildes
) / function(s) return {"\\st{", s, "}"} end

reader.insert_pattern("Inline after Emph", read_strike_through)
reader.insert_pattern("Inline after Emph", read_strike_through,
"StrikeThrough")
reader.add_special_character("/")
end
}
Expand Down Expand Up @@ -17223,6 +17230,20 @@ end
% \par
% \begin{markdown}
%
% The \luamdef{util.encode_json_string} method encodes a string `s` in
% \acro{JSON}.
%
% \end{markdown}
% \begin{macrocode}
function util.encode_json_string(s)
s = s:gsub([[\]], [[\\]])
s = s:gsub([["]], [[\"]])
return [["]] .. s .. [["]]
end
% \end{macrocode}
% \par
% \begin{markdown}
%
% The \luamdef{util.lookup_files} method looks up files with filename `f`
% and returns its path. If the \pkg{kpathsea} library is available, it will
% search for files not only in the current working directory but also in the
Expand Down Expand Up @@ -21602,18 +21623,16 @@ function M.reader.new(writer, options)
% \par
% \begin{markdown}
%
% Define \luamref{reader->insert_pattern} as a function that receives two
% arguments: a selector string in the form `"`\meta{left-hand side terminal
% symbol} \meta{`before`, `after`, or `instead of`} \meta{right-hand side
% terminal symbol}`"` and a \acro{peg} pattarn to insert. The function adds
% the pattern to \luamref{walkable_syntax}`[`*left-hand side terminal
% symbol*`]` before or after *right-hand side terminal symbol*.
% The \luamref{reader->insert_pattern} method adds a pattern to
% \luamref{walkable_syntax}`[`*left-hand side terminal symbol*`]` before,
% instead of, or after a right-hand-side terminal symbol.
%
% \end{markdown}
% \begin{macrocode}
local current_extension_name = nil
self.insert_pattern = function(selector, pattern)
self.insert_pattern = function(selector, pattern, pattern_name)
assert(current_extension_name ~= nil)
assert(pattern_name == nil or type(pattern_name) == "string")
local _, _, lhs, pos, rhs = selector:find("^(%a+)%s+([%a%s]+%a+)%s+(%a+)$")
assert(lhs ~= nil,
[[Expected selector in form "LHS (before|after|instead of) RHS", not "]]
Expand All @@ -21637,7 +21656,7 @@ function M.reader.new(writer, options)
assert(index ~= nil,
[[Rule ]] .. lhs .. [[ -> ]] .. rhs
.. [[ does not exist in markdown grammar]])
local accountable_pattern = { pattern, current_extension_name }
local accountable_pattern = { pattern, current_extension_name, pattern_name }
if pos == "instead of" then
rule[index] = accountable_pattern
else
Expand Down Expand Up @@ -21706,17 +21725,23 @@ function M.reader.new(writer, options)
% \par
% \begin{markdown}
%
% Define \luamref{reader->update_rule} as a function that receives two arguments:
% a left-hand side terminal symbol and a \acro{peg} pattarn. The function
% (re)defines \luamref{walkable_syntax}`[`left-hand side terminal symbol`]` to
% be equal to pattern.
% Define \luamref{reader->update_rule} as a function that receives two
% mandatory arguments: a left-hand side terminal symbol and a \acro{peg}
% pattern, and an optional third argument with a name of the \acro{peg} pattern
% for debugging purposes (see the \Opt{debugExtensions} option). The name does
% not need to be unique and shall not be interpreted by the Markdown
% package; you can treat it as a comment. The function (re)defines
% \luamref{walkable_syntax}`[`left-hand side terminal symbol`]` to be
% equal to pattern.
%
% \end{markdown}
% \begin{macrocode}
self.update_rule = function(rule_name, pattern)
self.update_rule = function(rule_name, pattern, pattern_name)
assert(current_extension_name ~= nil)
assert(pattern_name == nil or type(pattern_name) == "string")
assert(syntax[rule_name] ~= nil,
[[Rule ]] .. rule_name .. [[ -> ... does not exist in markdown grammar]])
local accountable_pattern = { pattern, current_extension_name }
local accountable_pattern = { pattern, current_extension_name, pattern_name }
walkable_syntax[rule_name] = { accountable_pattern }
end
% \end{macrocode}
Expand Down Expand Up @@ -21774,17 +21799,24 @@ function M.reader.new(writer, options)
local output_lines = {"{"}
for lhs_index, lhs in ipairs(sorted_lhs) do
local encoded_lhs = util.encode_json_string(lhs)
table.insert(output_lines, [[ "]] ..encoded_lhs .. [[": []])
table.insert(output_lines, [[ ]] ..encoded_lhs .. [[: []])
local rule = walkable_syntax[lhs]
for rhs_index, rhs in ipairs(rule) do
local human_readable_rhs
if type(rhs) == "string" then
human_readable_rhs = rhs .. [[ (built-in)]]
else
human_readable_rhs = [[Anonymous Pattern (]] .. rhs[2] .. [[)]]
iocal pattern_name
if rhs[3] then
pattern_name = rhs[3]
else
pattern_name = "Anonymous Pattern"
end
local extension_name = rhs[2]
human_readable_rhs = pattern_name .. [[ (]] .. extension_name .. [[)]]
end
local encoded_rhs = util.encode_json_string(human_readable_rhs)
local output_line = [[ "]] .. encoded_rhs .. [["]]
local output_line = [[ ]] .. encoded_rhs
if rhs_index < #rule then
output_line = output_line .. ","
end
Expand Down Expand Up @@ -23546,7 +23578,8 @@ function M.new(options)
.. [[" specifies field "api_version" of type "]]
.. type(user_extension.api_version)
.. [[" but "number" was expected]])
assert(user_extension.api_version == metadata.user_extension_api_version,
assert(user_extension.api_version > 0
and user_extension.api_version <= metadata.user_extension_api_version,
[[User-defined syntax extension "]] .. pathname
.. [[" uses syntax extension API version "]]
.. user_extension.api_version .. [[ but markdown.lua ]]
Expand Down
5 changes: 3 additions & 2 deletions tests/support/strike-through.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
local strike_through = {
api_version = 1,
api_version = 2,
grammar_version = 1,
finalize_grammar = function(reader)
local nonspacechar = lpeg.P(1) - lpeg.S("\t ")
Expand All @@ -14,7 +14,8 @@ local strike_through = {
lpeg.V("Inline"), doubleslashes, doubleslashes
) / function(s) return {"\\markdownRendererStrikeThrough{", s, "}"} end

reader.insert_pattern("Inline after Emph", read_strike_through)
reader.insert_pattern("Inline after Emph", read_strike_through,
"StrikeThrough")
reader.add_special_character("/")
end
}
Expand Down

0 comments on commit b8e8123

Please sign in to comment.