feat: parse and render markdown frontmatter metadata#13
Merged
Conversation
YAML (---) and TOML (+++) frontmatter blocks at the top of a document are now parsed via pulldown-cmark's metadata extensions and never leak into body content. cat mode renders a single dim line: · metadata · title=…, author=…, tags=[…], … TUI mode shows the same line by default and adds a new `m` key to expand it into an inline key/value box. Disable entirely via `[metadata] show = false` in ~/.termdown/config.toml. Field extraction uses a line-based heuristic (no real YAML/TOML parser); see docs/adr/0001-metadata-block-handling.md for the rationale and rejected alternatives. Drive-by: fix flaky TempMarkdownFile uniqueness in tests/cli.rs by adding a process-local atomic counter — clock granularity alone collided once test parallelism grew. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Folded one-line summary becomes: [metadata · key=value, key=value, …] Truncation now preserves the closing `]` after the ellipsis (`…]`), so the chip never looks unterminated. Both --cat and TUI folded state use the same string. After the metadata block (folded or expanded), emit one blank row so the body element below isn't visually crammed against the chip / inline box. Drive-by: tests/snapshots.rs check_snapshot now sanitizes `/` out of fixture names when composing the temp-file path, so specialized/ fixtures can write their actual output for diffing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The `fixtures/expected/*.ansi` and `fixtures/*.md` patterns only matched top-level files, so the new `fixtures/expected/specialized/*.ansi` snapshots were checked out with CRLF on Windows and the snapshot tests failed. Recurse with `**`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Address review findings on PR #13: - Use a sentinel logical_index (NO_LOGICAL) for metadata visual rows so search-jump and heading navigation no longer mis-resolve a real line 0 to a metadata row; guard ToC highlight and reorder draw()'s is_spacer check so a metadata-only doc can't panic on doc.lines[0]. - Share the folded `[metadata · …]` summary + width-correct truncation via frontmatter::folded_summary so cat and TUI folded state can't drift. - Compute the expanded-box layout in display columns (not char counts) so CJK/wide chars keep the border aligned. - Make `m` a true no-op when `[metadata] show = false`. - Skip empty quoted values (`key: ""`) so they don't render as `key=`. - Correct the malformed fixture's prose: nested keys are lifted to top-level, not skipped; regenerate its golden snapshot. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
---) and TOML (+++) frontmatter blocks at the top of a doc are now parsed viapulldown-cmark's metadata extensions and never leak into body content (the long-standing setext-H2-rasterized-as-PNG bug at the top of any file with frontmatter is gone).--catrenders a single dim summary line:· metadata · title=…, author=…, …(truncated to terminal width).mkey to expand it into an inline key/value box. Default state: folded.~/.termdown/config.toml:showonly gates display.Design
Full rationale, alternatives considered, and rejected designs in
docs/adr/0001-metadata-block-handling.md. Key choices:mkeybinding is new; added to the?help screen.A glossary lives in the new
CONTEXT.mdfor future maintainers.Test plan
make checkclean (fmt, clippy-D warnings, full test suite).fixtures/specialized/:metadata-yaml.md— happy path for YAML.metadata-toml.md— happy path for TOML.metadata-malformed.md— nested + multi-line YAML, exercises the heuristic's edge behavior.metadata-none.md— regression guard: mid-doc---must stay a horizontal rule.fixtures/expected/supported-syntax.ansiupdated (the top-of-doc setext-H2 PNG noise → one dim summary line). Eyeballed the diff.src/frontmatter.rs(empty block, multi-line continuation, value containing:, fallback path).mto expand/collapse. TODO before merge.Drive-by
tests/cli.rs::TempMarkdownFileusedpid + nanosfor uniqueness — with the four new snapshot tests pushing parallelism higher, two test threads occasionally landed on the same nanosecond and shared a filename. Added a process-local atomic counter; flake is gone (5 consecutive cleancargo testruns verified).🤖 Generated with Claude Code