Excel writes comments as a sequence of formatted runs <r><rPr>…</rPr><t>…</t></r>: a bold author prefix followed by the plain body is the default shape. python-xlsx collapses the entire <text> to a single <t> on save, dropping every per-run format (bold, font, size, color). This manifest pins that gap as a conformance failure.
Library verdicts: python-xlsx: — xlsxjs: —
| Feature id | xlsx/preserve-comment-rich-text |
|---|---|
| Format | xlsx |
| Category | round-trip |
| Spec | ecma-376-5-part-1 § 18.7.5 comment |
| ID / part | Predicate | XPath | python-xlsx | xlsxjs |
|---|---|---|---|---|
comment-run-preservedxl/comments1.xml | existAt least one <r> child must survive inside a comment's <text>. python-xlsx currently collapses rich text to a single <t>, stripping every <r>. | //x:comments/x:commentList/x:comment/x:text/x:r | — | — |
comment-run-properties-preservedxl/comments1.xml | existAt least one run-property block <rPr> must survive. Without it the visual distinction between the bold author prefix and the plain body is lost. | //x:comments/x:commentList/x:comment/x:text/x:r/x:rPr | — | — |
comment-bold-prefix-preservedxl/comments1.xml | existAt least one <b/> must survive inside a run-property block — comment 'Author:' prefixes are bold by convention. | //x:comments/x:commentList/x:comment/x:text/x:r/x:rPr/x:b | — | — |
No render assertions declared.
{
"$schema": "../manifest.schema.json",
"id": "xlsx/preserve-comment-rich-text",
"title": "Preserve comment rich-text runs across round-trip",
"format": "xlsx",
"category": "round-trip",
"summary": "Excel writes comments as a sequence of formatted runs <r><rPr>…</rPr><t>…</t></r>: a bold author prefix followed by the plain body is the default shape. python-xlsx collapses the entire <text> to a single <t> on save, dropping every per-run format (bold, font, size, color). This manifest pins that gap as a conformance failure.",
"roles": [
"authoring"
],
"spec": {
"source": "ecma-376-5-part-1",
"clause": "18.7.5",
"element": "comment",
"rnc_reference": "spec/ecma-376-5/part-1/rnc/SpreadsheetML.rnc",
"xsd_reference": "spec/ecma-376-5/part-1/xsd/sml.xsd",
"notes": "ECMA-376 Part 1 clause 18.7 specifies xl/comments*.xml and its <commentList>/<comment>/<text> structure. The <text> child uses the same CT_Rst shape as <si> in sharedStrings.xml — so rich-text runs <r><rPr>…</rPr><t>…</t></r> are schema-legal and, in practice, Excel emits them unconditionally (the default 'author:' prefix is bold, the body is plain). Code: src/xlsx/comments/comments.py — Comment.__init__ stores only self.content as str; src/xlsx/comments/comment_sheet.py::CommentRecord.from_cell replays it as self.text.t (a single <t> child). python-xlsx has CellRichText / InlineFont support for inline strings but the comment path never uses it."
},
"fixtures": {
"machine": "xlsx/preserve-comment-rich-text"
},
"round_trip": {
"library": "python-xlsx",
"source_fixture": "xlsx/preserve-comment-rich-text",
"notes": "Source is a copy of python-xlsx's own bundled comments.xlsx test fixture, authored in Excel with the standard 'bold author prefix + plain body' comment shape. Runner loads it, saves through python-xlsx, and evaluates the assertions against the re-saved bytes."
},
"assertions": [
{
"id": "comment-run-preserved",
"part": "xl/comments1.xml",
"namespaces": {
"x": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
},
"xpath": "//x:comments/x:commentList/x:comment/x:text/x:r",
"must": "exist",
"description": "At least one <r> child must survive inside a comment's <text>. python-xlsx currently collapses rich text to a single <t>, stripping every <r>."
},
{
"id": "comment-run-properties-preserved",
"part": "xl/comments1.xml",
"namespaces": {
"x": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
},
"xpath": "//x:comments/x:commentList/x:comment/x:text/x:r/x:rPr",
"must": "exist",
"description": "At least one run-property block <rPr> must survive. Without it the visual distinction between the bold author prefix and the plain body is lost."
},
{
"id": "comment-bold-prefix-preserved",
"part": "xl/comments1.xml",
"namespaces": {
"x": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
},
"xpath": "//x:comments/x:commentList/x:comment/x:text/x:r/x:rPr/x:b",
"must": "exist",
"description": "At least one <b/> must survive inside a run-property block — comment 'Author:' prefixes are bold by convention."
}
]
}
No rendered reference is available for this case.