blogs/CONTENT_BRIDGE.md
Neeldhara Misra 58310e1944
Some checks are pending
Build / build (push) Waiting to run
Add semantic block parser and PDF export
2026-06-25 12:35:40 +05:30

9.3 KiB

Blog Content Bridge

The public Obsidian vault is the writing source of truth. The Astro sites are deployable targets that receive copied Markdown and assets.

Folder Map

Vault folder Astro content folder Public domain
blogs/01-research sites/research/src/content/research https://research.neeldhara.blog
blogs/02-vibes sites/vibes/src/content/vibes https://vibes.neeldhara.blog
blogs/03-puzzles sites/puzzles/src/content/puzzles https://puzzles.neeldhara.blog
blogs/04-reflections sites/reflections/src/content/reflections https://reflections.neeldhara.blog
blogs/05-poetry sites/poetry/src/content/poetry https://poetry.neeldhara.blog
blogs/06-reviews sites/reviews/src/content/reviews https://reviews.neeldhara.blog
blogs/07-art sites/art/src/content/art https://art.neeldhara.blog
blogs/micro ../micro/src/content/blog https://micro.neeldhara.blog

The installed Obsidian plugin lives at:

/Users/neeldhara/obsidian/public/.obsidian/plugins/microblog-sync

The versioned copy lives in this repo at:

obsidian-plugin/microblog-sync

The plugin id remains microblog-sync, but Obsidian shows it as Blog Family Sync.

Post Layout

Use one folder per post:

blogs/01-research/example-post/index.md
blogs/01-research/example-post/diagram.png

The folder path becomes the public URL:

blogs/01-research/example-post/index.md
https://research.neeldhara.blog/example-post/

Nested folders are supported:

blogs/04-reflections/exportober/2021/index.md
https://reflections.neeldhara.blog/exportober/2021/

Frontmatter

Every public post needs the fields required by the Astro content schema:

---
title: "Post title"
description: "One or two sentence summary for cards and RSS."
pubDate: "2024-05-10"
authorName: "Neeldhara"
---

Optional fields currently understood by the sites include updatedDate, image, and authorImage. Prefer colocated images in the body over remote stock images.

Use main-feature: true on at most one post per blog to pin a fixed featured post on the neeldhara.blog homepage. The homepage still shows the two newest non-featured posts for that blog, sorted by pubDate.

The Quarto import also preserved sourceCategories and sourcePath. Astro strips unknown schema fields, but they are useful in Obsidian for provenance.

Markdown Conventions

Standard Markdown headings, lists, links, tables, code fences, footnotes, and raw HTML are preserved.

Use colocated relative assets:

![Caption](image.png)

Quarto image attributes such as {width=70%} were removed during import. Going forward, use normal Markdown and let Astro CSS handle presentation.

Quarto callouts were converted to portable blockquotes:

> **Note**
>
> Text of the callout.

Use the same convention for new notes:

> **Warning**
>
> This point needs attention.

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:

```{.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:

sites/<blog>/src/interactives/tape-layout/index.tsx

The component receives:

{
  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="...":

```{.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:

```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:

```{.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:

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:

\begin{theorem}[Hall's theorem]
\label{thm:hall}
...
\end{theorem}

Astro also accepts shorter forms when PDF export is not needed:

```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:

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:

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:

scripts/import-quarto-blog.mjs

It reads the Quarto archive, skips draft: true, converts index.qmd to index.md, copies colocated assets, and writes a temporary tree under /private/tmp/quarto-blog-import.

The first import made these category choices:

Blog Rule of thumb
research CS/math exposition, lecture notes, and academic explainers.
vibes LLM-assisted making, interactives, and generated-tool experiments.
puzzles Puzzle/game/problem posts.
reflections Essays, speeches, teaching/career notes, and Exportober context.
poetry Poems.
reviews Tool, workflow, software, website, book-list, and tutorial posts.
art Visual/sketchnote/design/communications-oriented posts.

See IMPORT_REPORT.md for the specific source-to-destination mapping.

Sync Rules

  • Obsidian is the source of truth for day-to-day writing.
  • Auto-sync copies changes from the matching blogs/... folder into the matching local Astro content folder.
  • The plugin includes Markdown plus common web assets: images, PDFs, JSON/YAML, JS, CSS, HTML, and text files.
  • One-way sync does not delete target files unless Delete orphaned target files is enabled.
  • The initial Quarto import used replace-style sync to clear placeholder Astro posts. Day-to-day editing should use the plugin.

Preview And Publish

Use these Obsidian commands:

  • Blog Family Sync: Sync and preview current note
  • Blog Family Sync: Publish current note
  • Blog Family Sync: Publish all changes for current blog

Preview detects the current note's folder, starts the matching Astro dev server on its configured local port, and opens the post URL.

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:

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.