Skip to content

Add support for cross-document references#79

Open
imphil wants to merge 1 commit into
atsphinx:mainfrom
imphil:crossref
Open

Add support for cross-document references#79
imphil wants to merge 1 commit into
atsphinx:mainfrom
imphil:crossref

Conversation

@imphil

@imphil imphil commented Jun 22, 2026

Copy link
Copy Markdown

Implement :doc:/:ref:/:confval:/etc. cross-references in the Typst
builder, following the same approach as Sphinx's LaTeX builder: all
documents are merged into a single doctree, and Sphinx's standard
env.resolve_references() runs against that merged tree right after
merging. This lets Sphinx's own domains handle path normalization,
label lookup, title substitution, and intersphinx exactly as they do
for any other builder.

Builder.get_target_uri()/get_relative_uri() map a docname onto the
single merged Typst document, mirroring the LaTeX builder's
"%docname" convention. The writer's job is then only to translate the
refid/refuri that Sphinx resolves into a namespaced Typst label
(docname:id); the namespace keeps ids from colliding across
documents now that they all share one output file. A small
per-document "#metadata(none) " anchor - the same trick HTML
uses for an extra empty anchor per additional id on an element -
gives whole-document :doc: references something to link to even when
the target document has no sections, and covers section/signature
ids beyond the first, since Typst only allows one label per element.

Includes test coverage for basic cross-references, :ref: to named
targets, relative paths (including bare relative paths resolved from
the referring document's directory), nested documents, and edge
cases such as documents without sections and confval-style targets.

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Fixed cross-reference resolution in merged Typst documents
    • Corrected :doc: and :ref: role handling for internal and external linking
    • Improved section anchor labeling and document-wide link targets
  • Tests

    • Added comprehensive end-to-end test suite validating cross-reference functionality across documents

Implement :doc:/:ref:/:confval:/etc. cross-references in the Typst
builder, following the same approach as Sphinx's LaTeX builder: all
documents are merged into a single doctree, and Sphinx's standard
env.resolve_references() runs against that merged tree right after
merging. This lets Sphinx's own domains handle path normalization,
label lookup, title substitution, and intersphinx exactly as they do
for any other builder.

Builder.get_target_uri()/get_relative_uri() map a docname onto the
single merged Typst document, mirroring the LaTeX builder's
"%docname" convention. The writer's job is then only to translate the
refid/refuri that Sphinx resolves into a namespaced Typst label
(<docname:id>); the namespace keeps ids from colliding across
documents now that they all share one output file. A small
per-document "#metadata(none) <label>" anchor - the same trick HTML
uses for an extra empty anchor per additional id on an element -
gives whole-document :doc: references something to link to even when
the target document has no sections, and covers section/signature
ids beyond the first, since Typst only allows one label per element.

Includes test coverage for basic cross-references, :ref: to named
targets, relative paths (including bare relative paths resolved from
the referring document's directory), nested documents, and edge
cases such as documents without sections and confval-style targets.
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1d0ed57e-43a4-4151-b277-1431637ba811

📥 Commits

Reviewing files that changed from the base of the PR and between 06e8d1b and 6c1390b.

📒 Files selected for processing (10)
  • src/atsphinx/typst/builders.py
  • src/atsphinx/typst/writer.py
  • tests/test_e2e/test_it.py
  • tests/testdocs/test-cross-references/conf.py
  • tests/testdocs/test-cross-references/index.rst
  • tests/testdocs/test-cross-references/no_sections.rst
  • tests/testdocs/test-cross-references/page1.rst
  • tests/testdocs/test-cross-references/page2.rst
  • tests/testdocs/test-cross-references/subdir/nested.rst
  • tests/testdocs/test-cross-references/subdir/sibling.rst

📝 Walkthrough

Walkthrough

This PR implements cross-reference support for the merged single-file Typst builder. In builders.py, NoUri is imported, a self.docnames set is added to track merged documents, and assemble_doctree now records the current docname, resolves references on the merged tree, while get_target_uri and get_relative_uri replace their stubs with real validation and delegation logic. In writer.py, a _doc_label helper converts document names to Typst label namespaces, curfilestack tracking is added to the translator, and visit_document, depart_title, visit_reference, depart_desc_signature, visit_start_of_file, and _write_anchor are all implemented or updated to emit correctly namespaced Typst #link and #metadata anchors. A new test fixture tree (test-cross-references/) with conf.py, seven RST source files, and seven E2E test functions covers the full cross-reference pipeline including :doc:, :ref:, bare-relative paths, no-sections documents, implicit titles, label syntax validation, and PDF compilation.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • atsphinx/typst#47: Adds desc node support and visit_reference/desc_* methods in writer.py, directly overlapping with this PR's changes to visit_reference, depart_desc_signature, and anchor handling in the same translator.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately and concisely summarizes the main change: adding support for cross-document references to the Typst builder.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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.

1 participant