Skip to content

Style

Style class for various style tags and BackgroundImage class.

Classes:

Name Description
BackgroundImage

Style for a background image, “style:background-image”.

Style

Style class for many ODF tags, “style:style”, “number:date-style”,…

Functions:

Name Description
create_table_cell_style

Create and return a table cell style.

default_boolean_style

Return a default boolean style.

default_currency_style

Return a default currency style (€).

default_date_style

Return a default date style (Y-M-D).

default_number_style

Return a default number style with two decimals.

default_percentage_style

Return a default percentage style with two decimals.

default_time_style

Return a default time style.

hex2rgb

Convert a “#RRGGBB” hexadecimal color to an (R, G, B) tuple.

make_table_cell_border_string

Generate a string for “style:table-cell-properties” “fo:border”.

rgb2hex

Convert a color name or (R, G, B) tuple to a “#RRGGBB” hexadecimal string.

Attributes:

Name Type Description
CSS3_COLORMAP
ODF_PROPERTIES

CSS3_COLORMAP module-attribute

CSS3_COLORMAP = {
    "indigo": (75, 0, 130),
    "gold": (255, 215, 0),
    "firebrick": (178, 34, 34),
    "indianred": (205, 92, 92),
    "yellow": (255, 255, 0),
    "darkolivegreen": (85, 107, 47),
    "darkseagreen": (143, 188, 143),
    "slategrey": (112, 128, 144),
    "darkslategrey": (47, 79, 79),
    "mediumvioletred": (199, 21, 133),
    "mediumorchid": (186, 85, 211),
    "chartreuse": (127, 255, 0),
    "mediumslateblue": (123, 104, 238),
    "black": (0, 0, 0),
    "springgreen": (0, 255, 127),
    "crimson": (220, 20, 60),
    "lightsalmon": (255, 160, 122),
    "brown": (165, 42, 42),
    "turquoise": (64, 224, 208),
    "olivedrab": (107, 142, 35),
    "lightcyan": (224, 255, 255),
    "cyan": (0, 255, 255),
    "silver": (192, 192, 192),
    "skyblue": (135, 206, 235),
    "gray": (128, 128, 128),
    "darkturquoise": (0, 206, 209),
    "goldenrod": (218, 165, 32),
    "darkgreen": (0, 100, 0),
    "darkviolet": (148, 0, 211),
    "darkgray": (169, 169, 169),
    "lightpink": (255, 182, 193),
    "teal": (0, 128, 128),
    "darkmagenta": (139, 0, 139),
    "lightgoldenrodyellow": (250, 250, 210),
    "lavender": (230, 230, 250),
    "yellowgreen": (154, 205, 50),
    "thistle": (216, 191, 216),
    "violet": (238, 130, 238),
    "navy": (0, 0, 128),
    "dimgrey": (105, 105, 105),
    "orchid": (218, 112, 214),
    "blue": (0, 0, 255),
    "ghostwhite": (248, 248, 255),
    "honeydew": (240, 255, 240),
    "cornflowerblue": (100, 149, 237),
    "darkblue": (0, 0, 139),
    "darkkhaki": (189, 183, 107),
    "mediumpurple": (147, 112, 216),
    "cornsilk": (255, 248, 220),
    "red": (255, 0, 0),
    "bisque": (255, 228, 196),
    "slategray": (112, 128, 144),
    "darkcyan": (0, 139, 139),
    "khaki": (240, 230, 140),
    "wheat": (245, 222, 179),
    "deepskyblue": (0, 191, 255),
    "darkred": (139, 0, 0),
    "steelblue": (70, 130, 180),
    "aliceblue": (240, 248, 255),
    "lightslategrey": (119, 136, 153),
    "gainsboro": (220, 220, 220),
    "mediumturquoise": (72, 209, 204),
    "floralwhite": (255, 250, 240),
    "plum": (221, 160, 221),
    "purple": (128, 0, 128),
    "lightgrey": (211, 211, 211),
    "burlywood": (222, 184, 135),
    "darksalmon": (233, 150, 122),
    "beige": (245, 245, 220),
    "azure": (240, 255, 255),
    "lightsteelblue": (176, 196, 222),
    "oldlace": (253, 245, 230),
    "greenyellow": (173, 255, 47),
    "royalblue": (65, 105, 225),
    "lightseagreen": (32, 178, 170),
    "sienna": (160, 82, 45),
    "lightcoral": (240, 128, 128),
    "orangered": (255, 69, 0),
    "navajowhite": (255, 222, 173),
    "lime": (0, 255, 0),
    "palegreen": (152, 251, 152),
    "mistyrose": (255, 228, 225),
    "seashell": (255, 245, 238),
    "mediumspringgreen": (0, 250, 154),
    "fuchsia": (255, 0, 255),
    "papayawhip": (255, 239, 213),
    "blanchedalmond": (255, 235, 205),
    "peru": (205, 133, 63),
    "aquamarine": (127, 255, 212),
    "white": (255, 255, 255),
    "darkslategray": (47, 79, 79),
    "lightgray": (211, 211, 211),
    "ivory": (255, 255, 240),
    "dodgerblue": (30, 144, 255),
    "lawngreen": (124, 252, 0),
    "chocolate": (210, 105, 30),
    "orange": (255, 165, 0),
    "forestgreen": (34, 139, 34),
    "darkgrey": (169, 169, 169),
    "olive": (128, 128, 0),
    "mintcream": (245, 255, 250),
    "antiquewhite": (250, 235, 215),
    "darkorange": (255, 140, 0),
    "cadetblue": (95, 158, 160),
    "moccasin": (255, 228, 181),
    "limegreen": (50, 205, 50),
    "saddlebrown": (139, 69, 19),
    "grey": (128, 128, 128),
    "darkslateblue": (72, 61, 139),
    "lightskyblue": (135, 206, 250),
    "deeppink": (255, 20, 147),
    "coral": (255, 127, 80),
    "aqua": (0, 255, 255),
    "darkgoldenrod": (184, 134, 11),
    "maroon": (128, 0, 0),
    "sandybrown": (244, 164, 96),
    "tan": (210, 180, 140),
    "magenta": (255, 0, 255),
    "rosybrown": (188, 143, 143),
    "pink": (255, 192, 203),
    "lightblue": (173, 216, 230),
    "palevioletred": (216, 112, 147),
    "mediumseagreen": (60, 179, 113),
    "slateblue": (106, 90, 205),
    "dimgray": (105, 105, 105),
    "powderblue": (176, 224, 230),
    "seagreen": (46, 139, 87),
    "snow": (255, 250, 250),
    "mediumblue": (0, 0, 205),
    "midnightblue": (25, 25, 112),
    "paleturquoise": (175, 238, 238),
    "palegoldenrod": (238, 232, 170),
    "whitesmoke": (245, 245, 245),
    "darkorchid": (153, 50, 204),
    "salmon": (250, 128, 114),
    "lightslategray": (119, 136, 153),
    "lemonchiffon": (255, 250, 205),
    "lightgreen": (144, 238, 144),
    "tomato": (255, 99, 71),
    "hotpink": (255, 105, 180),
    "lightyellow": (255, 255, 224),
    "lavenderblush": (255, 240, 245),
    "linen": (250, 240, 230),
    "mediumaquamarine": (102, 205, 170),
    "green": (0, 128, 0),
    "blueviolet": (138, 43, 226),
    "peachpuff": (255, 218, 185),
}

ODF_PROPERTIES module-attribute

