mirror of
https://github.com/mudler/LocalAI.git
synced 2026-11-03 19:14:56 -05:00
feat(sandbox): own document authoring skills (#13038)
* feat(skills): reserve document provider slots Separate document provider slots from protected core skill names. Keep existing same-name shadows declarations compatible. Normalize legacy document OFF markers in JSON and database stores. Persist normalization under the existing lock or transaction so an explicit re-enable cannot be overwritten by a stale read. Cover persistence, rollback, ownership and concurrent replacement. Refresh the contracts inventory from the passing Ginkgo report. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: nib:gpt-6.1-sol * feat(skills): gate Sandbox document procedures Resolve document providers against the selected isolated command backend. Keep Office guidance available without command execution and preserve explicit provider pins when their backend is unavailable. Reuse authorized chat access during tool construction to avoid reentering the session lock. Recheck access and capabilities when loading guidance. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: nib:gpt-6.1-sol * fix(skills): resolve saved-agent child command grants Describe saved-agent child commands from their current agent scope rather than the inherited tool map reserved for ad-hoc children. Cover index, picker and loader behavior for permitted, absent and revoked Sandbox grants without changing saved skill selections. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: nib:gpt-6.1-sol * feat(sandbox): install and exercise guest-owned PDF helpers Preserve PDF helper sources and MIT attribution in the guest image. Exercise valid, empty-text and defective PDFs during the image build and through the packaged isolated command route. Register the packaging regression in the exact suite inventory. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: nib:gpt-5 * feat(sandbox): own document skills and consolidated references Move the four document authoring trees out of core and package their text-only procedures with Sandbox. Preserve source coverage with offline fingerprints, guest PDF helper paths, and package-local license notices. Exercise actual skill receipt materialization across install, upgrade and uninstall; keep stale built-in cleanup and report-derived suite inventories current. Assisted-by: nib:gpt-6.1-sol Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(ui): explain document skill providers and unavailable selections Show provider-owned document procedures without removed built-in fallbacks, retain remaining built-in replacement notices, and translate install guidance in every locale. Cover picker labels, saved names and real API OFF normalization, and document grants, isolated execution and unchanged extraction. Acknowledge the intentionally injected GORM callback error in preference regression tests for lint. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: nib:gpt-6.1-sol * docs(agents): fix document guidance formatting Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: nib:gpt-6.1-sol * fix(ui): correct rebased skill label import Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: nib:gpt-6.1-sol --------- Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
1 parent
5b2414f6bc
commit
74e293ef38
497 files changed
+98765
-80238
No files matched your search
@@ -101,6 +101,10 @@ RUN set -eux; \
|
||||
python3 /tmp/guest-python/check-python.py; \
|
||||
sh /tmp/guest-python/check-tools.sh; \
|
||||
rm -rf /tmp/guest-python
|
||||
# Helpers belong to the guest, not the documentation-only skill package.
|
||||
COPY addons/sandbox/images/guest/document-skills/ /usr/local/lib/localai/document-skills/
|
||||
COPY addons/sandbox/images/guest/check-document-skills.py /usr/local/lib/localai/document-skills/check-document-skills.py
|
||||
RUN python3 /usr/local/lib/localai/document-skills/check-document-skills.py
|
||||
# The guest has no network device. Every tool must use the proxy on the
|
||||
# loopback interface; the sandbox serves it with a host port handler.
|
||||
ENV HTTP_PROXY=http://127.0.0.1:3128 HTTPS_PROXY=http://127.0.0.1:3128 NO_PROXY=localhost,127.0.0.1 \
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""Exercise the installed PDF helper CLIs using only guest dependencies."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from reportlab.pdfgen import canvas
|
||||
|
||||
|
||||
HELPERS = Path("/usr/local/lib/localai/document-skills/pdf")
|
||||
SUCCESS = "document-skills fixtures: ok"
|
||||
|
||||
|
||||
def require(condition, message):
|
||||
if not condition:
|
||||
raise RuntimeError(message)
|
||||
|
||||
|
||||
def run_helper(name, pdf, exit_code):
|
||||
result = subprocess.run(
|
||||
[sys.executable, str(HELPERS / name), str(pdf), "--json"],
|
||||
capture_output=True, text=True, timeout=30, check=False,
|
||||
)
|
||||
require(result.returncode == exit_code,
|
||||
f"{name} {pdf.name}: exit {result.returncode}, expected {exit_code}: {result.stderr}")
|
||||
data = json.loads(result.stdout)
|
||||
require(data["ok"] is (exit_code == 0), f"{name}: incorrect ok field")
|
||||
require(data["page_count"] == 1 and len(data["pages"]) == 1,
|
||||
f"{name}: incorrect page count")
|
||||
require(data["error_count"] == sum(p["severity"] == "error" for p in data["problems"]),
|
||||
f"{name}: incorrect error count")
|
||||
require(data["warning_count"] == sum(p["severity"] == "warning" for p in data["problems"]),
|
||||
f"{name}: incorrect warning count")
|
||||
return data
|
||||
|
||||
|
||||
def main():
|
||||
for name in ("content_qa.py", "verify_pdf.py", "notice.txt"):
|
||||
require((HELPERS / name).is_file(), f"missing guest helper asset: {name}")
|
||||
notice = (HELPERS / "notice.txt").read_text()
|
||||
for attribution in ("MIT License", "Copyright (c) 2026 Paper Instruments, Inc.",
|
||||
"Permission is hereby granted", "THE SOFTWARE IS PROVIDED"):
|
||||
require(attribution in notice, f"missing helper license attribution: {attribution}")
|
||||
|
||||
with tempfile.TemporaryDirectory(prefix="document-skills-") as directory:
|
||||
root = Path(directory)
|
||||
for name, x in (("valid", 72), ("empty", None), ("defective", -144)):
|
||||
pdf = root / f"{name}.pdf"
|
||||
document = canvas.Canvas(str(pdf), pagesize=(612, 792), invariant=1)
|
||||
if x is not None:
|
||||
document.drawString(x, 720, "Sandbox PDF fixture")
|
||||
document.showPage()
|
||||
document.save()
|
||||
|
||||
for name in ("content_qa.py", "verify_pdf.py"):
|
||||
valid = run_helper(name, root / "valid.pdf", 0)
|
||||
require(valid["error_count"] == 0 and valid["warning_count"] == 0,
|
||||
f"{name}: valid document reported problems")
|
||||
empty = run_helper(name, root / "empty.pdf", 0)
|
||||
expected = "empty_page_text" if name == "content_qa.py" else "pdf-no-extractable-text"
|
||||
require(empty["error_count"] == 0 and empty["warning_count"] == 1,
|
||||
f"{name}: empty-text document must warn, not fail")
|
||||
require(empty["problems"][0]["kind"] == expected, f"{name}: missing empty-text warning")
|
||||
require(empty["problems"][0]["page"] == 1, f"{name}: incorrect warning page")
|
||||
if name == "content_qa.py":
|
||||
require(valid["pages"][0]["text"].strip() == "Sandbox PDF fixture",
|
||||
"content_qa.py: fixture text not extracted")
|
||||
require(empty["pages"][0]["text"] == "", "empty fixture contains text")
|
||||
else:
|
||||
require(valid["pages"][0]["text_line_count"] > 0,
|
||||
"verify_pdf.py: fixture text geometry not extracted")
|
||||
|
||||
# The PDF is openable and contains text, but that text is outside its
|
||||
# page box. Content QA should accept it; geometry verification must not.
|
||||
content = run_helper("content_qa.py", root / "defective.pdf", 0)
|
||||
require(content["error_count"] == 0 and content["warning_count"] == 0,
|
||||
"content_qa.py: changed content-only behavior")
|
||||
defective = run_helper("verify_pdf.py", root / "defective.pdf", 1)
|
||||
require(defective["error_count"] > 0, "verify_pdf.py: missed defective geometry")
|
||||
require(any(p["kind"] == "layout-boundary-violation" and p["severity"] == "error"
|
||||
and p["page"] == 1 for p in defective["problems"]),
|
||||
"verify_pdf.py: missing boundary violation")
|
||||
print(SUCCESS)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
File renamed without changes.
@@ -0,0 +1,30 @@
|
||||
PDF helpers from Feather
|
||||
========================
|
||||
|
||||
Source: https://github.com/paper-instruments/feather-train
|
||||
Commit: b7463092af862ebbdf4c5920c4bc9ab38ab17ad9
|
||||
Folder: feather-harness/src/feather_harness/skills/pdf/scripts
|
||||
|
||||
The helper sources are copied without changes.
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
File renamed without changes.
@@ -118,7 +118,25 @@
|
||||
}
|
||||
],
|
||||
"title": "Sandbox"
|
||||
}
|
||||
},
|
||||
"skillDefinitions": [
|
||||
{
|
||||
"name": "docx",
|
||||
"shadows": "docx"
|
||||
},
|
||||
{
|
||||
"name": "pptx",
|
||||
"shadows": "pptx"
|
||||
},
|
||||
{
|
||||
"name": "pdf",
|
||||
"shadows": "pdf"
|
||||
},
|
||||
{
|
||||
"name": "xlsx",
|
||||
"shadows": "xlsx"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dataFormat": {
|
||||
"max": 1,
|
||||
|
||||
@@ -26,6 +26,7 @@ executable: sandbox
|
||||
manifest: addons/sandbox/manifest.json
|
||||
# The directory whose content is laid at the package root (ui/sandbox.js ...).
|
||||
ui: addons/sandbox/ui/dist
|
||||
skills: addons/sandbox/skills
|
||||
platforms:
|
||||
- platform: linux/amd64
|
||||
enabled: true
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ Use your existing knowledge of `python-docx` for normal paragraphs, runs, styles
|
||||
|
||||
`paper-docx` is installed under the `docx` import.
|
||||
|
||||
The [Paper API companion](references/paper-api.md) maps Paper-specific capabilities to their public symbols. The [generated API reference](references/api/index.md) covers the complete public API, including the surface inherited from `python-docx`, with one page per module. It is large; search by symbol and read only the relevant section.
|
||||
The [Paper API companion](references/paper-api.md#source-c4b328c0772ccf3b) maps Paper-specific capabilities to their public symbols. The [generated API reference](references/api-002.md#source-56f84baa75bfbe31) covers the complete public API, including the surface inherited from `python-docx`, with one page per module. It is large; search by symbol and read only the relevant section.
|
||||
|
||||
## Package behavior
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
Sandbox document skills
|
||||
=============================
|
||||
|
||||
The skills "docx", "xlsx", "pptx" and "pdf" are adapted from the skills of the
|
||||
Feather project.
|
||||
|
||||
Source: https://github.com/paper-instruments/feather-train
|
||||
(folder feather-harness/src/feather_harness/skills)
|
||||
Commit: b7463092af862ebbdf4c5920c4bc9ab38ab17ad9
|
||||
Licence: MIT, Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
What was changed: the text about LibreOffice was replaced by a note that
|
||||
LibreOffice is not installed, the text about OCR was shortened in the same way,
|
||||
and the generated page of the LibreOffice-backed module "openpyxl.oracle" got
|
||||
the same note. Each of the four got one line that says to write
|
||||
helper scripts in the chat's work folder. The remaining built-in skills are not part of this package.
|
||||
|
||||
The MIT licence of the Feather project
|
||||
--------------------------------------
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
The generated API pages
|
||||
-----------------------
|
||||
|
||||
The pages under docx/references/api, xlsx/references/api and
|
||||
pptx/references/api are generated from the docstrings of the Paper libraries
|
||||
and of the libraries that they extend. The licences of those projects apply to
|
||||
that text. All three are MIT licences.
|
||||
|
||||
paper-docx extends python-docx, and paper-pptx extends python-pptx. Steve Canny
|
||||
wrote both upstream libraries, so the two licence files of the Paper packages
|
||||
have the same text. Each applies to its own package.
|
||||
|
||||
paper-docx https://pypi.org/project/paper-docx/ (python-docx)
|
||||
paper-pptx https://pypi.org/project/paper-pptx/ (python-pptx)
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2013 Steve Canny, https://github.com/scanny
|
||||
Portions Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
paper-xlsx extends openpyxl.
|
||||
|
||||
paper-xlsx https://pypi.org/project/paper-xlsx/ (openpyxl)
|
||||
|
||||
This software is under the MIT Licence
|
||||
======================================
|
||||
|
||||
Copyright (c) 2010 openpyxl
|
||||
Portions Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+2
@@ -1,3 +1,5 @@
|
||||
<a id="source-c4b328c0772ccf3b"></a>
|
||||
<!-- source: docx/references/paper-api.md -->
|
||||
# Paper DOCX API Companion
|
||||
|
||||
This companion covers capabilities beyond familiar `python-docx`. The installed distribution is `paper-docx`, but the import remains `docx`; ordinary `Document`, paragraph, run, style, table, section, picture, header, and footer APIs remain available.
|
||||
+3
-3
@@ -29,11 +29,11 @@ content; overlays and annotations do not.
|
||||
|
||||
## References and helpers
|
||||
|
||||
- [Deterministic PDF quality](references/deterministic-pdf-quality.md) describes the mechanical
|
||||
- [Deterministic PDF quality](references/deterministic-pdf-quality.md#source-1924639cbd4f358c) describes the mechanical
|
||||
verifier and the limits of extracted-geometry heuristics.
|
||||
- [Content QA](references/content-qa.md) describes final-PDF text extraction.
|
||||
- [Content QA](references/content-qa.md#source-7cbccb7ea6593740) describes final-PDF text extraction.
|
||||
|
||||
The `scripts/` directory contains mechanical checks for openability, page boxes, text layers,
|
||||
The guest directory `/usr/local/lib/localai/document-skills/pdf/` contains mechanical checks for openability, page boxes, text layers,
|
||||
extracted content, and selected geometry. The verifier's `--strict-layout` mode is designed for known
|
||||
generated layouts with predictable geometry, not arbitrary PDFs, scans, assembled pages, forms,
|
||||
redactions, logos, watermarks, or background artwork.
|
||||
@@ -0,0 +1,107 @@
|
||||
Sandbox document skills
|
||||
=============================
|
||||
|
||||
The skills "docx", "xlsx", "pptx" and "pdf" are adapted from the skills of the
|
||||
Feather project.
|
||||
|
||||
Source: https://github.com/paper-instruments/feather-train
|
||||
(folder feather-harness/src/feather_harness/skills)
|
||||
Commit: b7463092af862ebbdf4c5920c4bc9ab38ab17ad9
|
||||
Licence: MIT, Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
What was changed: the text about LibreOffice was replaced by a note that
|
||||
LibreOffice is not installed, the text about OCR was shortened in the same way,
|
||||
and the generated page of the LibreOffice-backed module "openpyxl.oracle" got
|
||||
the same note. Each of the four got one line that says to write
|
||||
helper scripts in the chat's work folder. The remaining built-in skills are not part of this package.
|
||||
|
||||
The MIT licence of the Feather project
|
||||
--------------------------------------
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
The generated API pages
|
||||
-----------------------
|
||||
|
||||
The pages under docx/references/api, xlsx/references/api and
|
||||
pptx/references/api are generated from the docstrings of the Paper libraries
|
||||
and of the libraries that they extend. The licences of those projects apply to
|
||||
that text. All three are MIT licences.
|
||||
|
||||
paper-docx extends python-docx, and paper-pptx extends python-pptx. Steve Canny
|
||||
wrote both upstream libraries, so the two licence files of the Paper packages
|
||||
have the same text. Each applies to its own package.
|
||||
|
||||
paper-docx https://pypi.org/project/paper-docx/ (python-docx)
|
||||
paper-pptx https://pypi.org/project/paper-pptx/ (python-pptx)
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2013 Steve Canny, https://github.com/scanny
|
||||
Portions Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
paper-xlsx extends openpyxl.
|
||||
|
||||
paper-xlsx https://pypi.org/project/paper-xlsx/ (openpyxl)
|
||||
|
||||
This software is under the MIT Licence
|
||||
======================================
|
||||
|
||||
Copyright (c) 2010 openpyxl
|
||||
Portions Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+3
-1
@@ -1,3 +1,5 @@
|
||||
<a id="source-7cbccb7ea6593740"></a>
|
||||
<!-- source: pdf/references/content-qa.md -->
|
||||
# Content QA
|
||||
|
||||
Content QA extracts text from a PDF and reports:
|
||||
@@ -7,7 +9,7 @@ Content QA extracts text from a PDF and reports:
|
||||
Command:
|
||||
|
||||
```bash
|
||||
python scripts/content_qa.py artifact.pdf --json
|
||||
python3 /usr/local/lib/localai/document-skills/pdf/content_qa.py artifact.pdf --json
|
||||
```
|
||||
|
||||
The script does not determine semantic completeness, correctness, or whether omissions are
|
||||
+3
-1
@@ -1,3 +1,5 @@
|
||||
<a id="source-1924639cbd4f358c"></a>
|
||||
<!-- source: pdf/references/deterministic-pdf-quality.md -->
|
||||
# Deterministic PDF Quality
|
||||
|
||||
The final PDF verifier is a mechanical guard for the rendered PDF package. It intentionally avoids
|
||||
@@ -14,7 +16,7 @@ Default `verify_pdf.py` checks:
|
||||
Command:
|
||||
|
||||
```bash
|
||||
python scripts/verify_pdf.py artifact.pdf --json
|
||||
python3 /usr/local/lib/localai/document-skills/pdf/verify_pdf.py artifact.pdf --json
|
||||
```
|
||||
|
||||
The default verifier checks mechanical PDF properties; it does not judge semantic completeness or
|
||||
+1
-1
@@ -22,7 +22,7 @@ Use your existing knowledge of `python-pptx` for normal slides, shapes, text, ta
|
||||
|
||||
`paper-pptx` is installed under the `pptx` import.
|
||||
|
||||
The [Paper API companion](references/paper-api.md) maps Paper-specific capabilities to their public symbols. The [generated API reference](references/api/index.md) covers the complete public API, including the surface inherited from `python-pptx`, with one page per module. It is large; search by symbol and read only the relevant section.
|
||||
The [Paper API companion](references/paper-api.md#source-bd380984355417c8) maps Paper-specific capabilities to their public symbols. The [generated API reference](references/api-002.md#source-21810f9156652e60) covers the complete public API, including the surface inherited from `python-pptx`, with one page per module. It is large; search by symbol and read only the relevant section.
|
||||
|
||||
## Package behavior
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
Sandbox document skills
|
||||
=============================
|
||||
|
||||
The skills "docx", "xlsx", "pptx" and "pdf" are adapted from the skills of the
|
||||
Feather project.
|
||||
|
||||
Source: https://github.com/paper-instruments/feather-train
|
||||
(folder feather-harness/src/feather_harness/skills)
|
||||
Commit: b7463092af862ebbdf4c5920c4bc9ab38ab17ad9
|
||||
Licence: MIT, Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
What was changed: the text about LibreOffice was replaced by a note that
|
||||
LibreOffice is not installed, the text about OCR was shortened in the same way,
|
||||
and the generated page of the LibreOffice-backed module "openpyxl.oracle" got
|
||||
the same note. Each of the four got one line that says to write
|
||||
helper scripts in the chat's work folder. The remaining built-in skills are not part of this package.
|
||||
|
||||
The MIT licence of the Feather project
|
||||
--------------------------------------
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
The generated API pages
|
||||
-----------------------
|
||||
|
||||
The pages under docx/references/api, xlsx/references/api and
|
||||
pptx/references/api are generated from the docstrings of the Paper libraries
|
||||
and of the libraries that they extend. The licences of those projects apply to
|
||||
that text. All three are MIT licences.
|
||||
|
||||
paper-docx extends python-docx, and paper-pptx extends python-pptx. Steve Canny
|
||||
wrote both upstream libraries, so the two licence files of the Paper packages
|
||||
have the same text. Each applies to its own package.
|
||||
|
||||
paper-docx https://pypi.org/project/paper-docx/ (python-docx)
|
||||
paper-pptx https://pypi.org/project/paper-pptx/ (python-pptx)
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2013 Steve Canny, https://github.com/scanny
|
||||
Portions Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
paper-xlsx extends openpyxl.
|
||||
|
||||
paper-xlsx https://pypi.org/project/paper-xlsx/ (openpyxl)
|
||||
|
||||
This software is under the MIT Licence
|
||||
======================================
|
||||
|
||||
Copyright (c) 2010 openpyxl
|
||||
Portions Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because one or more lines are too long.
File diff suppressed because it is too large.
Load diff
File diff suppressed because one or more lines are too long.
@@ -0,0 +1,689 @@
|
||||
<a id="source-7265f22343afe4ee"></a>
|
||||
<!-- source: pptx/references/api/text.bullet.md -->
|
||||
<!-- Generated from pptx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `pptx.text.bullet`
|
||||
|
||||
BulletFormat proxy, providing bullet and numbering control for a paragraph (paper-pptx).
|
||||
|
||||
## `BulletFormat`
|
||||
|
||||
```python
|
||||
BulletFormat(p: CT_TextParagraph, part: CT_TextParagraph = None)
|
||||
```
|
||||
|
||||
Bases: `object`
|
||||
|
||||
Bullet and numbering state of a single paragraph.
|
||||
|
||||
Read properties report this paragraph's **local** `a:pPr` state only: `None` means "nothing
|
||||
set here", in which case rendering inherits from the placeholder/list-style chain (use the
|
||||
effective-style inspection API to see what actually renders).
|
||||
|
||||
Wrap a paragraph's bullet properties.
|
||||
|
||||
Passing `part` enables the attachment check and the rollback boundary that the setters use.
|
||||
|
||||
### `char`
|
||||
|
||||
```python
|
||||
char: str | None
|
||||
```
|
||||
|
||||
The bullet character (`a:buChar/@char`), `None` unless a character bullet is set.
|
||||
|
||||
### `font_name`
|
||||
|
||||
```python
|
||||
font_name: str | None
|
||||
```
|
||||
|
||||
Bullet-specific typeface (`a:buFont/@typeface`), or `None` when not set locally.
|
||||
|
||||
### `number_scheme`
|
||||
|
||||
```python
|
||||
number_scheme: str | None
|
||||
```
|
||||
|
||||
Numbering scheme token (`a:buAutoNum/@type`), e.g. "arabicPeriod", or `None`.
|
||||
|
||||
### `set_character`
|
||||
|
||||
```python
|
||||
set_character(char: str = '•', *, font_name: str | None = None, size_percent: float | None = None, left_margin: Length | None = DEFAULT_BULLET_LEFT_MARGIN, hanging_indent: Length | None = DEFAULT_BULLET_HANGING_INDENT) -> None
|
||||
```
|
||||
|
||||
Give this paragraph a real character bullet (`a:buChar`).
|
||||
|
||||
`left_margin`/`hanging_indent` write `marL`/`indent` so the bullet hangs correctly;
|
||||
pass `None` for either to leave the existing paragraph attribute untouched.
|
||||
`font_name` sets a bullet-specific typeface (`a:buFont`); `size_percent` scales the
|
||||
bullet relative to the text size (fraction, 0.25–4.0).
|
||||
|
||||
### `set_none`
|
||||
|
||||
```python
|
||||
set_none() -> None
|
||||
```
|
||||
|
||||
Set an explicit "no bullet" (`a:buNone`), overriding any inherited bullet.
|
||||
|
||||
Margins, bullet font, and bullet size attributes are left untouched.
|
||||
|
||||
### `set_numbered`
|
||||
|
||||
```python
|
||||
set_numbered(scheme: str = 'arabicPeriod', *, start_at: int = 1, font_name: str | None = None, size_percent: float | None = None, left_margin: Length | None = DEFAULT_BULLET_LEFT_MARGIN, hanging_indent: Length | None = DEFAULT_BULLET_HANGING_INDENT) -> None
|
||||
```
|
||||
|
||||
Give this paragraph PowerPoint automatic numbering (`a:buAutoNum`).
|
||||
|
||||
`scheme` is an ECMA-376 auto-number token like "arabicPeriod" or "romanUcParenR";
|
||||
an unknown token raises `ValueError`. Numbering restarts at `start_at`.
|
||||
|
||||
### `size_percent`
|
||||
|
||||
```python
|
||||
size_percent: float | None
|
||||
```
|
||||
|
||||
Bullet size as a fraction of the text size (`a:buSzPct`), e.g. 0.75, or `None`.
|
||||
|
||||
### `start_at`
|
||||
|
||||
```python
|
||||
start_at: int | None
|
||||
```
|
||||
|
||||
First number of an auto-numbered sequence, `None` unless numbering is set.
|
||||
|
||||
### `type`
|
||||
|
||||
```python
|
||||
type: PP_BULLET_TYPE | None
|
||||
```
|
||||
|
||||
Kind of bullet explicitly set on this paragraph, `None` when nothing local is set.
|
||||
|
||||
## `DEFAULT_BULLET_HANGING_INDENT`
|
||||
|
||||
```python
|
||||
DEFAULT_BULLET_HANGING_INDENT = Emu(171450)
|
||||
```
|
||||
|
||||
## `DEFAULT_BULLET_LEFT_MARGIN`
|
||||
|
||||
```python
|
||||
DEFAULT_BULLET_LEFT_MARGIN = Emu(342900)
|
||||
```
|
||||
|
||||
<a id="source-c6ff4d26749bee76"></a>
|
||||
<!-- source: pptx/references/api/text.fonts.md -->
|
||||
<!-- Generated from pptx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `pptx.text.fonts`
|
||||
|
||||
Objects related to system font file lookup.
|
||||
|
||||
## `FontFiles`
|
||||
|
||||
Bases: `object`
|
||||
|
||||
A class-based singleton serving as a lazy cache for system font details.
|
||||
|
||||
### `find`
|
||||
|
||||
```python
|
||||
find(family_name: str, is_bold: bool, is_italic: bool) -> str
|
||||
```
|
||||
|
||||
Return the absolute path to an installed OpenType font.
|
||||
|
||||
File is matched by `family_name` and the styles `is_bold` and `is_italic`.
|
||||
|
||||
<a id="source-720ef7cbb39d9baa"></a>
|
||||
<!-- source: pptx/references/api/text.layout.md -->
|
||||
<!-- Generated from pptx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `pptx.text.layout`
|
||||
|
||||
Objects related to layout of rendered text, such as TextFitter.
|
||||
|
||||
## `TextFitter`
|
||||
|
||||
Bases: `tuple`
|
||||
|
||||
Value object that knows how to fit text into given rectangular extents.
|
||||
|
||||
### `best_fit_font_size`
|
||||
|
||||
```python
|
||||
best_fit_font_size(text: str, extents: tuple[Length, Length], max_size: int, font_file: str) -> int
|
||||
```
|
||||
|
||||
Return whole-number best fit point size less than or equal to `max_size`.
|
||||
|
||||
The return value is the largest whole-number point size less than or equal to
|
||||
`max_size` that allows `text` to fit completely within `extents` when rendered
|
||||
using font defined in `font_file`.
|
||||
|
||||
<a id="source-641574f4f1a6c03b"></a>
|
||||
<!-- source: pptx/references/api/text.text.md -->
|
||||
<!-- Generated from pptx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `pptx.text.text`
|
||||
|
||||
Text-related objects such as TextFrame and Paragraph.
|
||||
|
||||
## `Font`
|
||||
|
||||
```python
|
||||
Font(rPr: CT_TextCharacterProperties)
|
||||
```
|
||||
|
||||
Bases: `object`
|
||||
|
||||
Character properties object, providing font size, font name, bold, italic, etc.
|
||||
|
||||
Corresponds to `a:rPr` child element of a run. Also appears as `a:defRPr` and
|
||||
`a:endParaRPr` in paragraph and `a:defRPr` in list style elements.
|
||||
|
||||
### `bold`
|
||||
|
||||
```python
|
||||
bold: bool | None
|
||||
```
|
||||
|
||||
Get or set boolean bold value of `Font`, e.g. `paragraph.font.bold = True`.
|
||||
|
||||
If set to `None`, the bold setting is cleared and is inherited from an enclosing shape's
|
||||
setting, or a setting in a style or master. Returns None if no bold attribute is present,
|
||||
meaning the effective bold value is inherited from a master or the theme.
|
||||
|
||||
### `color`
|
||||
|
||||
```python
|
||||
color() -> ColorFormat
|
||||
```
|
||||
|
||||
The `ColorFormat` instance that provides access to the color settings for this font.
|
||||
|
||||
### `fill`
|
||||
|
||||
```python
|
||||
fill() -> FillFormat
|
||||
```
|
||||
|
||||
`FillFormat` instance for this font.
|
||||
|
||||
Provides access to fill properties such as fill color.
|
||||
|
||||
### `italic`
|
||||
|
||||
```python
|
||||
italic: bool | None
|
||||
```
|
||||
|
||||
Get or set boolean italic value of `Font` instance.
|
||||
|
||||
Has the same behaviors as bold with respect to None values.
|
||||
|
||||
### `language_id`
|
||||
|
||||
```python
|
||||
language_id: MSO_LANGUAGE_ID | None
|
||||
```
|
||||
|
||||
Get or set the language id of this `Font` instance.
|
||||
|
||||
The language id is a member of the `MsoLanguageId` enumeration. Assigning `None`
|
||||
removes any language setting, the same behavior as assigning `MSO_LANGUAGE_ID.NONE`.
|
||||
|
||||
### `name`
|
||||
|
||||
```python
|
||||
name: str | None
|
||||
```
|
||||
|
||||
Get or set the typeface name for this `Font` instance.
|
||||
|
||||
Causes the text it controls to appear in the named font, if a matching font is found.
|
||||
Returns `None` if the typeface is currently inherited from the theme. Setting it to `None`
|
||||
removes any override of the theme typeface.
|
||||
|
||||
### `size`
|
||||
|
||||
```python
|
||||
size: Length | None
|
||||
```
|
||||
|
||||
Indicates the font height in English Metric Units (EMU).
|
||||
|
||||
Read/write. `None` indicates the font size should be inherited from its style hierarchy,
|
||||
such as a placeholder or document defaults (usually 18pt). `Length` is a subclass of `int`
|
||||
having properties for convenient conversion into points or other length units. Likewise,
|
||||
the `pptx.util.Pt` class allows convenient specification of point values::
|
||||
|
||||
>>> font.size = Pt(24)
|
||||
>>> font.size
|
||||
304800
|
||||
>>> font.size.pt
|
||||
24.0
|
||||
|
||||
### `underline`
|
||||
|
||||
```python
|
||||
underline: bool | MSO_TEXT_UNDERLINE_TYPE | None
|
||||
```
|
||||
|
||||
Indicaties the underline setting for this font.
|
||||
|
||||
Value is `True`, `False`, `None`, or a member of the `MsoTextUnderlineType`
|
||||
enumeration. `None` is the default and indicates the underline setting should be inherited
|
||||
from the style hierarchy, such as from a placeholder. `True` indicates single underline.
|
||||
`False` indicates no underline. Other settings such as double and wavy underlining are
|
||||
indicated with members of the `MsoTextUnderlineType` enumeration.
|
||||
|
||||
## `TextFrame`
|
||||
|
||||
```python
|
||||
TextFrame(txBody: CT_TextBody, parent: ProvidesPart)
|
||||
```
|
||||
|
||||
Bases: `Subshape`
|
||||
|
||||
The part of a shape that contains its text.
|
||||
|
||||
Not all shapes have a text frame. Corresponds to the `p:txBody` element that can
|
||||
appear as a child element of `p:sp`. Not intended to be constructed directly.
|
||||
|
||||
### `add_paragraph`
|
||||
|
||||
```python
|
||||
add_paragraph()
|
||||
```
|
||||
|
||||
Return new `_Paragraph` instance appended to the sequence of
|
||||
paragraphs contained in this text frame.
|
||||
|
||||
### `auto_size`
|
||||
|
||||
```python
|
||||
auto_size: MSO_AUTO_SIZE | None
|
||||
```
|
||||
|
||||
Resizing strategy used to fit text within this shape.
|
||||
|
||||
Determins the type of automatic resizing used to fit the text of this shape within its
|
||||
bounding box when the text would otherwise extend beyond the shape boundaries. May be
|
||||
`None`, `MSO_AUTO_SIZE.NONE`, `MSO_AUTO_SIZE.SHAPE_TO_FIT_TEXT`, or
|
||||
`MSO_AUTO_SIZE.TEXT_TO_FIT_SHAPE`.
|
||||
|
||||
### `clear`
|
||||
|
||||
```python
|
||||
clear()
|
||||
```
|
||||
|
||||
Remove all paragraphs except one empty one.
|
||||
|
||||
### `fit_text`
|
||||
|
||||
```python
|
||||
fit_text(font_family: str = 'Calibri', max_size: int = 18, bold: bool = False, italic: bool = False, font_file: str | None = None)
|
||||
```
|
||||
|
||||
Fit text-frame text entirely within bounds of its shape.
|
||||
|
||||
Make the text in this text frame fit entirely within the bounds of its shape by setting
|
||||
word wrap on and applying the "best-fit" font size to all the text it contains.
|
||||
|
||||
`TextFrame.auto_size` is set to `MSO_AUTO_SIZE.NONE`. The font size will not
|
||||
be set larger than `max_size` points. If the path to a matching TrueType font is provided
|
||||
as `font_file`, that font file will be used for the font metrics. If `font_file` is `None`,
|
||||
best efforts are made to locate a font file with matchhing `font_family`, `bold`, and
|
||||
`italic` installed on the current system (usually succeeds if the font is installed).
|
||||
|
||||
### `font_scale`
|
||||
|
||||
```python
|
||||
font_scale: float | None
|
||||
```
|
||||
|
||||
Font scale percent of this frame's `a:normAutofit`, e.g. 62.5 (paper-pptx addition).
|
||||
|
||||
100.0 when the frame has `a:normAutofit` with no explicit scale; `None` when the
|
||||
frame's autofit setting is anything other than `a:normAutofit`. Read-only: PowerPoint
|
||||
owns this value (it records the shrink-to-fit reduction last applied); use
|
||||
`normalize_autofit` to freeze it into explicit sizes.
|
||||
|
||||
### `line_space_reduction`
|
||||
|
||||
```python
|
||||
line_space_reduction: float | None
|
||||
```
|
||||
|
||||
Line-spacing reduction percent of `a:normAutofit`, e.g. 20.0 (paper-pptx addition).
|
||||
|
||||
0.0 when the frame has `a:normAutofit` with no explicit reduction; `None` when the
|
||||
frame's autofit setting is anything other than `a:normAutofit`. Read-only.
|
||||
|
||||
### `margin_bottom`
|
||||
|
||||
```python
|
||||
margin_bottom: Length
|
||||
```
|
||||
|
||||
`Length` value representing the inset of text from the bottom text frame border.
|
||||
|
||||
`pptx.util.Inches` provides a convenient way of setting the value, e.g.
|
||||
`text_frame.margin_bottom = Inches(0.05)`.
|
||||
|
||||
### `margin_left`
|
||||
|
||||
```python
|
||||
margin_left: Length
|
||||
```
|
||||
|
||||
Inset of text from left text frame border as `Length` value.
|
||||
|
||||
### `margin_right`
|
||||
|
||||
```python
|
||||
margin_right: Length
|
||||
```
|
||||
|
||||
Inset of text from right text frame border as `Length` value.
|
||||
|
||||
### `margin_top`
|
||||
|
||||
```python
|
||||
margin_top: Length
|
||||
```
|
||||
|
||||
Inset of text from top text frame border as `Length` value.
|
||||
|
||||
### `normalize_autofit`
|
||||
|
||||
```python
|
||||
normalize_autofit(*, min_font_size: Length | None = None, resolve: bool = False) -> None
|
||||
```
|
||||
|
||||
Freeze this frame's rendered text metrics and set explicit no-autofit.
|
||||
|
||||
paper-pptx addition. What the reader currently sees is made explicit, then the frame's
|
||||
autofit is set to `a:noAutofit`:
|
||||
|
||||
- `a:normAutofit` with a font scale: every explicit font size in the frame (run,
|
||||
paragraph-default, and end-paragraph properties) is multiplied by the scale. If any
|
||||
run's size is not locally resolvable (neither its own `sz` nor its paragraph's
|
||||
default), `UnsupportedStructureError` is raised — unless `resolve=True`, in which
|
||||
case the size is resolved through the effective-style walk (placeholder → layout →
|
||||
master → theme) and frozen from the resolved value; what the walk cannot resolve
|
||||
still refuses. This API never silently guesses.
|
||||
- `a:normAutofit` with a line-spacing reduction: every paragraph's explicit line
|
||||
spacing is reduced accordingly; any paragraph without explicit line spacing raises
|
||||
`UnsupportedStructureError` (`resolve` covers font sizes only in this version).
|
||||
- `a:spAutoFit`, `a:noAutofit`, or no autofit element: no text metrics change.
|
||||
|
||||
`min_font_size` (a `Length`, e.g. `Pt(11)`) is applied after freezing: explicit sizes
|
||||
below the floor are raised to it. Validation completes fully before the first write
|
||||
(a refusal leaves the frame byte-identical).
|
||||
|
||||
### `paragraphs`
|
||||
|
||||
```python
|
||||
paragraphs: tuple[_Paragraph, ...]
|
||||
```
|
||||
|
||||
Sequence of paragraphs in this text frame.
|
||||
|
||||
A text frame always contains at least one paragraph.
|
||||
|
||||
### `text`
|
||||
|
||||
```python
|
||||
text: str
|
||||
```
|
||||
|
||||
All text in this text-frame as a single string.
|
||||
|
||||
Read/write. The return value contains all text in this text-frame. A line-feed character
|
||||
(`"\n"`) separates the text for each paragraph. A vertical-tab character (`"\v"`) appears
|
||||
for each line break (aka. soft carriage-return) encountered.
|
||||
|
||||
The vertical-tab character is how PowerPoint represents a soft carriage return in clipboard
|
||||
text, which is why that encoding was chosen.
|
||||
|
||||
Assignment replaces all text in the text frame. A new paragraph is added for each line-feed
|
||||
character (`"\n"`) encountered. A line-break (soft carriage-return) is inserted for each
|
||||
vertical-tab character (`"\v"`) encountered.
|
||||
|
||||
Any control character other than newline, tab, or vertical-tab are escaped as plain-text
|
||||
like "_x001B_" (for ESC (ASCII 32) in this example).
|
||||
|
||||
### `vertical_anchor`
|
||||
|
||||
```python
|
||||
vertical_anchor: MSO_VERTICAL_ANCHOR | None
|
||||
```
|
||||
|
||||
Represents the vertical alignment of text in this text frame.
|
||||
|
||||
`None` indicates the effective value should be inherited from this object's style hierarchy.
|
||||
|
||||
### `word_wrap`
|
||||
|
||||
```python
|
||||
word_wrap: bool | None
|
||||
```
|
||||
|
||||
`True` when lines of text in this shape are wrapped to fit within the shape's width.
|
||||
|
||||
Read-write. Valid values are True, False, or None. True and False turn word wrap on and
|
||||
off, respectively. Assigning None to word wrap causes any word wrap setting to be removed
|
||||
from the text frame, causing it to inherit this setting from its style hierarchy.
|
||||
|
||||
<a id="source-8c8b08f561ed110c"></a>
|
||||
<!-- source: pptx/references/api/types.md -->
|
||||
<!-- Generated from pptx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `pptx.types`
|
||||
|
||||
Abstract types used by `python-pptx`.
|
||||
|
||||
## `ProvidesExtents`
|
||||
|
||||
Bases: `Protocol`
|
||||
|
||||
An object that has width and height.
|
||||
|
||||
### `height`
|
||||
|
||||
```python
|
||||
height: Length
|
||||
```
|
||||
|
||||
Distance between top and bottom extents of shape in EMUs.
|
||||
|
||||
### `width`
|
||||
|
||||
```python
|
||||
width: Length
|
||||
```
|
||||
|
||||
Distance between left and right extents of shape in EMUs.
|
||||
|
||||
## `ProvidesPart`
|
||||
|
||||
Bases: `Protocol`
|
||||
|
||||
An object that provides access to its XmlPart.
|
||||
|
||||
This type is for objects that need access to their part, possibly because they need access to
|
||||
the package or related parts.
|
||||
|
||||
### `part`
|
||||
|
||||
```python
|
||||
part: XmlPart
|
||||
```
|
||||
|
||||
<a id="source-c6f3b84c67d06ef5"></a>
|
||||
<!-- source: pptx/references/api/util.md -->
|
||||
<!-- Generated from pptx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `pptx.util`
|
||||
|
||||
Utility functions and classes.
|
||||
|
||||
## `Centipoints`
|
||||
|
||||
Bases: `Length`
|
||||
|
||||
Convenience constructor for length in hundredths of a point.
|
||||
|
||||
## `Cm`
|
||||
|
||||
Bases: `Length`
|
||||
|
||||
Convenience constructor for length in centimeters.
|
||||
|
||||
## `Emu`
|
||||
|
||||
Bases: `Length`
|
||||
|
||||
Convenience constructor for length in english metric units.
|
||||
|
||||
## `Inches`
|
||||
|
||||
Bases: `Length`
|
||||
|
||||
Convenience constructor for length in inches.
|
||||
|
||||
## `Length`
|
||||
|
||||
Bases: `int`
|
||||
|
||||
Base class for length classes Inches, Emu, Cm, Mm, and Pt.
|
||||
|
||||
Provides properties for converting length values to convenient units.
|
||||
|
||||
### `centipoints`
|
||||
|
||||
```python
|
||||
centipoints: int
|
||||
```
|
||||
|
||||
Integer length in hundredths of a point (1/7200 inch).
|
||||
|
||||
Used internally because PowerPoint stores font size in centipoints.
|
||||
|
||||
### `cm`
|
||||
|
||||
```python
|
||||
cm: float
|
||||
```
|
||||
|
||||
Floating point length in centimeters.
|
||||
|
||||
### `emu`
|
||||
|
||||
```python
|
||||
emu: int
|
||||
```
|
||||
|
||||
Integer length in English Metric Units.
|
||||
|
||||
### `inches`
|
||||
|
||||
```python
|
||||
inches: float
|
||||
```
|
||||
|
||||
Floating point length in inches.
|
||||
|
||||
### `mm`
|
||||
|
||||
```python
|
||||
mm: float
|
||||
```
|
||||
|
||||
Floating point length in millimeters.
|
||||
|
||||
### `pt`
|
||||
|
||||
```python
|
||||
pt: float
|
||||
```
|
||||
|
||||
Floating point length in points.
|
||||
|
||||
## `Mm`
|
||||
|
||||
Bases: `Length`
|
||||
|
||||
Convenience constructor for length in millimeters.
|
||||
|
||||
## `Pt`
|
||||
|
||||
Bases: `Length`
|
||||
|
||||
Convenience value class for specifying a length in points.
|
||||
|
||||
## `lazyproperty`
|
||||
|
||||
```python
|
||||
lazyproperty(fget: Callable[..., _T]) -> None
|
||||
```
|
||||
|
||||
Bases: `Generic[_T]`
|
||||
|
||||
Decorator like @property, but evaluated only on first access.
|
||||
|
||||
Like @property, this can only be used to decorate methods having only a `self` parameter, and
|
||||
is accessed like an attribute on an instance, i.e. trailing parentheses are not used. Unlike
|
||||
@property, the decorated method is only evaluated on first access; the resulting value is
|
||||
cached and that same value returned on second and later access without re-evaluation of the
|
||||
method.
|
||||
|
||||
Like @property, this class produces a *data descriptor* object, which is stored in the __dict__
|
||||
of the *class* under the name of the decorated method ('fget' nominally). The cached value is
|
||||
stored in the __dict__ of the *instance* under that same name.
|
||||
|
||||
Because it is a data descriptor (as opposed to a *non-data descriptor*), its `__get__()` method
|
||||
is executed on each access of the decorated attribute; the __dict__ item of the same name is
|
||||
"shadowed" by the descriptor.
|
||||
|
||||
While this may represent a performance improvement over a property, its greater benefit may be
|
||||
its other characteristics. One common use is to construct collaborator objects, removing that
|
||||
"real work" from the constructor, while still only executing once. It also de-couples client
|
||||
code from any sequencing considerations; if it's accessed from more than one location, it's
|
||||
assured it will be ready whenever needed.
|
||||
|
||||
Loosely based on: https://stackoverflow.com/a/6849299/1902513.
|
||||
|
||||
A lazyproperty is read-only. There is no counterpart to the optional "setter" (or deleter)
|
||||
behavior of an @property. This is critically important to maintaining its immutability and
|
||||
idempotence guarantees. Attempting to assign to a lazyproperty raises AttributeError
|
||||
unconditionally.
|
||||
|
||||
The parameter names in the methods below correspond to this usage example::
|
||||
|
||||
class Obj(object)
|
||||
|
||||
@lazyproperty
|
||||
def fget(self):
|
||||
return 'some result'
|
||||
|
||||
obj = Obj()
|
||||
|
||||
Not suitable for wrapping a function (as opposed to a method) because it is not callable.
|
||||
|
||||
*fget* is the decorated method (a "getter" function).
|
||||
|
||||
A lazyproperty is read-only, so there is only an *fget* function (a regular
|
||||
@property can also have an fset and fdel function). This name was chosen for
|
||||
consistency with Python's `property` class which uses this name for the
|
||||
corresponding parameter.
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
<a id="source-bd380984355417c8"></a>
|
||||
<!-- source: pptx/references/paper-api.md -->
|
||||
# Paper PPTX API companion
|
||||
|
||||
This companion covers capabilities beyond familiar `python-pptx`. The installed distribution is
|
||||
+1
-1
@@ -22,7 +22,7 @@ Use your existing knowledge of `openpyxl` for worksheets, cells, formulas, style
|
||||
|
||||
`paper-xlsx` is installed under the `openpyxl` import.
|
||||
|
||||
The [Paper API companion](references/paper-api.md) maps Paper-specific capabilities to their public symbols. The [generated API reference](references/api/index.md) covers the complete public API, including the surface inherited from `openpyxl`, with one page per module. It is large; search by symbol and read only the relevant section.
|
||||
The [Paper API companion](references/paper-api.md#source-1d5d2fa5f7f8302a) maps Paper-specific capabilities to their public symbols. The [generated API reference](references/api-003.md#source-52f276c95ae6d391) covers the complete public API, including the surface inherited from `openpyxl`, with one page per module. It is large; search by symbol and read only the relevant section.
|
||||
|
||||
## Package behavior
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
Sandbox document skills
|
||||
=============================
|
||||
|
||||
The skills "docx", "xlsx", "pptx" and "pdf" are adapted from the skills of the
|
||||
Feather project.
|
||||
|
||||
Source: https://github.com/paper-instruments/feather-train
|
||||
(folder feather-harness/src/feather_harness/skills)
|
||||
Commit: b7463092af862ebbdf4c5920c4bc9ab38ab17ad9
|
||||
Licence: MIT, Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
What was changed: the text about LibreOffice was replaced by a note that
|
||||
LibreOffice is not installed, the text about OCR was shortened in the same way,
|
||||
and the generated page of the LibreOffice-backed module "openpyxl.oracle" got
|
||||
the same note. Each of the four got one line that says to write
|
||||
helper scripts in the chat's work folder. The remaining built-in skills are not part of this package.
|
||||
|
||||
The MIT licence of the Feather project
|
||||
--------------------------------------
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
The generated API pages
|
||||
-----------------------
|
||||
|
||||
The pages under docx/references/api, xlsx/references/api and
|
||||
pptx/references/api are generated from the docstrings of the Paper libraries
|
||||
and of the libraries that they extend. The licences of those projects apply to
|
||||
that text. All three are MIT licences.
|
||||
|
||||
paper-docx extends python-docx, and paper-pptx extends python-pptx. Steve Canny
|
||||
wrote both upstream libraries, so the two licence files of the Paper packages
|
||||
have the same text. Each applies to its own package.
|
||||
|
||||
paper-docx https://pypi.org/project/paper-docx/ (python-docx)
|
||||
paper-pptx https://pypi.org/project/paper-pptx/ (python-pptx)
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2013 Steve Canny, https://github.com/scanny
|
||||
Portions Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
paper-xlsx extends openpyxl.
|
||||
|
||||
paper-xlsx https://pypi.org/project/paper-xlsx/ (openpyxl)
|
||||
|
||||
This software is under the MIT Licence
|
||||
======================================
|
||||
|
||||
Copyright (c) 2010 openpyxl
|
||||
Portions Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+2379
-400
File diff suppressed because one or more lines are too long.
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because one or more lines are too long.
+2
@@ -1,3 +1,5 @@
|
||||
<a id="source-1d5d2fa5f7f8302a"></a>
|
||||
<!-- source: xlsx/references/paper-api.md -->
|
||||
# Paper XLSX API companion
|
||||
|
||||
This companion covers capabilities beyond familiar `openpyxl`. The installed distribution is `paper-xlsx`, but the import remains `openpyxl`; ordinary `openpyxl` APIs remain available.
|
||||
+1
-1
@@ -49,7 +49,7 @@ export const RUNS = {
|
||||
export const SKILLS = [
|
||||
{ name: 'citations', description: 'Cite every claim with a numbered source.', layer: 'personal', path: '/skills/citations/SKILL.md', enabled: true, editable: true },
|
||||
{ name: 'house-style', description: 'The shared writing rules.', layer: 'shared', path: '/shared/house-style/SKILL.md', enabled: true, editable: false },
|
||||
{ name: 'pdf', description: 'Read and fill PDF forms.', layer: 'builtin', path: '/builtin/pdf/SKILL.md', enabled: true, editable: false },
|
||||
{ name: 'pdf', description: 'Read and create PDFs with Office tools.', layer: 'addon', addon: 'office', addon_title: 'Office', path: '/addon-skills/office/pdf/SKILL.md', enabled: true, editable: false },
|
||||
{ name: 'broken', description: '', layer: 'folder', path: '/Notes/.skills/broken/SKILL.md', enabled: true, editable: false, invalid: 'the description is empty' },
|
||||
]
|
||||
|
||||
|
||||
@@ -25,3 +25,44 @@ test('a skill written on the page shows in the list and can be deleted', async (
|
||||
await page.getByRole('alertdialog').getByRole('button', { name: 'Delete' }).click()
|
||||
await expect(page.getByTestId(`skill-row-${name}`)).toHaveCount(0)
|
||||
})
|
||||
|
||||
// No route interception: these checks cover the application's actual skills,
|
||||
// saved-agent and preference APIs on a server without an authoring provider.
|
||||
test('document names keep agent selections and normalize OFF without a core provider', async ({ request }) => {
|
||||
const names = ['docx', 'pptx', 'pdf', 'xlsx']
|
||||
const list = await request.get('/api/chats/skills')
|
||||
expect(list.ok()).toBeTruthy()
|
||||
const { skills } = await list.json()
|
||||
expect(skills.filter(skill => names.includes(skill.name))).toEqual([])
|
||||
|
||||
const saved = await request.post('/api/chats/agents', {
|
||||
data: { name: `document-selection-${Date.now()}`, model: 'mock-model', skills: names, addons: [] },
|
||||
})
|
||||
expect(saved.status()).toBe(201)
|
||||
const agent = await saved.json()
|
||||
let chat
|
||||
try {
|
||||
expect(agent.skills).toEqual(names)
|
||||
expect(agent.addons).toEqual([])
|
||||
const created = await request.post('/api/chats', { data: { model: 'mock-model', agent_id: agent.id } })
|
||||
expect(created.status()).toBe(201)
|
||||
chat = await created.json()
|
||||
const off = await request.put(`/api/chats/${chat.id}/skills`, { data: { off: ['builtin:docx'] } })
|
||||
expect(off.ok()).toBeTruthy()
|
||||
expect((await off.json()).off).toEqual(['addon:docx'])
|
||||
const reload = await request.get(`/api/chats/${chat.id}`)
|
||||
expect(reload.ok()).toBeTruthy()
|
||||
expect((await reload.json()).agent_id).toBe(agent.id)
|
||||
const picker = await request.get(`/api/chats/skills?chat=${chat.id}`)
|
||||
expect(picker.ok()).toBeTruthy()
|
||||
expect((await picker.json()).skills.filter(skill => names.includes(skill.name))).toEqual([])
|
||||
const enabled = await request.put(`/api/chats/${chat.id}/skills`, { data: { off: [] } })
|
||||
expect(enabled.ok()).toBeTruthy()
|
||||
expect((await enabled.json()).off).toEqual([])
|
||||
const reread = await request.get(`/api/chats/agents/${agent.id}`)
|
||||
expect((await reread.json()).skills).toEqual(names)
|
||||
} finally {
|
||||
if (chat) expect((await request.delete(`/api/chats/${chat.id}`)).ok()).toBeTruthy()
|
||||
expect((await request.delete(`/api/chats/agents/${agent.id}`)).ok()).toBeTruthy()
|
||||
}
|
||||
})
|
||||
@@ -246,34 +246,49 @@ test.describe('Chat skills picker with add-on skills', () => {
|
||||
return state
|
||||
}
|
||||
const office = { id: 'addon:xlsx', name: 'xlsx', description: 'Read and edit spreadsheets with the Office tools', layer: 'addon', addon: 'office', addon_title: 'Office', enabled: true }
|
||||
const builtinX = { id: 'builtin:xlsx', name: 'xlsx', description: 'Spreadsheets in a sandbox', layer: 'builtin', shadowed: 'addon', shadowed_by: 'office', enabled: true }
|
||||
const mine = { id: 'personal:review', name: 'review', description: 'Check a change', layer: 'personal', enabled: true }
|
||||
|
||||
test('labels each skill with its source and lists the built-in one an add-on replaces, dimmed and with no switch', async ({ page }) => {
|
||||
await stubAddon(page, () => [office, builtinX, mine])
|
||||
test('labels document skills with their provider, with no removed built-in', async ({ page }) => {
|
||||
await stubAddon(page, () => [office, mine])
|
||||
await open(page)
|
||||
const sources = page.getByTestId('chat-skills-source')
|
||||
await expect(sources).toHaveText(['Office', 'Personal'])
|
||||
await expect(page.getByRole('switch')).toHaveCount(2)
|
||||
const replaced = page.getByTestId('chat-skills-replaced')
|
||||
await expect(replaced).toHaveCount(1)
|
||||
await expect(replaced).toContainText('xlsx')
|
||||
await expect(replaced).toContainText('Replaced by Office')
|
||||
await expect(replaced).toHaveCount(0)
|
||||
await expect(page.getByTestId('chat-skills-fallback')).toHaveCount(0)
|
||||
await expect(summary(page)).toHaveText('2 of 2 on')
|
||||
await shot(page, 'skills-picker-addon')
|
||||
})
|
||||
|
||||
test('switching the add-on skill off brings the built-in one back, with one line that says why', async ({ page }) => {
|
||||
const state = await stubAddon(page, (s) => (s.puts.length === 0
|
||||
? [office, builtinX, mine]
|
||||
: [{ ...office, enabled: false }, { ...builtinX, shadowed: undefined, shadowed_by: undefined, fallback: 'Office' }, mine]))
|
||||
test('switching a document skill off persists OFF without a core fallback', async ({ page }) => {
|
||||
const state = await stubAddon(page, s => [{ ...office, enabled: !s.puts.at(-1)?.off.includes('addon:xlsx') }, mine])
|
||||
await open(page)
|
||||
await sw(page, 'xlsx').click()
|
||||
await expect.poll(() => state.puts).toEqual([{ off: ['addon:xlsx'] }])
|
||||
await expect(page.getByTestId('chat-skills-fallback')).toHaveText('Built-in xlsx in use: the Office add-on\'s own skill is off or not running here.')
|
||||
await expect(sw(page, 'xlsx')).not.toBeChecked()
|
||||
await expect(page.getByTestId('chat-skills-fallback')).toHaveCount(0)
|
||||
await expect(page.getByTestId('chat-skills-replaced')).toHaveCount(0)
|
||||
await expect(page.locator('[data-testid="chat-skills-source"][data-kind="builtin"]')).toHaveText('Built-in')
|
||||
await shot(page, 'skills-picker-fallback')
|
||||
await expect(page.locator('[data-testid="chat-skills-source"][data-kind="builtin"]')).toHaveCount(0)
|
||||
})
|
||||
|
||||
for (const addon of ['office', 'sandbox']) {
|
||||
test(`${addon} supplies familiar document names without a builtin`, async ({ page }) => {
|
||||
await stubAddon(page, () => ['docx', 'pptx', 'pdf', 'xlsx'].map(name => ({
|
||||
...office, id: `addon:${name}`, name, addon, addon_title: addon === 'office' ? 'Office' : 'Sandbox',
|
||||
})))
|
||||
await open(page)
|
||||
await expect(page.getByRole('switch')).toHaveCount(4)
|
||||
await expect(page.getByTestId('chat-skills-source')).toHaveText(Array(4).fill(addon === 'office' ? 'Office' : 'Sandbox'))
|
||||
await expect(page.getByTestId('chat-skills-fallback')).toHaveCount(0)
|
||||
await expect(page.getByTestId('chat-skills-replaced')).toHaveCount(0)
|
||||
})
|
||||
}
|
||||
|
||||
test('an unavailable pinned provider explains why without suggesting a fallback', async ({ page }) => {
|
||||
await stubAddon(page, () => [{ ...office, unavailable: 'Pinned provider is not available for this chat.' }, mine])
|
||||
await open(page)
|
||||
await expect(page.getByTestId('chat-skills-item').first()).toContainText('Pinned provider is not available for this chat.')
|
||||
await expect(page.getByTestId('chat-skills-fallback')).toHaveCount(0)
|
||||
})
|
||||
})
|
||||
@@ -10,7 +10,7 @@ test.describe('Skills', () => {
|
||||
await expect(page.getByTestId('skills-page')).toBeVisible()
|
||||
await expect(page.getByTestId('skill-row-citations')).toContainText('Personal')
|
||||
await expect(page.getByTestId('skill-used-citations')).toHaveText('Used by research-assistant')
|
||||
await expect(page.getByTestId('skill-row-pdf')).toContainText('Built-in')
|
||||
await expect(page.getByTestId('skill-row-pdf')).toContainText('Office')
|
||||
await expect(page.getByTestId('skill-row-house-style')).toContainText('Shared')
|
||||
await expect(page.getByTestId('skill-row-broken')).toContainText('Workspace')
|
||||
await expect(page.getByTestId('skill-used-broken')).toContainText('not a valid skill')
|
||||
@@ -26,13 +26,11 @@ test.describe('Skills', () => {
|
||||
await installAgents(page, {
|
||||
skills: [
|
||||
{ name: 'xlsx', description: 'Office sheets.', layer: 'addon', addon: 'office', addon_title: 'Office', path: '/addon-skills/office/xlsx/SKILL.md', enabled: true, editable: false },
|
||||
{ name: 'xlsx', description: 'Sheets sheets.', layer: 'addon', addon: 'sheets', addon_title: 'Sheets', path: '/addon-skills/sheets/xlsx/SKILL.md', enabled: true, editable: false, shadowed: 'addon', shadowed_by: 'office' },
|
||||
{ name: 'xlsx', description: 'Built-in sheets.', layer: 'builtin', path: '/builtin-skills/xlsx/SKILL.md', enabled: true, editable: false, shadowed: 'addon', shadowed_by: 'office' },
|
||||
{ name: 'xlsx', description: 'Sandbox Python spreadsheets.', layer: 'addon', addon: 'sandbox', addon_title: 'Sandbox', path: '/addon-skills/sandbox/xlsx/SKILL.md', enabled: true, editable: false, shadowed: 'addon', shadowed_by: 'office' },
|
||||
],
|
||||
})
|
||||
await page.goto('/app/skills')
|
||||
await expect(page.getByTestId('skills-page')).toContainText('Not active: Office provides it')
|
||||
await expect(page.getByTestId('skills-page')).toContainText('Replaced by Office')
|
||||
})
|
||||
|
||||
test('only your own skills can be edited or deleted', async ({ page }) => {
|
||||
@@ -40,7 +38,7 @@ test.describe('Skills', () => {
|
||||
await page.goto('/app/skills')
|
||||
await page.getByTestId('skill-row-pdf').click()
|
||||
await expect(page.getByTestId('skill-title')).toHaveText('pdf')
|
||||
await expect(page.getByTestId('skill-layer')).toHaveText('Built-in')
|
||||
await expect(page.getByTestId('skill-layer')).toHaveText('Provided by Office')
|
||||
await expect(page.getByRole('button', { name: 'Edit' })).toHaveCount(0)
|
||||
await expect(page.getByRole('button', { name: 'Delete' })).toHaveCount(0)
|
||||
await page.getByTestId('skill-row-citations').click()
|
||||
@@ -150,7 +148,7 @@ test.describe('Skill editor', () => {
|
||||
|
||||
test('a skill you cannot write opens read-only', async ({ page }) => {
|
||||
await installAgents(page)
|
||||
await page.goto('/app/skills/edit/builtin/pdf')
|
||||
await page.goto('/app/skills/edit/addon/pdf')
|
||||
await expect(page.getByTestId('skill-readonly')).toBeVisible()
|
||||
await expect(page.getByRole('button', { name: 'Save changes' })).toHaveCount(0)
|
||||
})
|
||||
|
||||
@@ -691,7 +691,9 @@
|
||||
"installNamed": "{{name}} installieren",
|
||||
"shadowWarning": "Dieses Add-on ersetzt das eingebaute {{tool}}. Ein anderes Add-on ({{name}}) tut das bereits. Nur eines kann aktiv sein; welches, wählen Sie unter Einstellungen > Werkzeuge. Solange Sie nichts wählen, stellt das zuerst installierte es bereit.",
|
||||
"skillShadow": "Dieses Add-on ersetzt den integrierten Skill {{skill}}.",
|
||||
"skillShadowWarning": "Dieses Add-on ersetzt den integrierten Skill {{skill}}. Ein anderes Add-on ({{name}}) tut das bereits. Nur eines kann aktiv sein; welches, wählen Sie unter Einstellungen > Werkzeuge. Solange Sie nichts wählen, stellt das zuerst installierte es bereit."
|
||||
"skillShadowWarning": "Dieses Add-on ersetzt den integrierten Skill {{skill}}. Ein anderes Add-on ({{name}}) tut das bereits. Nur eines kann aktiv sein; welches, wählen Sie unter Einstellungen > Werkzeuge. Solange Sie nichts wählen, stellt das zuerst installierte es bereit.",
|
||||
"skillProvides": "Dieses Add-on stellt die Fähigkeit {{skill}} bereit.",
|
||||
"skillProvidesWarning": "Dieses Add-on stellt die Fähigkeit {{skill}} bereit. Ein anderes Add-on ({{name}}) stellt sie ebenfalls bereit. Nur eines kann aktiv sein; wähle unter Einstellungen > Werkzeuge. Ohne Auswahl wird das zuerst installierte verwendet."
|
||||
},
|
||||
"family": {
|
||||
"pages": "Du suchst Seiten, die du oder ein Agent erstellt hast? Sie sind unter <go>Seiten</go>."
|
||||
@@ -731,6 +733,7 @@
|
||||
"skills": {
|
||||
"title_one": "{{count}} Chat-Skill",
|
||||
"title_other": "{{count}} Chat-Skills",
|
||||
"provides": "stellt die Fähigkeit {{skill}} bereit",
|
||||
"replaces": "ersetzt den integrierten Skill",
|
||||
"serves": "wird in den Chats verwendet",
|
||||
"notServing": "derzeit nicht verwendet",
|
||||
|
||||
@@ -691,7 +691,9 @@
|
||||
"installNamed": "Install {{name}}",
|
||||
"shadowWarning": "This add-on replaces the built-in {{tool}}. Another add-on ({{name}}) already does. Only one can be active; you choose which in Settings > Tools. Until you choose, the one installed first serves.",
|
||||
"skillShadow": "This add-on replaces the built-in skill {{skill}}.",
|
||||
"skillShadowWarning": "This add-on replaces the built-in skill {{skill}}. Another add-on ({{name}}) already does. Only one can be active; you choose which in Settings > Tools. Until you choose, the one installed first serves."
|
||||
"skillShadowWarning": "This add-on replaces the built-in skill {{skill}}. Another add-on ({{name}}) already does. Only one can be active; you choose which in Settings > Tools. Until you choose, the one installed first serves.",
|
||||
"skillProvides": "This add-on provides the {{skill}} skill.",
|
||||
"skillProvidesWarning": "This add-on provides the {{skill}} skill. Another add-on ({{name}}) also provides it. Only one can be active; choose in Settings > Tools. Without a choice, the one installed first serves."
|
||||
},
|
||||
"family": {
|
||||
"pages": "Looking for pages you or an agent made? They are in <go>Pages</go>."
|
||||
@@ -731,6 +733,7 @@
|
||||
"skills": {
|
||||
"title_one": "{{count}} chat skill",
|
||||
"title_other": "{{count}} chat skills",
|
||||
"provides": "provides the {{skill}} skill",
|
||||
"replaces": "replaces the built-in skill",
|
||||
"serves": "serves in the chats",
|
||||
"notServing": "not serving now",
|
||||
|
||||
@@ -691,7 +691,9 @@
|
||||
"installNamed": "Instalar {{name}}",
|
||||
"shadowWarning": "Este complemento reemplaza el {{tool}} integrado. Otro complemento ({{name}}) ya lo hace. Solo uno puede estar activo; eliges cuál en Ajustes > Herramientas. Hasta que elijas, lo sirve el que se instaló primero.",
|
||||
"skillShadow": "Este complemento reemplaza la habilidad integrada {{skill}}.",
|
||||
"skillShadowWarning": "Este complemento reemplaza la habilidad integrada {{skill}}. Otro complemento ({{name}}) ya lo hace. Solo uno puede estar activo; eliges cuál en Ajustes > Herramientas. Hasta que elijas, lo sirve el que se instaló primero."
|
||||
"skillShadowWarning": "Este complemento reemplaza la habilidad integrada {{skill}}. Otro complemento ({{name}}) ya lo hace. Solo uno puede estar activo; eliges cuál en Ajustes > Herramientas. Hasta que elijas, lo sirve el que se instaló primero.",
|
||||
"skillProvides": "Este complemento proporciona la habilidad {{skill}}.",
|
||||
"skillProvidesWarning": "Este complemento proporciona la habilidad {{skill}}. Otro complemento ({{name}}) también la proporciona. Solo uno puede estar activo; elige en Configuración > Herramientas. Sin una elección, se usa el instalado primero."
|
||||
},
|
||||
"family": {
|
||||
"pages": "¿Buscas páginas que creaste tú o un agente? Están en <go>Páginas</go>."
|
||||
@@ -731,6 +733,7 @@
|
||||
"skills": {
|
||||
"title_one": "{{count}} habilidad de chat",
|
||||
"title_other": "{{count}} habilidades de chat",
|
||||
"provides": "proporciona la habilidad {{skill}}",
|
||||
"replaces": "reemplaza la habilidad integrada",
|
||||
"serves": "se usa en los chats",
|
||||
"notServing": "no se usa ahora",
|
||||
|
||||
@@ -695,7 +695,9 @@
|
||||
"installNamed": "Installer {{name}}",
|
||||
"shadowWarning": "Ce module remplace l'outil intégré {{tool}}. Un autre module ({{name}}) le fait déjà. Un seul peut être actif ; vous choisissez lequel dans Paramètres > Outils. Tant que vous ne choisissez pas, c'est le premier installé qui le fournit.",
|
||||
"skillShadow": "Ce module remplace la compétence intégrée {{skill}}.",
|
||||
"skillShadowWarning": "Ce module remplace la compétence intégrée {{skill}}. Un autre module ({{name}}) le fait déjà. Un seul peut être actif ; vous choisissez lequel dans Paramètres > Outils. Tant que vous ne choisissez pas, c'est le premier installé qui le fournit."
|
||||
"skillShadowWarning": "Ce module remplace la compétence intégrée {{skill}}. Un autre module ({{name}}) le fait déjà. Un seul peut être actif ; vous choisissez lequel dans Paramètres > Outils. Tant que vous ne choisissez pas, c'est le premier installé qui le fournit.",
|
||||
"skillProvides": "Cette extension fournit la compétence {{skill}}.",
|
||||
"skillProvidesWarning": "Cette extension fournit la compétence {{skill}}. Une autre extension ({{name}}) la fournit aussi. Une seule peut être active ; choisissez dans Paramètres > Outils. Sans choix, celle installée en premier est utilisée."
|
||||
},
|
||||
"family": {
|
||||
"pages": "Vous cherchez des pages créées par vous ou par un agent ? Elles sont dans <go>Pages</go>."
|
||||
@@ -735,6 +737,7 @@
|
||||
"skills": {
|
||||
"title_one": "{{count}} compétence de chat",
|
||||
"title_other": "{{count}} compétences de chat",
|
||||
"provides": "fournit la compétence {{skill}}",
|
||||
"replaces": "remplace la compétence intégrée",
|
||||
"serves": "utilisée dans les discussions",
|
||||
"notServing": "non utilisée pour l'instant",
|
||||
|
||||
@@ -691,7 +691,9 @@
|
||||
"installNamed": "Pasang {{name}}",
|
||||
"shadowWarning": "Add-on ini menggantikan {{tool}} bawaan. Add-on lain ({{name}}) sudah melakukannya. Hanya satu yang bisa aktif; Anda memilih yang mana di Pengaturan > Alat. Sebelum Anda memilih, yang dipasang lebih dulu yang melayaninya.",
|
||||
"skillShadow": "Add-on ini menggantikan skill bawaan {{skill}}.",
|
||||
"skillShadowWarning": "Add-on ini menggantikan skill bawaan {{skill}}. Add-on lain ({{name}}) sudah melakukannya. Hanya satu yang bisa aktif; Anda memilih yang mana di Pengaturan > Alat. Sebelum Anda memilih, yang dipasang lebih dulu yang melayaninya."
|
||||
"skillShadowWarning": "Add-on ini menggantikan skill bawaan {{skill}}. Add-on lain ({{name}}) sudah melakukannya. Hanya satu yang bisa aktif; Anda memilih yang mana di Pengaturan > Alat. Sebelum Anda memilih, yang dipasang lebih dulu yang melayaninya.",
|
||||
"skillProvides": "Add-on ini menyediakan keterampilan {{skill}}.",
|
||||
"skillProvidesWarning": "Add-on ini menyediakan keterampilan {{skill}}. Add-on lain ({{name}}) juga menyediakannya. Hanya satu yang dapat aktif; pilih di Pengaturan > Alat. Tanpa pilihan, yang dipasang lebih dahulu akan digunakan."
|
||||
},
|
||||
"family": {
|
||||
"pages": "Mencari halaman yang Anda atau agen buat? Ada di <go>Halaman</go>."
|
||||
@@ -731,6 +733,7 @@
|
||||
"skills": {
|
||||
"title_one": "{{count}} skill obrolan",
|
||||
"title_other": "{{count}} skill obrolan",
|
||||
"provides": "menyediakan keterampilan {{skill}}",
|
||||
"replaces": "menggantikan skill bawaan",
|
||||
"serves": "dipakai di obrolan",
|
||||
"notServing": "tidak dipakai sekarang",
|
||||
|
||||
@@ -691,7 +691,9 @@
|
||||
"installNamed": "Installa {{name}}",
|
||||
"shadowWarning": "Questo componente sostituisce lo strumento integrato {{tool}}. Un altro componente ({{name}}) lo fa già. Solo uno può essere attivo; scegli quale in Impostazioni > Strumenti. Finché non scegli, lo fornisce quello installato per primo.",
|
||||
"skillShadow": "Questo componente sostituisce la skill integrata {{skill}}.",
|
||||
"skillShadowWarning": "Questo componente sostituisce la skill integrata {{skill}}. Un altro componente ({{name}}) lo fa già. Solo uno può essere attivo; scegli quale in Impostazioni > Strumenti. Finché non scegli, lo fornisce quello installato per primo."
|
||||
"skillShadowWarning": "Questo componente sostituisce la skill integrata {{skill}}. Un altro componente ({{name}}) lo fa già. Solo uno può essere attivo; scegli quale in Impostazioni > Strumenti. Finché non scegli, lo fornisce quello installato per primo.",
|
||||
"skillProvides": "Questo componente aggiuntivo fornisce la competenza {{skill}}.",
|
||||
"skillProvidesWarning": "Questo componente aggiuntivo fornisce la competenza {{skill}}. Anche un altro componente aggiuntivo ({{name}}) la fornisce. Solo uno può essere attivo; scegli in Impostazioni > Strumenti. Senza una scelta, viene usato quello installato per primo."
|
||||
},
|
||||
"family": {
|
||||
"pages": "Cerchi le pagine create da te o da un agente? Sono in <go>Pagine</go>."
|
||||
@@ -731,6 +733,7 @@
|
||||
"skills": {
|
||||
"title_one": "{{count}} skill della chat",
|
||||
"title_other": "{{count}} skill della chat",
|
||||
"provides": "fornisce la competenza {{skill}}",
|
||||
"replaces": "sostituisce la skill integrata",
|
||||
"serves": "usata nelle chat",
|
||||
"notServing": "non usata ora",
|
||||
|
||||
@@ -691,7 +691,9 @@
|
||||
"installNamed": "{{name}} 설치",
|
||||
"shadowWarning": "이 애드온은 내장 {{tool}}을 대체합니다. 다른 애드온({{name}})이 이미 대체하고 있습니다. 하나만 활성화할 수 있으며, 설정 > 도구에서 선택합니다. 선택하기 전까지는 먼저 설치된 애드온이 제공합니다.",
|
||||
"skillShadow": "이 애드온은 기본 제공 스킬 {{skill}}을(를) 대체합니다.",
|
||||
"skillShadowWarning": "이 애드온은 기본 제공 스킬 {{skill}}을(를) 대체합니다. 다른 애드온({{name}})이 이미 대체하고 있습니다. 하나만 활성화할 수 있으며, 설정 > 도구에서 선택합니다. 선택하기 전까지는 먼저 설치된 애드온이 제공합니다."
|
||||
"skillShadowWarning": "이 애드온은 기본 제공 스킬 {{skill}}을(를) 대체합니다. 다른 애드온({{name}})이 이미 대체하고 있습니다. 하나만 활성화할 수 있으며, 설정 > 도구에서 선택합니다. 선택하기 전까지는 먼저 설치된 애드온이 제공합니다.",
|
||||
"skillProvides": "이 애드온은 {{skill}} 스킬을 제공합니다.",
|
||||
"skillProvidesWarning": "이 애드온은 {{skill}} 스킬을 제공합니다. 다른 애드온({{name}})도 제공합니다. 하나만 활성화할 수 있습니다. 설정 > 도구에서 선택하세요. 선택하지 않으면 먼저 설치된 애드온이 사용됩니다."
|
||||
},
|
||||
"family": {
|
||||
"pages": "본인이나 에이전트가 만든 페이지를 찾으시나요? <go>페이지</go>에 있습니다."
|
||||
@@ -731,6 +733,7 @@
|
||||
"skills": {
|
||||
"title_one": "채팅 스킬 {{count}}개",
|
||||
"title_other": "채팅 스킬 {{count}}개",
|
||||
"provides": "{{skill}} 스킬 제공",
|
||||
"replaces": "기본 제공 스킬을 대체",
|
||||
"serves": "채팅에서 사용 중",
|
||||
"notServing": "현재 사용 안 함",
|
||||
|
||||
@@ -691,7 +691,9 @@
|
||||
"installNamed": "Instalar {{name}}",
|
||||
"shadowWarning": "Este complemento substitui o {{tool}} integrado. Outro complemento ({{name}}) já faz isso. Só um pode estar ativo; você escolhe qual em Configurações > Ferramentas. Até você escolher, o que foi instalado primeiro o fornece.",
|
||||
"skillShadow": "Este complemento substitui a habilidade integrada {{skill}}.",
|
||||
"skillShadowWarning": "Este complemento substitui a habilidade integrada {{skill}}. Outro complemento ({{name}}) já faz isso. Só um pode estar ativo; você escolhe qual em Configurações > Ferramentas. Até você escolher, o que foi instalado primeiro o fornece."
|
||||
"skillShadowWarning": "Este complemento substitui a habilidade integrada {{skill}}. Outro complemento ({{name}}) já faz isso. Só um pode estar ativo; você escolhe qual em Configurações > Ferramentas. Até você escolher, o que foi instalado primeiro o fornece.",
|
||||
"skillProvides": "Este complemento fornece a habilidade {{skill}}.",
|
||||
"skillProvidesWarning": "Este complemento fornece a habilidade {{skill}}. Outro complemento ({{name}}) também a fornece. Apenas um pode estar ativo; escolha em Configurações > Ferramentas. Sem uma escolha, o instalado primeiro será usado."
|
||||
},
|
||||
"family": {
|
||||
"pages": "Procurando páginas que você ou um agente criou? Elas estão em <go>Páginas</go>."
|
||||
@@ -731,6 +733,7 @@
|
||||
"skills": {
|
||||
"title_one": "{{count}} habilidade de chat",
|
||||
"title_other": "{{count}} habilidades de chat",
|
||||
"provides": "fornece a habilidade {{skill}}",
|
||||
"replaces": "substitui a habilidade integrada",
|
||||
"serves": "usada nos chats",
|
||||
"notServing": "não está em uso agora",
|
||||
|
||||
@@ -691,7 +691,9 @@
|
||||
"installNamed": "安装 {{name}}",
|
||||
"shadowWarning": "此插件会替换内置的 {{tool}}。另一个插件({{name}})已经替换了它。只能有一个生效;你可以在 设置 > 工具 中选择。 在你选择之前,由最先安装的插件提供。",
|
||||
"skillShadow": "此插件会替换内置技能 {{skill}}。",
|
||||
"skillShadowWarning": "此插件会替换内置技能 {{skill}}。另一个插件({{name}})已经替换了它。只能有一个生效;你可以在 设置 > 工具 中选择。 在你选择之前,由最先安装的插件提供。"
|
||||
"skillShadowWarning": "此插件会替换内置技能 {{skill}}。另一个插件({{name}})已经替换了它。只能有一个生效;你可以在 设置 > 工具 中选择。 在你选择之前,由最先安装的插件提供。",
|
||||
"skillProvides": "此插件提供 {{skill}} 技能。",
|
||||
"skillProvidesWarning": "此插件提供 {{skill}} 技能。另一个插件({{name}})也提供此技能。只能启用一个;请在设置 > 工具中选择。如果未选择,则使用最先安装的插件。"
|
||||
},
|
||||
"family": {
|
||||
"pages": "在找你或智能体创建的页面?它们在<go>页面</go>中。"
|
||||
@@ -731,6 +733,7 @@
|
||||
"skills": {
|
||||
"title_one": "{{count}} 个聊天技能",
|
||||
"title_other": "{{count}} 个聊天技能",
|
||||
"provides": "提供 {{skill}} 技能",
|
||||
"replaces": "替换内置技能",
|
||||
"serves": "在聊天中使用",
|
||||
"notServing": "当前未使用",
|
||||
|
||||
@@ -8,10 +8,11 @@ import { createHostSettingsClient } from '../../utils/hostSettingsClient'
|
||||
import { createAddonsApi } from '../../utils/addonsApi'
|
||||
import { apiUrl } from '../../utils/basePath'
|
||||
import { useHostSettings } from '../../hooks/useHostSettings'
|
||||
import { skillDeclarationLabel } from '../../utils/chatSkills'
|
||||
import { skillsOf } from './addonState'
|
||||
|
||||
// The skills an add-on ships, in its details: each name, and whether it
|
||||
// replaces the built-in skill of that name. For an administrator, a skill that
|
||||
// provides a document slot or replaces a remaining built-in. For an administrator, a skill that
|
||||
// several add-ons replace has a switch: on, this add-on serves it in the
|
||||
// chats; off, the next add-on that replaces it does. The choice is the pin of
|
||||
// Settings > Tools (chats_tool_providers), so both places show the same.
|
||||
@@ -79,7 +80,7 @@ function SkillItem({ skill, app, row, busy, onChoose }) {
|
||||
<Icon name="book" aria-hidden="true" />
|
||||
<span className="ad-skill__text">
|
||||
<span className="dk-mono">{skill.name}</span>
|
||||
{skill.replaces && <span className="ad-quiet"> · {t('skills.replaces', { skill: skill.name })}</span>}
|
||||
{skill.replaces && <span className="ad-quiet"> · {t(`skills.${skillDeclarationLabel(skill)}`, { skill: skill.name })}</span>}
|
||||
{row && !several && <span className="ad-quiet"> · {serves ? t('skills.serves') : t('skills.notServing')}</span>}
|
||||
</span>
|
||||
{several && (
|
||||
|
||||
@@ -7,6 +7,7 @@ import Button from '../ui/Button'
|
||||
import { pushLayer } from '../../utils/modalLayers'
|
||||
import { EntryAdds, UnknownNotice } from './AddonBits'
|
||||
import { shortDigest, skillShadowNotes } from './addonState'
|
||||
import { skillInstallNoticeKey } from '../../utils/chatSkills'
|
||||
import { describeOutcome } from './errors'
|
||||
import Callout from '../ui/Callout'
|
||||
|
||||
@@ -90,7 +91,7 @@ export default function InstallDialog({ entry, flow, actions, onClose, installed
|
||||
))}
|
||||
{skillShadowNotes(entry, installed).map(c => (
|
||||
<Callout key={c.skill} tone={c.name ? 'warn' : 'info'} testId="install-skill-warning" data-skill={c.skill}>
|
||||
{t(c.name ? 'flow.skillShadowWarning' : 'flow.skillShadow', { skill: c.skill, name: c.name })}
|
||||
{t(skillInstallNoticeKey(c), { skill: c.skill, name: c.name })}
|
||||
</Callout>
|
||||
))}
|
||||
<dl className="dk-kv">
|
||||
|
||||
@@ -112,7 +112,7 @@ function SkillRow({ skill, onSet, testId }) {
|
||||
return (
|
||||
<SwitchRow
|
||||
name={skill.name}
|
||||
desc={desc ? skill.description : ''}
|
||||
desc={skill.unavailable || (desc ? skill.description : '')}
|
||||
meta={source}
|
||||
metaTestId={`${testId}-source`}
|
||||
metaKind={src.kind}
|
||||
|
||||
+12
@@ -66,3 +66,15 @@ export function fallbackNotice(skills) {
|
||||
if (on.length === 0) return null
|
||||
return { skills: on.map((s) => s.name), addons: [...new Set(on.map((s) => s.fallback))] }
|
||||
}
|
||||
|
||||
// These stable names are provider slots; none has a core implementation.
|
||||
export function skillDeclarationLabel(skill) {
|
||||
if (!skill.replaces) return null
|
||||
return ['docx', 'pptx', 'pdf', 'xlsx'].includes(skill.name) ? 'provides' : 'replaces'
|
||||
}
|
||||
|
||||
// Only document slots lack a core fallback; other shadows still replace one.
|
||||
export function skillInstallNoticeKey({ skill, name }) {
|
||||
const provides = skillDeclarationLabel({ name: skill, replaces: true }) === 'provides'
|
||||
return `flow.${provides ? 'skillProvides' : 'skillShadow'}${name ? 'Warning' : ''}`
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import {
|
||||
SEARCH_MIN, changedIds, fallbackNotice, filterSkills, offList, pickerSkills, revertSkills, skillCounts, skillKey, skillSource, withSkillsSet,
|
||||
skillDeclarationLabel, skillInstallNoticeKey, SEARCH_MIN, changedIds, fallbackNotice, filterSkills, offList, pickerSkills, revertSkills, skillCounts, skillKey, skillSource, withSkillsSet,
|
||||
} from '../../src/utils/chatSkills.js'
|
||||
|
||||
const skills = [
|
||||
@@ -50,15 +50,15 @@ test('chat skills: a failed request puts back its own ids only', () => {
|
||||
|
||||
test('chat skills: an add-on skill wins, and the built-in one it replaces is listed apart', () => {
|
||||
const list = [
|
||||
{ id: 'addon:xlsx', name: 'xlsx', layer: 'addon', addon: 'office', addon_title: 'Office', enabled: true },
|
||||
{ id: 'builtin:xlsx', name: 'xlsx', layer: 'builtin', shadowed: 'addon', shadowed_by: 'office', enabled: true },
|
||||
{ id: 'builtin:docx', name: 'docx', layer: 'builtin', fallback: 'Office', enabled: true },
|
||||
{ id: 'addon:writing', name: 'writing', layer: 'addon', addon: 'office', addon_title: 'Office', enabled: true },
|
||||
{ id: 'builtin:writing', name: 'writing', layer: 'builtin', shadowed: 'addon', shadowed_by: 'office', enabled: true },
|
||||
{ id: 'builtin:apps', name: 'apps', layer: 'builtin', fallback: 'Office', enabled: true },
|
||||
{ id: 'personal:docx', name: 'docx', layer: 'personal', shadowed: 'x', enabled: true },
|
||||
{ id: 'addon:bad', name: 'bad', layer: 'addon', invalid: 'no name', enabled: true },
|
||||
]
|
||||
const picked = pickerSkills(list)
|
||||
assert.deepEqual(picked.skills.map(skillKey), ['addon:xlsx', 'builtin:docx'])
|
||||
assert.deepEqual(picked.replaced.map(skillKey), ['builtin:xlsx'])
|
||||
assert.deepEqual(picked.skills.map(skillKey), ['addon:writing', 'builtin:apps'])
|
||||
assert.deepEqual(picked.replaced.map(skillKey), ['builtin:writing'])
|
||||
assert.deepEqual(pickerSkills(undefined), { skills: [], replaced: [] })
|
||||
})
|
||||
|
||||
@@ -71,9 +71,51 @@ test('chat skills: the source of a row is the add-on title or the layer', () =>
|
||||
test('chat skills: one notice names the built-in skills that serve for an add-on', () => {
|
||||
assert.equal(fallbackNotice([{ layer: 'builtin', name: 'xlsx', enabled: true }]), null)
|
||||
const n = fallbackNotice([
|
||||
{ layer: 'builtin', name: 'xlsx', fallback: 'Office', enabled: true },
|
||||
{ layer: 'builtin', name: 'docx', fallback: 'Office', enabled: true },
|
||||
{ layer: 'builtin', name: 'writing', fallback: 'Office', enabled: true },
|
||||
{ layer: 'builtin', name: 'apps', fallback: 'Office', enabled: true },
|
||||
{ layer: 'builtin', name: 'pdf', fallback: 'Office', enabled: false },
|
||||
])
|
||||
assert.deepEqual(n, { skills: ['xlsx', 'docx'], addons: ['Office'] })
|
||||
assert.deepEqual(n, { skills: ['writing', 'apps'], addons: ['Office'] })
|
||||
})
|
||||
|
||||
// Document slots have providers, not a removed core implementation. Ordinary
|
||||
// replacements still describe and retain their existing built-in fallback.
|
||||
test('document declarations use provider-neutral labels, remaining built-ins use replacement labels', () => {
|
||||
for (const name of ['docx', 'pptx', 'pdf', 'xlsx']) {
|
||||
assert.equal(skillDeclarationLabel({ name, replaces: true }), 'provides')
|
||||
}
|
||||
assert.equal(skillDeclarationLabel({ name: 'writing', replaces: true }), 'replaces')
|
||||
assert.equal(skillDeclarationLabel({ name: 'custom', replaces: false }), null)
|
||||
})
|
||||
|
||||
test('document provider states never invent a built-in or fallback', () => {
|
||||
for (const name of ['docx', 'pptx', 'pdf', 'xlsx']) {
|
||||
for (const provider of ['office', 'sandbox']) {
|
||||
for (const state of [{ enabled: true }, { enabled: false }, { enabled: true, unavailable: 'pinned provider unavailable' }]) {
|
||||
const row = { id: `addon:${name}`, name, layer: 'addon', addon: provider, ...state }
|
||||
const picked = pickerSkills([row])
|
||||
assert.deepEqual(picked, { skills: [row], replaced: [] })
|
||||
assert.equal(fallbackNotice(picked.skills), null)
|
||||
assert.deepEqual(skillSource(row), { kind: 'addon', name: provider })
|
||||
}
|
||||
}
|
||||
}
|
||||
assert.deepEqual(pickerSkills([]), { skills: [], replaced: [] })
|
||||
})
|
||||
|
||||
test('install document notices use flow provider keys and retain built-in replacement notices', async () => {
|
||||
const { readFile } = await import('node:fs/promises')
|
||||
const en = JSON.parse(await readFile(new URL('../../public/locales/en/addons.json', import.meta.url)))
|
||||
assert.equal(en.flow.skillProvides, 'This add-on provides the {{skill}} skill.')
|
||||
assert.match(en.flow.skillProvidesWarning, /Another add-on/)
|
||||
assert.match(en.flow.skillShadow, /built-in/)
|
||||
assert.equal(en.skills.skillShadow, undefined)
|
||||
const source = await readFile(new URL('../../src/components/addons/InstallDialog.jsx', import.meta.url), 'utf8')
|
||||
assert.match(source, /skillInstallNoticeKey\(c\)/)
|
||||
for (const skill of ['docx', 'pptx', 'pdf', 'xlsx']) {
|
||||
assert.equal(skillInstallNoticeKey({ skill }), 'flow.skillProvides')
|
||||
assert.equal(skillInstallNoticeKey({ skill, name: 'Office' }), 'flow.skillProvidesWarning')
|
||||
}
|
||||
assert.equal(skillInstallNoticeKey({ skill: 'writing' }), 'flow.skillShadow')
|
||||
assert.equal(skillInstallNoticeKey({ skill: 'writing', name: 'Other' }), 'flow.skillShadowWarning')
|
||||
})
|
||||
@@ -23,9 +23,14 @@ import (
|
||||
|
||||
"github.com/mudler/LocalAI/core/services/addons/catalog"
|
||||
"github.com/mudler/LocalAI/core/services/addons/packages"
|
||||
"github.com/mudler/LocalAI/core/services/studio/files"
|
||||
"github.com/mudler/LocalAI/core/services/studio/workspace/blob"
|
||||
"github.com/mudler/LocalAI/core/services/studio/workspace/gormstore"
|
||||
"github.com/mudler/LocalAI/pkg/addons/contract"
|
||||
"github.com/mudler/LocalAI/pkg/sqlitedb"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func TestLifecycle(t *testing.T) {
|
||||
@@ -693,6 +698,112 @@ var _ = Describe("the skills of a package", func() {
|
||||
Expect(ids).To(BeEmpty())
|
||||
})
|
||||
|
||||
It("installs upgrades and uninstalls the actual Sandbox document skills through verified receipts", func() {
|
||||
// Keep the existing sample lifecycle transport/executable fixture; use the
|
||||
// first-party Sandbox declarations and every byte of its real skill tree.
|
||||
data, err := os.ReadFile("../../../addons/sandbox/manifest.json")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
var sandbox contract.Manifest
|
||||
Expect(json.Unmarshal(data, &sandbox)).To(Succeed())
|
||||
data, err = os.ReadFile("../../../tests/addons/fixtures/packages/manifest.json")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
var manifest contract.Manifest
|
||||
Expect(json.Unmarshal(data, &manifest)).To(Succeed())
|
||||
manifest.Capabilities.SkillDefinitions = sandbox.Capabilities.SkillDefinitions
|
||||
data, err = json.Marshal(manifest)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
tree := os.DirFS("../../../addons/sandbox/skills")
|
||||
archive := map[string][]byte{}
|
||||
Expect(fs.WalkDir(tree, ".", func(path string, entry fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if entry.IsDir() {
|
||||
return nil
|
||||
}
|
||||
body, err := fs.ReadFile(tree, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
archive["skills/"+path] = body
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
Expect(archive).NotTo(BeEmpty())
|
||||
cfg, c, installer := fixtureWithFiles(data, "", archive)
|
||||
manager := open(cfg, c, installer)
|
||||
db, err := sqlitedb.Open("file:"+filepath.Join(GinkgoT().TempDir(), "workspace.db")+"?_busy_timeout=5000&_txlock=immediate", &gorm.Config{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
raw, err := db.DB()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
DeferCleanup(raw.Close)
|
||||
blobs, err := blob.NewFS(filepath.Join(GinkgoT().TempDir(), "blobs"))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
store, err := gormstore.New(db, blobs, gormstore.Options{Admin: files.AdminPrincipal})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
materialized := files.New(store)
|
||||
Expect(materialized.EnsureHome(ctx, "alice")).To(Succeed())
|
||||
var receipts []packages.PackageReceipt
|
||||
manager.SetSkillSync(ctx, func(ctx context.Context, id string, receipt *packages.PackageReceipt) error {
|
||||
if receipt == nil {
|
||||
return materialized.RemoveAddonSkills(ctx, id)
|
||||
}
|
||||
Expect(receipt.Skills).To(HaveLen(4))
|
||||
verified, err := packages.SkillFS(*receipt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n := 0
|
||||
for _, skill := range receipt.Skills {
|
||||
var notice bool
|
||||
for _, file := range skill.Files {
|
||||
want := archive["skills/"+skill.Name+"/"+file.Path]
|
||||
Expect(want).NotTo(BeNil())
|
||||
Expect(file.Size).To(Equal(int64(len(want))))
|
||||
Expect(file.SHA256).To(Equal(fmt.Sprintf("%x", sha256.Sum256(want))))
|
||||
got, err := fs.ReadFile(verified, skill.Name+"/"+file.Path)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(got).To(Equal(want))
|
||||
n++
|
||||
notice = notice || file.Path == "notice.txt"
|
||||
}
|
||||
Expect(notice).To(BeTrue(), skill.Name)
|
||||
}
|
||||
Expect(n).To(Equal(len(archive)), "receipt must cover every actual file")
|
||||
receipts = append(receipts, *receipt)
|
||||
return materialized.SyncAddonSkills(ctx, id, verified)
|
||||
})
|
||||
check := func() {
|
||||
for _, name := range []string{"docx", "pptx", "pdf", "xlsx"} {
|
||||
_, body, err := materialized.ReadAddonSkill(ctx, "alice", "sample", name)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(body).NotTo(BeEmpty())
|
||||
}
|
||||
ids, err := materialized.AddonSkillIDs(ctx)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ids).To(Equal([]string{"sample"}))
|
||||
}
|
||||
_, err = manager.Submit(ctx, actor, command("sandbox-tree-install", "install"))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
check()
|
||||
_, err = manager.Submit(ctx, actor, command("sandbox-tree-stop", "disable"))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
_, err = manager.Submit(ctx, actor, command("sandbox-tree-upgrade", "upgrade"))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(receipts).To(HaveLen(2))
|
||||
Expect(receipts[1].Directory).NotTo(Equal(receipts[0].Directory))
|
||||
Expect(receipts[1].Skills).To(Equal(receipts[0].Skills))
|
||||
check()
|
||||
_, err = manager.Submit(ctx, actor, command("sandbox-tree-uninstall", "uninstall"))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
ids, err := materialized.AddonSkillIDs(ctx)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ids).To(BeEmpty())
|
||||
for _, name := range []string{"docx", "pptx", "pdf", "xlsx"} {
|
||||
_, _, err = materialized.ReadAddonSkill(ctx, "alice", "sample", name)
|
||||
Expect(err).To(HaveOccurred())
|
||||
}
|
||||
})
|
||||
|
||||
It("never fails the operation when the copy fails", func() {
|
||||
cfg, c, i := fixture()
|
||||
m := open(cfg, c, i)
|
||||
|
||||
@@ -68,7 +68,7 @@ type addonSkills struct {
|
||||
// off by the chat (addonsOff) and, for a chat with an agent, granted by it. An
|
||||
// add-on the broker reports as unavailable is left out. A broker that cannot
|
||||
// answer gives none and a warning; it never fails the chat.
|
||||
func (s *Service) addonSkillsFor(ctx context.Context, p string, addonsOff []string, sc *scope) (addonSkills, error) {
|
||||
func (s *Service) addonSkillsFor(ctx context.Context, p string, addonsOff []string, sc *scope, command Commands) (addonSkills, error) {
|
||||
var out addonSkills
|
||||
pins, err := s.toolPins(ctx)
|
||||
if err != nil {
|
||||
@@ -101,6 +101,10 @@ func (s *Service) addonSkillsFor(ctx context.Context, p string, addonsOff []stri
|
||||
if gate != nil && gate.Unavailable(ctx, p, set.AddonID, s.d.Files.Available()) != "" {
|
||||
continue
|
||||
}
|
||||
if set.AddonID == "sandbox" && !sandboxDocumentEligible(command) {
|
||||
set.Skills = slices.DeleteFunc(slices.Clone(set.Skills), contract.DocumentSkill)
|
||||
set.Shadows = slices.DeleteFunc(slices.Clone(set.Shadows), contract.DocumentSkill)
|
||||
}
|
||||
out.usable = append(out.usable, set)
|
||||
}
|
||||
return out, nil
|
||||
@@ -122,7 +126,7 @@ func (a addonSkills) provider(name string) (string, bool) {
|
||||
if !contract.ReplaceableSkill(name) {
|
||||
return "", false
|
||||
}
|
||||
if pin := a.pins[name]; pin != "" && shipsReplacement(a.known, pin, name) {
|
||||
if pin := a.pins[name]; pin != "" && (contract.DocumentSkill(name) || shipsReplacement(a.known, pin, name)) {
|
||||
if shipsReplacement(a.usable, pin, name) {
|
||||
return pin, true
|
||||
}
|
||||
@@ -131,7 +135,7 @@ func (a addonSkills) provider(name string) (string, bool) {
|
||||
if id := ChooseProvider(a.shippers(a.usable, name), a.installTimes(), ""); id != "" {
|
||||
return id, true
|
||||
}
|
||||
return "", false
|
||||
return "", contract.DocumentSkill(name)
|
||||
}
|
||||
|
||||
// shippers lists the add-ons of the sets that ship a replacement for name.
|
||||
|
||||
@@ -103,7 +103,7 @@ var _ = Describe("add-on skills in a chat", func() {
|
||||
It("fails the turn rather than substituting built-ins when provider policy is unavailable", func() {
|
||||
unavailable := errors.New("owner policy unavailable")
|
||||
svc.d.ToolPins = func(context.Context) (map[string]string, error) { return nil, unavailable }
|
||||
prompt, _, _, fallback, err := svc.skillTurn(ctx, "alice", nil, nil, nil, nil)
|
||||
prompt, _, _, fallback, err := svc.skillTurn(ctx, "alice", nil, nil, nil, Commands{}, nil)
|
||||
Expect(errors.Is(err, unavailable)).To(BeTrue())
|
||||
Expect(prompt).To(BeEmpty())
|
||||
Expect(fallback).To(BeEmpty())
|
||||
@@ -118,7 +118,7 @@ var _ = Describe("add-on skills in a chat", func() {
|
||||
})
|
||||
|
||||
It("offers the skills of a usable add-on, by name", func() {
|
||||
prompt, _, key, _, err := svc.skillTurn(ctx, "alice", nil, nil, nil, nil)
|
||||
prompt, _, key, _, err := svc.skillTurn(ctx, "alice", nil, nil, nil, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(prompt).To(ContainSubstring("\n- notes: Use for notes."))
|
||||
Expect(prompt).NotTo(ContainSubstring("shared-addon-skills"), "the index names no path")
|
||||
@@ -127,39 +127,39 @@ var _ = Describe("add-on skills in a chat", func() {
|
||||
})
|
||||
|
||||
It("offers nothing for an add-on the chat switched off, that stopped or that cannot work", func() {
|
||||
prompt, _, _, _, err := svc.skillTurn(ctx, "alice", nil, []string{"notes"}, nil, nil)
|
||||
prompt, _, _, _, err := svc.skillTurn(ctx, "alice", nil, []string{"notes"}, nil, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(prompt).NotTo(ContainSubstring("- notes:"), "addons_off removes the add-on's root")
|
||||
b.reasons = map[string]string{"notes": "the Files workspace is off"}
|
||||
prompt, _, _, _, err = svc.skillTurn(ctx, "alice", nil, nil, nil, nil)
|
||||
prompt, _, _, _, err = svc.skillTurn(ctx, "alice", nil, nil, nil, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(prompt).NotTo(ContainSubstring("- notes:"), "an unavailable add-on gives no skills")
|
||||
b.reasons = nil
|
||||
b.set(AddonSkillSet{AddonID: "notes", Title: "Notes", Skills: []string{"notes", "notes-quick"}}) // stopped
|
||||
prompt, _, _, _, err = svc.skillTurn(ctx, "alice", nil, nil, nil, nil)
|
||||
prompt, _, _, _, err = svc.skillTurn(ctx, "alice", nil, nil, nil, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(prompt).NotTo(ContainSubstring("- notes:"), "a stopped add-on gives no skills; the files stay")
|
||||
})
|
||||
|
||||
It("moves the refresh key when the add-on starts or stops, not on a switch", func() {
|
||||
_, _, running, _, err := svc.skillTurn(ctx, "alice", nil, nil, nil, nil)
|
||||
_, _, running, _, err := svc.skillTurn(ctx, "alice", nil, nil, nil, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
_, _, switched, _, err := svc.skillTurn(ctx, "alice", []string{"addon:notes"}, nil, nil, nil)
|
||||
_, _, switched, _, err := svc.skillTurn(ctx, "alice", []string{"addon:notes"}, nil, nil, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(switched).To(Equal(running), "a switch changed the key")
|
||||
b.set()
|
||||
_, _, stopped, _, err := svc.skillTurn(ctx, "alice", nil, nil, nil, nil)
|
||||
_, _, stopped, _, err := svc.skillTurn(ctx, "alice", nil, nil, nil, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(stopped).NotTo(Equal(running), "a stop left the key as it was")
|
||||
})
|
||||
|
||||
It("keeps an agent's grant: an add-on the agent does not grant gives no skills", func() {
|
||||
sc := &scope{addons: map[string]bool{}, skills: map[string]bool{"notes": true}}
|
||||
prompt, _, _, _, err := svc.skillTurn(ctx, "alice", nil, nil, sc, nil)
|
||||
prompt, _, _, _, err := svc.skillTurn(ctx, "alice", nil, nil, sc, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(prompt).NotTo(ContainSubstring("- notes:"))
|
||||
sc.addons["notes"] = true
|
||||
prompt, _, _, _, err = svc.skillTurn(ctx, "alice", nil, nil, sc, nil)
|
||||
prompt, _, _, _, err = svc.skillTurn(ctx, "alice", nil, nil, sc, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(prompt).To(ContainSubstring("- notes: Use for notes."))
|
||||
Expect(prompt).NotTo(ContainSubstring("notes-quick"), "the agent grants the skill notes only")
|
||||
@@ -229,7 +229,7 @@ var _ = Describe("add-on skills that replace built-in skills", func() {
|
||||
})).To(Succeed())
|
||||
})
|
||||
turn := func(off, addonsOff []string) (string, string, string) {
|
||||
prompt, _, key, fallback, err := svc.skillTurn(ctx, "alice", off, addonsOff, nil, nil)
|
||||
prompt, _, key, fallback, err := svc.skillTurn(ctx, "alice", off, addonsOff, nil, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
return prompt, key, fallback
|
||||
}
|
||||
@@ -346,16 +346,16 @@ var _ = Describe("add-on skills that replace built-in skills", func() {
|
||||
other, err := New(Deps{Store: svc.d.Store, Provider: provider.New(), StateDir: GinkgoT().TempDir(), Files: f, AddonTools: b})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
DeferCleanup(func() { _ = other.Close(ctx) })
|
||||
one, _, k1, _, err := svc.skillTurn(ctx, "alice", nil, nil, nil, nil)
|
||||
one, _, k1, _, err := svc.skillTurn(ctx, "alice", nil, nil, nil, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
two, _, k2, _, err := other.skillTurn(ctx, "alice", nil, nil, nil, nil)
|
||||
two, _, k2, _, err := other.skillTurn(ctx, "alice", nil, nil, nil, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(two).To(Equal(one))
|
||||
Expect(k2).To(Equal(k1))
|
||||
down, err := New(Deps{Store: svc.d.Store, Provider: provider.New(), StateDir: GinkgoT().TempDir(), Files: f, AddonTools: &skillBroker{}})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
DeferCleanup(func() { _ = down.Close(ctx) })
|
||||
prompt, _, _, _, err := down.skillTurn(ctx, "alice", nil, nil, nil, nil)
|
||||
prompt, _, _, _, err := down.skillTurn(ctx, "alice", nil, nil, nil, Commands{}, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(prompt).To(ContainSubstring("Built-in sheets."))
|
||||
})
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Package builtinskills holds the skills that ship with the server: the office
|
||||
// skills docx, xlsx, pptx and pdf, writing-skills, localai-workspace and localai-apps.
|
||||
// The tree is embedded in the binary and written into the built-in layer when the
|
||||
// server starts. The
|
||||
// office skills are adapted from the Feather project (MIT); the NOTICE file in
|
||||
// the tree keeps its source and licence, and must stay with them.
|
||||
// Package builtinskills holds writing-skills, localai-workspace and localai-apps.
|
||||
// The tree is embedded in the binary and synchronized into the built-in layer
|
||||
// when the server starts. Document authoring procedures belong to add-ons.
|
||||
package builtinskills
|
||||
|
||||
import (
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
"github.com/mudler/LocalAI/pkg/sqlitedb"
|
||||
)
|
||||
|
||||
var names = []string{"docx", "xlsx", "pptx", "pdf", "writing-skills", "localai-workspace", "localai-apps"}
|
||||
var names = []string{"writing-skills", "localai-workspace", "localai-apps"}
|
||||
|
||||
var _ = Describe("the built-in skills", func() {
|
||||
It("sends the model to another skill by its name, never by a path", func() {
|
||||
@@ -68,30 +68,25 @@ var _ = Describe("the built-in skills", func() {
|
||||
})
|
||||
|
||||
It("sends the helper scripts of the skills that make files to the chat's work folder", func() {
|
||||
for _, n := range []string{"docx", "xlsx", "pptx", "pdf", "localai-apps", "localai-workspace"} {
|
||||
for _, n := range []string{"localai-apps", "localai-workspace"} {
|
||||
data, err := fs.ReadFile(builtinskills.FS(), n+"/SKILL.md")
|
||||
Expect(err).NotTo(HaveOccurred(), n)
|
||||
Expect(string(data)).To(ContainSubstring("the chat's work folder that the prompt names (`/workspace/home/Chats/<chat>/work/`)"), n)
|
||||
}
|
||||
})
|
||||
|
||||
It("marks the office skills as needing command execution, and only them", func() {
|
||||
It("keeps remaining built-in skills independent of command execution", func() {
|
||||
for _, n := range names {
|
||||
data, err := fs.ReadFile(builtinskills.FS(), n+"/SKILL.md")
|
||||
Expect(err).NotTo(HaveOccurred(), n)
|
||||
switch n {
|
||||
case "docx", "xlsx", "pptx", "pdf":
|
||||
Expect(skills.Requires(data)).To(Equal([]string{skills.RequireExec}), n)
|
||||
default:
|
||||
Expect(skills.Requires(data)).To(BeEmpty(), n)
|
||||
}
|
||||
Expect(skills.Requires(data)).To(BeEmpty(), n)
|
||||
}
|
||||
})
|
||||
|
||||
It("keeps the source and the licence in the notice", func() {
|
||||
data, err := fs.ReadFile(builtinskills.FS(), "NOTICE")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
for _, want := range []string{"paper-instruments/feather-train", "b7463092af862ebbdf4c5920c4bc9ab38ab17ad9", "MIT License", "Permission is hereby granted"} {
|
||||
for _, want := range names {
|
||||
Expect(string(data)).To(ContainSubstring(want), "the NOTICE lacks %q", want)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,108 +1,5 @@
|
||||
Built-in skills of the chats
|
||||
=============================
|
||||
Built-in chat skills
|
||||
====================
|
||||
|
||||
The skills "docx", "xlsx", "pptx" and "pdf" are adapted from the skills of the
|
||||
Feather project.
|
||||
|
||||
Source: https://github.com/paper-instruments/feather-train
|
||||
(folder feather-harness/src/feather_harness/skills)
|
||||
Commit: b7463092af862ebbdf4c5920c4bc9ab38ab17ad9
|
||||
Licence: MIT, Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
What was changed: the text about LibreOffice was replaced by a note that
|
||||
LibreOffice is not installed, the text about OCR was shortened in the same way,
|
||||
and the generated page of the LibreOffice-backed module "openpyxl.oracle" got
|
||||
the same note. Each of the four got one line that says to write
|
||||
helper scripts in the chat's work folder. The skills "writing-skills" and "localai-workspace" were written
|
||||
for the chats.
|
||||
|
||||
The MIT licence of the Feather project
|
||||
--------------------------------------
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
The generated API pages
|
||||
-----------------------
|
||||
|
||||
The pages under docx/references/api, xlsx/references/api and
|
||||
pptx/references/api are generated from the docstrings of the Paper libraries
|
||||
and of the libraries that they extend. The licences of those projects apply to
|
||||
that text. All three are MIT licences.
|
||||
|
||||
paper-docx extends python-docx, and paper-pptx extends python-pptx. Steve Canny
|
||||
wrote both upstream libraries, so the two licence files of the Paper packages
|
||||
have the same text. Each applies to its own package.
|
||||
|
||||
paper-docx https://pypi.org/project/paper-docx/ (python-docx)
|
||||
paper-pptx https://pypi.org/project/paper-pptx/ (python-pptx)
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2013 Steve Canny, https://github.com/scanny
|
||||
Portions Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
paper-xlsx extends openpyxl.
|
||||
|
||||
paper-xlsx https://pypi.org/project/paper-xlsx/ (openpyxl)
|
||||
|
||||
This software is under the MIT Licence
|
||||
======================================
|
||||
|
||||
Copyright (c) 2010 openpyxl
|
||||
Portions Copyright (c) 2026 Paper Instruments, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
writing-skills, localai-workspace and localai-apps were written for LocalAI
|
||||
and are distributed under the MIT license in the project LICENSE file.
|
||||
@@ -1,17 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.api`
|
||||
|
||||
Directly exposed API functions and classes, `Document` for now.
|
||||
|
||||
## `Document`
|
||||
|
||||
```python
|
||||
Document(docx: str | IO[bytes] | None = None) -> DocumentObject
|
||||
```
|
||||
|
||||
Return a `Document` object loaded from `docx`, where `docx` can be either a path
|
||||
to a ``.docx`` file (a string) or a file-like object.
|
||||
|
||||
If `docx` is missing or ``None``, the built-in default document "template" is
|
||||
loaded.
|
||||
@@ -1,79 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.blkcntnr`
|
||||
|
||||
Block item container, used by body, cell, header, etc.
|
||||
|
||||
## `BlockItemContainer`
|
||||
|
||||
```python
|
||||
BlockItemContainer(element: BlockItemElement, parent: t.ProvidesStoryPart)
|
||||
```
|
||||
|
||||
Bases: `StoryChild`
|
||||
|
||||
Base class for proxy objects that can contain block items.
|
||||
|
||||
These containers include _Body, _Cell, header, footer, footnote, endnote, comment,
|
||||
and text box objects. Provides the shared functionality to add a block item like a
|
||||
paragraph or table.
|
||||
|
||||
### `add_paragraph`
|
||||
|
||||
```python
|
||||
add_paragraph(text: str = '', style: str | ParagraphStyle | None = None) -> Paragraph
|
||||
```
|
||||
|
||||
Return paragraph newly added to the end of the content in this container.
|
||||
|
||||
The paragraph has `text` in a single run if present, and is given paragraph
|
||||
style `style`.
|
||||
|
||||
If `style` is `None`, no paragraph style is applied, which has the same effect
|
||||
as applying the 'Normal' style.
|
||||
|
||||
### `add_table`
|
||||
|
||||
```python
|
||||
add_table(rows: int, cols: int, width: Length) -> Table
|
||||
```
|
||||
|
||||
Return table of `width` having `rows` rows and `cols` columns.
|
||||
|
||||
The table is appended appended at the end of the content in this container.
|
||||
|
||||
`width` is evenly distributed between the table columns.
|
||||
|
||||
### `iter_inner_content`
|
||||
|
||||
```python
|
||||
iter_inner_content() -> Iterator[Paragraph | Table]
|
||||
```
|
||||
|
||||
Generate each `Paragraph` or `Table` in this container in document order.
|
||||
|
||||
### `paragraphs`
|
||||
|
||||
```python
|
||||
paragraphs
|
||||
```
|
||||
|
||||
A list containing the paragraphs in this container, in document order.
|
||||
|
||||
Read-only.
|
||||
|
||||
### `tables`
|
||||
|
||||
```python
|
||||
tables
|
||||
```
|
||||
|
||||
A list containing the tables in this container, in document order.
|
||||
|
||||
Read-only.
|
||||
|
||||
## `BlockItemElement`
|
||||
|
||||
```python
|
||||
BlockItemElement: TypeAlias = 'CT_Body | CT_Comment | CT_HdrFtr | CT_Tc'
|
||||
```
|
||||
@@ -1,216 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.blocks`
|
||||
|
||||
Anchor-relative block operations and clause-level redlines (paper-docx).
|
||||
|
||||
## `BlockEditResult`
|
||||
|
||||
```python
|
||||
BlockEditResult(story: str, inserted_blocks: int, deleted_blocks: int, deleted_text: Tuple[str, ...], revision_ids: Tuple[int, ...]) -> None
|
||||
```
|
||||
|
||||
Outcome of a block-level edit.
|
||||
|
||||
### `deleted_blocks`
|
||||
|
||||
```python
|
||||
deleted_blocks: int
|
||||
```
|
||||
|
||||
### `deleted_text`
|
||||
|
||||
```python
|
||||
deleted_text: Tuple[str, ...]
|
||||
```
|
||||
|
||||
### `inserted_blocks`
|
||||
|
||||
```python
|
||||
inserted_blocks: int
|
||||
```
|
||||
|
||||
### `revision_ids`
|
||||
|
||||
```python
|
||||
revision_ids: Tuple[int, ...]
|
||||
```
|
||||
|
||||
### `story`
|
||||
|
||||
```python
|
||||
story: str
|
||||
```
|
||||
|
||||
### `to_dict`
|
||||
|
||||
```python
|
||||
to_dict() -> dict
|
||||
```
|
||||
|
||||
## `BlockTarget`
|
||||
|
||||
```python
|
||||
BlockTarget = Union[str, Block, Span]
|
||||
```
|
||||
|
||||
## `ListBlock`
|
||||
|
||||
```python
|
||||
ListBlock(items: Sequence[str], kind: str = 'bullet', level: int = 0) -> None
|
||||
```
|
||||
|
||||
A real bullet/decimal list (backed by a real numbering definition).
|
||||
|
||||
### `items`
|
||||
|
||||
```python
|
||||
items: Sequence[str]
|
||||
```
|
||||
|
||||
### `kind`
|
||||
|
||||
```python
|
||||
kind: str = 'bullet'
|
||||
```
|
||||
|
||||
### `level`
|
||||
|
||||
```python
|
||||
level: int = 0
|
||||
```
|
||||
|
||||
## `RichParagraph`
|
||||
|
||||
```python
|
||||
RichParagraph(runs: Sequence[TextRun], style: Optional[str] = None) -> None
|
||||
```
|
||||
|
||||
A paragraph built from styled runs.
|
||||
|
||||
### `runs`
|
||||
|
||||
```python
|
||||
runs: Sequence[TextRun]
|
||||
```
|
||||
|
||||
### `style`
|
||||
|
||||
```python
|
||||
style: Optional[str] = None
|
||||
```
|
||||
|
||||
## `TableBlock`
|
||||
|
||||
```python
|
||||
TableBlock(rows: Sequence[Sequence[str]]) -> None
|
||||
```
|
||||
|
||||
A simple rectangular table of plain-text cells.
|
||||
|
||||
### `rows`
|
||||
|
||||
```python
|
||||
rows: Sequence[Sequence[str]]
|
||||
```
|
||||
|
||||
## `TextRun`
|
||||
|
||||
```python
|
||||
TextRun(text: str, bold: bool = False, italic: bool = False) -> None
|
||||
```
|
||||
|
||||
One run of a rich paragraph.
|
||||
|
||||
### `bold`
|
||||
|
||||
```python
|
||||
bold: bool = False
|
||||
```
|
||||
|
||||
### `italic`
|
||||
|
||||
```python
|
||||
italic: bool = False
|
||||
```
|
||||
|
||||
### `text`
|
||||
|
||||
```python
|
||||
text: str
|
||||
```
|
||||
|
||||
## `check_install`
|
||||
|
||||
```python
|
||||
check_install() -> None
|
||||
```
|
||||
|
||||
Refuse when paper-docx and python-docx are both installed.
|
||||
|
||||
## `insert_blocks_after`
|
||||
|
||||
```python
|
||||
insert_blocks_after(document: 'Document', anchor: BlockTarget, *, blocks: 'Sequence[object]', tracked: bool = False, author: Optional[str] = None, date: Optional[dt.datetime] = None) -> BlockEditResult
|
||||
```
|
||||
|
||||
Insert a typed block list after `anchor`, and return a `BlockEditResult`.
|
||||
|
||||
`blocks` mixes `RichParagraph` (styled runs), `ListBlock` (real bullet or decimal lists,
|
||||
numbering definition created on demand) and `TableBlock` (rectangular tables). Reach for
|
||||
this when you want structure rather than raw XML. Refuses a protected document, and an
|
||||
anchor that is missing, ambiguous, foreign, stale, or spans more than one paragraph.
|
||||
|
||||
## `insert_section_after`
|
||||
|
||||
```python
|
||||
insert_section_after(document: 'Document', anchor: BlockTarget, *, heading: str, paragraphs: Sequence[str], heading_style: str = 'Heading2', body_style: Optional[str] = None, tracked: bool = False, author: Optional[str] = None, date: Optional[dt.datetime] = None) -> BlockEditResult
|
||||
```
|
||||
|
||||
Insert a heading plus body paragraphs after `anchor`, and return a `BlockEditResult`.
|
||||
|
||||
With `tracked=True` each inserted paragraph is a real Word insertion attributed to
|
||||
`author` (required) and `date`. Refuses a protected document, an undefined heading
|
||||
style, and an anchor that is missing, ambiguous, foreign, stale, or spans
|
||||
more than one paragraph.
|
||||
|
||||
## `require_anchor_owner`
|
||||
|
||||
```python
|
||||
require_anchor_owner(document: 'Document', anchor: object, *, argument: str = 'anchor') -> None
|
||||
```
|
||||
|
||||
Check ownership for live anchor forms; value/string anchors are inert.
|
||||
|
||||
## `rollback_on_error`
|
||||
|
||||
```python
|
||||
rollback_on_error(document: 'Document', *participants: Any) -> Generator[None, None, None]
|
||||
```
|
||||
|
||||
Restore the live package and named mutable proxies after an error.
|
||||
|
||||
## `tracked_delete_paragraphs`
|
||||
|
||||
```python
|
||||
tracked_delete_paragraphs(document: 'Document', start_anchor: BlockTarget, *, end_anchor: Optional[BlockTarget] = None, count: int = 1, author: str, date: Optional[dt.datetime] = None) -> BlockEditResult
|
||||
```
|
||||
|
||||
Mark a paragraph range deleted with real tracked changes; returns a `BlockEditResult`.
|
||||
|
||||
Runs move into `w:del` with formatting intact and the paragraph mark is stamped, so
|
||||
accepting removes the paragraphs and rejecting restores them exactly. Refuses a
|
||||
protected document, an endpoint spanning multiple paragraphs, a range
|
||||
crossing stories or parents, a bookmarked or non-plain run, and an open field.
|
||||
|
||||
## `tracked_replace_paragraphs`
|
||||
|
||||
```python
|
||||
tracked_replace_paragraphs(document: 'Document', start_anchor: BlockTarget, replacement_paragraphs: Sequence[str], *, end_anchor: Optional[BlockTarget] = None, count: int = 1, body_style: Optional[str] = None, author: str, date: Optional[dt.datetime] = None) -> BlockEditResult
|
||||
```
|
||||
|
||||
Tracked-delete a paragraph range and tracked-insert replacements after it.
|
||||
|
||||
Returns a `BlockEditResult`. Replacements land after the last deleted paragraph. Carries
|
||||
the same refusals as `tracked_delete_paragraphs`: protection, a multi-paragraph
|
||||
endpoint, a range crossing stories, bookmarked or non-plain runs, an open field.
|
||||
@@ -1,134 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.bookmarks`
|
||||
|
||||
Bookmark enumeration, creation, and deletion.
|
||||
|
||||
## `BookmarkInfo`
|
||||
|
||||
```python
|
||||
BookmarkInfo(name: str, bookmark_id: int, story: str, text: str) -> None
|
||||
```
|
||||
|
||||
One bookmark: its name, id, story, and the visible text it wraps.
|
||||
|
||||
### `bookmark_id`
|
||||
|
||||
```python
|
||||
bookmark_id: int
|
||||
```
|
||||
|
||||
### `is_point`
|
||||
|
||||
```python
|
||||
is_point: bool
|
||||
```
|
||||
|
||||
### `name`
|
||||
|
||||
```python
|
||||
name: str
|
||||
```
|
||||
|
||||
### `story`
|
||||
|
||||
```python
|
||||
story: str
|
||||
```
|
||||
|
||||
### `text`
|
||||
|
||||
```python
|
||||
text: str
|
||||
```
|
||||
|
||||
### `to_dict`
|
||||
|
||||
```python
|
||||
to_dict() -> dict
|
||||
```
|
||||
|
||||
## `DEL_TEXT`
|
||||
|
||||
```python
|
||||
DEL_TEXT = qn('w:delText')
|
||||
```
|
||||
|
||||
## `INSTR_TEXT`
|
||||
|
||||
```python
|
||||
INSTR_TEXT = qn('w:instrText')
|
||||
```
|
||||
|
||||
## `check_install`
|
||||
|
||||
```python
|
||||
check_install() -> None
|
||||
```
|
||||
|
||||
Refuse when paper-docx and python-docx are both installed.
|
||||
|
||||
## `create_bookmark`
|
||||
|
||||
```python
|
||||
create_bookmark(document: 'Document', span: 'Span', name: str) -> BookmarkInfo
|
||||
```
|
||||
|
||||
Bookmark exactly `span`'s text under `name`, and return its `BookmarkInfo`.
|
||||
|
||||
Use this to give a span a stable target that survives later edits; cross-references and
|
||||
`add_reference_field` ride on bookmarks. Splits boundary runs so the markers wrap the
|
||||
span's characters exactly. Refuses a protected document, a foreign or stale span, and a
|
||||
name Word rejects or the document already uses.
|
||||
|
||||
## `delete_bookmark`
|
||||
|
||||
```python
|
||||
delete_bookmark(document: 'Document', name: str) -> None
|
||||
```
|
||||
|
||||
Remove `name`'s markers, leaving the text in place.
|
||||
|
||||
Use this to retire a bookmark without touching content. Refuses while a field
|
||||
instruction still references the name, since a dangling REF renders "Error! Reference
|
||||
source not found." in Word. Refuses a protected document and an unknown name.
|
||||
|
||||
## `is_direct_run_child`
|
||||
|
||||
```python
|
||||
is_direct_run_child(element: '_Element') -> bool
|
||||
```
|
||||
|
||||
Whether ``element`` is a direct child of a ``w:r`` element.
|
||||
|
||||
## `list_bookmarks`
|
||||
|
||||
```python
|
||||
list_bookmarks(document: 'Document') -> 'List[BookmarkInfo]'
|
||||
```
|
||||
|
||||
Every bookmark across every story, in document order.
|
||||
|
||||
## `project_run_child`
|
||||
|
||||
```python
|
||||
project_run_child(element: '_Element') -> RunChildProjection
|
||||
```
|
||||
|
||||
Return the conservative text projection for a direct ``w:r`` child.
|
||||
|
||||
## `require_span_owner`
|
||||
|
||||
```python
|
||||
require_span_owner(document: 'Document', span: 'Span', *, argument: str = 'span') -> None
|
||||
```
|
||||
|
||||
Refuse a live span captured from a different document package.
|
||||
|
||||
## `rollback_on_error`
|
||||
|
||||
```python
|
||||
rollback_on_error(document: 'Document', *participants: Any) -> Generator[None, None, None]
|
||||
```
|
||||
|
||||
Restore the live package and named mutable proxies after an error.
|
||||
@@ -1,173 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.commentops`
|
||||
|
||||
Comment thread operations: anchored text, replies, resolution.
|
||||
|
||||
## `COMMENTS_EXTENDED_CONTENT_TYPE`
|
||||
|
||||
```python
|
||||
COMMENTS_EXTENDED_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml'
|
||||
```
|
||||
|
||||
## `COMMENTS_EXTENDED_RELATIONSHIP_TYPE`
|
||||
|
||||
```python
|
||||
COMMENTS_EXTENDED_RELATIONSHIP_TYPE = 'http://schemas.microsoft.com/office/2011/relationships/commentsExtended'
|
||||
```
|
||||
|
||||
## `COMMENTS_EXTENSIBLE_CONTENT_TYPE`
|
||||
|
||||
```python
|
||||
COMMENTS_EXTENSIBLE_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtensible+xml'
|
||||
```
|
||||
|
||||
## `COMMENTS_EXTENSIBLE_RELATIONSHIP_TYPE`
|
||||
|
||||
```python
|
||||
COMMENTS_EXTENSIBLE_RELATIONSHIP_TYPE = 'http://schemas.microsoft.com/office/2018/08/relationships/commentsExtensible'
|
||||
```
|
||||
|
||||
## `COMMENTS_IDS_CONTENT_TYPE`
|
||||
|
||||
```python
|
||||
COMMENTS_IDS_CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.commentsIds+xml'
|
||||
```
|
||||
|
||||
## `COMMENTS_IDS_RELATIONSHIP_TYPE`
|
||||
|
||||
```python
|
||||
COMMENTS_IDS_RELATIONSHIP_TYPE = 'http://schemas.microsoft.com/office/2016/09/relationships/commentsIds'
|
||||
```
|
||||
|
||||
## `DEL_TEXT`
|
||||
|
||||
```python
|
||||
DEL_TEXT = qn('w:delText')
|
||||
```
|
||||
|
||||
## `INSTR_TEXT`
|
||||
|
||||
```python
|
||||
INSTR_TEXT = qn('w:instrText')
|
||||
```
|
||||
|
||||
## `anchored_text`
|
||||
|
||||
```python
|
||||
anchored_text(document: 'Document', comment: 'Comment') -> str
|
||||
```
|
||||
|
||||
The document text `comment` is anchored to, taken from its range marks.
|
||||
|
||||
Refuses a stale or foreign comment, and a comment whose range marks are missing or
|
||||
crossed.
|
||||
|
||||
## `check_install`
|
||||
|
||||
```python
|
||||
check_install() -> None
|
||||
```
|
||||
|
||||
Refuse when paper-docx and python-docx are both installed.
|
||||
|
||||
## `comment_thread`
|
||||
|
||||
```python
|
||||
comment_thread(document: 'Document') -> Tuple[dict, ...]
|
||||
```
|
||||
|
||||
Every comment with its thread state: id, author, text, resolved, parent id, and anchored
|
||||
text where available.
|
||||
|
||||
Use it to read a whole discussion in one pass rather than walking replies. Refuses a
|
||||
stale comment and a malformed `commentsExtended` part.
|
||||
|
||||
## `delete_comment`
|
||||
|
||||
```python
|
||||
delete_comment(document: 'Document', comment: 'Comment') -> None
|
||||
```
|
||||
|
||||
Delete `comment` and its replies, removing their range marks from the text.
|
||||
|
||||
Refuses a protected document, a stale or foreign comment, and a comments part that is
|
||||
missing or ambiguous.
|
||||
|
||||
## `is_direct_run_child`
|
||||
|
||||
```python
|
||||
is_direct_run_child(element: '_Element') -> bool
|
||||
```
|
||||
|
||||
Whether ``element`` is a direct child of a ``w:r`` element.
|
||||
|
||||
## `is_resolved`
|
||||
|
||||
```python
|
||||
is_resolved(document: 'Document', comment: 'Comment') -> bool
|
||||
```
|
||||
|
||||
Whether `comment`'s thread is marked resolved.
|
||||
|
||||
Reads `commentsExtended`, where Word keeps resolution state. Refuses a stale or foreign
|
||||
comment, and a malformed `commentsExtended` part.
|
||||
|
||||
## `parent_of`
|
||||
|
||||
```python
|
||||
parent_of(document: 'Document', comment: 'Comment') -> Optional[int]
|
||||
```
|
||||
|
||||
The comment `comment` replies to, or None when it starts a thread.
|
||||
|
||||
Refuses a stale or foreign comment, and a malformed `commentsExtended` part.
|
||||
|
||||
## `project_run_child`
|
||||
|
||||
```python
|
||||
project_run_child(element: '_Element') -> RunChildProjection
|
||||
```
|
||||
|
||||
Return the conservative text projection for a direct ``w:r`` child.
|
||||
|
||||
## `reply`
|
||||
|
||||
```python
|
||||
reply(document: 'Document', comment: 'Comment', text: str, *, author: str, initials: Optional[str] = None, date: Optional[dt.datetime] = None) -> 'Comment'
|
||||
```
|
||||
|
||||
Add a threaded reply to `comment` and return the new `Comment`.
|
||||
|
||||
The reply gets its own comment-range start, range end, and reference around the same
|
||||
selected text. Its `w15:paraIdParent` names the parent's final comment-body paragraph; the
|
||||
reply does not reuse the parent's marker id. Creates `commentsExtended` on first use, since
|
||||
Word keeps threading outside `w:comment`. Refuses a protected document, a stale or foreign
|
||||
comment, and a comments part that is missing or ambiguous.
|
||||
|
||||
## `require_comment_owner`
|
||||
|
||||
```python
|
||||
require_comment_owner(document: 'Document', comment: 'Comment', *, argument: str = 'comment') -> None
|
||||
```
|
||||
|
||||
Refuse a comment proxy from another part and detect detached proxies.
|
||||
|
||||
## `resolve`
|
||||
|
||||
```python
|
||||
resolve(document: 'Document', comment: 'Comment', *, resolved: bool = True) -> None
|
||||
```
|
||||
|
||||
Mark `comment`'s thread resolved, or reopen it with `resolved=False`.
|
||||
|
||||
Word keeps resolution in `commentsExtended` rather than on the comment, so this writes
|
||||
that part. Refuses a protected document, and a stale or foreign comment.
|
||||
|
||||
## `rollback_on_error`
|
||||
|
||||
```python
|
||||
rollback_on_error(document: 'Document', *participants: Any) -> Generator[None, None, None]
|
||||
```
|
||||
|
||||
Restore the live package and named mutable proxies after an error.
|
||||
@@ -1,138 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.comments`
|
||||
|
||||
Collection providing access to comments added to this document.
|
||||
|
||||
## `Comment`
|
||||
|
||||
```python
|
||||
Comment(comment_elm: CT_Comment, comments_part: CommentsPart)
|
||||
```
|
||||
|
||||
Bases: `BlockItemContainer`
|
||||
|
||||
Proxy for a single comment in the document.
|
||||
|
||||
Reads author, initials, date and body content, and adds paragraphs or tables. Every
|
||||
mutation revalidates that the comment is still live first, so a proxy whose part was
|
||||
removed or replaced refuses instead of writing into a detached tree.
|
||||
|
||||
### `add_paragraph`
|
||||
|
||||
```python
|
||||
add_paragraph(text: str = '', style: str | ParagraphStyle | None = None) -> Paragraph
|
||||
```
|
||||
|
||||
Append a paragraph to this comment's body and return it.
|
||||
|
||||
Re-keys the comment's `commentEx`, its replies' `paraIdParent`, and its `commentsIds` row
|
||||
onto the new last paragraph, so appending rewrites thread and resolution state. Refuses a
|
||||
protected document, and a proxy whose part was removed or replaced.
|
||||
|
||||
### `add_table`
|
||||
|
||||
```python
|
||||
add_table(rows: int, cols: int, width: Length) -> Table
|
||||
```
|
||||
|
||||
Append a table to this comment's body and return it.
|
||||
|
||||
Re-keys thread and resolution state onto the new last paragraph, as `add_paragraph` does.
|
||||
Refuses a protected document, and a proxy whose part was removed or replaced.
|
||||
|
||||
### `author`
|
||||
|
||||
```python
|
||||
author: str
|
||||
```
|
||||
|
||||
Read/write. The recorded author of this comment.
|
||||
|
||||
This field is required but can be set to the empty string.
|
||||
|
||||
### `comment_id`
|
||||
|
||||
```python
|
||||
comment_id: int
|
||||
```
|
||||
|
||||
The unique identifier of this comment.
|
||||
|
||||
### `initials`
|
||||
|
||||
```python
|
||||
initials: str | None
|
||||
```
|
||||
|
||||
Read/write. The recorded initials of the comment author.
|
||||
|
||||
This attribute is optional in the XML, returns `None` if not set. Assigning `None` removes
|
||||
any existing initials from the XML.
|
||||
|
||||
### `text`
|
||||
|
||||
```python
|
||||
text: str
|
||||
```
|
||||
|
||||
The text content of this comment as a string.
|
||||
|
||||
Only content in paragraphs is included and of course all emphasis and styling is stripped.
|
||||
|
||||
Paragraph boundaries are indicated with a newline (`"\\n"`)
|
||||
|
||||
### `timestamp`
|
||||
|
||||
```python
|
||||
timestamp: dt.datetime | None
|
||||
```
|
||||
|
||||
The date and time this comment was authored.
|
||||
|
||||
This attribute is optional in the XML, returns `None` if not set.
|
||||
|
||||
## `Comments`
|
||||
|
||||
```python
|
||||
Comments(comments_elm: CT_Comments, comments_part: CommentsPart)
|
||||
```
|
||||
|
||||
Collection containing the comments added to this document.
|
||||
|
||||
### `add_comment`
|
||||
|
||||
```python
|
||||
add_comment(text: str = '', author: str = '', initials: str | None = '') -> Comment
|
||||
```
|
||||
|
||||
Add a new comment to the document and return it.
|
||||
|
||||
Assigns a unique id and writes the modern identity parts (`commentsIds`,
|
||||
`commentsExtensible`, a `w14:paraId`) that Word needs to thread replies. Refuses a
|
||||
protected document, a collection whose part was removed or replaced, and an ambiguous
|
||||
comments relationship.
|
||||
|
||||
### `get`
|
||||
|
||||
```python
|
||||
get(comment_id: int) -> Comment | None
|
||||
```
|
||||
|
||||
Return the comment identified by `comment_id`, or `None` if not found.
|
||||
|
||||
## `rollback_on_error`
|
||||
|
||||
```python
|
||||
rollback_on_error(document: 'Document', *participants: Any) -> Generator[None, None, None]
|
||||
```
|
||||
|
||||
Restore the live package and named mutable proxies after an error.
|
||||
|
||||
## `rollback_xml_on_error`
|
||||
|
||||
```python
|
||||
rollback_xml_on_error(root: '_Element') -> Generator[None, None, None]
|
||||
```
|
||||
|
||||
Restore one live XML tree after an error in a local compound edit.
|
||||
@@ -1,152 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.composition`
|
||||
|
||||
Cross-document composition.
|
||||
|
||||
## `CompositionFinding`
|
||||
|
||||
```python
|
||||
CompositionFinding(kind: str, detail: str) -> None
|
||||
```
|
||||
|
||||
### `detail`
|
||||
|
||||
```python
|
||||
detail: str
|
||||
```
|
||||
|
||||
### `kind`
|
||||
|
||||
```python
|
||||
kind: str
|
||||
```
|
||||
|
||||
### `to_dict`
|
||||
|
||||
```python
|
||||
to_dict() -> dict
|
||||
```
|
||||
|
||||
## `CompositionReport`
|
||||
|
||||
```python
|
||||
CompositionReport(inserted_blocks: int = 0, style_map: Dict[str, str] = dict(), imported_styles: List[str] = list(), renamed_styles: Dict[str, str] = dict(), numbering_map: Dict[int, int] = dict(), media_copied: List[str] = list(), bookmarks_renamed: Dict[str, str] = dict(), findings: List[CompositionFinding] = list(), declared_parts: List[str] = list()) -> None
|
||||
```
|
||||
|
||||
Everything one composition call did — the declared changed-part
|
||||
budget, the reconciliation maps, and what was reported instead of done.
|
||||
|
||||
### `bookmarks_renamed`
|
||||
|
||||
```python
|
||||
bookmarks_renamed: Dict[str, str] = field(default_factory=dict)
|
||||
```
|
||||
|
||||
### `declared_parts`
|
||||
|
||||
```python
|
||||
declared_parts: List[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
### `findings`
|
||||
|
||||
```python
|
||||
findings: List[CompositionFinding] = field(default_factory=list)
|
||||
```
|
||||
|
||||
### `imported_styles`
|
||||
|
||||
```python
|
||||
imported_styles: List[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
### `inserted_blocks`
|
||||
|
||||
```python
|
||||
inserted_blocks: int = 0
|
||||
```
|
||||
|
||||
### `media_copied`
|
||||
|
||||
```python
|
||||
media_copied: List[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
### `numbering_map`
|
||||
|
||||
```python
|
||||
numbering_map: Dict[int, int] = field(default_factory=dict)
|
||||
```
|
||||
|
||||
### `renamed_styles`
|
||||
|
||||
```python
|
||||
renamed_styles: Dict[str, str] = field(default_factory=dict)
|
||||
```
|
||||
|
||||
### `style_map`
|
||||
|
||||
```python
|
||||
style_map: Dict[str, str] = field(default_factory=dict)
|
||||
```
|
||||
|
||||
### `to_dict`
|
||||
|
||||
```python
|
||||
to_dict() -> dict
|
||||
```
|
||||
|
||||
## `append_document`
|
||||
|
||||
```python
|
||||
append_document(document: 'Document', source: 'Document', *, section: str = 'new_page', styles: str = 'match_by_name', headers: str = 'destination') -> CompositionReport
|
||||
```
|
||||
|
||||
Append `source`'s whole body to `document`, and return a `CompositionReport`.
|
||||
|
||||
Keeps the destination's headers and footers by default and authors no new `w:sectPr`:
|
||||
`section="new_page"` prefixes a page break, `"continuous"` appends flush.
|
||||
`headers="source"` overwrites the destination's last-section header and footer and flips
|
||||
the document-wide even/odd setting. Refuses a protected document and an empty body on
|
||||
either side. Also refuses when insertion after the destination's final paragraph,
|
||||
table, or block content control would remain inside an open field result.
|
||||
|
||||
## `check_install`
|
||||
|
||||
```python
|
||||
check_install() -> None
|
||||
```
|
||||
|
||||
Refuse when paper-docx and python-docx are both installed.
|
||||
|
||||
## `insert_blocks_from`
|
||||
|
||||
```python
|
||||
insert_blocks_from(document: 'Document', source: 'Document', start_anchor: 'Document', *, anchor: 'Document', end_anchor: 'Document' = None, count: int = 1, styles: str = 'match_by_name', include_start: bool = True, include_end: bool = True) -> CompositionReport
|
||||
```
|
||||
|
||||
Copy a block range from `source` after `anchor`, and return a `CompositionReport`.
|
||||
|
||||
Reconciles styles, numbering, media and bookmarks so the copy keeps its appearance.
|
||||
`start_anchor` and `end_anchor` identify SOURCE paragraphs whose containing top-level body
|
||||
blocks form the range endpoints. A direct body paragraph or a paragraph in a top-level
|
||||
content control can serve as an endpoint; paragraphs in tables, table cells, and text boxes
|
||||
cannot. Both endpoints are included by default; setting either inclusion flag false excludes
|
||||
that endpoint's block. With no `end_anchor`, `count` blocks are copied beginning at the start
|
||||
block or the following block when `include_start=False`. With an `end_anchor`, `count` is
|
||||
validated but does not limit the range. `include_end=False` without an end anchor raises
|
||||
`ValueError`. Refuses an empty adjusted range, a protected destination, an endpoint that is
|
||||
missing, ambiguous, or spans multiple paragraphs, and source content this package cannot
|
||||
carry over: revisions, comments, OLE objects, EMF/WMF images. Live source
|
||||
endpoints may come from any supported inspection view. A live destination
|
||||
must come from ``view="current"``; reacquire a historical destination before
|
||||
composing.
|
||||
|
||||
## `rollback_on_error`
|
||||
|
||||
```python
|
||||
rollback_on_error(document: 'Document', *participants: Any) -> Generator[None, None, None]
|
||||
```
|
||||
|
||||
Restore the live package and named mutable proxies after an error.
|
||||
@@ -1,183 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.controls`
|
||||
|
||||
Content-control (structured document tag) surface — the templating
|
||||
|
||||
## `Control`
|
||||
|
||||
```python
|
||||
Control(sdt: '_Element', story: str, document: 'Document') -> None
|
||||
```
|
||||
|
||||
Live proxy for one content control.
|
||||
|
||||
### `alias`
|
||||
|
||||
```python
|
||||
alias: Optional[str]
|
||||
```
|
||||
|
||||
### `control_type`
|
||||
|
||||
```python
|
||||
control_type: str
|
||||
```
|
||||
|
||||
### `info`
|
||||
|
||||
```python
|
||||
info() -> ControlInfo
|
||||
```
|
||||
|
||||
### `is_data_bound`
|
||||
|
||||
```python
|
||||
is_data_bound: bool
|
||||
```
|
||||
|
||||
### `set_value`
|
||||
|
||||
```python
|
||||
set_value(value: 'Union[str, bool, dt.date, dt.datetime]') -> None
|
||||
```
|
||||
|
||||
Set the control's value, validating fully before mutating anything.
|
||||
|
||||
Text and rich-text controls take a string, checkboxes a bool, dropdowns a value from
|
||||
their `w:listItem` choices, dates an ISO date. Refuses a protected document, a stale or
|
||||
foreign control, a locked or data-bound surface, a picture, group or building-block
|
||||
control, a dropdown value outside its choices, and an unsupported date format.
|
||||
|
||||
### `showing_placeholder`
|
||||
|
||||
```python
|
||||
showing_placeholder: bool
|
||||
```
|
||||
|
||||
### `tag`
|
||||
|
||||
```python
|
||||
tag: Optional[str]
|
||||
```
|
||||
|
||||
### `value`
|
||||
|
||||
```python
|
||||
value: 'Union[str, bool]'
|
||||
```
|
||||
|
||||
The control's current value (bool for checkboxes, text otherwise).
|
||||
|
||||
## `ControlInfo`
|
||||
|
||||
```python
|
||||
ControlInfo(tag: Optional[str], alias: Optional[str], control_type: str, value: str, story: str, showing_placeholder: bool, is_data_bound: bool, choices: Tuple[str, ...]) -> None
|
||||
```
|
||||
|
||||
Identity and current state of one content control.
|
||||
|
||||
### `alias`
|
||||
|
||||
```python
|
||||
alias: Optional[str]
|
||||
```
|
||||
|
||||
### `choices`
|
||||
|
||||
```python
|
||||
choices: Tuple[str, ...]
|
||||
```
|
||||
|
||||
### `control_type`
|
||||
|
||||
```python
|
||||
control_type: str
|
||||
```
|
||||
|
||||
### `is_data_bound`
|
||||
|
||||
```python
|
||||
is_data_bound: bool
|
||||
```
|
||||
|
||||
### `showing_placeholder`
|
||||
|
||||
```python
|
||||
showing_placeholder: bool
|
||||
```
|
||||
|
||||
### `story`
|
||||
|
||||
```python
|
||||
story: str
|
||||
```
|
||||
|
||||
### `tag`
|
||||
|
||||
```python
|
||||
tag: Optional[str]
|
||||
```
|
||||
|
||||
### `to_dict`
|
||||
|
||||
```python
|
||||
to_dict() -> dict
|
||||
```
|
||||
|
||||
### `value`
|
||||
|
||||
```python
|
||||
value: str
|
||||
```
|
||||
|
||||
## `check_install`
|
||||
|
||||
```python
|
||||
check_install() -> None
|
||||
```
|
||||
|
||||
Refuse when paper-docx and python-docx are both installed.
|
||||
|
||||
## `get_control`
|
||||
|
||||
```python
|
||||
get_control(document: 'Document', *, tag: Optional[str] = None, alias: Optional[str] = None) -> Control
|
||||
```
|
||||
|
||||
The single control matching `tag` and/or `alias`, or a typed refusal.
|
||||
|
||||
## `iter_controls`
|
||||
|
||||
```python
|
||||
iter_controls(document: 'Document') -> 'Iterator[Control]'
|
||||
```
|
||||
|
||||
Every content control in every story part, document order.
|
||||
|
||||
## `list_controls`
|
||||
|
||||
```python
|
||||
list_controls(document: 'Document') -> Tuple[ControlInfo, ...]
|
||||
```
|
||||
|
||||
Identity and state of every control (schema-stable via .to_dict()).
|
||||
|
||||
## `rollback_on_error`
|
||||
|
||||
```python
|
||||
rollback_on_error(document: 'Document', *participants: Any) -> Generator[None, None, None]
|
||||
```
|
||||
|
||||
Restore the live package and named mutable proxies after an error.
|
||||
|
||||
## `set_control_value`
|
||||
|
||||
```python
|
||||
set_control_value(document: 'Document', value: 'Union[str, bool, dt.date, dt.datetime]', *, tag: Optional[str] = None, alias: Optional[str] = None) -> None
|
||||
```
|
||||
|
||||
Set the value of the control that `tag` names.
|
||||
|
||||
Refuses when no control carries the tag and when several do, plus every refusal
|
||||
`Control.set_value` raises.
|
||||
@@ -1,69 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.dml.color`
|
||||
|
||||
DrawingML objects related to color, ColorFormat being the most prominent.
|
||||
|
||||
## `ColorFormat`
|
||||
|
||||
```python
|
||||
ColorFormat(rPr_parent: RPrParent)
|
||||
```
|
||||
|
||||
Bases: `ElementProxy`
|
||||
|
||||
Provides access to color settings like RGB color, theme color, and luminance adjustments.
|
||||
|
||||
### `rgb`
|
||||
|
||||
```python
|
||||
rgb: RGBColor | None
|
||||
```
|
||||
|
||||
An `RGBColor` value or `None` if no RGB color is specified.
|
||||
|
||||
When `type` is `MSO_COLOR_TYPE.RGB`, the value of this property will always be an
|
||||
`RGBColor` value. It may also be an `RGBColor` value if `type` is
|
||||
`MSO_COLOR_TYPE.THEME`, as Word writes the current value of a theme color when one is
|
||||
assigned. In that case, the RGB value should be interpreted as no more than a good guess
|
||||
however, as the theme color takes precedence at rendering time. Its value is `None`
|
||||
whenever `type` is either `None` or `MSO_COLOR_TYPE.AUTO`.
|
||||
|
||||
Assigning an `RGBColor` value causes `type` to become `MSO_COLOR_TYPE.RGB` and any
|
||||
theme color is removed. Assigning `None` causes any color to be removed such that the
|
||||
effective color is inherited from the style hierarchy.
|
||||
|
||||
### `theme_color`
|
||||
|
||||
```python
|
||||
theme_color: MSO_THEME_COLOR | None
|
||||
```
|
||||
|
||||
Member of `MsoThemeColorIndex` or `None` if no theme color is specified.
|
||||
|
||||
When `type` is `MSO_COLOR_TYPE.THEME`, the value of this property will always be a
|
||||
member of `MsoThemeColorIndex`. When `type` has any other value, the value of
|
||||
this property is `None`.
|
||||
|
||||
Assigning a member of `MsoThemeColorIndex` causes `type` to become
|
||||
`MSO_COLOR_TYPE.THEME`. Any existing RGB value is retained but ignored by Word. Assigning
|
||||
`None` causes any color specification to be removed such that the effective color is
|
||||
inherited from the style hierarchy.
|
||||
|
||||
### `type`
|
||||
|
||||
```python
|
||||
type: MSO_COLOR_TYPE | None
|
||||
```
|
||||
|
||||
Read-only.
|
||||
|
||||
A member of `MsoColorType`, one of RGB, THEME, or AUTO, corresponding to the way this
|
||||
color is defined. Its value is `None` if no color is applied at this level, which causes
|
||||
the effective color to be inherited from the style hierarchy.
|
||||
|
||||
## `RPrParent`
|
||||
|
||||
```python
|
||||
RPrParent: TypeAlias = 'CT_R'
|
||||
```
|
||||
@@ -1,228 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.document`
|
||||
|
||||
`Document` and closely related objects.
|
||||
|
||||
## `Document`
|
||||
|
||||
```python
|
||||
Document(element: CT_Document, part: DocumentPart)
|
||||
```
|
||||
|
||||
Bases: `ElementProxy`
|
||||
|
||||
WordprocessingML (WML) document.
|
||||
|
||||
Not intended to be constructed directly. Use `docx.Document` to open or create
|
||||
a document.
|
||||
|
||||
### `add_comment`
|
||||
|
||||
```python
|
||||
add_comment(runs: Run | Sequence[Run], text: str | None = '', author: str = '', initials: str | None = '') -> Comment
|
||||
```
|
||||
|
||||
Add a comment anchored to `runs`, and return it.
|
||||
|
||||
Pass one `Run` or a sequence; only the first and last are used, so handing over
|
||||
`paragraph.runs` works. Reach for `Span.comment` instead when the anchor should match
|
||||
exact text rather than whole runs. Refuses a protected document, runs belonging to
|
||||
another document, and a comments part that is missing or ambiguous.
|
||||
|
||||
### `add_heading`
|
||||
|
||||
```python
|
||||
add_heading(text: str = '', level: int = 1)
|
||||
```
|
||||
|
||||
Return a heading paragraph newly added to the end of the document.
|
||||
|
||||
The heading paragraph will contain `text` and have its paragraph style
|
||||
determined by `level`. If `level` is 0, the style is set to `Title`. If `level`
|
||||
is 1 (or omitted), `Heading 1` is used. Otherwise the style is set to `Heading
|
||||
{level}`. Raises `ValueError` if `level` is outside the range 0-9.
|
||||
|
||||
### `add_page_break`
|
||||
|
||||
```python
|
||||
add_page_break()
|
||||
```
|
||||
|
||||
Return newly `Paragraph` object containing only a page break.
|
||||
|
||||
### `add_paragraph`
|
||||
|
||||
```python
|
||||
add_paragraph(text: str = '', style: str | ParagraphStyle | None = None) -> Paragraph
|
||||
```
|
||||
|
||||
Return paragraph newly added to the end of the document.
|
||||
|
||||
The paragraph is populated with `text` and having paragraph style `style`.
|
||||
|
||||
`text` can contain tab (``\t``) characters, which are converted to the
|
||||
appropriate XML form for a tab. `text` can also include newline (``\n``) or
|
||||
carriage return (``\r``) characters, each of which is converted to a line
|
||||
break.
|
||||
|
||||
### `add_picture`
|
||||
|
||||
```python
|
||||
add_picture(image_path_or_stream: str | IO[bytes], width: int | Length | None = None, height: int | Length | None = None)
|
||||
```
|
||||
|
||||
Return new picture shape added in its own paragraph at end of the document.
|
||||
|
||||
The picture contains the image at `image_path_or_stream`, scaled based on
|
||||
`width` and `height`. If neither width nor height is specified, the picture
|
||||
appears at its native size. If only one is specified, it is used to compute a
|
||||
scaling factor that is then applied to the unspecified dimension, preserving the
|
||||
aspect ratio of the image. The native size of the picture is calculated using
|
||||
the dots-per-inch (dpi) value specified in the image file, defaulting to 72 dpi
|
||||
if no value is specified, as is often the case.
|
||||
|
||||
### `add_section`
|
||||
|
||||
```python
|
||||
add_section(start_type: WD_SECTION = WD_SECTION.NEW_PAGE)
|
||||
```
|
||||
|
||||
Return a `Section` object newly added at the end of the document.
|
||||
|
||||
The optional `start_type` argument must be a member of the `WdSectionStart`
|
||||
enumeration, and defaults to ``WD_SECTION.NEW_PAGE`` if not provided.
|
||||
|
||||
### `add_table`
|
||||
|
||||
```python
|
||||
add_table(rows: int, cols: int, style: str | _TableStyle | None = None)
|
||||
```
|
||||
|
||||
Add a table having row and column counts of `rows` and `cols` respectively.
|
||||
|
||||
`style` may be a table style object or a table style name. If `style` is `None`,
|
||||
the table inherits the default table style of the document.
|
||||
|
||||
### `comments`
|
||||
|
||||
```python
|
||||
comments: Comments
|
||||
```
|
||||
|
||||
A `Comments` object providing access to comments added to the document.
|
||||
|
||||
### `core_properties`
|
||||
|
||||
```python
|
||||
core_properties
|
||||
```
|
||||
|
||||
A `CoreProperties` object providing Dublin Core properties of document.
|
||||
|
||||
### `inline_shapes`
|
||||
|
||||
```python
|
||||
inline_shapes
|
||||
```
|
||||
|
||||
The `InlineShapes` collection for this document.
|
||||
|
||||
An inline shape is a graphical object, such as a picture, contained in a run of
|
||||
text and behaving like a character glyph, being flowed like other text in a
|
||||
paragraph.
|
||||
|
||||
### `iter_inner_content`
|
||||
|
||||
```python
|
||||
iter_inner_content() -> Iterator[Paragraph | Table]
|
||||
```
|
||||
|
||||
Generate each `Paragraph` or `Table` in this document in document order.
|
||||
|
||||
### `paragraphs`
|
||||
|
||||
```python
|
||||
paragraphs: List[Paragraph]
|
||||
```
|
||||
|
||||
The `Paragraph` instances in the document, in document order.
|
||||
|
||||
Note that paragraphs within revision marks such as ``<w:ins>`` or ``<w:del>`` do
|
||||
not appear in this list.
|
||||
|
||||
### `part`
|
||||
|
||||
```python
|
||||
part: DocumentPart
|
||||
```
|
||||
|
||||
The `DocumentPart` object of this document.
|
||||
|
||||
### `revisions`
|
||||
|
||||
```python
|
||||
revisions
|
||||
```
|
||||
|
||||
`Revisions` object enumerating tracked changes across all story parts.
|
||||
|
||||
paper-docx addition: a fresh snapshot on each access; supports
|
||||
accept/reject of all revisions or filtered by author. See
|
||||
`docx.revision`.
|
||||
|
||||
### `save`
|
||||
|
||||
```python
|
||||
save(path_or_stream: str | IO[bytes])
|
||||
```
|
||||
|
||||
Save this document to `path_or_stream`.
|
||||
|
||||
`path_or_stream` can be either a path to a filesystem location (a string) or a
|
||||
file-like object.
|
||||
|
||||
### `sections`
|
||||
|
||||
```python
|
||||
sections: Sections
|
||||
```
|
||||
|
||||
`Sections` object providing access to each section in this document.
|
||||
|
||||
### `settings`
|
||||
|
||||
```python
|
||||
settings: Settings
|
||||
```
|
||||
|
||||
A `Settings` object providing access to the document-level settings.
|
||||
|
||||
### `styles`
|
||||
|
||||
```python
|
||||
styles
|
||||
```
|
||||
|
||||
A `Styles` object providing access to the styles in this document.
|
||||
|
||||
### `tables`
|
||||
|
||||
```python
|
||||
tables: List[Table]
|
||||
```
|
||||
|
||||
All `Table` instances in the document, in document order.
|
||||
|
||||
Note that only tables appearing at the top level of the document appear in this
|
||||
list; a table nested inside a table cell does not appear. A table within
|
||||
revision marks such as ``<w:ins>`` or ``<w:del>`` will also not appear in the
|
||||
list.
|
||||
|
||||
## `rollback_on_error`
|
||||
|
||||
```python
|
||||
rollback_on_error(document: 'Document', *participants: Any) -> Generator[None, None, None]
|
||||
```
|
||||
|
||||
Restore the live package and named mutable proxies after an error.
|
||||
@@ -1,64 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.drawing`
|
||||
|
||||
DrawingML-related objects are in this subpackage.
|
||||
|
||||
## `Drawing`
|
||||
|
||||
```python
|
||||
Drawing(drawing: CT_Drawing, parent: t.ProvidesStoryPart)
|
||||
```
|
||||
|
||||
Bases: `Parented`
|
||||
|
||||
Container for a DrawingML object.
|
||||
|
||||
### `has_picture`
|
||||
|
||||
```python
|
||||
has_picture: bool
|
||||
```
|
||||
|
||||
True when `drawing` contains an embedded picture.
|
||||
|
||||
A drawing can contain a picture, but it can also contain a chart, SmartArt, or a
|
||||
drawing canvas. Methods related to a picture, like `.image`, will raise when the drawing
|
||||
does not contain a picture. Use this value to determine whether image methods will succeed.
|
||||
|
||||
This value is `False` when a linked picture is present. This should be relatively rare and
|
||||
the image would only be retrievable from the filesystem.
|
||||
|
||||
Note this does not distinguish between inline and floating images. The presence of either
|
||||
one will cause this value to be `True`.
|
||||
|
||||
### `image`
|
||||
|
||||
```python
|
||||
image: Image
|
||||
```
|
||||
|
||||
An `Image` proxy object for the image in this (picture) drawing.
|
||||
|
||||
Raises `ValueError` when this drawing does contains something other than a picture. Use
|
||||
`.has_picture` to qualify drawing objects before using this property.
|
||||
|
||||
### `replace_picture`
|
||||
|
||||
```python
|
||||
replace_picture(image_descriptor: str | IO[bytes]) -> None
|
||||
```
|
||||
|
||||
Swap this drawing's image bytes, keeping display size and position.
|
||||
|
||||
Always writes a new image part, so other shapes sharing the old part are unchanged;
|
||||
the old relationship stays behind. Refuses a drawing with no picture, a linked picture
|
||||
whose bytes live outside the package, and a protected document.
|
||||
|
||||
## `rollback_on_error`
|
||||
|
||||
```python
|
||||
rollback_on_error(document: 'Document', *participants: Any) -> Generator[None, None, None]
|
||||
```
|
||||
|
||||
Restore the live package and named mutable proxies after an error.
|
||||
@@ -1,71 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.enum.base`
|
||||
|
||||
Base classes and other objects used by enumerations.
|
||||
|
||||
## `BaseEnum`
|
||||
|
||||
Bases: `int`, `Enum`
|
||||
|
||||
Base class for Enums that do not map XML attr values.
|
||||
|
||||
The enum's value will be an integer, corresponding to the integer assigned the
|
||||
corresponding member in the MS API enum of the same name.
|
||||
|
||||
## `BaseXmlEnum`
|
||||
|
||||
Bases: `int`, `Enum`
|
||||
|
||||
Base class for Enums that also map XML attr values.
|
||||
|
||||
The enum's value will be an integer, corresponding to the integer assigned the
|
||||
corresponding member in the MS API enum of the same name.
|
||||
|
||||
### `from_xml`
|
||||
|
||||
```python
|
||||
from_xml(xml_value: str | None) -> Self
|
||||
```
|
||||
|
||||
Enumeration member corresponding to XML attribute value `xml_value`.
|
||||
|
||||
Example::
|
||||
|
||||
>>> WD_PARAGRAPH_ALIGNMENT.from_xml("center")
|
||||
WD_PARAGRAPH_ALIGNMENT.CENTER
|
||||
|
||||
### `to_xml`
|
||||
|
||||
```python
|
||||
to_xml(value: int | _T | None) -> str | None
|
||||
```
|
||||
|
||||
XML value of this enum member, generally an XML attribute value.
|
||||
|
||||
### `xml_value`
|
||||
|
||||
```python
|
||||
xml_value: str | None
|
||||
```
|
||||
|
||||
## `DocsPageFormatter`
|
||||
|
||||
```python
|
||||
DocsPageFormatter(clsname: str, clsdict: Dict[str, Any])
|
||||
```
|
||||
|
||||
Generate an .rst doc page for an enumeration.
|
||||
|
||||
Formats a RestructuredText documention page (string) for the enumeration class parts
|
||||
passed to the constructor. An immutable one-shot service object.
|
||||
|
||||
### `page_str`
|
||||
|
||||
```python
|
||||
page_str
|
||||
```
|
||||
|
||||
The RestructuredText documentation page for the enumeration.
|
||||
|
||||
This is the only API member for the class.
|
||||
@@ -1,206 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.enum.dml`
|
||||
|
||||
Enumerations used by DrawingML objects.
|
||||
|
||||
## `MSO_COLOR_TYPE`
|
||||
|
||||
Bases: `BaseEnum`
|
||||
|
||||
Specifies the color specification scheme.
|
||||
|
||||
Example::
|
||||
|
||||
from docx.enum.dml import MSO_COLOR_TYPE
|
||||
|
||||
assert font.color.type == MSO_COLOR_TYPE.SCHEME
|
||||
|
||||
MS API name: `MsoColorType`
|
||||
|
||||
http://msdn.microsoft.com/en-us/library/office/ff864912(v=office.15).aspx
|
||||
|
||||
### `AUTO`
|
||||
|
||||
```python
|
||||
AUTO = (101, 'Color is determined automatically by the application.')
|
||||
```
|
||||
|
||||
Color is determined automatically by the application.
|
||||
|
||||
### `RGB`
|
||||
|
||||
```python
|
||||
RGB = (1, 'Color is specified by an `RGBColor` value.')
|
||||
```
|
||||
|
||||
Color is specified by an `RGBColor` value.
|
||||
|
||||
### `THEME`
|
||||
|
||||
```python
|
||||
THEME = (2, 'Color is one of the preset theme colors.')
|
||||
```
|
||||
|
||||
Color is one of the preset theme colors.
|
||||
|
||||
## `MSO_THEME_COLOR`
|
||||
|
||||
```python
|
||||
MSO_THEME_COLOR = MSO_THEME_COLOR_INDEX
|
||||
```
|
||||
|
||||
## `MSO_THEME_COLOR_INDEX`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Indicates the Office theme color, one of those shown in the color gallery on the
|
||||
formatting ribbon.
|
||||
|
||||
Alias: ``MSO_THEME_COLOR``
|
||||
|
||||
Example::
|
||||
|
||||
from docx.enum.dml import MSO_THEME_COLOR
|
||||
|
||||
font.color.theme_color = MSO_THEME_COLOR.ACCENT_1
|
||||
|
||||
MS API name: `MsoThemeColorIndex`
|
||||
|
||||
http://msdn.microsoft.com/en-us/library/office/ff860782(v=office.15).aspx
|
||||
|
||||
### `ACCENT_1`
|
||||
|
||||
```python
|
||||
ACCENT_1 = (5, 'accent1', 'Specifies the Accent 1 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Accent 1 theme color.
|
||||
|
||||
### `ACCENT_2`
|
||||
|
||||
```python
|
||||
ACCENT_2 = (6, 'accent2', 'Specifies the Accent 2 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Accent 2 theme color.
|
||||
|
||||
### `ACCENT_3`
|
||||
|
||||
```python
|
||||
ACCENT_3 = (7, 'accent3', 'Specifies the Accent 3 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Accent 3 theme color.
|
||||
|
||||
### `ACCENT_4`
|
||||
|
||||
```python
|
||||
ACCENT_4 = (8, 'accent4', 'Specifies the Accent 4 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Accent 4 theme color.
|
||||
|
||||
### `ACCENT_5`
|
||||
|
||||
```python
|
||||
ACCENT_5 = (9, 'accent5', 'Specifies the Accent 5 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Accent 5 theme color.
|
||||
|
||||
### `ACCENT_6`
|
||||
|
||||
```python
|
||||
ACCENT_6 = (10, 'accent6', 'Specifies the Accent 6 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Accent 6 theme color.
|
||||
|
||||
### `BACKGROUND_1`
|
||||
|
||||
```python
|
||||
BACKGROUND_1 = (14, 'background1', 'Specifies the Background 1 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Background 1 theme color.
|
||||
|
||||
### `BACKGROUND_2`
|
||||
|
||||
```python
|
||||
BACKGROUND_2 = (16, 'background2', 'Specifies the Background 2 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Background 2 theme color.
|
||||
|
||||
### `DARK_1`
|
||||
|
||||
```python
|
||||
DARK_1 = (1, 'dark1', 'Specifies the Dark 1 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Dark 1 theme color.
|
||||
|
||||
### `DARK_2`
|
||||
|
||||
```python
|
||||
DARK_2 = (3, 'dark2', 'Specifies the Dark 2 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Dark 2 theme color.
|
||||
|
||||
### `FOLLOWED_HYPERLINK`
|
||||
|
||||
```python
|
||||
FOLLOWED_HYPERLINK = (12, 'followedHyperlink', 'Specifies the theme color for a clicked hyperlink.')
|
||||
```
|
||||
|
||||
Specifies the theme color for a clicked hyperlink.
|
||||
|
||||
### `HYPERLINK`
|
||||
|
||||
```python
|
||||
HYPERLINK = (11, 'hyperlink', 'Specifies the theme color for a hyperlink.')
|
||||
```
|
||||
|
||||
Specifies the theme color for a hyperlink.
|
||||
|
||||
### `LIGHT_1`
|
||||
|
||||
```python
|
||||
LIGHT_1 = (2, 'light1', 'Specifies the Light 1 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Light 1 theme color.
|
||||
|
||||
### `LIGHT_2`
|
||||
|
||||
```python
|
||||
LIGHT_2 = (4, 'light2', 'Specifies the Light 2 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Light 2 theme color.
|
||||
|
||||
### `NOT_THEME_COLOR`
|
||||
|
||||
```python
|
||||
NOT_THEME_COLOR = (0, 'UNMAPPED', 'Indicates the color is not a theme color.')
|
||||
```
|
||||
|
||||
Indicates the color is not a theme color.
|
||||
|
||||
### `TEXT_1`
|
||||
|
||||
```python
|
||||
TEXT_1 = (13, 'text1', 'Specifies the Text 1 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Text 1 theme color.
|
||||
|
||||
### `TEXT_2`
|
||||
|
||||
```python
|
||||
TEXT_2 = (15, 'text2', 'Specifies the Text 2 theme color.')
|
||||
```
|
||||
|
||||
Specifies the Text 2 theme color.
|
||||
@@ -1,150 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.enum.section`
|
||||
|
||||
Enumerations related to the main document in WordprocessingML files.
|
||||
|
||||
## `WD_HEADER_FOOTER`
|
||||
|
||||
```python
|
||||
WD_HEADER_FOOTER = WD_HEADER_FOOTER_INDEX
|
||||
```
|
||||
|
||||
## `WD_HEADER_FOOTER_INDEX`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Alias: **WD_HEADER_FOOTER**
|
||||
|
||||
Specifies one of the three possible header/footer definitions for a section.
|
||||
|
||||
For internal use only; not part of the python-docx API.
|
||||
|
||||
MS API name: `WdHeaderFooterIndex`
|
||||
URL: https://docs.microsoft.com/en-us/office/vba/api/word.wdheaderfooterindex
|
||||
|
||||
### `EVEN_PAGE`
|
||||
|
||||
```python
|
||||
EVEN_PAGE = (3, 'even', 'Header for even pages of recto/verso section.')
|
||||
```
|
||||
|
||||
Header for even pages of recto/verso section.
|
||||
|
||||
### `FIRST_PAGE`
|
||||
|
||||
```python
|
||||
FIRST_PAGE = (2, 'first', 'Header for first page of section.')
|
||||
```
|
||||
|
||||
Header for first page of section.
|
||||
|
||||
### `PRIMARY`
|
||||
|
||||
```python
|
||||
PRIMARY = (1, 'default', 'Header for odd pages or all if no even header.')
|
||||
```
|
||||
|
||||
Header for odd pages or all if no even header.
|
||||
|
||||
## `WD_ORIENT`
|
||||
|
||||
```python
|
||||
WD_ORIENT = WD_ORIENTATION
|
||||
```
|
||||
|
||||
## `WD_ORIENTATION`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Alias: **WD_ORIENT**
|
||||
|
||||
Specifies the page layout orientation.
|
||||
|
||||
Example::
|
||||
|
||||
from docx.enum.section import WD_ORIENT
|
||||
|
||||
section = document.sections[-1] section.orientation = WD_ORIENT.LANDSCAPE
|
||||
|
||||
MS API name: `WdOrientation`
|
||||
MS API URL: http://msdn.microsoft.com/en-us/library/office/ff837902.aspx
|
||||
|
||||
### `LANDSCAPE`
|
||||
|
||||
```python
|
||||
LANDSCAPE = (1, 'landscape', 'Landscape orientation.')
|
||||
```
|
||||
|
||||
Landscape orientation.
|
||||
|
||||
### `PORTRAIT`
|
||||
|
||||
```python
|
||||
PORTRAIT = (0, 'portrait', 'Portrait orientation.')
|
||||
```
|
||||
|
||||
Portrait orientation.
|
||||
|
||||
## `WD_SECTION`
|
||||
|
||||
```python
|
||||
WD_SECTION = WD_SECTION_START
|
||||
```
|
||||
|
||||
## `WD_SECTION_START`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Alias: **WD_SECTION**
|
||||
|
||||
Specifies the start type of a section break.
|
||||
|
||||
Example::
|
||||
|
||||
from docx.enum.section import WD_SECTION
|
||||
|
||||
section = document.sections[0] section.start_type = WD_SECTION.NEW_PAGE
|
||||
|
||||
MS API name: `WdSectionStart`
|
||||
MS API URL: http://msdn.microsoft.com/en-us/library/office/ff840975.aspx
|
||||
|
||||
### `CONTINUOUS`
|
||||
|
||||
```python
|
||||
CONTINUOUS = (0, 'continuous', 'Continuous section break.')
|
||||
```
|
||||
|
||||
Continuous section break.
|
||||
|
||||
### `EVEN_PAGE`
|
||||
|
||||
```python
|
||||
EVEN_PAGE = (3, 'evenPage', 'Even pages section break.')
|
||||
```
|
||||
|
||||
Even pages section break.
|
||||
|
||||
### `NEW_COLUMN`
|
||||
|
||||
```python
|
||||
NEW_COLUMN = (1, 'nextColumn', 'New column section break.')
|
||||
```
|
||||
|
||||
New column section break.
|
||||
|
||||
### `NEW_PAGE`
|
||||
|
||||
```python
|
||||
NEW_PAGE = (2, 'nextPage', 'New page section break.')
|
||||
```
|
||||
|
||||
New page section break.
|
||||
|
||||
### `ODD_PAGE`
|
||||
|
||||
```python
|
||||
ODD_PAGE = (4, 'oddPage', 'Section begins on next odd page.')
|
||||
```
|
||||
|
||||
Section begins on next odd page.
|
||||
@@ -1,49 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.enum.shape`
|
||||
|
||||
Enumerations related to DrawingML shapes in WordprocessingML files.
|
||||
|
||||
## `WD_INLINE_SHAPE`
|
||||
|
||||
```python
|
||||
WD_INLINE_SHAPE = WD_INLINE_SHAPE_TYPE
|
||||
```
|
||||
|
||||
## `WD_INLINE_SHAPE_TYPE`
|
||||
|
||||
Bases: `Enum`
|
||||
|
||||
Corresponds to WdInlineShapeType enumeration.
|
||||
|
||||
http://msdn.microsoft.com/en-us/library/office/ff192587.aspx.
|
||||
|
||||
### `CHART`
|
||||
|
||||
```python
|
||||
CHART = 12
|
||||
```
|
||||
|
||||
### `LINKED_PICTURE`
|
||||
|
||||
```python
|
||||
LINKED_PICTURE = 4
|
||||
```
|
||||
|
||||
### `NOT_IMPLEMENTED`
|
||||
|
||||
```python
|
||||
NOT_IMPLEMENTED = -6
|
||||
```
|
||||
|
||||
### `PICTURE`
|
||||
|
||||
```python
|
||||
PICTURE = 3
|
||||
```
|
||||
|
||||
### `SMART_ART`
|
||||
|
||||
```python
|
||||
SMART_ART = 15
|
||||
```
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,190 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.enum.table`
|
||||
|
||||
Enumerations related to tables in WordprocessingML files.
|
||||
|
||||
## `WD_ALIGN_VERTICAL`
|
||||
|
||||
```python
|
||||
WD_ALIGN_VERTICAL = WD_CELL_VERTICAL_ALIGNMENT
|
||||
```
|
||||
|
||||
## `WD_CELL_VERTICAL_ALIGNMENT`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Alias: **WD_ALIGN_VERTICAL**
|
||||
|
||||
Specifies the vertical alignment of text in one or more cells of a table.
|
||||
|
||||
Example::
|
||||
|
||||
from docx.enum.table import WD_ALIGN_VERTICAL
|
||||
|
||||
table = document.add_table(3, 3)
|
||||
table.cell(0, 0).vertical_alignment = WD_ALIGN_VERTICAL.BOTTOM
|
||||
|
||||
MS API name: `WdCellVerticalAlignment`
|
||||
|
||||
https://msdn.microsoft.com/en-us/library/office/ff193345.aspx
|
||||
|
||||
### `BOTH`
|
||||
|
||||
```python
|
||||
BOTH = (101, 'both', "This is an option in the OpenXml spec, but not in Word itself. It's not clear what Word behavior this setting produces. If you find out please let us know and we'll update this documentation. Otherwise, probably best to avoid this option.")
|
||||
```
|
||||
|
||||
This is an option in the OpenXml spec, but not in Word itself.
|
||||
|
||||
It's not clear what Word behavior this setting produces. If you find out please let
|
||||
us know and we'll update this documentation. Otherwise, probably best to avoid this
|
||||
option.
|
||||
|
||||
### `BOTTOM`
|
||||
|
||||
```python
|
||||
BOTTOM = (3, 'bottom', 'Text is aligned to the bottom border of the cell.')
|
||||
```
|
||||
|
||||
Text is aligned to the bottom border of the cell.
|
||||
|
||||
### `CENTER`
|
||||
|
||||
```python
|
||||
CENTER = (1, 'center', 'Text is aligned to the center of the cell.')
|
||||
```
|
||||
|
||||
Text is aligned to the center of the cell.
|
||||
|
||||
### `TOP`
|
||||
|
||||
```python
|
||||
TOP = (0, 'top', 'Text is aligned to the top border of the cell.')
|
||||
```
|
||||
|
||||
Text is aligned to the top border of the cell.
|
||||
|
||||
## `WD_ROW_HEIGHT`
|
||||
|
||||
```python
|
||||
WD_ROW_HEIGHT = WD_ROW_HEIGHT_RULE
|
||||
```
|
||||
|
||||
## `WD_ROW_HEIGHT_RULE`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Alias: **WD_ROW_HEIGHT**
|
||||
|
||||
Specifies the rule for determining the height of a table row
|
||||
|
||||
Example::
|
||||
|
||||
from docx.enum.table import WD_ROW_HEIGHT_RULE
|
||||
|
||||
table = document.add_table(3, 3)
|
||||
table.rows[0].height_rule = WD_ROW_HEIGHT_RULE.EXACTLY
|
||||
|
||||
MS API name: `WdRowHeightRule`
|
||||
|
||||
https://msdn.microsoft.com/en-us/library/office/ff193620.aspx
|
||||
|
||||
### `AT_LEAST`
|
||||
|
||||
```python
|
||||
AT_LEAST = (1, 'atLeast', 'The row height is at least a minimum specified value.')
|
||||
```
|
||||
|
||||
The row height is at least a minimum specified value.
|
||||
|
||||
### `AUTO`
|
||||
|
||||
```python
|
||||
AUTO = (0, 'auto', 'The row height is adjusted to accommodate the tallest value in the row.')
|
||||
```
|
||||
|
||||
The row height is adjusted to accommodate the tallest value in the row.
|
||||
|
||||
### `EXACTLY`
|
||||
|
||||
```python
|
||||
EXACTLY = (2, 'exact', 'The row height is an exact value.')
|
||||
```
|
||||
|
||||
The row height is an exact value.
|
||||
|
||||
## `WD_TABLE_ALIGNMENT`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Specifies table justification type.
|
||||
|
||||
Example::
|
||||
|
||||
from docx.enum.table import WD_TABLE_ALIGNMENT
|
||||
|
||||
table = document.add_table(3, 3)
|
||||
table.alignment = WD_TABLE_ALIGNMENT.CENTER
|
||||
|
||||
MS API name: `WdRowAlignment`
|
||||
|
||||
http://office.microsoft.com/en-us/word-help/HV080607259.aspx
|
||||
|
||||
### `CENTER`
|
||||
|
||||
```python
|
||||
CENTER = (1, 'center', 'Center-aligned.')
|
||||
```
|
||||
|
||||
Center-aligned.
|
||||
|
||||
### `LEFT`
|
||||
|
||||
```python
|
||||
LEFT = (0, 'left', 'Left-aligned')
|
||||
```
|
||||
|
||||
Left-aligned
|
||||
|
||||
### `RIGHT`
|
||||
|
||||
```python
|
||||
RIGHT = (2, 'right', 'Right-aligned.')
|
||||
```
|
||||
|
||||
Right-aligned.
|
||||
|
||||
## `WD_TABLE_DIRECTION`
|
||||
|
||||
Bases: `BaseEnum`
|
||||
|
||||
Specifies the direction in which an application orders cells in the specified
|
||||
table or row.
|
||||
|
||||
Example::
|
||||
|
||||
from docx.enum.table import WD_TABLE_DIRECTION
|
||||
|
||||
table = document.add_table(3, 3)
|
||||
table.direction = WD_TABLE_DIRECTION.RTL
|
||||
|
||||
MS API name: `WdTableDirection`
|
||||
|
||||
http://msdn.microsoft.com/en-us/library/ff835141.aspx
|
||||
|
||||
### `LTR`
|
||||
|
||||
```python
|
||||
LTR = (0, 'The table or row is arranged with the first column in the leftmost position.')
|
||||
```
|
||||
|
||||
The table or row is arranged with the first column in the leftmost position.
|
||||
|
||||
### `RTL`
|
||||
|
||||
```python
|
||||
RTL = (1, 'The table or row is arranged with the first column in the rightmost position.')
|
||||
```
|
||||
|
||||
The table or row is arranged with the first column in the rightmost position.
|
||||
@@ -1,725 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.enum.text`
|
||||
|
||||
Enumerations related to text in WordprocessingML files.
|
||||
|
||||
## `WD_ALIGN_PARAGRAPH`
|
||||
|
||||
```python
|
||||
WD_ALIGN_PARAGRAPH = WD_PARAGRAPH_ALIGNMENT
|
||||
```
|
||||
|
||||
## `WD_BREAK`
|
||||
|
||||
```python
|
||||
WD_BREAK = WD_BREAK_TYPE
|
||||
```
|
||||
|
||||
## `WD_BREAK_TYPE`
|
||||
|
||||
Bases: `Enum`
|
||||
|
||||
Corresponds to WdBreakType enumeration.
|
||||
|
||||
http://msdn.microsoft.com/en-us/library/office/ff195905.aspx.
|
||||
|
||||
### `COLUMN`
|
||||
|
||||
```python
|
||||
COLUMN = 8
|
||||
```
|
||||
|
||||
### `LINE`
|
||||
|
||||
```python
|
||||
LINE = 6
|
||||
```
|
||||
|
||||
### `LINE_CLEAR_ALL`
|
||||
|
||||
```python
|
||||
LINE_CLEAR_ALL = 11
|
||||
```
|
||||
|
||||
### `LINE_CLEAR_LEFT`
|
||||
|
||||
```python
|
||||
LINE_CLEAR_LEFT = 9
|
||||
```
|
||||
|
||||
### `LINE_CLEAR_RIGHT`
|
||||
|
||||
```python
|
||||
LINE_CLEAR_RIGHT = 10
|
||||
```
|
||||
|
||||
### `PAGE`
|
||||
|
||||
```python
|
||||
PAGE = 7
|
||||
```
|
||||
|
||||
### `SECTION_CONTINUOUS`
|
||||
|
||||
```python
|
||||
SECTION_CONTINUOUS = 3
|
||||
```
|
||||
|
||||
### `SECTION_EVEN_PAGE`
|
||||
|
||||
```python
|
||||
SECTION_EVEN_PAGE = 4
|
||||
```
|
||||
|
||||
### `SECTION_NEXT_PAGE`
|
||||
|
||||
```python
|
||||
SECTION_NEXT_PAGE = 2
|
||||
```
|
||||
|
||||
### `SECTION_ODD_PAGE`
|
||||
|
||||
```python
|
||||
SECTION_ODD_PAGE = 5
|
||||
```
|
||||
|
||||
### `TEXT_WRAPPING`
|
||||
|
||||
```python
|
||||
TEXT_WRAPPING = 11
|
||||
```
|
||||
|
||||
## `WD_COLOR`
|
||||
|
||||
```python
|
||||
WD_COLOR = WD_COLOR_INDEX
|
||||
```
|
||||
|
||||
## `WD_COLOR_INDEX`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Specifies a standard preset color to apply.
|
||||
|
||||
Used for font highlighting and perhaps other applications.
|
||||
|
||||
* MS API name: `WdColorIndex`
|
||||
* URL: https://msdn.microsoft.com/EN-US/library/office/ff195343.aspx
|
||||
|
||||
### `AUTO`
|
||||
|
||||
```python
|
||||
AUTO = (0, 'default', 'Automatic color. Default; usually black.')
|
||||
```
|
||||
|
||||
Automatic color. Default; usually black.
|
||||
|
||||
### `BLACK`
|
||||
|
||||
```python
|
||||
BLACK = (1, 'black', 'Black color.')
|
||||
```
|
||||
|
||||
Black color.
|
||||
|
||||
### `BLUE`
|
||||
|
||||
```python
|
||||
BLUE = (2, 'blue', 'Blue color')
|
||||
```
|
||||
|
||||
Blue color
|
||||
|
||||
### `BRIGHT_GREEN`
|
||||
|
||||
```python
|
||||
BRIGHT_GREEN = (4, 'green', 'Bright green color.')
|
||||
```
|
||||
|
||||
Bright green color.
|
||||
|
||||
### `DARK_BLUE`
|
||||
|
||||
```python
|
||||
DARK_BLUE = (9, 'darkBlue', 'Dark blue color.')
|
||||
```
|
||||
|
||||
Dark blue color.
|
||||
|
||||
### `DARK_RED`
|
||||
|
||||
```python
|
||||
DARK_RED = (13, 'darkRed', 'Dark red color.')
|
||||
```
|
||||
|
||||
Dark red color.
|
||||
|
||||
### `DARK_YELLOW`
|
||||
|
||||
```python
|
||||
DARK_YELLOW = (14, 'darkYellow', 'Dark yellow color.')
|
||||
```
|
||||
|
||||
Dark yellow color.
|
||||
|
||||
### `GRAY_25`
|
||||
|
||||
```python
|
||||
GRAY_25 = (16, 'lightGray', '25% shade of gray color.')
|
||||
```
|
||||
|
||||
25% shade of gray color.
|
||||
|
||||
### `GRAY_50`
|
||||
|
||||
```python
|
||||
GRAY_50 = (15, 'darkGray', '50% shade of gray color.')
|
||||
```
|
||||
|
||||
50% shade of gray color.
|
||||
|
||||
### `GREEN`
|
||||
|
||||
```python
|
||||
GREEN = (11, 'darkGreen', 'Green color.')
|
||||
```
|
||||
|
||||
Green color.
|
||||
|
||||
### `INHERITED`
|
||||
|
||||
```python
|
||||
INHERITED = (-1, None, 'Color is inherited from the style hierarchy.')
|
||||
```
|
||||
|
||||
Color is inherited from the style hierarchy.
|
||||
|
||||
### `PINK`
|
||||
|
||||
```python
|
||||
PINK = (5, 'magenta', 'Pink color.')
|
||||
```
|
||||
|
||||
Pink color.
|
||||
|
||||
### `RED`
|
||||
|
||||
```python
|
||||
RED = (6, 'red', 'Red color.')
|
||||
```
|
||||
|
||||
Red color.
|
||||
|
||||
### `TEAL`
|
||||
|
||||
```python
|
||||
TEAL = (10, 'darkCyan', 'Teal color.')
|
||||
```
|
||||
|
||||
Teal color.
|
||||
|
||||
### `TURQUOISE`
|
||||
|
||||
```python
|
||||
TURQUOISE = (3, 'cyan', 'Turquoise color.')
|
||||
```
|
||||
|
||||
Turquoise color.
|
||||
|
||||
### `VIOLET`
|
||||
|
||||
```python
|
||||
VIOLET = (12, 'darkMagenta', 'Violet color.')
|
||||
```
|
||||
|
||||
Violet color.
|
||||
|
||||
### `WHITE`
|
||||
|
||||
```python
|
||||
WHITE = (8, 'white', 'White color.')
|
||||
```
|
||||
|
||||
White color.
|
||||
|
||||
### `YELLOW`
|
||||
|
||||
```python
|
||||
YELLOW = (7, 'yellow', 'Yellow color.')
|
||||
```
|
||||
|
||||
Yellow color.
|
||||
|
||||
## `WD_LINE_SPACING`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Specifies a line spacing format to be applied to a paragraph.
|
||||
|
||||
Example::
|
||||
|
||||
from docx.enum.text import WD_LINE_SPACING
|
||||
|
||||
paragraph = document.add_paragraph()
|
||||
paragraph.line_spacing_rule = WD_LINE_SPACING.EXACTLY
|
||||
|
||||
|
||||
MS API name: `WdLineSpacing`
|
||||
|
||||
URL: http://msdn.microsoft.com/en-us/library/office/ff844910.aspx
|
||||
|
||||
### `AT_LEAST`
|
||||
|
||||
```python
|
||||
AT_LEAST = (3, 'atLeast', 'Minimum line spacing is specified amount. Amount is specified separately.')
|
||||
```
|
||||
|
||||
Minimum line spacing is specified amount. Amount is specified separately.
|
||||
|
||||
### `DOUBLE`
|
||||
|
||||
```python
|
||||
DOUBLE = (2, 'UNMAPPED', 'Double spaced.')
|
||||
```
|
||||
|
||||
Double spaced.
|
||||
|
||||
### `EXACTLY`
|
||||
|
||||
```python
|
||||
EXACTLY = (4, 'exact', 'Line spacing is exactly specified amount. Amount is specified separately.')
|
||||
```
|
||||
|
||||
Line spacing is exactly specified amount. Amount is specified separately.
|
||||
|
||||
### `MULTIPLE`
|
||||
|
||||
```python
|
||||
MULTIPLE = (5, 'auto', 'Line spacing is specified as multiple of line heights. Changing font size will change line spacing proportionately.')
|
||||
```
|
||||
|
||||
Line spacing is specified as multiple of line heights. Changing font size will
|
||||
change the line spacing proportionately.
|
||||
|
||||
### `ONE_POINT_FIVE`
|
||||
|
||||
```python
|
||||
ONE_POINT_FIVE = (1, 'UNMAPPED', 'Space-and-a-half line spacing.')
|
||||
```
|
||||
|
||||
Space-and-a-half line spacing.
|
||||
|
||||
### `SINGLE`
|
||||
|
||||
```python
|
||||
SINGLE = (0, 'UNMAPPED', 'Single spaced (default).')
|
||||
```
|
||||
|
||||
Single spaced (default).
|
||||
|
||||
## `WD_PARAGRAPH_ALIGNMENT`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Alias: **WD_ALIGN_PARAGRAPH**
|
||||
|
||||
Specifies paragraph justification type.
|
||||
|
||||
Example::
|
||||
|
||||
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
||||
|
||||
paragraph = document.add_paragraph()
|
||||
paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||
|
||||
### `CENTER`
|
||||
|
||||
```python
|
||||
CENTER = (1, 'center', 'Center-aligned.')
|
||||
```
|
||||
|
||||
Center-aligned.
|
||||
|
||||
### `DISTRIBUTE`
|
||||
|
||||
```python
|
||||
DISTRIBUTE = (4, 'distribute', 'Paragraph characters are distributed to fill entire width of paragraph.')
|
||||
```
|
||||
|
||||
Paragraph characters are distributed to fill entire width of paragraph.
|
||||
|
||||
### `JUSTIFY`
|
||||
|
||||
```python
|
||||
JUSTIFY = (3, 'both', 'Fully justified.')
|
||||
```
|
||||
|
||||
Fully justified.
|
||||
|
||||
### `JUSTIFY_HI`
|
||||
|
||||
```python
|
||||
JUSTIFY_HI = (7, 'highKashida', 'Justified with a high character compression ratio.')
|
||||
```
|
||||
|
||||
Justified with a high character compression ratio.
|
||||
|
||||
### `JUSTIFY_LOW`
|
||||
|
||||
```python
|
||||
JUSTIFY_LOW = (8, 'lowKashida', 'Justified with a low character compression ratio.')
|
||||
```
|
||||
|
||||
Justified with a low character compression ratio.
|
||||
|
||||
### `JUSTIFY_MED`
|
||||
|
||||
```python
|
||||
JUSTIFY_MED = (5, 'mediumKashida', 'Justified with a medium character compression ratio.')
|
||||
```
|
||||
|
||||
Justified with a medium character compression ratio.
|
||||
|
||||
### `LEFT`
|
||||
|
||||
```python
|
||||
LEFT = (0, 'left', 'Left-aligned')
|
||||
```
|
||||
|
||||
Left-aligned
|
||||
|
||||
### `RIGHT`
|
||||
|
||||
```python
|
||||
RIGHT = (2, 'right', 'Right-aligned.')
|
||||
```
|
||||
|
||||
Right-aligned.
|
||||
|
||||
### `THAI_JUSTIFY`
|
||||
|
||||
```python
|
||||
THAI_JUSTIFY = (9, 'thaiDistribute', 'Justified according to Thai formatting layout.')
|
||||
```
|
||||
|
||||
Justified according to Thai formatting layout.
|
||||
|
||||
## `WD_TAB_ALIGNMENT`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Specifies the tab stop alignment to apply.
|
||||
|
||||
MS API name: `WdTabAlignment`
|
||||
|
||||
URL: https://msdn.microsoft.com/EN-US/library/office/ff195609.aspx
|
||||
|
||||
### `BAR`
|
||||
|
||||
```python
|
||||
BAR = (4, 'bar', 'Bar-aligned.')
|
||||
```
|
||||
|
||||
Bar-aligned.
|
||||
|
||||
### `CENTER`
|
||||
|
||||
```python
|
||||
CENTER = (1, 'center', 'Center-aligned.')
|
||||
```
|
||||
|
||||
Center-aligned.
|
||||
|
||||
### `CLEAR`
|
||||
|
||||
```python
|
||||
CLEAR = (101, 'clear', 'Clear an inherited tab stop.')
|
||||
```
|
||||
|
||||
Clear an inherited tab stop.
|
||||
|
||||
### `DECIMAL`
|
||||
|
||||
```python
|
||||
DECIMAL = (3, 'decimal', 'Decimal-aligned.')
|
||||
```
|
||||
|
||||
Decimal-aligned.
|
||||
|
||||
### `END`
|
||||
|
||||
```python
|
||||
END = (102, 'end', 'Right-aligned. (deprecated)')
|
||||
```
|
||||
|
||||
Right-aligned. (deprecated)
|
||||
|
||||
### `LEFT`
|
||||
|
||||
```python
|
||||
LEFT = (0, 'left', 'Left-aligned.')
|
||||
```
|
||||
|
||||
Left-aligned.
|
||||
|
||||
### `LIST`
|
||||
|
||||
```python
|
||||
LIST = (6, 'list', 'List-aligned. (deprecated)')
|
||||
```
|
||||
|
||||
List-aligned. (deprecated)
|
||||
|
||||
### `NUM`
|
||||
|
||||
```python
|
||||
NUM = (103, 'num', 'Left-aligned. (deprecated)')
|
||||
```
|
||||
|
||||
Left-aligned. (deprecated)
|
||||
|
||||
### `RIGHT`
|
||||
|
||||
```python
|
||||
RIGHT = (2, 'right', 'Right-aligned.')
|
||||
```
|
||||
|
||||
Right-aligned.
|
||||
|
||||
### `START`
|
||||
|
||||
```python
|
||||
START = (104, 'start', 'Left-aligned. (deprecated)')
|
||||
```
|
||||
|
||||
Left-aligned. (deprecated)
|
||||
|
||||
## `WD_TAB_LEADER`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Specifies the character to use as the leader with formatted tabs.
|
||||
|
||||
MS API name: `WdTabLeader`
|
||||
|
||||
URL: https://msdn.microsoft.com/en-us/library/office/ff845050.aspx
|
||||
|
||||
### `DASHES`
|
||||
|
||||
```python
|
||||
DASHES = (2, 'hyphen', 'Dashes.')
|
||||
```
|
||||
|
||||
Dashes.
|
||||
|
||||
### `DOTS`
|
||||
|
||||
```python
|
||||
DOTS = (1, 'dot', 'Dots.')
|
||||
```
|
||||
|
||||
Dots.
|
||||
|
||||
### `HEAVY`
|
||||
|
||||
```python
|
||||
HEAVY = (4, 'heavy', 'A heavy line.')
|
||||
```
|
||||
|
||||
A heavy line.
|
||||
|
||||
### `LINES`
|
||||
|
||||
```python
|
||||
LINES = (3, 'underscore', 'Double lines.')
|
||||
```
|
||||
|
||||
Double lines.
|
||||
|
||||
### `MIDDLE_DOT`
|
||||
|
||||
```python
|
||||
MIDDLE_DOT = (5, 'middleDot', 'A vertically-centered dot.')
|
||||
```
|
||||
|
||||
A vertically-centered dot.
|
||||
|
||||
### `SPACES`
|
||||
|
||||
```python
|
||||
SPACES = (0, 'none', 'Spaces. Default.')
|
||||
```
|
||||
|
||||
Spaces. Default.
|
||||
|
||||
## `WD_UNDERLINE`
|
||||
|
||||
Bases: `BaseXmlEnum`
|
||||
|
||||
Specifies the style of underline applied to a run of characters.
|
||||
|
||||
MS API name: `WdUnderline`
|
||||
|
||||
URL: http://msdn.microsoft.com/en-us/library/office/ff822388.aspx
|
||||
|
||||
### `DASH`
|
||||
|
||||
```python
|
||||
DASH = (7, 'dash', 'Dashes.')
|
||||
```
|
||||
|
||||
Dashes.
|
||||
|
||||
### `DASH_HEAVY`
|
||||
|
||||
```python
|
||||
DASH_HEAVY = (23, 'dashedHeavy', 'Heavy dashes.')
|
||||
```
|
||||
|
||||
Heavy dashes.
|
||||
|
||||
### `DASH_LONG`
|
||||
|
||||
```python
|
||||
DASH_LONG = (39, 'dashLong', 'Long dashes.')
|
||||
```
|
||||
|
||||
Long dashes.
|
||||
|
||||
### `DASH_LONG_HEAVY`
|
||||
|
||||
```python
|
||||
DASH_LONG_HEAVY = (55, 'dashLongHeavy', 'Long heavy dashes.')
|
||||
```
|
||||
|
||||
Long heavy dashes.
|
||||
|
||||
### `DOTTED`
|
||||
|
||||
```python
|
||||
DOTTED = (4, 'dotted', 'Dots.')
|
||||
```
|
||||
|
||||
Dots.
|
||||
|
||||
### `DOTTED_HEAVY`
|
||||
|
||||
```python
|
||||
DOTTED_HEAVY = (20, 'dottedHeavy', 'Heavy dots.')
|
||||
```
|
||||
|
||||
Heavy dots.
|
||||
|
||||
### `DOT_DASH`
|
||||
|
||||
```python
|
||||
DOT_DASH = (9, 'dotDash', 'Alternating dots and dashes.')
|
||||
```
|
||||
|
||||
Alternating dots and dashes.
|
||||
|
||||
### `DOT_DASH_HEAVY`
|
||||
|
||||
```python
|
||||
DOT_DASH_HEAVY = (25, 'dashDotHeavy', 'Alternating heavy dots and heavy dashes.')
|
||||
```
|
||||
|
||||
Alternating heavy dots and heavy dashes.
|
||||
|
||||
### `DOT_DOT_DASH`
|
||||
|
||||
```python
|
||||
DOT_DOT_DASH = (10, 'dotDotDash', 'An alternating dot-dot-dash pattern.')
|
||||
```
|
||||
|
||||
An alternating dot-dot-dash pattern.
|
||||
|
||||
### `DOT_DOT_DASH_HEAVY`
|
||||
|
||||
```python
|
||||
DOT_DOT_DASH_HEAVY = (26, 'dashDotDotHeavy', 'An alternating heavy dot-dot-dash pattern.')
|
||||
```
|
||||
|
||||
An alternating heavy dot-dot-dash pattern.
|
||||
|
||||
### `DOUBLE`
|
||||
|
||||
```python
|
||||
DOUBLE = (3, 'double', 'A double line.')
|
||||
```
|
||||
|
||||
A double line.
|
||||
|
||||
### `INHERITED`
|
||||
|
||||
```python
|
||||
INHERITED = (-1, None, 'Inherit underline setting from containing paragraph.')
|
||||
```
|
||||
|
||||
Inherit underline setting from containing paragraph.
|
||||
|
||||
### `NONE`
|
||||
|
||||
```python
|
||||
NONE = (0, 'none', 'No underline.\n\nThis setting overrides any inherited underline value, so can be used to remove underline from a run that inherits underlining from its containing paragraph. Note this is not the same as assigning `None` to Run.underline. `None` is a valid assignment value, but causes the run to inherit its underline value. Assigning `WD_UNDERLINE.NONE` causes underlining to be unconditionally turned off.')
|
||||
```
|
||||
|
||||
No underline.
|
||||
|
||||
This setting overrides any inherited underline value, so can be used to remove
|
||||
underline from a run that inherits underlining from its containing paragraph. Note
|
||||
this is not the same as assigning `None` to Run.underline. `None` is a valid
|
||||
assignment value, but causes the run to inherit its underline value. Assigning
|
||||
``WD_UNDERLINE.NONE`` causes underlining to be unconditionally turned off.
|
||||
|
||||
### `SINGLE`
|
||||
|
||||
```python
|
||||
SINGLE = (1, 'single', 'A single line.\n\nNote that this setting is write-only in the sense that `True` (rather than `WD_UNDERLINE.SINGLE`) is returned for a run having this setting.')
|
||||
```
|
||||
|
||||
A single line.
|
||||
|
||||
Note that this setting is write-only in the sense that `True`
|
||||
(rather than ``WD_UNDERLINE.SINGLE``) is returned for a run having this setting.
|
||||
|
||||
### `THICK`
|
||||
|
||||
```python
|
||||
THICK = (6, 'thick', 'A single thick line.')
|
||||
```
|
||||
|
||||
A single thick line.
|
||||
|
||||
### `WAVY`
|
||||
|
||||
```python
|
||||
WAVY = (11, 'wave', 'A single wavy line.')
|
||||
```
|
||||
|
||||
A single wavy line.
|
||||
|
||||
### `WAVY_DOUBLE`
|
||||
|
||||
```python
|
||||
WAVY_DOUBLE = (43, 'wavyDouble', 'A double wavy line.')
|
||||
```
|
||||
|
||||
A double wavy line.
|
||||
|
||||
### `WAVY_HEAVY`
|
||||
|
||||
```python
|
||||
WAVY_HEAVY = (27, 'wavyHeavy', 'A heavy wavy line.')
|
||||
```
|
||||
|
||||
A heavy wavy line.
|
||||
|
||||
### `WORDS`
|
||||
|
||||
```python
|
||||
WORDS = (2, 'words', 'Underline individual words only.')
|
||||
```
|
||||
|
||||
Underline individual words only.
|
||||
@@ -1,96 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.errors`
|
||||
|
||||
Typed refusals for paper-docx safe-editing APIs.
|
||||
|
||||
## `AmbiguousTargetError`
|
||||
|
||||
Bases: `PaperRefusal`
|
||||
|
||||
The target specification matches more than one location.
|
||||
|
||||
Supply a more specific exact target: for example a live span or block, a
|
||||
narrower story, or an explicit `nth` when supported. To inspect contextual
|
||||
ranking without hiding candidates, use `find_text(..., near=...)`.
|
||||
|
||||
## `BoundaryViolationError`
|
||||
|
||||
Bases: `PaperRefusal`
|
||||
|
||||
The operation would cross a structural boundary it must respect.
|
||||
|
||||
Examples: a character-level replacement spanning a paragraph boundary or
|
||||
entering/leaving a content control; a block operation selecting
|
||||
paragraphs that do not share one parent.
|
||||
|
||||
## `DocumentProtectedError`
|
||||
|
||||
Bases: `PaperRefusal`
|
||||
|
||||
The document enforces an editing restriction this operation ignores.
|
||||
|
||||
Word honors `w:documentProtection` (read-only, forms-only, comments-only,
|
||||
tracked-changes-enforced); silently editing a locked template reports
|
||||
false state. Protection is ADVISORY, not security — after reviewing why
|
||||
the document is locked, call
|
||||
`docx.protection.acknowledge_protection(document)` to proceed. paper-docx
|
||||
never strips the protection setting itself.
|
||||
|
||||
## `MalformedPackageError`
|
||||
|
||||
Bases: `PaperRefusal`
|
||||
|
||||
The file is not a package this library can safely read.
|
||||
|
||||
Raised for a damaged or inconsistent ZIP envelope, an encrypted or
|
||||
unsupported member, a member name that cannot denote one part, and a
|
||||
`[Content_Types].xml` or relationship graph that does not describe a
|
||||
readable package. Validation runs before any XML is parsed or any output is
|
||||
replaced, so this is a safe refusal: nothing was read into the object model
|
||||
and nothing on disk was touched.
|
||||
|
||||
It does not mean the file is too large. Size and member-count ceilings were
|
||||
removed once Word was measured opening documents past all of them.
|
||||
|
||||
## `PaperRefusal`
|
||||
|
||||
Bases: `Exception`
|
||||
|
||||
Base for every safe refusal raised by paper-docx APIs.
|
||||
|
||||
A refused operation mutated nothing, in memory or on disk. The message
|
||||
states what was found and why it was unsafe to proceed.
|
||||
|
||||
## `RelationshipPolicyError`
|
||||
|
||||
Bases: `PaperRefusal`
|
||||
|
||||
The operation would create or modify a package relationship unsafely.
|
||||
|
||||
## `TargetNotFoundError`
|
||||
|
||||
Bases: `PaperRefusal`
|
||||
|
||||
No location matches the target specification.
|
||||
|
||||
Also raised when a previously-valid anchor or span has gone stale — the
|
||||
underlying content changed since it was captured.
|
||||
|
||||
## `UnsupportedStructureError`
|
||||
|
||||
Bases: `PaperRefusal`
|
||||
|
||||
The target involves structure this operation does not safely support.
|
||||
|
||||
Examples: text inside a tracked deletion or field instruction; a table
|
||||
with merged or nested cells; numbering that would require authoring new
|
||||
definitions.
|
||||
|
||||
## `check_install`
|
||||
|
||||
```python
|
||||
check_install() -> None
|
||||
```
|
||||
|
||||
Refuse when paper-docx and python-docx are both installed.
|
||||
@@ -1,25 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.exceptions`
|
||||
|
||||
Exceptions used with python-docx.
|
||||
|
||||
## `InvalidSpanError`
|
||||
|
||||
Bases: `PythonDocxError`
|
||||
|
||||
Raised when an invalid merge region is specified in a request to merge table
|
||||
cells.
|
||||
|
||||
## `InvalidXmlError`
|
||||
|
||||
Bases: `PythonDocxError`
|
||||
|
||||
Raised when invalid XML is encountered, such as on attempt to access a missing
|
||||
required child element.
|
||||
|
||||
## `PythonDocxError`
|
||||
|
||||
Bases: `Exception`
|
||||
|
||||
Generic error class.
|
||||
@@ -1,90 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.fields`
|
||||
|
||||
Field authoring — formulas, never values.
|
||||
|
||||
## `add_caption`
|
||||
|
||||
```python
|
||||
add_caption(paragraph: 'Paragraph', *, label: str = 'Figure', description: str = '') -> None
|
||||
```
|
||||
|
||||
Append a SEQ caption (`Figure 1`, `Table 1`) to `paragraph`.
|
||||
|
||||
Writes the field rather than the displayed integer, so Word recomputes the number on
|
||||
open. Sets the paragraph style to "Caption" without checking that the style exists.
|
||||
Refuses a protected document and an unknown label.
|
||||
|
||||
## `add_date_field`
|
||||
|
||||
```python
|
||||
add_date_field(paragraph: 'Paragraph', *, date_format: Optional[str] = None) -> None
|
||||
```
|
||||
|
||||
Append a DATE field; `date_format` is Word's \@ picture, for example 'MMMM d, yyyy'.
|
||||
|
||||
The result stays a placeholder until a renderer opens the file; this package never
|
||||
computes a date into the result. Refuses a protected document.
|
||||
|
||||
## `add_page_count_field`
|
||||
|
||||
```python
|
||||
add_page_count_field(paragraph: 'Paragraph') -> None
|
||||
```
|
||||
|
||||
Append a NUMPAGES field, typically to a footer paragraph.
|
||||
|
||||
Writes the field, not a number, so Word computes the count on open. Refuses a protected
|
||||
document.
|
||||
|
||||
## `add_page_number_field`
|
||||
|
||||
```python
|
||||
add_page_number_field(paragraph: 'Paragraph') -> None
|
||||
```
|
||||
|
||||
Append a PAGE field, typically to a footer paragraph.
|
||||
|
||||
Writes the field, not a number, so Word computes the page on open. Refuses a protected
|
||||
document.
|
||||
|
||||
## `add_reference_field`
|
||||
|
||||
```python
|
||||
add_reference_field(paragraph: 'Paragraph', *, bookmark: str, kind: str = 'text') -> None
|
||||
```
|
||||
|
||||
Append a cross-reference to `bookmark`: its text (`kind="text"`), page (`"page"`), or
|
||||
paragraph number (`"number"`).
|
||||
|
||||
Writes a REF field, so Word recomputes it on open. Refuses a protected document and an
|
||||
unknown bookmark name.
|
||||
|
||||
## `check_install`
|
||||
|
||||
```python
|
||||
check_install() -> None
|
||||
```
|
||||
|
||||
Refuse when paper-docx and python-docx are both installed.
|
||||
|
||||
## `insert_toc_after`
|
||||
|
||||
```python
|
||||
insert_toc_after(document: 'Document', anchor: 'Document', *, levels: Tuple[int, int] = (1, 3)) -> None
|
||||
```
|
||||
|
||||
Insert a TOC field in a new paragraph after `anchor`.
|
||||
|
||||
Marked dirty so the renderer builds the real table on open; heading `levels` maps to the
|
||||
\o "1-3" switch. Refuses a protected document, and an anchor that is missing, ambiguous
|
||||
foreign, or spans more than one paragraph.
|
||||
|
||||
## `rollback_on_error`
|
||||
|
||||
```python
|
||||
rollback_on_error(document: 'Document', *participants: Any) -> Generator[None, None, None]
|
||||
```
|
||||
|
||||
Restore the live package and named mutable proxies after an error.
|
||||
@@ -1,94 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.formatting`
|
||||
|
||||
Effective-format resolver — read-only, provenance-bearing.
|
||||
|
||||
## `EffectiveFormat`
|
||||
|
||||
```python
|
||||
EffectiveFormat(properties: Dict[str, ResolvedValue], unresolved: Tuple[str, ...]) -> None
|
||||
```
|
||||
|
||||
The resolved property map, plus what is declared unresolvable.
|
||||
|
||||
### `properties`
|
||||
|
||||
```python
|
||||
properties: Dict[str, ResolvedValue]
|
||||
```
|
||||
|
||||
### `to_dict`
|
||||
|
||||
```python
|
||||
to_dict() -> dict
|
||||
```
|
||||
|
||||
### `unresolved`
|
||||
|
||||
```python
|
||||
unresolved: Tuple[str, ...]
|
||||
```
|
||||
|
||||
### `value_of`
|
||||
|
||||
```python
|
||||
value_of(key: str)
|
||||
```
|
||||
|
||||
## `ResolvedValue`
|
||||
|
||||
```python
|
||||
ResolvedValue(value: object, source: str, chain: Tuple[str, ...] = ()) -> None
|
||||
```
|
||||
|
||||
One property's effective value and where it came from.
|
||||
|
||||
`source` is "direct", "character_style:<id>", "paragraph_style:<id>", "doc_defaults",
|
||||
"toggle_xor", "agreeing_layers", "mixed", or "none". `chain` holds the contributing
|
||||
layers.
|
||||
|
||||
### `chain`
|
||||
|
||||
```python
|
||||
chain: Tuple[str, ...] = ()
|
||||
```
|
||||
|
||||
### `source`
|
||||
|
||||
```python
|
||||
source: str
|
||||
```
|
||||
|
||||
### `to_dict`
|
||||
|
||||
```python
|
||||
to_dict() -> dict
|
||||
```
|
||||
|
||||
### `value`
|
||||
|
||||
```python
|
||||
value: object
|
||||
```
|
||||
|
||||
## `check_install`
|
||||
|
||||
```python
|
||||
check_install() -> None
|
||||
```
|
||||
|
||||
Refuse when paper-docx and python-docx are both installed.
|
||||
|
||||
## `format_of`
|
||||
|
||||
```python
|
||||
format_of(target) -> EffectiveFormat
|
||||
```
|
||||
|
||||
The effective formatting of a `Run`, `Paragraph` or `Span`.
|
||||
|
||||
Read-only and provenance-bearing: each `ResolvedValue` says where its value came from.
|
||||
Runs resolve the supported run-property subset; paragraphs resolve alignment and style
|
||||
plus the run defaults their style chain implies; spans resolve every run they touch and
|
||||
report "mixed" where runs disagree. Raises `TypeError` for anything else.
|
||||
@@ -1,35 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.image.bmp`
|
||||
|
||||
## `Bmp`
|
||||
|
||||
Bases: `BaseImageHeader`
|
||||
|
||||
Image header parser for BMP images.
|
||||
|
||||
### `content_type`
|
||||
|
||||
```python
|
||||
content_type
|
||||
```
|
||||
|
||||
MIME content type for this image, unconditionally `image/bmp` for BMP
|
||||
images.
|
||||
|
||||
### `default_ext`
|
||||
|
||||
```python
|
||||
default_ext
|
||||
```
|
||||
|
||||
Default filename extension, always 'bmp' for BMP images.
|
||||
|
||||
### `from_stream`
|
||||
|
||||
```python
|
||||
from_stream(stream)
|
||||
```
|
||||
|
||||
Return `Bmp` instance having header properties parsed from the BMP image in
|
||||
`stream`.
|
||||
@@ -1,469 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.image.constants`
|
||||
|
||||
Constants specific the the image sub-package.
|
||||
|
||||
## `JPEG_MARKER_CODE`
|
||||
|
||||
JPEG marker codes.
|
||||
|
||||
### `APP0`
|
||||
|
||||
```python
|
||||
APP0 = b'\xe0'
|
||||
```
|
||||
|
||||
### `APP1`
|
||||
|
||||
```python
|
||||
APP1 = b'\xe1'
|
||||
```
|
||||
|
||||
### `APP2`
|
||||
|
||||
```python
|
||||
APP2 = b'\xe2'
|
||||
```
|
||||
|
||||
### `APP3`
|
||||
|
||||
```python
|
||||
APP3 = b'\xe3'
|
||||
```
|
||||
|
||||
### `APP4`
|
||||
|
||||
```python
|
||||
APP4 = b'\xe4'
|
||||
```
|
||||
|
||||
### `APP5`
|
||||
|
||||
```python
|
||||
APP5 = b'\xe5'
|
||||
```
|
||||
|
||||
### `APP6`
|
||||
|
||||
```python
|
||||
APP6 = b'\xe6'
|
||||
```
|
||||
|
||||
### `APP7`
|
||||
|
||||
```python
|
||||
APP7 = b'\xe7'
|
||||
```
|
||||
|
||||
### `APP8`
|
||||
|
||||
```python
|
||||
APP8 = b'\xe8'
|
||||
```
|
||||
|
||||
### `APP9`
|
||||
|
||||
```python
|
||||
APP9 = b'\xe9'
|
||||
```
|
||||
|
||||
### `APPA`
|
||||
|
||||
```python
|
||||
APPA = b'\xea'
|
||||
```
|
||||
|
||||
### `APPB`
|
||||
|
||||
```python
|
||||
APPB = b'\xeb'
|
||||
```
|
||||
|
||||
### `APPC`
|
||||
|
||||
```python
|
||||
APPC = b'\xec'
|
||||
```
|
||||
|
||||
### `APPD`
|
||||
|
||||
```python
|
||||
APPD = b'\xed'
|
||||
```
|
||||
|
||||
### `APPE`
|
||||
|
||||
```python
|
||||
APPE = b'\xee'
|
||||
```
|
||||
|
||||
### `APPF`
|
||||
|
||||
```python
|
||||
APPF = b'\xef'
|
||||
```
|
||||
|
||||
### `DAC`
|
||||
|
||||
```python
|
||||
DAC = b'\xcc'
|
||||
```
|
||||
|
||||
### `DHP`
|
||||
|
||||
```python
|
||||
DHP = b'\xde'
|
||||
```
|
||||
|
||||
### `DHT`
|
||||
|
||||
```python
|
||||
DHT = b'\xc4'
|
||||
```
|
||||
|
||||
### `DNL`
|
||||
|
||||
```python
|
||||
DNL = b'\xdc'
|
||||
```
|
||||
|
||||
### `DQT`
|
||||
|
||||
```python
|
||||
DQT = b'\xdb'
|
||||
```
|
||||
|
||||
### `DRI`
|
||||
|
||||
```python
|
||||
DRI = b'\xdd'
|
||||
```
|
||||
|
||||
### `EOI`
|
||||
|
||||
```python
|
||||
EOI = b'\xd9'
|
||||
```
|
||||
|
||||
### `EXP`
|
||||
|
||||
```python
|
||||
EXP = b'\xdf'
|
||||
```
|
||||
|
||||
### `JPG`
|
||||
|
||||
```python
|
||||
JPG = b'\xc8'
|
||||
```
|
||||
|
||||
### `RST0`
|
||||
|
||||
```python
|
||||
RST0 = b'\xd0'
|
||||
```
|
||||
|
||||
### `RST1`
|
||||
|
||||
```python
|
||||
RST1 = b'\xd1'
|
||||
```
|
||||
|
||||
### `RST2`
|
||||
|
||||
```python
|
||||
RST2 = b'\xd2'
|
||||
```
|
||||
|
||||
### `RST3`
|
||||
|
||||
```python
|
||||
RST3 = b'\xd3'
|
||||
```
|
||||
|
||||
### `RST4`
|
||||
|
||||
```python
|
||||
RST4 = b'\xd4'
|
||||
```
|
||||
|
||||
### `RST5`
|
||||
|
||||
```python
|
||||
RST5 = b'\xd5'
|
||||
```
|
||||
|
||||
### `RST6`
|
||||
|
||||
```python
|
||||
RST6 = b'\xd6'
|
||||
```
|
||||
|
||||
### `RST7`
|
||||
|
||||
```python
|
||||
RST7 = b'\xd7'
|
||||
```
|
||||
|
||||
### `SOF0`
|
||||
|
||||
```python
|
||||
SOF0 = b'\xc0'
|
||||
```
|
||||
|
||||
### `SOF1`
|
||||
|
||||
```python
|
||||
SOF1 = b'\xc1'
|
||||
```
|
||||
|
||||
### `SOF2`
|
||||
|
||||
```python
|
||||
SOF2 = b'\xc2'
|
||||
```
|
||||
|
||||
### `SOF3`
|
||||
|
||||
```python
|
||||
SOF3 = b'\xc3'
|
||||
```
|
||||
|
||||
### `SOF5`
|
||||
|
||||
```python
|
||||
SOF5 = b'\xc5'
|
||||
```
|
||||
|
||||
### `SOF6`
|
||||
|
||||
```python
|
||||
SOF6 = b'\xc6'
|
||||
```
|
||||
|
||||
### `SOF7`
|
||||
|
||||
```python
|
||||
SOF7 = b'\xc7'
|
||||
```
|
||||
|
||||
### `SOF9`
|
||||
|
||||
```python
|
||||
SOF9 = b'\xc9'
|
||||
```
|
||||
|
||||
### `SOFA`
|
||||
|
||||
```python
|
||||
SOFA = b'\xca'
|
||||
```
|
||||
|
||||
### `SOFB`
|
||||
|
||||
```python
|
||||
SOFB = b'\xcb'
|
||||
```
|
||||
|
||||
### `SOFD`
|
||||
|
||||
```python
|
||||
SOFD = b'\xcd'
|
||||
```
|
||||
|
||||
### `SOFE`
|
||||
|
||||
```python
|
||||
SOFE = b'\xce'
|
||||
```
|
||||
|
||||
### `SOFF`
|
||||
|
||||
```python
|
||||
SOFF = b'\xcf'
|
||||
```
|
||||
|
||||
### `SOF_MARKER_CODES`
|
||||
|
||||
```python
|
||||
SOF_MARKER_CODES = (SOF0, SOF1, SOF2, SOF3, SOF5, SOF6, SOF7, SOF9, SOFA, SOFB, SOFD, SOFE, SOFF)
|
||||
```
|
||||
|
||||
### `SOI`
|
||||
|
||||
```python
|
||||
SOI = b'\xd8'
|
||||
```
|
||||
|
||||
### `SOS`
|
||||
|
||||
```python
|
||||
SOS = b'\xda'
|
||||
```
|
||||
|
||||
### `STANDALONE_MARKERS`
|
||||
|
||||
```python
|
||||
STANDALONE_MARKERS = (TEM, SOI, EOI, RST0, RST1, RST2, RST3, RST4, RST5, RST6, RST7)
|
||||
```
|
||||
|
||||
### `TEM`
|
||||
|
||||
```python
|
||||
TEM = b'\x01'
|
||||
```
|
||||
|
||||
### `is_standalone`
|
||||
|
||||
```python
|
||||
is_standalone(marker_code)
|
||||
```
|
||||
|
||||
### `marker_names`
|
||||
|
||||
```python
|
||||
marker_names = {b'\x00': 'UNKNOWN', b'\xc0': 'SOF0', b'\xc2': 'SOF2', b'\xc4': 'DHT', b'\xda': 'SOS', b'\xd8': 'SOI', b'\xd9': 'EOI', b'\xdb': 'DQT', b'\xe0': 'APP0', b'\xe1': 'APP1', b'\xe2': 'APP2', b'\xed': 'APP13', b'\xee': 'APP14'}
|
||||
```
|
||||
|
||||
## `MIME_TYPE`
|
||||
|
||||
Image content types.
|
||||
|
||||
### `BMP`
|
||||
|
||||
```python
|
||||
BMP = 'image/bmp'
|
||||
```
|
||||
|
||||
### `GIF`
|
||||
|
||||
```python
|
||||
GIF = 'image/gif'
|
||||
```
|
||||
|
||||
### `JPEG`
|
||||
|
||||
```python
|
||||
JPEG = 'image/jpeg'
|
||||
```
|
||||
|
||||
### `PNG`
|
||||
|
||||
```python
|
||||
PNG = 'image/png'
|
||||
```
|
||||
|
||||
### `TIFF`
|
||||
|
||||
```python
|
||||
TIFF = 'image/tiff'
|
||||
```
|
||||
|
||||
## `PNG_CHUNK_TYPE`
|
||||
|
||||
PNG chunk type names.
|
||||
|
||||
### `IEND`
|
||||
|
||||
```python
|
||||
IEND = 'IEND'
|
||||
```
|
||||
|
||||
### `IHDR`
|
||||
|
||||
```python
|
||||
IHDR = 'IHDR'
|
||||
```
|
||||
|
||||
### `pHYs`
|
||||
|
||||
```python
|
||||
pHYs = 'pHYs'
|
||||
```
|
||||
|
||||
## `TIFF_FLD`
|
||||
|
||||
```python
|
||||
TIFF_FLD = TIFF_FLD_TYPE
|
||||
```
|
||||
|
||||
## `TIFF_FLD_TYPE`
|
||||
|
||||
Tag codes for TIFF Image File Directory (IFD) entries.
|
||||
|
||||
### `ASCII`
|
||||
|
||||
```python
|
||||
ASCII = 2
|
||||
```
|
||||
|
||||
### `BYTE`
|
||||
|
||||
```python
|
||||
BYTE = 1
|
||||
```
|
||||
|
||||
### `LONG`
|
||||
|
||||
```python
|
||||
LONG = 4
|
||||
```
|
||||
|
||||
### `RATIONAL`
|
||||
|
||||
```python
|
||||
RATIONAL = 5
|
||||
```
|
||||
|
||||
### `SHORT`
|
||||
|
||||
```python
|
||||
SHORT = 3
|
||||
```
|
||||
|
||||
### `field_type_names`
|
||||
|
||||
```python
|
||||
field_type_names = {1: 'BYTE', 2: 'ASCII char', 3: 'SHORT', 4: 'LONG', 5: 'RATIONAL'}
|
||||
```
|
||||
|
||||
## `TIFF_TAG`
|
||||
|
||||
Tag codes for TIFF Image File Directory (IFD) entries.
|
||||
|
||||
### `IMAGE_LENGTH`
|
||||
|
||||
```python
|
||||
IMAGE_LENGTH = 257
|
||||
```
|
||||
|
||||
### `IMAGE_WIDTH`
|
||||
|
||||
```python
|
||||
IMAGE_WIDTH = 256
|
||||
```
|
||||
|
||||
### `RESOLUTION_UNIT`
|
||||
|
||||
```python
|
||||
RESOLUTION_UNIT = 296
|
||||
```
|
||||
|
||||
### `X_RESOLUTION`
|
||||
|
||||
```python
|
||||
X_RESOLUTION = 282
|
||||
```
|
||||
|
||||
### `Y_RESOLUTION`
|
||||
|
||||
```python
|
||||
Y_RESOLUTION = 283
|
||||
```
|
||||
|
||||
### `tag_names`
|
||||
|
||||
```python
|
||||
tag_names = {254: 'NewSubfileType', 256: 'ImageWidth', 257: 'ImageLength', 258: 'BitsPerSample', 259: 'Compression', 262: 'PhotometricInterpretation', 270: 'ImageDescription', 271: 'Make', 272: 'Model', 273: 'StripOffsets', 274: 'Orientation', 277: 'SamplesPerPixel', 279: 'StripByteCounts', 282: 'XResolution', 283: 'YResolution', 284: 'PlanarConfiguration', 296: 'ResolutionUnit', 305: 'Software', 306: 'DateTime', 531: 'YCbCrPositioning', 34665: 'ExifTag', 34853: 'GPS IFD', 50341: 'PrintImageMatching'}
|
||||
```
|
||||
@@ -1,23 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.image.exceptions`
|
||||
|
||||
Exceptions specific the the image sub-package.
|
||||
|
||||
## `InvalidImageStreamError`
|
||||
|
||||
Bases: `Exception`
|
||||
|
||||
The recognized image stream appears to be corrupted.
|
||||
|
||||
## `UnexpectedEndOfFileError`
|
||||
|
||||
Bases: `Exception`
|
||||
|
||||
EOF was unexpectedly encountered while reading an image stream.
|
||||
|
||||
## `UnrecognizedImageError`
|
||||
|
||||
Bases: `Exception`
|
||||
|
||||
The provided image stream could not be recognized.
|
||||
@@ -1,38 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.image.gif`
|
||||
|
||||
## `Gif`
|
||||
|
||||
Bases: `BaseImageHeader`
|
||||
|
||||
Image header parser for GIF images.
|
||||
|
||||
Note that the GIF format does not support resolution (DPI) information. Both
|
||||
horizontal and vertical DPI default to 72.
|
||||
|
||||
### `content_type`
|
||||
|
||||
```python
|
||||
content_type
|
||||
```
|
||||
|
||||
MIME content type for this image, unconditionally `image/gif` for GIF
|
||||
images.
|
||||
|
||||
### `default_ext`
|
||||
|
||||
```python
|
||||
default_ext
|
||||
```
|
||||
|
||||
Default filename extension, always 'gif' for GIF images.
|
||||
|
||||
### `from_stream`
|
||||
|
||||
```python
|
||||
from_stream(stream)
|
||||
```
|
||||
|
||||
Return `Gif` instance having header properties parsed from GIF image in
|
||||
`stream`.
|
||||
@@ -1,90 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.image.helpers`
|
||||
|
||||
## `BIG_ENDIAN`
|
||||
|
||||
```python
|
||||
BIG_ENDIAN = '>'
|
||||
```
|
||||
|
||||
## `LITTLE_ENDIAN`
|
||||
|
||||
```python
|
||||
LITTLE_ENDIAN = '<'
|
||||
```
|
||||
|
||||
## `StreamReader`
|
||||
|
||||
```python
|
||||
StreamReader(stream, byte_order, base_offset = 0)
|
||||
```
|
||||
|
||||
Wraps a file-like object to provide access to structured data from a binary file.
|
||||
|
||||
Byte-order is configurable. `base_offset` is added to any base value provided to
|
||||
calculate actual location for reads.
|
||||
|
||||
### `read`
|
||||
|
||||
```python
|
||||
read(count)
|
||||
```
|
||||
|
||||
Allow pass-through read() call.
|
||||
|
||||
### `read_byte`
|
||||
|
||||
```python
|
||||
read_byte(base, offset = 0)
|
||||
```
|
||||
|
||||
Return the int value of the byte at the file position defined by
|
||||
self._base_offset + `base` + `offset`.
|
||||
|
||||
If `base` is None, the byte is read from the current position in the stream.
|
||||
|
||||
### `read_long`
|
||||
|
||||
```python
|
||||
read_long(base, offset = 0)
|
||||
```
|
||||
|
||||
Return the int value of the four bytes at the file position defined by
|
||||
self._base_offset + `base` + `offset`.
|
||||
|
||||
If `base` is None, the long is read from the current position in the stream. The
|
||||
endian setting of this instance is used to interpret the byte layout of the
|
||||
long.
|
||||
|
||||
### `read_short`
|
||||
|
||||
```python
|
||||
read_short(base, offset = 0)
|
||||
```
|
||||
|
||||
Return the int value of the two bytes at the file position determined by
|
||||
`base` and `offset`, similarly to ``read_long()`` above.
|
||||
|
||||
### `read_str`
|
||||
|
||||
```python
|
||||
read_str(char_count, base, offset = 0)
|
||||
```
|
||||
|
||||
Return a string containing the `char_count` bytes at the file position
|
||||
determined by self._base_offset + `base` + `offset`.
|
||||
|
||||
### `seek`
|
||||
|
||||
```python
|
||||
seek(base, offset = 0)
|
||||
```
|
||||
|
||||
### `tell`
|
||||
|
||||
```python
|
||||
tell()
|
||||
```
|
||||
|
||||
Allow pass-through tell() call.
|
||||
@@ -1,214 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.image.image`
|
||||
|
||||
Provides objects that can characterize image streams.
|
||||
|
||||
## `BaseImageHeader`
|
||||
|
||||
```python
|
||||
BaseImageHeader(px_width: int, px_height: int, horz_dpi: int, vert_dpi: int)
|
||||
```
|
||||
|
||||
Base class for image header subclasses like `Jpeg` and `Tiff`.
|
||||
|
||||
### `content_type`
|
||||
|
||||
```python
|
||||
content_type: str
|
||||
```
|
||||
|
||||
Abstract property definition, must be implemented by all subclasses.
|
||||
|
||||
### `default_ext`
|
||||
|
||||
```python
|
||||
default_ext: str
|
||||
```
|
||||
|
||||
Default filename extension for images of this type.
|
||||
|
||||
An abstract property definition, must be implemented by all subclasses.
|
||||
|
||||
### `horz_dpi`
|
||||
|
||||
```python
|
||||
horz_dpi
|
||||
```
|
||||
|
||||
Integer dots per inch for the width of this image.
|
||||
|
||||
Defaults to 72 when not present in the file, as is often the case.
|
||||
|
||||
### `px_height`
|
||||
|
||||
```python
|
||||
px_height
|
||||
```
|
||||
|
||||
The vertical pixel dimension of the image.
|
||||
|
||||
### `px_width`
|
||||
|
||||
```python
|
||||
px_width
|
||||
```
|
||||
|
||||
The horizontal pixel dimension of the image.
|
||||
|
||||
### `vert_dpi`
|
||||
|
||||
```python
|
||||
vert_dpi
|
||||
```
|
||||
|
||||
Integer dots per inch for the height of this image.
|
||||
|
||||
Defaults to 72 when not present in the file, as is often the case.
|
||||
|
||||
## `Image`
|
||||
|
||||
```python
|
||||
Image(blob: bytes, filename: str, image_header: BaseImageHeader)
|
||||
```
|
||||
|
||||
Graphical image stream such as JPEG, PNG, or GIF with properties and methods
|
||||
required by ImagePart.
|
||||
|
||||
### `blob`
|
||||
|
||||
```python
|
||||
blob
|
||||
```
|
||||
|
||||
The bytes of the image 'file'.
|
||||
|
||||
### `content_type`
|
||||
|
||||
```python
|
||||
content_type: str
|
||||
```
|
||||
|
||||
MIME content type for this image, e.g. ``'image/jpeg'`` for a JPEG image.
|
||||
|
||||
### `ext`
|
||||
|
||||
```python
|
||||
ext()
|
||||
```
|
||||
|
||||
The file extension for the image.
|
||||
|
||||
If an actual one is available from a load filename it is used. Otherwise a
|
||||
canonical extension is assigned based on the content type. Does not contain the
|
||||
leading period, e.g. 'jpg', not '.jpg'.
|
||||
|
||||
### `filename`
|
||||
|
||||
```python
|
||||
filename
|
||||
```
|
||||
|
||||
Original image file name, if loaded from disk, or a generic filename if
|
||||
loaded from an anonymous stream.
|
||||
|
||||
### `from_blob`
|
||||
|
||||
```python
|
||||
from_blob(blob: bytes) -> Image
|
||||
```
|
||||
|
||||
Return a new `Image` subclass instance parsed from the image binary contained
|
||||
in `blob`.
|
||||
|
||||
### `from_file`
|
||||
|
||||
```python
|
||||
from_file(image_descriptor: str | IO[bytes])
|
||||
```
|
||||
|
||||
Return a new `Image` subclass instance loaded from the image file identified
|
||||
by `image_descriptor`, a path or file-like object.
|
||||
|
||||
### `height`
|
||||
|
||||
```python
|
||||
height: Inches
|
||||
```
|
||||
|
||||
A `Length` value representing the native height of the image, calculated from
|
||||
the values of `px_height` and `vert_dpi`.
|
||||
|
||||
### `horz_dpi`
|
||||
|
||||
```python
|
||||
horz_dpi: int
|
||||
```
|
||||
|
||||
Integer dots per inch for the width of this image.
|
||||
|
||||
Defaults to 72 when not present in the file, as is often the case.
|
||||
|
||||
### `px_height`
|
||||
|
||||
```python
|
||||
px_height: int
|
||||
```
|
||||
|
||||
The vertical pixel dimension of the image.
|
||||
|
||||
### `px_width`
|
||||
|
||||
```python
|
||||
px_width: int
|
||||
```
|
||||
|
||||
The horizontal pixel dimension of the image.
|
||||
|
||||
### `scaled_dimensions`
|
||||
|
||||
```python
|
||||
scaled_dimensions(width: int | Length | None = None, height: int | Length | None = None) -> Tuple[Length, Length]
|
||||
```
|
||||
|
||||
(cx, cy) pair representing scaled dimensions of this image.
|
||||
|
||||
The native dimensions of the image are scaled by applying the following rules to
|
||||
the `width` and `height` arguments.
|
||||
|
||||
* If both `width` and `height` are specified, the return value is (`width`,
|
||||
`height`); no scaling is performed.
|
||||
* If only one is specified, it is used to compute a scaling factor that is then
|
||||
applied to the unspecified dimension, preserving the aspect ratio of the image.
|
||||
* If both `width` and `height` are `None`, the native dimensions are returned.
|
||||
|
||||
The native dimensions are calculated using the dots-per-inch (dpi) value
|
||||
embedded in the image, defaulting to 72 dpi if no value is specified, as is
|
||||
often the case. The returned values are both `Length` objects.
|
||||
|
||||
### `sha1`
|
||||
|
||||
```python
|
||||
sha1()
|
||||
```
|
||||
|
||||
SHA1 hash digest of the image blob.
|
||||
|
||||
### `vert_dpi`
|
||||
|
||||
```python
|
||||
vert_dpi: int
|
||||
```
|
||||
|
||||
Integer dots per inch for the height of this image.
|
||||
|
||||
Defaults to 72 when not present in the file, as is often the case.
|
||||
|
||||
### `width`
|
||||
|
||||
```python
|
||||
width: Inches
|
||||
```
|
||||
|
||||
A `Length` value representing the native width of the image, calculated from
|
||||
the values of `px_width` and `horz_dpi`.
|
||||
@@ -1,58 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.image.jpeg`
|
||||
|
||||
Objects related to parsing headers of JPEG image streams.
|
||||
|
||||
## `Exif`
|
||||
|
||||
Bases: `Jpeg`
|
||||
|
||||
Image header parser for Exif image format.
|
||||
|
||||
### `from_stream`
|
||||
|
||||
```python
|
||||
from_stream(stream)
|
||||
```
|
||||
|
||||
Return `Exif` instance having header properties parsed from Exif image in
|
||||
`stream`.
|
||||
|
||||
## `Jfif`
|
||||
|
||||
Bases: `Jpeg`
|
||||
|
||||
Image header parser for JFIF image format.
|
||||
|
||||
### `from_stream`
|
||||
|
||||
```python
|
||||
from_stream(stream)
|
||||
```
|
||||
|
||||
Return a `Jfif` instance having header properties parsed from image in
|
||||
`stream`.
|
||||
|
||||
## `Jpeg`
|
||||
|
||||
Bases: `BaseImageHeader`
|
||||
|
||||
Base class for JFIF and EXIF subclasses.
|
||||
|
||||
### `content_type`
|
||||
|
||||
```python
|
||||
content_type
|
||||
```
|
||||
|
||||
MIME content type for this image, unconditionally `image/jpeg` for JPEG
|
||||
images.
|
||||
|
||||
### `default_ext`
|
||||
|
||||
```python
|
||||
default_ext
|
||||
```
|
||||
|
||||
Default filename extension, always 'jpg' for JPG images.
|
||||
@@ -1,11 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.image`
|
||||
|
||||
Provides objects that can characterize image streams.
|
||||
|
||||
## `SIGNATURES`
|
||||
|
||||
```python
|
||||
SIGNATURES = ((Png, 0, b'\x89PNG\r\n\x1a\n'), (Jfif, 6, b'JFIF'), (Exif, 6, b'Exif'), (Gif, 0, b'GIF87a'), (Gif, 0, b'GIF89a'), (Tiff, 0, b'MM\x00*'), (Tiff, 0, b'II*\x00'), (Bmp, 0, b'BM'))
|
||||
```
|
||||
@@ -1,35 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.image.png`
|
||||
|
||||
## `Png`
|
||||
|
||||
Bases: `BaseImageHeader`
|
||||
|
||||
Image header parser for PNG images.
|
||||
|
||||
### `content_type`
|
||||
|
||||
```python
|
||||
content_type
|
||||
```
|
||||
|
||||
MIME content type for this image, unconditionally `image/png` for PNG
|
||||
images.
|
||||
|
||||
### `default_ext`
|
||||
|
||||
```python
|
||||
default_ext
|
||||
```
|
||||
|
||||
Default filename extension, always 'png' for PNG images.
|
||||
|
||||
### `from_stream`
|
||||
|
||||
```python
|
||||
from_stream(stream)
|
||||
```
|
||||
|
||||
Return a `Png` instance having header properties parsed from image in
|
||||
`stream`.
|
||||
@@ -1,37 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.image.tiff`
|
||||
|
||||
## `Tiff`
|
||||
|
||||
Bases: `BaseImageHeader`
|
||||
|
||||
Image header parser for TIFF images.
|
||||
|
||||
Handles both big and little endian byte ordering.
|
||||
|
||||
### `content_type`
|
||||
|
||||
```python
|
||||
content_type
|
||||
```
|
||||
|
||||
Return the MIME type of this TIFF image, unconditionally the string
|
||||
``image/tiff``.
|
||||
|
||||
### `default_ext`
|
||||
|
||||
```python
|
||||
default_ext
|
||||
```
|
||||
|
||||
Default filename extension, always 'tiff' for TIFF images.
|
||||
|
||||
### `from_stream`
|
||||
|
||||
```python
|
||||
from_stream(stream)
|
||||
```
|
||||
|
||||
Return a `Tiff` instance containing the properties of the TIFF image in
|
||||
`stream`.
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,42 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.links`
|
||||
|
||||
Create and retarget hyperlinks on existing text.
|
||||
|
||||
## `add_hyperlink`
|
||||
|
||||
```python
|
||||
add_hyperlink(document: 'Document', span: 'Span', address: str) -> Hyperlink
|
||||
```
|
||||
|
||||
Wrap `span`'s runs in a hyperlink pointing at `address`.
|
||||
|
||||
Visible text stays; Word shows it in the Hyperlink character style, which this defines
|
||||
when the document lacks it. Refuses a protected document, a stale or foreign span, a span
|
||||
crossing paragraphs, a field result, an existing hyperlink, and a data-bound, locked or
|
||||
plain-text control surface.
|
||||
|
||||
## `check_install`
|
||||
|
||||
```python
|
||||
check_install() -> None
|
||||
```
|
||||
|
||||
Refuse when paper-docx and python-docx are both installed.
|
||||
|
||||
## `require_span_owner`
|
||||
|
||||
```python
|
||||
require_span_owner(document: 'Document', span: 'Span', *, argument: str = 'span') -> None
|
||||
```
|
||||
|
||||
Refuse a live span captured from a different document package.
|
||||
|
||||
## `rollback_on_error`
|
||||
|
||||
```python
|
||||
rollback_on_error(document: 'Document', *participants: Any) -> Generator[None, None, None]
|
||||
```
|
||||
|
||||
Restore the live package and named mutable proxies after an error.
|
||||
@@ -1,53 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.notes`
|
||||
|
||||
Create footnotes and endnotes, including the note body and the mark.
|
||||
|
||||
## `add_endnote`
|
||||
|
||||
```python
|
||||
add_endnote(document: 'Document', span: 'Span', text: str) -> int
|
||||
```
|
||||
|
||||
Attach an endnote to `span` and return its note id.
|
||||
|
||||
Creates the endnotes part on first use. Same refusals as `add_footnote`: protection, a
|
||||
stale or foreign span, a span outside the main body, and one inside a text box, a field
|
||||
result, or a data-bound, locked or plain-text control.
|
||||
|
||||
## `add_footnote`
|
||||
|
||||
```python
|
||||
add_footnote(document: 'Document', span: 'Span', text: str) -> int
|
||||
```
|
||||
|
||||
Attach a footnote to `span` and return its note id.
|
||||
|
||||
Creates the footnotes part on first use. Refuses a protected document, a stale or foreign
|
||||
span, a span outside the main body, and one inside a text box, a field result, or a
|
||||
data-bound, locked or plain-text control.
|
||||
|
||||
## `check_install`
|
||||
|
||||
```python
|
||||
check_install() -> None
|
||||
```
|
||||
|
||||
Refuse when paper-docx and python-docx are both installed.
|
||||
|
||||
## `require_span_owner`
|
||||
|
||||
```python
|
||||
require_span_owner(document: 'Document', span: 'Span', *, argument: str = 'span') -> None
|
||||
```
|
||||
|
||||
Refuse a live span captured from a different document package.
|
||||
|
||||
## `rollback_on_error`
|
||||
|
||||
```python
|
||||
rollback_on_error(document: 'Document', *participants: Any) -> Generator[None, None, None]
|
||||
```
|
||||
|
||||
Restore the live package and named mutable proxies after an error.
|
||||
@@ -1,215 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.numbering`
|
||||
|
||||
Numbering enumeration, application, and minimal authoring (paper-docx).
|
||||
|
||||
## `NumberedParagraph`
|
||||
|
||||
```python
|
||||
NumberedParagraph(story: str, index: int, num_id: int, level: int, text: str, table_cell: 'Optional[Tuple[int, int, int]]' = None) -> None
|
||||
```
|
||||
|
||||
### `index`
|
||||
|
||||
```python
|
||||
index: int
|
||||
```
|
||||
|
||||
### `level`
|
||||
|
||||
```python
|
||||
level: int
|
||||
```
|
||||
|
||||
### `num_id`
|
||||
|
||||
```python
|
||||
num_id: int
|
||||
```
|
||||
|
||||
### `story`
|
||||
|
||||
```python
|
||||
story: str
|
||||
```
|
||||
|
||||
### `table_cell`
|
||||
|
||||
```python
|
||||
table_cell: 'Optional[Tuple[int, int, int]]' = None
|
||||
```
|
||||
|
||||
### `text`
|
||||
|
||||
```python
|
||||
text: str
|
||||
```
|
||||
|
||||
### `to_dict`
|
||||
|
||||
```python
|
||||
to_dict() -> dict
|
||||
```
|
||||
|
||||
## `NumberingDefinition`
|
||||
|
||||
```python
|
||||
NumberingDefinition(num_id: int, abstract_num_id: int, levels: Tuple[NumberingLevel, ...]) -> None
|
||||
```
|
||||
|
||||
### `abstract_num_id`
|
||||
|
||||
```python
|
||||
abstract_num_id: int
|
||||
```
|
||||
|
||||
### `levels`
|
||||
|
||||
```python
|
||||
levels: Tuple[NumberingLevel, ...]
|
||||
```
|
||||
|
||||
### `num_id`
|
||||
|
||||
```python
|
||||
num_id: int
|
||||
```
|
||||
|
||||
### `to_dict`
|
||||
|
||||
```python
|
||||
to_dict() -> dict
|
||||
```
|
||||
|
||||
## `NumberingLevel`
|
||||
|
||||
```python
|
||||
NumberingLevel(level: int, num_fmt: Optional[str], lvl_text: Optional[str]) -> None
|
||||
```
|
||||
|
||||
### `level`
|
||||
|
||||
```python
|
||||
level: int
|
||||
```
|
||||
|
||||
### `lvl_text`
|
||||
|
||||
```python
|
||||
lvl_text: Optional[str]
|
||||
```
|
||||
|
||||
### `num_fmt`
|
||||
|
||||
```python
|
||||
num_fmt: Optional[str]
|
||||
```
|
||||
|
||||
### `to_dict`
|
||||
|
||||
```python
|
||||
to_dict() -> dict
|
||||
```
|
||||
|
||||
## `NumberingReport`
|
||||
|
||||
```python
|
||||
NumberingReport(definitions: Tuple[NumberingDefinition, ...], numbered_paragraphs: Tuple[NumberedParagraph, ...]) -> None
|
||||
```
|
||||
|
||||
### `definitions`
|
||||
|
||||
```python
|
||||
definitions: Tuple[NumberingDefinition, ...]
|
||||
```
|
||||
|
||||
### `numbered_paragraphs`
|
||||
|
||||
```python
|
||||
numbered_paragraphs: Tuple[NumberedParagraph, ...]
|
||||
```
|
||||
|
||||
### `to_dict`
|
||||
|
||||
```python
|
||||
to_dict() -> dict
|
||||
```
|
||||
|
||||
## `apply_list_style`
|
||||
|
||||
```python
|
||||
apply_list_style(paragraph: 'Paragraph', style_name: str) -> None
|
||||
```
|
||||
|
||||
Apply the existing paragraph style `style_name` to `paragraph`.
|
||||
|
||||
Refuses a protected document, a style the document does not define, and a style whose
|
||||
numbering binding does not resolve.
|
||||
|
||||
## `apply_numbering`
|
||||
|
||||
```python
|
||||
apply_numbering(paragraph: 'Paragraph', *, num_id: int, level: int = 0) -> None
|
||||
```
|
||||
|
||||
Give `paragraph` the existing numbering definition `num_id` at `level`.
|
||||
|
||||
Writes `w:numPr` into the paragraph's `w:pPr`. This never fabricates a definition; create
|
||||
one deliberately with `ensure_bullet_definition` or `ensure_decimal_definition`. Refuses a
|
||||
protected document, and a numId or level the document does not define.
|
||||
|
||||
## `check_install`
|
||||
|
||||
```python
|
||||
check_install() -> None
|
||||
```
|
||||
|
||||
Refuse when paper-docx and python-docx are both installed.
|
||||
|
||||
## `ensure_bullet_definition`
|
||||
|
||||
```python
|
||||
ensure_bullet_definition(document: 'Document') -> int
|
||||
```
|
||||
|
||||
The numId of a canonical bullet-list definition, creating it when absent.
|
||||
|
||||
Creates `/word/numbering.xml` and its relationship on first use. Reuse requires an exactly
|
||||
canonical definition, so a hand-edited one of the same name is left alone and a new
|
||||
definition is appended. Refuses a protected document.
|
||||
|
||||
## `ensure_decimal_definition`
|
||||
|
||||
```python
|
||||
ensure_decimal_definition(document: 'Document') -> int
|
||||
```
|
||||
|
||||
The numId of a canonical decimal-list definition, creating it when absent.
|
||||
|
||||
Same creation and exact-shape reuse rules as `ensure_bullet_definition`. Refuses a
|
||||
protected document.
|
||||
|
||||
## `list_numbering`
|
||||
|
||||
```python
|
||||
list_numbering(document: 'Document') -> NumberingReport
|
||||
```
|
||||
|
||||
Every numbering definition and every numbered paragraph in `document`.
|
||||
|
||||
Walks all story parts and reports text in the "current" view. Refuses when a paragraph
|
||||
resolves to a definition the document does not define, or to a level that definition
|
||||
omits.
|
||||
|
||||
## `restart_numbering`
|
||||
|
||||
```python
|
||||
restart_numbering(document: 'Document', *, num_id: int) -> int
|
||||
```
|
||||
|
||||
A NEW numId continuing `num_id`'s formatting but restarting the count at 1.
|
||||
|
||||
Paragraphs are not re-pointed; re-point them yourself with `apply_numbering`. Refuses a
|
||||
protected document, an unknown numId, a malformed `w:numId`, and a definition carrying
|
||||
`w:lvlOverride`.
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,104 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.opc.coreprops`
|
||||
|
||||
Provides CoreProperties, Dublin-Core attributes of the document.
|
||||
|
||||
## `CoreProperties`
|
||||
|
||||
```python
|
||||
CoreProperties(element: CT_CoreProperties)
|
||||
```
|
||||
|
||||
Corresponds to part named ``/docProps/core.xml``, containing the core document
|
||||
properties for this document package.
|
||||
|
||||
### `author`
|
||||
|
||||
```python
|
||||
author
|
||||
```
|
||||
|
||||
### `category`
|
||||
|
||||
```python
|
||||
category
|
||||
```
|
||||
|
||||
### `comments`
|
||||
|
||||
```python
|
||||
comments
|
||||
```
|
||||
|
||||
### `content_status`
|
||||
|
||||
```python
|
||||
content_status
|
||||
```
|
||||
|
||||
### `created`
|
||||
|
||||
```python
|
||||
created
|
||||
```
|
||||
|
||||
### `identifier`
|
||||
|
||||
```python
|
||||
identifier
|
||||
```
|
||||
|
||||
### `keywords`
|
||||
|
||||
```python
|
||||
keywords
|
||||
```
|
||||
|
||||
### `language`
|
||||
|
||||
```python
|
||||
language
|
||||
```
|
||||
|
||||
### `last_modified_by`
|
||||
|
||||
```python
|
||||
last_modified_by
|
||||
```
|
||||
|
||||
### `last_printed`
|
||||
|
||||
```python
|
||||
last_printed
|
||||
```
|
||||
|
||||
### `modified`
|
||||
|
||||
```python
|
||||
modified
|
||||
```
|
||||
|
||||
### `revision`
|
||||
|
||||
```python
|
||||
revision
|
||||
```
|
||||
|
||||
### `subject`
|
||||
|
||||
```python
|
||||
subject
|
||||
```
|
||||
|
||||
### `title`
|
||||
|
||||
```python
|
||||
title
|
||||
```
|
||||
|
||||
### `version`
|
||||
|
||||
```python
|
||||
version
|
||||
```
|
||||
@@ -1,17 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.opc.exceptions`
|
||||
|
||||
Exceptions specific to python-opc.
|
||||
|
||||
## `OpcError`
|
||||
|
||||
Bases: `Exception`
|
||||
|
||||
Base error class for python-opc.
|
||||
|
||||
## `PackageNotFoundError`
|
||||
|
||||
Bases: `OpcError`
|
||||
|
||||
Raised when a package cannot be found at the specified path.
|
||||
@@ -1,292 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.opc.oxml`
|
||||
|
||||
Temporary stand-in for main oxml module.
|
||||
|
||||
## `BaseOxmlElement`
|
||||
|
||||
Bases: `ElementBase`
|
||||
|
||||
Base class for all custom element classes, to add standardized behavior to all
|
||||
classes in one place.
|
||||
|
||||
### `xml`
|
||||
|
||||
```python
|
||||
xml: str
|
||||
```
|
||||
|
||||
Return XML string for this element, suitable for testing purposes.
|
||||
|
||||
Pretty printed for readability and without an XML declaration at the top.
|
||||
|
||||
## `CT_Default`
|
||||
|
||||
Bases: `BaseOxmlElement`
|
||||
|
||||
`<Default>` element that appears in `[Content_Types].xml` part.
|
||||
|
||||
Used to specify a default content type to be applied to any part with the specified extension.
|
||||
|
||||
### `content_type`
|
||||
|
||||
```python
|
||||
content_type
|
||||
```
|
||||
|
||||
String held in the ``ContentType`` attribute of this ``<Default>``
|
||||
element.
|
||||
|
||||
### `extension`
|
||||
|
||||
```python
|
||||
extension
|
||||
```
|
||||
|
||||
String held in the ``Extension`` attribute of this ``<Default>`` element.
|
||||
|
||||
### `new`
|
||||
|
||||
```python
|
||||
new(ext: str, content_type: str)
|
||||
```
|
||||
|
||||
Return a new ``<Default>`` element with attributes set to parameter values.
|
||||
|
||||
## `CT_Override`
|
||||
|
||||
Bases: `BaseOxmlElement`
|
||||
|
||||
``<Override>`` element, specifying the content type to be applied for a part with
|
||||
the specified partname.
|
||||
|
||||
### `content_type`
|
||||
|
||||
```python
|
||||
content_type
|
||||
```
|
||||
|
||||
String held in the ``ContentType`` attribute of this ``<Override>``
|
||||
element.
|
||||
|
||||
### `new`
|
||||
|
||||
```python
|
||||
new(partname, content_type)
|
||||
```
|
||||
|
||||
Return a new ``<Override>`` element with attributes set to parameter values.
|
||||
|
||||
### `partname`
|
||||
|
||||
```python
|
||||
partname
|
||||
```
|
||||
|
||||
String held in the ``PartName`` attribute of this ``<Override>`` element.
|
||||
|
||||
## `CT_Relationship`
|
||||
|
||||
Bases: `BaseOxmlElement`
|
||||
|
||||
`<Relationship>` element, representing a single relationship from source to target part.
|
||||
|
||||
### `new`
|
||||
|
||||
```python
|
||||
new(rId: str, reltype: str, target: str, target_mode: str = RTM.INTERNAL)
|
||||
```
|
||||
|
||||
Return a new ``<Relationship>`` element.
|
||||
|
||||
### `rId`
|
||||
|
||||
```python
|
||||
rId
|
||||
```
|
||||
|
||||
String held in the ``Id`` attribute of this ``<Relationship>`` element.
|
||||
|
||||
### `reltype`
|
||||
|
||||
```python
|
||||
reltype
|
||||
```
|
||||
|
||||
String held in the ``Type`` attribute of this ``<Relationship>`` element.
|
||||
|
||||
### `target_mode`
|
||||
|
||||
```python
|
||||
target_mode
|
||||
```
|
||||
|
||||
String held in the ``TargetMode`` attribute of this ``<Relationship>``
|
||||
element, either ``Internal`` or ``External``.
|
||||
|
||||
Defaults to ``Internal``.
|
||||
|
||||
### `target_ref`
|
||||
|
||||
```python
|
||||
target_ref
|
||||
```
|
||||
|
||||
String held in the ``Target`` attribute of this ``<Relationship>``
|
||||
element.
|
||||
|
||||
## `CT_Relationships`
|
||||
|
||||
Bases: `BaseOxmlElement`
|
||||
|
||||
``<Relationships>`` element, the root element in a .rels file.
|
||||
|
||||
### `Relationship_lst`
|
||||
|
||||
```python
|
||||
Relationship_lst
|
||||
```
|
||||
|
||||
Return a list containing all the ``<Relationship>`` child elements.
|
||||
|
||||
### `add_rel`
|
||||
|
||||
```python
|
||||
add_rel(rId: str, reltype: str, target: str, is_external: bool = False)
|
||||
```
|
||||
|
||||
Add a child ``<Relationship>`` element with attributes set according to
|
||||
parameter values.
|
||||
|
||||
### `new`
|
||||
|
||||
```python
|
||||
new() -> CT_Relationships
|
||||
```
|
||||
|
||||
Return a new ``<Relationships>`` element.
|
||||
|
||||
### `xml`
|
||||
|
||||
```python
|
||||
xml
|
||||
```
|
||||
|
||||
Return XML string for this element, suitable for saving in a .rels stream,
|
||||
not pretty printed and with an XML declaration at the top.
|
||||
|
||||
## `CT_Types`
|
||||
|
||||
Bases: `BaseOxmlElement`
|
||||
|
||||
``<Types>`` element, the container element for Default and Override elements in
|
||||
[Content_Types].xml.
|
||||
|
||||
### `add_default`
|
||||
|
||||
```python
|
||||
add_default(ext, content_type)
|
||||
```
|
||||
|
||||
Add a child ``<Default>`` element with attributes set to parameter values.
|
||||
|
||||
### `add_override`
|
||||
|
||||
```python
|
||||
add_override(partname, content_type)
|
||||
```
|
||||
|
||||
Add a child ``<Override>`` element with attributes set to parameter
|
||||
values.
|
||||
|
||||
### `defaults`
|
||||
|
||||
```python
|
||||
defaults
|
||||
```
|
||||
|
||||
### `new`
|
||||
|
||||
```python
|
||||
new()
|
||||
```
|
||||
|
||||
Return a new ``<Types>`` element.
|
||||
|
||||
### `overrides`
|
||||
|
||||
```python
|
||||
overrides
|
||||
```
|
||||
|
||||
## `ct_namespace`
|
||||
|
||||
```python
|
||||
ct_namespace = element_class_lookup.get_namespace(nsmap['ct'])
|
||||
```
|
||||
|
||||
## `element_class_lookup`
|
||||
|
||||
```python
|
||||
element_class_lookup = etree.ElementNamespaceClassLookup()
|
||||
```
|
||||
|
||||
## `nsmap`
|
||||
|
||||
```python
|
||||
nsmap = {'ct': NS.OPC_CONTENT_TYPES, 'pr': NS.OPC_RELATIONSHIPS, 'r': NS.OFC_RELATIONSHIPS}
|
||||
```
|
||||
|
||||
## `oxml_parser`
|
||||
|
||||
```python
|
||||
oxml_parser = etree.XMLParser(remove_blank_text=True, resolve_entities=False)
|
||||
```
|
||||
|
||||
## `parse_xml`
|
||||
|
||||
```python
|
||||
parse_xml(text: str) -> etree._Element
|
||||
```
|
||||
|
||||
`etree.fromstring()` replacement that uses oxml parser.
|
||||
|
||||
## `pr_namespace`
|
||||
|
||||
```python
|
||||
pr_namespace = element_class_lookup.get_namespace(nsmap['pr'])
|
||||
```
|
||||
|
||||
## `qn`
|
||||
|
||||
```python
|
||||
qn(tag: str) -> str
|
||||
```
|
||||
|
||||
Stands for "qualified name", a utility function to turn a namespace prefixed tag
|
||||
name into a Clark-notation qualified tag name for lxml.
|
||||
|
||||
For
|
||||
example, ``qn('p:cSld')`` returns ``'{http://schemas.../main}cSld'``.
|
||||
|
||||
## `serialize_for_reading`
|
||||
|
||||
```python
|
||||
serialize_for_reading(element: etree._Element) -> str
|
||||
```
|
||||
|
||||
Serialize `element` to human-readable XML suitable for tests.
|
||||
|
||||
No XML declaration.
|
||||
|
||||
## `serialize_part_xml`
|
||||
|
||||
```python
|
||||
serialize_part_xml(part_elm: etree._Element) -> bytes
|
||||
```
|
||||
|
||||
Serialize `part_elm` etree element to XML suitable for storage as an XML part.
|
||||
|
||||
That is to say, no insignificant whitespace added for readability, and an
|
||||
appropriate XML declaration added with UTF-8 encoding specified.
|
||||
@@ -1,166 +0,0 @@
|
||||
<!-- Generated from docx 0.2.0 docstrings by griffe2md. Do not edit: fix the docstring in the source. -->
|
||||
|
||||
# `docx.opc.package`
|
||||
|
||||
Objects that implement reading and writing OPC packages.
|
||||
|
||||
## `OpcPackage`
|
||||
|
||||
Main API class for `python-opc`.
|
||||
|
||||
A new instance is constructed by calling the `open` class method with a path
|
||||
to a package file or file-like object containing one.
|
||||
|
||||
### `after_unmarshal`
|
||||
|
||||
```python
|
||||
after_unmarshal()
|
||||
```
|
||||
|
||||
Entry point for any post-unmarshaling processing.
|
||||
|
||||
May be overridden by subclasses without forwarding call to super.
|
||||
|
||||
### `core_properties`
|
||||
|
||||
```python
|
||||
core_properties: CoreProperties
|
||||
```
|
||||
|
||||
`CoreProperties` object providing read/write access to the Dublin Core
|
||||
properties for this document.
|
||||
|
||||
### `iter_parts`
|
||||
|
||||
```python
|
||||
iter_parts() -> Iterator[Part]
|
||||
```
|
||||
|
||||
Generate exactly one reference to each of the parts in the package by
|
||||
performing a depth-first traversal of the rels graph.
|
||||
|
||||
### `iter_rels`
|
||||
|
||||
```python
|
||||
iter_rels() -> Iterator[_Relationship]
|
||||
```
|
||||
|
||||
Generate exactly one reference to each relationship in the package by
|
||||
performing a depth-first traversal of the rels graph.
|
||||
|
||||
### `load_rel`
|
||||
|
||||
```python
|
||||
load_rel(reltype: str, target: Part | str, rId: str, is_external: bool = False)
|
||||
```
|
||||
|
||||
Return newly added `_Relationship` instance of `reltype` between this part
|
||||
and `target` with key `rId`.
|
||||
|
||||
Target mode is set to ``RTM.EXTERNAL`` if `is_external` is `True`. Intended for
|
||||
use during load from a serialized package, where the rId is well known. Other
|
||||
methods exist for adding a new relationship to the package during processing.
|
||||
|
||||
### `main_document_part`
|
||||
|
||||
```python
|
||||
main_document_part
|
||||
```
|
||||
|
||||
Return a reference to the main document part for this package.
|
||||
|
||||
Examples include a document part for a WordprocessingML package, a presentation
|
||||
part for a PresentationML package, or a workbook part for a SpreadsheetML
|
||||
package.
|
||||
|
||||
### `next_partname`
|
||||
|
||||
```python
|
||||
next_partname(template: str) -> PackURI
|
||||
```
|
||||
|
||||
Return a `PackURI` instance representing partname matching `template`.
|
||||
|
||||
The returned part-name has the next available numeric suffix to distinguish it
|
||||
from other parts of its type. `template` is a printf (%)-style template string
|
||||
containing a single replacement item, a '%d' to be used to insert the integer
|
||||
portion of the partname. Example: "/word/header%d.xml"
|
||||
|
||||
### `open`
|
||||
|
||||
```python
|
||||
open(pkg_file: str | IO[bytes]) -> Self
|
||||
```
|
||||
|
||||
Return an `OpcPackage` instance loaded with the contents of `pkg_file`.
|
||||
|
||||
### `part_related_by`
|
||||
|
||||
```python
|
||||
part_related_by(reltype: str) -> Part
|
||||
```
|
||||
|
||||
Return part to which this package has a relationship of `reltype`.
|
||||
|
||||
Raises `KeyError` if no such relationship is found and `ValueError` if more than
|
||||
one such relationship is found.
|
||||
|
||||
### `parts`
|
||||
|
||||
```python
|
||||
parts: list[Part]
|
||||
```
|
||||
|
||||
Return a list containing a reference to each of the parts in this package.
|
||||
|
||||
### `relate_to`
|
||||
|
||||
```python
|
||||
relate_to(part: Part, reltype: str)
|
||||
```
|
||||
|
||||
Return rId key of new or existing relationship to `part`.
|
||||
|
||||
If a relationship of `reltype` to `part` already exists, its rId is returned. Otherwise a
|
||||
new relationship is created and that rId is returned.
|
||||
|
||||
### `rels`
|
||||
|
||||
```python
|
||||
rels()
|
||||
```
|
||||
|
||||
Return a reference to the `Relationships` instance holding the collection of
|
||||
relationships for this package.
|
||||
|
||||
### `save`
|
||||
|
||||
```python
|
||||
save(pkg_file: str | IO[bytes])
|
||||
```
|
||||
|
||||
Save this package to `pkg_file`, a path or a stream positioned at byte zero.
|
||||
|
||||
Serializes to a sibling temp file, reparses it to confirm it opens, then replaces the
|
||||
destination. A failed save leaves the original untouched and never leaves behind a
|
||||
package Word cannot open. An existing destination keeps its permission bits. A symlink
|
||||
destination is followed and its target replaced.
|
||||
|
||||
Raises `MalformedPackageError` when the serialized output will not reparse, and
|
||||
`OSError` for a stream in append mode, a stream positioned past byte zero, or a
|
||||
destination symlink that moves mid-save.
|
||||
|
||||
## `Unmarshaller`
|
||||
|
||||
Hosts static methods for unmarshalling a package from a `PackageReader`.
|
||||
|
||||
### `unmarshal`
|
||||
|
||||
```python
|
||||
unmarshal(pkg_reader, package, part_factory)
|
||||
```
|
||||
|
||||
Construct graph of parts and realized relationships based on the contents of
|
||||
`pkg_reader`, delegating construction of each part to `part_factory`.
|
||||
|
||||
Package relationships are added to `pkg`.
|
||||
Loaded 100 of 497 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user