From 45dc83f83e230c0ca933ac183bae9400d37ea12f Mon Sep 17 00:00:00 2001 From: illilillillili <189730003+illilillillili@users.noreply.github.com> Date: Fri, 19 Jun 2026 08:07:22 +0000 Subject: [PATCH 1/3] feat: add custom theme directory support with typst_themes_path config --- src/atsphinx/typst/builders.py | 4 +++- src/atsphinx/typst/config.py | 12 +++++++++++- src/atsphinx/typst/theming.py | 8 +++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/atsphinx/typst/builders.py b/src/atsphinx/typst/builders.py index 53ff2ed..8b39b3b 100644 --- a/src/atsphinx/typst/builders.py +++ b/src/atsphinx/typst/builders.py @@ -54,7 +54,9 @@ def _load_theme(name: str) -> theming.Theme | None: if name in self._themes: return - theme = theming.load_theme(name) + theme = theming.load_theme( + name, typst_themes_path=self.config.typst_themes_path + ) theme.init(self) self._themes[name] = theme parent = theme.get_parent_theme() diff --git a/src/atsphinx/typst/config.py b/src/atsphinx/typst/config.py index 560f444..9d5f52a 100644 --- a/src/atsphinx/typst/config.py +++ b/src/atsphinx/typst/config.py @@ -56,7 +56,7 @@ def compute_configurations(app: Sphinx, config: Config): "filename": f"document-{config.language}", "title": f"{config.project} Documentation [{config.language.upper()}]", "author": config.author, - "theme": "manual", + "theme": config.theme, } ) for idx, user_value in enumerate(document_settings): @@ -72,9 +72,19 @@ def compute_configurations(app: Sphinx, config: Config): typst_static_path.append(app.confdir / p) config.typst_static_path = typst_static_path + # 3. Cast string path to Path object and register custom theme directories. + typst_themes_path = [] + for p in config.typst_themes_path: + if isinstance(p, Path): + typst_themes_path.append(p) + else: + typst_themes_path.append(app.confdir / p) + config.typst_themes_path = typst_themes_path + def setup(app: Sphinx): # noqa: D103 app.add_config_value("typst_documents", [], "env", list[dict]) app.add_config_value("typst_static_path", [], "env", [list[str | Path]]) + app.add_config_value("typst_themes_path", [], "env", [list[str | Path]]) app.add_config_value("typst_font_paths", [], "env", [list[str | Path]]) app.connect("config-inited", compute_configurations) diff --git a/src/atsphinx/typst/theming.py b/src/atsphinx/typst/theming.py index fc35963..7e8c364 100644 --- a/src/atsphinx/typst/theming.py +++ b/src/atsphinx/typst/theming.py @@ -152,7 +152,7 @@ def _verify_theme_path(theme_dir: Path) -> bool: ) -def load_theme(name: str) -> Theme: +def load_theme(name: str, typst_themes_path: list[Path] = []) -> Theme: """Find theme directory and load as theme object. If it is not found, raise error. @@ -167,6 +167,12 @@ def _find_theme_path(name: str) -> Path: When it does not found, it raises ThemeError. """ + # Search from custom theme directories first + for custom_dir in typst_themes_path: + theme_dir = custom_dir / name + if _verify_theme_path(theme_dir): + return theme_dir + # Search from built-in themes theme_dir = _BASE_THEMES_DIR / name if _verify_theme_path(theme_dir): From f98c4bf2d2315ccd0c9efbe9f5d1b10bc11ca1a8 Mon Sep 17 00:00:00 2001 From: illilillillili <189730003+illilillillili@users.noreply.github.com> Date: Fri, 19 Jun 2026 08:29:43 +0000 Subject: [PATCH 2/3] fix: improve path resolution as suggested by coderabbit --- src/atsphinx/typst/config.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/atsphinx/typst/config.py b/src/atsphinx/typst/config.py index 9d5f52a..6e601ce 100644 --- a/src/atsphinx/typst/config.py +++ b/src/atsphinx/typst/config.py @@ -63,20 +63,20 @@ def compute_configurations(app: Sphinx, config: Config): document_settings[idx] = DEFAULT_DOCUMENT_SETTINGS | user_value config.typst_documents = document_settings - # 2. Cast string path to Path object. + # 2. Cast string path to Path object for static_paths typst_static_path = [] for p in config.typst_static_path: if isinstance(p, Path): - typst_static_path.append(p) + typst_static_path.append(p if p.is_absolute() else app.confdir / p) continue typst_static_path.append(app.confdir / p) config.typst_static_path = typst_static_path - # 3. Cast string path to Path object and register custom theme directories. + # 3. Cast string path to Path object for themes_paths typst_themes_path = [] for p in config.typst_themes_path: if isinstance(p, Path): - typst_themes_path.append(p) + typst_themes_path.append(p if p.is_absolute() else app.confdir / p) else: typst_themes_path.append(app.confdir / p) config.typst_themes_path = typst_themes_path From ada7042c903ddc1f2ecfcf07708b42ebb4de4dce Mon Sep 17 00:00:00 2001 From: illilillillili <189730003+illilillillili@users.noreply.github.com> Date: Fri, 19 Jun 2026 08:47:28 +0000 Subject: [PATCH 3/3] docs: add docstrings to config and builder functions --- src/atsphinx/typst/builders.py | 5 +++++ src/atsphinx/typst/config.py | 7 ++++++- src/atsphinx/typst/theming.py | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/atsphinx/typst/builders.py b/src/atsphinx/typst/builders.py index 8b39b3b..27d4748 100644 --- a/src/atsphinx/typst/builders.py +++ b/src/atsphinx/typst/builders.py @@ -49,6 +49,11 @@ def get_outdated_docs(self): # noqa: D102 return "all targets" def prepare_writing(self, docnames: set[str]) -> None: # noqa: D102 + """ + Preload themes to copy assets before write_documents. + args: + docnames: set[str] unused parameter + """ # Preload themes to copy assets before write_documents. def _load_theme(name: str) -> theming.Theme | None: if name in self._themes: diff --git a/src/atsphinx/typst/config.py b/src/atsphinx/typst/config.py index 6e601ce..3ce371e 100644 --- a/src/atsphinx/typst/config.py +++ b/src/atsphinx/typst/config.py @@ -82,7 +82,12 @@ def compute_configurations(app: Sphinx, config: Config): config.typst_themes_path = typst_themes_path -def setup(app: Sphinx): # noqa: D103 +def setup(app: Sphinx): + """Register configuration values and connect event handlers. + + Args: + app: Sphinx application instance + """ app.add_config_value("typst_documents", [], "env", list[dict]) app.add_config_value("typst_static_path", [], "env", [list[str | Path]]) app.add_config_value("typst_themes_path", [], "env", [list[str | Path]]) diff --git a/src/atsphinx/typst/theming.py b/src/atsphinx/typst/theming.py index 7e8c364..1b92e4e 100644 --- a/src/atsphinx/typst/theming.py +++ b/src/atsphinx/typst/theming.py @@ -164,6 +164,7 @@ def load_theme(name: str, typst_themes_path: list[Path] = []) -> Theme: def _find_theme_path(name: str) -> Path: """Search theme path in order to rules. + Searches custom theme directories first, then built-in themes. When it does not found, it raises ThemeError. """