Skip to content

Add a w:tblLook API for table style conditional formatting #97

Closed

Description

@toxicphreAK

w:tblLook is the element that tells Word which parts of a table style to apply — whether the first row is a header row, whether the first column is emphasised, and whether row or column banding is on. Without it, applying a table style produces a table that looks nothing like the style preview in Word.

Today it is written once as a hardcoded string in CT_Tbl._tbl_xml() (src/docx/oxml/table.py:593), with firstRow="1" firstColumn="1" noHBand="0" noVBand="1", and there is no way to read or change it. "w:tblLook" appears in CT_TblPr._tag_seq (src/docx/oxml/table.py:693) but no accessor is declared for it.

So a user who applies "Table Grid" or a banded style to a table gets whatever those five defaults imply, and cannot turn banding on, cannot mark a total row, and cannot switch the first-column emphasis off.

Where the prior art is

lnv42/python-docx, branch feature/tableLooking, adds CT_TblLook with the six attributes, a tblLook accessor on CT_TblPr, and first_row / first_col / last_row / last_col / h_band / v_band properties on Table. It also threads the flags through Table.add_table() as keyword arguments.

It is against upstream v0.8.7 and has bugs — the hBand/vBand property pairs are defined twice as plain methods rather than as a property and its setter, so table.h_band returns a bound method and h_band = True overwrites it. Take the shape, not the code.

Shape

Per ref/xsd/wml.xsd, CT_TblLook is all-attribute, no children:

firstRow, lastRow, firstColumn, lastColumn, noHBand, noVBand   s:ST_OnOff
val                                                            ST_ShortHexNumber
  • CT_TblLook in oxml/table.py, registered in oxml/__init__.py
  • tblLook = ZeroOrOne("w:tblLook", successors=...) on CT_TblPr, sliced at the right index of _tag_seq, with a placement test
  • Table.look returning a small proxy with first_row, last_row, first_column, last_column, horizontal_banding and vertical_banding as read/write booleans

The banding pair inverts — horizontal_banding is not noHBand. Make that inversion a property on the proxy and keep the oxml layer faithful to the attribute names.

@w:val is the legacy bitmask carrying the same six flags. Word writes both and keeps them in sync. Decide whether to maintain it on write (Word tolerates its absence, but some older consumers read only the bitmask) and say so in the docstring either way.

Activity

  1. toxicphreAK commented on Aug 5, 2026

    @toxicphreAK
    OwnerAuthor

    Landed in #139. Table.look with the six flags; the banding pair is inverted in the proxy so the oxml layer stays faithful to w:noHBand/w:noVBand. On the @w:val question: it is maintained. Word writes both and keeps them in step, some older consumers read only the bitmask, and CT_TblLook.update_val() says so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions