docx_plus.styles.theme¶
Read-only theme color and font resolution. The cascade resolver in
styles.inspect uses these to translate themeColor
attributes into concrete hex values and *Theme font tokens (minorHAnsi,
…) into typeface names. Writing themes is out of scope — this module is
read-only (SPEC §1).
docx_plus.styles.theme ¶
Read-only theme color resolution.
WordprocessingML references theme colors symbolically (themeColor="accent1")
with optional themeTint/themeShade modifiers. The actual RGB values
live in word/theme/theme1.xml under a:clrScheme. This module reads that
scheme, translates Word's ST_ThemeColor names to DrawingML scheme keys
(ECMA-376 17.18.97), and applies the tint/shade/lumMod/lumOff transforms
defined in ECMA-376 17.18.40.
Failures here are recoverable: a missing or malformed theme part is reported
by :func:load_theme returning None (or a partially-populated scheme),
not by raising. Callers — primarily the cascade resolver — fold that into a
partial=True flag on the resolved formatting. SPEC §4 "Theme references".
The same scheme also exposes the theme's fonts (a:fontScheme):
:func:resolve_theme_font maps a WordprocessingML font-theme token
(w:asciiTheme="minorHAnsi" etc.) to the concrete typeface the theme
defines ("Calibri"), so the cascade can report a real font name rather
than the bare token.
The w:color cascade element (ECMA-376 CT_Color) carries only
themeTint / themeShade, so :func:resolve_theme_color applies just
those two transforms. :func:apply_lum_mod / :func:apply_lum_off
implement the DrawingML lumMod / lumOff transforms for callers that
read theme colors referenced from DrawingML (shape fills, w14 text
effects), where those transforms do appear — they are deliberately not part
of the w:color resolution path because that element cannot carry them.
The module is read-only; writing themes is a v0.2 non-goal (SPEC §1).
ThemeColors
dataclass
¶
Resolved theme color + font scheme.
Built by :func:load_theme. Use :meth:base to look up a color by
Word's ST_ThemeColor name and :meth:font to look up a typeface
by ST_Theme font token (both are what appear in WordprocessingML).
Attributes:
| Name | Type | Description |
|---|---|---|
scheme |
dict[str, str]
|
DrawingML color key ( |
fonts |
dict[str, str]
|
|
base ¶
Return the unmodified hex color for a Word theme color name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
theme_name
|
str
|
A value from |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Uppercase |
str | None
|
recognized theme color or the underlying scheme entry is missing. |
Source code in docx_plus/styles/theme.py
font ¶
Return the concrete typeface for an ST_Theme font token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
A |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
The typeface name from the theme's |
str | None
|
|
str | None
|
scheme entry is empty / missing. |
Source code in docx_plus/styles/theme.py
ThemeError ¶
Bases: DocxPlusError
Raised when theme inputs are structurally invalid in an unrecoverable way.
Most theme defects (missing part, malformed XML, unknown name) are reported
via None returns or partial=True per SPEC §4. This error is
reserved for programmer-error cases such as an unparseable hex transform
byte that would otherwise pass through silently.
load_theme ¶
Read word/theme/theme1.xml and return its color scheme.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
doc
|
Document
|
A python-docx :class: |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ThemeColors | None
|
class: |
ThemeColors | None
|
|
|
ThemeColors | None
|
cannot be parsed at all. A partially-readable scheme is returned as a |
|
ThemeColors | None
|
|
|
ThemeColors | None
|
entries — callers can detect partiality via :meth: |
|
ThemeColors | None
|
returning |
Source code in docx_plus/styles/theme.py
resolve_theme_color ¶
resolve_theme_color(
theme: ThemeColors | None,
name: str,
*,
tint: str | None = None,
shade: str | None = None,
) -> str | None
Resolve a WordprocessingML theme color reference to RRGGBB hex.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
theme
|
ThemeColors | None
|
The document's theme scheme, or |
required |
name
|
str
|
Word |
required |
tint
|
str | None
|
Optional |
None
|
shade
|
str | None
|
Optional |
None
|
Returns:
| Type | Description |
|---|---|
str | None
|
Uppercase |
str | None
|
the theme is absent, or the name is the literal |
Note
WordprocessingML treats themeTint and themeShade as mutually
exclusive in practice, but this function tolerates both being set: the
shade is applied first, then the tint, matching the order Word uses
when it encounters the (unusual) combination.
Source code in docx_plus/styles/theme.py
resolve_theme_font ¶
Resolve a WordprocessingML font-theme token to a concrete typeface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
theme
|
ThemeColors | None
|
The document's theme, or |
required |
token
|
str
|
An |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
The typeface name (e.g. |
str | None
|
absent or the token has no entry in the font scheme. |
Source code in docx_plus/styles/theme.py
apply_theme_tint ¶
Lighten hex_color toward white by ECMA-376 17.18.40 themeTint.
Algorithm: convert to HSL, replace L with L * t + (1 - t) where
t = int(tint_byte, 16) / 255. tint="FF" is a no-op; tint="00"
forces L to 1 (pure white).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hex_color
|
str
|
Six-character hex color (with or without leading |
required |
tint_byte
|
str
|
Hex byte |
required |
Returns:
| Type | Description |
|---|---|
str
|
Uppercase |
Source code in docx_plus/styles/theme.py
apply_theme_shade ¶
Darken hex_color toward black by ECMA-376 17.18.40 themeShade.
Algorithm: convert to HSL, replace L with L * s where
s = int(shade_byte, 16) / 255. shade="FF" is a no-op; shade="00"
forces L to 0 (pure black).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hex_color
|
str
|
Six-character hex color (with or without leading |
required |
shade_byte
|
str
|
Hex byte |
required |
Returns:
| Type | Description |
|---|---|
str
|
Uppercase |
Source code in docx_plus/styles/theme.py
apply_lum_mod ¶
Multiply L by lum_mod / 100000 per ECMA-376 17.18.40.
DrawingML transform values are percent thousandths: 50000 means 50%.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hex_color
|
str
|
Six-character hex color. |
required |
lum_mod
|
int
|
Percent thousandths (e.g. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Uppercase |
Source code in docx_plus/styles/theme.py
apply_lum_off ¶
Add lum_off / 100000 to L per ECMA-376 17.18.40.
DrawingML transform values are percent thousandths: 80000 adds 0.8.
The result is clamped to [0, 1].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hex_color
|
str
|
Six-character hex color. |
required |
lum_off
|
int
|
Percent thousandths (e.g. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Uppercase |