SEP 64: Redesign shortcodes
PENDING:
-
Implement
@val
,@import
,@aside
,@terminal/shell/command
-
Finish migrating all instances of old
link::
andslug:
syntax (slug is now@val($uid.slug)
) - Remove last of the legacy substitution code
- Ultimately I would love to get rid of all regex based substitution schemes and instead parse my documents into an AST and then walk the tree, altering nodes directly, but I’m a ways away from that yet.
I want a better design for the shortcodes I use throughout the site.
The current “design” is captured in the regexes used to extract them:
REF_LINK_RE = re.compile(r"!?\[([^\]]*?)\](\((.*?::)([^)]+)\))")
REF_SLUG_RE = re.compile(r"(?<!`)(/bored)([a-zA-Z0-9]*)((?:#[^)\s]*)?)")
REF_TITLE_RE = re.compile(r"(\{\{ *)(title::)([a-zA-Z0-9]*)( *(?:#[^}]*)?)( *\}\})")
REF_CITE_RE = re.compile(r"(\{\{ *)(cite::)([a-zA-Z0-9]*)( *(?:#[^}]*)?)( *\}\})")
REF_IMPT_RE = re.compile(
r"(\{\{ *)((?:aside|import)::)([a-zA-Z0-9]*)( *(?:#[^}]*)?)( *\}\})"
)
text = page.content.get("plain")
if text:
text = replace_import_references(text, REF_IMPT_RE, merged_data, key, page)
text = replace_cite_references(text, REF_CITE_RE, merged_data)
text = replace_title_references(text, REF_TITLE_RE, merged_data)
text = replace_slug_references(text, REF_SLUG_RE, merged_data)
text = process_reference_links(text, REF_LINK_RE, merged_data, key)
page.content["plain"] = text.strip()
For example, quote::$UID
would be replaced with a quote embed of the provided uid.
I want a design that generalises better, provides more legibility and extensibility, and has support for parameters.
TLDR: @keyword(option="value")
or something similar.
Core Idea: A single sigil, @, initiates a “function” with a clear name and parameters.
Syntax & Examples:
-
The Function Call: @command(id, …) or @command{…}
-
Links: @link(a1b2c3d4, text=”Custom Text”, fragment=”…“)
- Could use positional params for brevity: @link(a1b2c3d4, “Custom Text”)
-
Images/Media:
- @img(a1b2c3d4, alt=”…“)
- @video(a1b2c3d4)
-
Inline Data: A dedicated command to retrieve values.
- The title is @val(a1b2c3d4.title).
- Find it at @val(a1b2c3d4.slug).
-
Formatted Content & Transclusion: Each has a clear, named command.
- @cite(a1b2c3d4)
- @quote(a1b2c3d4)
- @import(a1b2c3d4)
- @aside(a1b2c3d4)
- @gallery{ @img(b2c3d4e5) @img(f6g7h8i9) } (Block-form for wrapping content)
- Key/value parameters. Positional arguments can be more terse, but like short-opts (vs long-opts) they are less legible and they bake in assumptions. A key/value system is more verbose but removes ambiguity and makes changing defaults, and adding or deprecating arguments much safer.
- There should be a syntax for escaping/skipping a shortcode, when I want the actual shortcode to remain in a document.