Plugins

Other pages
Table of contents

Plugins:

List of built-in plugins

...for importing

For example, this /plugins page uses these two patterns for each plugin on the page:

Note: Major text editors (including VSCode), without any extensions, will consider the (…) part to be the src of an Image node, so they will helpfully provide link-autocompletion when writing and link-following when command-clicking.

Note: when used in zip2zip mode, these import-* plugins can load files from your input/source zip without having to leave the WASM sandbox or incur any more FS latency.

PluginDescription
import-markdown

Import contents via !![](./foo.md), or a section thereof via …#some-section, optionally filtering further — e.g. to the first paragraph or first EGC in that section.

import-code

Import via !![](../src/foo.py), as a CodeBlock, optionally filtering further — e.g. to #someFunction or line range #L32-L48.

🚧import-usda-from-usdz

Import a USDZ file's scene graph (or subtree(s) thereof) as a usda CodeBlock via usdcat: !![](foo.usdz#/foo/bar):usdcat.

This plugin requires authz to run usdcat.

...for code

PluginDescription
syntax-highlighting

Add syntax highlighting to some CodeBlock and/or CodeInline elements, eventually including semantic highlighting via a language server, or via plugin config where you can have a case-sensitive set of names always be considered to be classes.

🚧codeinline-info-string

e.g. `{}`:json → (lang="json", meta=None)

Additionally:

:var → have the end result be a <var>, not a <code>

:kbd → convert a text-editor-config-style keyboard shortcut representation to web standards, with nested <kbd> elements

`\cap`:math → same as $\cap$ with math

...for external rendering

(these require authz beyond the WASM sandbox)

PluginDescription
🚧render-image-iiif

