docx/east-asian-layout--auto-space-dn-off

East-Asian typography controls: paragraph-level kinsoku, word_wrap, auto-spacing, plus run-level two-lines-in-one (w:eastAsianLayout/@w:combine) and vertical text direction (w:textDirection=tbRl on a table cell).

Library verdicts: python-docx: — docxjs: —

Metadata

Feature iddocx/east-asian-layout--auto-space-dn-off
Formatdocx
Categorytext-formatting
Familydocx/east-asian-layout
Axis valuescase=auto-space-dn-off
Spececma-376-5-part-1 § 17.3.1.16 w:kinsoku

XPath assertions

ID / partPredicateXPathpython-docxdocxjs
east-asian-auto-space-dn-off
word/document.xml
exist
East-Asian typography element for case auto-space-dn-off.
//w:pPr/w:autoSpaceDN[@w:val='0' or @w:val='false' or @w:val='off']

Render assertions

No render assertions declared.

Generator source

scripts/gen_east_asian_layout.py

#!/usr/bin/env python3
"""Generate ``fixtures/docx/east-asian-layout--<case>.docx``.

Parameterised generator for the ``docx/east-asian-layout`` family.
Each case exercises one East-Asian typography knob and asserts the
corresponding OOXML element is emitted.

Case index:

- ``kinsoku-on``            — paragraph-level ``w:kinsoku``.
- ``word-wrap-off``         — paragraph-level ``w:wordWrap w:val="0"`` (allow
                              mid-word break in CJK).
- ``auto-space-de-off``     — paragraph-level ``w:autoSpaceDE w:val="0"``.
- ``auto-space-dn-off``     — paragraph-level ``w:autoSpaceDN w:val="0"``.
- ``eal-two-lines-in-one``  — run-level ``w:eastAsianLayout w:combine="1"``.
- ``eal-vertical``          — run-level ``w:eastAsianLayout w:vert="1"``.
- ``cell-vertical-tbRl``    — table cell ``w:textDirection w:val="tbRl"``.
- ``section-vertical-tbRl`` — section ``w:textDirection w:val="tbRl"``.
"""

from __future__ import annotations

import argparse
from pathlib import Path
from typing import Callable

from docx import Document
from docx.enum.table import WD_TEXT_DIRECTION

_REPO_ROOT = Path(__file__).resolve().parent.parent


def _case_kinsoku(doc):
    p = doc.add_paragraph("漢字テスト")
    p.paragraph_format.kinsoku = True


def _case_word_wrap_off(doc):
    p = doc.add_paragraph("漢字テスト")
    p.paragraph_format.word_wrap = False


def _case_auto_space_de_off(doc):
    p = doc.add_paragraph("漢字 Latin")
    p.paragraph_format.auto_space_de = False


def _case_auto_space_dn_off(doc):
    p = doc.add_paragraph("漢字 123")
    p.paragraph_format.auto_space_dn = False


def _case_eal_two_lines_in_one(doc):
    p = doc.add_paragraph()
    r = p.add_run("中文")
    r.font.set_east_asian_layout(two_lines_in_one=True)


def _case_eal_vertical(doc):
    p = doc.add_paragraph()
    r = p.add_run("縦")
    r.font.set_east_asian_layout(vertical_alignment=True)


def _case_cell_vertical_tbRl(doc):
    table = doc.add_table(rows=1, cols=1)
    cell = table.cell(0, 0)
    cell.text = "縦書き"
    cell.text_direction = WD_TEXT_DIRECTION.TB_RL


def _case_section_vertical_tbRl(doc):
    doc.add_paragraph("Section vertical text direction")
    doc.sections[0].text_direction = WD_TEXT_DIRECTION.TB_RL


_CASES: dict[str, Callable] = {
    "kinsoku-on":            _case_kinsoku,
    "word-wrap-off":         _case_word_wrap_off,
    "auto-space-de-off":     _case_auto_space_de_off,
    "auto-space-dn-off":     _case_auto_space_dn_off,
    "eal-two-lines-in-one":  _case_eal_two_lines_in_one,
    "eal-vertical":          _case_eal_vertical,
    "cell-vertical-tbRl":    _case_cell_vertical_tbRl,
    "section-vertical-tbRl": _case_section_vertical_tbRl,
}