ODF_PROPERTIES = {
    "chart:angle-offset",
    "chart:auto-position",
    "chart:auto-size",
    "chart:automatic-content",
    "chart:axis-label-position",
    "chart:axis-position",
    "chart:connect-bars",
    "chart:data-label-number",
    "chart:data-label-symbol",
    "chart:data-label-text",
    "chart:deep",
    "chart:display-equation",
    "chart:display-label",
    "chart:display-r-square",
    "chart:error-category",
    "chart:error-lower-indicator",
    "chart:error-lower-limit",
    "chart:error-lower-range",
    "chart:error-margin",
    "chart:error-percentage",
    "chart:error-upper-indicator",
    "chart:error-upper-limit",
    "chart:error-upper-range",
    "chart:gap-width",
    "chart:group-bars-per-axis",
    "chart:hole-size",
    "chart:include-hidden-cells",
    "chart:interpolation",
    "chart:interval-major",
    "chart:interval-minor-divisor",
    "chart:japanese-candle-stick",
    "chart:label-arrangement",
    "chart:label-position",
    "chart:label-position-negative",
    "chart:lines",
    "chart:link-data-style-to-source",
    "chart:logarithmic",
    "chart:maximum",
    "chart:mean-value",
    "chart:minimum",
    "chart:origin",
    "chart:overlap",
    "chart:percentage",
    "chart:pie-offset",
    "chart:regression-type",
    "chart:reverse-direction",
    "chart:right-angled-axes",
    "chart:scale-text",
    "chart:series-source",
    "chart:solid-type",
    "chart:sort-by-x-values",
    "chart:spline-order",
    "chart:spline-resolution",
    "chart:stacked",
    "chart:symbol-height",
    "chart:symbol-name",
    "chart:symbol-type",
    "chart:symbol-width",
    "chart:text-overlap",
    "chart:three-dimensional",
    "chart:tick-mark-position",
    "chart:tick-marks-major-inner",
    "chart:tick-marks-major-outer",
    "chart:tick-marks-minor-inner",
    "chart:tick-marks-minor-outer",
    "chart:treat-empty-cells",
    "chart:vertical",
    "chart:visible",
    "db:additional-column-statement",
    "db:append-table-alias-name",
    "db:apply-command",
    "db:as-template",
    "db:base-dn",
    "db:boolean-comparison-mode",
    "db:catalog-name",
    "db:command",
    "db:data-source-setting-is-list",
    "db:data-source-setting-name",
    "db:data-source-setting-type",
    "db:data-type",
    "db:database-name",
    "db:decimal",
    "db:default-cell-style-name",
    "db:default-row-style-name",
    "db:delete-rule",
    "db:description",
    "db:enable-sql92-check",
    "db:encoding",
    "db:escape-processing",
    "db:extension",
    "db:field",
    "db:hostname",
    "db:ignore-driver-privileges",
    "db:is-ascending",
    "db:is-autoincrement",
    "db:is-clustered",
    "db:is-empty-allowed",
    "db:is-first-row-header-line",
    "db:is-nullable",
    "db:is-password-required",
    "db:is-table-name-length-limited",
    "db:is-unique",
    "db:local-socket",
    "db:login-timeout",
    "db:max-row-count",
    "db:media-type",
    "db:name",
    "db:parameter-name-substitution",
    "db:port",
    "db:precision",
    "db:referenced-table-name",
    "db:related-column-name",
    "db:row-retrieving-statement",
    "db:scale",
    "db:schema-name",
    "db:show-deleted",
    "db:string",
    "db:style-name",
    "db:suppress-version-columns",
    "db:system-driver-settings",
    "db:thousand",
    "db:title",
    "db:type",
    "db:type-name",
    "db:update-rule",
    "db:use-catalog",
    "db:use-system-user",
    "db:user-name",
    "db:visible",
    "dr3d:ambient-color",
    "dr3d:back-scale",
    "dr3d:backface-culling",
    "dr3d:close-back",
    "dr3d:close-front",
    "dr3d:depth",
    "dr3d:diffuse-color",
    "dr3d:edge-rounding",
    "dr3d:edge-rounding-mode",
    "dr3d:emissive-color",
    "dr3d:end-angle",
    "dr3d:horizontal-segments",
    "dr3d:lighting-mode",
    "dr3d:normals-direction",
    "dr3d:normals-kind",
    "dr3d:shadow",
    "dr3d:shininess",
    "dr3d:specular-color",
    "dr3d:texture-filter",
    "dr3d:texture-generation-mode-x",
    "dr3d:texture-generation-mode-y",
    "dr3d:texture-kind",
    "dr3d:texture-mode",
    "dr3d:vertical-segments",
    "draw:auto-grow-height",
    "draw:auto-grow-width",
    "draw:background-size",
    "draw:blue",
    "draw:caption-angle",
    "draw:caption-angle-type",
    "draw:caption-escape",
    "draw:caption-escape-direction",
    "draw:caption-fit-line-length",
    "draw:caption-gap",
    "draw:caption-line-length",
    "draw:caption-type",
    "draw:color-inversion",
    "draw:color-mode",
    "draw:contrast",
    "draw:decimal-places",
    "draw:display-name",
    "draw:draw-aspect",
    "draw:end-guide",
    "draw:end-line-spacing-horizontal",
    "draw:end-line-spacing-vertical",
    "draw:escape-direction",
    "draw:fill",
    "draw:fill-color",
    "draw:fill-gradient-name",
    "draw:fill-hatch-name",
    "draw:fill-hatch-solid",
    "draw:fill-image-height",
    "draw:fill-image-name",
    "draw:fill-image-ref-point",
    "draw:fill-image-ref-point-x",
    "draw:fill-image-ref-point-y",
    "draw:fill-image-width",
    "draw:fit-to-contour",
    "draw:fit-to-size",
    "draw:frame-display-border",
    "draw:frame-display-scrollbar",
    "draw:frame-margin-horizontal",
    "draw:frame-margin-vertical",
    "draw:gamma",
    "draw:gradient-step-count",
    "draw:green",
    "draw:guide-distance",
    "draw:guide-overhang",
    "draw:id",
    "draw:image-opacity",
    "draw:line-distance",
    "draw:luminance",
    "draw:marker-end",
    "draw:marker-end-center",
    "draw:marker-end-width",
    "draw:marker-start",
    "draw:marker-start-center",
    "draw:marker-start-width",
    "draw:measure-align",
    "draw:measure-vertical-align",
    "draw:name",
    "draw:ole-draw-aspect",
    "draw:opacity",
    "draw:opacity-name",
    "draw:parallel",
    "draw:placing",
    "draw:red",
    "draw:secondary-fill-color",
    "draw:shadow",
    "draw:shadow-color",
    "draw:shadow-offset-x",
    "draw:shadow-offset-y",
    "draw:shadow-opacity",
    "draw:show-unit",
    "draw:start-guide",
    "draw:start-line-spacing-horizontal",
    "draw:start-line-spacing-vertical",
    "draw:stroke",
    "draw:stroke-dash",
    "draw:stroke-dash-names",
    "draw:stroke-linejoin",
    "draw:symbol-color",
    "draw:textarea-horizontal-align",
    "draw:textarea-vertical-align",
    "draw:tile-repeat-offset",
    "draw:unit",
    "draw:visible-area-height",
    "draw:visible-area-left",
    "draw:visible-area-top",
    "draw:visible-area-width",
    "draw:wrap-influence-on-position",
    "fo:background-color",
    "fo:border",
    "fo:border-bottom",
    "fo:border-left",
    "fo:border-right",
    "fo:border-top",
    "fo:break-after",
    "fo:break-before",
    "fo:clip",
    "fo:color",
    "fo:country",
    "fo:font-family",
    "fo:font-size",
    "fo:font-style",
    "fo:font-variant",
    "fo:font-weight",
    "fo:height",
    "fo:hyphenate",
    "fo:hyphenation-keep",
    "fo:hyphenation-ladder-count",
    "fo:hyphenation-push-char-count",
    "fo:hyphenation-remain-char-count",
    "fo:keep-together",
    "fo:keep-with-next",
    "fo:language",
    "fo:letter-spacing",
    "fo:line-height",
    "fo:margin",
    "fo:margin-bottom",
    "fo:margin-left",
    "fo:margin-right",
    "fo:margin-top",
    "fo:max-height",
    "fo:max-width",
    "fo:min-height",
    "fo:min-width",
    "fo:orphans",
    "fo:padding",
    "fo:padding-bottom",
    "fo:padding-left",
    "fo:padding-right",
    "fo:padding-top",
    "fo:page-height",
    "fo:page-width",
    "fo:script",
    "fo:text-align",
    "fo:text-align-last",
    "fo:text-indent",
    "fo:text-shadow",
    "fo:text-transform",
    "fo:widows",
    "fo:width",
    "fo:wrap-option",
    "form:allow-deletes",
    "form:allow-inserts",
    "form:allow-updates",
    "form:apply-filter",
    "form:command",
    "form:command-type",
    "form:control-implementation",
    "form:datasource",
    "form:detail-fields",
    "form:enctype",
    "form:filter",
    "form:id",
    "form:ignore-result",
    "form:label",
    "form:linked-cell",
    "form:list-linkage-type",
    "form:master-fields",
    "form:method",
    "form:name",
    "form:navigation-mode",
    "form:order",
    "form:property-name",
    "form:repeat",
    "form:source-cell-range",
    "form:spin-button",
    "form:tabcycle",
    "form:value",
    "form:xforms-list-source",
    "form:xforms-submission",
    "grddl:transformation",
    "number:rfc-language-tag",
    "number:script",
    "presentation:background-objects-visible",
    "presentation:background-visible",
    "presentation:display-date-time",
    "presentation:display-footer",
    "presentation:display-header",
    "presentation:display-page-number",
    "presentation:duration",
    "presentation:transition-speed",
    "presentation:transition-style",
    "presentation:transition-type",
    "presentation:visibility",
    "smil:direction",
    "smil:fadeColor",
    "smil:subtype",
    "smil:type",
    "style:auto-text-indent",
    "style:background-transparency",
    "style:border-line-width",
    "style:border-line-width-bottom",
    "style:border-line-width-left",
    "style:border-line-width-right",
    "style:border-line-width-top",
    "style:cell-protect",
    "style:column-width",
    "style:country-asian",
    "style:country-complex",
    "style:decimal-places",
    "style:diagonal-bl-tr",
    "style:diagonal-bl-tr-widths",
    "style:diagonal-tl-br",
    "style:diagonal-tl-br-widths",
    "style:direction",
    "style:display-name",
    "style:dynamic-spacing",
    "style:editable",
    "style:first-page-number",
    "style:flow-with-text",
    "style:font-charset",
    "style:font-charset-asian",
    "style:font-charset-complex",
    "style:font-family-asian",
    "style:font-family-complex",
    "style:font-family-generic",
    "style:font-family-generic-asian",
    "style:font-family-generic-complex",
    "style:font-independent-line-spacing",
    "style:font-name",
    "style:font-name-asian",
    "style:font-name-complex",
    "style:font-pitch",
    "style:font-pitch-asian",
    "style:font-pitch-complex",
    "style:font-relief",
    "style:font-size-asian",
    "style:font-size-complex",
    "style:font-size-rel",
    "style:font-size-rel-asian",
    "style:font-size-rel-complex",
    "style:font-style-asian",
    "style:font-style-complex",
    "style:font-style-name",
    "style:font-style-name-asian",
    "style:font-style-name-complex",
    "style:font-weight-asian",
    "style:font-weight-complex",
    "style:footnote-max-height",
    "style:glyph-orientation-vertical",
    "style:horizontal-pos",
    "style:horizontal-rel",
    "style:join-border",
    "style:justify-single-word",
    "style:language-asian",
    "style:language-complex",
    "style:layout-grid-base-height",
    "style:layout-grid-base-width",
    "style:layout-grid-color",
    "style:layout-grid-display",
    "style:layout-grid-lines",
    "style:layout-grid-mode",
    "style:layout-grid-print",
    "style:layout-grid-ruby-below",
    "style:layout-grid-ruby-height",
    "style:layout-grid-snap-to",
    "style:layout-grid-standard-mode",
    "style:letter-kerning",
    "style:line-break",
    "style:line-height-at-least",
    "style:line-spacing",
    "style:list-level",
    "style:master-page-name",
    "style:may-break-between-rows",
    "style:min-row-height",
    "style:mirror",
    "style:name",
    "style:num-format",
    "style:num-letter-sync",
    "style:num-prefix",
    "style:num-suffix",
    "style:number-wrapped-paragraphs",
    "style:overflow-behavior",
    "style:page-layout-name",
    "style:page-number",
    "style:paper-tray-name",
    "style:percentage-data-style-name",
    "style:print",
    "style:print-content",
    "style:print-orientation",
    "style:print-page-order",
    "style:protect",
    "style:punctuation-wrap",
    "style:register-true",
    "style:register-truth-ref-style-name",
    "style:rel-column-width",
    "style:rel-height",
    "style:rel-width",
    "style:repeat",
    "style:repeat-content",
    "style:rfc-language-tag",
    "style:rfc-language-tag-asian",
    "style:rfc-language-tag-complex",
    "style:rotation-align",
    "style:rotation-angle",
    "style:row-height",
    "style:ruby-align",
    "style:ruby-position",
    "style:run-through",
    "style:scale-to",
    "style:scale-to-pages",
    "style:script-asian",
    "style:script-complex",
    "style:script-type",
    "style:shadow",
    "style:shrink-to-fit",
    "style:snap-to-layout-grid",
    "style:tab-stop-distance",
    "style:table-centering",
    "style:text-align-source",
    "style:text-autospace",
    "style:text-blinking",
    "style:text-combine",
    "style:text-combine-end-char",
    "style:text-combine-start-char",
    "style:text-emphasize",
    "style:text-line-through-color",
    "style:text-line-through-mode",
    "style:text-line-through-style",
    "style:text-line-through-text",
    "style:text-line-through-text-style",
    "style:text-line-through-type",
    "style:text-line-through-width",
    "style:text-outline",
    "style:text-overline-color",
    "style:text-overline-mode",
    "style:text-overline-style",
    "style:text-overline-type",
    "style:text-overline-width",
    "style:text-position",
    "style:text-rotation-angle",
    "style:text-rotation-scale",
    "style:text-scale",
    "style:text-underline-color",
    "style:text-underline-mode",
    "style:text-underline-style",
    "style:text-underline-type",
    "style:text-underline-width",
    "style:use-optimal-column-width",
    "style:use-optimal-row-height",
    "style:use-window-font-color",
    "style:vertical-align",
    "style:vertical-pos",
    "style:vertical-rel",
    "style:width",
    "style:wrap",
    "style:wrap-contour",
    "style:wrap-contour-mode",
    "style:wrap-dynamic-threshold",
    "style:writing-mode",
    "style:writing-mode-automatic",
    "svg:fill-rule",
    "svg:height",
    "svg:stroke-color",
    "svg:stroke-linecap",
    "svg:stroke-opacity",
    "svg:stroke-width",
    "svg:width",
    "svg:x",
    "svg:y",
    "table:align",
    "table:border-model",
    "table:display",
    "table:embedded-number-behavior",
    "table:first-row-end-column",
    "table:first-row-start-column",
    "table:last-row-end-column",
    "table:last-row-start-column",
    "table:paragraph-style-name",
    "table:protection-key-digest-algorithm",
    "table:rfc-language-tag",
    "table:script",
    "table:template-name",
    "table:use-banding-columns-styles",
    "table:use-banding-rows-styles",
    "table:use-first-column-styles",
    "table:use-first-row-styles",
    "table:use-last-column-styles",
    "table:use-last-row-styles",
    "table:use-wildcards",
    "text:anchor-page-number",
    "text:anchor-type",
    "text:animation",
    "text:animation-delay",
    "text:animation-direction",
    "text:animation-repeat",
    "text:animation-start-inside",
    "text:animation-steps",
    "text:animation-stop-inside",
    "text:condition",
    "text:continue-list",
    "text:display",
    "text:dont-balance-text-columns",
    "text:id",
    "text:label-followed-by",
    "text:label",
    "text:line-break",
    "text:line-number",
    "text:list-id",
    "text:list-level-position-and-space-mode",
    "text:list-tab-stop-position",
    "text:min-label-distance",
    "text:min-label-width",
    "text:name",
    "text:number-lines",
    "text:protection-key-digest-algorithm",
    "text:space-before",
    "text:style-name",
    "text:style-override",
    "xforms:bind",
    "xhtml:about",
    "xhtml:content",
    "xhtml:datatype",
    "xhtml:property",
    "xml:id",
}

