Skip to content

Refactor to mimic singlehtml builder#1

Open
jdillard wants to merge 14 commits intoakaihola:singlemarkdownfrom
jdillard:bug/singlemarkdown
Open

Refactor to mimic singlehtml builder#1
jdillard wants to merge 14 commits intoakaihola:singlemarkdownfrom
jdillard:bug/singlemarkdown

Conversation

@jdillard
Copy link

@jdillard jdillard commented Oct 29, 2025

Developer Note: I used Claude Code to generate this PR (making sure it had access to the sample docs and the singlehtml builder for references) to address liran-funaro#37 (comment) and haven't reviewed the code, but I did check it's work and it did fix the issue. I'm not sure if this helpful, and if not feel free to ignore, but thought I would make the PR in case it could serve as inspiration.

Below is its PR description.


Summary

Successfully adapted the singlemarkdown builder to behave like Sphinx's built-in singlehtml builder, which fixed the duplicate heading and incorrect nesting issues.

Changes Made

  1. singlemarkdown.py (sphinx_markdown_builder/singlemarkdown.py:176-212):
    • Removed the old approach that manually iterated through documents and added synthetic titles
    • Implemented the same pattern as singlehtml: use assemble_doctree() to merge all documents into a single doctree via inline_all_toctrees()
    • Set current_doc_name and sec_numbers before writing (needed for URL adjustments)
    • Updated get_target_uri() to use #document-{docname} anchors like singlehtml does
  2. singletranslator.py (sphinx_markdown_builder/singletranslator.py:1-37):
    • Replaced the old custom section handling with proper start_of_file node handlers
    • visit_start_of_file() adds document anchors (like HTML translator)
    • depart_start_of_file() tracks docname stack
  3. Updated tests to match the new behavior:
    • Fixed unit tests to use proper mocking for the new approach
    • Updated anchor format expectations from #docname to #document-docname

Result

Before

## Changelog          ← Synthetic title added by builder
# Changelog           ← Original document title
## 0.7.0
### 0.6.0            ← Each version gets progressively deeper
#### 0.5.3
##### 0.5.2

After

### Changelog         ← Single title at correct level (nested under main doc)
#### 0.7.0
#### 0.6.0           ← All versions at same level
#### 0.5.3
#### 0.5.2

All 19 tests pass, and the output now correctly handles heading hierarchy when merging multiple documents!

akaihola and others added 12 commits May 17, 2025 14:02
This commit adds a functional SingleFileMarkdownBuilder that generates a single consolidated Markdown file from Sphinx documentation rather than separate files for each document.

Key changes:
- Complete implementation of SingleFileMarkdownBuilder with custom write_documents() method
- Add custom SingleMarkdownTranslator to properly handle document anchors and styling
- Add table of contents and document anchors to improve navigation in the single file
- Simplify cross-references by using document anchors within the same file
- Reformat test file to follow code style without functional changes

The builder can be used with: sphinx-build -M singlemarkdown ./docs ./build
The output will be a single file at ./build/singlemarkdown/<root_doc>.md
…tion errors

- Refactor setup function in __init__.py with proper type hints and return metadata
- Update singlemarkdown.py to follow Sphinx extension pattern by removing duplicate builder registration
- Follow pattern from Sphinx's singlehtml.py implementation
- Ensure proper extension loading through app.setup_extension
This commit adds the missing render_partial method to the SingleFileMarkdownBuilder class,
which resolves the 'no-member' errors in the singlemarkdown.py file.

The implementation:
- Creates a proper render_partial method based on Sphinx's similar functionality
- Uses StringOutput instead of StringIO for proper document rendering
- Ensures correct type handling for method return values
- Updates write_documents method to use StringOutput for consistency

Fixes E1101: Instance of 'SingleFileMarkdownBuilder' has no 'render_partial' member (no-member)
- Add proper type annotations to class attributes and method parameters/return types
- Fix potential type incompatibilities with appropriate casts
- Add pyright-specific comments to suppress false positives
- Improve variable naming and eliminate unused variables
- Replace implicit variable assignments with explicit ones using underscore
…nnotations

- Add extensive unit tests for SingleFileMarkdownBuilder methods
- Create separate test file for SingleMarkdownTranslator
- Improve Path handling in tests using pathlib
- Add proper type annotations for MarkdownWriter variable
- Test error handling and edge cases for better coverage
- Add parametrized tests to test singlemarkdown with various configuration options
- Test handling of missing build directories
- Test handling of file permission issues
- Match the integration test pattern from test_builder.py
- Enhance error handling and coverage
@coveralls
Copy link

Pull Request Test Coverage Report for Build 18898729777

Details

  • 24 of 25 (96.0%) changed or added relevant lines in 3 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+1.1%) to 98.678%

Changes Missing Coverage Covered Lines Changed/Added Lines %
sphinx_markdown_builder/singlemarkdown.py 15 16 93.75%
Totals Coverage Status
Change from base Build 16329732637: 1.1%
Covered Lines: 896
Relevant Lines: 908

💛 - Coveralls

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.

3 participants