Replies: 1 comment 5 replies
-
Although having the ability to convert a parameterless snippet into a parametric zero-arity snippet without changing the call syntax seems important, the definition syntax for parameterless and parametric snippets can be different. Namely, we might extend the snippet name with a comma-list of all accepted parameters at definition time: \markdownSetupSnippet
{ greet { who } }
{ code = { Hello,~\who! } }
\markdownSetup
{ snippet = greet { who = world } } This allows us to safely use shorthands such as
Furthermore, this also has the following benefits compared to the previous proposal:
|
Beta Was this translation helpful? Give feedback.
-
Rationale
Themes and snippets in the Markdown package for TeX are like modules and functions in conventional programming languages. Users can import snippets from themes and use them to change how YAML and Markdown content is shown on page. For an introduction to themes and snippets, see my article titled Markdown 2.10.0: LaTeX Themes & Snippets, Two Flavors of Comments, and LuaMetaTeX published in TUGboat 42:2. For more information about themes and snippets, see also my work-in-progress article titled Markdown Themes in Practice to appear in TUG 2024 proceedings and in TUGboat.
Unlike functions in conventional programming languages, snippets are zero-arity, i.e. they accept no parameters. The original rationale behind this design decision was that parameters would make snippets more difficult to use for authors and that authors would parametrize snippets indirectly using YAML metadata. While this rationale is still sound, snippets are used not just by authors but also by TeXperts to structure the internal implementation of themes. The latter use case would commonly benefit from the ability to pass parameters to snippets.
Syntax
The body of a snippet may contain control sequences titled
\markdownParameter
⟨parameter name⟩:When a snippet is called, a key–value that maps each ⟨parameter name⟩ to a value can be provided:
\markdownSetup { snippet = greet { who = world } }
The above code expands to snippet
greet
with all control sequences titled\markdownParameterWho
replaced with the text "world".\markdownSetup { code = { Hello,~world! } }
Considered alternatives
I considered using the parameters
#1
,#2
, ...,#9
for the parameters:However, since snippets may contain renderer and function definitions with their own parameters, this would require that all parameter tokens (
#
) in existing snippets are doubled (##
) when the snippets become parametric. Besides breaking backwards-compatibility, lists of parameters also seem less self-documenting and more error-prone compared to key–values.I also considered using any control sequences as parameters, not just those titled
\markdownParameter
⟨parameter name⟩:While this makes snippet definitions less verbose, it is less obvious at a glance which control sequences are parameters. Besides the readability concerns, this also makes it impossible for the Markdown package to automatically determine whether all parameters were provided to a snippet call. Furthermore, while the ability to replace any control sequence may seem useful for patching snippets, this ability falls outside the intended scope of this change.
Examples
Lazy imports
Since version 2.22.0 (2023-04-02), the Markdown package has supported the
import
statement, which imports snippets from themes:\markdownSetup { import = { jdoe / lists = romanNumerals as roman, }, }
The above code imports the snippet
romanNumerals
from themejdoe/lists
immediately. However, since version 3.3.0 (2023-12-30), the Markdown package has supported plain TeX themes that can be loaded at any time, not just in the document preamble. This makes it possible to lazily import a snippet from a theme at the time of first use:\markdownSetupSnippet { roman } { import = jdoe / lists, snippet = jdoe / lists / romanNumerals, }
The above code works but its intention seems unclear without additional comments. With parametric snippets, we can extract it into a higher-order snippet titled
lazy-import
:Then, we might lazily import the snippet
romanNumerals
from the themejdoe/lists
as follows:\markdownSetup { snippet = lazy-import { snippet = romanNumerals, from = jdoe / lists, as = roman, } }
Local snippet calls
In Section 1.1 of Markdown Themes in Practice, I discuss the following design pattern that uses a snippet (here
istqb/common/metadata/provided-by
) locally inside a Markdown element (herejekyllDataSequence
):This design pattern is used in several places and is highly repetitive. Furthermore, the intention of the design pattern seems unclear without additional comments. With parametric snippets, we can extract this design pattern into a higher-order snippet titled
local-call
:Then, we might call the snippet as follows:
\markdownSetup { snippet = local-call { element = jekyllDataSequence, snippet = istqb / common / metadata / provided-by, } }
Beta Was this translation helpful? Give feedback.
All reactions