typsphinx 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
typsphinx/writer.py ADDED
@@ -0,0 +1,144 @@
1
+ """
2
+ Typst writer for docutils.
3
+
4
+ This module implements the TypstWriter class, which converts docutils
5
+ document trees to Typst markup.
6
+ """
7
+
8
+ from typing import Any
9
+
10
+ from docutils import writers
11
+
12
+ from typsphinx.template_engine import TemplateEngine
13
+ from typsphinx.translator import TypstTranslator
14
+
15
+
16
+ class TypstWriter(writers.Writer):
17
+ """
18
+ Writer class for Typst output format.
19
+
20
+ This writer converts docutils document trees to Typst markup files.
21
+ """
22
+
23
+ supported = ("typst",)
24
+ """Formats this writer supports."""
25
+
26
+ def __init__(self, builder: Any) -> None:
27
+ """
28
+ Initialize the writer.
29
+
30
+ Args:
31
+ builder: The Sphinx builder instance
32
+ """
33
+ super().__init__()
34
+ self.builder = builder
35
+
36
+ def _is_master_document(self, docname: str) -> bool:
37
+ """
38
+ Check if the current document is a master document (defined in typst_documents).
39
+
40
+ Master documents should have templates applied, while included documents
41
+ (via #include()) should only contain body content.
42
+
43
+ Args:
44
+ docname: Document name (e.g., 'index', 'chapter1')
45
+
46
+ Returns:
47
+ True if this is a master document, False otherwise
48
+ """
49
+ config = self.builder.config
50
+ typst_documents = getattr(config, "typst_documents", [])
51
+
52
+ # Check if docname is in typst_documents
53
+ # typst_documents format: [(sourcename, targetname, title, author), ...]
54
+ for doc_tuple in typst_documents:
55
+ if doc_tuple[0] == docname:
56
+ return True
57
+
58
+ return False
59
+
60
+ def translate(self) -> None:
61
+ """
62
+ Translate the document tree to Typst markup.
63
+
64
+ This method creates a TypstTranslator and visits the document tree,
65
+ then wraps the output with a template using TemplateEngine.
66
+
67
+ For master documents (defined in typst_documents), the full template
68
+ is applied. For included documents, only the body content is output.
69
+ """
70
+ # Generate body content
71
+ self.visitor = TypstTranslator(self.document, self.builder)
72
+ self.document.walkabout(self.visitor)
73
+ body = self.visitor.astext()
74
+
75
+ # Get current document name
76
+ docname = self.builder.current_docname
77
+
78
+ # Check if this is a master document
79
+ is_master = self._is_master_document(docname)
80
+
81
+ if not is_master:
82
+ # For included documents, add essential imports but no template
83
+ # Typst's #include() does not inherit imports from parent file,
84
+ # so each file needs its own imports
85
+ imports = []
86
+ imports.append("// Essential imports for included document")
87
+ imports.append('#import "@preview/codly:1.3.0": *')
88
+ imports.append('#import "@preview/codly-languages:0.1.1": *')
89
+ imports.append('#import "@preview/mitex:0.2.4": mi, mitex')
90
+ imports.append('#import "@preview/gentle-clues:1.2.0": *')
91
+ imports.append("")
92
+ imports.append("// Initialize codly")
93
+ imports.append("#show: codly-init.with()")
94
+ imports.append("#codly(languages: codly-languages)")
95
+ imports.append("")
96
+
97
+ self.output = "\n".join(imports) + "\n" + body
98
+ return
99
+
100
+ # For master documents, apply template
101
+ config = self.builder.config
102
+
103
+ # Get template configuration from Sphinx config
104
+ template_path = getattr(config, "typst_template", None)
105
+ if template_path:
106
+ # Resolve relative path from source directory
107
+ import os
108
+
109
+ source_dir = self.builder.srcdir
110
+ template_path = os.path.join(source_dir, template_path)
111
+
112
+ # Create template engine
113
+ template_engine = TemplateEngine(
114
+ template_path=template_path,
115
+ search_paths=[self.builder.srcdir],
116
+ parameter_mapping=getattr(config, "typst_template_mapping", None),
117
+ typst_package=getattr(config, "typst_package", None),
118
+ typst_template_function=getattr(config, "typst_template_function", None),
119
+ typst_package_imports=getattr(config, "typst_package_imports", None),
120
+ )
121
+
122
+ # Gather Sphinx metadata
123
+ sphinx_metadata = {
124
+ "project": config.project,
125
+ "author": config.author,
126
+ "release": config.release,
127
+ "copyright": config.copyright,
128
+ }
129
+
130
+ # Add custom elements from config
131
+ typst_elements = getattr(config, "typst_elements", {})
132
+ sphinx_metadata.update(typst_elements)
133
+
134
+ # Map parameters
135
+ params = template_engine.map_parameters(sphinx_metadata)
136
+
137
+ # Extract toctree options and add to parameters
138
+ toctree_options = template_engine.extract_toctree_options(self.document)
139
+ params.update(toctree_options)
140
+
141
+ # Render with template (using separate template file)
142
+ self.output = template_engine.render(
143
+ params, body, template_file="_template.typ"
144
+ )
@@ -0,0 +1,355 @@
1
+ Metadata-Version: 2.4
2
+ Name: typsphinx
3
+ Version: 0.3.0
4
+ Summary: Sphinx extension for Typst output
5
+ Author-email: Sphinx Typst Contributors <noreply@example.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/YuSabo90002/typsphinx
8
+ Project-URL: Documentation, https://github.com/YuSabo90002/typsphinx#readme
9
+ Project-URL: Repository, https://github.com/YuSabo90002/typsphinx
10
+ Project-URL: Issues, https://github.com/YuSabo90002/typsphinx/issues
11
+ Keywords: sphinx,typst,documentation,pdf
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Framework :: Sphinx :: Extension
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Documentation :: Sphinx
21
+ Classifier: Topic :: Software Development :: Documentation
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: sphinx>=5.0
26
+ Requires-Dist: docutils>=0.18
27
+ Requires-Dist: typst>=0.11.1
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=7.0; extra == "dev"
30
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
31
+ Requires-Dist: tox>=4.0; extra == "dev"
32
+ Requires-Dist: tox-uv>=1.0; extra == "dev"
33
+ Requires-Dist: black>=23.0; extra == "dev"
34
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
35
+ Requires-Dist: mypy>=1.0; extra == "dev"
36
+ Requires-Dist: sphinx-testing>=1.0; extra == "dev"
37
+ Requires-Dist: pre-commit>=3.0; extra == "dev"
38
+ Requires-Dist: types-docutils>=0.18; extra == "dev"
39
+ Requires-Dist: twine>=5.0; extra == "dev"
40
+ Requires-Dist: build>=1.0; extra == "dev"
41
+ Provides-Extra: docs
42
+ Requires-Dist: sphinx-rtd-theme>=2.0; extra == "docs"
43
+ Requires-Dist: sphinx-autodoc-typehints>=1.0; extra == "docs"
44
+ Dynamic: license-file
45
+
46
+ # typsphinx
47
+
48
+ [![PyPI version](https://badge.fury.io/py/typsphinx.svg)](https://badge.fury.io/py/typsphinx)
49
+ [![Python Support](https://img.shields.io/pypi/pyversions/typsphinx.svg)](https://pypi.org/project/typsphinx/)
50
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
51
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
52
+
53
+ Sphinx extension for Typst output format support.
54
+
55
+ ## Overview
56
+
57
+ typsphinx is a Sphinx extension that enables generating Typst documents from reStructuredText sources. Typst is a modern typesetting system designed as an alternative to LaTeX, offering faster compilation and a more intuitive syntax.
58
+
59
+ ## Features
60
+
61
+ - **Convert Sphinx documentation to Typst format**: Seamlessly transform your reStructuredText/Markdown documents
62
+ - **Standard docutils nodes**: Full support for paragraphs, sections, lists, tables, admonitions, and more
63
+ - **Mathematical expressions**:
64
+ - LaTeX syntax via mitex (`@preview/mitex:0.2.4`)
65
+ - Native Typst math syntax
66
+ - **Code blocks with syntax highlighting**: Using codly package (`@preview/codly:1.3.0`)
67
+ - Automatic line numbering
68
+ - Syntax highlighting for multiple languages
69
+ - Highlight specific lines
70
+ - **Images and figures**: Embed images with captions and references
71
+ - **Cross-references and citations**: Maintain document structure with internal links
72
+ - **Customizable templates**: Use default or custom Typst templates
73
+ - **Direct PDF generation**: Self-contained PDF generation via typst-py (no external Typst CLI required)
74
+ - **Multi-document support**: Generate multiple Typst files with toctree integration using `#include()`
75
+
76
+ ## Requirements
77
+
78
+ - Python 3.9 or higher
79
+ - Sphinx 5.0 or higher
80
+ - typst-py 0.11.1 or higher
81
+
82
+ ## Installation
83
+
84
+ ### From PyPI (Beta Release)
85
+
86
+ ```bash
87
+ pip install typsphinx
88
+ ```
89
+
90
+ ### Using uv (recommended for development)
91
+
92
+ ```bash
93
+ # Clone the repository
94
+ git clone https://github.com/YuSabo90002/typsphinx.git
95
+ cd typsphinx
96
+
97
+ # Install dependencies with uv
98
+ uv sync
99
+
100
+ # For development dependencies
101
+ uv sync --extra dev
102
+ ```
103
+
104
+ ## Quick Start
105
+
106
+ ### Basic Configuration
107
+
108
+ Configure Typst output in your `conf.py`:
109
+
110
+ ```python
111
+ # conf.py
112
+
113
+ # Note: typsphinx is auto-discovered via entry points.
114
+ # Adding to extensions list is optional but recommended for clarity.
115
+ # extensions = ['typsphinx']
116
+
117
+ # Optional: Configure Typst builder
118
+ typst_use_mitex = True # Use mitex for LaTeX math (default: True)
119
+ ```
120
+
121
+ ### Build Typst Output
122
+
123
+ ```bash
124
+ # Generate Typst files
125
+ sphinx-build -b typst source build/typst
126
+
127
+ # Generate PDF directly
128
+ sphinx-build -b typstpdf source build/pdf
129
+ ```
130
+
131
+ ### Example Document
132
+
133
+ Create a simple reStructuredText document:
134
+
135
+ ```rst
136
+ ==============
137
+ My Document
138
+ ==============
139
+
140
+ This is a paragraph with **bold** and *italic* text.
141
+
142
+ Math Example
143
+ ============
144
+
145
+ Inline math: :math:`E = mc^2`
146
+
147
+ Block math:
148
+
149
+ .. math::
150
+
151
+ \int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
152
+
153
+ Code Example
154
+ ============
155
+
156
+ .. code-block:: python
157
+
158
+ def hello_world():
159
+ print("Hello, Typst!")
160
+ ```
161
+
162
+ This will generate a Typst file with:
163
+ - Proper heading hierarchy
164
+ - Formatted text with emphasis
165
+ - LaTeX math via mitex (or native Typst math)
166
+ - Syntax-highlighted code blocks with codly
167
+
168
+ ## Advanced Usage
169
+
170
+ ### Custom Templates
171
+
172
+ Create a custom Typst template:
173
+
174
+ ```python
175
+ # conf.py
176
+ typst_template = '_templates/custom.typ'
177
+
178
+ typst_elements = {
179
+ 'papersize': 'a4',
180
+ 'fontsize': '11pt',
181
+ 'lang': 'ja',
182
+ }
183
+ ```
184
+
185
+ ### Template Parameter Mapping
186
+
187
+ Map Sphinx metadata to template parameters:
188
+
189
+ ```python
190
+ # conf.py
191
+ typst_template_mapping = {
192
+ 'title': 'project',
193
+ 'authors': ['author'],
194
+ 'date': 'release',
195
+ }
196
+ ```
197
+
198
+ ### Multi-Document Projects
199
+
200
+ Use toctree to combine multiple documents:
201
+
202
+ ```rst
203
+ .. toctree::
204
+ :maxdepth: 2
205
+ :numbered:
206
+
207
+ intro
208
+ chapter1
209
+ chapter2
210
+ ```
211
+
212
+ This generates `#include()` directives in Typst with proper heading level adjustments.
213
+
214
+ ### Working with Third-Party Extensions
215
+
216
+ typsphinx integrates with Sphinx's standard extension mechanism. For custom nodes from third-party extensions (e.g., sphinxcontrib-mermaid), you can register Typst handlers in your `conf.py`:
217
+
218
+ ```python
219
+ # conf.py
220
+ def setup(app):
221
+ # Example: Support sphinxcontrib-mermaid diagrams
222
+ if 'sphinxcontrib.mermaid' in app.config.extensions:
223
+ from sphinxcontrib.mermaid import mermaid
224
+ from docutils import nodes
225
+
226
+ def typst_visit_mermaid(self, node):
227
+ """Render Mermaid diagram as image in Typst output"""
228
+ # Export diagram as SVG and include in Typst
229
+ diagram_path = f"diagrams/{node['name']}.svg"
230
+ self.add_text(f'#image("{diagram_path}")\n\n')
231
+ raise nodes.SkipNode
232
+
233
+ # Register with Sphinx's standard API
234
+ app.add_node(mermaid, typst=(typst_visit_mermaid, None))
235
+ ```
236
+
237
+ **How it works**:
238
+ - typsphinx uses Sphinx's standard `app.add_node()` API (no custom registry needed)
239
+ - Unknown nodes trigger `unknown_visit()` which logs a warning and extracts text content
240
+ - Users can add Typst support for any extension by registering handlers in `conf.py`
241
+
242
+ For more details, see the [Sphinx Extension API documentation](https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_node).
243
+
244
+ ## Configuration Options
245
+
246
+ See [docs/configuration.rst](docs/configuration.rst) for all available configuration options:
247
+
248
+ - `typst_use_mitex`: Enable/disable mitex for LaTeX math
249
+ - `typst_template`: Custom template path
250
+ - `typst_elements`: Template parameters (paper size, fonts, etc.)
251
+ - `typst_template_mapping`: Sphinx metadata to template parameter mapping
252
+ - `typst_toctree_defaults`: Default toctree options
253
+
254
+ ## Development
255
+
256
+ This project uses uv for fast package management and follows TDD (Test-Driven Development) practices.
257
+
258
+ ### Setup Development Environment
259
+
260
+ ```bash
261
+ # Install with development dependencies
262
+ uv sync --extra dev
263
+
264
+ # Run tests (286 tests, 93% coverage)
265
+ uv run pytest
266
+
267
+ # Run tests with coverage report
268
+ uv run pytest --cov=typsphinx --cov-report=html
269
+
270
+ # Run tests across multiple Python versions
271
+ uv run tox
272
+
273
+ # Run linters
274
+ uv run black .
275
+ uv run ruff check .
276
+ uv run mypy sphinxcontrib/
277
+ ```
278
+
279
+ ### Testing Strategy
280
+
281
+ - **Unit tests**: 286 tests covering all major components
282
+ - **Integration tests**: Full build process validation
283
+ - **Example projects**: `examples/basic/` and `examples/advanced/`
284
+ - **Code coverage**: 93% overall
285
+
286
+ ### Project Structure
287
+
288
+ ```
289
+ typsphinx/
290
+ ├── sphinxcontrib/typst/ # Main package
291
+ │ ├── builder.py # Typst builder
292
+ │ ├── writer.py # Doctree writer
293
+ │ ├── translator.py # Node translator
294
+ │ ├── template_engine.py # Template processor
295
+ │ ├── pdf.py # PDF generation
296
+ │ └── templates/ # Default templates
297
+ ├── tests/ # Test suite
298
+ ├── docs/ # Documentation
299
+ ├── examples/ # Example projects
300
+ └── pyproject.toml # Project configuration
301
+ ```
302
+
303
+ ## Known Limitations (v0.2.0)
304
+
305
+ - **Bibliography**: BibTeX integration not yet supported
306
+ - **Glossary**: Glossary generation not yet supported
307
+
308
+ See full requirements verification in project documentation.
309
+
310
+ ## Documentation
311
+
312
+ - [Installation Guide](docs/installation.rst)
313
+ - [Usage Guide](docs/usage.rst)
314
+ - [Configuration Reference](docs/configuration.rst)
315
+ - [Examples](examples/)
316
+
317
+ ## Contributing
318
+
319
+ Contributions are welcome! Please:
320
+
321
+ 1. Fork the repository
322
+ 2. Create a feature branch
323
+ 3. Write tests for new features
324
+ 4. Ensure all tests pass: `uv run pytest`
325
+ 5. Submit a pull request
326
+
327
+ ### Development Guidelines
328
+
329
+ - Follow TDD (Test-Driven Development)
330
+ - Maintain 80%+ code coverage
331
+ - Use black for code formatting
332
+ - Follow Sphinx extension conventions
333
+ - Add tests for all new features
334
+
335
+ ## License
336
+
337
+ MIT License - see [LICENSE](LICENSE) file for details.
338
+
339
+ ## Acknowledgments
340
+
341
+ - Built on top of [Sphinx](https://www.sphinx-doc.org/)
342
+ - Uses [Typst](https://typst.app/) for typesetting
343
+ - Integrates [mitex](https://github.com/mitex-rs/mitex) for LaTeX math
344
+ - Uses [codly](https://typst.app/universe/package/codly) for code highlighting
345
+ - Uses [gentle-clues](https://typst.app/universe/package/gentle-clues) for admonitions
346
+ - Developed with [Claude Code](https://claude.ai/code) and Kiro-style Spec-Driven Development
347
+
348
+ ## Version History
349
+
350
+ See [CHANGELOG.md](CHANGELOG.md) for detailed version history.
351
+
352
+ ---
353
+
354
+ **Status**: Stable (v0.2.2) - Production ready
355
+ **Python**: 3.9+ | **Sphinx**: 5.0+ | **Typst**: 0.11.1+
@@ -0,0 +1,13 @@
1
+ typsphinx/__init__.py,sha256=0Ufg4ynUM70hFs7WQpxJEQ9jFh0K-QRVa19gPIJz6Vk,2011
2
+ typsphinx/builder.py,sha256=Dk0qPp7EH8BjzOST_HgkaQqbWNi7cZD6wzQXLx_wOog,10520
3
+ typsphinx/pdf.py,sha256=7iTjd9Pdo17dM-_29TjdD2wjQGZxDhH1DbRDV0d1xpk,5577
4
+ typsphinx/template_engine.py,sha256=jsjOT-2vborHkp8w10d0CMMSnKa07DYFd7NdPQ1xI5I,14934
5
+ typsphinx/translator.py,sha256=xIq7xMBHdPslFhB8KTSP2BCSu7TcDQ9764JMbe9r0UI,48497
6
+ typsphinx/writer.py,sha256=n0M6br3Xdk_L6nsL_o06Xo83nh2iLabfbUDvWmbbb3Y,5027
7
+ typsphinx/templates/base.typ,sha256=E6eMJzzwzY4tjJTyQUVeY6ecHj30Eg00VnX_6de6wZg,2024
8
+ typsphinx-0.3.0.dist-info/licenses/LICENSE,sha256=hhDy2B1WzKS4HadL0kpNQO_LLJCpzAeqlmNvhdVijhk,1068
9
+ typsphinx-0.3.0.dist-info/METADATA,sha256=BzFho6QZ94kS8ExCNli8AhBoslF-2FC8hdUFAcohGEY,10419
10
+ typsphinx-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
+ typsphinx-0.3.0.dist-info/entry_points.txt,sha256=FUPwoj8Z8mx2q0v33yxTO1dlqtgbJc9FkY66rOlb01o,57
12
+ typsphinx-0.3.0.dist-info/top_level.txt,sha256=08jmdf7hvCEFJ6UTjz8Od31dUpPK39jZJy4o73iUdyA,10
13
+ typsphinx-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [sphinx.builders]
2
+ typst = typsphinx
3
+ typstpdf = typsphinx
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 YuSabo90002
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ typsphinx