__all__ module-attribute

__all__ = [
    "BackgroundImage",
    "CSS3_COLORMAP",
    "ODF_PROPERTIES",
    "Style",
    "create_table_cell_style",
    "default_boolean_style",
    "default_currency_style",
    "default_date_style",
    "default_number_style",
    "default_percentage_style",
    "default_time_style",
    "hex2rgb",
    "make_table_cell_border_string",
    "rgb2hex",
]

BackgroundImage

Bases: Style, DrawImage

Style for a background image, “style:background-image”.

This class combines styling capabilities with image-specific properties to manage background images within ODF documents.

Methods:

Name Description
__init__

Create a style for a background image “style:background-image”.

Attributes:

Name Type Description
display_name
family
name
position
Source code in odfdo/style.py
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
class BackgroundImage(Style, DrawImage):
    """Style for a background image, "style:background-image".

    This class combines styling capabilities with image-specific properties
    to manage background images within ODF documents.
    """

    _tag = "style:background-image"
    _properties: tuple[PropDef | PropDefBool, ...] = (
        PropDef("name", "style:name"),
        PropDef("display_name", "style:display-name"),
        PropDef("svg_font_family", "svg:font-family"),
        PropDef("font_family_generic", "style:font-family-generic"),
        PropDef("font_pitch", "style:font-pitch"),
        PropDef("position", "style:position", "background-image"),
        PropDef("repeat", "style:repeat", "background-image"),
        PropDef("opacity", "draw:opacity", "background-image"),
        PropDef("filter", "style:filter-name", "background-image"),
        PropDef("text_style", "text:style-name"),
    )

    def __init__(
        self,
        name: str | None = None,
        display_name: str | None = None,
        position: str | None = None,
        repeat: str | None = None,
        opacity: str | None = None,
        filter: str | None = None,  # noqa: A002
        # Every other property
        **kwargs: Any,
    ) -> None:
        """Create a style for a background image "style:background-image".

        Args:
            name: The name of the background image style.
            display_name: The display name of the background image style.
            position: The position of the background image.
            repeat: How the background image is repeated.
            opacity: The opacity of the background image.
            filter: A filter to apply to the image.
            **kwargs: Additional properties to set on the background image style.
        """
        kwargs["family"] = "background-image"
        super().__init__(**kwargs)
        if self._do_init:
            kwargs.pop("tag", None)
            kwargs.pop("tag_or_elem", None)
            self.family = "background-image"
            if name:
                self.name = name
            if display_name:
                self.display_name = display_name
            if position:
                self.position = position
            if repeat:
                self.position = repeat
            if opacity:
                self.position = opacity
            if filter:
                self.position = filter
            # Every other properties
            for prop in BackgroundImage._properties:
                if prop.name in kwargs:
                    self.set_style_attribute(prop.attr, kwargs[prop.name])

_properties class-attribute instance-attribute

_properties: tuple[PropDef | PropDefBool, ...] = (
    PropDef("name", "style:name"),
    PropDef("display_name", "style:display-name"),
    PropDef("svg_font_family", "svg:font-family"),
    PropDef(
        "font_family_generic", "style:font-family-generic"
    ),
    PropDef("font_pitch", "style:font-pitch"),
    PropDef(
        "position", "style:position", "background-image"
    ),
    PropDef("repeat", "style:repeat", "background-image"),
    PropDef("opacity", "draw:opacity", "background-image"),
    PropDef(
        "filter", "style:filter-name", "background-image"
    ),
    PropDef("text_style", "text:style-name"),
)

_tag class-attribute instance-attribute

_tag = 'style:background-image'

display_name instance-attribute

display_name = display_name

family instance-attribute

family = 'background-image'

name instance-attribute

name = name

position instance-attribute

position = position

__init__

__init__(
    name: str | None = None,
    display_name: str | None = None,
    position: str | None = None,
    repeat: str | None = None,
    opacity: str | None = None,
    filter: str | None = None,
    **kwargs: Any,
) -> None

Create a style for a background image “style:background-image”.

Parameters:

Name Type Description Default
name str | None

The name of the background image style.

None
display_name str | None

The display name of the background image style.

None
position str | None

The position of the background image.

None
repeat str | None

How the background image is repeated.

None
opacity str | None

The opacity of the background image.

None
filter str | None

A filter to apply to the image.

None
**kwargs Any

Additional properties to set on the background image style.

{}
Source code in odfdo/style.py
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
def __init__(
    self,
    name: str | None = None,
    display_name: str | None = None,
    position: str | None = None,
    repeat: str | None = None,
    opacity: str | None = None,
    filter: str | None = None,  # noqa: A002
    # Every other property
    **kwargs: Any,
) -> None:
    """Create a style for a background image "style:background-image".

    Args:
        name: The name of the background image style.
        display_name: The display name of the background image style.
        position: The position of the background image.
        repeat: How the background image is repeated.
        opacity: The opacity of the background image.
        filter: A filter to apply to the image.
        **kwargs: Additional properties to set on the background image style.
    """
    kwargs["family"] = "background-image"
    super().__init__(**kwargs)
    if self._do_init:
        kwargs.pop("tag", None)
        kwargs.pop("tag_or_elem", None)
        self.family = "background-image"
        if name:
            self.name = name
        if display_name:
            self.display_name = display_name
        if position:
            self.position = position
        if repeat:
            self.position = repeat
        if opacity:
            self.position = opacity
        if filter:
            self.position = filter
        # Every other properties
        for prop in BackgroundImage._properties:
            if prop.name in kwargs:
                self.set_style_attribute(prop.attr, kwargs[prop.name])

Style

Bases: StyleProps

Style class for many ODF tags, “style:style”, “number:date-style”,…

The element represents styles. Styles defined by the element use a hierarchical style model. The element supports inheritance of formatting properties by a style from its parent style. A parent style is specified by the style:parent-style-name attribute on a element.

Partial list of ODF elements covered by this generic class: “style:style”, “number:date-style”, “number:number-style”, “number:percentage-style”, “number:time-style”, “style:font-face”, “style:page-layout”, “style:presentation-page-layout”, “text:list-style”, “text:outline-style”, “style:tab-stops” …

Methods:

Name Description
__init__

Create a style of the given family.

__new__

Create a new Style instance, delegating to specialized classes for

__repr__
get_level_style

Get the list level style for a specific level.

set_background

Set the background color or image for the style.

set_font

Set font properties for a ‘font-face’ style.

set_level_style

Set the list level style for a specific level.

Attributes:

Name Type Description
display_name
family str | None

Get the style family.

