typsphinx 0.4.2__tar.gz → 0.4.4__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.
Files changed (49) hide show
  1. {typsphinx-0.4.2/typsphinx.egg-info → typsphinx-0.4.4}/PKG-INFO +20 -18
  2. {typsphinx-0.4.2 → typsphinx-0.4.4}/README.md +4 -3
  3. {typsphinx-0.4.2 → typsphinx-0.4.4}/pyproject.toml +21 -20
  4. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_config_other_options.py +20 -40
  5. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_config_toctree_defaults.py +4 -8
  6. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_entry_points.py +2 -13
  7. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_inline_references.py +151 -0
  8. typsphinx-0.4.4/tests/test_preview_version_sync.py +105 -0
  9. typsphinx-0.4.4/tests/test_template_assets.py +403 -0
  10. {typsphinx-0.4.2 → typsphinx-0.4.4}/typsphinx/__init__.py +4 -2
  11. {typsphinx-0.4.2 → typsphinx-0.4.4}/typsphinx/builder.py +179 -4
  12. {typsphinx-0.4.2 → typsphinx-0.4.4}/typsphinx/pdf.py +3 -4
  13. {typsphinx-0.4.2 → typsphinx-0.4.4}/typsphinx/template_engine.py +12 -12
  14. {typsphinx-0.4.2 → typsphinx-0.4.4}/typsphinx/translator.py +31 -8
  15. {typsphinx-0.4.2 → typsphinx-0.4.4/typsphinx.egg-info}/PKG-INFO +20 -18
  16. {typsphinx-0.4.2 → typsphinx-0.4.4}/typsphinx.egg-info/SOURCES.txt +2 -0
  17. typsphinx-0.4.4/typsphinx.egg-info/requires.txt +24 -0
  18. typsphinx-0.4.2/typsphinx.egg-info/requires.txt +0 -21
  19. {typsphinx-0.4.2 → typsphinx-0.4.4}/LICENSE +0 -0
  20. {typsphinx-0.4.2 → typsphinx-0.4.4}/setup.cfg +0 -0
  21. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_admonitions.py +0 -0
  22. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_builder.py +0 -0
  23. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_builder_requirement13.py +0 -0
  24. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_config.py +0 -0
  25. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_config_template_mapping.py +0 -0
  26. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_documentation_configuration.py +0 -0
  27. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_documentation_installation.py +0 -0
  28. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_documentation_usage.py +0 -0
  29. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_examples_basic.py +0 -0
  30. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_extension.py +0 -0
  31. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_integration_advanced.py +0 -0
  32. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_integration_basic.py +0 -0
  33. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_integration_multi_doc.py +0 -0
  34. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_integration_nested_toctree.py +0 -0
  35. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_math_fallback.py +0 -0
  36. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_math_mitex.py +0 -0
  37. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_math_native.py +0 -0
  38. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_nested_toctree_paths.py +0 -0
  39. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_pdf_generation.py +0 -0
  40. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_template_codly.py +0 -0
  41. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_template_engine.py +0 -0
  42. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_template_mitex.py +0 -0
  43. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_toctree_requirement13.py +0 -0
  44. {typsphinx-0.4.2 → typsphinx-0.4.4}/tests/test_translator.py +0 -0
  45. {typsphinx-0.4.2 → typsphinx-0.4.4}/typsphinx/templates/base.typ +0 -0
  46. {typsphinx-0.4.2 → typsphinx-0.4.4}/typsphinx/writer.py +0 -0
  47. {typsphinx-0.4.2 → typsphinx-0.4.4}/typsphinx.egg-info/dependency_links.txt +0 -0
  48. {typsphinx-0.4.2 → typsphinx-0.4.4}/typsphinx.egg-info/entry_points.txt +0 -0
  49. {typsphinx-0.4.2 → typsphinx-0.4.4}/typsphinx.egg-info/top_level.txt +0 -0
@@ -1,39 +1,38 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: typsphinx
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: Sphinx extension for Typst output
5
- Author-email: Sphinx Typst Contributors <noreply@example.com>
5
+ Author-email: YuSabo <yusabo90002@gmail.com>
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/YuSabo90002/typsphinx
8
8
  Project-URL: Documentation, https://github.com/YuSabo90002/typsphinx#readme
