Skip to content

feat: render guide markdown for human output with termimad#38

Open
jpage-godaddy wants to merge 2 commits into
mainfrom
guide-terminal-wrapping
Open

feat: render guide markdown for human output with termimad#38
jpage-godaddy wants to merge 2 commits into
mainfrom
guide-terminal-wrapping

Conversation

@jpage-godaddy

@jpage-godaddy jpage-godaddy commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

What

Guide bodies were printed to stdout verbatim, so long lines wrapped mid-word at the terminal's column boundary. This renders the human output format (the default when stdout is a TTY) through termimad, reflowing prose to the terminal width at word boundaries.

  • Human/TTY: colored skin at the live terminal width.
  • Piped --human (non-TTY): plain, no-color skin at width 80, so output is deterministic.
  • --output json / --output toon: unchanged — raw markdown body, byte-for-byte identical to the source. This keeps machine-readable output stable and left every existing guide test green.
  • Topic list (guide with no topic): stays plain text (it is not markdown).
  • Invalid --output (e.g. yaml) is now rejected with InvalidOutputFormat, matching normal commands, instead of silently emitting raw content. (added during review)

Key changes

  • src/guide.rs — new public render_guide_human(content, width, color) (documented; unit-tested for word-boundary wrapping and no-ANSI determinism).
  • src/cli.rsrender_guide now takes the resolved output format, validates it, and reflows only a resolved topic body under human.
  • Cargo.toml / Cargo.lock — add termimad = "0.34.1".
  • docs/concepts.md — guide-authoring best practices (one line per paragraph, code in fenced blocks, prefer * bullets) plus a Known issues note on the numbered-list limitation.
  • tests/foundation.rs — integration test: --human reflows a long line (≤80 cols, no ANSI, no split words) while --output json stays raw and invalid --output is rejected. The TTY-dependent assertions are skipped when stdout is a terminal, so the test is stable under -- --nocapture.

Known limitation

termimad's parser (minimad) only recognizes * bullets as list items; ordered 1. lists and -/+ bullets render as plain paragraphs, so their wrapped continuations don't hang-indent. Documented with a workaround and filed upstream: Canop/termimad#75.

Verification

cargo fmt --all --check · cargo clippy --all-targets -- -D warnings · RUSTDOCFLAGS='-D warnings' cargo doc --no-deps · cargo test --all-targets · cargo test --doc · cargo rustdoc --lib -- -W missing-docs (0 missing) — all pass.

🤖 Generated with Claude Code

Guide bodies were printed verbatim, so long lines wrapped mid-word at the
terminal boundary. Render the human/TTY format through termimad, wrapping
prose to the terminal width at word boundaries (colored skin + live width on
a TTY; plain skin + width 80 when piped, so output stays deterministic).

json/toon keep returning the raw markdown body unchanged, so machine-readable
output is byte-for-byte identical to the source and existing tests are
unaffected. The topic list stays plain text.

Also document guide-authoring best practices in docs/concepts.md (one line
per paragraph, code in fenced blocks, prefer `* ` bullets) and note the
upstream numbered-list limitation (Canop/termimad#75).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the readability of embedded guide content in human/TTY output by rendering guide markdown through termimad, enabling word-boundary wrapping to the terminal width while keeping machine-readable outputs (json/toon) byte-for-byte stable.

Changes:

  • Added render_guide_human(content, width, color) to render guide markdown for human output via termimad.
  • Updated guide rendering in the CLI so only --output human topic bodies are reflowed; json/toon remain raw markdown.
  • Added documentation and tests covering guide authoring expectations and human reflow behavior.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/guide.rs Introduces render_guide_human and unit tests for wrapping behavior.
src/cli.rs Routes guide output through the human renderer only for human topic output.
tests/foundation.rs Adds an integration test asserting human reflow behavior and raw json stability.
docs/concepts.md Documents guide rendering behavior and authoring guidelines/limitations.
Cargo.toml Adds the termimad dependency.
Cargo.lock Locks the new dependency and transitive additions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/cli.rs
Comment thread src/guide.rs Outdated
Comment thread docs/concepts.md Outdated
Comment thread tests/foundation.rs
Comment thread tests/foundation.rs
- Validate an explicit --output for the guide command, matching render_root
  and the normal command path, instead of silently emitting raw content for an
  unrecognized format.
- Make render_guide_human rustdoc precise: words wrap at boundaries, but a
  token longer than the width can still overflow.
- Avoid a literal triple-backtick sequence in docs/concepts.md prose.
- Make the human-reflow integration test robust when run attached to a TTY
  (e.g. with --nocapture) by gating the no-color/fixed-width assertions on a
  non-terminal stdout; add coverage for the invalid --output rejection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated no new comments.

@jpage-godaddy

Copy link
Copy Markdown
Collaborator Author

Samples of what's changed:

Before:
markdown-before

After:
markdown-after

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants