Themeable Markdown to HTML Studio for VS Code.
md-hinagata is a VS Code extension and Rust-powered transformation engine for turning Markdown into theme-controlled HTML. It is designed for people who want to write content in Markdown, choose an output theme from frontmatter, edit the theme templates, preview the result, and copy the generated HTML fragment.
2026-05-26.1.41.57.mov
md-hinagata is not just another Markdown previewer. Its core purpose is to control the final HTML structure.
Markdown + frontmatter + theme templates
-> Rust transform core
-> structured HTML fragment
-> preview / copy / exportmd-hinagata is in early 0.x.x development.
The current VS Code extension line is 0.1.x pre-release. The next release
target is 0.2.0, the first stable Marketplace release.
The implemented core flow is:
Write Markdown
-> select a theme with frontmatter
-> inspect the theme in the left sidebar
-> edit templates with VS Code
-> preview themed HTML
-> copy generated HTMLDuring 0.x.x, the theme schema, frontmatter schema, template variables, and Rust API may change.
Most Markdown tools focus on one of these goals:
- Render Markdown as a preview.
- Generate a full static site.
- Manage CMS content.
- Convert Markdown to many output formats.
md-hinagata focuses on a narrower problem:
Convert Markdown blocks into predictable, theme-controlled HTML components.
For example, this Markdown:
## Notice
This action cannot be undone.can become this HTML, depending on the selected theme:
<h2 id="notice" class="article-heading article-heading--level2">
Notice
</h2>
<p class="article-body">
This action cannot be undone.
</p>The theme is not only CSS. A theme is a package of templates, styles, metadata, and output rules.
hinagata.output: fragment produces an HTML fragment. By default, when a
resolved theme provides entryCss, the generated HTML includes that CSS in a
<style> tag followed by the themed document root and rendered Markdown
content.
The Preview webview renders the same generated HTML that md-hinagata: Copy Generated HTML copies. Preview does not apply theme CSS through a separate Preview-only path.
hinagata.cssMode controls how theme CSS is represented in the generated HTML.
The frontmatter value is the source of truth:
| Mode | Output |
|---|---|
style-tag |
Includes theme CSS in a <style> tag before the document root. This is the default. |
inline |
Expands supported theme CSS into style attributes and omits separate CSS. |
separate |
Returns document HTML and keeps CSS separate for callers that need it. |
none |
Returns document HTML without theme CSS. |
A Markdown file chooses its theme through frontmatter:
---
hinagata:
theme: default
output: fragment
---
# Title
Body text.This keeps the output reproducible. The document itself knows how it should be transformed.
The current draft frontmatter JSON Schema is tracked at schemas/frontmatter.schema.json. The VS Code extension offers completions for hinagata keys inside leading Markdown frontmatter; hinagata.theme values come from the same selectable theme set as md-hinagata: Select Theme.
A theme is a directory such as:
.md-hinagata/
themes/
company-blog/
theme.json
styles.css
templates/
h1.hbs
h2.hbs
h3.hbs
p.hbs
codeblock.hbs
blockquote.hbs
ul.hbs
ol.hbs
li.hbsA theme.json file describes the theme:
{
"$schema": "https://raw.githubusercontent.com/shm11C3/md-hinagata/main/schemas/theme.schema.json",
"schemaVersion": "0.1",
"id": "company-blog",
"name": "Company Blog",
"version": "1.0.0",
"entryCss": "styles.css",
"templates": {
"h1": "templates/h1.hbs",
"h2": "templates/h2.hbs",
"h3": "templates/h3.hbs",
"p": "templates/p.hbs",
"codeblock": "templates/codeblock.hbs",
"blockquote": "templates/blockquote.hbs",
"ul": "templates/ul.hbs",
"ol": "templates/ol.hbs",
"li": "templates/li.hbs"
}
}The current draft theme JSON Schema is tracked at schemas/theme.schema.json.
Templates keep the .hbs file extension for theme compatibility, but the
supported syntax is md-hinagata Template Interpolation, not full Handlebars.
Use {{name}} for escaped known values and allowlisted {{{name}}} for
generated HTML such as inner_html. Helpers, partials, conditionals, loops,
unknown variables, and non-allowlisted raw insertions are template render
errors and fall back to built-in element rendering. See the detailed
specification in docs/template-interpolation.md.
Existing custom .hbs themes that relied on Handlebars leniency should be
updated because those unsupported constructs now fall back for the whole
element.
Example templates/h2.hbs:
Example templates/codeblock.hbs:
Supported interpolation examples:
{{text}}
Escaped plain text.
{{{inner_html}}}
HTML generated from Markdown children.
{{code}}
Escaped code text.- VS Code extension.
- Standard VS Code Markdown editor.
- Frontmatter-based theme selection with
hinagata.theme. - Left sidebar Theme Manager.
- Right-side themed preview Webview.
- Rust transform core compiled to WASM.
- Editable
.hbstheme templates using Template Interpolation. - Bundled
defaulttheme. - Workspace themes under
.md-hinagata/themes/{themeId}. - Create Theme from Default command.
- Preview updates when Markdown changes.
- Preview updates when theme files are saved.
- Copy Generated HTML command.
- Basic diagnostics for unknown themes and missing templates.
- CSS output modes through
hinagata.cssMode.
Markdown block support:
h1
h2
h3
p
codeblock
blockquote
ul
ol
liNot included:
- WYSIWYG editing.
- CLI.
- Theme package import/export.
.hinagata-themepackages.- Table support.
- Image and link template support.
- Advanced syntax highlighting.
- Preview element to template jump.
- Left-sidebar code editor.
The left sidebar is a Theme Manager and Inspector. Template files are opened in the normal VS Code editor, so editing, diff, search, formatting, and Git workflow stay native to VS Code.
Theme resolution order:
1. workspace/.md-hinagata/themes/{themeId}, in trusted workspaces
2. bundled themes/{themeId}In untrusted workspaces, workspace theme loading is disabled while bundled themes, preview, and copy behavior remain available.
Top-level structure:
md-hinagata/
package.json
pnpm-workspace.yaml
Cargo.toml
README.md
README.ja.md
apps/
vscode-extension/
crates/
md-hinagata-core/
md-hinagata-wasm/
themes/
default/
examples/
basic/
schemas/
docs/Prerequisites:
- Node.js 22 or 24 with
pnpm10.x. - Rust toolchain with Cargo.
wasm-bindgenCLI0.2.121for WASM bridge builds.
Install JavaScript workspace dependencies:
pnpm installCheck the Rust workspace:
cargo check --workspaceInstall the WASM bridge CLI when building the Rust bridge for the extension:
cargo install wasm-bindgen-cli --version 0.2.121 --lockedRun the current workspace checks:
pnpm run check
pnpm run format
pnpm run lint
pnpm run testpnpm run format formats both the VS Code extension and Rust workspace. pnpm run lint runs Biome for the extension, then verifies Rust formatting and Clippy warnings.
Build the VS Code extension bundle:
pnpm run buildBuild the WASM bridge and copy the generated module into the VS Code extension:
pnpm run build:wasmThe generated WASM files are written to apps/vscode-extension/wasm/ and are not committed.
Run the VS Code Extension Host E2E smoke test:
pnpm run test:e2eThis copies examples/basic into a temporary workspace, launches VS Code with
the local extension, verifies the contributed commands, and runs Preview, Copy
Generated HTML, and Create Theme from Default against sample.md. On Linux CI
this command runs under xvfb.
Open the repository root in VS Code, then press F5 or choose Run md-hinagata Extension from Run and Debug.
The launch configuration starts an Extension Development Host from apps/vscode-extension and runs the md-hinagata: build extension task before launch. This builds the extension bundle without packaging a VSIX.
To exercise the Rust/WASM transform path with the bundled example, choose Run md-hinagata Extension (Basic Example) from Run and Debug. This opens examples/basic as the Extension Development Host workspace, opens sample.md, and runs the md-hinagata: prepare basic example task before launch, so the workspace theme at .md-hinagata/themes/basic is available.
In the Extension Development Host:
- Confirm
sample.mdis active when using the basic example launch configuration. - Confirm the
md-hinagataActivity Bar container and Theme Manager view are visible. - Run
md-hinagata: Open Previewfrom the Command Palette. - Compare the generated HTML, including theme CSS, with
expected.html. - Confirm
md-hinagata: Copy Generated HTMLandmd-hinagata: Select Themeappear in the Command Palette.
The Rust core is not used for editing. VS Code already handles editing well.
Rust is used for the transformation engine:
- Markdown and frontmatter parsing.
- Theme template rendering.
- HTML generation.
- Diagnostics.
- Future CLI and CI integration.
- Future batch export.
The VS Code extension should handle VS Code-specific work. The Rust core should remain editor-independent.
VS Code extension:
read files
manage webviews
update frontmatter
resolve workspace paths
Rust core:
receive Markdown and theme packages
generate HTML
return diagnosticsmd-hinagata handles Markdown, HTML, CSS, and templates, so security is part of the design.
Current defaults:
- Raw HTML is disabled by default.
- Workspace themes are allowed only in trusted workspaces.
- Webview CSP is required.
- Webview local resource access is restricted to extension-controlled resources.
- Preview HTML is rendered in a VS Code Webview rather than a general browser page.
Stable release hardening and theme authoring improvements.
- Stabilize CSS output modes.
- Improve theme validation and diagnostics.
- Improve JSON Schema integration.
- Improve workspace theme authoring.
- Improve README, examples, and Marketplace metadata.
Tooling and export.
- CLI.
- CI validation.
- Batch export.
- Open Generated HTML.
- Full HTML export.
- Table support.
- Theme package import/export.
.hinagata-themepackage format.- Syntax highlighting.
- Link, image support.
- Preview element to template jump.
- Desktop app.
md-hinagata is licensed under your choice of either:
Unless otherwise noted, code, bundled themes, and examples are licensed under MIT OR Apache-2.0. User-authored content and generated HTML are not claimed by the tool license. See Licensing for scope details.