def _write(case: str, out: Path) -> None:
    if case not in _CASES:
        raise SystemExit(f"Unknown case id {case!r}; expected one of {sorted(_CASES)}")
    doc = Document()
    _CASES[case](doc)
    out.parent.mkdir(parents=True, exist_ok=True)
    doc.save(out, reproducible=True)


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--case", required=True)
    parser.add_argument("--out", required=True)
    args = parser.parse_args()

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


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

Manifest (expanded)

{
  "$schema": "../manifest.schema.json",
  "id": "docx/east-asian-layout--auto-space-dn-off",
  "kind": "literal",
  "title": "East-Asian typography layout",
  "format": "docx",
  "category": "text-formatting",
  "summary": "East-Asian typography controls: paragraph-level kinsoku, word_wrap, auto-spacing, plus run-level two-lines-in-one (w:eastAsianLayout/@w:combine) and vertical text direction (w:textDirection=tbRl on a table cell).",
  "spec": {
    "source": "ecma-376-5-part-1",
    "clause": "17.3.1.16",
    "element": "w:kinsoku",
    "rnc_reference": "spec/ecma-376-5/part-1/rnc/WordprocessingML.rnc",
    "xsd_reference": "spec/ecma-376-5/part-1/xsd/wml.xsd",
    "notes": "East-Asian typography in WordprocessingML splits across several elements and levels. On w:pPr: w:kinsoku (line-break rules forbidding certain characters at line start/end), w:wordWrap (when w:val=\"0\" / false, allow mid-word breaks in CJK — latin-script word-wrap is the default when absent), w:autoSpaceDE (auto-space CJK↔Latin), w:autoSpaceDN (auto-space CJK↔numerals). On w:rPr: w:eastAsianLayout (@w:combine=\"1\" → two-lines-in-one; @w:vert=\"1\" → vertical alignment within an inline run). On w:tcPr (table cells) and w:sectPr: w:textDirection (w:val=\"tbRl\" → vertical writing, top-to-bottom right-to-left). This family covers each of those five element positions."
  },
  "fixtures": {
    "machine": "docx/east-asian-layout--auto-space-dn-off"
  },
  "generator": {
    "python": "scripts/gen_east_asian_layout.py",
    "arg_template": "--case {case.id} --out fixtures/docx/east-asian-layout--{case.id}.docx"
  },
  "_expansion": {
    "parent_id": "docx/east-asian-layout",
    "bindings": {
      "case": "auto-space-dn-off"
    }
  },
  "assertions": [
    {
      "id": "east-asian-auto-space-dn-off",
      "part": "word/document.xml",
      "namespaces": {
        "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
      },
      "xpath": "//w:pPr/w:autoSpaceDN[@w:val='0' or @w:val='false' or @w:val='off']",
      "must": "exist",
      "description": "East-Asian typography element for case auto-space-dn-off."
    }
  ]
}

Fixture

Download east-asian-layout--auto-space-dn-off.docx (18.6 KB)

Reference preview

No rendered reference is available for this case.

Spec notes

East-Asian typography in WordprocessingML splits across several elements and levels. On w:pPr: w:kinsoku (line-break rules forbidding certain characters at line start/end), w:wordWrap (when w:val="0" / false, allow mid-word breaks in CJK — latin-script word-wrap is the default when absent), w:autoSpaceDE (auto-space CJK↔Latin), w:autoSpaceDN (auto-space CJK↔numerals). On w:rPr: w:eastAsianLayout (@w:combine="1" → two-lines-in-one; @w:vert="1" → vertical alignment within an inline run). On w:tcPr (table cells) and w:sectPr: w:textDirection (w:val="tbRl" → vertical writing, top-to-bottom right-to-left). This family covers each of those five element positions.