Introduces scripts/pipeline/, a Mix project that runs as a post-export
transformation pass over content/*.md before Quartz builds the site.
Pipeline (scripts/export.exs phase 3):
- Compiles and loads the Mix project at export time (cached after first run)
- Applies a list of Transform modules sequentially over all .md files
- Only rewrites files that were actually changed
Citations transform (Pipeline.Transforms.Citations):
- Resolves [cite:@key] and bare cite:key syntax produced by ox-hugo/citar
- Resolution chain: Zotero BBT JSON-RPC → BibTeX file → DOI/bare-key fallback
- Zotero probe uses a no-op JSON-RPC call (cayw endpoint blocks indefinitely)
- Zotero resolver fetches PDF attachments via item.attachments, producing
zotero://open-pdf/... links; falls back to zotero://select/library/items/...
- BibTeX resolver parses .bib files with a simple regex parser (no deps)
- DOI resolver is the always-succeeding last resort
Configuration via env vars:
BIBTEX_FILE — path to .bib file for fallback resolution
ZOTERO_URL — Zotero base URL (default: http://localhost:23119)
CITATION_MODE — silent | warn (default) | strict
Adding future transforms requires only implementing Pipeline.Transform
behaviour and appending the module to the transforms list in export.exs.
The fetchData function suffer from a race condition. If the function is
called before the promise finishes, it will result in another pair of
HTTP request. This does not only make the function useless but
Actually, it makes it harmful as the data might be redownloaded twice.
Now fetchData is not a function but rather the promise by itself.
Previous callers are expected to await the variable instead, this
should be not concern as awaiting a promise multiple time in
JavaScript is completely safe.