diff --git a/README.md b/README.md index f0e0765..7e1442b 100644 --- a/README.md +++ b/README.md @@ -214,6 +214,9 @@ uv run scripts/i18n/test_validate_i18n.py uv run scripts/catalog/test_validate_catalog_metadata.py uv run scripts/catalog/test_collection_generator.py uv run scripts/catalog/test_check_upstream_health.py + +# Compile bundled Office schemas offline and validate Chinese XML with a GBK default. +uv run scripts/office/test_offline_resources.py ``` Passing a skill path narrows skill-body validation, but market-level and sidecar checks still run. Choose the relevant test file for your change rather than treating every documentation edit as a reason to run all test suites. diff --git a/README.zh-CN.md b/README.zh-CN.md index 47c3282..2137452 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -214,6 +214,9 @@ uv run scripts/i18n/test_validate_i18n.py uv run scripts/catalog/test_validate_catalog_metadata.py uv run scripts/catalog/test_collection_generator.py uv run scripts/catalog/test_check_upstream_health.py + +# 离线编译内置 Office Schema,并验证 GBK 默认环境中的中文 XML。 +uv run scripts/office/test_offline_resources.py ``` 传入技能路径只缩小技能正文的校验范围,市场级与 sidecar 检查仍会执行。应根据改动选择相关测试文件,而不是每次修改文档都运行全部测试。 diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index ebcea94..d884291 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -23,6 +23,18 @@ required NOTICE attribution apply to those skills. Upstream: https://github.com/anthropics/skills +## Dublin Core XML schemas + +Office core-property validation includes DCMI XML schemas in the `docx`, `pptx`, +and `xlsx` skills. XML schemas Copyright © 2011 [DCMI](https://www.dublincore.org/), +licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). +See the [DCMI Schema Use Notice](https://www.dublincore.org/about/copyright/). + +Original authors and annotations are retained; imports are adapted to local paths +for offline use. Each skill includes a `scripts/office/schemas/NOTICE.md` with the +original URLs, source digests, and adaptation details, so attribution also travels +with an independently installed skill. + ## External / pointer skills Skills described only by an `entry.json` pointer (no vendored source) are diff --git a/scripts/office/test_offline_resources.py b/scripts/office/test_offline_resources.py new file mode 100644 index 0000000..41e53f3 --- /dev/null +++ b/scripts/office/test_offline_resources.py @@ -0,0 +1,120 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.10" +# dependencies = ["lxml>=5.3,<7", "defusedxml>=0.7"] +# /// +"""内置 Office 技能的离线 Schema 与中文 XML 回归,不访问网络。""" + +from __future__ import annotations + +import builtins +import importlib.util +import json +import sys +import tempfile +import unittest +from pathlib import Path +from unittest.mock import patch +from urllib.parse import urlsplit + +from lxml import etree + + +ROOT = Path(__file__).resolve().parents[2] +OFFICE_SKILLS = ("docx", "pptx", "xlsx") +XSD = "{http://www.w3.org/2001/XMLSchema}" +WORD_XML = ''' + + 离线中文文档 +''' +CORE_XML = ''' + + 离线中文文档 + 2026-10-14T00:00:00Z +''' + + +class RejectRemoteSchema(etree.Resolver): + def resolve(self, url, public_id, context): + if urlsplit(url).scheme not in ("", "file") and not Path(url).is_absolute(): + raise OSError(f"离线 Schema 不允许远程依赖:{url}") + return None + + +def offline_parser(): + parser = etree.XMLParser(no_network=True) + parser.resolvers.add(RejectRemoteSchema()) + return parser + + +def load_docx_validator(skill: str): + directory = ROOT / "skills" / skill / "scripts" / "office" / "validators" + name = f"market_office_{skill}_validators" + spec = importlib.util.spec_from_file_location( + name, directory / "__init__.py", submodule_search_locations=[str(directory)] + ) + assert spec is not None and spec.loader is not None + module = importlib.util.module_from_spec(spec) + sys.modules[name] = module + spec.loader.exec_module(module) + return module.DOCXSchemaValidator + + +class OfflineOfficeResourcesTests(unittest.TestCase): + def test_all_builtin_schemas_have_local_dependencies_and_compile_offline(self): + builtin_ids = json.loads((ROOT / "builtin-skills.json").read_text(encoding="utf-8"))["skills"] + checked = 0 + for skill in builtin_ids: + skill_root = ROOT / "skills" / skill + for schema in sorted(skill_root.rglob("*.xsd")): + with self.subTest(schema=str(schema.relative_to(ROOT))): + document = etree.parse(str(schema), offline_parser()) + for node in document.iter(): + if node.tag not in (XSD + "import", XSD + "include", XSD + "redefine"): + continue + location = node.get("schemaLocation") + if location is None: + continue + self.assertEqual(urlsplit(location).scheme, "", location) + target = (schema.parent / location).resolve() + self.assertTrue(target.is_relative_to(skill_root.resolve()), location) + self.assertTrue(target.is_file(), location) + etree.XMLSchema(document) + checked += 1 + self.assertGreater(checked, 0, "不能在未发现任何 Schema 时静默通过") + + def test_chinese_document_and_dublin_core_validate_with_gbk_default(self): + # 模拟 Windows GBK 默认文本读取,避免只在 UTF-8 的 CI 上掩盖回归。 + original_open = builtins.open + + def gbk_open(file, mode="r", *args, **kwargs): + if "b" not in mode and not args and "encoding" not in kwargs: + kwargs["encoding"] = "gbk" + return original_open(file, mode, *args, **kwargs) + + for skill in OFFICE_SKILLS: + with self.subTest(skill=skill), tempfile.TemporaryDirectory() as temporary: + directory = Path(temporary) + word = directory / "word" / "document.xml" + core = directory / "docProps" / "core.xml" + word.parent.mkdir() + core.parent.mkdir() + word.write_bytes(WORD_XML.encode("utf-8")) + core.write_bytes(CORE_XML.encode("utf-8")) + validator = load_docx_validator(skill)(directory) + with patch("builtins.open", side_effect=gbk_open): + for file in (word, core): + valid, errors = validator._validate_single_file_xsd(file, directory) + self.assertTrue(valid, errors) + + # 保留真实 XSD 校验,不能用跳过/放宽校验来实现“通过”。 + word.write_bytes(WORD_XML.replace("", "").replace("", "").encode("utf-8")) + valid, errors = validator._validate_single_file_xsd(word, directory) + self.assertFalse(valid) + self.assertTrue(errors) + + +if __name__ == "__main__": + unittest.main() diff --git a/skills/docx/SKILL.md b/skills/docx/SKILL.md index 982e48c..78d0357 100644 --- a/skills/docx/SKILL.md +++ b/skills/docx/SKILL.md @@ -14,7 +14,7 @@ description: >- PDFs, spreadsheets, Google Docs, or general coding tasks unrelated to document generation. Use when 用户提到 Word文档、docx、创建文档、编辑文档、报告、 备忘录、公文、合同、信函模板。 -version: 1.0.3 +version: 1.0.4 type: procedural risk_level: low status: enabled @@ -26,7 +26,7 @@ tags: - office metadata: author: anthropic - updated_at: '2026-06-02' + updated_at: '2026-10-14' i18n: default_locale: en-US source_locale: zh-CN diff --git a/skills/docx/catalog-metadata.v1.json b/skills/docx/catalog-metadata.v1.json index 7895c44..2d9b0db 100644 --- a/skills/docx/catalog-metadata.v1.json +++ b/skills/docx/catalog-metadata.v1.json @@ -29,14 +29,14 @@ }, "release": { "state": "known", - "version": "1.0.3", + "version": "1.0.4", "versionScheme": "semver" }, "timestamps": { "catalogUpdatedAt": { "state": "known", - "value": "2026-06-04T03:14:36Z", - "precision": "second" + "value": "2026-10-14", + "precision": "day" }, "releasePublishedAt": { "state": "unknown" diff --git a/skills/docx/scripts/office/schemas/NOTICE.md b/skills/docx/scripts/office/schemas/NOTICE.md new file mode 100644 index 0000000..227ca16 --- /dev/null +++ b/skills/docx/scripts/office/schemas/NOTICE.md @@ -0,0 +1,13 @@ +# Office 离线 Schema 依赖 + +此目录包含 Office 元数据校验所需的 Dublin Core XML Schema。XML schemas Copyright © 2011 [DCMI](https://www.dublincore.org/),按 [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) 使用;许可依据见 [DCMI Schema Use Notice](https://www.dublincore.org/about/copyright/)。上游 Schema 标注创建日期为 2003-04-02,原作者与文档注释保留在文件内。 + +|本地文件|原始来源|原始文件 SHA-256| +|---|---|---| +|`dublin-core/dc.xsd`|https://www.dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd|`bc1d454db1bb20dfb1867a3fe0cf007775fc4afa33a5df425c12d854f049f1f6`| +|`dublin-core/dcterms.xsd`|https://www.dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd|`6328c8b574c166f8ebc28d07231e6ee47121e9791689b70c3afa665f22099fed`| +|`dublin-core/dcmitype.xsd`|https://www.dublincore.org/schemas/xmls/qdc/2003/04/02/dcmitype.xsd|`4980845d0bedcf45e707fa64eb47492ae4f95ac4ae42f5c3c68b58c0bc9e8e49`| + +本地适配规范化三份文件的行尾空白与缩进,并修改 `dc.xsd` / `dcterms.xsd` 的 XML 命名空间 import 路径,复用已随包提供的 `ISO-IEC29500-4_2016/xml.xsd`;`dcmitype.xsd` 仅调整空白。Office `opc-coreProperties.xsd` 改为引用本地 `dublin-core/`,不改变命名空间 URI 或类型定义。三套技能分别携带完整闭包,独立安装时不依赖其它技能目录。 + +离线编译与中文 XML 回归:从市场仓库根运行 `uv run scripts/office/test_offline_resources.py`。运行时仍需要 `lxml` / `defusedxml`;本文件不表示捆绑 LibreOffice 或其它办公系统工具。 diff --git a/skills/docx/scripts/office/schemas/dublin-core/dc.xsd b/skills/docx/scripts/office/schemas/dublin-core/dc.xsd new file mode 100644 index 0000000..9ffbe15 --- /dev/null +++ b/skills/docx/scripts/office/schemas/dublin-core/dc.xsd @@ -0,0 +1,118 @@ + + + + + + DCMES 1.1 XML Schema + XML Schema for http://purl.org/dc/elements/1.1/ namespace + + Created 2003-04-02 + + Created by + + Tim Cole (t-cole3@uiuc.edu) + Tom Habing (thabing@uiuc.edu) + Jane Hunter (jane@dstc.edu.au) + Pete Johnston (p.johnston@ukoln.ac.uk), + Carl Lagoze (lagoze@cs.cornell.edu) + + This schema declares XML elements for the 15 DC elements from the + http://purl.org/dc/elements/1.1/ namespace. + + It defines a complexType SimpleLiteral which permits mixed content + and makes the xml:lang attribute available. It disallows child elements by + use of minOcccurs/maxOccurs. + + However, this complexType does permit the derivation of other complexTypes + which would permit child elements. + + All elements are declared as substitutable for the abstract element any, + which means that the default type for all elements is dc:SimpleLiteral. + + + + + + + + + + + + + This is the default type for all of the DC elements. + It permits text content only with optional + xml:lang attribute. + Text is allowed because mixed="true", but sub-elements + are disallowed because minOccurs="0" and maxOccurs="0" + are on the xs:any tag. + + This complexType allows for restriction or extension permitting + child elements. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This group is included as a convenience for schema authors + who need to refer to all the elements in the + http://purl.org/dc/elements/1.1/ namespace. + + + + + + + + + + + + + + This complexType is included as a convenience for schema authors who need to define a root + or container element for all of the DC elements. + + + + + + + + + + diff --git a/skills/docx/scripts/office/schemas/dublin-core/dcmitype.xsd b/skills/docx/scripts/office/schemas/dublin-core/dcmitype.xsd new file mode 100644 index 0000000..37f9472 --- /dev/null +++ b/skills/docx/scripts/office/schemas/dublin-core/dcmitype.xsd @@ -0,0 +1,50 @@ + + + + + + DCMI Type Vocabulary XML Schema + XML Schema for http://purl.org/dc/dcmitype/ namespace + + Created 2003-04-02 + + Created by + + Tim Cole (t-cole3@uiuc.edu) + Tom Habing (thabing@uiuc.edu) + Jane Hunter (jane@dstc.edu.au) + Pete Johnston (p.johnston@ukoln.ac.uk), + Carl Lagoze (lagoze@cs.cornell.edu) + + This schema defines a simpleType which enumerates + the allowable values for the DCMI Type Vocabulary. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/skills/docx/scripts/office/schemas/dublin-core/dcterms.xsd b/skills/docx/scripts/office/schemas/dublin-core/dcterms.xsd new file mode 100644 index 0000000..ea2d874 --- /dev/null +++ b/skills/docx/scripts/office/schemas/dublin-core/dcterms.xsd @@ -0,0 +1,331 @@ + + + + + + DCterms XML Schema + XML Schema for http://purl.org/dc/terms/ namespace + + Created 2003-04-02 + + Created by + + Tim Cole (t-cole3@uiuc.edu) + Tom Habing (thabing@uiuc.edu) + Jane Hunter (jane@dstc.edu.au) + Pete Johnston (p.johnston@ukoln.ac.uk), + Carl Lagoze (lagoze@cs.cornell.edu) + + This schema declares XML elements for the DC elements and + DC element refinements from the http://purl.org/dc/terms/ namespace. + + It reuses the complexType dc:SimpleLiteral, imported from the dc.xsd + schema, which permits simple element content, and makes the xml:lang + attribute available. + + This complexType permits the derivation of other complexTypes + which would permit child elements. + + DC elements are declared as substitutable for the abstract element dc:any, and + DC element refinements are defined as substitutable for the base elements + which they refine. + + This means that the default type for all XML elements (i.e. all DC elements and + element refinements) is dc:SimpleLiteral. + + Encoding schemes are defined as complexTypes which are restrictions + of the dc:SimpleLiteral complexType. These complexTypes restrict + values to an appropriates syntax or format using data typing, + regular expressions, or enumerated lists. + + In order to specify one of these encodings an xsi:type attribute must + be used in the instance document. + + Also, note that one shortcoming of this approach is that any type can be + applied to any of the elements or refinements. There is no convenient way + to restrict types to specific elements using this approach. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This group is included as a convenience for schema authors + who need to refer to all the DC elements and element refinements + in the http://purl.org/dc/elements/1.1/ and + http://purl.org/dc/terms namespaces. + N.B. Refinements available via substitution groups. + + + + + + + + + + + + + + This is included as a convenience for schema authors who need to define a root + or container element for all of the DC elements and element refinements. + + + + + + + + + + diff --git a/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd b/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd index 10e978b..e53487c 100644 --- a/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +++ b/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd @@ -5,9 +5,9 @@ xmlns:dcterms="http://purl.org/dc/terms/" elementFormDefault="qualified" blockDefault="#all"> + schemaLocation="../../dublin-core/dc.xsd"/> + schemaLocation="../../dublin-core/dcterms.xsd"/> diff --git a/skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd b/skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd index 680cf15..74b807f 100644 --- a/skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +++ b/skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd @@ -1,4 +1,5 @@ - + + - + diff --git a/skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd b/skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd index 89ada90..f5bd5b2 100644 --- a/skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +++ b/skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd @@ -1,7 +1,8 @@ - + + - + diff --git a/skills/docx/scripts/office/validators/base.py b/skills/docx/scripts/office/validators/base.py index db4a06a..ae01112 100644 --- a/skills/docx/scripts/office/validators/base.py +++ b/skills/docx/scripts/office/validators/base.py @@ -760,7 +760,8 @@ class BaseSchemaValidator: ) schema = lxml.etree.XMLSchema(xsd_doc) - with open(xml_file, "r") as f: + # 按 XML 自身的编码声明读取,避免 Windows 默认 GBK 破坏 UTF-8 文档。 + with open(xml_file, "rb") as f: xml_doc = lxml.etree.parse(f) xml_doc, _ = self._remove_template_tags_from_text_nodes(xml_doc) diff --git a/skills/pptx/SKILL.md b/skills/pptx/SKILL.md index 8f52c42..4a5e306 100644 --- a/skills/pptx/SKILL.md +++ b/skills/pptx/SKILL.md @@ -13,7 +13,7 @@ description: >- content afterward. If a .pptx file needs to be opened, created, or touched, use this skill. Use when 用户提到 PPT、演示文稿、幻灯片、演讲稿、汇报材料、 pptx、创建演示、编辑幻灯片。 -version: 1.0.4 +version: 1.0.5 type: procedural risk_level: low status: enabled @@ -26,7 +26,7 @@ tags: - office metadata: author: anthropic - updated_at: '2026-05-04' + updated_at: '2026-10-14' i18n: default_locale: en-US source_locale: zh-CN diff --git a/skills/pptx/catalog-metadata.v1.json b/skills/pptx/catalog-metadata.v1.json index 0638732..94603cc 100644 --- a/skills/pptx/catalog-metadata.v1.json +++ b/skills/pptx/catalog-metadata.v1.json @@ -30,14 +30,14 @@ }, "release": { "state": "known", - "version": "1.0.4", + "version": "1.0.5", "versionScheme": "semver" }, "timestamps": { "catalogUpdatedAt": { "state": "known", - "value": "2026-07-07T13:14:31Z", - "precision": "second" + "value": "2026-10-14", + "precision": "day" }, "releasePublishedAt": { "state": "unknown" diff --git a/skills/pptx/scripts/office/schemas/NOTICE.md b/skills/pptx/scripts/office/schemas/NOTICE.md new file mode 100644 index 0000000..227ca16 --- /dev/null +++ b/skills/pptx/scripts/office/schemas/NOTICE.md @@ -0,0 +1,13 @@ +# Office 离线 Schema 依赖 + +此目录包含 Office 元数据校验所需的 Dublin Core XML Schema。XML schemas Copyright © 2011 [DCMI](https://www.dublincore.org/),按 [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) 使用;许可依据见 [DCMI Schema Use Notice](https://www.dublincore.org/about/copyright/)。上游 Schema 标注创建日期为 2003-04-02,原作者与文档注释保留在文件内。 + +|本地文件|原始来源|原始文件 SHA-256| +|---|---|---| +|`dublin-core/dc.xsd`|https://www.dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd|`bc1d454db1bb20dfb1867a3fe0cf007775fc4afa33a5df425c12d854f049f1f6`| +|`dublin-core/dcterms.xsd`|https://www.dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd|`6328c8b574c166f8ebc28d07231e6ee47121e9791689b70c3afa665f22099fed`| +|`dublin-core/dcmitype.xsd`|https://www.dublincore.org/schemas/xmls/qdc/2003/04/02/dcmitype.xsd|`4980845d0bedcf45e707fa64eb47492ae4f95ac4ae42f5c3c68b58c0bc9e8e49`| + +本地适配规范化三份文件的行尾空白与缩进,并修改 `dc.xsd` / `dcterms.xsd` 的 XML 命名空间 import 路径,复用已随包提供的 `ISO-IEC29500-4_2016/xml.xsd`;`dcmitype.xsd` 仅调整空白。Office `opc-coreProperties.xsd` 改为引用本地 `dublin-core/`,不改变命名空间 URI 或类型定义。三套技能分别携带完整闭包,独立安装时不依赖其它技能目录。 + +离线编译与中文 XML 回归:从市场仓库根运行 `uv run scripts/office/test_offline_resources.py`。运行时仍需要 `lxml` / `defusedxml`;本文件不表示捆绑 LibreOffice 或其它办公系统工具。 diff --git a/skills/pptx/scripts/office/schemas/dublin-core/dc.xsd b/skills/pptx/scripts/office/schemas/dublin-core/dc.xsd new file mode 100644 index 0000000..9ffbe15 --- /dev/null +++ b/skills/pptx/scripts/office/schemas/dublin-core/dc.xsd @@ -0,0 +1,118 @@ + + + + + + DCMES 1.1 XML Schema + XML Schema for http://purl.org/dc/elements/1.1/ namespace + + Created 2003-04-02 + + Created by + + Tim Cole (t-cole3@uiuc.edu) + Tom Habing (thabing@uiuc.edu) + Jane Hunter (jane@dstc.edu.au) + Pete Johnston (p.johnston@ukoln.ac.uk), + Carl Lagoze (lagoze@cs.cornell.edu) + + This schema declares XML elements for the 15 DC elements from the + http://purl.org/dc/elements/1.1/ namespace. + + It defines a complexType SimpleLiteral which permits mixed content + and makes the xml:lang attribute available. It disallows child elements by + use of minOcccurs/maxOccurs. + + However, this complexType does permit the derivation of other complexTypes + which would permit child elements. + + All elements are declared as substitutable for the abstract element any, + which means that the default type for all elements is dc:SimpleLiteral. + + + + + + + + + + + + + This is the default type for all of the DC elements. + It permits text content only with optional + xml:lang attribute. + Text is allowed because mixed="true", but sub-elements + are disallowed because minOccurs="0" and maxOccurs="0" + are on the xs:any tag. + + This complexType allows for restriction or extension permitting + child elements. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This group is included as a convenience for schema authors + who need to refer to all the elements in the + http://purl.org/dc/elements/1.1/ namespace. + + + + + + + + + + + + + + This complexType is included as a convenience for schema authors who need to define a root + or container element for all of the DC elements. + + + + + + + + + + diff --git a/skills/pptx/scripts/office/schemas/dublin-core/dcmitype.xsd b/skills/pptx/scripts/office/schemas/dublin-core/dcmitype.xsd new file mode 100644 index 0000000..37f9472 --- /dev/null +++ b/skills/pptx/scripts/office/schemas/dublin-core/dcmitype.xsd @@ -0,0 +1,50 @@ + + + + + + DCMI Type Vocabulary XML Schema + XML Schema for http://purl.org/dc/dcmitype/ namespace + + Created 2003-04-02 + + Created by + + Tim Cole (t-cole3@uiuc.edu) + Tom Habing (thabing@uiuc.edu) + Jane Hunter (jane@dstc.edu.au) + Pete Johnston (p.johnston@ukoln.ac.uk), + Carl Lagoze (lagoze@cs.cornell.edu) + + This schema defines a simpleType which enumerates + the allowable values for the DCMI Type Vocabulary. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/skills/pptx/scripts/office/schemas/dublin-core/dcterms.xsd b/skills/pptx/scripts/office/schemas/dublin-core/dcterms.xsd new file mode 100644 index 0000000..ea2d874 --- /dev/null +++ b/skills/pptx/scripts/office/schemas/dublin-core/dcterms.xsd @@ -0,0 +1,331 @@ + + + + + + DCterms XML Schema + XML Schema for http://purl.org/dc/terms/ namespace + + Created 2003-04-02 + + Created by + + Tim Cole (t-cole3@uiuc.edu) + Tom Habing (thabing@uiuc.edu) + Jane Hunter (jane@dstc.edu.au) + Pete Johnston (p.johnston@ukoln.ac.uk), + Carl Lagoze (lagoze@cs.cornell.edu) + + This schema declares XML elements for the DC elements and + DC element refinements from the http://purl.org/dc/terms/ namespace. + + It reuses the complexType dc:SimpleLiteral, imported from the dc.xsd + schema, which permits simple element content, and makes the xml:lang + attribute available. + + This complexType permits the derivation of other complexTypes + which would permit child elements. + + DC elements are declared as substitutable for the abstract element dc:any, and + DC element refinements are defined as substitutable for the base elements + which they refine. + + This means that the default type for all XML elements (i.e. all DC elements and + element refinements) is dc:SimpleLiteral. + + Encoding schemes are defined as complexTypes which are restrictions + of the dc:SimpleLiteral complexType. These complexTypes restrict + values to an appropriates syntax or format using data typing, + regular expressions, or enumerated lists. + + In order to specify one of these encodings an xsi:type attribute must + be used in the instance document. + + Also, note that one shortcoming of this approach is that any type can be + applied to any of the elements or refinements. There is no convenient way + to restrict types to specific elements using this approach. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This group is included as a convenience for schema authors + who need to refer to all the DC elements and element refinements + in the http://purl.org/dc/elements/1.1/ and + http://purl.org/dc/terms namespaces. + N.B. Refinements available via substitution groups. + + + + + + + + + + + + + + This is included as a convenience for schema authors who need to define a root + or container element for all of the DC elements and element refinements. + + + + + + + + + + diff --git a/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd b/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd index 10e978b..e53487c 100644 --- a/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +++ b/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd @@ -5,9 +5,9 @@ xmlns:dcterms="http://purl.org/dc/terms/" elementFormDefault="qualified" blockDefault="#all"> + schemaLocation="../../dublin-core/dc.xsd"/> + schemaLocation="../../dublin-core/dcterms.xsd"/> diff --git a/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd b/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd index 680cf15..74b807f 100644 --- a/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +++ b/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd @@ -1,4 +1,5 @@ - + + - + diff --git a/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd b/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd index 89ada90..f5bd5b2 100644 --- a/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +++ b/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd @@ -1,7 +1,8 @@ - + + - + diff --git a/skills/pptx/scripts/office/validators/base.py b/skills/pptx/scripts/office/validators/base.py index db4a06a..ae01112 100644 --- a/skills/pptx/scripts/office/validators/base.py +++ b/skills/pptx/scripts/office/validators/base.py @@ -760,7 +760,8 @@ class BaseSchemaValidator: ) schema = lxml.etree.XMLSchema(xsd_doc) - with open(xml_file, "r") as f: + # 按 XML 自身的编码声明读取,避免 Windows 默认 GBK 破坏 UTF-8 文档。 + with open(xml_file, "rb") as f: xml_doc = lxml.etree.parse(f) xml_doc, _ = self._remove_template_tags_from_text_nodes(xml_doc) diff --git a/skills/presentation-forge/SKILL.md b/skills/presentation-forge/SKILL.md index 2381da5..0ee8c2f 100644 --- a/skills/presentation-forge/SKILL.md +++ b/skills/presentation-forge/SKILL.md @@ -1,7 +1,7 @@ --- name: presentation-forge description: "创建中文商业汇报,从主题、文档或 slides.md 生成原生可编辑 PPTX,提供 Markdown-first 实时画布、样式切换和同版导出,使用 image-2 辅助生成独立视觉资产,把截图或图片型幻灯片重建为可编辑 PPTX/SVG,或用原生 PPTX 模板填充新内容。用户要求制作售前方案、项目汇报、产品介绍、行业分析、培训材料、像 Markdown 一样编辑并导出、AIPPT 式可编辑演示、套用 PowerPoint 模板、图片页转可编辑 PowerPoint、重建幻灯片或输出 SVG 时使用。" -version: 0.1.0 +version: 0.1.1 type: procedural risk_level: low status: enabled @@ -13,7 +13,7 @@ tags: - slides metadata: author: Ronnie2025 - updated_at: '2026-08-10' + updated_at: '2026-10-14' i18n: default_locale: en-US source_locale: zh-CN diff --git a/skills/presentation-forge/_desirecore/frontmatter.yaml b/skills/presentation-forge/_desirecore/frontmatter.yaml index ad0f9f4..a7bc0aa 100644 --- a/skills/presentation-forge/_desirecore/frontmatter.yaml +++ b/skills/presentation-forge/_desirecore/frontmatter.yaml @@ -1,6 +1,6 @@ name: presentation-forge description: "创建中文商业汇报,从主题、文档或 slides.md 生成原生可编辑 PPTX,提供 Markdown-first 实时画布、样式切换和同版导出,使用 image-2 辅助生成独立视觉资产,把截图或图片型幻灯片重建为可编辑 PPTX/SVG,或用原生 PPTX 模板填充新内容。用户要求制作售前方案、项目汇报、产品介绍、行业分析、培训材料、像 Markdown 一样编辑并导出、AIPPT 式可编辑演示、套用 PowerPoint 模板、图片页转可编辑 PowerPoint、重建幻灯片或输出 SVG 时使用。" -version: 0.1.0 +version: 0.1.1 type: procedural risk_level: low status: enabled @@ -12,7 +12,7 @@ tags: - slides metadata: author: Ronnie2025 - updated_at: '2026-08-10' + updated_at: '2026-10-14' i18n: default_locale: en-US source_locale: zh-CN diff --git a/skills/presentation-forge/assets/editor/render_editor_canvas.py b/skills/presentation-forge/assets/editor/render_editor_canvas.py new file mode 100644 index 0000000..ba5c267 --- /dev/null +++ b/skills/presentation-forge/assets/editor/render_editor_canvas.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import argparse +import html +import json +from pathlib import Path + + +def esc(value: object) -> str: + return html.escape(str(value or "")) + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--manifest", required=True) + parser.add_argument("--out", required=True) + args = parser.parse_args() + manifest = json.loads(Path(args.manifest).read_text(encoding="utf-8")) + slides = manifest["slides"] + manifest_json = json.dumps(manifest, ensure_ascii=False).replace(" + +{esc(manifest.get('session_id'))} · Presentation Forge Canvas + + +
+
{esc(manifest.get('session_id'))} 画布编辑中 · {len(slides)} 页
+
+ +
+ +
+
+ +''' + Path(args.out).write_text(document, encoding="utf-8") + print(json.dumps({"status": "PASS", "slide_count": len(slides), "out": str(Path(args.out).resolve())}, ensure_ascii=False)) + + +if __name__ == "__main__": + main() diff --git a/skills/presentation-forge/catalog-metadata.v1.json b/skills/presentation-forge/catalog-metadata.v1.json index 8a6d12e..ccc7479 100644 --- a/skills/presentation-forge/catalog-metadata.v1.json +++ b/skills/presentation-forge/catalog-metadata.v1.json @@ -30,14 +30,14 @@ }, "release": { "state": "known", - "version": "0.1.0", + "version": "0.1.1", "versionScheme": "semver" }, "timestamps": { "catalogUpdatedAt": { "state": "known", - "value": "2026-08-23T15:31:26Z", - "precision": "second" + "value": "2026-10-14", + "precision": "day" }, "releasePublishedAt": { "state": "unknown" diff --git a/skills/presentation-forge/references/editor-ui-integration.md b/skills/presentation-forge/references/editor-ui-integration.md index c431de3..0171387 100644 --- a/skills/presentation-forge/references/editor-ui-integration.md +++ b/skills/presentation-forge/references/editor-ui-integration.md @@ -29,7 +29,7 @@ canvas-first 不是示意界面。画布和最终 PPTX 必须使用同一份完 ```bash python scripts/editor_bridge.py export --session -cp assets/editor/render_editor_canvas.py /analysis/render_editor_canvas.py +cp scripts/render_editor_canvas.py /analysis/render_editor_canvas.py python scripts/render_editor_canvas.py \ --manifest /reports/editor-manifest.json \ --out /reports/editor-canvas.html diff --git a/skills/xlsx/SKILL.md b/skills/xlsx/SKILL.md index 7513945..f68e05a 100644 --- a/skills/xlsx/SKILL.md +++ b/skills/xlsx/SKILL.md @@ -16,7 +16,7 @@ description: >- report, standalone Python script, database pipeline, or Google Sheets API integration, even if tabular data is involved. Use when 用户提到 Excel、 电子表格、xlsx、表格处理、公式计算、数据清洗、图表、CSV导入导出。 -version: 1.0.3 +version: 1.0.4 type: procedural risk_level: low status: enabled @@ -28,7 +28,7 @@ tags: - office metadata: author: anthropic - updated_at: '2026-04-13' + updated_at: '2026-10-14' i18n: default_locale: en-US source_locale: zh-CN diff --git a/skills/xlsx/catalog-metadata.v1.json b/skills/xlsx/catalog-metadata.v1.json index 7788399..0324abd 100644 --- a/skills/xlsx/catalog-metadata.v1.json +++ b/skills/xlsx/catalog-metadata.v1.json @@ -29,14 +29,14 @@ }, "release": { "state": "known", - "version": "1.0.3", + "version": "1.0.4", "versionScheme": "semver" }, "timestamps": { "catalogUpdatedAt": { "state": "known", - "value": "2026-07-07T13:14:31Z", - "precision": "second" + "value": "2026-10-14", + "precision": "day" }, "releasePublishedAt": { "state": "unknown" diff --git a/skills/xlsx/scripts/office/schemas/NOTICE.md b/skills/xlsx/scripts/office/schemas/NOTICE.md new file mode 100644 index 0000000..227ca16 --- /dev/null +++ b/skills/xlsx/scripts/office/schemas/NOTICE.md @@ -0,0 +1,13 @@ +# Office 离线 Schema 依赖 + +此目录包含 Office 元数据校验所需的 Dublin Core XML Schema。XML schemas Copyright © 2011 [DCMI](https://www.dublincore.org/),按 [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) 使用;许可依据见 [DCMI Schema Use Notice](https://www.dublincore.org/about/copyright/)。上游 Schema 标注创建日期为 2003-04-02,原作者与文档注释保留在文件内。 + +|本地文件|原始来源|原始文件 SHA-256| +|---|---|---| +|`dublin-core/dc.xsd`|https://www.dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd|`bc1d454db1bb20dfb1867a3fe0cf007775fc4afa33a5df425c12d854f049f1f6`| +|`dublin-core/dcterms.xsd`|https://www.dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd|`6328c8b574c166f8ebc28d07231e6ee47121e9791689b70c3afa665f22099fed`| +|`dublin-core/dcmitype.xsd`|https://www.dublincore.org/schemas/xmls/qdc/2003/04/02/dcmitype.xsd|`4980845d0bedcf45e707fa64eb47492ae4f95ac4ae42f5c3c68b58c0bc9e8e49`| + +本地适配规范化三份文件的行尾空白与缩进,并修改 `dc.xsd` / `dcterms.xsd` 的 XML 命名空间 import 路径,复用已随包提供的 `ISO-IEC29500-4_2016/xml.xsd`;`dcmitype.xsd` 仅调整空白。Office `opc-coreProperties.xsd` 改为引用本地 `dublin-core/`,不改变命名空间 URI 或类型定义。三套技能分别携带完整闭包,独立安装时不依赖其它技能目录。 + +离线编译与中文 XML 回归:从市场仓库根运行 `uv run scripts/office/test_offline_resources.py`。运行时仍需要 `lxml` / `defusedxml`;本文件不表示捆绑 LibreOffice 或其它办公系统工具。 diff --git a/skills/xlsx/scripts/office/schemas/dublin-core/dc.xsd b/skills/xlsx/scripts/office/schemas/dublin-core/dc.xsd new file mode 100644 index 0000000..9ffbe15 --- /dev/null +++ b/skills/xlsx/scripts/office/schemas/dublin-core/dc.xsd @@ -0,0 +1,118 @@ + + + + + + DCMES 1.1 XML Schema + XML Schema for http://purl.org/dc/elements/1.1/ namespace + + Created 2003-04-02 + + Created by + + Tim Cole (t-cole3@uiuc.edu) + Tom Habing (thabing@uiuc.edu) + Jane Hunter (jane@dstc.edu.au) + Pete Johnston (p.johnston@ukoln.ac.uk), + Carl Lagoze (lagoze@cs.cornell.edu) + + This schema declares XML elements for the 15 DC elements from the + http://purl.org/dc/elements/1.1/ namespace. + + It defines a complexType SimpleLiteral which permits mixed content + and makes the xml:lang attribute available. It disallows child elements by + use of minOcccurs/maxOccurs. + + However, this complexType does permit the derivation of other complexTypes + which would permit child elements. + + All elements are declared as substitutable for the abstract element any, + which means that the default type for all elements is dc:SimpleLiteral. + + + + + + + + + + + + + This is the default type for all of the DC elements. + It permits text content only with optional + xml:lang attribute. + Text is allowed because mixed="true", but sub-elements + are disallowed because minOccurs="0" and maxOccurs="0" + are on the xs:any tag. + + This complexType allows for restriction or extension permitting + child elements. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This group is included as a convenience for schema authors + who need to refer to all the elements in the + http://purl.org/dc/elements/1.1/ namespace. + + + + + + + + + + + + + + This complexType is included as a convenience for schema authors who need to define a root + or container element for all of the DC elements. + + + + + + + + + + diff --git a/skills/xlsx/scripts/office/schemas/dublin-core/dcmitype.xsd b/skills/xlsx/scripts/office/schemas/dublin-core/dcmitype.xsd new file mode 100644 index 0000000..37f9472 --- /dev/null +++ b/skills/xlsx/scripts/office/schemas/dublin-core/dcmitype.xsd @@ -0,0 +1,50 @@ + + + + + + DCMI Type Vocabulary XML Schema + XML Schema for http://purl.org/dc/dcmitype/ namespace + + Created 2003-04-02 + + Created by + + Tim Cole (t-cole3@uiuc.edu) + Tom Habing (thabing@uiuc.edu) + Jane Hunter (jane@dstc.edu.au) + Pete Johnston (p.johnston@ukoln.ac.uk), + Carl Lagoze (lagoze@cs.cornell.edu) + + This schema defines a simpleType which enumerates + the allowable values for the DCMI Type Vocabulary. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/skills/xlsx/scripts/office/schemas/dublin-core/dcterms.xsd b/skills/xlsx/scripts/office/schemas/dublin-core/dcterms.xsd new file mode 100644 index 0000000..ea2d874 --- /dev/null +++ b/skills/xlsx/scripts/office/schemas/dublin-core/dcterms.xsd @@ -0,0 +1,331 @@ + + + + + + DCterms XML Schema + XML Schema for http://purl.org/dc/terms/ namespace + + Created 2003-04-02 + + Created by + + Tim Cole (t-cole3@uiuc.edu) + Tom Habing (thabing@uiuc.edu) + Jane Hunter (jane@dstc.edu.au) + Pete Johnston (p.johnston@ukoln.ac.uk), + Carl Lagoze (lagoze@cs.cornell.edu) + + This schema declares XML elements for the DC elements and + DC element refinements from the http://purl.org/dc/terms/ namespace. + + It reuses the complexType dc:SimpleLiteral, imported from the dc.xsd + schema, which permits simple element content, and makes the xml:lang + attribute available. + + This complexType permits the derivation of other complexTypes + which would permit child elements. + + DC elements are declared as substitutable for the abstract element dc:any, and + DC element refinements are defined as substitutable for the base elements + which they refine. + + This means that the default type for all XML elements (i.e. all DC elements and + element refinements) is dc:SimpleLiteral. + + Encoding schemes are defined as complexTypes which are restrictions + of the dc:SimpleLiteral complexType. These complexTypes restrict + values to an appropriates syntax or format using data typing, + regular expressions, or enumerated lists. + + In order to specify one of these encodings an xsi:type attribute must + be used in the instance document. + + Also, note that one shortcoming of this approach is that any type can be + applied to any of the elements or refinements. There is no convenient way + to restrict types to specific elements using this approach. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This group is included as a convenience for schema authors + who need to refer to all the DC elements and element refinements + in the http://purl.org/dc/elements/1.1/ and + http://purl.org/dc/terms namespaces. + N.B. Refinements available via substitution groups. + + + + + + + + + + + + + + This is included as a convenience for schema authors who need to define a root + or container element for all of the DC elements and element refinements. + + + + + + + + + + diff --git a/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd b/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd index 10e978b..e53487c 100644 --- a/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +++ b/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd @@ -5,9 +5,9 @@ xmlns:dcterms="http://purl.org/dc/terms/" elementFormDefault="qualified" blockDefault="#all"> + schemaLocation="../../dublin-core/dc.xsd"/> + schemaLocation="../../dublin-core/dcterms.xsd"/> diff --git a/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd b/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd index 680cf15..74b807f 100644 --- a/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +++ b/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd @@ -1,4 +1,5 @@ - + + - + diff --git a/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd b/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd index 89ada90..f5bd5b2 100644 --- a/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +++ b/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd @@ -1,7 +1,8 @@ - + + - + diff --git a/skills/xlsx/scripts/office/validators/base.py b/skills/xlsx/scripts/office/validators/base.py index db4a06a..ae01112 100644 --- a/skills/xlsx/scripts/office/validators/base.py +++ b/skills/xlsx/scripts/office/validators/base.py @@ -760,7 +760,8 @@ class BaseSchemaValidator: ) schema = lxml.etree.XMLSchema(xsd_doc) - with open(xml_file, "r") as f: + # 按 XML 自身的编码声明读取,避免 Windows 默认 GBK 破坏 UTF-8 文档。 + with open(xml_file, "rb") as f: xml_doc = lxml.etree.parse(f) xml_doc, _ = self._remove_template_tags_from_text_nodes(xml_doc)