typsphinx 0.6.0__tar.gz → 0.6.2__tar.gz
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-0.6.0/typsphinx.egg-info → typsphinx-0.6.2}/PKG-INFO +14 -21
- {typsphinx-0.6.0 → typsphinx-0.6.2}/README.md +13 -20
- {typsphinx-0.6.0 → typsphinx-0.6.2}/pyproject.toml +3 -3
- typsphinx-0.6.2/tests/test_abbr_pep_separator_render_gate.py +236 -0
- typsphinx-0.6.2/tests/test_builder_output_stem.py +327 -0
- typsphinx-0.6.2/tests/test_codly_caption_listitem_leak_render_gate.py +205 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_config_other_options.py +0 -41
- typsphinx-0.6.2/tests/test_confval_field_spacing_render_gate.py +222 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_corpus_gate.py +40 -21
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_cross_doc_label_namespace_render_gate.py +20 -4
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_deflist_term_concat_render_gate.py +132 -0
- typsphinx-0.6.2/tests/test_desc_bodyless_concat_render_gate.py +154 -0
- typsphinx-0.6.2/tests/test_desc_sig_space_render_gate.py +254 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_desc_signature_concat_render_gate.py +101 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_documentation_configuration.py +1 -1
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_examples_basic.py +20 -6
- typsphinx-0.6.2/tests/test_examples_charged_ieee_gate.py +249 -0
- typsphinx-0.6.2/tests/test_external_link_style_render_gate.py +303 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_field_list_in_list_item_render_gate.py +93 -3
- typsphinx-0.6.2/tests/test_inline_literal_overflow_render_gate.py +232 -0
- typsphinx-0.6.2/tests/test_missing_and_malformed_master_gate.py +230 -0
- typsphinx-0.6.2/tests/test_nested_master_render_gate.py +692 -0
- typsphinx-0.6.2/tests/test_package_only_config_gate.py +538 -0
- typsphinx-0.6.2/tests/test_package_template_routing.py +199 -0
- typsphinx-0.6.2/tests/test_paragraph_concat_render_gate.py +157 -0
- typsphinx-0.6.2/tests/test_paragraph_soft_newline_render_gate.py +198 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_pdf_generation.py +222 -12
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_pdf_render_gate.py +559 -1
- typsphinx-0.6.2/tests/test_readme_version_sync.py +75 -0
- typsphinx-0.6.2/tests/test_rubric_option_concat_render_gate.py +166 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_table_in_list_item_render_gate.py +8 -2
- typsphinx-0.6.2/tests/test_target_name_render_gate.py +164 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_template_engine.py +203 -50
- typsphinx-0.6.2/tests/test_template_import_path.py +302 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_translator.py +19 -5
- typsphinx-0.6.2/tests/test_wide_table_render_gate.py +209 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/typsphinx/__init__.py +1 -3
- {typsphinx-0.6.0 → typsphinx-0.6.2}/typsphinx/builder.py +262 -23
- {typsphinx-0.6.0 → typsphinx-0.6.2}/typsphinx/pdf.py +55 -17
- {typsphinx-0.6.0 → typsphinx-0.6.2}/typsphinx/template_engine.py +87 -63
- {typsphinx-0.6.0 → typsphinx-0.6.2}/typsphinx/templates/base.typ +12 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/typsphinx/translator.py +420 -28
- typsphinx-0.6.2/typsphinx/writer.py +247 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2/typsphinx.egg-info}/PKG-INFO +14 -21
- {typsphinx-0.6.0 → typsphinx-0.6.2}/typsphinx.egg-info/SOURCES.txt +20 -0
- typsphinx-0.6.0/typsphinx/writer.py +0 -153
- {typsphinx-0.6.0 → typsphinx-0.6.2}/LICENSE +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/setup.cfg +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_admonitions.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_builder.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_builder_requirement13.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_config.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_config_template_mapping.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_config_toctree_defaults.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_confval_field_body_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_deflist_definition_multiblock_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_deflist_nested_definition_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_deflist_term_inline_children_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_desc_container_propagated_target_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_desc_signature_anchor_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_documentation_installation.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_documentation_usage.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_duplicate_include_label_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_entry_points.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_epigraph_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_extension.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_footnotes.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_glob_image_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_inline_references.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_integration_advanced.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_integration_basic.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_integration_multi_doc.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_integration_nested_toctree.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_label_at_char_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_line_blocks.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_list_item_nested_block_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_math_fallback.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_math_mitex.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_math_native.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_nested_toctree_paths.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_paragraph_propagated_target_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_preview_smoke_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_preview_version_sync.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_ref_target_nested_list_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_rubric_propagated_target_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_static_asset_copy_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_substitution_definition_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_target_label_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_template_assets.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_template_codly.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_template_mitex.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_toctree_requirement13.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_topics.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_typst_string_escape_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/tests/test_xref_orphan_degrade_render_gate.py +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/typsphinx.egg-info/dependency_links.txt +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/typsphinx.egg-info/entry_points.txt +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/typsphinx.egg-info/requires.txt +0 -0
- {typsphinx-0.6.0 → typsphinx-0.6.2}/typsphinx.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: typsphinx
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.2
|
|
4
4
|
Summary: Sphinx extension for Typst output
|
|
5
5
|
Author-email: YuSabo <yusabo90002@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -71,7 +71,7 @@ typsphinx is a Sphinx extension that enables generating Typst documents from reS
|
|
|
71
71
|
- Syntax highlighting for multiple languages
|
|
72
72
|
- Highlight specific lines
|
|
73
73
|
- **Images and figures**: Embed images with captions and references
|
|
74
|
-
- **Cross-references
|
|
74
|
+
- **Cross-references**: Maintain document structure with internal links
|
|
75
75
|
- **Customizable templates**: Use default or custom Typst templates
|
|
76
76
|
- **Direct PDF generation**: Self-contained PDF generation via typst-py (no external Typst CLI required)
|
|
77
77
|
- **Multi-document support**: Generate multiple Typst files with toctree integration using `#include()`
|
|
@@ -177,12 +177,6 @@ Create a custom Typst template:
|
|
|
177
177
|
```python
|
|
178
178
|
# conf.py
|
|
179
179
|
typst_template = '_templates/custom.typ'
|
|
180
|
-
|
|
181
|
-
typst_elements = {
|
|
182
|
-
'papersize': 'a4',
|
|
183
|
-
'fontsize': '11pt',
|
|
184
|
-
'lang': 'ja',
|
|
185
|
-
}
|
|
186
180
|
```
|
|
187
181
|
|
|
188
182
|
### Template Parameter Mapping
|
|
@@ -192,12 +186,14 @@ Map Sphinx metadata to template parameters:
|
|
|
192
186
|
```python
|
|
193
187
|
# conf.py
|
|
194
188
|
typst_template_mapping = {
|
|
195
|
-
'
|
|
196
|
-
'
|
|
197
|
-
'
|
|
189
|
+
'project': 'doc_title',
|
|
190
|
+
'author': 'doc_authors',
|
|
191
|
+
'release': 'version',
|
|
198
192
|
}
|
|
199
193
|
```
|
|
200
194
|
|
|
195
|
+
Keys are Sphinx metadata names; values are the template parameter names they map to.
|
|
196
|
+
|
|
201
197
|
### Multi-Document Projects
|
|
202
198
|
|
|
203
199
|
Use toctree to combine multiple documents:
|
|
@@ -246,8 +242,9 @@ For more details, see the [Sphinx Extension API documentation](https://www.sphin
|
|
|
246
242
|
|
|
247
243
|
## Configuration Options
|
|
248
244
|
|
|
249
|
-
|
|
245
|
+
Below are the main configuration options. This is not the complete set — see [docs/source/user_guide/configuration.rst](docs/source/user_guide/configuration.rst) for the full reference:
|
|
250
246
|
|
|
247
|
+
- `typst_documents`: Master documents to build, as `[(source, target, title, author), ...]` — required for PDF output
|
|
251
248
|
- `typst_use_mitex`: Enable/disable mitex for LaTeX math
|
|
252
249
|
- `typst_template`: Custom template path
|
|
253
250
|
- `typst_elements`: Template parameters (paper size, fonts, etc.)
|
|
@@ -264,7 +261,7 @@ This project uses uv for fast package management and follows TDD (Test-Driven De
|
|
|
264
261
|
# Install with development dependencies
|
|
265
262
|
uv sync --extra dev
|
|
266
263
|
|
|
267
|
-
# Run tests
|
|
264
|
+
# Run tests
|
|
268
265
|
uv run pytest
|
|
269
266
|
|
|
270
267
|
# Run tests with coverage report
|
|
@@ -284,10 +281,9 @@ uv run tox -e docs # Build both HTML and PDF docs
|
|
|
284
281
|
|
|
285
282
|
### Testing Strategy
|
|
286
283
|
|
|
287
|
-
- **Unit tests**:
|
|
284
|
+
- **Unit tests**: Cover all major components
|
|
288
285
|
- **Integration tests**: Full build process validation
|
|
289
286
|
- **Example projects**: `examples/basic/` and `examples/advanced/`
|
|
290
|
-
- **Code coverage**: 93% overall
|
|
291
287
|
|
|
292
288
|
### Project Structure
|
|
293
289
|
|
|
@@ -309,9 +305,7 @@ typsphinx/
|
|
|
309
305
|
## Known Limitations
|
|
310
306
|
|
|
311
307
|
- **Bibliography**: BibTeX integration not yet supported
|
|
312
|
-
- **
|
|
313
|
-
|
|
314
|
-
See full requirements verification in project documentation.
|
|
308
|
+
- **Citations**: reStructuredText citation directives are not yet supported
|
|
315
309
|
|
|
316
310
|
## Documentation
|
|
317
311
|
|
|
@@ -340,7 +334,6 @@ Contributions are welcome! Please:
|
|
|
340
334
|
### Development Guidelines
|
|
341
335
|
|
|
342
336
|
- Follow TDD (Test-Driven Development)
|
|
343
|
-
- Maintain 80%+ code coverage
|
|
344
337
|
- Use black for code formatting
|
|
345
338
|
- Follow Sphinx extension conventions
|
|
346
339
|
- Add tests for all new features
|
|
@@ -356,7 +349,7 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
356
349
|
- Integrates [mitex](https://github.com/mitex-rs/mitex) for LaTeX math
|
|
357
350
|
- Uses [codly](https://typst.app/universe/package/codly) for code highlighting
|
|
358
351
|
- Uses [gentle-clues](https://typst.app/universe/package/gentle-clues) for admonitions
|
|
359
|
-
- Developed with [Claude Code](https://claude.ai/code) and
|
|
352
|
+
- Developed with [Claude Code](https://claude.ai/code) and [GSD](https://github.com/open-gsd/gsd-core) (spec-driven development for AI coding agents)
|
|
360
353
|
|
|
361
354
|
## Version History
|
|
362
355
|
|
|
@@ -364,5 +357,5 @@ See [CHANGELOG.md](CHANGELOG.md) for detailed version history.
|
|
|
364
357
|
|
|
365
358
|
---
|
|
366
359
|
|
|
367
|
-
**Status**: Stable (v0.
|
|
360
|
+
**Status**: Stable (v0.6.2) - Production ready
|
|
368
361
|
**Python**: 3.12+ | **Sphinx**: 9.1+ | **Typst**: 0.15+
|
|
@@ -27,7 +27,7 @@ typsphinx is a Sphinx extension that enables generating Typst documents from reS
|
|
|
27
27
|
- Syntax highlighting for multiple languages
|
|
28
28
|
- Highlight specific lines
|
|
29
29
|
- **Images and figures**: Embed images with captions and references
|
|
30
|
-
- **Cross-references
|
|
30
|
+
- **Cross-references**: Maintain document structure with internal links
|
|
31
31
|
- **Customizable templates**: Use default or custom Typst templates
|
|
32
32
|
- **Direct PDF generation**: Self-contained PDF generation via typst-py (no external Typst CLI required)
|
|
33
33
|
- **Multi-document support**: Generate multiple Typst files with toctree integration using `#include()`
|
|
@@ -133,12 +133,6 @@ Create a custom Typst template:
|
|
|
133
133
|
```python
|
|
134
134
|
# conf.py
|
|
135
135
|
typst_template = '_templates/custom.typ'
|
|
136
|
-
|
|
137
|
-
typst_elements = {
|
|
138
|
-
'papersize': 'a4',
|
|
139
|
-
'fontsize': '11pt',
|
|
140
|
-
'lang': 'ja',
|
|
141
|
-
}
|
|
142
136
|
```
|
|
143
137
|
|
|
144
138
|
### Template Parameter Mapping
|
|
@@ -148,12 +142,14 @@ Map Sphinx metadata to template parameters:
|
|
|
148
142
|
```python
|
|
149
143
|
# conf.py
|
|
150
144
|
typst_template_mapping = {
|
|
151
|
-
'
|
|
152
|
-
'
|
|
153
|
-
'
|
|
145
|
+
'project': 'doc_title',
|
|
146
|
+
'author': 'doc_authors',
|
|
147
|
+
'release': 'version',
|
|
154
148
|
}
|
|
155
149
|
```
|
|
156
150
|
|
|
151
|
+
Keys are Sphinx metadata names; values are the template parameter names they map to.
|
|
152
|
+
|
|
157
153
|
### Multi-Document Projects
|
|
158
154
|
|
|
159
155
|
Use toctree to combine multiple documents:
|
|
@@ -202,8 +198,9 @@ For more details, see the [Sphinx Extension API documentation](https://www.sphin
|
|
|
202
198
|
|
|
203
199
|
## Configuration Options
|
|
204
200
|
|
|
205
|
-
|
|
201
|
+
Below are the main configuration options. This is not the complete set — see [docs/source/user_guide/configuration.rst](docs/source/user_guide/configuration.rst) for the full reference:
|
|
206
202
|
|
|
203
|
+
- `typst_documents`: Master documents to build, as `[(source, target, title, author), ...]` — required for PDF output
|
|
207
204
|
- `typst_use_mitex`: Enable/disable mitex for LaTeX math
|
|
208
205
|
- `typst_template`: Custom template path
|
|
209
206
|
- `typst_elements`: Template parameters (paper size, fonts, etc.)
|
|
@@ -220,7 +217,7 @@ This project uses uv for fast package management and follows TDD (Test-Driven De
|
|
|
220
217
|
# Install with development dependencies
|
|
221
218
|
uv sync --extra dev
|
|
222
219
|
|
|
223
|
-
# Run tests
|
|
220
|
+
# Run tests
|
|
224
221
|
uv run pytest
|
|
225
222
|
|
|
226
223
|
# Run tests with coverage report
|
|
@@ -240,10 +237,9 @@ uv run tox -e docs # Build both HTML and PDF docs
|
|
|
240
237
|
|
|
241
238
|
### Testing Strategy
|
|
242
239
|
|
|
243
|
-
- **Unit tests**:
|
|
240
|
+
- **Unit tests**: Cover all major components
|
|
244
241
|
- **Integration tests**: Full build process validation
|
|
245
242
|
- **Example projects**: `examples/basic/` and `examples/advanced/`
|
|
246
|
-
- **Code coverage**: 93% overall
|
|
247
243
|
|
|
248
244
|
### Project Structure
|
|
249
245
|
|
|
@@ -265,9 +261,7 @@ typsphinx/
|
|
|
265
261
|
## Known Limitations
|
|
266
262
|
|
|
267
263
|
- **Bibliography**: BibTeX integration not yet supported
|
|
268
|
-
- **
|
|
269
|
-
|
|
270
|
-
See full requirements verification in project documentation.
|
|
264
|
+
- **Citations**: reStructuredText citation directives are not yet supported
|
|
271
265
|
|
|
272
266
|
## Documentation
|
|
273
267
|
|
|
@@ -296,7 +290,6 @@ Contributions are welcome! Please:
|
|
|
296
290
|
### Development Guidelines
|
|
297
291
|
|
|
298
292
|
- Follow TDD (Test-Driven Development)
|
|
299
|
-
- Maintain 80%+ code coverage
|
|
300
293
|
- Use black for code formatting
|
|
301
294
|
- Follow Sphinx extension conventions
|
|
302
295
|
- Add tests for all new features
|
|
@@ -312,7 +305,7 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
312
305
|
- Integrates [mitex](https://github.com/mitex-rs/mitex) for LaTeX math
|
|
313
306
|
- Uses [codly](https://typst.app/universe/package/codly) for code highlighting
|
|
314
307
|
- Uses [gentle-clues](https://typst.app/universe/package/gentle-clues) for admonitions
|
|
315
|
-
- Developed with [Claude Code](https://claude.ai/code) and
|
|
308
|
+
- Developed with [Claude Code](https://claude.ai/code) and [GSD](https://github.com/open-gsd/gsd-core) (spec-driven development for AI coding agents)
|
|
316
309
|
|
|
317
310
|
## Version History
|
|
318
311
|
|
|
@@ -320,5 +313,5 @@ See [CHANGELOG.md](CHANGELOG.md) for detailed version history.
|
|
|
320
313
|
|
|
321
314
|
---
|
|
322
315
|
|
|
323
|
-
**Status**: Stable (v0.
|
|
316
|
+
**Status**: Stable (v0.6.2) - Production ready
|
|
324
317
|
**Python**: 3.12+ | **Sphinx**: 9.1+ | **Typst**: 0.15+
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "typsphinx"
|
|
7
|
-
version = "0.6.
|
|
7
|
+
version = "0.6.2"
|
|
8
8
|
description = "Sphinx extension for Typst output"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
@@ -119,8 +119,8 @@ ignore = [
|
|
|
119
119
|
"E501", # Line too long (handled by black)
|
|
120
120
|
"T201", # print found (used in tests for debugging)
|
|
121
121
|
"B017", # asserting blind exception in tests
|
|
122
|
-
"UP035", # typing.Dict/List/Set deprecation (
|
|
123
|
-
"UP006", # Use dict instead of Dict
|
|
122
|
+
"UP035", # typing.Dict/List/Set deprecation; modernization deferred (see .planning/todos/pending/2026-07-22-modernize-typing-imports-drop-up006-up035-ignore.md)
|
|
123
|
+
"UP006", # Use dict instead of Dict; same deferral as UP035 above
|
|
124
124
|
"UP028", # yield from (minor optimization)
|
|
125
125
|
"N802", # Function naming (docutils visitor pattern uses PascalCase)
|
|
126
126
|
"A001", # Shadowing builtins (copyright in conf.py is Sphinx convention)
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Real-compile regression gate for the narrow-scope abbr-title suppression fix
|
|
3
|
+
(FID-14, Phase 21 Plan 02, GATE-01).
|
|
4
|
+
|
|
5
|
+
The shipping bug: Sphinx's Python-domain signature renderer wraps the
|
|
6
|
+
auto-generated PEP 3102 keyword-only ``*`` and PEP 570 positional-only ``/``
|
|
7
|
+
signature separators in a genuine ``docutils.nodes.abbreviation`` node whose
|
|
8
|
+
own visible text (``node.astext()``) is exactly the single character ``*``
|
|
9
|
+
or ``/``. ``depart_abbreviation`` unconditionally appended the node's
|
|
10
|
+
``<abbr>`` hover-title explanation inline for EVERY ``abbreviation`` node,
|
|
11
|
+
so every affected signature rendered with the clutter ``"*
|
|
12
|
+
(Keyword-only parameters separator (PEP 3102))"`` / ``"/ (Positional-only
|
|
13
|
+
parameter separator (PEP 570))"`` inline.
|
|
14
|
+
|
|
15
|
+
Fix: ``depart_abbreviation`` now narrows its existing ``if explanation:``
|
|
16
|
+
guard to ``if explanation and node.astext() not in ("*", "/"):`` -- the
|
|
17
|
+
explanation is suppressed ONLY for the two auto-generated separators (whose
|
|
18
|
+
own node text is exactly ``"*"``/``"/"``); a genuine ``:abbr:`` role's
|
|
19
|
+
acronym text is never bare ``"*"``/``"/"``, so it keeps its inline
|
|
20
|
+
expansion unchanged (D-Disc-3, narrow scope).
|
|
21
|
+
|
|
22
|
+
Confirmed against the pre-fix translator this session: ``index.typ``
|
|
23
|
+
contained ``text(" (Positional-only parameter separator (PEP 570))")`` and
|
|
24
|
+
``text(" (Keyword-only parameters separator (PEP 3102))")`` inline in the
|
|
25
|
+
signature's parameter-list concat, and the extracted PDF text read
|
|
26
|
+
``"abbrpepsepfunc(pos_only, / (Positional-only parameter separator (PEP
|
|
27
|
+
570)), both, * (Keyword-only parameters separator (PEP 3102)), kw_only)"``
|
|
28
|
+
-- both fail the asserts below pre-fix. The genuine ``:abbr:`` usage in the
|
|
29
|
+
same fixture (``ABBRSENTINELACRONYM (ABBRSENTINELEXPANSIONPHRASE)``) already
|
|
30
|
+
passes pre-fix and must continue to pass post-fix (D-Disc-3 regression
|
|
31
|
+
guard).
|
|
32
|
+
|
|
33
|
+
Verification is Shape-B (structural + pypdf, D-10): a structural ``.typ``
|
|
34
|
+
assert plus a pypdf extracted-text adjacency assert, since FID-14's fix IS
|
|
35
|
+
text-extractable (unlike FID-11's non-extractable vertical-layout property).
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
import subprocess
|
|
39
|
+
import sys
|
|
40
|
+
from pathlib import Path
|
|
41
|
+
|
|
42
|
+
import pytest
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
import typst # noqa: F401
|
|
46
|
+
|
|
47
|
+
TYPST_AVAILABLE = True
|
|
48
|
+
except ImportError:
|
|
49
|
+
TYPST_AVAILABLE = False
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
import pypdf
|
|
53
|
+
|
|
54
|
+
PYPDF_AVAILABLE = True
|
|
55
|
+
except ImportError:
|
|
56
|
+
PYPDF_AVAILABLE = False
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@pytest.fixture
|
|
60
|
+
def abbr_pep_separator_render_gate_dir():
|
|
61
|
+
"""Return the path to the abbr_pep_separator_render_gate fixture."""
|
|
62
|
+
return Path(__file__).parent / "fixtures" / "abbr_pep_separator_render_gate"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@pytest.fixture
|
|
66
|
+
def temp_build_dir(tmp_path):
|
|
67
|
+
"""Provide a temporary directory for build output."""
|
|
68
|
+
return tmp_path / "_build"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _run_sphinx_build_typstpdf(
|
|
72
|
+
source_dir: Path, build_dir: Path
|
|
73
|
+
) -> subprocess.CompletedProcess:
|
|
74
|
+
"""
|
|
75
|
+
Run ``sphinx-build -b typstpdf`` as a subprocess and return the completed
|
|
76
|
+
process (stdout/stderr captured as text).
|
|
77
|
+
|
|
78
|
+
Invoked as ``sys.executable -m sphinx`` (never ``uv run sphinx-build``)
|
|
79
|
+
so the exact interpreter/venv running this test is reused, sidestepping
|
|
80
|
+
the documented NixOS-sandbox PATH-shadowing hazard.
|
|
81
|
+
"""
|
|
82
|
+
return subprocess.run(
|
|
83
|
+
[
|
|
84
|
+
sys.executable,
|
|
85
|
+
"-m",
|
|
86
|
+
"sphinx",
|
|
87
|
+
"-b",
|
|
88
|
+
"typstpdf",
|
|
89
|
+
str(source_dir),
|
|
90
|
+
str(build_dir),
|
|
91
|
+
],
|
|
92
|
+
capture_output=True,
|
|
93
|
+
text=True,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@pytest.mark.skipif(
|
|
98
|
+
not TYPST_AVAILABLE,
|
|
99
|
+
reason="typst-py is required for the abbr-pep-separator render gate",
|
|
100
|
+
)
|
|
101
|
+
class TestAbbrPepSeparatorRenderGate:
|
|
102
|
+
"""
|
|
103
|
+
Real-compile regression gate proving the PEP 3102 ``*`` / PEP 570 ``/``
|
|
104
|
+
signature separators no longer inject their ``<abbr>`` hover-title text
|
|
105
|
+
inline, while a genuine ``:abbr:`` role usage in the same document keeps
|
|
106
|
+
its inline expansion unchanged.
|
|
107
|
+
|
|
108
|
+
Requirements: FID-14, GATE-01.
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
def test_typstpdf_abbr_pep_separator_produces_pdf_with_structural_suppression(
|
|
112
|
+
self, abbr_pep_separator_render_gate_dir, temp_build_dir
|
|
113
|
+
):
|
|
114
|
+
"""
|
|
115
|
+
Build the fixture through ``-b typstpdf`` and confirm, at the
|
|
116
|
+
SOURCE (``.typ``) level:
|
|
117
|
+
|
|
118
|
+
- the build exits cleanly and did not report a compile failure;
|
|
119
|
+
- the signature's parameter-list concat does NOT append the
|
|
120
|
+
PEP-separator hover-title explanation text for the ``*``/``/``
|
|
121
|
+
cases;
|
|
122
|
+
- the genuine ``:abbr:`` usage DOES still append its expansion
|
|
123
|
+
text -- ``text(" (ABBRSENTINELEXPANSIONPHRASE)")`` is present;
|
|
124
|
+
- ``index.pdf`` exists, is non-empty, and begins with the ``%PDF``
|
|
125
|
+
magic bytes (real ``typst.compile()`` succeeded).
|
|
126
|
+
"""
|
|
127
|
+
result = _run_sphinx_build_typstpdf(
|
|
128
|
+
abbr_pep_separator_render_gate_dir, temp_build_dir
|
|
129
|
+
)
|
|
130
|
+
assert result.returncode == 0, (
|
|
131
|
+
f"sphinx-build -b typstpdf failed:\n"
|
|
132
|
+
f"stdout: {result.stdout}\n"
|
|
133
|
+
f"stderr: {result.stderr}"
|
|
134
|
+
)
|
|
135
|
+
assert "Typst compilation failed" not in result.stderr, (
|
|
136
|
+
"TypstPDFBuilder.finish() logged a compilation failure:\n"
|
|
137
|
+
f"stderr: {result.stderr}"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
typ_output = temp_build_dir / "index.typ"
|
|
141
|
+
assert typ_output.exists(), "index.typ was not emitted"
|
|
142
|
+
typ_text = typ_output.read_text(encoding="utf-8")
|
|
143
|
+
|
|
144
|
+
# Structural: the PEP-separator hover-title text must not be
|
|
145
|
+
# appended anywhere in the emitted .typ for the *"/"/ cases.
|
|
146
|
+
assert "Keyword-only parameters separator" not in typ_text, (
|
|
147
|
+
"Found the PEP 3102 '*' separator's hover-title text in the "
|
|
148
|
+
f"emitted .typ -- the FID-14 fix is not applied:\n{typ_text}"
|
|
149
|
+
)
|
|
150
|
+
assert "Positional-only parameter separator" not in typ_text, (
|
|
151
|
+
"Found the PEP 570 '/' separator's hover-title text in the "
|
|
152
|
+
f"emitted .typ -- the FID-14 fix is not applied:\n{typ_text}"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Regression: the genuine :abbr: usage in the SAME fixture must
|
|
156
|
+
# still append its expansion (D-Disc-3's narrow-scope requirement).
|
|
157
|
+
assert 'text(" (ABBRSENTINELEXPANSIONPHRASE)")' in typ_text, (
|
|
158
|
+
"Expected the genuine :abbr: role's expansion to still be "
|
|
159
|
+
"appended inline -- the FID-14 fix must not suppress a real "
|
|
160
|
+
f":abbr: usage:\n{typ_text}"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# The emitted .typ must have compiled to a real, non-empty PDF.
|
|
164
|
+
pdf_output = temp_build_dir / "index.pdf"
|
|
165
|
+
assert pdf_output.exists(), (
|
|
166
|
+
"index.pdf was not produced:\n" f"stderr: {result.stderr}"
|
|
167
|
+
)
|
|
168
|
+
assert pdf_output.stat().st_size > 0, "PDF file is empty"
|
|
169
|
+
with open(pdf_output, "rb") as f:
|
|
170
|
+
magic = f.read(4)
|
|
171
|
+
assert magic == b"%PDF", "Generated file is not a valid PDF"
|
|
172
|
+
|
|
173
|
+
@pytest.mark.skipif(
|
|
174
|
+
not PYPDF_AVAILABLE,
|
|
175
|
+
reason="pypdf is required for the extracted-text adjacency assert",
|
|
176
|
+
)
|
|
177
|
+
def test_pdf_extracted_text_suppresses_pep_separator_titles_only(
|
|
178
|
+
self, abbr_pep_separator_render_gate_dir, temp_build_dir
|
|
179
|
+
):
|
|
180
|
+
"""
|
|
181
|
+
Build the fixture through ``-b typstpdf``, extract the compiled
|
|
182
|
+
PDF's text with pypdf, and confirm (D-10 required adjacency
|
|
183
|
+
assert):
|
|
184
|
+
|
|
185
|
+
- ``"(Keyword-only parameters separator"`` is ABSENT from the
|
|
186
|
+
extracted signature text;
|
|
187
|
+
- ``"(Positional-only parameter separator"`` is ABSENT from the
|
|
188
|
+
extracted signature text;
|
|
189
|
+
- the plain ``/`` and ``*`` separator characters are still present
|
|
190
|
+
in the signature (suppression removes only the appended
|
|
191
|
+
explanation segment, not the separator itself);
|
|
192
|
+
- the genuine ``:abbr:`` expansion sentinel phrase IS present.
|
|
193
|
+
"""
|
|
194
|
+
result = _run_sphinx_build_typstpdf(
|
|
195
|
+
abbr_pep_separator_render_gate_dir, temp_build_dir
|
|
196
|
+
)
|
|
197
|
+
assert result.returncode == 0, (
|
|
198
|
+
f"sphinx-build -b typstpdf failed:\n"
|
|
199
|
+
f"stdout: {result.stdout}\n"
|
|
200
|
+
f"stderr: {result.stderr}"
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
pdf_output = temp_build_dir / "index.pdf"
|
|
204
|
+
assert pdf_output.exists(), (
|
|
205
|
+
"index.pdf was not produced:\n" f"stderr: {result.stderr}"
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
reader = pypdf.PdfReader(str(pdf_output))
|
|
209
|
+
full_text = "\n".join(page.extract_text() for page in reader.pages)
|
|
210
|
+
|
|
211
|
+
assert "(Keyword-only parameters separator" not in full_text, (
|
|
212
|
+
"Found the PEP 3102 '*' separator's hover-title text in the "
|
|
213
|
+
f"extracted PDF text -- the FID-14 fix is not in effect:\n"
|
|
214
|
+
f"{full_text}"
|
|
215
|
+
)
|
|
216
|
+
assert "(Positional-only parameter separator" not in full_text, (
|
|
217
|
+
"Found the PEP 570 '/' separator's hover-title text in the "
|
|
218
|
+
f"extracted PDF text -- the FID-14 fix is not in effect:\n"
|
|
219
|
+
f"{full_text}"
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
# The separator characters themselves must remain in the signature.
|
|
223
|
+
assert "abbrpepsepfunc(pos_only, /" in full_text, (
|
|
224
|
+
"Expected the '/' positional-only separator to remain in the "
|
|
225
|
+
f"rendered signature:\n{full_text}"
|
|
226
|
+
)
|
|
227
|
+
assert ", both, *" in full_text, (
|
|
228
|
+
"Expected the '*' keyword-only separator to remain in the "
|
|
229
|
+
f"rendered signature:\n{full_text}"
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
# The genuine :abbr: usage must keep its inline expansion.
|
|
233
|
+
assert "ABBRSENTINELACRONYM (ABBRSENTINELEXPANSIONPHRASE)" in full_text, (
|
|
234
|
+
"Expected the genuine :abbr: role's inline expansion to remain "
|
|
235
|
+
f"present -- the FID-14 fix must not suppress it:\n{full_text}"
|
|
236
|
+
)
|