quillmark 0.4.1__tar.gz → 0.5.0__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 (90) hide show
  1. {quillmark-0.4.1 → quillmark-0.5.0}/Cargo.lock +8 -8
  2. {quillmark-0.4.1 → quillmark-0.5.0}/Cargo.toml +5 -5
  3. {quillmark-0.4.1 → quillmark-0.5.0}/PKG-INFO +8 -10
  4. {quillmark-0.4.1/quillmark-python → quillmark-0.5.0}/README.md +7 -8
  5. {quillmark-0.4.1 → quillmark-0.5.0}/pyproject.toml +0 -1
  6. {quillmark-0.4.1 → quillmark-0.5.0}/python/quillmark/__init__.pyi +10 -26
  7. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/IMPLEMENTATION_SUMMARY.md +18 -0
  8. {quillmark-0.4.1 → quillmark-0.5.0/quillmark-python}/README.md +7 -8
  9. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/python/quillmark/__init__.pyi +10 -26
  10. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/src/types.rs +0 -54
  11. {quillmark-0.4.1 → quillmark-0.5.0}/python/quillmark/__init__.py +0 -0
  12. {quillmark-0.4.1 → quillmark-0.5.0}/python/quillmark/py.typed +0 -0
  13. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark/Cargo.toml +0 -0
  14. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark/README.md +0 -0
  15. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark/src/lib.rs +0 -0
  16. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark/src/orchestration.rs +0 -0
  17. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-acroform/Cargo.toml +0 -0
  18. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-acroform/README.md +0 -0
  19. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-acroform/src/lib.rs +0 -0
  20. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-core/Cargo.toml +0 -0
  21. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-core/README.md +0 -0
  22. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-core/src/backend.rs +0 -0
  23. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-core/src/error.rs +0 -0
  24. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-core/src/lib.rs +0 -0
  25. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-core/src/parse.rs +0 -0
  26. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-core/src/quill.rs +0 -0
  27. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-core/src/templating.rs +0 -0
  28. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-core/src/types.rs +0 -0
  29. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-core/src/value.rs +0 -0
  30. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/.npmignore +0 -0
  31. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/Cargo.toml +0 -0
  32. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/README.md +0 -0
  33. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/appreciated_letter/Quill.toml +0 -0
  34. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/appreciated_letter/appreciated_letter.md +0 -0
  35. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/appreciated_letter/glue.typ +0 -0
  36. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/extended_metadata_demo.md +0 -0
  37. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/frontmatter_demo.md +0 -0
  38. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/sample.md +0 -0
  39. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/taro/Quill.toml +0 -0
  40. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/taro/glue.typ +0 -0
  41. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/taro/taro.md +0 -0
  42. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/taro.png +0 -0
  43. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_form_8/Quill.toml +0 -0
  44. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_form_8/form.pdf +0 -0
  45. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_form_8/usaf_form_8.md +0 -0
  46. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/.quillignore +0 -0
  47. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/Quill.toml +0 -0
  48. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/assets/dow_seal.png +0 -0
  49. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/glue.typ +0 -0
  50. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/.gitignore +0 -0
  51. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/LICENSE +0 -0
  52. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/fonts/Cinzel/Cinzel-Regular.ttf +0 -0
  53. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/fonts/Cinzel/LICENSE +0 -0
  54. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/fonts/CopperplateCC/CopperplateCC-Heavy.otf +0 -0
  55. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/fonts/CopperplateCC/LICENSE.md +0 -0
  56. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/fonts/NimbusRomanNo9L/GNU General Public License.txt +0 -0
  57. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/fonts/NimbusRomanNo9L/NimbusRomNo9L-Med.otf +0 -0
  58. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/fonts/NimbusRomanNo9L/NimbusRomNo9L-MedIta.otf +0 -0
  59. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/fonts/NimbusRomanNo9L/NimbusRomNo9L-Reg.otf +0 -0
  60. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/fonts/NimbusRomanNo9L/NimbusRomNo9L-RegIta.otf +0 -0
  61. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/src/lib.typ +0 -0
  62. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/src/utils.typ +0 -0
  63. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/packages/tonguetoquill-usaf-memo/typst.toml +0 -0
  64. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/resources/usaf_memo/usaf_memo.md +0 -0
  65. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-fixtures/src/lib.rs +0 -0
  66. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/.gitignore +0 -0
  67. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/Cargo.toml +0 -0
  68. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/examples/basic.py +0 -0
  69. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/examples/batch.py +0 -0
  70. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/examples/workflow_demo.py +0 -0
  71. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/python/quillmark/__init__.py +0 -0
  72. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/python/quillmark/py.typed +0 -0
  73. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/src/enums.rs +0 -0
  74. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/src/errors.rs +0 -0
  75. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/src/lib.rs +0 -0
  76. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/tests/conftest.py +0 -0
  77. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/tests/test_api_requirements.py +0 -0
  78. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/tests/test_engine.py +0 -0
  79. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/tests/test_parse.py +0 -0
  80. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/tests/test_quill.py +0 -0
  81. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/tests/test_render.py +0 -0
  82. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-python/uv.lock +0 -0
  83. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-typst/Cargo.toml +0 -0
  84. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-typst/README.md +0 -0
  85. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-typst/src/compile.rs +0 -0
  86. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-typst/src/convert.rs +0 -0
  87. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-typst/src/error_mapping.rs +0 -0
  88. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-typst/src/filters.rs +0 -0
  89. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-typst/src/lib.rs +0 -0
  90. {quillmark-0.4.1 → quillmark-0.5.0}/quillmark-typst/src/world.rs +0 -0