9
9
  Project-URL: Repository, https://github.com/YuSabo90002/typsphinx
10
10
  Project-URL: Issues, https://github.com/YuSabo90002/typsphinx/issues
11
11
  Keywords: sphinx,typst,documentation,pdf
12
- Classifier: Development Status :: 4 - Beta
12
+ Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Framework :: Sphinx :: Extension
14
14
  Classifier: Intended Audience :: Developers
15
15
  Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.9
17
16
  Classifier: Programming Language :: Python :: 3.10
18
17
  Classifier: Programming Language :: Python :: 3.11
19
18
  Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
20
  Classifier: Topic :: Documentation :: Sphinx
21
21
  Classifier: Topic :: Software Development :: Documentation
22
- Requires-Python: >=3.9
22
+ Requires-Python: >=3.10
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
- Requires-Dist: sphinx>=5.0
26
- Requires-Dist: docutils>=0.18
27
- Requires-Dist: typst>=0.11.1
25
+ Requires-Dist: sphinx<9,>=5.0
26
+ Requires-Dist: docutils<0.22,>=0.18
27
+ Requires-Dist: typst<0.15,>=0.14.1
28
28
  Provides-Extra: dev
29
- Requires-Dist: pytest>=7.0; extra == "dev"
29
+ Requires-Dist: pytest<10,>=8.4; extra == "dev"
30
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"
31
+ Requires-Dist: tox<5,>=4.56; extra == "dev"
32
+ Requires-Dist: tox-uv<2,>=1.35; extra == "dev"
33
+ Requires-Dist: black<27,>=26; extra == "dev"
34
+ Requires-Dist: ruff<0.16,>=0.15; extra == "dev"
35
+ Requires-Dist: mypy<3.0,>=1.13; extra == "dev"
37
36
  Requires-Dist: pre-commit>=3.0; extra == "dev"
38
37
  Requires-Dist: types-docutils>=0.18; extra == "dev"
39
38
  Requires-Dist: twine>=5.0; extra == "dev"
@@ -41,10 +40,13 @@ Requires-Dist: build>=1.0; extra == "dev"
41
40
  Provides-Extra: docs
42
41
  Requires-Dist: furo>=2024.0; extra == "docs"
43
42
  Requires-Dist: sphinx-autodoc-typehints>=1.0; extra == "docs"
43
+ Requires-Dist: sphinx-intl>=2.0; extra == "docs"
44
+ Requires-Dist: tomli>=2.0; python_version < "3.11" and extra == "docs"
44
45
  Dynamic: license-file
45
46
 
46
47
  # typsphinx
47
48
 
