Matrix over the two OOXML strikethrough variants (w:strike single line, w:dstrike double line) x the two conventional enabled states (empty element, explicit w:val="true").
Library verdicts: python-docx: — docxjs: —
| Feature id | docx/run-strike-variants--double--explicit-true |
|---|---|
| Format | docx |
| Category | text-formatting |
| Family | docx/run-strike-variants |
| Axis values | kind=double, state=explicit-true |
| Spec | ecma-376-5-part-1 § 17.3.2.37 w:strike |
| ID / part | Predicate | XPath | python-docx | docxjs |
|---|---|---|---|---|
double-strike-present-explicit-trueword/document.xml | existThe run must carry a <w:dstrike> child inside <w:rPr> for state 'explicit-true'. | //w:r[w:t[normalize-space()='Striked text']]/w:rPr/w:dstrike | — | — |
No render assertions declared.
scripts/gen_run_strike_variants.py
#!/usr/bin/env python3
"""Generate a ``fixtures/docx/run-strike-variants--*.docx`` fixture.
Parameterised: called with ``--kind single|double --state enabled|explicit-true --out <path>``.
Writes a one-run document containing the text ``Striked text`` with
either a ``<w:strike>`` (kind=single) or ``<w:dstrike>`` (kind=double)
child inside the run's ``<w:rPr>``. The state axis controls whether the
element is emitted as an empty toggle (``state=enabled``) or with an
explicit ``w:val="true"`` attribute (``state=explicit-true``).
The ``features/docx/run-strike-variants.json`` manifest's
``generator.arg_template`` field drives these args at expansion time;
the Cartesian product of 2 kinds x 2 states yields 4 fixtures.
"""
from __future__ import annotations
import argparse
from pathlib import Path
from docx import Document
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
_REPO_ROOT = Path(__file__).resolve().parent.parent
def _write(kind: str, state: str, out: Path) -> None:
doc = Document()
paragraph = doc.add_paragraph()
run = paragraph.add_run("Striked text")
rPr = run._r.get_or_add_rPr()
if kind == "single":
tag = "w:strike"
elif kind == "double":
tag = "w:dstrike"
else:
raise ValueError(f"unknown kind {kind!r}; expected 'single' or 'double'")
el = OxmlElement(tag)
if state == "explicit-true":
el.set(qn("w:val"), "true")
elif state != "enabled":
raise ValueError(
f"unknown state {state!r}; expected 'enabled' or 'explicit-true'"
)
rPr.append(el)
out.parent.mkdir(parents=True, exist_ok=True)
doc.save(out, reproducible=True)
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument(
"--kind",
choices=("single", "double"),
required=True,
help="'single' -> <w:strike>, 'double' -> <w:dstrike>",
)
parser.add_argument(
"--state",
choices=("enabled", "explicit-true"),
required=True,
help="'enabled' -> empty element (implicit true); "
"'explicit-true' -> w:val=\"true\"",
)
parser.add_argument(
"--out",
required=True,
help="Output .docx path (absolute, or repo-relative).",
)
args = parser.parse_args()
out_path = Path(args.out)
if not out_path.is_absolute():
out_path = _REPO_ROOT / out_path
_write(args.kind, args.state, out_path)
print(out_path)
return 0
if __name__ == "__main__":
raise SystemExit(main())
{
"$schema": "../manifest.schema.json",
"id": "docx/run-strike-variants--double--explicit-true",
"kind": "literal",
"title": "Run strike variants (single vs double, enabled states)",
"format": "docx",
"category": "text-formatting",
"summary": "Matrix over the two OOXML strikethrough variants (w:strike single line, w:dstrike double line) x the two conventional enabled states (empty element, explicit w:val=\"true\").",
"spec": {
"source": "ecma-376-5-part-1",
"clause": "17.3.2.37",
"element": "w:strike",
"rnc_reference": "spec/ecma-376-5/part-1/rnc/WordprocessingML.rnc",
"xsd_reference": "spec/ecma-376-5/part-1/xsd/wml.xsd",
"notes": "Two mutually-exclusive strikethrough elements live in the OOXML run-properties schema: <w:strike> (clause 17.3.2.37) draws a single line, <w:dstrike> (clause 17.3.2.9) draws two parallel lines. Both are CT_OnOff toggles: an empty element means true; w:val=\"true\"/\"1\"/\"on\" are equivalent explicit-true spellings; w:val=\"false\"/\"0\"/\"off\" explicitly disables. This parameterised family walks the kind axis (single vs double) against the state axis (empty / explicit-true), producing 4 cases that confirm both variants accept both conventional enabled spellings. The existing literal manifests docx/strikethrough-text and docx/double-strikethrough cover the empty-element default shape only; this family adds the explicit-true dimension and keeps the two kinds in a single matrix."
},
"fixtures": {
"machine": "docx/run-strike-variants--double--explicit-true"
},
"generator": {
"python": "scripts/gen_run_strike_variants.py",
"arg_template": "--kind {kind.id} --state {state.id} --out fixtures/docx/run-strike-variants--{kind.id}--{state.id}.docx"
},
"_expansion": {
"parent_id": "docx/run-strike-variants",
"bindings": {
"kind": "double",
"state": "explicit-true"
}
},
"assertions": [
{
"id": "double-strike-present-explicit-true",
"part": "word/document.xml",
"namespaces": {
"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
},
"xpath": "//w:r[w:t[normalize-space()='Striked text']]/w:rPr/w:dstrike",
"must": "exist",
"description": "The run must carry a <w:dstrike> child inside <w:rPr> for state 'explicit-true'."
}
]
}
