Skip to content

feat: add custom theme directory support with typst_themes_path config#72

Open
illilillillili wants to merge 3 commits into
atsphinx:mainfrom
illilillillili:feat/custom_themes
Open

feat: add custom theme directory support with typst_themes_path config#72
illilillillili wants to merge 3 commits into
atsphinx:mainfrom
illilillillili:feat/custom_themes

Conversation

@illilillillili

@illilillillili illilillillili commented Jun 19, 2026

Copy link
Copy Markdown

How to use

typst_documents = [{
  "title": "project",
  "theme": "my_theme",
}]

typst_static_path = ["_static"]
# this is new
typst_themes_path = ["_themes"]

and then have _themes/my_theme/theme.toml available (see src/atsphinx/typst/themes/manual for reference)

Summary by CodeRabbit

  • New Features
    • Added support for custom Typst theme paths, enabling users to specify custom directories where themes are located. Custom themes are now searched before built-in themes.

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fd7616ea-84ee-4998-996e-31b1f2edf027

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR introduces a typst_themes_path configuration value for the atsphinx/typst Sphinx extension. In config.py, the new value is registered with environment scope and list[str | Path] type; during compute_configurations, string entries are converted to Path objects relative to app.confdir and stored back. The hardcoded "manual" default theme for auto-created document entries is replaced with config.theme. In theming.py, load_theme gains an optional typst_themes_path parameter, and _find_theme_path searches each custom directory before the built-in themes directory. In builders.py, the builder's _load_theme() passes self.config.typst_themes_path to theming.load_theme.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main feature addition: custom theme directory support via the new typst_themes_path config option, which accurately reflects the primary change across all modified files.
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.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/atsphinx/typst/theming.py (1)

155-155: ⚡ Quick win

Avoid mutable default in load_theme signature.

Use None and initialize inside the function to avoid shared default state across calls.

Suggested patch
-def load_theme(name: str, typst_themes_path: list[Path] = []) -> Theme:
+def load_theme(name: str, typst_themes_path: list[Path] | None = None) -> Theme:
@@
+    if typst_themes_path is None:
+        typst_themes_path = []
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/atsphinx/typst/theming.py` at line 155, The load_theme function has a
mutable default argument (empty list) for the typst_themes_path parameter, which
can cause unexpected shared state across multiple function calls. Replace the
empty list default with None, then add initialization logic at the beginning of
the function body to check if typst_themes_path is None and set it to an empty
list if so. This ensures each function call gets its own fresh list instance.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/atsphinx/typst/config.py`:
- Around line 78-81: The code currently treats relative Path objects and string
paths inconsistently when building typst_themes_path. A relative Path object
like Path("_themes") stays relative and is appended directly, while a string
"_themes" is normalized to app.confdir / "_themes". To fix this, modify the
isinstance(p, Path) branch to check if the Path p is relative using the
is_absolute() method, and if it is relative, append app.confdir / p instead of
just p, matching the behavior of the string case.

---

Nitpick comments:
In `@src/atsphinx/typst/theming.py`:
- Line 155: The load_theme function has a mutable default argument (empty list)
for the typst_themes_path parameter, which can cause unexpected shared state
across multiple function calls. Replace the empty list default with None, then
add initialization logic at the beginning of the function body to check if
typst_themes_path is None and set it to an empty list if so. This ensures each
function call gets its own fresh list instance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4a510e9d-beb2-4221-b512-a1b5b4aa8e24

📥 Commits

Reviewing files that changed from the base of the PR and between ef2cea2 and 45dc83f.

📒 Files selected for processing (3)
  • src/atsphinx/typst/builders.py
  • src/atsphinx/typst/config.py
  • src/atsphinx/typst/theming.py

Comment thread src/atsphinx/typst/config.py
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