49
+ [![CI](https://github.com/YuSabo90002/typsphinx/actions/workflows/ci.yml/badge.svg)](https://github.com/YuSabo90002/typsphinx/actions/workflows/ci.yml)
48
50
  [![PyPI version](https://badge.fury.io/py/typsphinx.svg)](https://badge.fury.io/py/typsphinx)
49
51
  [![Python Support](https://img.shields.io/pypi/pyversions/typsphinx.svg)](https://pypi.org/project/typsphinx/)
50
52
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -78,13 +80,13 @@ typsphinx is a Sphinx extension that enables generating Typst documents from reS
78
80
 
79
81
  ## Requirements
80
82
 
81
- - Python 3.9 or higher
83
+ - Python 3.10 or higher
82
84
  - Sphinx 5.0 or higher
83
85
  - typst-py 0.11.1 or higher
84
86
 
85
87
  ## Installation
86
88
 
87
- ### From PyPI (Beta Release)
89
+ ### From PyPI
88
90
 
89
91
  ```bash
90
92
  pip install typsphinx
@@ -365,4 +367,4 @@ See [CHANGELOG.md](CHANGELOG.md) for detailed version history.
365
367
  ---
366
368
 
367
369
  **Status**: Stable (v0.4.2) - Production ready
368
- **Python**: 3.9+ | **Sphinx**: 5.0+ | **Typst**: 0.11.1+
370
+ **Python**: 3.10+ | **Sphinx**: 5.0+ | **Typst**: 0.11.1+
@@ -1,5 +1,6 @@
1
1
  # typsphinx
2
2
 
3
+ [![CI](https://github.com/YuSabo90002/typsphinx/actions/workflows/ci.yml/badge.svg)](https://github.com/YuSabo90002/typsphinx/actions/workflows/ci.yml)
3
4
  [![PyPI version](https://badge.fury.io/py/typsphinx.svg)](https://badge.fury.io/py/typsphinx)
4
5
  [![Python Support](https://img.shields.io/pypi/pyversions/typsphinx.svg)](https://pypi.org/project/typsphinx/)
5
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -33,13 +34,13 @@ typsphinx is a Sphinx extension that enables generating Typst documents from reS
33
34
 
34
35
  ## Requirements
35
36
 
36
- - Python 3.9 or higher
37
+ - Python 3.10 or higher
37
38
  - Sphinx 5.0 or higher
38
39
  - typst-py 0.11.1 or higher
39
40
 
40
41
  ## Installation
41
42
 
42
- ### From PyPI (Beta Release)
43
+ ### From PyPI
43
44
 
44
45
  ```bash
45
46
  pip install typsphinx
@@ -320,4 +321,4 @@ See [CHANGELOG.md](CHANGELOG.md) for detailed version history.
320
321
  ---
321
322
 
322
323
  **Status**: Stable (v0.4.2) - Production ready
323
- **Python**: 3.9+ | **Sphinx**: 5.0+ | **Typst**: 0.11.1+
324
+ **Python**: 3.10+ | **Sphinx**: 5.0+ | **Typst**: 0.11.1+
@@ -4,44 +4,43 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "typsphinx"
7
- version = "0.4.2"
7
+ version = "0.4.4"
8
8
  description = "Sphinx extension for Typst output"
9
9
  readme = "README.md"
10
- requires-python = ">=3.9"
10
+ requires-python = ">=3.10"
11
11
  license = "MIT"
12
12
  authors = [
13
- {name = "Sphinx Typst Contributors", email = "noreply@example.com"}
13
+ {name = "YuSabo", email = "yusabo90002@gmail.com"}
14
14
  ]
15
15
  keywords = ["sphinx", "typst", "documentation", "pdf"]
16
16
  classifiers = [
17
- "Development Status :: 4 - Beta",
17
+ "Development Status :: 5 - Production/Stable",
18
18
  "Framework :: Sphinx :: Extension",
19
19
  "Intended Audience :: Developers",
20
20
  "Programming Language :: Python :: 3",
21
- "Programming Language :: Python :: 3.9",
22
21
  "Programming Language :: Python :: 3.10",
23
22
  "Programming Language :: Python :: 3.11",
24
23
  "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
25
  "Topic :: Documentation :: Sphinx",
26
26
  "Topic :: Software Development :: Documentation",
27
27
  ]
28
28
 
29
29
  dependencies = [
30
- "sphinx>=5.0",
31
- "docutils>=0.18",
32
- "typst>=0.11.1",
30
+ "sphinx>=5.0,<9",
31
+ "docutils>=0.18,<0.22",
32
+ "typst>=0.14.1,<0.15",
33
33
  ]
34
34
 
35
35
  [project.optional-dependencies]
36
36
  dev = [
37
- "pytest>=7.0",
37
+ "pytest>=8.4,<10",
38
38
  "pytest-cov>=4.0",
39
- "tox>=4.0",
40
- "tox-uv>=1.0",
41
- "black>=23.0",
42
- "ruff>=0.1.0",
43
- "mypy>=1.0",
44
- "sphinx-testing>=1.0",
39
+ "tox>=4.56,<5",
40
+ "tox-uv>=1.35,<2",
41
+ "black>=26,<27",
42
+ "ruff>=0.15,<0.16",
43
+ "mypy>=1.13,<3.0",
45
44
  "pre-commit>=3.0",
46
45
  "types-docutils>=0.18",
47
46
  "twine>=5.0",
@@ -50,6 +49,8 @@ dev = [
50
49
  docs = [
51
50
  "furo>=2024.0",
52
51
  "sphinx-autodoc-typehints>=1.0",
52
+ "sphinx-intl>=2.0",
53
+ "tomli>=2.0; python_version < '3.11'",
53
54
  ]
54
55
 
55
56
  [project.urls]
@@ -84,7 +85,7 @@ markers = [
84
85
 
85
86
  [tool.black]
86
87
  line-length = 88
87
- target-version = ["py39", "py310", "py311", "py312"]
88
+ target-version = ["py310", "py311", "py312", "py313"]
88
89
  include = '\.pyi?$'
89
90
  exclude = '''
90
91
  /(
@@ -99,7 +100,7 @@ exclude = '''
99
100
 
100
101
  [tool.ruff]
101
102
  line-length = 88
102
- target-version = "py39"
103
+ target-version = "py310"
103
104
 
104
105
  [tool.ruff.lint]
105
106
  select = ["E", "F", "W", "I", "N", "UP", "B", "A", "C4", "T20"]
@@ -107,8 +108,8 @@ ignore = [
107
108
  "E501", # Line too long (handled by black)
108
109
  "T201", # print found (used in tests for debugging)
109
110
  "B017", # asserting blind exception in tests
110
- "UP035", # typing.Dict/List/Set deprecation (Python 3.9+ support)
111
- "UP006", # Use dict instead of Dict (Python 3.9+ support)
111
+ "UP035", # typing.Dict/List/Set deprecation (Python 3.10+ support)
112
+ "UP006", # Use dict instead of Dict (Python 3.10+ support)
112
113
  "UP028", # yield from (minor optimization)
113
114
  "N802", # Function naming (docutils visitor pattern uses PascalCase)
114
115
  "A001", # Shadowing builtins (copyright in conf.py is Sphinx convention)
@@ -116,7 +117,7 @@ ignore = [
116
117
  ]
117
118
 
118
119
  [tool.mypy]
119
- python_version = "3.9"
120
+ python_version = "3.10"
120
121
  warn_return_any = false
121
122
  warn_unused_configs = true
122
123
  disallow_untyped_defs = false
@@ -12,12 +12,10 @@ def test_typst_package_config_registered(make_app, tmp_path):
12
12
  """Test that typst_package is registered as a config value"""
13
13
  # Arrange: Create conf.py with typst_package setting
14
14
  conf_py = tmp_path / "conf.py"
15
- conf_py.write_text(
16
- """
15
+ conf_py.write_text("""
17
16
  extensions = ['typsphinx']
18
17
  typst_package = "@preview/diagraph:0.2.5"
19
- """
20
- )
18
+ """)
21
19
 
22
20
  # Create minimal index.rst
23
21
  index_rst = tmp_path / "index.rst"
@@ -35,15 +33,13 @@ def test_typst_package_imports_config_registered(make_app, tmp_path):
35
33
  """Test that typst_package_imports is registered as a config value"""
36
34
  # Arrange: Create conf.py with typst_package_imports setting
37
35
  conf_py = tmp_path / "conf.py"
38
- conf_py.write_text(
39
- """
36
+ conf_py.write_text("""
40
37
  extensions = ['typsphinx']
41
38
  typst_package_imports = [
42
39
  '#import "@preview/diagraph:0.2.5": *',
43
40
  '#import "@preview/tablex:0.1.0": *',
44
41
  ]
45
- """
46
- )
42
+ """)
47
43
 
48
44
  # Create minimal index.rst
49
45
  index_rst = tmp_path / "index.rst"
@@ -65,12 +61,10 @@ def test_typst_template_function_config_registered(make_app, tmp_path):
65
61
  """Test that typst_template_function is registered as a config value"""
66
62
  # Arrange: Create conf.py with typst_template_function setting
67
63
  conf_py = tmp_path / "conf.py"
68
- conf_py.write_text(
69
- """
64
+ conf_py.write_text("""
70
65
  extensions = ['typsphinx']
71
66
  typst_template_function = "custom_template"
72
- """
73
- )
67
+ """)
74
68
 
75
69
  # Create minimal index.rst
76
70
  index_rst = tmp_path / "index.rst"
@@ -88,11 +82,9 @@ def test_typst_package_default_none(make_app, tmp_path):
88
82
  """Test that typst_package defaults to None when not set"""
89
83
  # Arrange: Create conf.py without typst_package
90
84
  conf_py = tmp_path / "conf.py"
91
- conf_py.write_text(
92
- """
85
+ conf_py.write_text("""
93
86
  extensions = ['typsphinx']
94
- """
95
- )
87
+ """)
96
88
 
97
89
  # Create minimal index.rst
98
90
  index_rst = tmp_path / "index.rst"
@@ -110,11 +102,9 @@ def test_typst_package_imports_default_none(make_app, tmp_path):
110
102
  """Test that typst_package_imports defaults to None when not set"""
111
103
  # Arrange: Create conf.py without typst_package_imports
112
104
  conf_py = tmp_path / "conf.py"
113
- conf_py.write_text(
114
- """
105
+ conf_py.write_text("""
115
106
  extensions = ['typsphinx']
116
- """
117
- )
107
+ """)
118
108
 
119
109
  # Create minimal index.rst
120
110
  index_rst = tmp_path / "index.rst"
@@ -132,11 +122,9 @@ def test_typst_template_function_default_none(make_app, tmp_path):
132
122
  """Test that typst_template_function defaults to None when not set"""
133
123
  # Arrange: Create conf.py without typst_template_function
134
124
  conf_py = tmp_path / "conf.py"
135
- conf_py.write_text(
136
- """
125
+ conf_py.write_text("""
137
126
  extensions = ['typsphinx']
138
- """
139
- )
127
+ """)
140
128
 
141
129
  # Create minimal index.rst
142
130
  index_rst = tmp_path / "index.rst"
@@ -154,12 +142,10 @@ def test_typst_output_dir_config_registered(make_app, tmp_path):
154
142
  """Test that typst_output_dir is registered as a config value"""
155
143
  # Arrange: Create conf.py with typst_output_dir setting
156
144
  conf_py = tmp_path / "conf.py"
157
- conf_py.write_text(
158
- """
145
+ conf_py.write_text("""
159
146
  extensions = ['typsphinx']
160
147
  typst_output_dir = '_custom/typst'
161
- """
162
- )
148
+ """)
163
149
 
164
150
  # Create minimal index.rst
165
151
  index_rst = tmp_path / "index.rst"
@@ -177,11 +163,9 @@ def test_typst_output_dir_default_value(make_app, tmp_path):
177
163
  """Test that typst_output_dir defaults to '_build/typst' when not set"""
178
164
  # Arrange: Create conf.py without typst_output_dir
179
165
  conf_py = tmp_path / "conf.py"
180
- conf_py.write_text(
181
- """
166
+ conf_py.write_text("""
182
167
  extensions = ['typsphinx']
183
- """
184
- )
168
+ """)
185
169
 
186
170
  # Create minimal index.rst
187
171
  index_rst = tmp_path / "index.rst"
@@ -199,12 +183,10 @@ def test_typst_debug_config_registered(make_app, tmp_path):
199
183
  """Test that typst_debug is registered as a config value"""
200
184
  # Arrange: Create conf.py with typst_debug setting
201
185
  conf_py = tmp_path / "conf.py"
202
- conf_py.write_text(
203
- """
186
+ conf_py.write_text("""
204
187
  extensions = ['typsphinx']
205
188
  typst_debug = True
206
- """
207
- )
189
+ """)
208
190
 
209
191
  # Create minimal index.rst
210
192
  index_rst = tmp_path / "index.rst"
@@ -222,11 +204,9 @@ def test_typst_debug_default_false(make_app, tmp_path):
222
204
  """Test that typst_debug defaults to False when not set"""
223
205
  # Arrange: Create conf.py without typst_debug
224
206
  conf_py = tmp_path / "conf.py"
225
- conf_py.write_text(
226
- """
207
+ conf_py.write_text("""
227
208
  extensions = ['typsphinx']
228
- """
229
- )
209
+ """)
230
210
 
231
211
  # Create minimal index.rst
232
212
  index_rst = tmp_path / "index.rst"
@@ -77,8 +77,7 @@ typst_toctree_defaults = {
77
77
  typst_documents = [('index', 'index', 'Test', 'Author')]
78
78
  """
79
79
  (srcdir / "conf.py").write_text(conf_content)
80
- (srcdir / "index.rst").write_text(
81
- """
80
+ (srcdir / "index.rst").write_text("""
82
81
  Test Document
83
82
  =============
84
83
 
@@ -86,8 +85,7 @@ Test Document
86
85
  :maxdepth: 2
87
86
 
88
87
  chapter1
89
- """
90
- )
88
+ """)
91
89
  (srcdir / "chapter1.rst").write_text("Chapter 1\n=========\n")
92
90
 
93
91
  app = make_app(srcdir=srcdir, buildername="typst")
@@ -123,8 +121,7 @@ typst_documents = [('index', 'index', 'Test', 'Author')]
123
121
  (srcdir / "conf.py").write_text(conf_content)
124
122
 
125
123
  # toctree with explicit maxdepth:2 (should override default maxdepth:4)
126
- (srcdir / "index.rst").write_text(
127
- """
124
+ (srcdir / "index.rst").write_text("""
128
125
  Test
129
126
  ====
130
127
 
@@ -133,8 +130,7 @@ Test
133
130
  :numbered:
134
131
 
135
132
  chapter1
136
- """
137
- )
133
+ """)
138
134
  (srcdir / "chapter1.rst").write_text("Chapter\n=======\n")
139
135
 
140
136
  app = make_app(srcdir=srcdir, buildername="typst")
@@ -2,20 +2,13 @@
2
2
  Tests for entry points configuration.
3
3
  """
4
4
 
5
- import sys
6
5
  from importlib.metadata import entry_points
7
6
 
8
7
 
9
8
  def test_entry_point_registration():
10
9
  """Test that entry points are defined in pyproject.toml."""
11
10
  # Get entry points for sphinx.builders group
12
- if sys.version_info >= (3, 10):
13
- # Python 3.10+ uses select() method
14
- eps = entry_points(group="sphinx.builders")
15
- else:
16
- # Python 3.9 uses dict-like access
17
- all_eps = entry_points()
18
- eps = all_eps.get("sphinx.builders", [])
11
+ eps = entry_points(group="sphinx.builders")
19
12
 
20
13
  # Convert to list of names
21
14
  ep_names = [ep.name for ep in eps]
@@ -32,11 +25,7 @@ def test_entry_point_registration():
32
25
  def test_entry_point_value():
33
26
  """Test that the entry points point to the correct module."""
34
27
  # Get entry points for sphinx.builders group
35
- if sys.version_info >= (3, 10):
36
- eps = entry_points(group="sphinx.builders")
37
- else:
38
- all_eps = entry_points()
39
- eps = all_eps.get("sphinx.builders", [])
28
+ eps = entry_points(group="sphinx.builders")
40
29
 
41
30
  # Find the entry points
42
31
  typst_ep = None
@@ -186,3 +186,154 @@ class TestInlineReferenceConversion:
186
186
  output = translator.astext()
187
187
  # Literal should use raw() function in unified code mode
188
188
  assert 'raw("code_reference")' in output
189
+
190
+
191
+ class TestEmptyURLHandling:
192
+ """Test empty URL handling in references (Typst 0.14+ compatibility)."""
193
+
194
+ def test_empty_refuri_skips_link_wrapper(self, temp_sphinx_app: SphinxTestApp):
195
+ """Test that empty refuri skips link() generation."""
196
+ ref = nodes.reference()
197
+ ref["refuri"] = "" # Empty URL
198
+ ref += nodes.Text("broken reference")
199
+
200
+ doc = create_document()
201
+ para = nodes.paragraph()
202
+ para += ref
203
+ doc += para
204
+
205
+ writer = TypstWriter(temp_sphinx_app.builder)
206
+ writer.document = doc
207
+ translator = TypstTranslator(doc, temp_sphinx_app.builder)
208
+ doc.walkabout(translator)
209
+
210
+ output = translator.astext()
211
+ # Should NOT generate link()
212
+ assert 'link("")' not in output
213
+ assert 'link("", ' not in output
214
+ # Should render content as plain text
215
+ assert "broken reference" in output
216
+
217
+ def test_empty_refuri_renders_content_as_text(self, temp_sphinx_app: SphinxTestApp):
218
+ """Test that content is rendered as plain text when refuri is empty."""
219
+ ref = nodes.reference()
220
+ ref["refuri"] = ""
221
+ ref += nodes.Text("nonexistent-section")
222
+
223
+ doc = create_document()
224
+ para = nodes.paragraph()
225
+ para += ref
226
+ doc += para
227
+
228
+ writer = TypstWriter(temp_sphinx_app.builder)
229
+ writer.document = doc
230
+ translator = TypstTranslator(doc, temp_sphinx_app.builder)
231
+ doc.walkabout(translator)
232
+
233
+ output = translator.astext()
234
+ # Content should be present as text
235
+ assert "nonexistent-section" in output
236
+ # No link wrapper
237
+ assert "link(" not in output
238
+
239
+ def test_empty_refuri_emits_warning(self, temp_sphinx_app: SphinxTestApp):
240
+ """Test that warning is emitted for empty refuri."""
241
+ ref = nodes.reference()
242
+ ref["refuri"] = ""
243
+ ref += nodes.Text("broken-link")
244
+
245
+ doc = create_document()
246
+ para = nodes.paragraph()
247
+ para += ref
248
+ doc += para
249
+
250
+ writer = TypstWriter(temp_sphinx_app.builder)
251
+ writer.document = doc
252
+ translator = TypstTranslator(doc, temp_sphinx_app.builder)
253
+
254
+ # Capture warnings
255
+ import io
256
+ from contextlib import redirect_stderr
257
+
258
+ stderr_capture = io.StringIO()
259
+ with redirect_stderr(stderr_capture):
260
+ doc.walkabout(translator)
261
+
262
+ # Sphinx logger output goes to stderr in test context
263
+ # We just verify the code runs without error and produces expected output
264
+ output = translator.astext()
265
+ assert "broken-link" in output
266
+ assert 'link("")' not in output
267
+
268
+ def test_valid_refuri_unchanged(self, temp_sphinx_app: SphinxTestApp):
269
+ """Test that valid refuri generates link() as before (regression test)."""
270
+ ref = nodes.reference()
271
+ ref["refuri"] = "https://python.org"
272
+ ref += nodes.Text("Python")
273
+
274
+ doc = create_document()
275
+ para = nodes.paragraph()
276
+ para += ref
277
+ doc += para
278
+
279
+ writer = TypstWriter(temp_sphinx_app.builder)
280
+ writer.document = doc
281
+ translator = TypstTranslator(doc, temp_sphinx_app.builder)
282
+ doc.walkabout(translator)
283
+
284
+ output = translator.astext()
285
+ # Should generate link()
286
+ assert 'link("https://python.org"' in output
287
+ assert "Python" in output
288
+
289
+ def test_internal_reference_with_hash(self, temp_sphinx_app: SphinxTestApp):
290
+ """Test that internal references (starting with #) work correctly."""
291
+ ref = nodes.reference()
292
+ ref["refuri"] = "#section-label"
293
+ ref += nodes.Text("See section")
294
+
295
+ doc = create_document()
296
+ para = nodes.paragraph()
297
+ para += ref
298
+ doc += para
299
+
300
+ writer = TypstWriter(temp_sphinx_app.builder)
301
+ writer.document = doc
302
+ translator = TypstTranslator(doc, temp_sphinx_app.builder)
303
+ doc.walkabout(translator)
304
+
305
+ output = translator.astext()
306
+ # Should generate link(<label>, ...)
307
+ assert "link(<section-label>" in output
308
+ assert "See section" in output
309
+
310
+ def test_multiple_empty_urls(self, temp_sphinx_app: SphinxTestApp):
311
+ """Test that multiple empty URLs are handled correctly."""
312
+ # First empty reference
313
+ ref1 = nodes.reference()
314
+ ref1["refuri"] = ""
315
+ ref1 += nodes.Text("ref1")
316
+
317
+ # Second empty reference
318
+ ref2 = nodes.reference()
319
+ ref2["refuri"] = ""
320
+ ref2 += nodes.Text("ref2")
321
+
322
+ doc = create_document()
323
+ para = nodes.paragraph()
324
+ para += ref1
325
+ para += nodes.Text(" and ")
326
+ para += ref2
327
+ doc += para
328
+
329
+ writer = TypstWriter(temp_sphinx_app.builder)
330
+ writer.document = doc
331
+ translator = TypstTranslator(doc, temp_sphinx_app.builder)
332
+ doc.walkabout(translator)
333
+
334
+ output = translator.astext()
335
+ # Both should be rendered as text
336
+ assert "ref1" in output
337
+ assert "ref2" in output
338
+ # No link wrappers
339
+ assert 'link("")' not in output