refigure 0.3.2__tar.gz → 0.3.3__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.
- {refigure-0.3.2 → refigure-0.3.3}/.gitignore +1 -0
- {refigure-0.3.2 → refigure-0.3.3}/PKG-INFO +145 -85
- {refigure-0.3.2 → refigure-0.3.3}/README.md +144 -84
- {refigure-0.3.2 → refigure-0.3.3}/pyproject.toml +1 -1
- {refigure-0.3.2 → refigure-0.3.3}/ATTRIBUTION.md +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/LICENSE +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/NOTICE +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/__main__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/_io.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/api.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/cli.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/core/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/core/chart_data.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/core/chart_render.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/core/zipsafe.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/docx/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/docx_groups.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/mcp/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/mcp/_lru.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/mcp/auth.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/mcp/cli.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/mcp/exceptions.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/mcp/server.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/mcp/state.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/mcp/vlm_cache.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/py.typed +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/vlm/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/vlm/cache.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/vlm/client.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/xlsx/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/refigure/xlsx/charts.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/support.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/core/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/core/test_chart_data.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/core/test_chart_render.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/core/test_chart_render_missing_mermaidx.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/core/test_chart_render_visual.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/docx/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/docx/test_docx.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/conftest.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/test_auth.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/test_batch.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/test_bridge.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/test_cli.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/test_http.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/test_lru.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/test_prompts.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/test_resources.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/test_schema_pin.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/test_state.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/test_tools.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/mcp/test_vlm_cache.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/test_cli.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/test_concurrency.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/test_docx_chart_group_coexistence.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/test_docx_groups.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/test_io.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/test_optional_dependency_guards.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/test_property_based.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/test_robustness.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/test_vlm_max_markers.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/test_xml_security.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/vlm/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/vlm/test_soffice_profile_isolation.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/vlm/test_vlm.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/vlm/test_vlm_cache.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/vlm/test_vlm_client.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/xlsx/__init__.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/xlsx/test_xlsx.py +0 -0
- {refigure-0.3.2 → refigure-0.3.3}/tests/unit/xlsx/test_xlsx_charts.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: refigure
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: DOCX/XLSX -> Markdown conversion with native OOXML chart-data extraction (no rasterize/OCR/VLM needed) + optional VLM interpretation for figures with no native chart data
|
|
5
5
|
Project-URL: Homepage, https://github.com/HelgDemidov/refigure
|
|
6
6
|
Project-URL: Repository, https://github.com/HelgDemidov/refigure
|
|
@@ -46,15 +46,65 @@ Description-Content-Type: text/markdown
|
|
|
46
46
|
[](https://github.com/HelgDemidov/refigure/actions/workflows/ci.yml)
|
|
47
47
|
[](LICENSE)
|
|
48
48
|
[](pyproject.toml)
|
|
49
|
+
[](https://pypi.org/project/refigure/)
|
|
50
|
+
[](https://github.com/HelgDemidov/refigure/pkgs/container/refigure)
|
|
51
|
+
[](https://registry.modelcontextprotocol.io/?q=refigure)
|
|
52
|
+
[](https://github.com/HelgDemidov/refigure/releases/latest/download/refigure.mcpb)
|
|
49
53
|
|
|
50
54
|
<!-- mcp-name: io.github.HelgDemidov/refigure -->
|
|
51
55
|
|
|
52
|
-
DOCX
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
DOCX/XLSX → Markdown that keeps charts and infographics machine-readable
|
|
57
|
+
instead of losing them to OCR or a vision model: native OOXML chart data
|
|
58
|
+
(`numCache`/`strCache`) recovers exact numbers with zero GPU calls, zero
|
|
59
|
+
VLM calls, zero lost precision — by default, not as a fallback.
|
|
60
|
+
|
|
61
|
+
That default path is also why the base install (`pip install
|
|
62
|
+
"refigure[docx,xlsx]"`) is **~500x lighter than PyTorch-based
|
|
63
|
+
alternatives** (5.6MB vs. multi-GB) — the core conversion needs no ML
|
|
64
|
+
model at all. That number is about the core architecture, not every
|
|
65
|
+
distribution format: the Docker image trades it back deliberately,
|
|
66
|
+
bundling VLM providers + LibreOffice for a turnkey composite-figure path
|
|
67
|
+
(see Docker below).
|
|
68
|
+
|
|
69
|
+
VLM interpretation itself is there for the rare figure with no native
|
|
70
|
+
data at all (a dashboard screenshot) — never required just to get real
|
|
71
|
+
numbers out of a chart, on any distribution format.
|
|
72
|
+
|
|
73
|
+
Ships as a library, CLI, MCP server, and a one-click Claude Desktop
|
|
74
|
+
bundle — every surface returns the same native-fidelity output, not a
|
|
75
|
+
degraded summary for agents.
|
|
76
|
+
|
|
77
|
+
## Features
|
|
78
|
+
|
|
79
|
+
- **Native chart-data extraction** — reads OOXML `numCache`/`strCache`
|
|
80
|
+
directly; no rasterize/OCR/VLM step for charts, real numbers every time.
|
|
81
|
+
- **Positioned zero-loss markers for composite figures** (DOCX) — grouped
|
|
82
|
+
shapes/infographics that mammoth would otherwise silently fragment into
|
|
83
|
+
disconnected pieces get a clean marker instead, with position and any
|
|
84
|
+
caption text preserved. Absent even in well-funded incumbents — see
|
|
85
|
+
[Docling issue #1287](https://github.com/docling-project/docling/issues/1287).
|
|
86
|
+
- **Optional VLM interpretation** (DOCX composite figures, `[vlm]` extra,
|
|
87
|
+
`--vlm`/`Config(use_vlm=True)`) — cloud description + a real rendered
|
|
88
|
+
mermaid diagram (26 supported diagram types — flowcharts, pie/xy charts,
|
|
89
|
+
sequence/state/ER diagrams, Gantt/timeline/sankey/treemap and more, see
|
|
90
|
+
Status below) on top of the zero-loss floor, for figures with no native
|
|
91
|
+
chart data at all (e.g. a dashboard screenshot). Provider-agnostic —
|
|
92
|
+
OpenRouter by default, or direct OpenAI/Ollama/vLLM/LM Studio/Anthropic
|
|
93
|
+
via `--vlm-provider` (`[vlm-direct]` extra). `--strict` upgrades one
|
|
94
|
+
specific failure (the system `soffice`/LibreOffice binary missing) from
|
|
95
|
+
a graceful skip to a hard error; every other VLM failure still degrades.
|
|
96
|
+
- **Rich, typed result** — `ConversionResult` (markdown + warnings +
|
|
97
|
+
chart/group counts + `vlm_used`), not a bare string.
|
|
98
|
+
- **CLI included** — `refigure` console command, stdin/stdout-first, native
|
|
99
|
+
batch mode, typed exit codes (see below).
|
|
100
|
+
- **MCP server included** — `refigure-mcp` console command (`[mcp]` extra),
|
|
101
|
+
stdio or Streamable HTTP, tools/resources/prompts, batch conversion with
|
|
102
|
+
per-file isolation (see below).
|
|
103
|
+
- **Docker image** — `ghcr.io/helgdemidov/refigure`, both console commands
|
|
104
|
+
on `PATH`, `soffice`/LibreOffice baked in — the VLM composite-figure
|
|
105
|
+
path works turnkey, no manual LibreOffice install (see below).
|
|
106
|
+
- **`.mcpb` bundle for Claude Desktop** — one-click install, no terminal
|
|
107
|
+
(`docx`+`xlsx` only, see below).
|
|
58
108
|
|
|
59
109
|
## Demo
|
|
60
110
|
|
|
@@ -117,7 +167,7 @@ uvx --from "refigure[docx,xlsx]" refigure report.docx
|
|
|
117
167
|
```
|
|
118
168
|
|
|
119
169
|
Optional VLM interpretation, for a composite figure the chart engine can't
|
|
120
|
-
reconstruct on its own (see Features
|
|
170
|
+
reconstruct on its own (see Features above):
|
|
121
171
|
|
|
122
172
|
```bash
|
|
123
173
|
pip install "refigure[docx,vlm]"
|
|
@@ -125,37 +175,13 @@ export OPENROUTER_API_KEY=... # or --vlm-api-key-file/--vlm-prov
|
|
|
125
175
|
refigure report.docx --vlm # needs the system soffice/LibreOffice binary too
|
|
126
176
|
```
|
|
127
177
|
|
|
128
|
-
##
|
|
178
|
+
## Installation & usage
|
|
129
179
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
- **Positioned zero-loss markers for composite figures** (DOCX) — grouped
|
|
133
|
-
shapes/infographics that mammoth would otherwise silently fragment into
|
|
134
|
-
disconnected pieces get a clean marker instead, with position and any
|
|
135
|
-
caption text preserved. Absent even in well-funded incumbents — see
|
|
136
|
-
[Docling issue #1287](https://github.com/docling-project/docling/issues/1287).
|
|
137
|
-
- **Optional VLM interpretation** (DOCX composite figures, `[vlm]` extra,
|
|
138
|
-
`--vlm`/`Config(use_vlm=True)`) — cloud description + a real rendered
|
|
139
|
-
mermaid diagram (26 supported diagram types — flowcharts, pie/xy charts,
|
|
140
|
-
sequence/state/ER diagrams, Gantt/timeline/sankey/treemap and more, see
|
|
141
|
-
Status below) on top of the zero-loss floor, for figures with no native
|
|
142
|
-
chart data at all (e.g. a dashboard screenshot). Provider-agnostic —
|
|
143
|
-
OpenRouter by default, or direct OpenAI/Ollama/vLLM/LM Studio/Anthropic
|
|
144
|
-
via `--vlm-provider` (`[vlm-direct]` extra). `--strict` upgrades one
|
|
145
|
-
specific failure (the system `soffice`/LibreOffice binary missing) from
|
|
146
|
-
a graceful skip to a hard error; every other VLM failure still degrades.
|
|
147
|
-
- **Rich, typed result** — `ConversionResult` (markdown + warnings +
|
|
148
|
-
chart/group counts + `vlm_used`), not a bare string.
|
|
149
|
-
- **CLI included** — `refigure` console command, stdin/stdout-first, native
|
|
150
|
-
batch mode, typed exit codes (see below).
|
|
151
|
-
- **MCP server included** — `refigure-mcp` console command (`[mcp]` extra),
|
|
152
|
-
stdio or Streamable HTTP, tools/resources/prompts, batch conversion with
|
|
153
|
-
per-file isolation (see below).
|
|
154
|
-
- **Docker image** — `ghcr.io/helgdemidov/refigure`, both console commands
|
|
155
|
-
on `PATH`, `soffice`/LibreOffice baked in — the VLM composite-figure
|
|
156
|
-
path works turnkey, no manual LibreOffice install (see below).
|
|
180
|
+
One converter, four ways to run it — pick whichever fits your pipeline.
|
|
181
|
+
Click a heading to expand it.
|
|
157
182
|
|
|
158
|
-
|
|
183
|
+
<details>
|
|
184
|
+
<summary><b>CLI</b> — a console command, stdin/stdout-first, native batch mode</summary>
|
|
159
185
|
|
|
160
186
|
`refigure` installs a console command — a thin wrapper over the same
|
|
161
187
|
`convert()` used programmatically, no separate logic:
|
|
@@ -187,12 +213,17 @@ Exit codes:
|
|
|
187
213
|
| 5 | the format's extra (`[docx]`/`[xlsx]`) isn't installed |
|
|
188
214
|
| 6 | unexpected internal error |
|
|
189
215
|
|
|
190
|
-
|
|
216
|
+
</details>
|
|
217
|
+
|
|
218
|
+
<details>
|
|
219
|
+
<summary><b>MCP server</b> — for agents/IDEs that speak the protocol directly</summary>
|
|
191
220
|
|
|
192
221
|
`refigure-mcp` — the same converters as an
|
|
193
222
|
[MCP](https://modelcontextprotocol.io) server, for agents/IDEs that speak
|
|
194
223
|
the protocol directly instead of shelling out to a CLI or importing the
|
|
195
|
-
library
|
|
224
|
+
library. Listed on the official
|
|
225
|
+
[MCP Registry](https://registry.modelcontextprotocol.io/?q=refigure) as
|
|
226
|
+
`io.github.HelgDemidov/refigure`:
|
|
196
227
|
|
|
197
228
|
```bash
|
|
198
229
|
pip install "refigure[mcp,docx,xlsx]"
|
|
@@ -246,7 +277,10 @@ fairness soft-cap once 2+ callers are configured; `refigure-mcp --help`
|
|
|
246
277
|
covers every tuning flag (concurrency, timeouts, resource-store limits,
|
|
247
278
|
batch size, VLM ceiling).
|
|
248
279
|
|
|
249
|
-
|
|
280
|
+
</details>
|
|
281
|
+
|
|
282
|
+
<details>
|
|
283
|
+
<summary><b>Docker</b> — one image, CLI and MCP server both on PATH, soffice baked in</summary>
|
|
250
284
|
|
|
251
285
|
One image, both surfaces — `refigure` and `refigure-mcp` are already on
|
|
252
286
|
`PATH`, no separate CLI/MCP builds to choose between. The one thing this
|
|
@@ -255,13 +289,17 @@ LibreOffice binary the VLM composite-figure path needs is baked in, not a
|
|
|
255
289
|
manual install.
|
|
256
290
|
|
|
257
291
|
```bash
|
|
258
|
-
docker pull ghcr.io/helgdemidov/refigure:
|
|
292
|
+
docker pull ghcr.io/helgdemidov/refigure:latest
|
|
259
293
|
```
|
|
260
294
|
|
|
295
|
+
Pin an exact version instead of `:latest` for reproducibility — e.g.
|
|
296
|
+
`:0.3.3` — see the [package page](https://github.com/HelgDemidov/refigure/pkgs/container/refigure)
|
|
297
|
+
for available tags.
|
|
298
|
+
|
|
261
299
|
CLI, via a bind mount (the image's working directory is already `/data`):
|
|
262
300
|
|
|
263
301
|
```bash
|
|
264
|
-
docker run --rm -v "$PWD:/data:ro" ghcr.io/helgdemidov/refigure:
|
|
302
|
+
docker run --rm -v "$PWD:/data:ro" ghcr.io/helgdemidov/refigure:latest \
|
|
265
303
|
refigure /data/report.docx
|
|
266
304
|
```
|
|
267
305
|
|
|
@@ -272,7 +310,7 @@ MCP, stdio — the client launches the container itself:
|
|
|
272
310
|
"mcpServers": {
|
|
273
311
|
"refigure": {
|
|
274
312
|
"command": "docker",
|
|
275
|
-
"args": ["run", "-i", "--rm", "ghcr.io/helgdemidov/refigure:
|
|
313
|
+
"args": ["run", "-i", "--rm", "ghcr.io/helgdemidov/refigure:latest", "refigure-mcp"]
|
|
276
314
|
}
|
|
277
315
|
}
|
|
278
316
|
}
|
|
@@ -287,24 +325,43 @@ flag would silently never respond:
|
|
|
287
325
|
```bash
|
|
288
326
|
echo "sk-... = alice" > tokens.txt
|
|
289
327
|
docker run --rm -p 8000:8000 -v "$PWD/tokens.txt:/data/tokens.txt:ro" \
|
|
290
|
-
ghcr.io/helgdemidov/refigure:
|
|
328
|
+
ghcr.io/helgdemidov/refigure:latest \
|
|
291
329
|
refigure-mcp --transport http --mcp-http-host 0.0.0.0 \
|
|
292
330
|
--mcp-auth-token-file /data/tokens.txt
|
|
293
331
|
```
|
|
294
332
|
|
|
333
|
+
</details>
|
|
334
|
+
|
|
335
|
+
<details>
|
|
336
|
+
<summary><b>Claude Desktop (<code>.mcpb</code>)</b> — download, double-click, done</summary>
|
|
337
|
+
|
|
338
|
+
The simplest install for a non-technical user: download, double-click,
|
|
339
|
+
done — no terminal, no `pip`/`uvx`/`docker`. Covers `docx`+`xlsx`
|
|
340
|
+
conversion only (no VLM — that needs the `[vlm]` extra, deliberately
|
|
341
|
+
not carried by this bundle); dependencies resolve fresh from PyPI via
|
|
342
|
+
`uv` on first launch, the same mechanism `uvx` uses under the hood,
|
|
343
|
+
just one click instead of a config snippet.
|
|
344
|
+
|
|
345
|
+
[**Download refigure.mcpb**](https://github.com/HelgDemidov/refigure/releases/latest/download/refigure.mcpb)
|
|
346
|
+
— open it with Claude Desktop to install.
|
|
347
|
+
|
|
348
|
+
</details>
|
|
349
|
+
|
|
295
350
|
## Real examples
|
|
296
351
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
352
|
+
Concentrated excerpts (≤200 lines each) of real `convert()` output on
|
|
353
|
+
real, openly-licensed documents — the actual markdown a pipeline would
|
|
354
|
+
ingest, not a screenshot or a cherry-picked one-liner. Each file's own
|
|
355
|
+
header states its source, license and attribution; trimmed sections are
|
|
356
|
+
marked inline, never fabricated to fill space.
|
|
300
357
|
|
|
301
358
|
| Source | Demonstrates | Output |
|
|
302
359
|
| --- | --- | --- |
|
|
303
|
-
| `hackair-d7.7-pilot-evaluation.docx` | native chart extraction —
|
|
304
|
-
| `swd2018-254-marine-litter-ia-annex.docx` |
|
|
305
|
-
| `govtech-2025-charts.xlsx` | XLSX
|
|
306
|
-
| `swd2021-396-platform-work-ia.docx` | native pie
|
|
307
|
-
| `efsa-trichinella-dashboard-guide.docx` | `--vlm` interpretation —
|
|
360
|
+
| `hackair-d7.7-pilot-evaluation.docx` | native chart extraction — real survey tables + `xychart-beta` bar charts | [examples/hackair-native-charts.md](examples/hackair-native-charts.md) |
|
|
361
|
+
| `swd2018-254-marine-litter-ia-annex.docx` | honest fallback — a chart that fails render-verification degrades to a clean table, plus 2 composite-figure zero-loss markers | [examples/swd2018-combo.md](examples/swd2018-combo.md) |
|
|
362
|
+
| `govtech-2025-charts.xlsx` | XLSX native charts — 3 distinct types (`xychart-beta`/`radar-beta`/`pie`) from one workbook | [examples/govtech-xlsx-charts.md](examples/govtech-xlsx-charts.md) |
|
|
363
|
+
| `swd2021-396-platform-work-ia.docx` | native pie + a 23-year time series, real EU-survey labels | [examples/swd2021-pie-chart.md](examples/swd2021-pie-chart.md) |
|
|
364
|
+
| `efsa-trichinella-dashboard-guide.docx` | `--vlm` interpretation — 2 screenshot figures recovered as a bar chart and a UI flowchart, real numbers | [examples/efsa-trichinella-vlm.md](examples/efsa-trichinella-vlm.md) |
|
|
308
365
|
|
|
309
366
|
Open any of these on GitHub and both views are right there: the raw
|
|
310
367
|
```` ```mermaid ```` fence an LLM/RAG pipeline would read, and its native
|
|
@@ -312,37 +369,42 @@ GitHub rendering — no extra step, that's GitHub's own Markdown support.
|
|
|
312
369
|
|
|
313
370
|
## Status
|
|
314
371
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
[`tests/integration/fixtures/manifest.yaml`](tests/integration/fixtures/manifest.yaml)
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
372
|
+
- **Validated** against 27 real documents (15 DOCX + 12 XLSX) — 407 native
|
|
373
|
+
charts found (400 rendered), 35 composite figures recovered as
|
|
374
|
+
positioned zero-loss markers. Full provenance:
|
|
375
|
+
[`tests/integration/fixtures/manifest.yaml`](tests/integration/fixtures/manifest.yaml).
|
|
376
|
+
- **Tested**: CI gates on a combined unit+integration coverage floor of 95%.
|
|
377
|
+
- **Published** as `v0.3.3` — [PyPI](https://pypi.org/project/refigure/)
|
|
378
|
+
(trusted publishing, no stored tokens),
|
|
379
|
+
[GHCR](https://github.com/HelgDemidov/refigure/pkgs/container/refigure),
|
|
380
|
+
and the official
|
|
381
|
+
[MCP Registry](https://registry.modelcontextprotocol.io/?q=refigure) as
|
|
382
|
+
`io.github.HelgDemidov/refigure`. `refigure-md` is a reserved alternate
|
|
383
|
+
name, not an active release.
|
|
384
|
+
|
|
385
|
+
Extracted from a working document-analysis pipeline (a government
|
|
386
|
+
AI-policy research corpus), not built from scratch for this release.
|
|
387
|
+
|
|
388
|
+
VLM interpretation of composite figures the chart engine can't reconstruct
|
|
389
|
+
is fully implemented and tested, not a stub — `[vlm]` extra,
|
|
390
|
+
provider-agnostic (direct OpenAI/Anthropic via `[vlm-direct]`), also needs
|
|
391
|
+
the system `soffice`/LibreOffice binary.
|
|
392
|
+
|
|
393
|
+
Mermaid-diagram recognition depends on diagram type and on what the
|
|
394
|
+
source figure actually contains:
|
|
395
|
+
|
|
396
|
+
- Common types (flowcharts, pie/xy charts) are picked reliably.
|
|
397
|
+
- More specialized ones need an unambiguous visual cue on the source figure.
|
|
398
|
+
- Not every figure produces a diagram — a plain-text description is an
|
|
399
|
+
honest fallback, not a failure.
|
|
335
400
|
|
|
336
401
|
**PDF is out of scope, on purpose — a boundary, not a gap.** PDF has no
|
|
337
402
|
equivalent of OOXML's cached chart data (`numCache`/`strCache`) for any
|
|
338
|
-
mainstream chart generator, so the native, rasterize-free extraction
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
[Docling](https://github.com/docling-project/docling) or
|
|
344
|
-
[MarkItDown](https://github.com/microsoft/markitdown) for PDF, refigure
|
|
345
|
-
for DOCX/XLSX where the chart data actually survives in the file:
|
|
403
|
+
mainstream chart generator, so the native, rasterize-free extraction this
|
|
404
|
+
project is built on doesn't transfer to it — confirmed by research into
|
|
405
|
+
PDF's own structure and how leading PDF converters handle charts today,
|
|
406
|
+
not assumed. For mixed-format corpora, route by extension instead of
|
|
407
|
+
expecting one tool to cover everything:
|
|
346
408
|
|
|
347
409
|
```python
|
|
348
410
|
import refigure.docx
|
|
@@ -356,11 +418,9 @@ else:
|
|
|
356
418
|
markdown = refigure.xlsx.convert(path).markdown
|
|
357
419
|
```
|
|
358
420
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
`io.github.HelgDemidov/refigure`. `refigure-md` is a reserved alternate
|
|
363
|
-
name, not an active release.
|
|
421
|
+
Use [Docling](https://github.com/docling-project/docling) or
|
|
422
|
+
[MarkItDown](https://github.com/microsoft/markitdown) for PDF, refigure
|
|
423
|
+
for DOCX/XLSX where the chart data actually survives in the file.
|
|
364
424
|
|
|
365
425
|
## License
|
|
366
426
|
|
|
@@ -6,15 +6,65 @@
|
|
|
6
6
|
[](https://github.com/HelgDemidov/refigure/actions/workflows/ci.yml)
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
[](pyproject.toml)
|
|
9
|
+
[](https://pypi.org/project/refigure/)
|
|
10
|
+
[](https://github.com/HelgDemidov/refigure/pkgs/container/refigure)
|
|
11
|
+
[](https://registry.modelcontextprotocol.io/?q=refigure)
|
|
12
|
+
[](https://github.com/HelgDemidov/refigure/releases/latest/download/refigure.mcpb)
|
|
9
13
|
|
|
10
14
|
<!-- mcp-name: io.github.HelgDemidov/refigure -->
|
|
11
15
|
|
|
12
|
-
DOCX
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
DOCX/XLSX → Markdown that keeps charts and infographics machine-readable
|
|
17
|
+
instead of losing them to OCR or a vision model: native OOXML chart data
|
|
18
|
+
(`numCache`/`strCache`) recovers exact numbers with zero GPU calls, zero
|
|
19
|
+
VLM calls, zero lost precision — by default, not as a fallback.
|
|
20
|
+
|
|
21
|
+
That default path is also why the base install (`pip install
|
|
22
|
+
"refigure[docx,xlsx]"`) is **~500x lighter than PyTorch-based
|
|
23
|
+
alternatives** (5.6MB vs. multi-GB) — the core conversion needs no ML
|
|
24
|
+
model at all. That number is about the core architecture, not every
|
|
25
|
+
distribution format: the Docker image trades it back deliberately,
|
|
26
|
+
bundling VLM providers + LibreOffice for a turnkey composite-figure path
|
|
27
|
+
(see Docker below).
|
|
28
|
+
|
|
29
|
+
VLM interpretation itself is there for the rare figure with no native
|
|
30
|
+
data at all (a dashboard screenshot) — never required just to get real
|
|
31
|
+
numbers out of a chart, on any distribution format.
|
|
32
|
+
|
|
33
|
+
Ships as a library, CLI, MCP server, and a one-click Claude Desktop
|
|
34
|
+
bundle — every surface returns the same native-fidelity output, not a
|
|
35
|
+
degraded summary for agents.
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
- **Native chart-data extraction** — reads OOXML `numCache`/`strCache`
|
|
40
|
+
directly; no rasterize/OCR/VLM step for charts, real numbers every time.
|
|
41
|
+
- **Positioned zero-loss markers for composite figures** (DOCX) — grouped
|
|
42
|
+
shapes/infographics that mammoth would otherwise silently fragment into
|
|
43
|
+
disconnected pieces get a clean marker instead, with position and any
|
|
44
|
+
caption text preserved. Absent even in well-funded incumbents — see
|
|
45
|
+
[Docling issue #1287](https://github.com/docling-project/docling/issues/1287).
|
|
46
|
+
- **Optional VLM interpretation** (DOCX composite figures, `[vlm]` extra,
|
|
47
|
+
`--vlm`/`Config(use_vlm=True)`) — cloud description + a real rendered
|
|
48
|
+
mermaid diagram (26 supported diagram types — flowcharts, pie/xy charts,
|
|
49
|
+
sequence/state/ER diagrams, Gantt/timeline/sankey/treemap and more, see
|
|
50
|
+
Status below) on top of the zero-loss floor, for figures with no native
|
|
51
|
+
chart data at all (e.g. a dashboard screenshot). Provider-agnostic —
|
|
52
|
+
OpenRouter by default, or direct OpenAI/Ollama/vLLM/LM Studio/Anthropic
|
|
53
|
+
via `--vlm-provider` (`[vlm-direct]` extra). `--strict` upgrades one
|
|
54
|
+
specific failure (the system `soffice`/LibreOffice binary missing) from
|
|
55
|
+
a graceful skip to a hard error; every other VLM failure still degrades.
|
|
56
|
+
- **Rich, typed result** — `ConversionResult` (markdown + warnings +
|
|
57
|
+
chart/group counts + `vlm_used`), not a bare string.
|
|
58
|
+
- **CLI included** — `refigure` console command, stdin/stdout-first, native
|
|
59
|
+
batch mode, typed exit codes (see below).
|
|
60
|
+
- **MCP server included** — `refigure-mcp` console command (`[mcp]` extra),
|
|
61
|
+
stdio or Streamable HTTP, tools/resources/prompts, batch conversion with
|
|
62
|
+
per-file isolation (see below).
|
|
63
|
+
- **Docker image** — `ghcr.io/helgdemidov/refigure`, both console commands
|
|
64
|
+
on `PATH`, `soffice`/LibreOffice baked in — the VLM composite-figure
|
|
65
|
+
path works turnkey, no manual LibreOffice install (see below).
|
|
66
|
+
- **`.mcpb` bundle for Claude Desktop** — one-click install, no terminal
|
|
67
|
+
(`docx`+`xlsx` only, see below).
|
|
18
68
|
|
|
19
69
|
## Demo
|
|
20
70
|
|
|
@@ -77,7 +127,7 @@ uvx --from "refigure[docx,xlsx]" refigure report.docx
|
|
|
77
127
|
```
|
|
78
128
|
|
|
79
129
|
Optional VLM interpretation, for a composite figure the chart engine can't
|
|
80
|
-
reconstruct on its own (see Features
|
|
130
|
+
reconstruct on its own (see Features above):
|
|
81
131
|
|
|
82
132
|
```bash
|
|
83
133
|
pip install "refigure[docx,vlm]"
|
|
@@ -85,37 +135,13 @@ export OPENROUTER_API_KEY=... # or --vlm-api-key-file/--vlm-prov
|
|
|
85
135
|
refigure report.docx --vlm # needs the system soffice/LibreOffice binary too
|
|
86
136
|
```
|
|
87
137
|
|
|
88
|
-
##
|
|
138
|
+
## Installation & usage
|
|
89
139
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
- **Positioned zero-loss markers for composite figures** (DOCX) — grouped
|
|
93
|
-
shapes/infographics that mammoth would otherwise silently fragment into
|
|
94
|
-
disconnected pieces get a clean marker instead, with position and any
|
|
95
|
-
caption text preserved. Absent even in well-funded incumbents — see
|
|
96
|
-
[Docling issue #1287](https://github.com/docling-project/docling/issues/1287).
|
|
97
|
-
- **Optional VLM interpretation** (DOCX composite figures, `[vlm]` extra,
|
|
98
|
-
`--vlm`/`Config(use_vlm=True)`) — cloud description + a real rendered
|
|
99
|
-
mermaid diagram (26 supported diagram types — flowcharts, pie/xy charts,
|
|
100
|
-
sequence/state/ER diagrams, Gantt/timeline/sankey/treemap and more, see
|
|
101
|
-
Status below) on top of the zero-loss floor, for figures with no native
|
|
102
|
-
chart data at all (e.g. a dashboard screenshot). Provider-agnostic —
|
|
103
|
-
OpenRouter by default, or direct OpenAI/Ollama/vLLM/LM Studio/Anthropic
|
|
104
|
-
via `--vlm-provider` (`[vlm-direct]` extra). `--strict` upgrades one
|
|
105
|
-
specific failure (the system `soffice`/LibreOffice binary missing) from
|
|
106
|
-
a graceful skip to a hard error; every other VLM failure still degrades.
|
|
107
|
-
- **Rich, typed result** — `ConversionResult` (markdown + warnings +
|
|
108
|
-
chart/group counts + `vlm_used`), not a bare string.
|
|
109
|
-
- **CLI included** — `refigure` console command, stdin/stdout-first, native
|
|
110
|
-
batch mode, typed exit codes (see below).
|
|
111
|
-
- **MCP server included** — `refigure-mcp` console command (`[mcp]` extra),
|
|
112
|
-
stdio or Streamable HTTP, tools/resources/prompts, batch conversion with
|
|
113
|
-
per-file isolation (see below).
|
|
114
|
-
- **Docker image** — `ghcr.io/helgdemidov/refigure`, both console commands
|
|
115
|
-
on `PATH`, `soffice`/LibreOffice baked in — the VLM composite-figure
|
|
116
|
-
path works turnkey, no manual LibreOffice install (see below).
|
|
140
|
+
One converter, four ways to run it — pick whichever fits your pipeline.
|
|
141
|
+
Click a heading to expand it.
|
|
117
142
|
|
|
118
|
-
|
|
143
|
+
<details>
|
|
144
|
+
<summary><b>CLI</b> — a console command, stdin/stdout-first, native batch mode</summary>
|
|
119
145
|
|
|
120
146
|
`refigure` installs a console command — a thin wrapper over the same
|
|
121
147
|
`convert()` used programmatically, no separate logic:
|
|
@@ -147,12 +173,17 @@ Exit codes:
|
|
|
147
173
|
| 5 | the format's extra (`[docx]`/`[xlsx]`) isn't installed |
|
|
148
174
|
| 6 | unexpected internal error |
|
|
149
175
|
|
|
150
|
-
|
|
176
|
+
</details>
|
|
177
|
+
|
|
178
|
+
<details>
|
|
179
|
+
<summary><b>MCP server</b> — for agents/IDEs that speak the protocol directly</summary>
|
|
151
180
|
|
|
152
181
|
`refigure-mcp` — the same converters as an
|
|
153
182
|
[MCP](https://modelcontextprotocol.io) server, for agents/IDEs that speak
|
|
154
183
|
the protocol directly instead of shelling out to a CLI or importing the
|
|
155
|
-
library
|
|
184
|
+
library. Listed on the official
|
|
185
|
+
[MCP Registry](https://registry.modelcontextprotocol.io/?q=refigure) as
|
|
186
|
+
`io.github.HelgDemidov/refigure`:
|
|
156
187
|
|
|
157
188
|
```bash
|
|
158
189
|
pip install "refigure[mcp,docx,xlsx]"
|
|
@@ -206,7 +237,10 @@ fairness soft-cap once 2+ callers are configured; `refigure-mcp --help`
|
|
|
206
237
|
covers every tuning flag (concurrency, timeouts, resource-store limits,
|
|
207
238
|
batch size, VLM ceiling).
|
|
208
239
|
|
|
209
|
-
|
|
240
|
+
</details>
|
|
241
|
+
|
|
242
|
+
<details>
|
|
243
|
+
<summary><b>Docker</b> — one image, CLI and MCP server both on PATH, soffice baked in</summary>
|
|
210
244
|
|
|
211
245
|
One image, both surfaces — `refigure` and `refigure-mcp` are already on
|
|
212
246
|
`PATH`, no separate CLI/MCP builds to choose between. The one thing this
|
|
@@ -215,13 +249,17 @@ LibreOffice binary the VLM composite-figure path needs is baked in, not a
|
|
|
215
249
|
manual install.
|
|
216
250
|
|
|
217
251
|
```bash
|
|
218
|
-
docker pull ghcr.io/helgdemidov/refigure:
|
|
252
|
+
docker pull ghcr.io/helgdemidov/refigure:latest
|
|
219
253
|
```
|
|
220
254
|
|
|
255
|
+
Pin an exact version instead of `:latest` for reproducibility — e.g.
|
|
256
|
+
`:0.3.3` — see the [package page](https://github.com/HelgDemidov/refigure/pkgs/container/refigure)
|
|
257
|
+
for available tags.
|
|
258
|
+
|
|
221
259
|
CLI, via a bind mount (the image's working directory is already `/data`):
|
|
222
260
|
|
|
223
261
|
```bash
|
|
224
|
-
docker run --rm -v "$PWD:/data:ro" ghcr.io/helgdemidov/refigure:
|
|
262
|
+
docker run --rm -v "$PWD:/data:ro" ghcr.io/helgdemidov/refigure:latest \
|
|
225
263
|
refigure /data/report.docx
|
|
226
264
|
```
|
|
227
265
|
|
|
@@ -232,7 +270,7 @@ MCP, stdio — the client launches the container itself:
|
|
|
232
270
|
"mcpServers": {
|
|
233
271
|
"refigure": {
|
|
234
272
|
"command": "docker",
|
|
235
|
-
"args": ["run", "-i", "--rm", "ghcr.io/helgdemidov/refigure:
|
|
273
|
+
"args": ["run", "-i", "--rm", "ghcr.io/helgdemidov/refigure:latest", "refigure-mcp"]
|
|
236
274
|
}
|
|
237
275
|
}
|
|
238
276
|
}
|
|
@@ -247,24 +285,43 @@ flag would silently never respond:
|
|
|
247
285
|
```bash
|
|
248
286
|
echo "sk-... = alice" > tokens.txt
|
|
249
287
|
docker run --rm -p 8000:8000 -v "$PWD/tokens.txt:/data/tokens.txt:ro" \
|
|
250
|
-
ghcr.io/helgdemidov/refigure:
|
|
288
|
+
ghcr.io/helgdemidov/refigure:latest \
|
|
251
289
|
refigure-mcp --transport http --mcp-http-host 0.0.0.0 \
|
|
252
290
|
--mcp-auth-token-file /data/tokens.txt
|
|
253
291
|
```
|
|
254
292
|
|
|
293
|
+
</details>
|
|
294
|
+
|
|
295
|
+
<details>
|
|
296
|
+
<summary><b>Claude Desktop (<code>.mcpb</code>)</b> — download, double-click, done</summary>
|
|
297
|
+
|
|
298
|
+
The simplest install for a non-technical user: download, double-click,
|
|
299
|
+
done — no terminal, no `pip`/`uvx`/`docker`. Covers `docx`+`xlsx`
|
|
300
|
+
conversion only (no VLM — that needs the `[vlm]` extra, deliberately
|
|
301
|
+
not carried by this bundle); dependencies resolve fresh from PyPI via
|
|
302
|
+
`uv` on first launch, the same mechanism `uvx` uses under the hood,
|
|
303
|
+
just one click instead of a config snippet.
|
|
304
|
+
|
|
305
|
+
[**Download refigure.mcpb**](https://github.com/HelgDemidov/refigure/releases/latest/download/refigure.mcpb)
|
|
306
|
+
— open it with Claude Desktop to install.
|
|
307
|
+
|
|
308
|
+
</details>
|
|
309
|
+
|
|
255
310
|
## Real examples
|
|
256
311
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
312
|
+
Concentrated excerpts (≤200 lines each) of real `convert()` output on
|
|
313
|
+
real, openly-licensed documents — the actual markdown a pipeline would
|
|
314
|
+
ingest, not a screenshot or a cherry-picked one-liner. Each file's own
|
|
315
|
+
header states its source, license and attribution; trimmed sections are
|
|
316
|
+
marked inline, never fabricated to fill space.
|
|
260
317
|
|
|
261
318
|
| Source | Demonstrates | Output |
|
|
262
319
|
| --- | --- | --- |
|
|
263
|
-
| `hackair-d7.7-pilot-evaluation.docx` | native chart extraction —
|
|
264
|
-
| `swd2018-254-marine-litter-ia-annex.docx` |
|
|
265
|
-
| `govtech-2025-charts.xlsx` | XLSX
|
|
266
|
-
| `swd2021-396-platform-work-ia.docx` | native pie
|
|
267
|
-
| `efsa-trichinella-dashboard-guide.docx` | `--vlm` interpretation —
|
|
320
|
+
| `hackair-d7.7-pilot-evaluation.docx` | native chart extraction — real survey tables + `xychart-beta` bar charts | [examples/hackair-native-charts.md](examples/hackair-native-charts.md) |
|
|
321
|
+
| `swd2018-254-marine-litter-ia-annex.docx` | honest fallback — a chart that fails render-verification degrades to a clean table, plus 2 composite-figure zero-loss markers | [examples/swd2018-combo.md](examples/swd2018-combo.md) |
|
|
322
|
+
| `govtech-2025-charts.xlsx` | XLSX native charts — 3 distinct types (`xychart-beta`/`radar-beta`/`pie`) from one workbook | [examples/govtech-xlsx-charts.md](examples/govtech-xlsx-charts.md) |
|
|
323
|
+
| `swd2021-396-platform-work-ia.docx` | native pie + a 23-year time series, real EU-survey labels | [examples/swd2021-pie-chart.md](examples/swd2021-pie-chart.md) |
|
|
324
|
+
| `efsa-trichinella-dashboard-guide.docx` | `--vlm` interpretation — 2 screenshot figures recovered as a bar chart and a UI flowchart, real numbers | [examples/efsa-trichinella-vlm.md](examples/efsa-trichinella-vlm.md) |
|
|
268
325
|
|
|
269
326
|
Open any of these on GitHub and both views are right there: the raw
|
|
270
327
|
```` ```mermaid ```` fence an LLM/RAG pipeline would read, and its native
|
|
@@ -272,37 +329,42 @@ GitHub rendering — no extra step, that's GitHub's own Markdown support.
|
|
|
272
329
|
|
|
273
330
|
## Status
|
|
274
331
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
[`tests/integration/fixtures/manifest.yaml`](tests/integration/fixtures/manifest.yaml)
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
332
|
+
- **Validated** against 27 real documents (15 DOCX + 12 XLSX) — 407 native
|
|
333
|
+
charts found (400 rendered), 35 composite figures recovered as
|
|
334
|
+
positioned zero-loss markers. Full provenance:
|
|
335
|
+
[`tests/integration/fixtures/manifest.yaml`](tests/integration/fixtures/manifest.yaml).
|
|
336
|
+
- **Tested**: CI gates on a combined unit+integration coverage floor of 95%.
|
|
337
|
+
- **Published** as `v0.3.3` — [PyPI](https://pypi.org/project/refigure/)
|
|
338
|
+
(trusted publishing, no stored tokens),
|
|
339
|
+
[GHCR](https://github.com/HelgDemidov/refigure/pkgs/container/refigure),
|
|
340
|
+
and the official
|
|
341
|
+
[MCP Registry](https://registry.modelcontextprotocol.io/?q=refigure) as
|
|
342
|
+
`io.github.HelgDemidov/refigure`. `refigure-md` is a reserved alternate
|
|
343
|
+
name, not an active release.
|
|
344
|
+
|
|
345
|
+
Extracted from a working document-analysis pipeline (a government
|
|
346
|
+
AI-policy research corpus), not built from scratch for this release.
|
|
347
|
+
|
|
348
|
+
VLM interpretation of composite figures the chart engine can't reconstruct
|
|
349
|
+
is fully implemented and tested, not a stub — `[vlm]` extra,
|
|
350
|
+
provider-agnostic (direct OpenAI/Anthropic via `[vlm-direct]`), also needs
|
|
351
|
+
the system `soffice`/LibreOffice binary.
|
|
352
|
+
|
|
353
|
+
Mermaid-diagram recognition depends on diagram type and on what the
|
|
354
|
+
source figure actually contains:
|
|
355
|
+
|
|
356
|
+
- Common types (flowcharts, pie/xy charts) are picked reliably.
|
|
357
|
+
- More specialized ones need an unambiguous visual cue on the source figure.
|
|
358
|
+
- Not every figure produces a diagram — a plain-text description is an
|
|
359
|
+
honest fallback, not a failure.
|
|
295
360
|
|
|
296
361
|
**PDF is out of scope, on purpose — a boundary, not a gap.** PDF has no
|
|
297
362
|
equivalent of OOXML's cached chart data (`numCache`/`strCache`) for any
|
|
298
|
-
mainstream chart generator, so the native, rasterize-free extraction
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
[Docling](https://github.com/docling-project/docling) or
|
|
304
|
-
[MarkItDown](https://github.com/microsoft/markitdown) for PDF, refigure
|
|
305
|
-
for DOCX/XLSX where the chart data actually survives in the file:
|
|
363
|
+
mainstream chart generator, so the native, rasterize-free extraction this
|
|
364
|
+
project is built on doesn't transfer to it — confirmed by research into
|
|
365
|
+
PDF's own structure and how leading PDF converters handle charts today,
|
|
366
|
+
not assumed. For mixed-format corpora, route by extension instead of
|
|
367
|
+
expecting one tool to cover everything:
|
|
306
368
|
|
|
307
369
|
```python
|
|
308
370
|
import refigure.docx
|
|
@@ -316,11 +378,9 @@ else:
|
|
|
316
378
|
markdown = refigure.xlsx.convert(path).markdown
|
|
317
379
|
```
|
|
318
380
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
`io.github.HelgDemidov/refigure`. `refigure-md` is a reserved alternate
|
|
323
|
-
name, not an active release.
|
|
381
|
+
Use [Docling](https://github.com/docling-project/docling) or
|
|
382
|
+
[MarkItDown](https://github.com/microsoft/markitdown) for PDF, refigure
|
|
383
|
+
for DOCX/XLSX where the chart data actually survives in the file.
|
|
324
384
|
|
|
325
385
|
## License
|
|
326
386
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "refigure"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.3"
|
|
8
8
|
description = "DOCX/XLSX -> Markdown conversion with native OOXML chart-data extraction (no rasterize/OCR/VLM needed) + optional VLM interpretation for figures with no native chart data"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|