docx/heading-1

A top-level heading paragraph styled with the built-in Heading 1 style.

Library verdicts: python-docx: — docxjs: pass

Metadata

Feature iddocx/heading-1
Formatdocx
Categoryheadings
Spececma-376-5-part-1 § 17.9.2 w:pStyle

XPath assertions

ID / partPredicateXPathpython-docxdocxjs
heading-1-pstyle-present
word/document.xml
exist
The heading paragraph must declare a pStyle inside its pPr.
//w:p[w:r/w:t[normalize-space()='Heading 1 Title']]/w:pPr/w:pStyle
heading-1-pstyle-val
word/document.xml
equal = Heading1
The pStyle value for a level-1 heading must be 'Heading1'.
//w:p[w:r/w:t[normalize-space()='Heading 1 Title']]/w:pPr/w:pStyle/@w:val

Render assertions

IDPredicateSelectorpython-docxdocxjs
heading-1-renderedcss_selector/ match-text = Heading 1 Title
A heading-1 DOM node (h1, .docx-heading-1, or Heading1-classed element) must contain the fixture text. Falls back to any paragraph since renderer conventions vary.
.docx-wrapper h1, .docx-wrapper .docx-heading-1, .docx-wrapper [class*='Heading1'], .docx-wrapper ppass
heading-1-has-semantic-rolecss_selector/ exist
Accessibility: the Heading 1 paragraph must surface either as a semantic <h1> element OR as an element with role='heading' and aria-level='1'. Either convention is accepted; a renderer that emits only a styled <p> or <div> with no heading role/level fails this assertion — that's the intended signal.
.docx-wrapper h1, .docx-wrapper [role='heading'][aria-level='1'], .docx-wrapper [role='heading'][aria-level="1"]

Generator source

scripts/gen_heading_1.py

#!/usr/bin/env python3
"""Generate ``fixtures/docx/heading-1.docx``.

A minimal document exercising the ``w:pStyle`` paragraph-style reference
for the built-in Heading 1 style. Satisfies the assertions in
``features/docx/heading-1.json``.
"""

from __future__ import annotations

from pathlib import Path

from docx import Document

_REPO_ROOT = Path(__file__).resolve().parent.parent
_OUT = _REPO_ROOT / "fixtures" / "docx" / "heading-1.docx"


def main() -> int:
    doc = Document()
    doc.add_heading("Heading 1 Title", level=1)
    _OUT.parent.mkdir(parents=True, exist_ok=True)
    doc.save(_OUT, reproducible=True)
    print(_OUT)
    return 0


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

Manifest (expanded)

{
  "$schema": "../manifest.schema.json",
  "id": "docx/heading-1",
  "title": "Heading 1",
  "format": "docx",
  "category": "headings",
  "summary": "A top-level heading paragraph styled with the built-in Heading 1 style.",
  "spec": {
    "source": "ecma-376-5-part-1",
    "clause": "17.9.2",
    "element": "w:pStyle",
    "rnc_reference": "spec/ecma-376-5/part-1/rnc/WordprocessingML.rnc",
    "xsd_reference": "spec/ecma-376-5/part-1/xsd/wml.xsd",
    "notes": "Heading style is applied via <w:pPr><w:pStyle w:val=\"Heading1\"/></w:pPr>. Word collapses the whitespace in the style name so the XML attribute is 'Heading1', not 'Heading 1'."
  },
  "fixtures": {
    "machine": "docx/heading-1",
    "office": "docx/heading-1"
  },
  "generator": {
    "python": "scripts/gen_heading_1.py"
  },
  "assertions": [
    {
      "id": "heading-1-pstyle-present",
      "part": "word/document.xml",
      "namespaces": {
        "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
      },
      "xpath": "//w:p[w:r/w:t[normalize-space()='Heading 1 Title']]/w:pPr/w:pStyle",
      "must": "exist",
      "description": "The heading paragraph must declare a pStyle inside its pPr."
    },
    {
      "id": "heading-1-pstyle-val",
      "part": "word/document.xml",
      "namespaces": {
        "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
      },
      "xpath": "//w:p[w:r/w:t[normalize-space()='Heading 1 Title']]/w:pPr/w:pStyle/@w:val",
      "must": "equal",
      "value": "Heading1",
      "description": "The pStyle value for a level-1 heading must be 'Heading1'."
    }
  ],
  "render_assertions": [
    {
      "id": "heading-1-rendered",
      "kind": "css_selector",
      "selector": ".docx-wrapper h1, .docx-wrapper .docx-heading-1, .docx-wrapper [class*='Heading1'], .docx-wrapper p",
      "must": "match-text",
      "value": "Heading 1 Title",
      "description": "A heading-1 DOM node (h1, .docx-heading-1, or Heading1-classed element) must contain the fixture text. Falls back to any paragraph since renderer conventions vary."
    },
    {
      "id": "heading-1-has-semantic-role",
      "kind": "css_selector",
      "selector": ".docx-wrapper h1, .docx-wrapper [role='heading'][aria-level='1'], .docx-wrapper [role='heading'][aria-level=\"1\"]",
      "must": "exist",
      "description": "Accessibility: the Heading 1 paragraph must surface either as a semantic <h1> element OR as an element with role='heading' and aria-level='1'. Either convention is accepted; a renderer that emits only a styled <p> or <div> with no heading role/level fails this assertion — that's the intended signal."
    }
  ]
}

Fixture

Download heading-1.docx (18.6 KB)

Reference preview

Reference (machine, page 1 PNG)

docx/heading-1 page 1 reference

Reference PDF


Download PDF Open in PDF.js

Spec notes

Heading style is applied via <w:pPr><w:pStyle w:val="Heading1"/></w:pPr>. Word collapses the whitespace in the style name so the XML attribute is 'Heading1', not 'Heading 1'.