exstruct 0.2.80__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- exstruct/__init__.py +387 -0
- exstruct/cli/availability.py +49 -0
- exstruct/cli/main.py +134 -0
- exstruct/core/__init__.py +0 -0
- exstruct/core/cells.py +1039 -0
- exstruct/core/charts.py +241 -0
- exstruct/core/integrate.py +388 -0
- exstruct/core/shapes.py +275 -0
- exstruct/engine.py +643 -0
- exstruct/errors.py +35 -0
- exstruct/io/__init__.py +555 -0
- exstruct/models/__init__.py +335 -0
- exstruct/models/maps.py +335 -0
- exstruct/models/types.py +8 -0
- exstruct/py.typed +0 -0
- exstruct/render/__init__.py +118 -0
- exstruct-0.2.80.dist-info/METADATA +435 -0
- exstruct-0.2.80.dist-info/RECORD +20 -0
- exstruct-0.2.80.dist-info/WHEEL +4 -0
- exstruct-0.2.80.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Generator
|
|
4
|
+
import json
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Literal
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Shape(BaseModel):
|
|
12
|
+
"""Shape metadata (position, size, text, and styling)."""
|
|
13
|
+
|
|
14
|
+
id: int | None = Field(
|
|
15
|
+
default=None, description="Sequential shape id within the sheet (if applicable)."
|
|
16
|
+
)
|
|
17
|
+
text: str = Field(description="Visible text content of the shape.")
|
|
18
|
+
l: int = Field(description="Left offset (Excel units).") # noqa: E741
|
|
19
|
+
t: int = Field(description="Top offset (Excel units).")
|
|
20
|
+
w: int | None = Field(default=None, description="Shape width (None if unknown).")
|
|
21
|
+
h: int | None = Field(default=None, description="Shape height (None if unknown).")
|
|
22
|
+
type: str | None = Field(default=None, description="Excel shape type name.")
|
|
23
|
+
rotation: float | None = Field(
|
|
24
|
+
default=None, description="Rotation angle in degrees."
|
|
25
|
+
)
|
|
26
|
+
begin_arrow_style: int | None = Field(
|
|
27
|
+
default=None, description="Arrow style enum for the start of a connector."
|
|
28
|
+
)
|
|
29
|
+
end_arrow_style: int | None = Field(
|
|
30
|
+
default=None, description="Arrow style enum for the end of a connector."
|
|
31
|
+
)
|
|
32
|
+
begin_id: int | None = Field(
|
|
33
|
+
default=None,
|
|
34
|
+
description=(
|
|
35
|
+
"Shape id at the start of a connector (ConnectorFormat.BeginConnectedShape)."
|
|
36
|
+
),
|
|
37
|
+
)
|
|
38
|
+
end_id: int | None = Field(
|
|
39
|
+
default=None,
|
|
40
|
+
description=(
|
|
41
|
+
"Shape id at the end of a connector (ConnectorFormat.EndConnectedShape)."
|
|
42
|
+
),
|
|
43
|
+
)
|
|
44
|
+
direction: Literal["E", "SE", "S", "SW", "W", "NW", "N", "NE"] | None = Field(
|
|
45
|
+
default=None, description="Connector direction (compass heading)."
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class CellRow(BaseModel):
|
|
50
|
+
"""A single row of cells with optional hyperlinks."""
|
|
51
|
+
|
|
52
|
+
r: int = Field(description="Row index (1-based).")
|
|
53
|
+
c: dict[str, int | float | str] = Field(
|
|
54
|
+
description="Column index (string) to cell value map."
|
|
55
|
+
)
|
|
56
|
+
links: dict[str, str] | None = Field(
|
|
57
|
+
default=None, description="Optional hyperlinks per column index."
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class ChartSeries(BaseModel):
|
|
62
|
+
"""Series metadata for a chart."""
|
|
63
|
+
|
|
64
|
+
name: str = Field(description="Series display name.")
|
|
65
|
+
name_range: str | None = Field(
|
|
66
|
+
default=None, description="Range reference for the series name."
|
|
67
|
+
)
|
|
68
|
+
x_range: str | None = Field(
|
|
69
|
+
default=None, description="Range reference for X axis values."
|
|
70
|
+
)
|
|
71
|
+
y_range: str | None = Field(
|
|
72
|
+
default=None, description="Range reference for Y axis values."
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class Chart(BaseModel):
|
|
77
|
+
"""Chart metadata including series and layout."""
|
|
78
|
+
|
|
79
|
+
name: str = Field(description="Chart name.")
|
|
80
|
+
chart_type: str = Field(description="Chart type (e.g., Column, Line).")
|
|
81
|
+
title: str | None = Field(default=None, description="Chart title.")
|
|
82
|
+
y_axis_title: str = Field(description="Y-axis title.")
|
|
83
|
+
y_axis_range: list[float] = Field(
|
|
84
|
+
default_factory=list, description="Y-axis range [min, max] when available."
|
|
85
|
+
)
|
|
86
|
+
w: int | None = Field(default=None, description="Chart width (None if unknown).")
|
|
87
|
+
h: int | None = Field(default=None, description="Chart height (None if unknown).")
|
|
88
|
+
series: list[ChartSeries] = Field(description="Series included in the chart.")
|
|
89
|
+
l: int = Field(description="Left offset (Excel units).") # noqa: E741
|
|
90
|
+
t: int = Field(description="Top offset (Excel units).")
|
|
91
|
+
error: str | None = Field(
|
|
92
|
+
default=None, description="Extraction error detail if any."
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class PrintArea(BaseModel):
|
|
97
|
+
"""Cell coordinate bounds for a print area."""
|
|
98
|
+
|
|
99
|
+
r1: int = Field(description="Start row (1-based).")
|
|
100
|
+
c1: int = Field(description="Start column (1-based).")
|
|
101
|
+
r2: int = Field(description="End row (1-based, inclusive).")
|
|
102
|
+
c2: int = Field(description="End column (1-based, inclusive).")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class SheetData(BaseModel):
|
|
106
|
+
"""Structured data for a single sheet."""
|
|
107
|
+
|
|
108
|
+
rows: list[CellRow] = Field(
|
|
109
|
+
default_factory=list, description="Extracted rows with cell values and links."
|
|
110
|
+
)
|
|
111
|
+
shapes: list[Shape] = Field(
|
|
112
|
+
default_factory=list, description="Shapes detected on the sheet."
|
|
113
|
+
)
|
|
114
|
+
charts: list[Chart] = Field(
|
|
115
|
+
default_factory=list, description="Charts detected on the sheet."
|
|
116
|
+
)
|
|
117
|
+
table_candidates: list[str] = Field(
|
|
118
|
+
default_factory=list, description="Cell ranges likely representing tables."
|
|
119
|
+
)
|
|
120
|
+
print_areas: list[PrintArea] = Field(
|
|
121
|
+
default_factory=list, description="User-defined print areas."
|
|
122
|
+
)
|
|
123
|
+
auto_print_areas: list[PrintArea] = Field(
|
|
124
|
+
default_factory=list, description="COM-computed auto page-break areas."
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
def _as_payload(self) -> dict[str, object]:
|
|
128
|
+
from ..io import dict_without_empty_values
|
|
129
|
+
|
|
130
|
+
return dict_without_empty_values(self.model_dump(exclude_none=True)) # type: ignore
|
|
131
|
+
|
|
132
|
+
def to_json(self, *, pretty: bool = False, indent: int | None = None) -> str:
|
|
133
|
+
"""
|
|
134
|
+
Serialize the sheet into JSON text.
|
|
135
|
+
"""
|
|
136
|
+
indent_val = 2 if pretty and indent is None else indent
|
|
137
|
+
return json.dumps(self._as_payload(), ensure_ascii=False, indent=indent_val)
|
|
138
|
+
|
|
139
|
+
def to_yaml(self) -> str:
|
|
140
|
+
"""
|
|
141
|
+
Serialize the sheet into YAML text (requires pyyaml).
|
|
142
|
+
"""
|
|
143
|
+
from ..io import _require_yaml
|
|
144
|
+
|
|
145
|
+
yaml = _require_yaml()
|
|
146
|
+
return str(
|
|
147
|
+
yaml.safe_dump(
|
|
148
|
+
self._as_payload(),
|
|
149
|
+
allow_unicode=True,
|
|
150
|
+
sort_keys=False,
|
|
151
|
+
indent=2,
|
|
152
|
+
)
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
def to_toon(self) -> str:
|
|
156
|
+
"""
|
|
157
|
+
Serialize the sheet into TOON text (requires python-toon).
|
|
158
|
+
"""
|
|
159
|
+
from ..io import _require_toon
|
|
160
|
+
|
|
161
|
+
toon = _require_toon()
|
|
162
|
+
return str(toon.encode(self._as_payload()))
|
|
163
|
+
|
|
164
|
+
def save(
|
|
165
|
+
self, path: str | Path, *, pretty: bool = False, indent: int | None = None
|
|
166
|
+
) -> Path:
|
|
167
|
+
"""
|
|
168
|
+
Save the sheet to a file, inferring format from the extension.
|
|
169
|
+
|
|
170
|
+
- .json → JSON
|
|
171
|
+
- .yaml/.yml → YAML
|
|
172
|
+
- .toon → TOON
|
|
173
|
+
"""
|
|
174
|
+
dest = Path(path)
|
|
175
|
+
fmt = (dest.suffix.lstrip(".") or "json").lower()
|
|
176
|
+
match fmt:
|
|
177
|
+
case "json":
|
|
178
|
+
dest.write_text(
|
|
179
|
+
self.to_json(pretty=pretty, indent=indent), encoding="utf-8"
|
|
180
|
+
)
|
|
181
|
+
case "yaml" | "yml":
|
|
182
|
+
dest.write_text(self.to_yaml(), encoding="utf-8")
|
|
183
|
+
case "toon":
|
|
184
|
+
dest.write_text(self.to_toon(), encoding="utf-8")
|
|
185
|
+
case _:
|
|
186
|
+
raise ValueError(f"Unsupported export format: {fmt}")
|
|
187
|
+
return dest
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class WorkbookData(BaseModel):
|
|
191
|
+
"""Workbook-level container with per-sheet data."""
|
|
192
|
+
|
|
193
|
+
book_name: str = Field(description="Workbook file name (no path).")
|
|
194
|
+
sheets: dict[str, SheetData] = Field(
|
|
195
|
+
description="Mapping of sheet name to SheetData."
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
def to_json(self, *, pretty: bool = False, indent: int | None = None) -> str:
|
|
199
|
+
"""
|
|
200
|
+
Serialize the workbook into JSON text.
|
|
201
|
+
"""
|
|
202
|
+
from ..io import serialize_workbook
|
|
203
|
+
|
|
204
|
+
return serialize_workbook(self, fmt="json", pretty=pretty, indent=indent)
|
|
205
|
+
|
|
206
|
+
def to_yaml(self) -> str:
|
|
207
|
+
"""
|
|
208
|
+
Serialize the workbook into YAML text (requires pyyaml).
|
|
209
|
+
"""
|
|
210
|
+
from ..io import serialize_workbook
|
|
211
|
+
|
|
212
|
+
return serialize_workbook(self, fmt="yaml")
|
|
213
|
+
|
|
214
|
+
def to_toon(self) -> str:
|
|
215
|
+
"""
|
|
216
|
+
Serialize the workbook into TOON text (requires python-toon).
|
|
217
|
+
"""
|
|
218
|
+
from ..io import serialize_workbook
|
|
219
|
+
|
|
220
|
+
return serialize_workbook(self, fmt="toon")
|
|
221
|
+
|
|
222
|
+
def save(
|
|
223
|
+
self, path: str | Path, *, pretty: bool = False, indent: int | None = None
|
|
224
|
+
) -> Path:
|
|
225
|
+
"""
|
|
226
|
+
Save the workbook to a file, inferring format from the extension.
|
|
227
|
+
|
|
228
|
+
- .json → JSON
|
|
229
|
+
- .yaml/.yml → YAML
|
|
230
|
+
- .toon → TOON
|
|
231
|
+
"""
|
|
232
|
+
from ..io import save_as_json, save_as_toon, save_as_yaml
|
|
233
|
+
|
|
234
|
+
dest = Path(path)
|
|
235
|
+
fmt = (dest.suffix.lstrip(".") or "json").lower()
|
|
236
|
+
match fmt:
|
|
237
|
+
case "json":
|
|
238
|
+
save_as_json(self, dest, pretty=pretty, indent=indent)
|
|
239
|
+
case "yaml" | "yml":
|
|
240
|
+
save_as_yaml(self, dest)
|
|
241
|
+
case "toon":
|
|
242
|
+
save_as_toon(self, dest)
|
|
243
|
+
case _:
|
|
244
|
+
raise ValueError(f"Unsupported export format: {fmt}")
|
|
245
|
+
return dest
|
|
246
|
+
|
|
247
|
+
def __getitem__(self, sheet_name: str) -> SheetData:
|
|
248
|
+
"""Return the SheetData for the given sheet name."""
|
|
249
|
+
return self.sheets[sheet_name]
|
|
250
|
+
|
|
251
|
+
def __iter__(self) -> Generator[tuple[str, SheetData], None, None]:
|
|
252
|
+
"""Iterate over (sheet_name, SheetData) pairs in order."""
|
|
253
|
+
yield from self.sheets.items()
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class PrintAreaView(BaseModel):
|
|
257
|
+
"""Slice of a sheet restricted to a print area (manual or auto)."""
|
|
258
|
+
|
|
259
|
+
book_name: str = Field(description="Workbook name owning the area.")
|
|
260
|
+
sheet_name: str = Field(description="Sheet name owning the area.")
|
|
261
|
+
area: PrintArea = Field(description="Print area bounds.")
|
|
262
|
+
shapes: list[Shape] = Field(
|
|
263
|
+
default_factory=list, description="Shapes overlapping the area."
|
|
264
|
+
)
|
|
265
|
+
charts: list[Chart] = Field(
|
|
266
|
+
default_factory=list, description="Charts overlapping the area."
|
|
267
|
+
)
|
|
268
|
+
rows: list[CellRow] = Field(
|
|
269
|
+
default_factory=list, description="Rows within the area bounds."
|
|
270
|
+
)
|
|
271
|
+
table_candidates: list[str] = Field(
|
|
272
|
+
default_factory=list, description="Table candidates intersecting the area."
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
def _as_payload(self) -> dict[str, object]:
|
|
276
|
+
from ..io import dict_without_empty_values
|
|
277
|
+
|
|
278
|
+
return dict_without_empty_values(self.model_dump(exclude_none=True)) # type: ignore
|
|
279
|
+
|
|
280
|
+
def to_json(self, *, pretty: bool = False, indent: int | None = None) -> str:
|
|
281
|
+
"""
|
|
282
|
+
Serialize the print-area view into JSON text.
|
|
283
|
+
"""
|
|
284
|
+
indent_val = 2 if pretty and indent is None else indent
|
|
285
|
+
return json.dumps(self._as_payload(), ensure_ascii=False, indent=indent_val)
|
|
286
|
+
|
|
287
|
+
def to_yaml(self) -> str:
|
|
288
|
+
"""
|
|
289
|
+
Serialize the print-area view into YAML text (requires pyyaml).
|
|
290
|
+
"""
|
|
291
|
+
from ..io import _require_yaml
|
|
292
|
+
|
|
293
|
+
yaml = _require_yaml()
|
|
294
|
+
return str(
|
|
295
|
+
yaml.safe_dump(
|
|
296
|
+
self._as_payload(),
|
|
297
|
+
allow_unicode=True,
|
|
298
|
+
sort_keys=False,
|
|
299
|
+
indent=2,
|
|
300
|
+
)
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
def to_toon(self) -> str:
|
|
304
|
+
"""
|
|
305
|
+
Serialize the print-area view into TOON text (requires python-toon).
|
|
306
|
+
"""
|
|
307
|
+
from ..io import _require_toon
|
|
308
|
+
|
|
309
|
+
toon = _require_toon()
|
|
310
|
+
return str(toon.encode(self._as_payload()))
|
|
311
|
+
|
|
312
|
+
def save(
|
|
313
|
+
self, path: str | Path, *, pretty: bool = False, indent: int | None = None
|
|
314
|
+
) -> Path:
|
|
315
|
+
"""
|
|
316
|
+
Save the print-area view to a file, inferring format from the extension.
|
|
317
|
+
|
|
318
|
+
- .json JSON
|
|
319
|
+
- .yaml/.yml YAML
|
|
320
|
+
- .toon TOON
|
|
321
|
+
"""
|
|
322
|
+
dest = Path(path)
|
|
323
|
+
fmt = (dest.suffix.lstrip(".") or "json").lower()
|
|
324
|
+
match fmt:
|
|
325
|
+
case "json":
|
|
326
|
+
dest.write_text(
|
|
327
|
+
self.to_json(pretty=pretty, indent=indent), encoding="utf-8"
|
|
328
|
+
)
|
|
329
|
+
case "yaml" | "yml":
|
|
330
|
+
dest.write_text(self.to_yaml(), encoding="utf-8")
|
|
331
|
+
case "toon":
|
|
332
|
+
dest.write_text(self.to_toon(), encoding="utf-8")
|
|
333
|
+
case _:
|
|
334
|
+
raise ValueError(f"Unsupported export format: {fmt}")
|
|
335
|
+
return dest
|
exstruct/models/maps.py
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# msoShapeType
|
|
2
|
+
MSO_SHAPE_TYPE_MAP = {
|
|
3
|
+
30: "3DModel", # 3D モデル
|
|
4
|
+
1: "AutoShape", # オートシェイプ
|
|
5
|
+
2: "Callout", # 吹き出し
|
|
6
|
+
20: "Canvas", # キャンバス
|
|
7
|
+
3: "Chart", # グラフ
|
|
8
|
+
4: "Comment", # コメント
|
|
9
|
+
27: "ContentApp", # コンテンツ Office アドイン
|
|
10
|
+
21: "Diagram", # ダイアグラム
|
|
11
|
+
7: "EmbeddedOLEObject", # 埋め込み OLE オブジェクト
|
|
12
|
+
8: "FormControl", # フォーム コントロール
|
|
13
|
+
5: "Freeform", # フリーフォーム
|
|
14
|
+
28: "Graphic", # グラフィック
|
|
15
|
+
6: "Group", # グループ
|
|
16
|
+
24: "IgxGraphic", # SmartArt グラフィック
|
|
17
|
+
22: "Ink", # インク
|
|
18
|
+
23: "InkComment", # インク コメント
|
|
19
|
+
9: "Line", # Line
|
|
20
|
+
31: "Linked3DModel", # リンクされた 3D モデル
|
|
21
|
+
29: "LinkedGraphic", # リンクされたグラフィック
|
|
22
|
+
10: "LinkedOLEObject", # リンク OLE オブジェクト
|
|
23
|
+
11: "LinkedPicture", # リンク画像
|
|
24
|
+
16: "Media", # メディア
|
|
25
|
+
12: "OLEControlObject", # OLE コントロール オブジェクト
|
|
26
|
+
13: "Picture", # 画像
|
|
27
|
+
14: "Placeholder", # プレースホルダー
|
|
28
|
+
18: "ScriptAnchor", # スクリプト アンカー
|
|
29
|
+
-2: "ShapeTypeMixed", # 図形の種類の組み合わせ
|
|
30
|
+
25: "Slicer", # Slicer
|
|
31
|
+
19: "Table", # テーブル
|
|
32
|
+
17: "TextBox", # テキスト ボックス
|
|
33
|
+
15: "TextEffect", # テキスト効果
|
|
34
|
+
26: "WebVideo", # Web ビデオ
|
|
35
|
+
}
|
|
36
|
+
# AutoShapeType(Type==1のときのみ)
|
|
37
|
+
MSO_AUTO_SHAPE_TYPE_MAP = {
|
|
38
|
+
149: "10pointStar", # 10-point star
|
|
39
|
+
150: "12pointStar", # 12-point star
|
|
40
|
+
94: "16pointStar", # 16-point star
|
|
41
|
+
95: "24pointStar", # 24-point star
|
|
42
|
+
96: "32pointStar", # 32-point star
|
|
43
|
+
91: "4pointStar", # 4-point star
|
|
44
|
+
92: "5pointStar", # 5-point star
|
|
45
|
+
147: "6pointStar", # 6-point star
|
|
46
|
+
148: "7pointStar", # 7-point star
|
|
47
|
+
93: "8pointStar", # 8-point star
|
|
48
|
+
129: "ActionButtonBackorPrevious", # Back or Previous button
|
|
49
|
+
131: "ActionButtonBeginning", # Beginning button
|
|
50
|
+
125: "ActionButtonCustom", # Custom action button
|
|
51
|
+
134: "ActionButtonDocument", # Document button
|
|
52
|
+
132: "ActionButtonEnd", # End button
|
|
53
|
+
130: "ActionButtonForwardorNext", # Forward or Next button
|
|
54
|
+
127: "ActionButtonHelp", # Help button
|
|
55
|
+
126: "ActionButtonHome", # Home button
|
|
56
|
+
128: "ActionButtonInformation", # Information button
|
|
57
|
+
136: "ActionButtonMovie", # Movie button
|
|
58
|
+
133: "ActionButtonReturn", # Return button
|
|
59
|
+
135: "ActionButtonSound", # Sound button
|
|
60
|
+
25: "Arc", # Arc
|
|
61
|
+
137: "Balloon", # Balloon
|
|
62
|
+
41: "BentArrow", # Bent Arrow
|
|
63
|
+
44: "BentUpArrow", # Bent Up Arrow
|
|
64
|
+
15: "Bevel", # Bevel
|
|
65
|
+
20: "BlockArc", # Block Arc
|
|
66
|
+
13: "Can", # Can
|
|
67
|
+
182: "ChartPlus", # Chart Plus
|
|
68
|
+
181: "ChartStar", # Chart Star
|
|
69
|
+
180: "ChartX", # Chart X
|
|
70
|
+
52: "Chevron", # Chevron
|
|
71
|
+
161: "Chord", # Chord
|
|
72
|
+
60: "CircularArrow", # Circular Arrow
|
|
73
|
+
179: "Cloud", # Cloud
|
|
74
|
+
108: "CloudCallout", # Cloud Callout
|
|
75
|
+
162: "Corner", # Corner
|
|
76
|
+
169: "CornerTabs", # Corner Tabs
|
|
77
|
+
11: "Cross", # Cross
|
|
78
|
+
14: "Cube", # Cube
|
|
79
|
+
48: "CurvedDownArrow", # Curved Down Arrow
|
|
80
|
+
100: "CurvedDownRibbon", # Curved Down Ribbon
|
|
81
|
+
46: "CurvedLeftArrow", # Curved Left Arrow
|
|
82
|
+
45: "CurvedRightArrow", # Curved Right Arrow
|
|
83
|
+
47: "CurvedUpArrow", # Curved Up Arrow
|
|
84
|
+
99: "CurvedUpRibbon", # Curved Up Ribbon
|
|
85
|
+
144: "Decagon", # Decagon
|
|
86
|
+
141: "DiagonalStripe", # Diagonal Stripe
|
|
87
|
+
4: "Diamond", # Diamond
|
|
88
|
+
146: "Dodecagon", # Dodecagon
|
|
89
|
+
18: "Donut", # Donut
|
|
90
|
+
27: "DoubleBrace", # Double Brace
|
|
91
|
+
26: "DoubleBracket", # Double Bracket
|
|
92
|
+
104: "DoubleWave", # Double Wave
|
|
93
|
+
36: "DownArrow", # Down Arrow
|
|
94
|
+
56: "DownArrowCallout", # Down Arrow Callout
|
|
95
|
+
98: "DownRibbon", # Down Ribbon
|
|
96
|
+
89: "Explosion1", # Explosion 1
|
|
97
|
+
90: "Explosion2", # Explosion 2
|
|
98
|
+
62: "FlowchartAlternateProcess", # Alternate Process
|
|
99
|
+
75: "FlowchartCard", # Card
|
|
100
|
+
79: "FlowchartCollate", # Collate
|
|
101
|
+
73: "FlowchartConnector", # Connector
|
|
102
|
+
64: "FlowchartData", # Data
|
|
103
|
+
63: "FlowchartDecision", # Decision
|
|
104
|
+
84: "FlowchartDelay", # Delay
|
|
105
|
+
87: "FlowchartDirectAccessStorage", # Direct Access Storage
|
|
106
|
+
88: "FlowchartDisplay", # Display
|
|
107
|
+
67: "FlowchartDocument", # Document
|
|
108
|
+
81: "FlowchartExtract", # Extract
|
|
109
|
+
66: "FlowchartInternalStorage", # Internal Storage
|
|
110
|
+
86: "FlowchartMagneticDisk", # Magnetic Disk
|
|
111
|
+
71: "FlowchartManualInput", # Manual Input
|
|
112
|
+
72: "FlowchartManualOperation", # Manual Operation
|
|
113
|
+
82: "FlowchartMerge", # Merge
|
|
114
|
+
68: "FlowchartMultidocument", # Multidocument
|
|
115
|
+
139: "FlowchartOfflineStorage", # Offline Storage
|
|
116
|
+
74: "FlowchartOffpageConnector", # Offpage Connector
|
|
117
|
+
78: "FlowchartOr", # Or
|
|
118
|
+
65: "FlowchartPredefinedProcess", # Predefined Process
|
|
119
|
+
70: "FlowchartPreparation", # Preparation
|
|
120
|
+
61: "FlowchartProcess", # Process
|
|
121
|
+
76: "FlowchartPunchedTape", # Punched Tape
|
|
122
|
+
85: "FlowchartSequentialAccessStorage", # Sequential Access Storage
|
|
123
|
+
80: "FlowchartSort", # Sort
|
|
124
|
+
83: "FlowchartStoredData", # Stored Data
|
|
125
|
+
77: "FlowchartSummingJunction", # Summing Junction
|
|
126
|
+
69: "FlowchartTerminator", # Terminator
|
|
127
|
+
16: "FoldedCorner", # Folded Corner
|
|
128
|
+
158: "Frame", # Frame
|
|
129
|
+
174: "Funnel", # Funnel
|
|
130
|
+
172: "Gear6", # Gear with six teeth
|
|
131
|
+
173: "Gear9", # Gear with nine teeth
|
|
132
|
+
159: "HalfFrame", # Half Frame
|
|
133
|
+
21: "Heart", # Heart
|
|
134
|
+
145: "Heptagon", # Heptagon
|
|
135
|
+
10: "Hexagon", # Hexagon
|
|
136
|
+
102: "HorizontalScroll", # Horizontal Scroll
|
|
137
|
+
7: "IsoscelesTriangle", # Isosceles Triangle
|
|
138
|
+
34: "LeftArrow", # Left Arrow
|
|
139
|
+
54: "LeftArrowCallout", # Left Arrow Callout
|
|
140
|
+
31: "LeftBrace", # Left Brace
|
|
141
|
+
29: "LeftBracket", # Left Bracket
|
|
142
|
+
176: "LeftCircularArrow", # Left Circular Arrow
|
|
143
|
+
37: "LeftRightArrow", # LeftRight Arrow
|
|
144
|
+
57: "LeftRightArrowCallout", # LeftRight Arrow Callout
|
|
145
|
+
177: "LeftRightCircularArrow", # LeftRight Circular Arrow
|
|
146
|
+
140: "LeftRightRibbon", # LeftRight Ribbon
|
|
147
|
+
40: "LeftRightUpArrow", # LeftRightUp Arrow
|
|
148
|
+
43: "LeftUpArrow", # LeftUp Arrow
|
|
149
|
+
22: "LightningBolt", # Lightning Bolt
|
|
150
|
+
109: "LineCallout1", # Line Callout 1
|
|
151
|
+
113: "LineCallout1AccentBar", # Line Callout 1 Accent Bar
|
|
152
|
+
121: "LineCallout1BorderandAccentBar", # Line Callout 1 Border and Accent Bar
|
|
153
|
+
117: "LineCallout1NoBorder", # Line Callout 1 No Border
|
|
154
|
+
110: "LineCallout2", # Line Callout 2
|
|
155
|
+
114: "LineCallout2AccentBar", # Line Callout 2 Accent Bar
|
|
156
|
+
122: "LineCallout2BorderandAccentBar", # Line Callout 2 Border and Accent Bar
|
|
157
|
+
118: "LineCallout2NoBorder", # Line Callout 2 No Border
|
|
158
|
+
111: "LineCallout3", # Line Callout 3
|
|
159
|
+
115: "LineCallout3AccentBar", # Line Callout 3 Accent Bar
|
|
160
|
+
123: "LineCallout3BorderandAccentBar", # Line Callout 3 Border and Accent Bar
|
|
161
|
+
119: "LineCallout3NoBorder", # Line Callout 3 No Border
|
|
162
|
+
112: "LineCallout4", # Line Callout 4
|
|
163
|
+
116: "LineCallout4AccentBar", # Line Callout 4 Accent Bar
|
|
164
|
+
124: "LineCallout4BorderandAccentBar", # Line Callout 4 Border and Accent Bar
|
|
165
|
+
120: "LineCallout4NoBorder", # Line Callout 4 No Border
|
|
166
|
+
183: "LineInverse", # Line inverse
|
|
167
|
+
166: "MathDivide", # Math Divide
|
|
168
|
+
167: "MathEqual", # Math Equal
|
|
169
|
+
164: "MathMinus", # Math Minus
|
|
170
|
+
165: "MathMultiply", # Math Multiply
|
|
171
|
+
168: "MathNotEqual", # Math Not Equal
|
|
172
|
+
163: "MathPlus", # Math Plus
|
|
173
|
+
-2: "Mixed", # Mixed (combination)
|
|
174
|
+
24: "Moon", # Moon
|
|
175
|
+
143: "NonIsoscelesTrapezoid", # Non Isosceles Trapezoid
|
|
176
|
+
19: "NoSymbol", # No symbol
|
|
177
|
+
50: "NotchedRightArrow", # Notched Right Arrow
|
|
178
|
+
138: "NotPrimitive", # Not supported
|
|
179
|
+
6: "Octagon", # Octagon
|
|
180
|
+
9: "Oval", # Oval
|
|
181
|
+
107: "OvalCallout", # Oval Callout
|
|
182
|
+
2: "Parallelogram", # Parallelogram
|
|
183
|
+
51: "Pentagon", # Pentagon
|
|
184
|
+
142: "Pie", # Pie
|
|
185
|
+
175: "PieWedge", # Pie Wedge
|
|
186
|
+
28: "Plaque", # Plaque
|
|
187
|
+
171: "PlaqueTabs", # Plaque Tabs
|
|
188
|
+
39: "QuadArrow", # Quad Arrow
|
|
189
|
+
59: "QuadArrowCallout", # Quad Arrow Callout
|
|
190
|
+
1: "Rectangle", # Rectangle
|
|
191
|
+
105: "RectangularCallout", # Rectangular Callout
|
|
192
|
+
12: "RegularPentagon", # Regular Pentagon
|
|
193
|
+
33: "RightArrow", # Right Arrow
|
|
194
|
+
53: "RightArrowCallout", # Right Arrow Callout
|
|
195
|
+
32: "RightBrace", # Right Brace
|
|
196
|
+
30: "RightBracket", # Right Bracket
|
|
197
|
+
8: "RightTriangle", # Right Triangle
|
|
198
|
+
151: "Round1Rectangle", # Round 1 Rectangle
|
|
199
|
+
153: "Round2DiagRectangle", # Round 2 Diagonal Rectangle
|
|
200
|
+
152: "Round2SameRectangle", # Round 2 Same Rectangle
|
|
201
|
+
5: "RoundedRectangle", # Rounded Rectangle
|
|
202
|
+
106: "RoundedRectangularCallout", # Rounded Rectangular Callout
|
|
203
|
+
17: "SmileyFace", # Smiley Face
|
|
204
|
+
155: "Snip1Rectangle", # Snip 1 Rectangle
|
|
205
|
+
157: "Snip2DiagRectangle", # Snip 2 Diagonal Rectangle
|
|
206
|
+
156: "Snip2SameRectangle", # Snip 2 Same Rectangle
|
|
207
|
+
154: "SnipRoundRectangle", # Snip Round Rectangle
|
|
208
|
+
170: "SquareTabs", # Square Tabs
|
|
209
|
+
49: "StripedRightArrow", # Striped Right Arrow
|
|
210
|
+
23: "Sun", # Sun
|
|
211
|
+
178: "SwooshArrow", # Swoosh Arrow
|
|
212
|
+
160: "Tear", # Tear
|
|
213
|
+
3: "Trapezoid", # Trapezoid
|
|
214
|
+
35: "UpArrow", # Up Arrow
|
|
215
|
+
55: "UpArrowCallout", # Up Arrow Callout
|
|
216
|
+
38: "UpDownArrow", # Up Down Arrow
|
|
217
|
+
58: "UpDownArrowCallout", # Up Down Arrow Callout
|
|
218
|
+
97: "UpRibbon", # Up Ribbon
|
|
219
|
+
42: "UTurnArrow", # U-Turn Arrow
|
|
220
|
+
101: "VerticalScroll", # Vertical Scroll
|
|
221
|
+
103: "Wave", # Wave
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
XL_CHART_TYPE_MAP = {
|
|
225
|
+
-4098: "3DArea",
|
|
226
|
+
78: "3DAreaStacked",
|
|
227
|
+
79: "3DAreaStacked100",
|
|
228
|
+
60: "3DBarClustered",
|
|
229
|
+
61: "3DBarStacked",
|
|
230
|
+
62: "3DBarStacked100",
|
|
231
|
+
-4100: "3DColumn",
|
|
232
|
+
54: "3DColumnClustered",
|
|
233
|
+
55: "3DColumnStacked",
|
|
234
|
+
56: "3DColumnStacked100",
|
|
235
|
+
-4101: "3DLine",
|
|
236
|
+
-4102: "3DPie",
|
|
237
|
+
70: "3DPieExploded",
|
|
238
|
+
1: "Area",
|
|
239
|
+
135: "AreaEx",
|
|
240
|
+
76: "AreaStacked",
|
|
241
|
+
77: "AreaStacked100",
|
|
242
|
+
137: "AreaStacked100Ex",
|
|
243
|
+
136: "AreaStackedEx",
|
|
244
|
+
57: "BarClustered",
|
|
245
|
+
132: "BarClusteredEx",
|
|
246
|
+
71: "BarOfPie",
|
|
247
|
+
58: "BarStacked",
|
|
248
|
+
59: "BarStacked100",
|
|
249
|
+
134: "BarStacked100Ex",
|
|
250
|
+
133: "BarStackedEx",
|
|
251
|
+
121: "Boxwhisker",
|
|
252
|
+
15: "Bubble",
|
|
253
|
+
87: "Bubble3DEffect",
|
|
254
|
+
139: "BubbleEx",
|
|
255
|
+
51: "ColumnClustered",
|
|
256
|
+
124: "ColumnClusteredEx",
|
|
257
|
+
52: "ColumnStacked",
|
|
258
|
+
53: "ColumnStacked100",
|
|
259
|
+
126: "ColumnStacked100Ex",
|
|
260
|
+
125: "ColumnStackedEx",
|
|
261
|
+
-4152: "Combo",
|
|
262
|
+
115: "ComboAreaStackedColumnClustered",
|
|
263
|
+
113: "ComboColumnClusteredLine",
|
|
264
|
+
114: "ComboColumnClusteredLineSecondaryAxis",
|
|
265
|
+
102: "ConeBarClustered",
|
|
266
|
+
103: "ConeBarStacked",
|
|
267
|
+
104: "ConeBarStacked100",
|
|
268
|
+
105: "ConeCol",
|
|
269
|
+
99: "ConeColClustered",
|
|
270
|
+
100: "ConeColStacked",
|
|
271
|
+
101: "ConeColStacked100",
|
|
272
|
+
95: "CylinderBarClustered",
|
|
273
|
+
96: "CylinderBarStacked",
|
|
274
|
+
97: "CylinderBarStacked100",
|
|
275
|
+
98: "CylinderCol",
|
|
276
|
+
92: "CylinderColClustered",
|
|
277
|
+
93: "CylinderColStacked",
|
|
278
|
+
94: "CylinderColStacked100",
|
|
279
|
+
-4120: "Doughnut",
|
|
280
|
+
131: "DoughnutEx",
|
|
281
|
+
80: "DoughnutExploded",
|
|
282
|
+
123: "Funnel",
|
|
283
|
+
118: "Histogram",
|
|
284
|
+
4: "Line",
|
|
285
|
+
127: "LineEx",
|
|
286
|
+
65: "LineMarkers",
|
|
287
|
+
66: "LineMarkersStacked",
|
|
288
|
+
67: "LineMarkersStacked100",
|
|
289
|
+
63: "LineStacked",
|
|
290
|
+
64: "LineStacked100",
|
|
291
|
+
129: "LineStacked100Ex",
|
|
292
|
+
128: "LineStackedEx",
|
|
293
|
+
116: "OtherCombinations",
|
|
294
|
+
122: "Pareto",
|
|
295
|
+
5: "Pie",
|
|
296
|
+
130: "PieEx",
|
|
297
|
+
69: "PieExploded",
|
|
298
|
+
68: "PieOfPie",
|
|
299
|
+
109: "PyramidBarClustered",
|
|
300
|
+
110: "PyramidBarStacked",
|
|
301
|
+
111: "PyramidBarStacked100",
|
|
302
|
+
112: "PyramidCol",
|
|
303
|
+
106: "PyramidColClustered",
|
|
304
|
+
107: "PyramidColStacked",
|
|
305
|
+
108: "PyramidColStacked100",
|
|
306
|
+
-4151: "Radar",
|
|
307
|
+
82: "RadarFilled",
|
|
308
|
+
81: "RadarMarkers",
|
|
309
|
+
140: "RegionMap",
|
|
310
|
+
88: "StockHLC",
|
|
311
|
+
89: "StockOHLC",
|
|
312
|
+
90: "StockVHLC",
|
|
313
|
+
91: "StockVOHLC",
|
|
314
|
+
-2: "SuggestedChart",
|
|
315
|
+
120: "Sunburst",
|
|
316
|
+
83: "Surface",
|
|
317
|
+
85: "SurfaceTopView",
|
|
318
|
+
86: "SurfaceTopViewWireframe",
|
|
319
|
+
84: "SurfaceWireframe",
|
|
320
|
+
117: "Treemap",
|
|
321
|
+
119: "Waterfall",
|
|
322
|
+
-4169: "XYScatter",
|
|
323
|
+
138: "XYScatterEx",
|
|
324
|
+
74: "XYScatterLines",
|
|
325
|
+
75: "XYScatterLinesNoMarkers",
|
|
326
|
+
72: "XYScatterSmooth",
|
|
327
|
+
73: "XYScatterSmoothNoMarkers",
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
XL_CHART_TYPE_PIE = {5, 18, 69, 68, 130} # Pie, PieExploded, PieOfPie, PieEx
|
|
331
|
+
XL_CHART_TYPE_DOUGHNUT = {-4120, 131, 80} # Doughnut, DoughnutEx, DoughnutExploded
|
|
332
|
+
XL_CHART_TYPE_XY_SCATTER = {-4169, 72, 74, 75, 73, 138} # XYScatter variants
|
|
333
|
+
XL_CHART_TYPE_BOXWHISKER = {121}
|
|
334
|
+
XL_CHART_TYPE_BUBBLE = {15, 87, 139}
|
|
335
|
+
XL_CHART_TYPE_LINE = {4, 127, 65, 66, 67, 63, 64, 128, 129}
|
exstruct/models/types.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
"""Shared JSON-compatible type aliases used across ExStruct."""
|
|
4
|
+
|
|
5
|
+
JsonPrimitive = str | int | float | bool | None
|
|
6
|
+
JsonStructure = JsonPrimitive | list["JsonStructure"] | dict[str, "JsonStructure"]
|
|
7
|
+
|
|
8
|
+
__all__ = ["JsonPrimitive", "JsonStructure"]
|
exstruct/py.typed
ADDED
|
File without changes
|