@@ -2043,7 +2043,7 @@ dependencies = [
2043
2043
 
2044
2044
  [[package]]
2045
2045
  name = "quillmark"
2046
- version = "0.4.1"
2046
+ version = "0.5.0"
2047
2047
  dependencies = [
2048
2048
  "acroform",
2049
2049
  "anyhow",
@@ -2060,7 +2060,7 @@ dependencies = [
2060
2060
 
2061
2061
  [[package]]
2062
2062
  name = "quillmark-acroform"
2063
- version = "0.4.1"
2063
+ version = "0.5.0"
2064
2064
  dependencies = [
2065
2065
  "acroform",
2066
2066
  "minijinja",
@@ -2073,7 +2073,7 @@ dependencies = [
2073
2073
 
2074
2074
  [[package]]
2075
2075
  name = "quillmark-core"
2076
- version = "0.4.1"
2076
+ version = "0.5.0"
2077
2077
  dependencies = [
2078
2078
  "anyhow",
2079
2079
  "glob",
@@ -2088,7 +2088,7 @@ dependencies = [
2088
2088
 
2089
2089
  [[package]]
2090
2090
  name = "quillmark-fixtures"
2091
- version = "0.4.1"
2091
+ version = "0.5.0"
2092
2092
  dependencies = [
2093
2093
  "quillmark",
2094
2094
  "quillmark-typst",
@@ -2096,7 +2096,7 @@ dependencies = [
2096
2096
 
2097
2097
  [[package]]
2098
2098
  name = "quillmark-fuzz"
2099
- version = "0.4.1"
2099
+ version = "0.5.0"
2100
2100
  dependencies = [
2101
2101
  "proptest",
2102
2102
  "quillmark-core",
@@ -2105,7 +2105,7 @@ dependencies = [
2105
2105
 
2106
2106
  [[package]]
2107
2107
  name = "quillmark-python"
2108
- version = "0.4.1"
2108
+ version = "0.5.0"
2109
2109
  dependencies = [
2110
2110
  "anyhow",
2111
2111
  "pyo3",
@@ -2116,7 +2116,7 @@ dependencies = [
2116
2116
 
2117
2117
  [[package]]
2118
2118
  name = "quillmark-typst"
2119
- version = "0.4.1"
2119
+ version = "0.5.0"
2120
2120
  dependencies = [
2121
2121
  "anyhow",
2122
2122
  "dirs",
@@ -2138,7 +2138,7 @@ dependencies = [
2138
2138
 
2139
2139
  [[package]]
2140
2140
  name = "quillmark-wasm"
2141
- version = "0.4.1"
2141
+ version = "0.5.0"
2142
2142
  dependencies = [
2143
2143
  "console_error_panic_hook",
2144
2144
  "getrandom 0.3.4",
@@ -11,7 +11,7 @@ default-members = [
11
11
  resolver = "2"
12
12
 
13
13
  [workspace.package]
14
- version = "0.4.1"
14
+ version = "0.5.0"
15
15
  edition = "2021"
16
16
  include = ["src/**", "Cargo.toml", "README*", "LICENSE*"]
17
17
  readme = "README.md"
@@ -47,10 +47,10 @@ dirs = "6.0"
47
47
  acroform = "0.1.3"
48
48
 
49
49
  # Intra-project dependencies
50
- quillmark-core = { version = "0.4.1", path = "quillmark-core" }
51
- quillmark-typst = { version = "0.4.1", path = "quillmark-typst", default-features = false }
52
- quillmark-acroform = { version = "0.4.1", path = "quillmark-acroform" }
53
- quillmark = { version = "0.4.1", path = "quillmark", default-features = false }
50
+ quillmark-core = { version = "0.5.0", path = "quillmark-core" }
51
+ quillmark-typst = { version = "0.5.0", path = "quillmark-typst", default-features = false }
52
+ quillmark-acroform = { version = "0.5.0", path = "quillmark-acroform" }
53
+ quillmark = { version = "0.5.0", path = "quillmark", default-features = false }
54
54
 
55
55
  # Test and dev dependencies
56
56
  tempfile = "~3.23"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quillmark
3
- Version: 0.4.1
3
+ Version: 0.5.0
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: Apache Software License
@@ -12,7 +12,6 @@ Classifier: Programming Language :: Python :: 3.13
12
12
  Classifier: Programming Language :: Rust
13
13
  Classifier: Topic :: Text Processing :: Markup
14
14
  Requires-Dist: pytest>=8.0 ; extra == 'dev'
15
- Requires-Dist: pytest-cov>=5.0 ; extra == 'dev'
16
15
  Requires-Dist: maturin>=1.7,<2.0 ; extra == 'dev'
17
16
  Provides-Extra: dev
18
17
  Summary: Python bindings for Quillmark - template-first Markdown rendering
@@ -118,10 +117,10 @@ Represents parsed Markdown with frontmatter.
118
117
  ```python
119
118
  parsed = ParsedDocument.from_markdown(markdown)
120
119
 
121
- parsed.body() # Document body
122
- parsed.quill_tag() # QUILL field value (if present)
123
- parsed.get_field(key) # Get specific field
124
- parsed.fields # All frontmatter fields
120
+ parsed.body() # Document body (str | None)
121
+ parsed.quill_tag() # QUILL field value (str | None)
122
+ parsed.get_field(key) # Get specific field (Any | None)
123
+ parsed.fields # All frontmatter fields (dict)
125
124
  ```
126
125
 
127
126
  #### `Workflow` - Rendering Pipeline
@@ -143,6 +142,8 @@ workflow.supported_formats # [OutputFormat.PDF, OutputFormat.SVG]
143
142
  glue_output = workflow.process_glue_parsed(parsed)
144
143
  ```
145
144
 
145
+ **Note**: Dynamic asset and font injection is not currently supported in Python bindings. Assets must be included in the quill bundle.
146
+
146
147
  #### `RenderResult` - Output Container
147
148
 
148
149
  Contains rendered artifacts and diagnostics.
@@ -184,10 +185,7 @@ Canonical development flow:
184
185
  uv venv
185
186
 
186
187
  # Install developer extras (includes maturin, pytest, mypy, ruff)
187
- uv pip install -e "[dev]"
188
-
189
- # Build and install (compile Rust + install into venv)
190
- uv run python -m maturin develop
188
+ uv pip install -e ".[dev]"
191
189
 
192
190
  # Run tests
193
191
  uv run pytest
@@ -92,10 +92,10 @@ Represents parsed Markdown with frontmatter.
92
92
  ```python
93
93
  parsed = ParsedDocument.from_markdown(markdown)
94
94
 
95
- parsed.body() # Document body
96
- parsed.quill_tag() # QUILL field value (if present)
97
- parsed.get_field(key) # Get specific field
98
- parsed.fields # All frontmatter fields
95
+ parsed.body() # Document body (str | None)
96
+ parsed.quill_tag() # QUILL field value (str | None)
97
+ parsed.get_field(key) # Get specific field (Any | None)
98
+ parsed.fields # All frontmatter fields (dict)
99
99
  ```
100
100
 
101
101
  #### `Workflow` - Rendering Pipeline
@@ -117,6 +117,8 @@ workflow.supported_formats # [OutputFormat.PDF, OutputFormat.SVG]
117
117
  glue_output = workflow.process_glue_parsed(parsed)
118
118
  ```
119
119
 
120
+ **Note**: Dynamic asset and font injection is not currently supported in Python bindings. Assets must be included in the quill bundle.
121
+
120
122
  #### `RenderResult` - Output Container
121
123
 
122
124
  Contains rendered artifacts and diagnostics.
@@ -158,10 +160,7 @@ Canonical development flow:
158
160
  uv venv
159
161
 
160
162
  # Install developer extras (includes maturin, pytest, mypy, ruff)
161
- uv pip install -e "[dev]"
162
-
163
- # Build and install (compile Rust + install into venv)
164
- uv run python -m maturin develop
163
+ uv pip install -e ".[dev]"
165
164
 
166
165
  # Run tests
167
166
  uv run pytest
@@ -31,7 +31,6 @@ Repository = "https://github.com/nibsbin/quillmark"
31
31
  [project.optional-dependencies]
32
32
  dev = [
33
33
  "pytest>=8.0",
34
- "pytest-cov>=5.0",
35
34
  "maturin>=1.7,<2.0",
36
35
  ]
37
36
 
@@ -78,7 +78,11 @@ class Quillmark:
78
78
  """Get list of registered quill names."""
79
79
 
80
80
  class Workflow:
81
- """Sealed workflow for executing the render pipeline."""
81
+ """Sealed workflow for executing the render pipeline.
82
+
83
+ Note: Dynamic asset and font injection is not currently supported in Python bindings.
84
+ Assets must be included in the quill bundle.
85
+ """
82
86
 
83
87
  def render(
84
88
  self,
@@ -112,38 +116,17 @@ class Workflow:
112
116
  def process_glue_parsed(self, parsed: ParsedDocument) -> str:
113
117
  """Process parsed document through glue template."""
114
118
 
115
- def with_asset(self, filename: str, contents: bytes) -> Workflow:
116
- """Add dynamic asset (returns new workflow instance)."""
117
-
118
- def with_assets(self, assets: dict[str, bytes]) -> Workflow:
119
- """Add multiple dynamic assets."""
120
-
121
- def clear_assets(self) -> Workflow:
122
- """Remove all dynamic assets."""
123
-
124
- def with_font(self, filename: str, contents: bytes) -> Workflow:
125
- """Add dynamic font."""
126
-
127
- def with_fonts(self, fonts: dict[str, bytes]) -> Workflow:
128
- """Add multiple dynamic fonts."""
129
-
130
- def clear_fonts(self) -> Workflow:
131
- """Remove all dynamic fonts."""
132
-
119
+ @property
133
120
  def backend_id(self) -> str:
134
121
  """Get backend identifier."""
135
122
 
123
+ @property
136
124
  def supported_formats(self) -> list[OutputFormat]:
137
125
  """Get supported output formats."""
138
126
 
127
+ @property
139
128
  def quill_name(self) -> str:
140
129
  """Get quill name."""
141
-
142
- def dynamic_asset_names(self) -> list[str]:
143
- """Get list of dynamic asset filenames."""
144
-
145
- def dynamic_font_names(self) -> list[str]:
146
- """Get list of dynamic font filenames."""
147
130
 
148
131
  class Quill:
149
132
  """Template bundle containing glue templates and assets."""
@@ -191,12 +174,13 @@ class ParsedDocument:
191
174
  ParseError: If YAML frontmatter is invalid
192
175
  """
193
176
 
194
- def body(self) -> str:
177
+ def body(self) -> str | None:
195
178
  """Get document body content."""
196
179
 
197
180
  def get_field(self, key: str) -> Any | None:
198
181
  """Get frontmatter field value."""
199
182
 
183
+ @property
200
184
  def fields(self) -> dict[str, Any]:
201
185
  """Get all frontmatter fields."""
202
186
 
@@ -129,6 +129,7 @@ As specified, the following are explicitly NOT exposed:
129
129
  - Low-level Workflow internals
130
130
  - Backend implementation details
131
131
  - Custom backend registration from Python
132
+ - Dynamic asset/font injection (not yet implemented in Python bindings)
132
133
 
133
134
  ## Usage Example
134
135
 
@@ -168,6 +169,23 @@ result.artifacts[0].save("output.pdf")
168
169
  - Maintains compatibility with existing Rust API design
169
170
  - Python 3.10+ required (abi3 support)
170
171
 
172
+ ## Breaking Changes (v0.4.1)
173
+
174
+ The following breaking changes were made to remove legacy code and ensure consistency:
175
+
176
+ 1. **Removed unsupported builder methods** - The following methods have been removed from `Workflow`:
177
+ - `with_asset()`, `with_assets()`, `clear_assets()`
178
+ - `with_font()`, `with_fonts()`, `clear_fonts()`
179
+ - `dynamic_asset_names()`, `dynamic_font_names()`
180
+
181
+ These methods were never properly implemented and always threw errors. Dynamic assets/fonts are not yet supported in Python bindings.
182
+
183
+ 2. **Removed redundant getter** - `RenderResult.output_format` has been removed. Use `artifact.output_format` on individual artifacts instead.
184
+
185
+ 3. **Type stub corrections** - Fixed type declarations to match actual implementation:
186
+ - `ParsedDocument.body()` now correctly returns `str | None` (was incorrectly documented as `str`)
187
+ - Various getters now correctly declared as properties in type stubs
188
+
171
189
  ## Documentation
172
190
 
173
191
  - README.md provides comprehensive API documentation
@@ -92,10 +92,10 @@ Represents parsed Markdown with frontmatter.
92
92
  ```python
93
93
  parsed = ParsedDocument.from_markdown(markdown)
94
94
 
95
- parsed.body() # Document body
96
- parsed.quill_tag() # QUILL field value (if present)
97
- parsed.get_field(key) # Get specific field
98
- parsed.fields # All frontmatter fields
95
+ parsed.body() # Document body (str | None)
96
+ parsed.quill_tag() # QUILL field value (str | None)
97
+ parsed.get_field(key) # Get specific field (Any | None)
98
+ parsed.fields # All frontmatter fields (dict)
99
99
  ```
100
100
 
101
101
  #### `Workflow` - Rendering Pipeline
@@ -117,6 +117,8 @@ workflow.supported_formats # [OutputFormat.PDF, OutputFormat.SVG]
117
117
  glue_output = workflow.process_glue_parsed(parsed)
118
118
  ```
119
119
 
120
+ **Note**: Dynamic asset and font injection is not currently supported in Python bindings. Assets must be included in the quill bundle.
121
+
120
122
  #### `RenderResult` - Output Container
121
123
 
122
124
  Contains rendered artifacts and diagnostics.
@@ -158,10 +160,7 @@ Canonical development flow:
158
160
  uv venv
159
161
 
160
162
  # Install developer extras (includes maturin, pytest, mypy, ruff)
161
- uv pip install -e "[dev]"
162
-
163
- # Build and install (compile Rust + install into venv)
164
- uv run python -m maturin develop
163
+ uv pip install -e ".[dev]"
165
164
 
166
165
  # Run tests
167
166
  uv run pytest
@@ -78,7 +78,11 @@ class Quillmark:
78
78
  """Get list of registered quill names."""
79
79
 
80
80
  class Workflow:
81
- """Sealed workflow for executing the render pipeline."""
81
+ """Sealed workflow for executing the render pipeline.
82
+
83
+ Note: Dynamic asset and font injection is not currently supported in Python bindings.
84
+ Assets must be included in the quill bundle.
85
+ """
82
86
 
83
87
  def render(
84
88
  self,
@@ -112,38 +116,17 @@ class Workflow:
112
116
  def process_glue_parsed(self, parsed: ParsedDocument) -> str:
113
117
  """Process parsed document through glue template."""
114
118
 
115
- def with_asset(self, filename: str, contents: bytes) -> Workflow:
116
- """Add dynamic asset (returns new workflow instance)."""
117
-
118
- def with_assets(self, assets: dict[str, bytes]) -> Workflow:
119
- """Add multiple dynamic assets."""
120
-
121
- def clear_assets(self) -> Workflow:
122
- """Remove all dynamic assets."""
123
-
124
- def with_font(self, filename: str, contents: bytes) -> Workflow:
125
- """Add dynamic font."""
126
-
127
- def with_fonts(self, fonts: dict[str, bytes]) -> Workflow:
128
- """Add multiple dynamic fonts."""
129
-
130
- def clear_fonts(self) -> Workflow:
131
- """Remove all dynamic fonts."""
132
-
119
+ @property
133
120
  def backend_id(self) -> str:
134
121
  """Get backend identifier."""
135
122
 
123
+ @property
136
124
  def supported_formats(self) -> list[OutputFormat]:
137
125
  """Get supported output formats."""
138
126
 
127
+ @property
139
128
  def quill_name(self) -> str:
140
129
  """Get quill name."""
141
-
142
- def dynamic_asset_names(self) -> list[str]:
143
- """Get list of dynamic asset filenames."""
144
-
145
- def dynamic_font_names(self) -> list[str]:
146
- """Get list of dynamic font filenames."""
147
130
 
148
131
  class Quill:
149
132
  """Template bundle containing glue templates and assets."""
@@ -191,12 +174,13 @@ class ParsedDocument:
191
174
  ParseError: If YAML frontmatter is invalid
192
175
  """
193
176
 
194
- def body(self) -> str:
177
+ def body(self) -> str | None:
195
178
  """Get document body content."""
196
179
 
197
180
  def get_field(self, key: str) -> Any | None:
198
181
  """Get frontmatter field value."""
199
182
 
183
+ @property
200
184
  def fields(self) -> dict[str, Any]:
201
185
  """Get all frontmatter fields."""
202
186
 
@@ -8,7 +8,6 @@ use pyo3::{Bound, PyAny}; // Bound, PyAny
8
8
  use quillmark::{
9
9
  Diagnostic, Location, OutputFormat, ParsedDocument, Quill, Quillmark, RenderResult, Workflow,
10
10
  };
11
- use std::collections::HashMap;
12
11
  use std::path::PathBuf;
13
12
 
14
13
  use crate::enums::{PyOutputFormat, PySeverity};
@@ -122,42 +121,6 @@ impl PyWorkflow {
122
121
  .map_err(convert_render_error)
123
122
  }
124
123
 
125
- fn with_asset(&self, _filename: String, _contents: Vec<u8>) -> PyResult<()> {
126
- Err(PyErr::new::<crate::errors::QuillmarkError, _>(
127
- "Builder pattern methods (with_asset, with_font, etc.) are not yet supported in Python bindings. \
128
- Create a new workflow instead.",
129
- ))
130
- }
131
-
132
- fn with_assets(&self, _assets: HashMap<String, Vec<u8>>) -> PyResult<()> {
133
- Err(PyErr::new::<crate::errors::QuillmarkError, _>(
134
- "Builder pattern methods are not yet supported in Python bindings",
135
- ))
136
- }
137
-
138
- fn clear_assets(&self) -> PyResult<()> {
139
- Err(PyErr::new::<crate::errors::QuillmarkError, _>(
140
- "Builder pattern methods are not yet supported in Python bindings",
141
- ))
142
- }
143
-
144
- fn with_font(&self, _filename: String, _contents: Vec<u8>) -> PyResult<()> {
145
- Err(PyErr::new::<crate::errors::QuillmarkError, _>(
146
- "Builder pattern methods are not yet supported in Python bindings",
147
- ))
148
- }
149
-
150
- fn with_fonts(&self, _fonts: HashMap<String, Vec<u8>>) -> PyResult<()> {
151
- Err(PyErr::new::<crate::errors::QuillmarkError, _>(
152
- "Builder pattern methods are not yet supported in Python bindings",
153
- ))
154
- }
155
-
156
- fn clear_fonts(&self) -> PyResult<()> {
157
- Err(PyErr::new::<crate::errors::QuillmarkError, _>(
158
- "Builder pattern methods are not yet supported in Python bindings",
159
- ))
160
- }
161
124
  #[getter]
162
125
  fn backend_id(&self) -> &str {
163
126
  self.inner.backend_id()
@@ -176,14 +139,6 @@ impl PyWorkflow {
176
139
  fn quill_name(&self) -> &str {
177
140
  self.inner.quill_name()
178
141
  }
179
-
180
- fn dynamic_asset_names(&self) -> Vec<String> {
181
- self.inner.dynamic_asset_names()
182
- }
183
-
184
- fn dynamic_font_names(&self) -> Vec<String> {
185
- self.inner.dynamic_font_names()
186
- }
187
142
  }
188
143
 
189
144
  // Quill wrapper
@@ -339,15 +294,6 @@ impl PyRenderResult {
339
294
  .map(|d| PyDiagnostic { inner: d.clone() })
340
295
  .collect()
341
296
  }
342
-
343
- #[getter]
344
- fn output_format(&self) -> &str {
345
- match self.inner.output_format {
346
- OutputFormat::Pdf => "pdf",
347
- OutputFormat::Svg => "svg",
348
- OutputFormat::Txt => "txt",
349
- }
350
- }
351
297
  }
352
298
 
353
299
  // Artifact wrapper
File without changes