tabella-docs 2.0.1__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.
- tabella_docs-2.0.1/LICENSE +21 -0
- tabella_docs-2.0.1/PKG-INFO +315 -0
- tabella_docs-2.0.1/README.md +266 -0
- tabella_docs-2.0.1/pyproject.toml +67 -0
- tabella_docs-2.0.1/setup.cfg +4 -0
- tabella_docs-2.0.1/tabella/__init__.py +53 -0
- tabella_docs-2.0.1/tabella/convert.py +187 -0
- tabella_docs-2.0.1/tabella/create.py +777 -0
- tabella_docs-2.0.1/tabella/read.py +248 -0
- tabella_docs-2.0.1/tabella/utils.py +43 -0
- tabella_docs-2.0.1/tabella_docs.egg-info/PKG-INFO +315 -0
- tabella_docs-2.0.1/tabella_docs.egg-info/SOURCES.txt +14 -0
- tabella_docs-2.0.1/tabella_docs.egg-info/dependency_links.txt +1 -0
- tabella_docs-2.0.1/tabella_docs.egg-info/requires.txt +31 -0
- tabella_docs-2.0.1/tabella_docs.egg-info/top_level.txt +1 -0
- tabella_docs-2.0.1/tests/test_text_section_alias.py +75 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 D Yiapanis
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tabella-docs
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: Portable document lifecycle suite — create (.docx/.xlsx/.pptx/.pdf/.odt/.ods/.odp), convert (pandoc), and read (anydoc + LiteParse OCR) documents. Agent Plugins v1 compatible.
|
|
5
|
+
Author-email: D Yiapanis <d@yiapanis.co>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dyiapanis/tabella
|
|
8
|
+
Project-URL: Source, https://github.com/dyiapanis/tabella
|
|
9
|
+
Project-URL: Issues, https://github.com/dyiapanis/tabella/issues
|
|
10
|
+
Keywords: documents,docx,xlsx,pptx,pdf,odt,pandoc,anydoc,document-generation,markdown,ocr,agent-plugins,mcp
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Office/Business :: Office Suites
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Provides-Extra: create
|
|
23
|
+
Requires-Dist: python-docx<2.0,>=1.0; extra == "create"
|
|
24
|
+
Requires-Dist: openpyxl<4.0,>=3.1; extra == "create"
|
|
25
|
+
Requires-Dist: python-pptx<2.0,>=0.6; extra == "create"
|
|
26
|
+
Requires-Dist: weasyprint<70.0,>=60.0; extra == "create"
|
|
27
|
+
Requires-Dist: odfpy<2.0,>=1.4; extra == "create"
|
|
28
|
+
Requires-Dist: Pillow<13.0,>=10.0; extra == "create"
|
|
29
|
+
Requires-Dist: lxml<7.0,>=5.0; extra == "create"
|
|
30
|
+
Provides-Extra: read
|
|
31
|
+
Requires-Dist: firecrawl-anydoc<0.3.0,>=0.1.1; extra == "read"
|
|
32
|
+
Requires-Dist: liteparse<3.0.0,>=2.0.0; extra == "read"
|
|
33
|
+
Requires-Dist: PyMuPDF<2.0,>=1.24; extra == "read"
|
|
34
|
+
Provides-Extra: convert
|
|
35
|
+
Provides-Extra: all
|
|
36
|
+
Requires-Dist: python-docx<2.0,>=1.0; extra == "all"
|
|
37
|
+
Requires-Dist: openpyxl<4.0,>=3.1; extra == "all"
|
|
38
|
+
Requires-Dist: python-pptx<2.0,>=0.6; extra == "all"
|
|
39
|
+
Requires-Dist: weasyprint<70.0,>=60.0; extra == "all"
|
|
40
|
+
Requires-Dist: odfpy<2.0,>=1.4; extra == "all"
|
|
41
|
+
Requires-Dist: Pillow<13.0,>=10.0; extra == "all"
|
|
42
|
+
Requires-Dist: lxml<7.0,>=5.0; extra == "all"
|
|
43
|
+
Requires-Dist: firecrawl-anydoc<0.3.0,>=0.1.1; extra == "all"
|
|
44
|
+
Requires-Dist: liteparse<3.0.0,>=2.0.0; extra == "all"
|
|
45
|
+
Requires-Dist: PyMuPDF<2.0,>=1.24; extra == "all"
|
|
46
|
+
Provides-Extra: dev
|
|
47
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
48
|
+
Dynamic: license-file
|
|
49
|
+
|
|
50
|
+
# tabella
|
|
51
|
+
|
|
52
|
+
A portable document lifecycle suite: create, convert, and read documents
|
|
53
|
+
from structured JSON or raw HTML/CSS.
|
|
54
|
+
|
|
55
|
+
## Cross-Platform Compatibility
|
|
56
|
+
|
|
57
|
+
This package conforms to the [Agent Plugins v1.0.0](https://agent-plugins.org/specification)
|
|
58
|
+
specification. It works with any compatible AI agent client that supports
|
|
59
|
+
MCP servers, including:
|
|
60
|
+
|
|
61
|
+
- [Hermes Agent](https://hermes-agent.nousresearch.com)
|
|
62
|
+
- [Cursor](https://cursor.com)
|
|
63
|
+
- [Claude Desktop](https://claude.ai/download)
|
|
64
|
+
- Any client that supports the Model Context Protocol
|
|
65
|
+
|
|
66
|
+
### Three installation paths
|
|
67
|
+
|
|
68
|
+
**Transports:** the plugin ships both.
|
|
69
|
+
|
|
70
|
+
- **stdio (default)** — the declaring client spawns `mcp_server.py` itself
|
|
71
|
+
(Agent Plugins v1 lifecycle; `PLUGIN_ROOT`/`PLUGIN_DATA` injected by the
|
|
72
|
+
client). Nothing to run by hand.
|
|
73
|
+
- **streamable-HTTP (self-host lane)** — for clients that prefer connecting
|
|
74
|
+
to a URL, run the server yourself:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
python3 scripts/mcp_http_server.py # serves 127.0.0.1:8602
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
First run bootstraps the dependency venv (or `scripts/setup.sh`);
|
|
81
|
+
`TABELLA_TOKEN` enables bearer auth. Then point an `mcp.json`
|
|
82
|
+
`streamable-http` entry at `http://127.0.0.1:8602/mcp`.
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
**Agent Plugins v1 package** — clients that support the v1 spec auto-discover
|
|
87
|
+
`plugin.json` + `mcp.json` from the repo root and launch the MCP server:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Hermes Agent
|
|
91
|
+
hermes plugins install dyiapanis/tabella --no-enable
|
|
92
|
+
hermes plugins enable tabella
|
|
93
|
+
|
|
94
|
+
# Other v1-compatible clients: follow your client's plugin installation instructions
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**MCP server (manual)** — point any MCP-compatible client at the server directly:
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"mcpServers": {
|
|
102
|
+
"tabella": {
|
|
103
|
+
"type": "stdio",
|
|
104
|
+
"command": "python3",
|
|
105
|
+
"args": ["/path/to/tabella/mcp_server.py"]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**pip install** — use the Python library directly:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
pip install tabella-docs[all]
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Or install only the modules you need:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
pip install tabella-docs[create] # python-docx, openpyxl, python-pptx, weasyprint, odfpy
|
|
121
|
+
pip install tabella-docs[read] # firecrawl-anydoc, liteparse, PyMuPDF
|
|
122
|
+
pip install tabella-docs[convert] # no python deps (needs system pandoc + texlive-xetex)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Modules
|
|
126
|
+
|
|
127
|
+
### Create
|
|
128
|
+
|
|
129
|
+
Generate documents from structured JSON content or raw HTML/CSS:
|
|
130
|
+
|
|
131
|
+
- **DOCX** — Word documents (python-docx)
|
|
132
|
+
- **XLSX** — Spreadsheets (openpyxl)
|
|
133
|
+
- **PPTX** — Presentations (python-pptx)
|
|
134
|
+
- **PDF** — Print-ready documents and visual designs (WeasyPrint)
|
|
135
|
+
- Document-style: structured JSON → HTML → PDF
|
|
136
|
+
- Visual-style: raw HTML/CSS (Grid, Flexbox, gradients, themes) → PDF
|
|
137
|
+
- **ODT/ODS/ODP** — OpenDocument formats (odfpy)
|
|
138
|
+
|
|
139
|
+
Accepts plain strings (auto-normalized), HTML, or structured dicts with
|
|
140
|
+
sections, sheets, slides, tables, images, and page breaks.
|
|
141
|
+
|
|
142
|
+
### Convert
|
|
143
|
+
|
|
144
|
+
Format conversion via pandoc + LaTeX (page size, margins, headers/footers
|
|
145
|
+
configurable). **Pandoc 3.1 supports 44 input and 54 output formats** —
|
|
146
|
+
`doc_convert` passes your `from`/`to` through, so all of them work. The
|
|
147
|
+
everyday set:
|
|
148
|
+
|
|
149
|
+
| Format | In | Out | Notes |
|
|
150
|
+
|---|---|---|---|
|
|
151
|
+
| Markdown (`.md`, variants) | ✅ | ✅ | gfm, commonmark, multimarkdown, strict… |
|
|
152
|
+
| HTML | ✅ | ✅ | html4/html5, chunkedhtml |
|
|
153
|
+
| DOCX (Word) | ✅ | ✅ | |
|
|
154
|
+
| ODT | ✅ | ✅ | + `opendocument` |
|
|
155
|
+
| PDF | ✅ | ✅ | in: text-based PDFs (pandoc's pdf reader); out: needs `pdflatex`/`xelatex` (texlive) — engine auto-selected |
|
|
156
|
+
| LaTeX (`.tex`) | ✅ | ✅ | incl. beamer slides out |
|
|
157
|
+
| RST | ✅ | ✅ | |
|
|
158
|
+
| EPUB | ✅ | ✅ | out: epub2/epub3 |
|
|
159
|
+
| CSV / TSV | ✅ | ✅ | out via markdown/AST route |
|
|
160
|
+
| RTF | ✅ | ✅ | |
|
|
161
|
+
| Plain text (`.txt`) | ✅ | ✅ | |
|
|
162
|
+
| Org-mode, MediaWiki, Jira wiki, Textile, DocBook, FB2, OPML, IPynb, JATS | ✅ | ✅ | writers for most |
|
|
163
|
+
| Typst / man / ms / texinfo / AsciiDoc | ✅ | ✅ | typst in+out |
|
|
164
|
+
| Presentations | — | ✅ | beamer, revealjs, slidy, s5, dzslides (from any reader, Markdown especially) |
|
|
165
|
+
| Pandoc AST (JSON) | ✅ | ✅ | for programmatic pipelines |
|
|
166
|
+
|
|
167
|
+
Everything not in the table: if `pandoc --list-input-formats` /
|
|
168
|
+
`--list-output-formats` lists it, `doc_convert` accepts it as-is — unknown
|
|
169
|
+
extensions pass through untouched.
|
|
170
|
+
|
|
171
|
+
### Read
|
|
172
|
+
|
|
173
|
+
Extract text and metadata from any document:
|
|
174
|
+
|
|
175
|
+
- **Office formats** (DOCX, DOC, XLSX, XLSB, PPTX, PPT, ODT, ODS, ODP, RTF,
|
|
176
|
+
EPUB, CSV) and **text-based PDFs** → GitHub-Flavored Markdown via
|
|
177
|
+
[anydoc](https://github.com/firecrawl/anydoc) (~4ms, in-process)
|
|
178
|
+
- **Scanned PDFs** and **images** (JPG, PNG, TIFF) → OCR via
|
|
179
|
+
[LiteParse](https://github.com/run-llama/liteparse) (Tesseract)
|
|
180
|
+
- **Plain text** (.txt, .md, .json, .py, .yaml, etc.) → direct file read
|
|
181
|
+
- Returns structured Markdown (office formats) or plain text (OCR, plain text)
|
|
182
|
+
|
|
183
|
+
## Prerequisites
|
|
184
|
+
|
|
185
|
+
### Create module
|
|
186
|
+
|
|
187
|
+
The create module uses a separate Python venv for heavy document libraries.
|
|
188
|
+
Set `DOCS_VENV_PYTHON` to point to it:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# Create a dedicated venv
|
|
192
|
+
python -m venv ~/.venvs/docs
|
|
193
|
+
~/.venvs/docs/bin/pip install python-docx openpyxl python-pptx weasyprint odfpy Pillow lxml PyMuPDF firecrawl-anydoc liteparse
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Or install the libraries into your main Python environment:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
pip install tabella-docs[create]
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Read module
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
~/.venvs/docs/bin/pip install firecrawl-anydoc liteparse PyMuPDF
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Or:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
pip install tabella-docs[read]
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Convert module
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
pip install tabella-docs[convert]
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Requires system-installed pandoc and a LaTeX engine:
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
# Debian/Ubuntu
|
|
224
|
+
sudo apt install pandoc texlive-xetex
|
|
225
|
+
|
|
226
|
+
# macOS
|
|
227
|
+
brew install pandoc basictex
|
|
228
|
+
|
|
229
|
+
# Arch
|
|
230
|
+
sudo pacman -S pandoc texlive
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### WeasyPrint system dependencies (PDF creation)
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Debian/Ubuntu
|
|
237
|
+
sudo apt install libcairo2 libpango-1.0-0 libgdk-pixbuf-2.0-0
|
|
238
|
+
|
|
239
|
+
# macOS
|
|
240
|
+
brew install cairo pango gdk-pixbuf
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Installation from source
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
git clone https://github.com/dyiapanis/tabella.git
|
|
247
|
+
cd tabella
|
|
248
|
+
pip install -e ".[all]"
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Configuration
|
|
252
|
+
|
|
253
|
+
| Variable | Purpose | Default |
|
|
254
|
+
|----------|---------|---------|
|
|
255
|
+
| `DOCS_VENV_PYTHON` | Python binary for document libraries | `PLUGIN_DATA/venv/bin/python` or `~/.venvs/docs/bin/python` |
|
|
256
|
+
| `DOCS_OUTPUT_DIR` | Default output directory for generated documents | `~/Documents` |
|
|
257
|
+
| `PLUGIN_DATA` | Client-managed data directory (set by v1 client) | — |
|
|
258
|
+
| `PLUGIN_ROOT` | Plugin root directory (set by v1 client) | — |
|
|
259
|
+
|
|
260
|
+
### Automatic bootstrap
|
|
261
|
+
|
|
262
|
+
On first startup, the MCP server checks if the docs venv exists. If not,
|
|
263
|
+
it runs `scripts/setup.sh` to create a venv in `PLUGIN_DATA` (provided by
|
|
264
|
+
the v1 client) or `~/.venvs/docs` as fallback, and installs all dependencies:
|
|
265
|
+
python-docx, openpyxl, python-pptx, weasyprint, odfpy, PyMuPDF,
|
|
266
|
+
firecrawl-anydoc, liteparse.
|
|
267
|
+
|
|
268
|
+
This means the v1 package is fully self-contained — no manual pip install
|
|
269
|
+
required. The bootstrap runs once; subsequent startups use the existing venv.
|
|
270
|
+
|
|
271
|
+
## Usage
|
|
272
|
+
|
|
273
|
+
### Create a PDF from HTML/CSS
|
|
274
|
+
|
|
275
|
+
```python
|
|
276
|
+
from agent_docs.create import create_document
|
|
277
|
+
|
|
278
|
+
result = create_document(
|
|
279
|
+
format="pdf",
|
|
280
|
+
content={"html": "<html><body><h1>Hello</h1></body></html>"},
|
|
281
|
+
output_path="/tmp/output.pdf",
|
|
282
|
+
options={"page_size": "A4"}
|
|
283
|
+
)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Read a DOCX file
|
|
287
|
+
|
|
288
|
+
```python
|
|
289
|
+
from agent_docs.read import read
|
|
290
|
+
|
|
291
|
+
text = read("/path/to/document.docx")
|
|
292
|
+
# Returns GitHub-Flavored Markdown
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Convert Markdown to PDF
|
|
296
|
+
|
|
297
|
+
```python
|
|
298
|
+
from agent_docs.convert import doc_convert
|
|
299
|
+
|
|
300
|
+
result = doc_convert(
|
|
301
|
+
input_path="/path/to/input.md",
|
|
302
|
+
to_format="pdf",
|
|
303
|
+
output_path="/path/to/output.pdf"
|
|
304
|
+
)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Via MCP
|
|
308
|
+
|
|
309
|
+
The bundled MCP server exposes five tools: `doc_read`, `doc_read_meta`,
|
|
310
|
+
`doc_convert`, `doc_create_document`, `doc_edit_pdf`. Any MCP-compatible
|
|
311
|
+
client can call these directly.
|
|
312
|
+
|
|
313
|
+
## License
|
|
314
|
+
|
|
315
|
+
MIT
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# tabella
|
|
2
|
+
|
|
3
|
+
A portable document lifecycle suite: create, convert, and read documents
|
|
4
|
+
from structured JSON or raw HTML/CSS.
|
|
5
|
+
|
|
6
|
+
## Cross-Platform Compatibility
|
|
7
|
+
|
|
8
|
+
This package conforms to the [Agent Plugins v1.0.0](https://agent-plugins.org/specification)
|
|
9
|
+
specification. It works with any compatible AI agent client that supports
|
|
10
|
+
MCP servers, including:
|
|
11
|
+
|
|
12
|
+
- [Hermes Agent](https://hermes-agent.nousresearch.com)
|
|
13
|
+
- [Cursor](https://cursor.com)
|
|
14
|
+
- [Claude Desktop](https://claude.ai/download)
|
|
15
|
+
- Any client that supports the Model Context Protocol
|
|
16
|
+
|
|
17
|
+
### Three installation paths
|
|
18
|
+
|
|
19
|
+
**Transports:** the plugin ships both.
|
|
20
|
+
|
|
21
|
+
- **stdio (default)** — the declaring client spawns `mcp_server.py` itself
|
|
22
|
+
(Agent Plugins v1 lifecycle; `PLUGIN_ROOT`/`PLUGIN_DATA` injected by the
|
|
23
|
+
client). Nothing to run by hand.
|
|
24
|
+
- **streamable-HTTP (self-host lane)** — for clients that prefer connecting
|
|
25
|
+
to a URL, run the server yourself:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
python3 scripts/mcp_http_server.py # serves 127.0.0.1:8602
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
First run bootstraps the dependency venv (or `scripts/setup.sh`);
|
|
32
|
+
`TABELLA_TOKEN` enables bearer auth. Then point an `mcp.json`
|
|
33
|
+
`streamable-http` entry at `http://127.0.0.1:8602/mcp`.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
**Agent Plugins v1 package** — clients that support the v1 spec auto-discover
|
|
38
|
+
`plugin.json` + `mcp.json` from the repo root and launch the MCP server:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Hermes Agent
|
|
42
|
+
hermes plugins install dyiapanis/tabella --no-enable
|
|
43
|
+
hermes plugins enable tabella
|
|
44
|
+
|
|
45
|
+
# Other v1-compatible clients: follow your client's plugin installation instructions
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**MCP server (manual)** — point any MCP-compatible client at the server directly:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"mcpServers": {
|
|
53
|
+
"tabella": {
|
|
54
|
+
"type": "stdio",
|
|
55
|
+
"command": "python3",
|
|
56
|
+
"args": ["/path/to/tabella/mcp_server.py"]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**pip install** — use the Python library directly:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install tabella-docs[all]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Or install only the modules you need:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install tabella-docs[create] # python-docx, openpyxl, python-pptx, weasyprint, odfpy
|
|
72
|
+
pip install tabella-docs[read] # firecrawl-anydoc, liteparse, PyMuPDF
|
|
73
|
+
pip install tabella-docs[convert] # no python deps (needs system pandoc + texlive-xetex)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Modules
|
|
77
|
+
|
|
78
|
+
### Create
|
|
79
|
+
|
|
80
|
+
Generate documents from structured JSON content or raw HTML/CSS:
|
|
81
|
+
|
|
82
|
+
- **DOCX** — Word documents (python-docx)
|
|
83
|
+
- **XLSX** — Spreadsheets (openpyxl)
|
|
84
|
+
- **PPTX** — Presentations (python-pptx)
|
|
85
|
+
- **PDF** — Print-ready documents and visual designs (WeasyPrint)
|
|
86
|
+
- Document-style: structured JSON → HTML → PDF
|
|
87
|
+
- Visual-style: raw HTML/CSS (Grid, Flexbox, gradients, themes) → PDF
|
|
88
|
+
- **ODT/ODS/ODP** — OpenDocument formats (odfpy)
|
|
89
|
+
|
|
90
|
+
Accepts plain strings (auto-normalized), HTML, or structured dicts with
|
|
91
|
+
sections, sheets, slides, tables, images, and page breaks.
|
|
92
|
+
|
|
93
|
+
### Convert
|
|
94
|
+
|
|
95
|
+
Format conversion via pandoc + LaTeX (page size, margins, headers/footers
|
|
96
|
+
configurable). **Pandoc 3.1 supports 44 input and 54 output formats** —
|
|
97
|
+
`doc_convert` passes your `from`/`to` through, so all of them work. The
|
|
98
|
+
everyday set:
|
|
99
|
+
|
|
100
|
+
| Format | In | Out | Notes |
|
|
101
|
+
|---|---|---|---|
|
|
102
|
+
| Markdown (`.md`, variants) | ✅ | ✅ | gfm, commonmark, multimarkdown, strict… |
|
|
103
|
+
| HTML | ✅ | ✅ | html4/html5, chunkedhtml |
|
|
104
|
+
| DOCX (Word) | ✅ | ✅ | |
|
|
105
|
+
| ODT | ✅ | ✅ | + `opendocument` |
|
|
106
|
+
| PDF | ✅ | ✅ | in: text-based PDFs (pandoc's pdf reader); out: needs `pdflatex`/`xelatex` (texlive) — engine auto-selected |
|
|
107
|
+
| LaTeX (`.tex`) | ✅ | ✅ | incl. beamer slides out |
|
|
108
|
+
| RST | ✅ | ✅ | |
|
|
109
|
+
| EPUB | ✅ | ✅ | out: epub2/epub3 |
|
|
110
|
+
| CSV / TSV | ✅ | ✅ | out via markdown/AST route |
|
|
111
|
+
| RTF | ✅ | ✅ | |
|
|
112
|
+
| Plain text (`.txt`) | ✅ | ✅ | |
|
|
113
|
+
| Org-mode, MediaWiki, Jira wiki, Textile, DocBook, FB2, OPML, IPynb, JATS | ✅ | ✅ | writers for most |
|
|
114
|
+
| Typst / man / ms / texinfo / AsciiDoc | ✅ | ✅ | typst in+out |
|
|
115
|
+
| Presentations | — | ✅ | beamer, revealjs, slidy, s5, dzslides (from any reader, Markdown especially) |
|
|
116
|
+
| Pandoc AST (JSON) | ✅ | ✅ | for programmatic pipelines |
|
|
117
|
+
|
|
118
|
+
Everything not in the table: if `pandoc --list-input-formats` /
|
|
119
|
+
`--list-output-formats` lists it, `doc_convert` accepts it as-is — unknown
|
|
120
|
+
extensions pass through untouched.
|
|
121
|
+
|
|
122
|
+
### Read
|
|
123
|
+
|
|
124
|
+
Extract text and metadata from any document:
|
|
125
|
+
|
|
126
|
+
- **Office formats** (DOCX, DOC, XLSX, XLSB, PPTX, PPT, ODT, ODS, ODP, RTF,
|
|
127
|
+
EPUB, CSV) and **text-based PDFs** → GitHub-Flavored Markdown via
|
|
128
|
+
[anydoc](https://github.com/firecrawl/anydoc) (~4ms, in-process)
|
|
129
|
+
- **Scanned PDFs** and **images** (JPG, PNG, TIFF) → OCR via
|
|
130
|
+
[LiteParse](https://github.com/run-llama/liteparse) (Tesseract)
|
|
131
|
+
- **Plain text** (.txt, .md, .json, .py, .yaml, etc.) → direct file read
|
|
132
|
+
- Returns structured Markdown (office formats) or plain text (OCR, plain text)
|
|
133
|
+
|
|
134
|
+
## Prerequisites
|
|
135
|
+
|
|
136
|
+
### Create module
|
|
137
|
+
|
|
138
|
+
The create module uses a separate Python venv for heavy document libraries.
|
|
139
|
+
Set `DOCS_VENV_PYTHON` to point to it:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Create a dedicated venv
|
|
143
|
+
python -m venv ~/.venvs/docs
|
|
144
|
+
~/.venvs/docs/bin/pip install python-docx openpyxl python-pptx weasyprint odfpy Pillow lxml PyMuPDF firecrawl-anydoc liteparse
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Or install the libraries into your main Python environment:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pip install tabella-docs[create]
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Read module
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
~/.venvs/docs/bin/pip install firecrawl-anydoc liteparse PyMuPDF
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Or:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
pip install tabella-docs[read]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Convert module
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
pip install tabella-docs[convert]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Requires system-installed pandoc and a LaTeX engine:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Debian/Ubuntu
|
|
175
|
+
sudo apt install pandoc texlive-xetex
|
|
176
|
+
|
|
177
|
+
# macOS
|
|
178
|
+
brew install pandoc basictex
|
|
179
|
+
|
|
180
|
+
# Arch
|
|
181
|
+
sudo pacman -S pandoc texlive
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### WeasyPrint system dependencies (PDF creation)
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# Debian/Ubuntu
|
|
188
|
+
sudo apt install libcairo2 libpango-1.0-0 libgdk-pixbuf-2.0-0
|
|
189
|
+
|
|
190
|
+
# macOS
|
|
191
|
+
brew install cairo pango gdk-pixbuf
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Installation from source
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
git clone https://github.com/dyiapanis/tabella.git
|
|
198
|
+
cd tabella
|
|
199
|
+
pip install -e ".[all]"
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Configuration
|
|
203
|
+
|
|
204
|
+
| Variable | Purpose | Default |
|
|
205
|
+
|----------|---------|---------|
|
|
206
|
+
| `DOCS_VENV_PYTHON` | Python binary for document libraries | `PLUGIN_DATA/venv/bin/python` or `~/.venvs/docs/bin/python` |
|
|
207
|
+
| `DOCS_OUTPUT_DIR` | Default output directory for generated documents | `~/Documents` |
|
|
208
|
+
| `PLUGIN_DATA` | Client-managed data directory (set by v1 client) | — |
|
|
209
|
+
| `PLUGIN_ROOT` | Plugin root directory (set by v1 client) | — |
|
|
210
|
+
|
|
211
|
+
### Automatic bootstrap
|
|
212
|
+
|
|
213
|
+
On first startup, the MCP server checks if the docs venv exists. If not,
|
|
214
|
+
it runs `scripts/setup.sh` to create a venv in `PLUGIN_DATA` (provided by
|
|
215
|
+
the v1 client) or `~/.venvs/docs` as fallback, and installs all dependencies:
|
|
216
|
+
python-docx, openpyxl, python-pptx, weasyprint, odfpy, PyMuPDF,
|
|
217
|
+
firecrawl-anydoc, liteparse.
|
|
218
|
+
|
|
219
|
+
This means the v1 package is fully self-contained — no manual pip install
|
|
220
|
+
required. The bootstrap runs once; subsequent startups use the existing venv.
|
|
221
|
+
|
|
222
|
+
## Usage
|
|
223
|
+
|
|
224
|
+
### Create a PDF from HTML/CSS
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
from agent_docs.create import create_document
|
|
228
|
+
|
|
229
|
+
result = create_document(
|
|
230
|
+
format="pdf",
|
|
231
|
+
content={"html": "<html><body><h1>Hello</h1></body></html>"},
|
|
232
|
+
output_path="/tmp/output.pdf",
|
|
233
|
+
options={"page_size": "A4"}
|
|
234
|
+
)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Read a DOCX file
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
from agent_docs.read import read
|
|
241
|
+
|
|
242
|
+
text = read("/path/to/document.docx")
|
|
243
|
+
# Returns GitHub-Flavored Markdown
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Convert Markdown to PDF
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
from agent_docs.convert import doc_convert
|
|
250
|
+
|
|
251
|
+
result = doc_convert(
|
|
252
|
+
input_path="/path/to/input.md",
|
|
253
|
+
to_format="pdf",
|
|
254
|
+
output_path="/path/to/output.pdf"
|
|
255
|
+
)
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Via MCP
|
|
259
|
+
|
|
260
|
+
The bundled MCP server exposes five tools: `doc_read`, `doc_read_meta`,
|
|
261
|
+
`doc_convert`, `doc_create_document`, `doc_edit_pdf`. Any MCP-compatible
|
|
262
|
+
client can call these directly.
|
|
263
|
+
|
|
264
|
+
## License
|
|
265
|
+
|
|
266
|
+
MIT
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tabella-docs"
|
|
7
|
+
version = "2.0.1"
|
|
8
|
+
description = "Portable document lifecycle suite — create (.docx/.xlsx/.pptx/.pdf/.odt/.ods/.odp), convert (pandoc), and read (anydoc + LiteParse OCR) documents. Agent Plugins v1 compatible."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "D Yiapanis", email = "d@yiapanis.co" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["documents", "docx", "xlsx", "pptx", "pdf", "odt", "pandoc", "anydoc", "document-generation", "markdown", "ocr", "agent-plugins", "mcp"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Programming Language :: Python :: 3.13",
|
|
23
|
+
"Topic :: Office/Business :: Office Suites",
|
|
24
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
dependencies = []
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
create = [
|
|
31
|
+
"python-docx>=1.0,<2.0",
|
|
32
|
+
"openpyxl>=3.1,<4.0",
|
|
33
|
+
"python-pptx>=0.6,<2.0",
|
|
34
|
+
"weasyprint>=60.0,<70.0",
|
|
35
|
+
"odfpy>=1.4,<2.0",
|
|
36
|
+
"Pillow>=10.0,<13.0",
|
|
37
|
+
"lxml>=5.0,<7.0",
|
|
38
|
+
]
|
|
39
|
+
read = [
|
|
40
|
+
"firecrawl-anydoc>=0.1.1,<0.3.0",
|
|
41
|
+
"liteparse>=2.0.0,<3.0.0",
|
|
42
|
+
"PyMuPDF>=1.24,<2.0",
|
|
43
|
+
]
|
|
44
|
+
convert = [] # requires system pandoc + LaTeX (texlive-xetex); no python wrapper needed
|
|
45
|
+
all = [
|
|
46
|
+
"python-docx>=1.0,<2.0",
|
|
47
|
+
"openpyxl>=3.1,<4.0",
|
|
48
|
+
"python-pptx>=0.6,<2.0",
|
|
49
|
+
"weasyprint>=60.0,<70.0",
|
|
50
|
+
"odfpy>=1.4,<2.0",
|
|
51
|
+
"Pillow>=10.0,<13.0",
|
|
52
|
+
"lxml>=5.0,<7.0",
|
|
53
|
+
"firecrawl-anydoc>=0.1.1,<0.3.0",
|
|
54
|
+
"liteparse>=2.0.0,<3.0.0",
|
|
55
|
+
"PyMuPDF>=1.24,<2.0",
|
|
56
|
+
]
|
|
57
|
+
dev = [
|
|
58
|
+
"pytest>=7.0",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[project.urls]
|
|
62
|
+
"Homepage" = "https://github.com/dyiapanis/tabella"
|
|
63
|
+
"Source" = "https://github.com/dyiapanis/tabella"
|
|
64
|
+
"Issues" = "https://github.com/dyiapanis/tabella/issues"
|
|
65
|
+
|
|
66
|
+
[tool.setuptools.packages.find]
|
|
67
|
+
include = ["tabella*"]
|