open-document-lib 1.0.0__tar.gz → 1.0.2__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.
- {open_document_lib-1.0.0/open_document_lib.egg-info → open_document_lib-1.0.2}/PKG-INFO +2 -1
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/README.md +11 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/odf_lib/odf_common.py +1 -1
- {open_document_lib-1.0.0 → open_document_lib-1.0.2/open_document_lib.egg-info}/PKG-INFO +2 -1
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/open_document_lib.egg-info/requires.txt +1 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/pyproject.toml +7 -2
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_install.py +69 -1
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/LICENSE +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/docs/library-api.md +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/odf_lib/__init__.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/odf_lib/citation_mapping.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/odf_lib/py.typed +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/open_document_lib.egg-info/SOURCES.txt +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/open_document_lib.egg-info/dependency_links.txt +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/open_document_lib.egg-info/top_level.txt +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/setup.cfg +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_benchmarks.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_citations.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_corpus.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_cross_refs.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_dao_template.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_docs.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_edge_cases.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_examples.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_flat_odf.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_footnotes.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_lib_odf_common.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_libreoffice_integration.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_math.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_meta_lifecycle.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_odg_connectors.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_odg_gluepoints.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_odg_groups.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_odp_animations.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_odp_master.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_odp_transitions.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_ods_charts.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_ods_named_ranges.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_ods_validation.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_property.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_schema_validation.py +0 -0
- {open_document_lib-1.0.0 → open_document_lib-1.0.2}/tests/test_smoke.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: open-document-lib
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.2
|
|
4
4
|
Summary: Standard-library toolkit for reading, editing, and writing OpenDocument Format files (ODT, ODP, ODS, ODG)
|
|
5
5
|
Author: Patrick Leiverkus
|
|
6
6
|
License: MIT
|
|
@@ -36,6 +36,7 @@ Requires-Dist: ruff>=0.9; extra == "dev"
|
|
|
36
36
|
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
37
37
|
Requires-Dist: hypothesis>=6.0; extra == "dev"
|
|
38
38
|
Requires-Dist: build>=1.0; extra == "dev"
|
|
39
|
+
Requires-Dist: mypy>=1.8; extra == "dev"
|
|
39
40
|
Dynamic: license-file
|
|
40
41
|
|
|
41
42
|
# open-document-lib
|
|
@@ -89,6 +89,17 @@ The skills are available through three channels — pick what fits your setup:
|
|
|
89
89
|
|
|
90
90
|
Browse and install via [smithery.ai](https://smithery.ai). Install one or more skills directly through the Smithery UI: [odt](https://smithery.ai/skills/leiverkus/odt), [odp](https://smithery.ai/skills/leiverkus/odp), [ods](https://smithery.ai/skills/leiverkus/ods), [odg](https://smithery.ai/skills/leiverkus/odg).
|
|
91
91
|
|
|
92
|
+
### Claude Code plugin marketplace
|
|
93
|
+
|
|
94
|
+
The repository is also a Claude Code plugin marketplace. Add it once, then install the plugin — all four skills come bundled:
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
/plugin marketplace add leiverkus/open-document-skills
|
|
98
|
+
/plugin install open-document-skills@leiverkus-skills
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`/plugin marketplace update` pulls later releases.
|
|
102
|
+
|
|
92
103
|
### Open Agent Skills CLI
|
|
93
104
|
|
|
94
105
|
The [vercel-labs/skills](https://github.com/vercel-labs/skills) CLI installs across Claude Code, Codex, Cursor, OpenCode, and 50+ other agents:
|
|
@@ -19,7 +19,7 @@ from datetime import datetime, timezone
|
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
from xml.etree import ElementTree as ET
|
|
21
21
|
|
|
22
|
-
VERSION = "1.0.
|
|
22
|
+
VERSION = "1.0.2" # keep in sync with pyproject.toml (see CONTRIBUTING.md)
|
|
23
23
|
|
|
24
24
|
ODF_NAMESPACES: dict[str, str] = {
|
|
25
25
|
"office": "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: open-document-lib
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.2
|
|
4
4
|
Summary: Standard-library toolkit for reading, editing, and writing OpenDocument Format files (ODT, ODP, ODS, ODG)
|
|
5
5
|
Author: Patrick Leiverkus
|
|
6
6
|
License: MIT
|
|
@@ -36,6 +36,7 @@ Requires-Dist: ruff>=0.9; extra == "dev"
|
|
|
36
36
|
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
37
37
|
Requires-Dist: hypothesis>=6.0; extra == "dev"
|
|
38
38
|
Requires-Dist: build>=1.0; extra == "dev"
|
|
39
|
+
Requires-Dist: mypy>=1.8; extra == "dev"
|
|
39
40
|
Dynamic: license-file
|
|
40
41
|
|
|
41
42
|
# open-document-lib
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "open-document-lib"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.2"
|
|
8
8
|
description = "Standard-library toolkit for reading, editing, and writing OpenDocument Format files (ODT, ODP, ODS, ODG)"
|
|
9
9
|
readme = "docs/library-api.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -47,7 +47,7 @@ Issues = "https://github.com/leiverkus/open-document-skills/issues"
|
|
|
47
47
|
odf = ["odfpy>=1.4.0"]
|
|
48
48
|
scholarly = ["bibtexparser>=1.4"]
|
|
49
49
|
validate = ["lxml>=4.9"]
|
|
50
|
-
dev = ["pytest>=8.0", "ruff>=0.9", "pytest-cov>=5.0", "hypothesis>=6.0", "build>=1.0"]
|
|
50
|
+
dev = ["pytest>=8.0", "ruff>=0.9", "pytest-cov>=5.0", "hypothesis>=6.0", "build>=1.0", "mypy>=1.8"]
|
|
51
51
|
|
|
52
52
|
[tool.setuptools]
|
|
53
53
|
packages = ["odf_lib"]
|
|
@@ -65,6 +65,11 @@ source = ["odf_lib"]
|
|
|
65
65
|
fail_under = 30
|
|
66
66
|
show_missing = true
|
|
67
67
|
|
|
68
|
+
[tool.mypy]
|
|
69
|
+
python_version = "3.10"
|
|
70
|
+
# Optional deps (lxml, bibtexparser) are lazily imported; don't fail on them.
|
|
71
|
+
ignore_missing_imports = true
|
|
72
|
+
|
|
68
73
|
[tool.ruff]
|
|
69
74
|
line-length = 120
|
|
70
75
|
target-version = "py310"
|
|
@@ -8,7 +8,9 @@ import tempfile
|
|
|
8
8
|
import unittest
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
|
|
11
|
-
from helpers import ROOT
|
|
11
|
+
from helpers import ROOT, run_script
|
|
12
|
+
|
|
13
|
+
MINIMAL_ODT_SPEC = {"title": "Install Test", "blocks": [{"type": "paragraph", "text": "Hi"}]}
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
class InstallTests(unittest.TestCase):
|
|
@@ -89,6 +91,72 @@ class InstallTests(unittest.TestCase):
|
|
|
89
91
|
self.assertTrue((dest / "skills" / "odt" / "SKILL.md").exists())
|
|
90
92
|
self.assertTrue((dest / "skills" / "odg" / "scripts").is_dir())
|
|
91
93
|
|
|
94
|
+
def test_installed_skill_bundles_odf_lib_and_runs(self) -> None:
|
|
95
|
+
"""A standalone-installed skill must carry odf_lib/ and run its scripts.
|
|
96
|
+
|
|
97
|
+
Regression: installs previously omitted the shared odf_lib/ package,
|
|
98
|
+
so every script crashed with ModuleNotFoundError outside the repo
|
|
99
|
+
checkout (surfaced when the plugin was installed in Claude Cowork).
|
|
100
|
+
"""
|
|
101
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
102
|
+
tmp_path = Path(tmp)
|
|
103
|
+
dest = tmp_path / "skills"
|
|
104
|
+
subprocess.run(
|
|
105
|
+
[
|
|
106
|
+
sys.executable,
|
|
107
|
+
str(ROOT / "scripts" / "install_skills.py"),
|
|
108
|
+
"--dest",
|
|
109
|
+
str(dest),
|
|
110
|
+
"--skills",
|
|
111
|
+
"odt",
|
|
112
|
+
],
|
|
113
|
+
cwd=ROOT,
|
|
114
|
+
check=True,
|
|
115
|
+
stdout=subprocess.PIPE,
|
|
116
|
+
stderr=subprocess.STDOUT,
|
|
117
|
+
text=True,
|
|
118
|
+
)
|
|
119
|
+
# odf_lib/ must be bundled into the installed skill.
|
|
120
|
+
self.assertTrue((dest / "odt" / "odf_lib" / "odf_common.py").is_file())
|
|
121
|
+
# The install must be free of build junk.
|
|
122
|
+
self.assertEqual(list(dest.rglob("__pycache__")), [])
|
|
123
|
+
self.assertEqual(list(dest.rglob("*.pyc")), [])
|
|
124
|
+
# A bundled script must run standalone — repo odf_lib/ is unreachable here.
|
|
125
|
+
spec = tmp_path / "spec.json"
|
|
126
|
+
spec.write_text(json.dumps(MINIMAL_ODT_SPEC), encoding="utf-8")
|
|
127
|
+
out = tmp_path / "out.odt"
|
|
128
|
+
run_script(dest / "odt" / "scripts" / "create_minimal_odt.py", spec, out)
|
|
129
|
+
result = run_script(dest / "odt" / "scripts" / "validate_refs.py", out)
|
|
130
|
+
self.assertEqual(json.loads(result.stdout)["status"], "ok")
|
|
131
|
+
|
|
132
|
+
def test_claude_plugin_bundle_runs_standalone(self) -> None:
|
|
133
|
+
"""The Claude plugin bundle must carry odf_lib/ and run its scripts."""
|
|
134
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
135
|
+
tmp_path = Path(tmp)
|
|
136
|
+
dest = tmp_path / "plugin"
|
|
137
|
+
subprocess.run(
|
|
138
|
+
[
|
|
139
|
+
sys.executable,
|
|
140
|
+
str(ROOT / "scripts" / "install_skills.py"),
|
|
141
|
+
"--target",
|
|
142
|
+
"claude",
|
|
143
|
+
"--dest",
|
|
144
|
+
str(dest),
|
|
145
|
+
],
|
|
146
|
+
cwd=ROOT,
|
|
147
|
+
check=True,
|
|
148
|
+
stdout=subprocess.PIPE,
|
|
149
|
+
stderr=subprocess.STDOUT,
|
|
150
|
+
text=True,
|
|
151
|
+
)
|
|
152
|
+
self.assertTrue((dest / "odf_lib" / "odf_common.py").is_file())
|
|
153
|
+
spec = tmp_path / "spec.json"
|
|
154
|
+
spec.write_text(json.dumps(MINIMAL_ODT_SPEC), encoding="utf-8")
|
|
155
|
+
out = tmp_path / "out.odt"
|
|
156
|
+
run_script(dest / "skills" / "odt" / "scripts" / "create_minimal_odt.py", spec, out)
|
|
157
|
+
result = run_script(dest / "skills" / "odt" / "scripts" / "validate_refs.py", out)
|
|
158
|
+
self.assertEqual(json.loads(result.stdout)["status"], "ok")
|
|
159
|
+
|
|
92
160
|
def test_claude_target_requires_destination(self) -> None:
|
|
93
161
|
result = subprocess.run(
|
|
94
162
|
[sys.executable, str(ROOT / "scripts" / "install_skills.py"), "--target", "claude"],
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{open_document_lib-1.0.0 → open_document_lib-1.0.2}/open_document_lib.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{open_document_lib-1.0.0 → open_document_lib-1.0.2}/open_document_lib.egg-info/top_level.txt
RENAMED
|
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
|