docx/table-border-style--left--thick

Each ST_Border line style applied to a single edge of w:tblBorders (top / left / bottom / right). Expands to 20 styles x 4 sides = 80 cases.

Library verdicts: python-docx: — docxjs: pass

Metadata

Feature iddocx/table-border-style--left--thick
Formatdocx
Categorytables
Familydocx/table-border-style
Axis valuesside=left, style=thick
Spececma-376-5-part-1 § 17.4.38 w:tblBorders

XPath assertions

ID / partPredicateXPathpython-docxdocxjs
border-left-is-thick
word/document.xml
equal = thick
The table's w:tblBorders/left edge must declare line style 'thick'.
//w:tblPr/w:tblBorders/w:left/@w:val

Render assertions

IDPredicateSelectorpython-docxdocxjs
table-border-style-thick-left-table-presentcss_selector/ exist
A rendered <table> element must be present under .docx-wrapper.
.docx-wrapper tablepass
table-border-style-thick-left-cell-text-smokecss_selector/ match-text = Border test cell
Smoke check: the rendered table cell text must include 'Border test cell'. Exact border-style rendering is renderer-specific and intentionally not asserted.
.docx-wrapper table td, .docx-wrapper table thpass

Generator source

scripts/gen_table_border_style.py

#!/usr/bin/env python3
"""Generate ``fixtures/docx/table-border-style--<style>--<side>.docx``.

Parameterised generator for the ``docx/table-border-style`` family: writes a
single-cell table whose ``w:tblBorders`` declares a single edge with the
requested ``ST_Border`` line style. Expanded at runtime by the manifest's
``generator.arg_template`` into 20 styles x 4 sides = 80 cases.

Uses raw ``OxmlElement`` rather than the fork's high-level
``Table.set_borders`` API because ``set_borders`` only accepts the
``WD_BORDER_STYLE`` enum, which does not cover every ``ST_Border`` value
enumerated in ECMA-376 Part 1 clause 17.18.2.
"""

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

_VALID_SIDES = {"top", "left", "bottom", "right", "insideH", "insideV"}


def _write(style_val: str, side: str, out: Path) -> None:
    if side not in _VALID_SIDES:
        raise ValueError(
            f"Unknown side {side!r}; expected one of {sorted(_VALID_SIDES)}"
        )

    doc = Document()
    table = doc.add_table(rows=1, cols=1)
    table.rows[0].cells[0].text = "Border test cell"

    tblPr = table._tbl.tblPr
    tblBorders = OxmlElement("w:tblBorders")
    edge = OxmlElement(f"w:{side}")
    edge.set(qn("w:val"), style_val)
    edge.set(qn("w:sz"), "8")
    edge.set(qn("w:space"), "0")
    edge.set(qn("w:color"), "000000")
    tblBorders.append(edge)
    tblPr.append(tblBorders)

    out.parent.mkdir(parents=True, exist_ok=True)
    doc.save(out, reproducible=True)


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--style", required=True, help="ST_Border val, e.g. 'single'")
    parser.add_argument(
        "--side",
        required=True,
        help="Edge element local name: top | left | bottom | right (also insideH/insideV)",
    )
    parser.add_argument("--out", required=True, help="Output .docx path")
    args = parser.parse_args()

    out_path = Path(args.out)
    if not out_path.is_absolute():
        out_path = _REPO_ROOT / out_path
    _write(args.style, args.side, out_path)
    print(out_path)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

Manifest (expanded)

{
  "$schema": "../manifest.schema.json",
  "id": "docx/table-border-style--left--thick",
  "kind": "literal",
  "title": "Table border style",
  "format": "docx",
  "category": "tables",
  "summary": "Each ST_Border line style applied to a single edge of w:tblBorders (top / left / bottom / right). Expands to 20 styles x 4 sides = 80 cases.",
  "spec": {
    "source": "ecma-376-5-part-1",
    "clause": "17.4.38",
    "element": "w:tblBorders",
    "rnc_reference": "spec/ecma-376-5/part-1/rnc/WordprocessingML.rnc",
    "xsd_reference": "spec/ecma-376-5/part-1/xsd/wml.xsd",
    "notes": "<w:tblBorders> inside <w:tblPr> carries per-edge border child elements (w:top, w:left, w:bottom, w:right, w:insideH, w:insideV). Each child's w:val attribute is an ST_Border line style. ECMA-376 Part 1 clause 17.18.2 enumerates ST_Border; this family covers 20 common values on the four outer edges. Rendering of specific border styles varies wildly across consumers, so only a smoke render check is asserted."
  },
  "fixtures": {
    "machine": "docx/table-border-style--left--thick"
  },
  "generator": {
    "python": "scripts/gen_table_border_style.py",
    "arg_template": "--style {style.val} --side {side.id} --out fixtures/docx/table-border-style--{side.id}--{style.id}.docx"
  },
  "_expansion": {
    "parent_id": "docx/table-border-style",
    "bindings": {
      "side": "left",
      "style": "thick"
    }
  },
  "assertions": [
    {
      "id": "border-left-is-thick",
      "part": "word/document.xml",
      "namespaces": {
        "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
      },
      "xpath": "//w:tblPr/w:tblBorders/w:left/@w:val",
      "must": "equal",
      "value": "thick",
      "description": "The table's w:tblBorders/left edge must declare line style 'thick'."
    }
  ],
  "render_assertions": [
    {
      "id": "table-border-style-thick-left-table-present",
      "kind": "css_selector",
      "selector": ".docx-wrapper table",
      "must": "exist",
      "description": "A rendered <table> element must be present under .docx-wrapper."
    },
    {
      "id": "table-border-style-thick-left-cell-text-smoke",
      "kind": "css_selector",
      "selector": ".docx-wrapper table td, .docx-wrapper table th",
      "must": "match-text",
      "value": "Border test cell",
      "description": "Smoke check: the rendered table cell text must include 'Border test cell'. Exact border-style rendering is renderer-specific and intentionally not asserted."
    }
  ]
}

Fixture

Download table-border-style--left--thick.docx (18.7 KB)

Reference preview

Reference (machine, page 1 PNG)

docx/table-border-style--left--thick page 1 reference

Reference PDF


Download PDF Open in PDF.js

Spec notes

<w:tblBorders> inside <w:tblPr> carries per-edge border child elements (w:top, w:left, w:bottom, w:right, w:insideH, w:insideV). Each child's w:val attribute is an ST_Border line style. ECMA-376 Part 1 clause 17.18.2 enumerates ST_Border; this family covers 20 common values on the four outer edges. Rendering of specific border styles varies wildly across consumers, so only a smoke render check is asserted.