master_page
name
parent_style
Source code in odfdo/style.py
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
class Style(StyleProps):
    """Style class for many ODF tags, "style:style", "number:date-style",...

    The <style:style> element represents styles.
    Styles defined by the <style:style> element use a hierarchical style model.
    The <style:style> element supports inheritance of formatting properties
    by a style from its parent style. A parent style is specified by the
    style:parent-style-name attribute on a <style:style> element.

    Partial list of ODF elements covered by this generic class:
    "style:style",
    "number:date-style",
    "number:number-style",
    "number:percentage-style",
    "number:time-style",
    "style:font-face",
    "style:page-layout",
    "style:presentation-page-layout",
    "text:list-style",
    "text:outline-style",
    "style:tab-stops"
    ...
    """

    _properties: tuple[PropDef | PropDefBool, ...] = (
        PropDef("name", "style:name"),
        PropDef("parent_style", "style:parent-style-name"),
        PropDef("display_name", "style:display-name"),
        PropDef("svg_font_family", "svg:font-family"),
        PropDef("font_family_generic", "style:font-family-generic"),
        PropDef("font_pitch", "style:font-pitch"),
        PropDef("text_style", "text:style-name"),
        PropDef("master_page", "style:master-page-name", "paragraph"),
        # style:tab-stop
        PropDef("style_type", "style:type"),
        PropDef("leader_style", "style:leader-style"),
        PropDef("leader_text", "style:leader-text"),
        PropDef("style_position", "style:position"),
        PropDef("leader_text", "style:position"),
        PropDef("list_style_name", "style:list-style-name"),
        PropDef("style_num_format", "style:num-format"),
    )

    def __new__(cls, *args: Any, **kwargs: Any) -> StyleBase:  # type: ignore[misc]
        """Create a new Style instance, delegating to specialized classes for
        'master-page' or 'page-layout' families.

        Args:
            *args: Variable length argument list, potentially including the style family.
            **kwargs: Arbitrary keyword arguments, potentially including the 'family'.

        Returns:
            StyleBase: An instance of Style, StyleMasterPage, or StylePageLayout.
        """
        family = kwargs.get("family")
        if family is None and args:
            family = args[0]
        if family == "master-page":
            return _new_master_page(*args, **kwargs)
        elif family == "page-layout":
            return _new_page_layout(*args, **kwargs)
        else:
            return super().__new__(cls)

    def __init__(
        self,
        family: str | None = None,
        name: str | None = None,
        display_name: str | None = None,
        parent_style: str | None = None,
        # Where properties apply
        area: str | None = None,
        # For family 'text':
        color: str | tuple | None = None,
        background_color: str | tuple | None = None,
        italic: bool = False,
        bold: bool = False,
        text_shadow: str | None = None,
        # For family 'paragraph'
        master_page: str | None = None,
        # For family 'table-cell' (and for paragraph for most of them)
        data_style: str | None = None,  # unused
        border: str | None = None,
        border_top: str | None = None,
        border_right: str | None = None,
        border_bottom: str | None = None,
        border_left: str | None = None,
        padding: str | None = None,
        padding_top: str | None = None,
        padding_bottom: str | None = None,
        padding_left: str | None = None,
        padding_right: str | None = None,
        shadow: str | None = None,
        # For family 'table-row'
        height: str | None = None,
        use_optimal_height: bool = False,
        # For family 'table-column'
        break_before: str | None = None,
        break_after: str | None = None,
        # for family 'table'
        align: str | None = None,
        # For family 'table-column' or 'table'
        width: str | None = None,
        # For family 'graphic'
        min_height: str | None = None,
        # For family 'font-face'
        font_name: str | None = None,
        font_family: str | None = None,
        font_family_generic: str | None = None,
        font_pitch: str = "variable",
        # Every other property
        **kwargs: Any,
    ) -> None:
        """Create a style of the given family.

        A Style of a given family (example: 'paragraph') may have a sub
        element (example: <style:paragraph-properties>) containing the
        relevant details.
        A Style may also have sub elements for other areas, however the
        Style initialisation method manages at most one area at creation
        time (see note 2).

        In brief, this initilisation method permits to create relatively
        simple styles like the below examples, but defining by program
        complex style hierarchies requires a lot of code.

        Style("table-column", width="5cm")
        Style("paragraph", area="text", color="#ff0000")


        Note 1: for "master-page" and "page-layout" style families, use
        the dedicated classes StyleMasterPage and StylePageLayout.

        Note 2: it is possible to add or modify area sub elements
        (ie: <style:paragraph-properties>) after the initialisation with
        the method Style.set_properties().

        Note 3: a helper function is provided for a specialized styles
        for table cells, see create_table_cell_style().

        family: str | None = None,
        name: str | None = None,
        display_name: str | None = None,
        parent_style: str | None = None,
        # Where properties apply
        area: str | None = None,


        The name is not mandatory at this
        point but will become required when inserting in a document as a
        common style.

        The display name is the name the user sees in an office
        application.

        The parent_style is the name of the style this style will
        inherit from.

        To set properties, pass them as keyword arguments. The area
        properties apply to is optional and defaults to the family.

        For attributes of style:{area}-properties (for example
        "style:paragraph-properties"), pass the attributes as keywords.
        You can safely remove the "fo:" or "style:" prefix and replace
        "-" by "_", so use "padding_let" for "fo:padding-left" value.

        Args:
            family: The style family. Can be 'paragraph', 'text',
                'section', 'table', 'table-column', 'table-row',
                'table-cell', 'table-page', 'chart', 'drawing-page',
                'graphic', 'presentation', 'control', 'ruby', 'list',
                'number', 'page-layout', 'font-face', or 'master-page'.
            name: The programmatic name of the style.
            display_name: The display name of the style.
            parent_style: The name of the parent style.
            area: The specific area to which properties apply.
                Defaults to the style's family.
            color: Text color (e.g., "#RRGGBB" or "red").
                ('text' property)
            background_color: Background color (e.g., "#RRGGBB" or
                "red"). ('text' property)
            italic: If True, applies italic formatting. ('text'
                property)
            bold: If True, applies bold formatting. ('text' property)
            text_shadow: Text shadow specification. ('text' property)
            master_page: The master page to use for the paragraph.
                ('paragraph' property)
            data_style: The data style for the cell. (unused)
                ('table-cell' property)
            border: Style string for all four borders (e.g.,
                "0.002cm solid #000000"). ('table-cell' property)
            border_top: Style string for the top border. ('table-cell'
                property)
            border_right: Style string for the right border.
                ('table-cell' property)
            border_bottom: Style string for the bottom border.
                ('table-cell' property)
            border_left: Style string for the left border. ('table-cell'
                property)
            padding: Style string for padding on all four sides (e.g.,
                "0.002cm"). ('table-cell' property)
            padding_top: Style string for top padding. ('table-cell'
                property)
            padding_bottom: Style string for bottom padding.
                ('table-cell' property)
            padding_left: Style string for left padding. ('table-cell'
                property)
            padding_right: Style string for right padding. ('table-cell'
                property)
            shadow: Shadow specification (e.g.,
                "#808080 0.176cm 0.176cm"). ('table-cell' property)
            height: Row height (e.g., '5cm'). ('table-row' property)
            use_optimal_height: If True, use optimal row height.
                ('table-row' property)
            break_before: Page or column break before ('page', 'column',
                or 'auto'). ('table-column' property)
            break_after: Page or column break after ('page', 'column',
                or 'auto'). ('table-column' property)
            align: Table alignment ('left', 'center', 'margins', or
                'right'). ('table' property)
            width: Column or table width (e.g., '5cm'). ('table-column'
                or 'table' property)
            min_height: Minimum height for the graphic (e.g., '1cm').
                ('graphic' property)
            font_name: The font name. ('font-face' property)
            font_family: The font family. ('font-face' property)
            font_family_generic: Generic font family. ('font-face'
                property)
            font_pitch: Font pitch ('variable' or 'fixed'). Defaults to
                'variable'. ('font-face' property)
            **kwargs: Additional properties to set on the style.
        """
        self._family: str | None = None
        tag_or_elem = kwargs.get("tag_or_elem")
        if tag_or_elem is None:
            family = to_str(family)
            if family in {"master-page", "page-layout"}:
                raise TypeError(f"Wrong initializer for: {family!r}")
            if family not in FAMILY_MAPPING:
                raise ValueError(f"Unknown family value: {family!r}")
            kwargs["tag"] = FAMILY_MAPPING[family]
        super().__init__(**kwargs)
        if self._do_init and family not in SUBCLASSED_STYLES:
            kwargs.pop("tag", None)
            kwargs.pop("tag_or_elem", None)
            self.family = family  # relevant test made by property
            # Common attributes
            if name:
                self.name = name
            if display_name:
                self.display_name = display_name
            if parent_style:
                self.parent_style = parent_style
            # Paragraph
            if family == "paragraph":
                if master_page:
                    self.master_page = master_page
            # Font face
            elif family == "font-face":
                if not font_name:
                    raise ValueError("A font_name is required for 'font-face' style")
                self.set_font(
                    font_name,
                    family=font_family,
                    family_generic=font_family_generic,
                    pitch=font_pitch,
                )
            # Properties
            if area is None:
                area = family
            area = to_str(area)
            # Text
            if area == "text":
                if color:
                    kwargs["fo:color"] = color
                if background_color:
                    kwargs["fo:background-color"] = background_color
                if italic:
                    kwargs["fo:font-style"] = "italic"
                    kwargs["style:font-style-asian"] = "italic"
                    kwargs["style:font-style-complex"] = "italic"
                if bold:
                    kwargs["fo:font-weight"] = "bold"
                    kwargs["style:font-weight-asian"] = "bold"
                    kwargs["style:font-weight-complex"] = "bold"
            # Table cell
            elif area == "table-cell":
                if border:
                    kwargs["fo:border"] = border
                elif border_top or border_right or border_bottom or border_left:
                    kwargs["fo:border-top"] = border_top or "none"
                    kwargs["fo:border-right"] = border_right or "none"
                    kwargs["fo:border-bottom"] = border_bottom or "none"
                    kwargs["fo:border-left"] = border_left or "none"
                else:  # no border_top, ... neither border are defined
                    pass  # left untouched
                if padding:
                    kwargs["fo:padding"] = padding
                elif padding_top or padding_right or padding_bottom or padding_left:
                    kwargs["fo:padding-top"] = padding_top or "none"
                    kwargs["fo:padding-right"] = padding_right or "none"
                    kwargs["fo:padding-bottom"] = padding_bottom or "none"
                    kwargs["fo:padding-left"] = padding_left or "none"
                else:  # no border_top, ... neither border are defined
                    pass  # left untouched
                if shadow:
                    kwargs["style:shadow"] = shadow
                if background_color:
                    kwargs["fo:background-color"] = background_color
            # Table row
            elif area == "table-row":
                if height:
                    kwargs["style:row-height"] = height
                if use_optimal_height:
                    kwargs["style:use-optimal-row-height"] = Boolean.encode(
                        use_optimal_height
                    )
                if background_color:
                    kwargs["fo:background-color"] = background_color
            # Table column
            elif area == "table-column":
                if width:
                    kwargs["style:column-width"] = width
                if break_before:
                    kwargs["fo:break-before"] = break_before
                if break_after:
                    kwargs["fo:break-after"] = break_after
            # Table
            elif area == "table":
                if width:
                    kwargs["style:width"] = width
                if align:
                    if align not in {"center", "left", "margins", "right"}:
                        raise ValueError(f"Invalid align value: {align!r}")
                    kwargs["table:align"] = align
            # Graphic
            elif area == "graphic":
                if min_height:
                    kwargs["fo:min-height"] = min_height
            # Every other properties
            if kwargs:
                self.set_properties(kwargs, area=area)

    @property
    def family(self) -> str | None:
        """Get the style family.

        Returns:
            str or None: The style family as a string, or None if not set.
        """
        if self._family is None:
            self._family = FALSE_FAMILY_MAP_REVERSE.get(
                self.tag, self.get_attribute_string("style:family")
            )
        return self._family

    @family.setter
    def family(self, family: str | None) -> None:
        """Set the style family.

        Args:
            family: The style family to set.
        """
        self._family = family
        if family in FAMILY_ODF_STD and self.tag == "style:style":
            self.set_attribute("style:family", family)

    def __repr__(self) -> str:
        return f"<{self.__class__.__name__} family={self.family} name={self.name}>"

    def set_background(
        self,
        color: str | None = None,
        url: str | None = None,
        position: str | None = "center",
        repeat: str | None = None,
        opacity: str | int | None = None,
        filter: str | None = None,  # noqa: A002
    ) -> None:
        """Set the background color or image for the style.

        With no arguments, any existing background is removed.

        The `position` attribute can be "left", "center", "right", "top", "bottom",
        or two whitespace-separated values (e.g., "left top"). One value must be
        from {"left", "center", "right"} and the other from {"top", "center", "bottom"}.
        The default value for this attribute is "center".

        The `repeat` value can be 'no-repeat', 'repeat', or 'stretch'.

        The `opacity` is an integer percentage (0-100), not a string with a '%' sign.

        The `filter` is an application-specific filter name defined elsewhere.

        Note: This method will raise an error if the style type is not compatible
        with background properties.

        Args:
            color: The background color (e.g., '#rrggbb').
            url: The URL of the background image.
            position: The position of the background image. Defaults to "center".
            repeat: How the background image is repeated.
            opacity: The opacity of the background.
            filter: An application-specific filter name.
        """
        _set_background(self, color, url, position, repeat, opacity, filter)

    # list-style only:

    def get_level_style(self, level: int) -> Style | None:
        """Get the list level style for a specific level.

        This method is applicable only if the style family is 'list'.

        Args:
            level: The list level (1-based index).

        Returns:
            Style | None: The Style element for the specified level, or None
            if the style family is not 'list' or the level style is not found.
        """
        if self.family != "list":
            return None
        level_styles = (
            "(text:list-level-style-number"
            "|text:list-level-style-bullet"
            "|text:list-level-style-image)"
        )
        return self._filtered_element(level_styles, 0, level=level)  # type: ignore

    def set_level_style(
        self,
        level: int,
        num_format: str | None = None,
        bullet_char: str | None = None,
        url: str | None = None,
        display_levels: int | None = None,
        prefix: str | None = None,
        suffix: str | None = None,
        start_value: int | None = None,
        style: str | None = None,
        clone: Style | None = None,
    ) -> Style | None:
        """Set the list level style for a specific level.

        This method is applicable only if the style family is 'list'.

        Args:
            level: The list level to configure (1-based index).
            num_format: Number format for numbered lists.
            bullet_char: Bullet character for bulleted lists.
            url: URL of the image for image bulleted lists.
            display_levels: The number of list levels to display.
            prefix: Text prefix for the list item.
            suffix: Text suffix for the list item.
            start_value: The starting value for a numbered list.
            style: The text style name for the list item.
            clone: An existing Style object to clone properties from.

        Returns:
            Style | None: The created or modified level style, or None
            if the style family is not 'list'.

        Raises:
            ValueError: If an unknown level style type is provided.
        """
        if self.family != "list":
            return None
        # Expected name
        if num_format is not None:
            level_style_name = "text:list-level-style-number"
        elif bullet_char is not None:
            level_style_name = "text:list-level-style-bullet"
        elif url is not None:
            level_style_name = "text:list-level-style-image"
        elif clone is not None:
            level_style_name = clone.tag
        else:
            raise ValueError("unknown level style type")
        was_created = False
        # Cloning or reusing an existing element
        level_style: Style | None = None
        if clone is not None:
            level_style = clone.clone  # type: ignore
            was_created = True
        else:
            level_style = self.get_level_style(level)
            if level_style is None:
                level_style = Element.from_tag(level_style_name)  # type: ignore
                was_created = True
        if level_style is None:
            return None
        # Transmute if the type changed
        if level_style.tag != level_style_name:
            print("Warn: different style", level_style_name, level_style.tag)
            level_style.tag = level_style_name
        # Set the level
        level_style.set_attribute("text:level", str(level))
        # Set the main attribute
        if num_format is not None:
            level_style.set_attribute("fo:num-format", num_format)
        elif bullet_char is not None:
            level_style.set_attribute("text:bullet-char", bullet_char)
        elif url is not None:
            level_style.set_attribute("xlink:href", url)
        # Set attributes
        if prefix:
            level_style.set_attribute("style:num-prefix", prefix)
        if suffix:
            level_style.set_attribute("style:num-suffix", suffix)
        if display_levels:
            level_style.set_attribute("text:display-levels", str(display_levels))
        if start_value:
            level_style.set_attribute("text:start-value", str(start_value))
        if style:
            level_style.text_style = style  # type: ignore
        # Commit the creation
        if was_created:
            self.append(level_style)
        return level_style

    # font-face only:

    def set_font(
        self,
        name: str,
        family: str | None = None,
        family_generic: str | None = None,
        pitch: str = "variable",
    ) -> None:
        """Set font properties for a 'font-face' style.

        This method is applicable only if the style family is 'font-face'.

        Args:
            name: The font name.
            family: The font family. If None, defaults to `name`.
            family_generic: The generic font family (e.g., 'swiss', 'roman').
            pitch: The font pitch ('variable' or 'fixed'). Defaults to 'variable'.
        """
        if self.family != "font-face":
            return
        self.name = name
        if family is None:
            family = name
        self.svg_font_family = f'"{family}"'
        if family_generic is not None:
            self.font_family_generic = family_generic
        self.font_pitch = pitch