Using some external IIIF tool/server, render image clips using IIIF Image API syntax (for region, size, rotation, quality, and format), e.g.
![](./….png#IIIF/pct:…/…/…/….png)

render-code

For each code element (CodeBlock/CodeInline) do you want the page to display the code, the result of running/rendering the code, or both? You can define defaults for each language, and you can override them in a specific code element's info string.

e.g. mermaid result, to render a diagram from Mermaid code, and show the result but not the code

e.g. py result, to run your Python code and show only the result.

e.g. py code is the same as just saying py.

e.g. py code <-> ast, to show your code and its AST side-by-side, with various cross-linked helpfulness (e.g. highlighting and descriptions) if you hover or click on either side.

e.g. py code <-> result, to show your code and its result side-by-side.

e.g. py code ; result, to show your code as a block, above a different block for its result.

e.g. py ▶︎code ; result, for the same thing but with the code wrapped in a (details, summary) that is collapsed by default.

🚧render-from-section

e.g. create an Image element with ![](#foo) or ![](./_diagrams.md#bar), referencing a section which contains a single CodeBlock, e.g. with something like Mermaid code, Excalidraw JSON, or Lilypond code.

This is helpful when you want the invocation to be concise and the implementation to be elsewhere.

🚧render-preview-img

Add an og:image social media thumbnail rendered from a section of code, as with render-from-section.

...for language extensions

PluginDescription
🚧footnotes

Footnote syntax: [^foo], [^foo]: …

🚧math

Use LaTeX via $…$ or $`…`$ for inlines, $$…$$ for blocks. These get pre-rendered and styled via KaTeX by default, leading to zero client-side JavaScript being required. This syntax matches GitHub's, and is syntactic sugar for a CodeInline/CodeBlock where lang=math. See also: codeinline-info-string.

This requires authz to run KaTeX outside the WASM sandbox.

details-summary-from-section

Wrap a section with a <details> /<summary> pair simply by adding a suffix to the end of its Heading line of Markdown.

The <summary> element will contain the corresponding H1-6 heading element, with the same id attribute (or lack thereof) that the Heading node would have led to without this plugin being involved.

See also:

...for metadata

title-and-description

e.g. you can compute title via the first H1 and description via the first paragraph. These can then be published via <title>, meta description, meta og:title, and meta og:description tags.

🚧signatures

Validate and embed already-externally-computed signatures of your doc's Markdown and/or article-HTML in your HTML page (GPG, Nostr, etc).

license-notices

Easily ensure that subsets of your pages are licensed a certain way, both with metadata and with a visible notice. For example, you could ensure that your /blog/* web pages are released under CC BY-NC-ND 4.0 and your other documents and diagrams are CC BY-SA 4.0.

🚧full-semantic-annotation

For maximum document quality, you can fully annotate your sentences.

If your readers do not completely understand the syntax and semantics of any part of a sentence, they should be able to expand a view of the sentence to see its parse tree, along with links to what each term means and any additional context that you have attached to that sentence.

These should come from actual annotation, not from a mistake-prone computational-linguistics guess. (Though computational linguistics could eventually assist in the process of creating the annotation.)

With reader-driven annotation-assisted variable-levels-of-explanatoriness, your sentences can simply contain an "anacrusis" or "bijection" without an "(i.e., …verbose explanation…)" block, and your readers can easily find their way to today's lucky 10,000 as needed.

...for other web stuff

PluginDescription
🚧mdx-subset

A subset of functionality from the MDX project.

🚧assets

Hash-suffixing, mounting at /assets/, SRI, etc.

page-template

Add page headers / page footers / head elements, via config strings and/or .html files in your docset.

🚧include-comments

By default, comments in your Markdown code are not included as HTML comments. This plugin lets you override that in some cases.

css-overrides-within-doc

To add CSS overrides that are specific to the current page, you can create a CodeBlock:css at the end of your Markdown file in a section with a specific name.

sitemap-xml

Automatically render a /sitemap.xml file for search engines, optionally including a comment for each URL with a hash of its content.

...for social

PluginDescription
rss

Render RSS XML for your posts, for one or more blog levels.

See also:

...for Unicode

...where "some patterns" means "some custom subsets of code points and/or EGCs:

PluginDescription
🚧unicode-autolink

Automatically link some patterns to custom URLs, e.g. linking 𝐙 (MATHEMATICAL BOLD CAPITAL Z) to enwiki:Integer.

🚧unicode-autoclass

Automatically add classes to the HTML for some patterns, e.g. so you can add custom styling.

...for validation / static analysis

🚧validate-internal-links


➞ Validate that the destination file (1) exists in this docset and (2) is part of the current docset edition

➞ Validate that "URL Scroll-To-Text Fragment" / "URL Fragment Text Directives" links connect to the destination's words

➞ Validate that other fragments connect to exactly one of the destination's section ids

🚧validate-external-links


➞ Validate that your docset's external link targets are (or were recently) valid, either by HTTP-requesting them or by validating that your docset has them within sufficiently-recent WARC files.

➞ Validate that "URL Scroll-To-Text Fragment" / "URL Fragment Text Directives" links connect to the destination's words.

➞ Validate that other fragments connect to exactly one of the destination's section ids.

If you opt for HTTP, authz is required.

🚧validate-placeholders

Configure this plugin as an additional guardrail in your workflow, re: placeholders.

For example, you could ensure that any occurence of the string TODO is also referenced in a nearby comment which authorizes it to go to prod.

You could also have that policy apply to command-line mm zip2zip builds, but not apply to live preview.


Asset hash validation (both for SRI attributes and for filename suffixes) will probably be part of the assets plugin.

...for tables of contents / search indexes

PluginDescription
🚧tables-of-contents

Automatically generate/update/validate tables of contents and other reader-visible indexes.

See also: polyfill-page-outline

🚧search-indexes

Generate simple index files for the searchable content of your docset, and they can be automatically published with hash-suffixed filenames along with the rest of your assets.

...for polyfilling various things that I wish browsers already had available for JavaScript-less use

PluginDescription
🚧polyfill-page-outline

Provide some basic (and CSS-style-able) UI/UX for having a concise outline float on the side of your documents.

🚧polyfill-range-input-functionality

Opinion: a range input (<input type="range" />) ought be able to update the value of a CSS variable while being adjusted.

This will pair well with CSS math functions, making a larger subset of interactive diagrams possible without any JavaScript.

(Note: many JS-less interactive diagrams are already possible with existing and standard-draft CSS and HTML — thanks, :hover, :active, :target, :target-within, [foo^="bar"], combinators, :checked, <map>, <area>, et al!)

🚧polyfill-search-ux

Provide a search bar with basic UI/UX.

If the web browser has JavaScript enabled, use polyfill-searching-clientside and preload an index file that was generated by search-indexes.

If not, this could still take you to /search?q= via <form method="GET" action="/search">, if your server has server-side search available.

🚧polyfill-searching-clientside

Very-basic client-side docset-wide search, using a simple search index file from search-indexes.



Ideally, you shouldn't need any JavaScript to publish your writings with a full UX.

The world wide web should let browsers be browsers and documents be documents.


Web-standards-proposal lens?

I have not been involved with the exploration/creation side of web standards proposals before, but I want to learn more about it and look at these polyfills from that lens.

These probably won't end up as standards proposals. But it'll at least be an interesting lens to use, and I want to learn more about the web standards world in general.

I might merge-request some of these for one of the indie browsers like Ladybird.



Authz beyond the WASM sandbox

While building your docset with zip2zip, a few of the plugins by the very nature of their value prop need to make build-time HTTP requests and/or run command-line tools and pass your input files to them. ⚠️😱‼️

This cannot be granted via config JSON

Like all plugins, these are off by default.

But unlike the fully-sandboxed plugins, these plugins CANNOT be activated simply by e.g. naming them inside a config JSON file inside the input zip. Activating them needs to occur via other channels, and with property names that are so verbose and explicit that it is not easy to authorize the sandbox breach without having at least some level of understanding of the security implications.

How the access happens

These plugins still run within the WASM blob, but they ask the blob's outer wrapper to do things on their behalf, e.g. make HTTP requests or run subprocesses.

The outer blob will only do so if authorized via tightly-scoped authorization, e.g.:

When creating plugins in Python, these three correspond to:

c.assetFromExternalRequest(…) → AssetRef
c.assetFromExternalSubproc(…) → AssetRef
c.assetFromExternalRender(…) → AssetRef