Add semantic block parser and PDF export
Some checks are pending
Build / build (push) Waiting to run
Some checks are pending
Build / build (push) Waiting to run
This commit is contained in:
parent
632543db4d
commit
58310e1944
47 changed files with 3078 additions and 0 deletions
|
|
@ -114,6 +114,129 @@ Quarto margin notes such as `[text]{.aside}` were converted to:
|
|||
> **Aside:** text
|
||||
```
|
||||
|
||||
## Semantic Blocks
|
||||
|
||||
Use Pandoc-style fenced attributes for blocks that need to render differently
|
||||
in HTML and PDF. This is the preferred form because it works cleanly with both
|
||||
Astro and Pandoc/LuaLaTeX.
|
||||
|
||||
### Interactive Blocks
|
||||
|
||||
An interactive block reserves a place in the post for a React component and
|
||||
also supplies fallback text for PDF or non-JavaScript rendering:
|
||||
|
||||
````markdown
|
||||
```{.interactive #int:tape-layout caption="Tape layout explorer"}
|
||||
Drag files along a tape and compare the access cost of each arrangement.
|
||||
```
|
||||
````
|
||||
|
||||
The id after `#` is the semantic label. For interactives, use the `int:` prefix.
|
||||
The component id is inferred by removing that prefix, so the example above
|
||||
mounts this component when it exists:
|
||||
|
||||
```text
|
||||
sites/<blog>/src/interactives/tape-layout/index.tsx
|
||||
```
|
||||
|
||||
The component receives:
|
||||
|
||||
```ts
|
||||
{
|
||||
id: "tape-layout",
|
||||
label: "int:tape-layout",
|
||||
caption: "Tape layout explorer",
|
||||
description: "Drag files along a tape...",
|
||||
fallback: "Drag files along a tape...",
|
||||
attrs: { caption: "Tape layout explorer" }
|
||||
}
|
||||
```
|
||||
|
||||
If the component is not present, Astro renders the fallback text in the
|
||||
interactive frame. For a different PDF fallback, add `pdf="..."`:
|
||||
|
||||
````markdown
|
||||
```{.interactive #int:tape-layout caption="Tape layout explorer" pdf="The HTML version contains an interactive tape layout explorer."}
|
||||
Implementation notes for the interactive can go here.
|
||||
```
|
||||
````
|
||||
|
||||
Astro also accepts the shorter Obsidian-friendly form:
|
||||
|
||||
````markdown
|
||||
```interactive id="tape-layout" caption="Tape layout explorer"
|
||||
Drag files along a tape and compare the access cost.
|
||||
```
|
||||
````
|
||||
|
||||
Use the Pandoc-style form for posts that should export to PDF.
|
||||
|
||||
### LaTeX-Style Environments
|
||||
|
||||
Use `.env` plus the environment class and a label:
|
||||
|
||||
````markdown
|
||||
```{.env .theorem #thm:hall title="Hall's theorem" html="callout"}
|
||||
Every bipartite graph satisfying Hall's condition has a matching that covers
|
||||
the left side.
|
||||
```
|
||||
````
|
||||
|
||||
Supported environment types are:
|
||||
|
||||
```text
|
||||
theorem, lemma, proposition, corollary, definition, example, remark, proof
|
||||
```
|
||||
|
||||
In Astro, `html="callout"` renders the block like a callout. `html="plain"`
|
||||
renders it as a quieter left-rule block. If `html` is omitted, theorem-like
|
||||
blocks default to `callout`, and `proof` defaults to `plain`.
|
||||
|
||||
In PDF, the same block becomes a real LuaLaTeX environment:
|
||||
|
||||
```tex
|
||||
\begin{theorem}[Hall's theorem]
|
||||
\label{thm:hall}
|
||||
...
|
||||
\end{theorem}
|
||||
```
|
||||
|
||||
Astro also accepts shorter forms when PDF export is not needed:
|
||||
|
||||
````markdown
|
||||
```theorem id="thm:hall" title="Hall's theorem"
|
||||
Every bipartite graph satisfying Hall's condition has a matching...
|
||||
```
|
||||
````
|
||||
|
||||
### Linking To Semantic Blocks
|
||||
|
||||
Use ordinary Markdown links to semantic ids:
|
||||
|
||||
```markdown
|
||||
The proof of [Hall's theorem](#thm:hall) is constructive.
|
||||
See the [tape explorer](#int:tape-layout) for an interactive version.
|
||||
```
|
||||
|
||||
Astro renders these as normal HTML links. The PDF pipeline converts internal
|
||||
links whose target starts with `#` into `\cref{...}`, so the first link above
|
||||
becomes `\cref{thm:hall}`.
|
||||
|
||||
Use these label prefixes consistently:
|
||||
|
||||
```text
|
||||
thm: theorem
|
||||
lem: lemma
|
||||
prop: proposition
|
||||
cor: corollary
|
||||
def: definition
|
||||
ex: example
|
||||
rem: remark
|
||||
prf: proof
|
||||
int: interactive
|
||||
fig: figure
|
||||
```
|
||||
|
||||
## Import Rules
|
||||
|
||||
The import script is:
|
||||
|
|
@ -168,3 +291,23 @@ Publish does three things:
|
|||
1. Sync vault content into the local repo.
|
||||
2. Run the configured Astro build command.
|
||||
3. Commit and push to Forgejo, where Dokploy picks up the change.
|
||||
|
||||
## PDF Export
|
||||
|
||||
PDF export uses Pandoc plus LuaLaTeX:
|
||||
|
||||
```bash
|
||||
npm run pdf:post -- sites/research/src/content/research/example/index.md --out /tmp/example.pdf
|
||||
```
|
||||
|
||||
The command runs:
|
||||
|
||||
- `scripts/pandoc-filters/semantic-blocks.lua` to convert interactive and
|
||||
environment fences.
|
||||
- `scripts/pandoc-templates/semantic-preamble.tex` to load `amsthm`,
|
||||
`cleveref`, and the shared theorem definitions.
|
||||
|
||||
The PDF route is intentionally separate from Astro. Astro owns HTML rendering;
|
||||
Pandoc owns PDF rendering. The Markdown conventions above are the shared
|
||||
contract between both outputs and can be reused for future site families such
|
||||
as `neeldhara.courses` and `books.neeldhara.com`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue