Skip to content

feat: add examples section to markdown and manpage generation#380

Merged
jdx merged 3 commits intomainfrom
test-example-generation
Nov 12, 2025
Merged

feat: add examples section to markdown and manpage generation#380
jdx merged 3 commits intomainfrom
test-example-generation

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Nov 12, 2025

Summary

This PR adds full support for rendering examples in both markdown documentation and manpage generation.

Previously, examples defined in usage specs using the example node were not rendered in:

  • Markdown documentation (single-file or multi-file)
  • Manpage subcommand detail sections

Changes

Core Changes

  • Markdown template: Added Examples section to cmd_template.md.tera that renders example code blocks with optional headers and help text
  • Manpage renderer: Added examples rendering for subcommands in render_subcommand_details() method
  • Test coverage: Created comprehensive tests for both markdown and manpage example generation

Files Changed

  • lib/src/docs/markdown/templates/cmd_template.md.tera - Added Examples section
  • lib/src/docs/manpage/renderer.rs - Added subcommand examples rendering
  • cli/tests/markdown.rs - New test file for markdown generation with examples
  • cli/tests/manpage.rs - Added test for manpage generation with examples
  • examples/with-examples.usage.kdl - New example spec file demonstrating example usage

Test Plan

Created comprehensive tests that verify:

  1. Examples appear in markdown output with correct formatting
  2. Examples appear in manpage output for subcommands
  3. Example headers, help text, and code blocks render correctly
  4. Nested subcommand examples work properly

All tests pass with snapshot testing to ensure consistent output.

Example Output

Markdown

### Examples

**Basic deployment**

Deploy to production environment

\```
demo deploy -e prod
\```

Manpage

\fBExamples:\fR
.PP
\fBBasic deployment\fR
Deploy to production environment
.PP
.RS 4
demo deploy \-e prod
.RE
.PP

🤖 Generated with Claude Code


Note

Add examples rendering to markdown and manpage (including subcommand detail sections), with tests and example spec.

  • Documentation generation:
    • Manpage (lib/src/docs/manpage/renderer.rs):
      • Render EXAMPLES section for root command with spacing/indentation.
      • Include examples in subcommand detail sections; show section when flags, documented args, or examples exist.
    • Markdown (lib/src/docs/markdown/templates/cmd_template.md.tera):
      • Add # Examples section rendering optional headers, help, and fenced code blocks with language.
  • Tests:
    • Add cli/tests/markdown.rs verifying examples in generated markdown and snapshot.
    • Extend cli/tests/manpage.rs with examples test and snapshot.
    • Add snapshots for markdown and manpage outputs.
  • Examples:
    • Add examples/with-examples.usage.kdl demonstrating example usage across commands/subcommands.

Written by Cursor Bugbot for commit 516ddd1. This will update automatically on new commits. Configure here.

Previously, examples defined in usage specs were not rendered in
markdown documentation or in manpage subcommand sections. This commit
adds full support for rendering examples in both formats.

Changes:
- Add Examples section to markdown template (cmd_template.md.tera)
- Add examples rendering for subcommands in manpage generator
- Create comprehensive tests for example generation in both formats
- Add example usage spec file (with-examples.usage.kdl) for testing

Examples now render with:
- Optional header (bold text in markdown, bold in manpage)
- Optional help text description
- Code block with proper formatting and indentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings November 12, 2025 16:32
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

Copilot AI left a comment

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 adds support for rendering examples in both markdown documentation and manpage generation. Previously, examples defined in usage specs were not being displayed in the generated documentation.

Key Changes:

  • Added examples rendering to markdown templates with formatted code blocks, headers, and help text
  • Extended manpage renderer to include examples sections for subcommands
  • Created comprehensive test coverage for both markdown and manpage example generation

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
lib/src/docs/markdown/templates/cmd_template.md.tera Added Examples section template with support for headers, help text, and code blocks
lib/src/docs/manpage/renderer.rs Extended subcommand rendering to include examples with proper roff formatting
examples/with-examples.usage.kdl New example spec demonstrating example feature usage
cli/tests/markdown.rs New test file with comprehensive markdown generation tests
cli/tests/manpage.rs Added test for manpage generation with examples
cli/tests/snapshots/markdown__markdown_snapshot_with_examples.snap Snapshot test output for markdown examples
cli/tests/snapshots/manpage__generate_manpage_with_examples.snap Snapshot test output for manpage examples

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

Comment on lines +337 to +352
if has_examples {
roff.text([bold("Examples:")]);
roff.control("PP", [] as [&str; 0]);
for example in &subcmd.examples {
if let Some(header) = &example.header {
roff.text([bold(header)]);
}
if let Some(help) = &example.help {
roff.text([roman(help.as_str())]);
}
roff.control("PP", [] as [&str; 0]);
roff.control("RS", ["4"]);
roff.text([roman(example.code.as_str())]);
roff.control("RE", [] as [&str; 0]);
roff.control("PP", [] as [&str; 0]);
}
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

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

The conditional check if has_examples is redundant here since it's already checked in the outer condition at line 297. The examples rendering code will only execute when has_examples is true, so this inner check can be removed to simplify the code.

Suggested change
if has_examples {
roff.text([bold("Examples:")]);
roff.control("PP", [] as [&str; 0]);
for example in &subcmd.examples {
if let Some(header) = &example.header {
roff.text([bold(header)]);
}
if let Some(help) = &example.help {
roff.text([roman(help.as_str())]);
}
roff.control("PP", [] as [&str; 0]);
roff.control("RS", ["4"]);
roff.text([roman(example.code.as_str())]);
roff.control("RE", [] as [&str; 0]);
roff.control("PP", [] as [&str; 0]);
}
roff.text([bold("Examples:")]);
roff.control("PP", [] as [&str; 0]);
for example in &subcmd.examples {
if let Some(header) = &example.header {
roff.text([bold(header)]);
}
if let Some(help) = &example.help {
roff.text([roman(help.as_str())]);
}
roff.control("PP", [] as [&str; 0]);
roff.control("RS", ["4"]);
roff.text([roman(example.code.as_str())]);
roff.control("RE", [] as [&str; 0]);
roff.control("PP", [] as [&str; 0]);

Copilot uses AI. Check for mistakes.
Comment on lines +336 to +353
// Render examples if any
if has_examples {
roff.text([bold("Examples:")]);
roff.control("PP", [] as [&str; 0]);
for example in &subcmd.examples {
if let Some(header) = &example.header {
roff.text([bold(header)]);
}
if let Some(help) = &example.help {
roff.text([roman(help.as_str())]);
}
roff.control("PP", [] as [&str; 0]);
roff.control("RS", ["4"]);
roff.text([roman(example.code.as_str())]);
roff.control("RE", [] as [&str; 0]);
roff.control("PP", [] as [&str; 0]);
}
}
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

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

The .PP control directive is called after header/help text (line 347) and again after the code block (line 351) for every example. This creates excessive spacing between examples. Consider adding .PP only between examples (not after the last one) or before each new example (not before the first one) to avoid unnecessary whitespace at the end of the Examples section.

Copilot uses AI. Check for mistakes.
Previously, the manpage renderer added .PP control directives both after
the code block of each example AND at the start of the next example,
creating double spacing. This also left unnecessary .PP after the last
example in a section.

Now .PP is only added between examples (not before the first or after
the last), resulting in cleaner spacing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@codecov
Copy link

codecov bot commented Nov 12, 2025

Codecov Report

❌ Patch coverage is 17.85714% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.04%. Comparing base (17adda8) to head (516ddd1).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
lib/src/docs/manpage/renderer.rs 17.85% 8 Missing and 15 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #380      +/-   ##
==========================================
- Coverage   70.08%   69.04%   -1.05%     
==========================================
  Files          45       45              
  Lines        4383     4436      +53     
  Branches     4383     4436      +53     
==========================================
- Hits         3072     3063       -9     
+ Misses       1011      985      -26     
- Partials      300      388      +88     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jdx jdx merged commit b3c39a7 into main Nov 12, 2025
7 of 9 checks passed
@jdx jdx deleted the test-example-generation branch November 12, 2025 16:38
jdx pushed a commit that referenced this pull request Nov 12, 2025
## [2.8.0](https://github.com/jdx/usage/compare/v2.7.0..v2.8.0) -
2025-11-12

### 🚀 Features

- add examples section to markdown and manpage generation by
[@jdx](https://github.com/jdx) in
[#380](#380)
- add examples support to spec-level by [@jdx](https://github.com/jdx)
in [#382](#382)

### 🐛 Bug Fixes

- allow blank comment lines in #USAGE blocks by
[@jdx](https://github.com/jdx) in
[#381](#381)
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Nov 14, 2025
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [usage](https://github.com/jdx/usage) | minor | `2.6.0` -> `2.8.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>jdx/usage (usage)</summary>