_family instance-attribute

_family: str | None = None

_properties class-attribute instance-attribute

_properties: tuple[PropDef | PropDefBool, ...] = (
    PropDef("name", "style:name"),
    PropDef("parent_style", "style:parent-style-name"),
    PropDef("display_name", "style:display-name"),
    PropDef("svg_font_family", "svg:font-family"),
    PropDef(
        "font_family_generic", "style:font-family-generic"
    ),
    PropDef("font_pitch", "style:font-pitch"),
    PropDef("text_style", "text:style-name"),
    PropDef(
        "master_page", "style:master-page-name", "paragraph"
    ),
    PropDef("style_type", "style:type"),
    PropDef("leader_style", "style:leader-style"),
    PropDef("leader_text", "style:leader-text"),
    PropDef("style_position", "style:position"),
    PropDef("leader_text", "style:position"),
    PropDef("list_style_name", "style:list-style-name"),
    PropDef("style_num_format", "style:num-format"),
)

display_name instance-attribute

display_name = display_name

family property writable

family: str | None

Get the style family.

Returns:

Type Description
str | None

str or None: The style family as a string, or None if not set.

master_page instance-attribute

master_page = master_page

name instance-attribute

name = name

parent_style instance-attribute

parent_style = parent_style

__init__

__init__(
    family: str | None = None,
    name: str | None = None,
    display_name: str | None = None,
    parent_style: str | None = None,
    area: str | None = None,
    color: str | tuple | None = None,
    background_color: str | tuple | None = None,
    italic: bool = False,
    bold: bool = False,
    text_shadow: str | None = None,
    master_page: str | None = None,
    data_style: str | None = None,
    border: str | None = None,
    border_top: str | None = None,
    border_right: str | None = None,
    border_bottom: str | None = None,
    border_left: str | None = None,
    padding: str | None = None,
    padding_top: str | None = None,
    padding_bottom: str | None = None,
    padding_left: str | None = None,
    padding_right: str | None = None,
    shadow: str | None = None,
    height: str | None = None,
    use_optimal_height: bool = False,
    break_before: str | None = None,
    break_after: str | None = None,
    align: str | None = None,
    width: str | None = None,
    min_height: str | None = None,
    font_name: str | None = None,
    font_family: str | None = None,
    font_family_generic: str | None = None,
    font_pitch: str = "variable",
    **kwargs: Any,
) -> None

Create a style of the given family.

A Style of a given family (example: ‘paragraph’) may have a sub element (example: ) containing the relevant details. A Style may also have sub elements for other areas, however the Style initialisation method manages at most one area at creation time (see note 2).

In brief, this initilisation method permits to create relatively simple styles like the below examples, but defining by program complex style hierarchies requires a lot of code.

