feat: render help pages via rd2qmd Markdown pipeline#83
Merged
Conversation
Replace the broken Rd2txt overstrike pipeline (raw _\x08C characters displayed in ratatui pager) with a proper Markdown rendering pipeline: - Add rd2qmd-core dependency to convert raw Rd to Markdown in arf-harp - Add pulldown-cmark dependency for Markdown parsing in arf-console - New get_help_markdown() function fetches raw Rd from R and converts via RdConverter with PipeTable format and standard code fences - New pager/markdown.rs module renders CommonMark to styled ratatui Lines with support for headings, emphasis, code blocks, lists, tables, blockquotes, and links - Unified rendering path: both help topics (rd2qmd) and vignettes (r-vignette-to-md) now share the same Markdown renderer - Remove dead overstrike parsing code (parse_section_header, match_section_name, section_type, HelpSection enum) Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Enable rd2qmd-core "roxygen" feature to properly convert roxygen2 markdown code blocks (fixes <div class="sourceCode"> appearing in help output for packages like dplyr) - Handle <br>/<br/>/<br /> inline HTML as line breaks instead of literal text - In table cells, <br> splits into multiple visual rows with proper column alignment - Block-level HTML rendered as plain text lines - Add tests for br handling in and outside tables Co-Authored-By: Claude Opus 4.6 <[email protected]>
…onsistency - Use UnicodeWidthStr::width() instead of byte len() for table column width calculation and padding, fixing misalignment with CJK text - Remove backtick wrapping from inline code in table cells to match non-table rendering (both now rely on cyan styling only) Co-Authored-By: Claude Opus 4.6 <[email protected]>
Extract tokenize_r() as a public API from RTreeSitterHighlighter, making tree-sitter R tokenization reusable outside the REPL. The markdown renderer now detects R code blocks (```r) and applies per-token syntax highlighting using the same tree-sitter-r parser and color scheme as the REPL input. Non-R code blocks continue to render with the dim style. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add default_code_lang parameter to render_markdown() so callers can
specify a fallback language for fenced code blocks without a tag.
The help pager passes Some("r"), which means \preformatted{} blocks
from Rd (which rd2qmd emits as bare ```) now receive R syntax
highlighting instead of the generic dim style.
Explicit language tags always take precedence over the default.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Derive pager colors from RColorConfig::default() via nu_ansi_color_to_ratatui instead of hardcoding duplicates - Unify parser: RTreeSitterHighlighter now uses the shared thread-local parse_r() instead of its own RefCell<Parser> - Replace silent bounds skip with debug_assert in flush_code_block Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Code blocks in the markdown pager now have a distinct dark background (Color::Indexed(236)) that spans the full terminal width, making them visually distinguishable from body text. The fix has two parts: - markdown.rs: flush_code_line() sets Line.style bg for code block lines - mod.rs: render() pads bg-colored lines with spaces to fill full width, working around ratatui's Paragraph only applying bg to content width Co-Authored-By: Claude Opus 4.6 <[email protected]>
flush_code_line() had an early return on empty spans, which caused blank lines within code blocks to lose their background color. Now always emit a line with the code block background style, even when no spans are accumulated. Co-Authored-By: Claude Opus 4.6 <[email protected]>
eitsupi
commented
Feb 15, 2026
There was a problem hiding this comment.
Pull request overview
This pull request replaces the broken Rd2txt overstrike-based help page renderer with a modern Markdown pipeline using rd2qmd-core and pulldown-cmark. The changes enable proper rendering of R help pages with syntax highlighting, styled headings, and structured elements like tables and code blocks.
Changes:
- Introduced
get_help_markdown()function in arf-harp that converts raw Rd help files to Markdown via rd2qmd-core - Added new
markdown.rsmodule in arf-console that renders Markdown to styled ratatui Lines with support for headings, code blocks, tables, lists, and blockquotes - Extracted
tokenize_r()as a public API from the tree-sitter highlighter to enable R syntax highlighting in help page code blocks - Enhanced pager to apply background color padding to code blocks spanning the full terminal width
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| crates/arf-harp/src/help.rs | Added get_help_markdown() to retrieve raw Rd and convert to Markdown via rd2qmd-core |
| crates/arf-harp/Cargo.toml | Added rd2qmd-core dependency |
| crates/arf-console/src/pager/markdown.rs | New module for rendering Markdown to styled ratatui Lines with R syntax highlighting |
| crates/arf-console/src/pager/mod.rs | Added background color padding logic for code blocks |
| crates/arf-console/src/pager/style_convert.rs | Made nu_ansi_color_to_ratatui pub(crate) for markdown module |
| crates/arf-console/src/pager/help.rs | Replaced overstrike parser with markdown renderer, removed obsolete section parsing tests |
| crates/arf-console/src/highlighter/r_tree_sitter.rs | Extracted tokenization logic as free functions, exposed tokenize_r() as public API |
| crates/arf-console/src/highlighter/mod.rs | Re-exported TokenType and tokenize_r |
| crates/arf-console/Cargo.toml | Added pulldown-cmark dependency |
| Cargo.toml | Added rd2qmd-core and pulldown-cmark to workspace dependencies |
| Cargo.lock | Updated with new dependencies and their transitive dependencies |
| CHANGELOG.md | Documented new Markdown rendering features and R syntax highlighting |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Add Tag::Superscript/Subscript and TagEnd::Superscript/Subscript match arms (new variants in 0.13) - Fix debug_assert to allow empty tokens at end of source (token.start <= source.len() instead of <) Co-Authored-By: Claude Opus 4.6 <[email protected]>
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
Details
rd2qmd Markdown pipeline
arf-harp: newget_help_markdown()sends raw Rd tord2qmd-corewhich produces clean Markdownarf-console: newmarkdown.rsmodule renders Markdown via pulldown-cmark into ratatui styled LinesR syntax highlighting in code blocks
tokenize_rextracted as public API)python,bash, etc.) rendered without highlightingCode block background
Test plan
cargo test -p arf-console -p arf-harp— all tests passcargo clippy -p arf-console -p arf-harp— no warnings:help print— headings styled, code blocks highlighted with background, tables readable🤖 Generated with Claude Code