### [`v2.8.0`](https://github.com/jdx/usage/blob/HEAD/CHANGELOG.md#280---2025-11-12)

[Compare Source](jdx/usage@v2.7.0...v2.8.0)

##### 🚀 Features

- add examples section to markdown and manpage generation by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;380](jdx/usage#380)
- add examples support to spec-level by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;382](jdx/usage#382)

##### 🐛 Bug Fixes

- allow blank comment lines in #USAGE blocks by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;381](jdx/usage#381)

### [`v2.7.0`](https://github.com/jdx/usage/blob/HEAD/CHANGELOG.md#270---2025-11-11)

[Compare Source](jdx/usage@v2.6.0...v2.7.0)

##### 🚀 Features

- support bracketed header syntax by [@&#8203;okuuva](https://github.com/okuuva) in [#&#8203;377](jdx/usage#377)

##### 📚 Documentation

- Fix VitePress build error in markdown documentation by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;378](jdx/usage#378)

##### 🔍 Other Changes

- integrate clap-sort to enforce alphabetical subcommand ordering by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;370](jdx/usage#370)

##### 📦️ Dependency Updates

- lock file maintenance by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;372](jdx/usage#372)
- update rust crate clap-sort to v1.0.3 by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;373](jdx/usage#373)
- update rust crate ctor to v0.6.1 by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;374](jdx/usage#374)
- lock file maintenance by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;375](jdx/usage#375)

##### New Contributors

- [@&#8203;okuuva](https://github.com/okuuva) made their first contribution in [#&#8203;377](jdx/usage#377)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS4xNzMuMSIsInVwZGF0ZWRJblZlciI6IjQxLjE3My4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
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