Style(“table-column”, width=”5cm”) Style(“paragraph”, area=”text”, color=”#ff0000”)

Note 1: for “master-page” and “page-layout” style families, use the dedicated classes StyleMasterPage and StylePageLayout.

Note 2: it is possible to add or modify area sub elements (ie: ) after the initialisation with the method Style.set_properties().

Note 3: a helper function is provided for a specialized styles for table cells, see create_table_cell_style().

family: str | None = None, name: str | None = None, display_name: str | None = None, parent_style: str | None = None,

Where properties apply

area: str | None = None,

The name is not mandatory at this point but will become required when inserting in a document as a common style.

The display name is the name the user sees in an office application.

The parent_style is the name of the style this style will inherit from.

To set properties, pass them as keyword arguments. The area properties apply to is optional and defaults to the family.

For attributes of style:{area}-properties (for example “style:paragraph-properties”), pass the attributes as keywords. You can safely remove the “fo:” or “style:” prefix and replace “-” by “_”, so use “padding_let” for “fo:padding-left” value.

Parameters:

Name Type Description Default
family str | None

The style family. Can be ‘paragraph’, ‘text’, ‘section’, ‘table’, ‘table-column’, ‘table-row’, ‘table-cell’, ‘table-page’, ‘chart’, ‘drawing-page’, ‘graphic’, ‘presentation’, ‘control’, ‘ruby’, ‘list’, ‘number’, ‘page-layout’, ‘font-face’, or ‘master-page’.

None
name str | None

The programmatic name of the style.

None
display_name str | None

The display name of the style.

None
parent_style str | None

The name of the parent style.

None
area str | None

The specific area to which properties apply. Defaults to the style’s family.

None
color str | tuple | None

Text color (e.g., “#RRGGBB” or “red”). (‘text’ property)

None
background_color str | tuple | None

Background color (e.g., “#RRGGBB” or “red”). (‘text’ property)

None
italic bool

If True, applies italic formatting. (‘text’ property)

False
bold bool

If True, applies bold formatting. (‘text’ property)

False
text_shadow str | None

Text shadow specification. (‘text’ property)

None
master_page str | None

The master page to use for the paragraph. (‘paragraph’ property)

None
data_style str | None

The data style for the cell. (unused) (‘table-cell’ property)

None
border str | None

Style string for all four borders (e.g., “0.002cm solid #000000”). (‘table-cell’ property)

None
border_top str | None

Style string for the top border. (‘table-cell’ property)

None
border_right str | None

Style string for the right border. (‘table-cell’ property)

None
border_bottom str | None

Style string for the bottom border. (‘table-cell’ property)

None
border_left str | None

Style string for the left border. (‘table-cell’ property)

None
padding str | None

Style string for padding on all four sides (e.g., “0.002cm”). (‘table-cell’ property)

None
padding_top str | None

Style string for top padding. (‘table-cell’ property)

None
padding_bottom str | None

Style string for bottom padding. (‘table-cell’ property)

None
padding_left str | None

Style string for left padding. (‘table-cell’ property)

None
padding_right str | None

Style string for right padding. (‘table-cell’ property)

None
shadow str | None

Shadow specification (e.g., “#808080 0.176cm 0.176cm”). (‘table-cell’ property)

None
height str | None

Row height (e.g., ‘5cm’). (‘table-row’ property)

None
use_optimal_height bool

If True, use optimal row height. (‘table-row’ property)

False
break_before str | None

Page or column break before (‘page’, ‘column’, or ‘auto’). (‘table-column’ property)

None
break_after str | None

Page or column break after (‘page’, ‘column’, or ‘auto’). (‘table-column’ property)

None
align str | None

Table alignment (‘left’, ‘center’, ‘margins’, or ‘right’). (‘table’ property)

None
width str | None

Column or table width (e.g., ‘5cm’). (‘table-column’ or ‘table’ property)

None
min_height str | None

Minimum height for the graphic (e.g., ‘1cm’). (‘graphic’ property)

None
font_name str | None

The font name. (‘font-face’ property)

None
font_family str | None

The font family. (‘font-face’ property)

None
font_family_generic str | None

Generic font family. (‘font-face’ property)

None
font_pitch str

Font pitch (‘variable’ or ‘fixed’). Defaults to ‘variable’. (‘font-face’ property)

'variable'
**kwargs Any

Additional properties to set on the style.

{}
Source code in odfdo/style.py
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
def __init__(
    self,
    family: str | None = None,
    name: str | None = None,
    display_name: str | None = None,
    parent_style: str | None = None,
    # Where properties apply
    area: str | None = None,
    # For family 'text':
    color: str | tuple | None = None,
    background_color: str | tuple | None = None,
    italic: bool = False,
    bold: bool = False,
    text_shadow: str | None = None,
    # For family 'paragraph'
    master_page: str | None = None,
    # For family 'table-cell' (and for paragraph for most of them)
    data_style: str | None = None,  # unused
    border: str | None = None,
    border_top: str | None = None,
    border_right: str | None = None,
    border_bottom: str | None = None,
    border_left: str | None = None,
    padding: str | None = None,
    padding_top: str | None = None,
    padding_bottom: str | None = None,
    padding_left: str | None = None,
    padding_right: str | None = None,
    shadow: str | None = None,
    # For family 'table-row'
    height: str | None = None,
    use_optimal_height: bool = False,
    # For family 'table-column'
    break_before: str | None = None,
    break_after: str | None = None,
    # for family 'table'
    align: str | None = None,
    # For family 'table-column' or 'table'
    width: str | None = None,
    # For family 'graphic'
    min_height: str | None = None,
    # For family 'font-face'
    font_name: str | None = None,
    font_family: str | None = None,
    font_family_generic: str | None = None,
    font_pitch: str = "variable",
    # Every other property
    **kwargs: Any,
) -> None:
    """Create a style of the given family.

    A Style of a given family (example: 'paragraph') may have a sub
    element (example: <style:paragraph-properties>) containing the
    relevant details.
    A Style may also have sub elements for other areas, however the
    Style initialisation method manages at most one area at creation
    time (see note 2).

    In brief, this initilisation method permits to create relatively
    simple styles like the below examples, but defining by program
    complex style hierarchies requires a lot of code.

    Style("table-column", width="5cm")
    Style("paragraph", area="text", color="#ff0000")


    Note 1: for "master-page" and "page-layout" style families, use
    the dedicated classes StyleMasterPage and StylePageLayout.

    Note 2: it is possible to add or modify area sub elements
    (ie: <style:paragraph-properties>) after the initialisation with
    the method Style.set_properties().

    Note 3: a helper function is provided for a specialized styles
    for table cells, see create_table_cell_style().

    family: str | None = None,
    name: str | None = None,
    display_name: str | None = None,
    parent_style: str | None = None,
    # Where properties apply
    area: str | None = None,


    The name is not mandatory at this
    point but will become required when inserting in a document as a
    common style.

    The display name is the name the user sees in an office
    application.

    The parent_style is the name of the style this style will
    inherit from.

    To set properties, pass them as keyword arguments. The area
    properties apply to is optional and defaults to the family.

    For attributes of style:{area}-properties (for example
    "style:paragraph-properties"), pass the attributes as keywords.
    You can safely remove the "fo:" or "style:" prefix and replace
    "-" by "_", so use "padding_let" for "fo:padding-left" value.

    Args:
        family: The style family. Can be 'paragraph', 'text',
            'section', 'table', 'table-column', 'table-row',
            'table-cell', 'table-page', 'chart', 'drawing-page',
            'graphic', 'presentation', 'control', 'ruby', 'list',
            'number', 'page-layout', 'font-face', or 'master-page'.
        name: The programmatic name of the style.
        display_name: The display name of the style.
        parent_style: The name of the parent style.
        area: The specific area to which properties apply.
            Defaults to the style's family.
        color: Text color (e.g., "#RRGGBB" or "red").
            ('text' property)
        background_color: Background color (e.g., "#RRGGBB" or
            "red"). ('text' property)
        italic: If True, applies italic formatting. ('text'
            property)
        bold: If True, applies bold formatting. ('text' property)
        text_shadow: Text shadow specification. ('text' property)
        master_page: The master page to use for the paragraph.
            ('paragraph' property)
        data_style: The data style for the cell. (unused)
            ('table-cell' property)
        border: Style string for all four borders (e.g.,
            "0.002cm solid #000000"). ('table-cell' property)
        border_top: Style string for the top border. ('table-cell'
            property)
        border_right: Style string for the right border.
            ('table-cell' property)
        border_bottom: Style string for the bottom border.
            ('table-cell' property)
        border_left: Style string for the left border. ('table-cell'
            property)
        padding: Style string for padding on all four sides (e.g.,
            "0.002cm"). ('table-cell' property)
        padding_top: Style string for top padding. ('table-cell'
            property)
        padding_bottom: Style string for bottom padding.
            ('table-cell' property)
        padding_left: Style string for left padding. ('table-cell'
            property)
        padding_right: Style string for right padding. ('table-cell'
            property)
        shadow: Shadow specification (e.g.,
            "#808080 0.176cm 0.176cm"). ('table-cell' property)
        height: Row height (e.g., '5cm'). ('table-row' property)
        use_optimal_height: If True, use optimal row height.
            ('table-row' property)
        break_before: Page or column break before ('page', 'column',
            or 'auto'). ('table-column' property)
        break_after: Page or column break after ('page', 'column',
            or 'auto'). ('table-column' property)
        align: Table alignment ('left', 'center', 'margins', or
            'right'). ('table' property)
        width: Column or table width (e.g., '5cm'). ('table-column'
            or 'table' property)
        min_height: Minimum height for the graphic (e.g., '1cm').
            ('graphic' property)
        font_name: The font name. ('font-face' property)
        font_family: The font family. ('font-face' property)
        font_family_generic: Generic font family. ('font-face'
            property)
        font_pitch: Font pitch ('variable' or 'fixed'). Defaults to
            'variable'. ('font-face' property)
        **kwargs: Additional properties to set on the style.
    """
    self._family: str | None = None
    tag_or_elem = kwargs.get("tag_or_elem")
    if tag_or_elem is None:
        family = to_str(family)
        if family in {"master-page", "page-layout"}:
            raise TypeError(f"Wrong initializer for: {family!r}")
        if family not in FAMILY_MAPPING:
            raise ValueError(f"Unknown family value: {family!r}")
        kwargs["tag"] = FAMILY_MAPPING[family]
    super().__init__(**kwargs)
    if self._do_init and family not in SUBCLASSED_STYLES:
        kwargs.pop("tag", None)
        kwargs.pop("tag_or_elem", None)
        self.family = family  # relevant test made by property
        # Common attributes
        if name:
            self.name = name
        if display_name:
            self.display_name = display_name
        if parent_style:
            self.parent_style = parent_style
        # Paragraph
        if family == "paragraph":
            if master_page:
                self.master_page = master_page
        # Font face
        elif family == "font-face":
            if not font_name:
                raise ValueError("A font_name is required for 'font-face' style")
            self.set_font(
                font_name,
                family=font_family,
                family_generic=font_family_generic,
                pitch=font_pitch,
            )
        # Properties
        if area is None:
            area = family
        area = to_str(area)
        # Text
        if area == "text":
            if color:
                kwargs["fo:color"] = color
            if background_color:
                kwargs["fo:background-color"] = background_color
            if italic:
                kwargs["fo:font-style"] = "italic"
                kwargs["style:font-style-asian"] = "italic"
                kwargs["style:font-style-complex"] = "italic"
            if bold:
                kwargs["fo:font-weight"] = "bold"
                kwargs["style:font-weight-asian"] = "bold"
                kwargs["style:font-weight-complex"] = "bold"
        # Table cell
        elif area == "table-cell":
            if border:
                kwargs["fo:border"] = border
            elif border_top or border_right or border_bottom or border_left:
                kwargs["fo:border-top"] = border_top or "none"
                kwargs["fo:border-right"] = border_right or "none"
                kwargs["fo:border-bottom"] = border_bottom or "none"
                kwargs["fo:border-left"] = border_left or "none"
            else:  # no border_top, ... neither border are defined
                pass  # left untouched
            if padding:
                kwargs["fo:padding"] = padding
            elif padding_top or padding_right or padding_bottom or padding_left:
                kwargs["fo:padding-top"] = padding_top or "none"
                kwargs["fo:padding-right"] = padding_right or "none"
                kwargs["fo:padding-bottom"] = padding_bottom or "none"
                kwargs["fo:padding-left"] = padding_left or "none"
            else:  # no border_top, ... neither border are defined
                pass  # left untouched
            if shadow:
                kwargs["style:shadow"] = shadow
            if background_color:
                kwargs["fo:background-color"] = background_color
        # Table row
        elif area == "table-row":
            if height:
                kwargs["style:row-height"] = height
            if use_optimal_height:
                kwargs["style:use-optimal-row-height"] = Boolean.encode(
                    use_optimal_height
                )
            if background_color:
                kwargs["fo:background-color"] = background_color
        # Table column
        elif area == "table-column":
            if width:
                kwargs["style:column-width"] = width
            if break_before:
                kwargs["fo:break-before"] = break_before
            if break_after:
                kwargs["fo:break-after"] = break_after
        # Table
        elif area == "table":
            if width:
                kwargs["style:width"] = width
            if align:
                if align not in {"center", "left", "margins", "right"}:
                    raise ValueError(f"Invalid align value: {align!r}")
                kwargs["table:align"] = align
        # Graphic
        elif area == "graphic":
            if min_height:
                kwargs["fo:min-height"] = min_height
        # Every other properties
        if kwargs:
            self.set_properties(kwargs, area=area)

__new__

__new__(*args: Any, **kwargs: Any) -> StyleBase

Create a new Style instance, delegating to specialized classes for ‘master-page’ or ‘page-layout’ families.

Parameters:

Name Type Description Default
*args Any

Variable length argument list, potentially including the style family.

()
**kwargs Any

Arbitrary keyword arguments, potentially including the ‘family’.

{}

Returns:

Name Type Description
StyleBase StyleBase

An instance of Style, StyleMasterPage, or StylePageLayout.

Source code in odfdo/style.py
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
def __new__(cls, *args: Any, **kwargs: Any) -> StyleBase:  # type: ignore[misc]
    """Create a new Style instance, delegating to specialized classes for
    'master-page' or 'page-layout' families.

    Args:
        *args: Variable length argument list, potentially including the style family.
        **kwargs: Arbitrary keyword arguments, potentially including the 'family'.

    Returns:
        StyleBase: An instance of Style, StyleMasterPage, or StylePageLayout.
    """
    family = kwargs.get("family")
    if family is None and args:
        family = args[0]
    if family == "master-page":
        return _new_master_page(*args, **kwargs)
    elif family == "page-layout":
        return _new_page_layout(*args, **kwargs)
    else:
        return super().__new__(cls)

__repr__

__repr__() -> str
Source code in odfdo/style.py
649
650
def __repr__(self) -> str:
    return f"<{self.__class__.__name__} family={self.family} name={self.name}>"

get_level_style

get_level_style(level: int) -> Style | None

Get the list level style for a specific level.

This method is applicable only if the style family is ‘list’.

Parameters:

Name Type Description Default
level int

The list level (1-based index).

required

Returns:

Type Description
Style | None

Style | None: The Style element for the specified level, or None

Style | None

if the style family is not ‘list’ or the level style is not found.

Source code in odfdo/style.py
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
def get_level_style(self, level: int) -> Style | None:
    """Get the list level style for a specific level.

    This method is applicable only if the style family is 'list'.

    Args:
        level: The list level (1-based index).

    Returns:
        Style | None: The Style element for the specified level, or None
        if the style family is not 'list' or the level style is not found.
    """
    if self.family != "list":
        return None
    level_styles = (
        "(text:list-level-style-number"
        "|text:list-level-style-bullet"
        "|text:list-level-style-image)"
    )
    return self._filtered_element(level_styles, 0, level=level)  # type: ignore

set_background

set_background(
    color: str | None = None,
    url: str | None = None,
    position: str | None = "center",
    repeat: str | None = None,
    opacity: str | int | None = None,
    filter: str | None = None,
) -> None

Set the background color or image for the style.

With no arguments, any existing background is removed.

The position attribute can be “left”, “center”, “right”, “top”, “bottom”, or two whitespace-separated values (e.g., “left top”). One value must be from {“left”, “center”, “right”} and the other from {“top”, “center”, “bottom”}. The default value for this attribute is “center”.

The repeat value can be ‘no-repeat’, ‘repeat’, or ‘stretch’.

The opacity is an integer percentage (0-100), not a string with a ‘%’ sign.

The filter is an application-specific filter name defined elsewhere.

Note: This method will raise an error if the style type is not compatible with background properties.

Parameters:

Name Type Description Default
color str | None

The background color (e.g., ‘#rrggbb’).

None
url str | None

The URL of the background image.

None
position str | None

The position of the background image. Defaults to “center”.

'center'
repeat str | None

How the background image is repeated.

None
opacity str | int | None

The opacity of the background.

None
filter str | None

An application-specific filter name.

None
Source code in odfdo/style.py
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
def set_background(
    self,
    color: str | None = None,
    url: str | None = None,
    position: str | None = "center",
    repeat: str | None = None,
    opacity: str | int | None = None,
    filter: str | None = None,  # noqa: A002
) -> None:
    """Set the background color or image for the style.

    With no arguments, any existing background is removed.

    The `position` attribute can be "left", "center", "right", "top", "bottom",
    or two whitespace-separated values (e.g., "left top"). One value must be
    from {"left", "center", "right"} and the other from {"top", "center", "bottom"}.
    The default value for this attribute is "center".

    The `repeat` value can be 'no-repeat', 'repeat', or 'stretch'.

    The `opacity` is an integer percentage (0-100), not a string with a '%' sign.

    The `filter` is an application-specific filter name defined elsewhere.

    Note: This method will raise an error if the style type is not compatible
    with background properties.

    Args:
        color: The background color (e.g., '#rrggbb').
        url: The URL of the background image.
        position: The position of the background image. Defaults to "center".
        repeat: How the background image is repeated.
        opacity: The opacity of the background.
        filter: An application-specific filter name.
    """
    _set_background(self, color, url, position, repeat, opacity, filter)

set_font

set_font(
    name: str,
    family: str | None = None,
    family_generic: str | None = None,
    pitch: str = "variable",
) -> None

Set font properties for a ‘font-face’ style.

This method is applicable only if the style family is ‘font-face’.

Parameters:

Name Type Description Default
name str

The font name.

required
family str | None

The font family. If None, defaults to name.

None
family_generic str | None

The generic font family (e.g., ‘swiss’, ‘roman’).

None
pitch str

The font pitch (‘variable’ or ‘fixed’). Defaults to ‘variable’.

'variable'
Source code in odfdo/style.py
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
def set_font(
    self,
    name: str,
    family: str | None = None,
    family_generic: str | None = None,
    pitch: str = "variable",
) -> None:
    """Set font properties for a 'font-face' style.

    This method is applicable only if the style family is 'font-face'.

    Args:
        name: The font name.
        family: The font family. If None, defaults to `name`.
        family_generic: The generic font family (e.g., 'swiss', 'roman').
        pitch: The font pitch ('variable' or 'fixed'). Defaults to 'variable'.
    """
    if self.family != "font-face":
        return
    self.name = name
    if family is None:
        family = name
    self.svg_font_family = f'"{family}"'
    if family_generic is not None:
        self.font_family_generic = family_generic
    self.font_pitch = pitch

set_level_style

set_level_style(
    level: int,
    num_format: str | None = None,
    bullet_char: str | None = None,
    url: str | None = None,
    display_levels: int | None = None,
    prefix: str | None = None,
    suffix: str | None = None,
    start_value: int | None = None,
    style: str | None = None,
    clone: Style | None = None,
) -> Style | None

Set the list level style for a specific level.

This method is applicable only if the style family is ‘list’.

Parameters:

Name Type Description Default
level int

The list level to configure (1-based index).

required
num_format str | None

Number format for numbered lists.

None
bullet_char str | None

Bullet character for bulleted lists.

None
url str | None

URL of the image for image bulleted lists.

None
display_levels int | None

The number of list levels to display.

None
prefix str | None

Text prefix for the list item.

None
suffix str | None

Text suffix for the list item.

None
start_value int | None

The starting value for a numbered list.

None
style str | None

The text style name for the list item.

None
clone Style | None

An existing Style object to clone properties from.

None

Returns:

Type Description
Style | None

Style | None: The created or modified level style, or None

Style | None

if the style family is not ‘list’.

Raises:

Type Description
ValueError

If an unknown level style type is provided.

Source code in odfdo/style.py
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
def set_level_style(
    self,
    level: int,
    num_format: str | None = None,
    bullet_char: str | None = None,
    url: str | None = None,
    display_levels: int | None = None,
    prefix: str | None = None,
    suffix: str | None = None,
    start_value: int | None = None,
    style: str | None = None,
    clone: Style | None = None,
) -> Style | None:
    """Set the list level style for a specific level.

    This method is applicable only if the style family is 'list'.

    Args:
        level: The list level to configure (1-based index).
        num_format: Number format for numbered lists.
        bullet_char: Bullet character for bulleted lists.
        url: URL of the image for image bulleted lists.
        display_levels: The number of list levels to display.
        prefix: Text prefix for the list item.
        suffix: Text suffix for the list item.
        start_value: The starting value for a numbered list.
        style: The text style name for the list item.
        clone: An existing Style object to clone properties from.

    Returns:
        Style | None: The created or modified level style, or None
        if the style family is not 'list'.

    Raises:
        ValueError: If an unknown level style type is provided.
    """
    if self.family != "list":
        return None
    # Expected name
    if num_format is not None:
        level_style_name = "text:list-level-style-number"
    elif bullet_char is not None:
        level_style_name = "text:list-level-style-bullet"
    elif url is not None:
        level_style_name = "text:list-level-style-image"
    elif clone is not None:
        level_style_name = clone.tag
    else:
        raise ValueError("unknown level style type")
    was_created = False
    # Cloning or reusing an existing element
    level_style: Style | None = None
    if clone is not None:
        level_style = clone.clone  # type: ignore
        was_created = True
    else:
        level_style = self.get_level_style(level)
        if level_style is None:
            level_style = Element.from_tag(level_style_name)  # type: ignore
            was_created = True
    if level_style is None:
        return None
    # Transmute if the type changed
    if level_style.tag != level_style_name:
        print("Warn: different style", level_style_name, level_style.tag)
        level_style.tag = level_style_name
    # Set the level
    level_style.set_attribute("text:level", str(level))
    # Set the main attribute
    if num_format is not None:
        level_style.set_attribute("fo:num-format", num_format)
    elif bullet_char is not None:
        level_style.set_attribute("text:bullet-char", bullet_char)
    elif url is not None:
        level_style.set_attribute("xlink:href", url)
    # Set attributes
    if prefix:
        level_style.set_attribute("style:num-prefix", prefix)
    if suffix:
        level_style.set_attribute("style:num-suffix", suffix)
    if display_levels:
        level_style.set_attribute("text:display-levels", str(display_levels))
    if start_value:
        level_style.set_attribute("text:start-value", str(start_value))
    if style:
        level_style.text_style = style  # type: ignore
    # Commit the creation
    if was_created:
        self.append(level_style)
    return level_style

_make_line_string

_make_line_string(line: str | None) -> str

Helper to convert a line style value to a string for border properties.

Parameters:

Name Type Description Default
line str | None

The line style value (e.g., “solid”, “dotted”).

required

Returns:

Name Type Description
str str

The formatted line style string (e.g., “solid”).

Raises:

Type Description
ValueError

If the line style type is not supported.

Source code in odfdo/style.py
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
def _make_line_string(line: str | None) -> str:
    """Helper to convert a line style value to a string for border properties.

    Args:
        line: The line style value (e.g., "solid", "dotted").

    Returns:
        str: The formatted line style string (e.g., "solid").

    Raises:
        ValueError: If the line style type is not supported.
    """
    LINE_DEFAULT = "solid"
    if line is None:
        return LINE_DEFAULT
    if isinstance(line, str):
        line = line.strip()
        if line:
            return line
        return LINE_DEFAULT
    raise ValueError("Line style must be None for default or string")

_make_thick_string

_make_thick_string(thick: str | float | int | None) -> str

Helper to convert a thickness value to a string for border properties.

Parameters:

Name Type Description Default
thick str | float | int | None

The thickness value. Can be a string (e.g., “1pt”), a float (e.g., 0.5 for 0.5pt), or an int (e.g., 100 for 1.00pt).

required

Returns:

Name Type Description
str str

The formatted thickness string (e.g., “0.06pt”).

Raises:

Type Description
ValueError

If the thickness type is not supported.

Source code in odfdo/style.py
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
def _make_thick_string(thick: str | float | int | None) -> str:
    """Helper to convert a thickness value to a string for border properties.

    Args:
        thick: The thickness value. Can be a string
            (e.g., "1pt"), a float (e.g., 0.5 for 0.5pt), or an int (e.g., 100 for 1.00pt).

    Returns:
        str: The formatted thickness string (e.g., "0.06pt").

    Raises:
        ValueError: If the thickness type is not supported.
    """
    THICK_DEFAULT = "0.06pt"
    if thick is None:
        return THICK_DEFAULT
    if isinstance(thick, str):
        thick = thick.strip()
        if thick:
            return thick
        return THICK_DEFAULT
    if isinstance(thick, float):
        return f"{thick:.2f}pt"
    if isinstance(thick, int):
        return f"{thick / 100.0:.2f}pt"
    raise ValueError("Thickness must be None for default or float value (pt)")

_new_master_page

_new_master_page(*args: Any, **kwargs: Any) -> StyleBase

Factory function for creating a new StyleMasterPage instance.

This function is used internally by the Style class’s new method to create StyleMasterPage objects when the ‘family’ is ‘master-page’.

Parameters:

Name Type Description Default
*args Any

Variable length argument list.

()
**kwargs Any

Arbitrary keyword arguments.

{}

Returns:

Name Type Description
StyleMasterPage StyleBase

A new instance of StyleMasterPage.

Source code in odfdo/style.py
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
def _new_master_page(*args: Any, **kwargs: Any) -> StyleBase:
    """Factory function for creating a new StyleMasterPage instance.

    This function is used internally by the Style class's __new__ method
    to create StyleMasterPage objects when the 'family' is 'master-page'.

    Args:
        *args: Variable length argument list.
        **kwargs: Arbitrary keyword arguments.

    Returns:
        StyleMasterPage: A new instance of StyleMasterPage.
    """
    family = kwargs.pop("family", None)
    if family is None:
        args = args[1:]
    from .master_page import StyleMasterPage

    return StyleMasterPage(*args, **kwargs)

_new_page_layout

_new_page_layout(*args: Any, **kwargs: Any) -> StyleBase

Factory function for creating a new StylePageLayout instance.

This function is used internally by the Style class’s new method to create StylePageLayout objects when the ‘family’ is ‘page-layout’.

Parameters:

Name Type Description Default
*args Any

Variable length argument list.

()
**kwargs Any

Arbitrary keyword arguments.

{}

Returns:

Name Type Description
StylePageLayout StyleBase

A new instance of StylePageLayout.

Source code in odfdo/style.py
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
def _new_page_layout(*args: Any, **kwargs: Any) -> StyleBase:
    """Factory function for creating a new StylePageLayout instance.

    This function is used internally by the Style class's __new__ method
    to create StylePageLayout objects when the 'family' is 'page-layout'.

    Args:
        *args: Variable length argument list.
        **kwargs: Arbitrary keyword arguments.

    Returns:
        StylePageLayout: A new instance of StylePageLayout.
    """
    family = kwargs.pop("family", None)
    if family is None:
        args = args[1:]
    from .page_layout import StylePageLayout

    return StylePageLayout(*args, **kwargs)

create_table_cell_style

create_table_cell_style(
    border: str | None = None,
    border_top: str | None = None,
    border_bottom: str | None = None,
    border_left: str | None = None,
    border_right: str | None = None,
    padding: str | None = None,
    padding_top: str | None = None,
    padding_bottom: str | None = None,
    padding_left: str | None = None,
    padding_right: str | None = None,
    background_color: str | tuple | None = None,
    shadow: str | None = None,
    color: str | tuple | None = None,
) -> Style

Create and return a table cell style.

The border arguments (e.g., border, border_top) accept style attribute strings (e.g., “0.06pt solid #000000”) or None. Use make_table_cell_border_string to generate valid border strings. - If border is “default”, the style “0.06pt solid #000000” is applied to all four borders. - If any value is provided for border, it overrides border_top, border_bottom, etc. - If all border-related arguments are None, an empty border (fo:border=”none”) is used.

padding arguments specify a length (e.g., “0.5mm”). If padding is provided, it applies to all four sides; otherwise, individual padding sides can be specified. Default padding is none.

Parameters:

Name Type Description Default
border str | None

Style string for all four borders. Use “default” for a predefined style.

None
border_top str | None

Style string for the top border.

None
border_bottom str | None

Style string for the bottom border.

None
border_left str | None

Style string for the left border.

None
border_right str | None

Style string for the right border.

None
padding str | None

Style string for padding on all four sides.

None
padding_top str | None

Style string for top padding.

None
padding_bottom str | None

Style string for bottom padding.

None
padding_left str | None

Style string for left padding.

None
padding_right str | None

Style string for right padding.

None
background_color str | tuple | None

Background color (e.g., “#RRGGBB”, “red”, or RGB tuple).

None
shadow str | None

Shadow specification (e.g., “#808080 0.176cm 0.176cm”).

None
color str | tuple | None

Text color (e.g., “black”, “#RRGGBB”, or RGB tuple).

None

Returns:

Name Type Description
Style Style

A Style object configured for a table cell.

Source code in odfdo/style.py
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
def create_table_cell_style(
    border: str | None = None,
    border_top: str | None = None,
    border_bottom: str | None = None,
    border_left: str | None = None,
    border_right: str | None = None,
    padding: str | None = None,
    padding_top: str | None = None,
    padding_bottom: str | None = None,
    padding_left: str | None = None,
    padding_right: str | None = None,
    background_color: str | tuple | None = None,
    shadow: str | None = None,
    color: str | tuple | None = None,
) -> Style:
    """Create and return a table cell style.

    The `border` arguments (e.g., `border`, `border_top`) accept style attribute
    strings (e.g., "0.06pt solid #000000") or None. Use
    `make_table_cell_border_string` to generate valid border strings.
    - If `border` is "default", the style "0.06pt solid #000000" is applied to all
      four borders.
    - If any value is provided for `border`, it overrides `border_top`, `border_bottom`, etc.
    - If all border-related arguments are None, an empty border (fo:border="none") is used.

    `padding` arguments specify a length (e.g., "0.5mm"). If `padding` is
    provided, it applies to all four sides; otherwise, individual padding
    sides can be specified. Default padding is none.

    Args:
        border: Style string for all four borders. Use "default" for a predefined style.
        border_top: Style string for the top border.
        border_bottom: Style string for the bottom border.
        border_left: Style string for the left border.
        border_right: Style string for the right border.
        padding: Style string for padding on all four sides.
        padding_top: Style string for top padding.
        padding_bottom: Style string for bottom padding.
        padding_left: Style string for left padding.
        padding_right: Style string for right padding.
        background_color: Background color (e.g., "#RRGGBB", "red", or RGB tuple).
        shadow: Shadow specification (e.g., "#808080 0.176cm 0.176cm").
        color: Text color (e.g., "black", "#RRGGBB", or RGB tuple).

    Returns:
        Style: A Style object configured for a table cell.
    """
    if border == "default":
        border = make_table_cell_border_string()  # default border
    if border is not None:
        # use the border value for 4 sides.
        border_bottom = border_top = border_left = border_right = None
    if (
        border is None
        and border_bottom is None
        and border_top is None
        and border_left is None
        and border_right is None
    ):
        border = "none"
    if padding is not None:
        # use the padding value for 4 sides.
        padding_bottom = padding_top = padding_left = padding_right = None
    cell_style = Style(
        "table-cell",
        area="table-cell",
        border=border,
        border_top=border_top,
        border_bottom=border_bottom,
        border_left=border_left,
        border_right=border_right,
        padding=padding,
        padding_top=padding_top,
        padding_bottom=padding_bottom,
        padding_left=padding_left,
        padding_right=padding_right,
        background_color=background_color,
        shadow=shadow,
    )
    if color:
        cell_style.set_properties(area="text", color=color)
    return cell_style

default_boolean_style

default_boolean_style() -> Style

Return a default boolean style.

Returns:

Type Description
Style

An Element representing a default boolean style.

Source code in odfdo/style_defaults.py
41
42
43
44
45
46
47
48
49
50
51
def default_boolean_style() -> Style:
    """Return a default boolean style.

    Returns:
        An Element representing a default boolean style.
    """
    return Element.from_tag(  # type: ignore[return-value]
        '<number:boolean-style style:name="lpod-default-boolean-style">\n'
        "  <number:boolean/>\n"
        "</number:boolean-style>\n"
    )

default_currency_style

default_currency_style() -> Style

Return a default currency style (€).

Returns:

Name Type Description
Style Style

An Element representing a default currency style configured for Euro.

Source code in odfdo/style_defaults.py
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
def default_currency_style() -> Style:
    """Return a default currency style (€).

    Returns:
        Style: An Element representing a default currency style configured for Euro.
    """
    return Element.from_tag(  # type: ignore[return-value]
        '<number:currency-style style:name="lpod-default-currency-style">\n'
        "  <number:text>-</number:text>\n"
        '  <number:number number:decimal-places="2" '
        'number:min-integer-digits="1" number:grouping="true"/>\n'
        "  <number:text> </number:text>\n"
        '  <number:currency-symbol number:language="fr" '
        'number:country="FR">€</number:currency-symbol>\n'
        "</number:currency-style>\n"
    )

default_date_style

default_date_style() -> Style

Return a default date style (Y-M-D).

Returns:

Name Type Description
Style Style

An Element representing a default date style formatted as Y-M-D.

Source code in odfdo/style_defaults.py
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
def default_date_style() -> Style:
    """Return a default date style (Y-M-D).

    Returns:
        Style: An Element representing a default date style formatted as Y-M-D.
    """
    return Element.from_tag(  # type: ignore[return-value]
        '<number:date-style style:name="lpod-default-date-style">\n'
        '  <number:year number:style="long"/>\n'
        "  <number:text>-</number:text>\n"
        '  <number:month number:style="long"/>\n'
        "  <number:text>-</number:text>\n"
        '  <number:day number:style="long"/>\n'
        "</number:date-style>\n"
    )

default_number_style

default_number_style() -> Style

Return a default number style with two decimals.

Returns:

Name Type Description
Style Style

An Element representing a default number style with two decimal places.

Source code in odfdo/style_defaults.py
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
def default_number_style() -> Style:
    """Return a default number style with two decimals.

    Returns:
        Style: An Element representing a default number style with two decimal places.
    """
    return Element.from_tag(  # type: ignore[return-value]
        '<number:number-style style:name="lpod-default-number-style">\n'
        '  <number:number number:decimal-places="2" '
        'number:min-integer-digits="1"/>\n'
        "</number:number-style>\n"
    )

default_percentage_style

default_percentage_style() -> Style

Return a default percentage style with two decimals.

Returns:

Name Type Description
Style Style

An Element representing a default percentage style with two decimal places.

Source code in odfdo/style_defaults.py
103
104
105
106
107
108
109
110
111
112
113
114
def default_percentage_style() -> Style:
    """Return a default percentage style with two decimals.

    Returns:
        Style: An Element representing a default percentage style with two decimal places.
    """
    return Element.from_tag(  # type: ignore[return-value]
        '<number:percentage-style style:name="lpod-default-percentage-style">\n'
        '  <number:number number:decimal-places="2" number:min-integer-digits="1"/>\n'
        "  <number:text>%</number:text>\n"
        "</number:percentage-style>\n"
    )

default_time_style

default_time_style() -> Style

Return a default time style.

Returns:

Type Description
Style

An Element representing a default time style.

Source code in odfdo/style_defaults.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
def default_time_style() -> Style:
    """Return a default time style.

    Returns:
        An Element representing a default time style.
    """
    return Element.from_tag(  # type: ignore[return-value]
        '<number:time-style style:name="lpod-default-time-style">\n'
        '  <number:hours number:style="long"/>\n'
        "  <number:text>:</number:text>\n"
        '  <number:minutes number:style="long"/>\n'
        "  <number:text>:</number:text>\n"
        '  <number:seconds number:style="long"/>\n'
        "</number:time-style>\n"
    )

hex2rgb

hex2rgb(color: str) -> tuple[int, int, int]

Convert a “#RRGGBB” hexadecimal color to an (R, G, B) tuple.

Parameters:

Name Type Description Default
color str

The hexadecimal color string (e.g., “#FF0000”).

required

Returns:

Type Description
tuple[int, int, int]

tuple[int, int, int]: A tuple representing the RGB values.

Raises:

Type Description
ValueError

If the input string is not a valid hexadecimal color.

Source code in odfdo/utils/color.py
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
def hex2rgb(color: str) -> tuple[int, int, int]:
    """Convert a "#RRGGBB" hexadecimal color to an (R, G, B) tuple.

    Args:
        color: The hexadecimal color string (e.g., "#FF0000").

    Returns:
        tuple[int, int, int]: A tuple representing the RGB values.

    Raises:
        ValueError: If the input string is not a valid hexadecimal color.
    """
    code = color[1:]
    if not (len(color) == 7 and color[0] == "#" and code.isalnum()):
        raise ValueError(f'"{color}" is not a valid color')
    red = int(code[:2], 16)
    green = int(code[2:4], 16)
    blue = int(code[4:6], 16)
    return (red, green, blue)

make_table_cell_border_string

make_table_cell_border_string(
    thick: str | float | int | None = None,
    line: str | None = None,
    color: str | tuple | None = None,
) -> str

Generate a string for “style:table-cell-properties” “fo:border”.

The default output is “0.06pt solid #000000”.

Parameters:

Name Type Description Default
thick str | float | int | None

The thickness of the border. Can be a string (e.g., “1pt”), a float (e.g., 0.5 for 0.5pt), or an int (e.g., 100 for 1.00pt).

None
line str | None

The style of the line (e.g., “solid”, “dotted”).

None
color str | tuple | None

The color of the border. Can be a string (e.g., “black”, “#RRGGBB”) or an RGB 3-tuple.

None

Returns:

Name Type Description
str str

A formatted string suitable for the “fo:border” attribute.

Source code in odfdo/style.py
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
def make_table_cell_border_string(
    thick: str | float | int | None = None,
    line: str | None = None,
    color: str | tuple | None = None,
) -> str:
    """Generate a string for "style:table-cell-properties" "fo:border".

    The default output is "0.06pt solid #000000".

    Args:
        thick: The thickness of the border. Can be
            a string (e.g., "1pt"), a float (e.g., 0.5 for 0.5pt), or an int
            (e.g., 100 for 1.00pt).
        line: The style of the line (e.g., "solid", "dotted").
        color: The color of the border. Can be a string
            (e.g., "black", "#RRGGBB") or an RGB 3-tuple.

    Returns:
        str: A formatted string suitable for the "fo:border" attribute.
    """
    thick_string = _make_thick_string(thick)
    line_string = _make_line_string(line)
    color_string = hexa_color(color) or "#000000"
    return " ".join((thick_string, line_string, color_string))

rgb2hex

rgb2hex(color: str | tuple[int, int, int]) -> str

Convert a color name or (R, G, B) tuple to a “#RRGGBB” hexadecimal string.

Parameters:

Name Type Description Default
color str | tuple[int, int, int]

The color as a standard CSS color name (e.g., “yellow”) or an RGB tuple (e.g., (238, 130, 238)).

required

Returns:

Name Type Description
str str

The hexadecimal representation of the color (e.g., “#FFFF00”).

Raises:

Type Description
KeyError

If the color name is unknown.

ValueError

If the color tuple is invalid.

TypeError

If the color argument is of an unsupported type.

Examples:

>>> rgb2hex('yellow')
'#FFFF00'
>>> rgb2hex((238, 130, 238))
'#EE82EE'
Source code in odfdo/utils/color.py
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
def rgb2hex(color: str | tuple[int, int, int]) -> str:
    """Convert a color name or (R, G, B) tuple to a "#RRGGBB" hexadecimal string.

    Args:
        color: The color as a standard CSS color name (e.g., "yellow") or an
            RGB tuple (e.g., (238, 130, 238)).

    Returns:
        str: The hexadecimal representation of the color (e.g., "#FFFF00").

    Raises:
        KeyError: If the color name is unknown.
        ValueError: If the color tuple is invalid.
        TypeError: If the color argument is of an unsupported type.

    Examples:
        >>> rgb2hex('yellow')
        '#FFFF00'
        >>> rgb2hex((238, 130, 238))
        '#EE82EE'
    """
    if isinstance(color, str):
        try:
            code = CSS3_COLORMAP[color.lower()]
        except KeyError as e:
            raise KeyError(f'Color "{color}" is unknown in CSS color list') from e
    elif isinstance(color, tuple):
        if len(color) != 3:
            raise ValueError("Color must be a 3-tuple")
        code = color
    else:
        raise TypeError(f'Invalid color "{color}"')
    for channel in code:
        if not 0 <= channel <= 255:
            raise ValueError(
                f'Invalid color "{color}", channel must be between 0 and 255'
            )
    return f"#{code[0]:02X}{code[1]:02X}{code[2]:02X}"