typ2pptx 0.1.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.
- typ2pptx-0.1.0/PKG-INFO +369 -0
- typ2pptx-0.1.0/README.md +353 -0
- typ2pptx-0.1.0/pyproject.toml +37 -0
- typ2pptx-0.1.0/setup.cfg +4 -0
- typ2pptx-0.1.0/tests/test_alignment.py +87 -0
- typ2pptx-0.1.0/tests/test_chinese.py +134 -0
- typ2pptx-0.1.0/tests/test_code_blocks.py +175 -0
- typ2pptx-0.1.0/tests/test_columns.py +128 -0
- typ2pptx-0.1.0/tests/test_converter.py +481 -0
- typ2pptx-0.1.0/tests/test_images.py +309 -0
- typ2pptx-0.1.0/tests/test_inline_math.py +366 -0
- typ2pptx-0.1.0/tests/test_links.py +165 -0
- typ2pptx-0.1.0/tests/test_math.py +221 -0
- typ2pptx-0.1.0/tests/test_path_pipeline.py +182 -0
- typ2pptx-0.1.0/tests/test_pinit.py +179 -0
- typ2pptx-0.1.0/tests/test_svg_parser.py +229 -0
- typ2pptx-0.1.0/tests/test_table.py +199 -0
- typ2pptx-0.1.0/tests/test_text_positioning.py +251 -0
- typ2pptx-0.1.0/typ2pptx/__init__.py +8 -0
- typ2pptx-0.1.0/typ2pptx/__main__.py +98 -0
- typ2pptx-0.1.0/typ2pptx/core/__init__.py +1 -0
- typ2pptx-0.1.0/typ2pptx/core/converter.py +3436 -0
- typ2pptx-0.1.0/typ2pptx/core/typst_svg_parser.py +1130 -0
- typ2pptx-0.1.0/typ2pptx/scripts/__init__.py +5 -0
- typ2pptx-0.1.0/typ2pptx/scripts/svg_to_shapes.py +2113 -0
- typ2pptx-0.1.0/typ2pptx.egg-info/PKG-INFO +369 -0
- typ2pptx-0.1.0/typ2pptx.egg-info/SOURCES.txt +29 -0
- typ2pptx-0.1.0/typ2pptx.egg-info/dependency_links.txt +1 -0
- typ2pptx-0.1.0/typ2pptx.egg-info/entry_points.txt +2 -0
- typ2pptx-0.1.0/typ2pptx.egg-info/requires.txt +9 -0
- typ2pptx-0.1.0/typ2pptx.egg-info/top_level.txt +1 -0
typ2pptx-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: typ2pptx
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Convert Typst presentations (Touying) to editable PowerPoint files
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: python-pptx>=0.6.21
|
|
9
|
+
Requires-Dist: lxml>=4.9.0
|
|
10
|
+
Requires-Dist: Pillow>=9.0.0
|
|
11
|
+
Requires-Dist: typst>=0.14.0
|
|
12
|
+
Requires-Dist: cssselect>=1.2.0
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
15
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
16
|
+
|
|
17
|
+
# typ2pptx
|
|
18
|
+
|
|
19
|
+
Convert [Typst](https://typst.app/) presentations (using the [Touying](https://github.com/touying-typ/touying) framework) to editable PowerPoint (.pptx) files.
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
- **Editable text**: All text is extracted as editable, selectable, copyable PowerPoint text (not rasterized images)
|
|
24
|
+
- **Font variants**: Detects and preserves regular, bold, italic, bold-italic, and monospace text styles
|
|
25
|
+
- **Math formulas**: Inline math rendered as Cambria Math text with PPTX-native sub/superscript baseline offsets (auto-sized by PowerPoint); display math rendered as native DrawingML curve shapes (glyph outlines) grouped per formula
|
|
26
|
+
- **Heuristic math mode**: Auto-classifies formulas as simple (text) or complex (glyph curves) for best rendering; stacked fractions (e.g. `$1/2$`) are auto-detected and routed to glyph mode
|
|
27
|
+
- **Native shapes**: Converts SVG shapes (rectangles, circles, ellipses, lines, paths, polygons) to native DrawingML custom geometry
|
|
28
|
+
- **Gradient fills**: Supports SVG linear gradients converted to PowerPoint gradient fills
|
|
29
|
+
- **Transparency/opacity**: Full support for alpha channels in colors (#RRGGBBAA, rgba), fill-opacity, and element opacity
|
|
30
|
+
- **Hyperlinks**: External links from Typst `#link()` are preserved as clickable hyperlinks in PowerPoint; internal document links are rendered as normal text without hyperlink styling; theme-level hyperlink colors are neutralized to prevent default blue/purple override
|
|
31
|
+
- **Speaker notes**: Extracts Touying speaker notes via `typst.query()` (Python package) and attaches them to slides
|
|
32
|
+
- **Color preservation**: Supports hex, rgb(), rgba(), named CSS colors, and per-character coloring
|
|
33
|
+
- **Multi-run textboxes**: Groups same-line text segments into single textboxes with multiple styled runs
|
|
34
|
+
- **Paragraph alignment**: Auto-detects left, center, right, and justify alignment from Typst layout
|
|
35
|
+
- **Code blocks**: Syntax-highlighted code blocks rendered with Consolas font, preserving per-token colors
|
|
36
|
+
- **Images**: Supports embedded (data URI) and external image references (PNG, SVG, PDF); SVG/PDF images rasterized to PNG with transparent background via the `typst` Python package
|
|
37
|
+
- **Tables**: Table content (cells, headers, colored fills) converted to text and shapes
|
|
38
|
+
|
|
39
|
+
## Prerequisites
|
|
40
|
+
|
|
41
|
+
- **Python 3.9+**
|
|
42
|
+
- **typst** (Python package, v0.14+): For speaker notes extraction and SVG/PDF image rasterization
|
|
43
|
+
- Installed automatically via pip
|
|
44
|
+
- **typst-ts-cli** (v0.6.0+): For compiling `.typ` files to SVG with foreignObject text overlays
|
|
45
|
+
- Download from [typst.ts releases](https://github.com/nickelc/typst.ts/releases)
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
### From PyPI (recommended)
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install typ2pptx
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
After installation, the `typ2pptx` CLI command is available system-wide.
|
|
56
|
+
|
|
57
|
+
### Development install
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Install in editable/development mode
|
|
61
|
+
pip install -e .
|
|
62
|
+
|
|
63
|
+
# Install with dev dependencies (pytest, etc.)
|
|
64
|
+
pip install -e ".[dev]"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Using uv
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Install from PyPI
|
|
71
|
+
uv pip install typ2pptx
|
|
72
|
+
|
|
73
|
+
# Or install in editable/development mode
|
|
74
|
+
uv pip install -e .
|
|
75
|
+
|
|
76
|
+
# Install with dev dependencies
|
|
77
|
+
uv pip install -e ".[dev]"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Updating dependencies
|
|
81
|
+
|
|
82
|
+
All dependencies are declared in `pyproject.toml`. After modifying them:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# pip
|
|
86
|
+
pip install -e .
|
|
87
|
+
|
|
88
|
+
# uv
|
|
89
|
+
uv pip install -e .
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Usage
|
|
93
|
+
|
|
94
|
+
### Command Line
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Convert a Typst presentation to PPTX
|
|
98
|
+
typ2pptx slides.typ -o slides.pptx
|
|
99
|
+
|
|
100
|
+
# Convert with verbose output
|
|
101
|
+
typ2pptx slides.typ -o slides.pptx -v
|
|
102
|
+
|
|
103
|
+
# Convert from pre-compiled SVG (no typst-ts-cli needed)
|
|
104
|
+
typ2pptx slides.artifact.svg -o slides.pptx
|
|
105
|
+
|
|
106
|
+
# Specify custom tool paths
|
|
107
|
+
typ2pptx slides.typ -o slides.pptx \
|
|
108
|
+
--typst-ts-cli /path/to/typst-ts-cli
|
|
109
|
+
|
|
110
|
+
# Math rendering mode options
|
|
111
|
+
typ2pptx slides.typ -o slides.pptx \
|
|
112
|
+
--inline-math-mode auto \ # "text", "glyph", or "auto" (default: auto)
|
|
113
|
+
--display-math-mode glyph # "text", "glyph", or "auto" (default: glyph)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Math Rendering Modes
|
|
117
|
+
|
|
118
|
+
| Mode | Inline Math Default | Display Math Default | Description |
|
|
119
|
+
|------|--------------------|--------------------|-------------|
|
|
120
|
+
| `text` | Cambria Math font | Cambria Math font | Renders math as editable text runs |
|
|
121
|
+
| `glyph` | Glyph curves | Glyph curves | Renders math as native DrawingML shapes (pixel-perfect) |
|
|
122
|
+
| `auto` | Heuristic | Heuristic | Simple formulas as text, complex ones (integrals, matrices, stacked fractions) as glyph curves |
|
|
123
|
+
|
|
124
|
+
### Python API
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from typ2pptx.core.converter import convert_typst_to_pptx
|
|
128
|
+
|
|
129
|
+
# Simple conversion
|
|
130
|
+
convert_typst_to_pptx("slides.typ", "slides.pptx")
|
|
131
|
+
|
|
132
|
+
# With options
|
|
133
|
+
convert_typst_to_pptx(
|
|
134
|
+
"slides.typ",
|
|
135
|
+
"slides.pptx",
|
|
136
|
+
typst_ts_cli="/path/to/typst-ts-cli",
|
|
137
|
+
verbose=True,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
# Convert from SVG directly
|
|
141
|
+
convert_typst_to_pptx("slides.artifact.svg", "slides.pptx")
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Advanced: Step-by-step conversion
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from typ2pptx.core.converter import (
|
|
148
|
+
compile_typst_to_svg,
|
|
149
|
+
query_speaker_notes,
|
|
150
|
+
TypstSVGConverter,
|
|
151
|
+
ConversionConfig,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
# Step 1: Compile to SVG
|
|
155
|
+
svg_path = compile_typst_to_svg("slides.typ")
|
|
156
|
+
|
|
157
|
+
# Step 2: Extract speaker notes
|
|
158
|
+
notes = query_speaker_notes("slides.typ")
|
|
159
|
+
|
|
160
|
+
# Step 3: Convert to PPTX with custom config
|
|
161
|
+
config = ConversionConfig(
|
|
162
|
+
verbose=True,
|
|
163
|
+
inline_math_mode="auto", # "text", "glyph", or "auto"
|
|
164
|
+
display_math_mode="glyph", # "text", "glyph", or "auto"
|
|
165
|
+
)
|
|
166
|
+
converter = TypstSVGConverter(config)
|
|
167
|
+
converter.convert(svg_path, "slides.pptx", speaker_notes=notes)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## How It Works
|
|
171
|
+
|
|
172
|
+
### Pipeline
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
Typst (.typ)
|
|
176
|
+
|
|
|
177
|
+
v
|
|
178
|
+
typst-ts-cli --> SVG (with foreignObject text overlays)
|
|
179
|
+
|
|
|
180
|
+
v
|
|
181
|
+
typst.query() --> Speaker notes (pdfpc JSON format, via Python package)
|
|
182
|
+
|
|
|
183
|
+
v
|
|
184
|
+
typ2pptx --> PowerPoint (.pptx)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Architecture
|
|
188
|
+
|
|
189
|
+
1. **SVG Parser** (`typst_svg_parser.py`): Parses the typst.ts SVG structure, which uses:
|
|
190
|
+
- Glyph outlines as `<path>` + `<use>` references (for rendering)
|
|
191
|
+
- `<foreignObject>` overlays with HTML text (for selection/copy)
|
|
192
|
+
- `scale(S, -S)` transforms with Y-axis flipping
|
|
193
|
+
- 5-character hash prefixes per font variant
|
|
194
|
+
- `<a>` hyperlink elements with `<rect>` bounding boxes for link regions
|
|
195
|
+
|
|
196
|
+
2. **Font Variant Detection**: Identifies font styles by analyzing glyph paths:
|
|
197
|
+
- Quadratic curves (Q commands) indicate monospace fonts
|
|
198
|
+
- Glyph width comparison differentiates bold from italic
|
|
199
|
+
- Unicode math character detection (U+1D400+) identifies math fonts
|
|
200
|
+
- Usage frequency determines the regular (body text) font
|
|
201
|
+
|
|
202
|
+
3. **Shape Converter**: Uses the ppt-master `svg_to_shapes.py` pipeline:
|
|
203
|
+
- `parse_svg_path()` -> `svg_path_to_absolute()` -> `normalize_path_commands()` -> `path_commands_to_drawingml()`
|
|
204
|
+
- Generates DrawingML `<a:custGeom>` XML for custom geometry
|
|
205
|
+
- Supports solid fills (with alpha transparency), gradient fills, and strokes
|
|
206
|
+
|
|
207
|
+
4. **Text Converter**: Groups and renders text:
|
|
208
|
+
- Groups same-line segments (within 2px baseline tolerance) into multi-run textboxes
|
|
209
|
+
- Handles gap-based space detection for word boundaries
|
|
210
|
+
- Inline math sub/superscripts merged into adjacent text lines with PPTX-native baseline offsets
|
|
211
|
+
- Math segments clustered spatially into formula regions
|
|
212
|
+
- Sets font properties (bold, italic, name, size, color) per run
|
|
213
|
+
- Auto-detects paragraph alignment (left, center, right, justify) from segment positions
|
|
214
|
+
|
|
215
|
+
5. **Math Renderer**: Dual-mode math formula handling:
|
|
216
|
+
- **Text mode**: Renders as Cambria Math text runs with sub/superscript baseline offsets
|
|
217
|
+
- **Graphics mode**: Renders glyph outlines as DrawingML `<a:custGeom>` shapes grouped in `<p:grpSp>`
|
|
218
|
+
- **Auto mode**: Heuristic classification - simple formulas (letters, digits, basic operators) as text, complex formulas (integrals, matrices, roots, stacked fractions) as glyph curves
|
|
219
|
+
|
|
220
|
+
6. **Link Processor**: Detects SVG `<a>` elements and applies hyperlinks to overlapping text runs in PPTX
|
|
221
|
+
- Only external links (http, https, mailto) become PPTX hyperlinks
|
|
222
|
+
- Internal document links are rendered as normal text
|
|
223
|
+
- Explicitly suppresses PowerPoint's default hyperlink styling (blue color + underline) via `u="none"` and explicit `solidFill`
|
|
224
|
+
- Theme-level hyperlink colors (hlink/folHlink) are neutralized to prevent blue/purple override
|
|
225
|
+
|
|
226
|
+
7. **Speaker Notes**: Extracts via `typst.query()` (Python package):
|
|
227
|
+
- Uses `typst.query(path, "<pdfpc-file>", field="value")` to extract pdfpc JSON
|
|
228
|
+
- Touying framework outputs pdfpc JSON with page indices and note text
|
|
229
|
+
- Notes are attached to the corresponding PowerPoint slides
|
|
230
|
+
- Falls back to CLI `typst query` if the Python package is unavailable
|
|
231
|
+
|
|
232
|
+
## Supported Typst Content
|
|
233
|
+
|
|
234
|
+
| Category | Feature | Support |
|
|
235
|
+
|----------|---------|---------|
|
|
236
|
+
| **Text** | Regular, Bold, Italic, Bold-Italic | Full |
|
|
237
|
+
| **Text** | Monospace / inline code | Full |
|
|
238
|
+
| **Text** | Colored text | Full |
|
|
239
|
+
| **Text** | Font size variants | Full |
|
|
240
|
+
| **Text** | Chinese/CJK text | Full |
|
|
241
|
+
| **Math** | Inline formulas | Cambria Math text (auto/text mode) or glyph curves (glyph mode) |
|
|
242
|
+
| **Math** | Display formulas | Glyph curves (default) or Cambria Math text |
|
|
243
|
+
| **Math** | Stacked fractions | Auto-detected and rendered as glyph curves in auto mode |
|
|
244
|
+
| **Math** | Subscripts/superscripts | PPTX-native baseline offset (auto-sized by PowerPoint) |
|
|
245
|
+
| **Math** | Formula grouping | Grouped as single draggable unit in PPTX |
|
|
246
|
+
| **Shapes** | Rectangles, circles, ellipses | Native DrawingML |
|
|
247
|
+
| **Shapes** | Lines, paths, polygons | Native DrawingML |
|
|
248
|
+
| **Shapes** | Gradient fills | DrawingML gradFill |
|
|
249
|
+
| **Shapes** | Transparency/opacity | Alpha channel support (RRGGBBAA, rgba, fill-opacity) |
|
|
250
|
+
| **Code** | Inline code | Consolas font |
|
|
251
|
+
| **Code** | Code blocks | Consolas font with syntax highlighting colors |
|
|
252
|
+
| **Images** | Embedded PNG (data URI) | Full |
|
|
253
|
+
| **Images** | Embedded SVG | Rasterized to PNG via typst (transparent background) |
|
|
254
|
+
| **Images** | Embedded/external PDF | Rasterized to PNG via typst (transparent background) |
|
|
255
|
+
| **Images** | External references | Full |
|
|
256
|
+
| **Links** | External hyperlinks (`#link()`) | Clickable in PPTX, preserves original styling |
|
|
257
|
+
| **Links** | Internal document links | Rendered as normal text (no hyperlink) |
|
|
258
|
+
| **Tables** | Table cells and headers | Text + shapes |
|
|
259
|
+
| **Tables** | Colored table backgrounds | Filled shapes |
|
|
260
|
+
| **Layout** | Slide dimensions (16:9, 4:3) | Full |
|
|
261
|
+
| **Layout** | Text alignment (left, center, right, justify) | Auto-detected |
|
|
262
|
+
| **Notes** | Touying speaker notes | Full |
|
|
263
|
+
| **Lists** | Bullet points | Text with bullet chars |
|
|
264
|
+
| **Plugins** | Pinit highlights | Colored overlay shapes |
|
|
265
|
+
|
|
266
|
+
## Testing
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
# Run all tests
|
|
270
|
+
pytest tests/ -v
|
|
271
|
+
|
|
272
|
+
# Run specific test modules
|
|
273
|
+
pytest tests/test_converter.py -v
|
|
274
|
+
pytest tests/test_math.py -v
|
|
275
|
+
pytest tests/test_inline_math.py -v
|
|
276
|
+
pytest tests/test_table.py -v
|
|
277
|
+
pytest tests/test_pinit.py -v
|
|
278
|
+
pytest tests/test_links.py -v
|
|
279
|
+
pytest tests/test_images.py -v
|
|
280
|
+
pytest tests/test_chinese.py -v
|
|
281
|
+
pytest tests/test_alignment.py -v
|
|
282
|
+
pytest tests/test_code_blocks.py -v
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Test Coverage
|
|
286
|
+
|
|
287
|
+
- **254 tests** covering:
|
|
288
|
+
- Converter & configuration (56 tests)
|
|
289
|
+
- SVG parser (30 tests)
|
|
290
|
+
- Inline math & stacked fractions (22 tests)
|
|
291
|
+
- Image embedding & rasterization (21 tests)
|
|
292
|
+
- SVG path pipeline (17 tests)
|
|
293
|
+
- Table rendering (17 tests)
|
|
294
|
+
- Math formulas & display curves (16 tests)
|
|
295
|
+
- Pinit annotations (15 tests)
|
|
296
|
+
- Code blocks & syntax highlighting (12 tests)
|
|
297
|
+
- Text positioning & multi-run merging (12 tests)
|
|
298
|
+
- Chinese text (11 tests)
|
|
299
|
+
- Hyperlinks (11 tests)
|
|
300
|
+
- Columns layout (7 tests)
|
|
301
|
+
- Text alignment (7 tests)
|
|
302
|
+
|
|
303
|
+
## Project Structure
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
typ2pptx/
|
|
307
|
+
core/
|
|
308
|
+
converter.py # Main SVG -> PPTX conversion logic
|
|
309
|
+
typst_svg_parser.py # typst.ts SVG parsing and text extraction
|
|
310
|
+
scripts/
|
|
311
|
+
svg_to_shapes.py # SVG path -> DrawingML pipeline (from ppt-master)
|
|
312
|
+
__main__.py # CLI entry point
|
|
313
|
+
tests/
|
|
314
|
+
conftest.py # Shared test fixtures
|
|
315
|
+
test_converter.py # Converter tests
|
|
316
|
+
test_math.py # Math formula tests
|
|
317
|
+
test_inline_math.py # Inline math and display math curve tests
|
|
318
|
+
test_chinese.py # Chinese text tests
|
|
319
|
+
test_table.py # Table rendering tests
|
|
320
|
+
test_pinit.py # Pinit annotation tests
|
|
321
|
+
test_links.py # Hyperlink tests
|
|
322
|
+
test_images.py # Image embedding tests
|
|
323
|
+
test_alignment.py # Text alignment tests
|
|
324
|
+
test_code_blocks.py # Code block & syntax highlighting tests
|
|
325
|
+
test_text_positioning.py # Text positioning tests
|
|
326
|
+
test_svg_parser.py # SVG parser tests
|
|
327
|
+
test_path_pipeline.py # Path conversion tests
|
|
328
|
+
typ_sources/ # Test Typst source files
|
|
329
|
+
basic_text.typ
|
|
330
|
+
shapes_test.typ
|
|
331
|
+
speaker_notes_test.typ
|
|
332
|
+
math_test.typ
|
|
333
|
+
chinese_test.typ
|
|
334
|
+
inline_math_test.typ
|
|
335
|
+
table_test.typ
|
|
336
|
+
pinit_test.typ
|
|
337
|
+
link_test.typ
|
|
338
|
+
image_test.typ
|
|
339
|
+
alignment_test.typ
|
|
340
|
+
code_block_test.typ
|
|
341
|
+
columns_test.typ
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## Acknowledgments
|
|
345
|
+
|
|
346
|
+
### ppt-master Attribution
|
|
347
|
+
|
|
348
|
+
The file `typ2pptx/scripts/svg_to_shapes.py` is adapted from the [ppt-master](https://github.com/niccolocorsani/ppt-master) project, which provides the core SVG path to DrawingML conversion pipeline:
|
|
349
|
+
|
|
350
|
+
- `parse_svg_path()` -- tokenizes SVG path `d` attributes into structured commands
|
|
351
|
+
- `svg_path_to_absolute()` -- converts relative path commands to absolute coordinates
|
|
352
|
+
- `normalize_path_commands()` -- reduces all curve types (S, Q, T, A) to cubic beziers (C)
|
|
353
|
+
- `path_commands_to_drawingml()` -- generates DrawingML `<a:custGeom>` XML for custom geometry
|
|
354
|
+
|
|
355
|
+
The pipeline supports solid fills, gradient fills (linear and radial), and strokes with configurable dash patterns and line caps.
|
|
356
|
+
|
|
357
|
+
The original ppt-master code has been modified for typst SVG compatibility, including:
|
|
358
|
+
|
|
359
|
+
- Added inherited style propagation through nested `<g>` elements via `ConvertContext`
|
|
360
|
+
- Added CJK font detection and Windows font fallback mapping for cross-platform PPTX compatibility
|
|
361
|
+
- Added donut-chart arc segment detection (SVG `stroke-dasharray` circles converted to filled annular sectors)
|
|
362
|
+
- Added support for element opacity, fill-opacity, and stroke-opacity (including multiplicative inheritance)
|
|
363
|
+
- Added `<ellipse>`, `<polyline>`, `<image>`, and `<text>` (with multi-run `<tspan>`) element converters
|
|
364
|
+
- Added group (`<g>`) to `<p:grpSp>` conversion with automatic bounds calculation
|
|
365
|
+
- Added shadow effect support via SVG `<filter>` (feGaussianBlur + feOffset)
|
|
366
|
+
|
|
367
|
+
## License
|
|
368
|
+
|
|
369
|
+
MIT
|