skills/dfk1352/libreoffice-writer/SKILL.md
Use when creating, editing, formatting, exporting, or extracting LibreOffice Writer (.odt) documents via UNO, including session-based edits, structured text targets, tables, images, lists, patch workflows, and snapshots.
npx skillsauth add aiskillstore/marketplace libreoffice-writerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use the bundled writer modules for UNO-backed Writer document work.
All paths must be absolute. Bundled modules live under scripts/ in this
skill directory, so set PYTHONPATH=<skill_base_dir>/scripts.
If setup or runtime issues appear, check references/troubleshooting.md.
# Non-session utilities
create_document(path)
export_document(path, output_path, format) # formats: "pdf", "docx"
snapshot_page(doc_path, output_path, page=1, dpi=150)
# Session (primary editing API)
open_writer_session(path) -> WriterSession
WriterSession methods:
read_text(target: WriterTarget | None = None) -> str
insert_text(text, target: WriterTarget | None = None)
replace_text(target: WriterTarget, new_text)
delete_text(target: WriterTarget)
format_text(target: WriterTarget, formatting: TextFormatting)
insert_table(rows, cols, data=None, name=None, target: WriterTarget | None = None)
update_table(target: WriterTarget, data)
delete_table(target: WriterTarget)
insert_image(image_path, width=None, height=None, name=None, target: WriterTarget | None = None)
update_image(target: WriterTarget, image_path=None, width=None, height=None)
delete_image(target: WriterTarget)
insert_list(items: list[ListItem], ordered: bool, target: WriterTarget | None = None)
replace_list(target: WriterTarget, items: list[ListItem], ordered: bool | None = None)
delete_list(target: WriterTarget)
patch(patch_text, mode="atomic") -> PatchApplyResult
export(output_path, format)
reset()
close(save=True)
# Standalone patch utility
patch(path, patch_text, mode="atomic") -> PatchApplyResult
WriterTargetfrom writer import WriterTarget
WriterTarget(
kind="text" | "insertion" | "table" | "image" | "list",
text=None,
after=None,
before=None,
occurrence=None,
name=None,
index=None,
)
| Kind | Supported fields | Use |
|---|---|---|
| text | text, after, before, occurrence | Read, replace, delete, or format matched text |
| insertion | text, after, before, occurrence | Insert at a resolved boundary or after a matched span |
| table | name or index | Update/delete a table |
| image | name or index | Update/delete an image |
| list | text, after, before, occurrence | Replace/delete one logical list block |
target to read the full document or append inserted content at the end.after and before to constrain a search window.occurrence when repeated text is expected; otherwise matching must be unique.text, after, and before anchors; single-word anchors are often too brittle for realistic prose edits.name; use index only when order is stable.from writer import TextFormatting
TextFormatting(
bold=None,
italic=None,
underline=None,
font_name=None,
font_size=None,
color=None, # named color or integer
align=None, # "left" | "center" | "right" | "justify"
line_spacing=None,
spacing_before=None,
spacing_after=None,
)
Notes:
align apply to the full paragraph containing the match, not just the exact matched span.from writer import ListItem
ListItem(text="Confirm scope", level=0)
level is zero-based nesting.ordered=True uses a numbering style; ordered=False uses bullets.Use patch() or session.patch() to apply ordered operations.
[operation]
type = format_text
target.kind = text
target.text = Quarterly revenue grew 18%.
target.after = Financial Summary
target.before = Action Items
format.bold = true
format.align = center
[operation]
type = insert_list
target.kind = insertion
target.after = Action Items
list.ordered = false
items <<JSON
[
{"text": "Confirm scope", "level": 0},
{"text": "Review output", "level": 0},
{"text": "Update packaging", "level": 1}
]
JSON
insert_textreplace_textdelete_textformat_textinsert_tableupdate_tabledelete_tableinsert_imageupdate_imagedelete_imageinsert_listreplace_listdelete_listtarget.* fields for target definition.format.* fields for formatting payloads.list.ordered plus JSON items for list operations.items and data must be valid JSON.<<TAG ... TAG for multiline text or JSON.atomic stops on first failure, resets the session, and persists nothing.best_effort keeps successful earlier operations and records failures.PatchApplyResult fields:
modeoverall_status = "ok" | "partial" | "failed"operations = list of PatchOperationResultdocument_persistedFor standalone patch(path, ...), document_persisted means the changes were
saved to disk. For session.patch(...), it means the patch produced successful
mutations in the current open session state.
from pathlib import Path
from writer import ListItem, TextFormatting, WriterTarget, open_writer_session
from writer.core import create_document
output = str(Path("test-output/report.odt").resolve())
create_document(output)
with open_writer_session(output) as session:
session.insert_text(
"Executive Summary\n\n"
"Financial Summary\n\n"
"Quarterly revenue grew 18%.\n\n"
"Action Items"
)
session.format_text(
WriterTarget(
kind="text",
text="Quarterly revenue grew 18%.",
after="Financial Summary",
before="Action Items",
),
TextFormatting(bold=True, align="center"),
)
session.insert_list(
[
ListItem(text="Confirm scope", level=0),
ListItem(text="Review output", level=0),
ListItem(text="Update packaging", level=1),
],
ordered=False,
target=WriterTarget(kind="insertion", after="Action Items"),
)
from writer import patch
result = patch(
"/abs/path/report.odt",
"""
[operation]
type = replace_text
target.kind = text
target.text = Draft
new_text = Final
[operation]
type = update_table
target.kind = table
target.name = Summary
data = [["Metric", "Value"], ["Revenue", "$2M"]]
[operation]
type = replace_list
target.kind = list
target.text = Confirm scope
items = [{"text": "Approve release", "level": 0}, {"text": "Notify team", "level": 1}]
list.ordered = true
""",
mode="best_effort",
)
print(result.overall_status)
from pathlib import Path
from writer import snapshot_page
result = snapshot_page(doc_path, "/tmp/page1.png", page=1, dpi=150)
print(result.file_path, result.width, result.height)
Path(result.file_path).unlink(missing_ok=True)
Use snapshots to verify layout after formatting, list edits, image placement, or table changes.
occurrence for repeated text and then getting an ambiguity error.after / before bounds when possible.align to apply only to a phrase; Writer applies paragraph alignment to the containing paragraph.items or data patch fields.session.export() or other methods after session.close().development
Apple Human Interface Guidelines for content display components. Use this skill when the user asks about charts component, collection view, image view, web view, color well, image well, activity view, lockup, data visualization, content display, displaying images, rendering web content, color pickers, or presenting collections of items in Apple apps. Also use when the user says how should I display charts, what's the best way to show images, should I use a web view, how do I build a grid of items, what component shows media, or how do I present a share sheet. Cross-references: hig-foundations for color/typography/accessibility, hig-patterns for data visualization patterns, hig-components-layout for structural containers, hig-platforms for platform-specific component behavior.
tools
Automate HelpDesk tasks via Rube MCP (Composio): list tickets, manage views, use canned responses, and configure custom fields. Always search tools first for current schemas.
testing
Expert Haskell engineer specializing in advanced type systems, pure functional design, and high-reliability software. Use PROACTIVELY for type-level programming, concurrency, and architecture guidance.
tools
GraphQL gives clients exactly the data they need - no more, no less. One endpoint, typed schema, introspection. But the flexibility that makes it powerful also makes it dangerous. Without proper controls, clients can craft queries that bring down your server. This skill covers schema design, resolvers, DataLoader for N+1 prevention, federation for microservices, and client integration with Apollo/urql. Key insight: GraphQL is a contract. The schema is the API documentation. Design it carefully.