YAML front-matter handling, default theme option, and code block UI enhancement#20
YAML front-matter handling, default theme option, and code block UI enhancement#20Al3cLee wants to merge 3 commits into
Conversation
- default_theme ("dark"|"light"): controls the initial theme the browser
preview loads with, replacing the previously hardcoded dark mode.
The value is injected into index.html at server start via the existing
__BOTTOM_PADDING__ substitution pattern.
- hide_yaml (bool, default false): when false, YAML front-matter is
displayed in a collapsible <details> panel at the top of the preview
(above the document content). The panel shows the raw YAML in a styled
code block and preserves its open/closed state across live reloads.
Set to true to suppress the panel entirely.
Both options are wired through setup() and require no server changes.
The markdown-it-front-matter package on jsDelivr only ships a CommonJS build (module.exports = ...) with no UMD wrapper, so loading it via <script> tag never exposes window.markdownItFrontMatter. The plugin registration guard was always false, lastFrontMatter was never set, and the panel never appeared. Fix: remove the broken <script> CDN tag and inline an equivalent front-matter block rule directly inside the ES module script. The inlined rule correctly extracts the YAML between --- delimiters and sets lastFrontMatter synchronously during md.render(), which sync() reads immediately after to show/hide the panel. Also reset lastFrontMatter to null before each md.render() so that removing front-matter from a file correctly hides the panel.
The lang badge and copy button were positioned absolute inside <pre>, which has overflow-x: auto. This made them scroll horizontally with the code content instead of staying fixed at the top-right corner. Fix: wrap each <pre> in a <div class="code-wrap"> that holds position: relative. The <pre> itself only keeps overflow-x: auto. Badge and button are absolute children of the wrapper, so they are anchored to the visible viewport of the block regardless of horizontal scroll position. The ::before pseudo-element lang badge (which cannot be independently positioned relative to a parent) is replaced with a real <span class="code-lang"> DOM element injected by attachCopyButtons(). All copy-button CSS selectors are re-scoped from pre to .code-wrap.
|
Hey @Al3cLee, all three of these are good changes, and the CJS-build diagnosis for Before merging, could you split this into two PRs? Each change has a different review surface and any one of them could need a revert independently. PR A: frontmatter panel (
PR B: sticky lang badge and copy button on wide code blocks
The theme part can be dropped. PR #16 lands first with the same feature, and the author is renaming the key to On the frontmatter UX itself: collapsible raw YAML is fine for v1. Most modern tools (Obsidian, VSCode + markdown-yaml-preamble) use a structured key/value table, and I'd like to add that as Happy to do the split for you if it's easier. Let me know. |
|
Hello @selimacerbas , thank you for the detailed feedback; please split this PR yourself if that's okay! |
Summary
I identified some UI related small issues and fixed them with Claude:
Three independent improvements to the browser preview, all confined to
assets/index.htmlandlua/markdown_preview/init.lua. No server logic was changed.These have been all tested on Neovim v0.12.2.
1. YAML front-matter collapsible panel (
hide_yaml)YAML front-matter was previously shown as ordinary contents the preview. It is now displayed as a collapsible
<details>panel at the top of the page, above the document content, below the "markdown preview" UI banner.Behaviour:
▶ Front matterlabel to expand it and see the raw YAML in a code block.hide_yaml = trueinsetup()to suppress the panel entirely; you will not even see the collapsible panel.Configuration:
Implementation note:
markdown-it-front-matteron jsDelivr only ships a CommonJS build with no UMD/global wrapper, so the existing<script>CDN tag silently did nothing (window.markdownItFrontMatterwas alwaysundefined). The plugin was replaced with an equivalent block rule inlined directly inside the ES module script.2. Configurable default theme (
default_theme)The browser preview previously always opened in dark mode (hardcoded). The initial theme is now configurable.
Configuration:
The value is injected into
index.htmlat server start via the same placeholder substitution pattern used forbottom_padding. The in-browser theme toggle button continues to work regardless of the configured default.3. Sticky lang badge and copy button on wide code blocks
When a code block's content was wider than the viewport and the user scrolled it horizontally, the language badge and copy button scrolled off with the content. They now stay fixed at the top-right corner of the visible block.
Root cause:
<pre>had bothposition: relativeandoverflow-x: auto. Absolutely-positioned children are anchored to the element's scrollable content area, not its visible viewport.Fix: Each
<pre>is now wrapped in a<div class="code-wrap">that carriesposition: relative. The<pre>itself retains onlyoverflow-x: auto. The badge and copy button are children of the wrapper, so they are always anchored to the visible corner of the block regardless of horizontal scroll position.The
::beforepseudo-element lang badge (which cannot be independently re-parented) was replaced with a real<span class="code-lang">DOM element injected by the existingattachCopyButtons()function.Files changed
lua/markdown_preview/init.luadefault_themeandhide_yamlconfig keys; two new placeholder substitutions inwrite_indexassets/index.html__DEFAULT_THEME__/__HIDE_YAML__placeholders;.code-wrapwrapper CSS + JS refactor ofattachCopyButtons