xlsx/conditional-formatting-authoring--expression

A single worksheet declares A1:A10 populated with 1..10 plus one conditional formatting rule attached via the public authoring API (Worksheet.add_conditional_formatting + the factory functions CellIsRule, FormulaRule, ColorScaleRule, DataBarRule, IconSetRule, Top10Rule). Each parameter row exercises one of the six core cfRule @type values a user reaches through a rule factory.

Library verdicts: python-xlsx: — xlsxjs: —

Metadata

Feature idxlsx/conditional-formatting-authoring--expression
Formatxlsx
Categorycell-formatting
Familyxlsx/conditional-formatting-authoring
Axis valuesrule=expression
Spececma-376-5-part-1 § 18.3.1.10 cfRule

XPath assertions

ID / partPredicateXPathpython-xlsxxlsxjs
authoring-cfrule-type-expression
xl/worksheets/sheet1.xml
equal = expression
The worksheet must contain a <conditionalFormatting>/<cfRule> whose @type equals the expected ST_CfType enum value produced by the authoring factory.
string(//x:conditionalFormatting/x:cfRule/@type)
authoring-cfrule-sqref-expression
xl/worksheets/sheet1.xml
equal = A1:A10
Worksheet.add_conditional_formatting must attach the rule to the exact sqref the caller supplied.
string(//x:conditionalFormatting/@sqref)
authoring-cfrule-detail-expression
xl/worksheets/sheet1.xml
match = ^1(\.0+)?$
Type-specific invariant: cellIs operator, expression formula count, colorScale / dataBar cfvo counts, iconSet @iconSet, top10 @rank. (XPath count() returns a float — lxml stringifies as 'N.0', so count-based checks use regex match.)
count(//x:conditionalFormatting/x:cfRule/x:formula)

Render assertions

No render assertions declared.

Generator source

scripts/gen_conditional_formatting_authoring.py

#!/usr/bin/env python3
"""Generate ``fixtures/xlsx/conditional-formatting-authoring--<kind>.xlsx`` fixtures.

Parameterised family exercising the six core conditional-formatting rule
types a user reaches through python-xlsx's public authoring API — the
rule-factory helpers in ``xlsx.formatting.rule`` (``CellIsRule``,
``FormulaRule``, ``ColorScaleRule``, ``DataBarRule``, ``IconSetRule``,
``Top10Rule``) plus ``Worksheet.add_conditional_formatting``.

This complements ``gen_conditional_format_rule.py`` (which exercises
every ST_CfType enum value, including the set-membership and text-match
kinds that don't have a dedicated factory). The authoring-side manifest
is narrower and focused on the six types the library actively *writes*
from first-class helpers.

Each invocation writes a one-sheet workbook with A1:A10 populated with
the integers 1..10 and a single rule attached via
``Worksheet.add_conditional_formatting``. See
``features/xlsx/conditional-formatting-authoring.json`` for the
manifest that drives the parameter expansion.
"""

from __future__ import annotations

import argparse
import datetime as _dt
from pathlib import Path

from xlsx import Workbook
from xlsx.styles import PatternFill
from xlsx.formatting.rule import (
    CellIsRule,
    ColorScaleRule,
    DataBarRule,
    FormulaRule,
    IconSetRule,
    Rule,
    Top10Rule,
)

_REPRODUCIBLE_DT = _dt.datetime(2000, 1, 1, 0, 0, 0)
_REPO_ROOT = Path(__file__).resolve().parent.parent

_FILL = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")


def build(kind: str) -> Rule:
    if kind == "cell-is":
        return CellIsRule(operator="greaterThan", formula=["5"], fill=_FILL)
    if kind == "expression":
        return FormulaRule(formula=["A1>0"], fill=_FILL)
    if kind == "color-scale":
        return ColorScaleRule(
            start_type="min",
            start_color="FF0000",
            end_type="max",
            end_color="00FF00",
        )
    if kind == "data-bar":
        return DataBarRule(start_type="min", end_type="max", color="638EC6")
    if kind == "icon-set":
        return IconSetRule("3TrafficLights1", "percent", [0, 33, 67])
    if kind == "top10":
        return Top10Rule(rank=10)
    raise ValueError(f"unknown kind: {kind!r}")


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--kind", required=True, help="Rule kind id from the manifest.")
    parser.add_argument("--out", required=True, help="Output .xlsx path.")
    args = parser.parse_args()

    out_path = Path(args.out)
    if not out_path.is_absolute():
        out_path = _REPO_ROOT / out_path
    out_path.parent.mkdir(parents=True, exist_ok=True)

    wb = Workbook()
    ws = wb.active
    for i in range(1, 11):
        ws.cell(row=i, column=1, value=i)

    ws.add_conditional_formatting("A1:A10", build(args.kind))
    wb.save(out_path, zip_date_time=_REPRODUCIBLE_DT)
    print(out_path)
    return 0


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

Manifest (expanded)

{
  "$schema": "../manifest.schema.json",
  "id": "xlsx/conditional-formatting-authoring--expression",
  "kind": "literal",
  "title": "Conditional formatting authoring API",
  "format": "xlsx",
  "category": "cell-formatting",
  "roles": [
    "authoring"
  ],
  "summary": "A single worksheet declares A1:A10 populated with 1..10 plus one conditional formatting rule attached via the public authoring API (Worksheet.add_conditional_formatting + the factory functions CellIsRule, FormulaRule, ColorScaleRule, DataBarRule, IconSetRule, Top10Rule). Each parameter row exercises one of the six core cfRule @type values a user reaches through a rule factory.",
  "spec": {
    "source": "ecma-376-5-part-1",
    "clause": "18.3.1.10",
    "element": "cfRule",
    "rnc_reference": "spec/ecma-376-5/part-1/rnc/SpreadsheetML.rnc",
    "xsd_reference": "spec/ecma-376-5/part-1/xsd/sml.xsd",
    "notes": "This manifest focuses on the authoring API rather than every ST_CfType enum value (see xlsx/conditional-format-rule for that). It pins the six rule types python-xlsx exposes via first-class factory helpers: cellIs / expression / colorScale / dataBar / iconSet / top10. Each factory is the public surface a caller is expected to use; the manifest validates that the resulting cfRule @type lands on the correct enum value and that the accompanying structural child (colorScale / dataBar / iconSet) or attribute (rank for top10, operator+formula for cellIs) is present. SpreadsheetML parts use a default namespace with no prefix; XPath binds it as 'x'."
  },
  "fixtures": {
    "machine": "xlsx/conditional-formatting-authoring--expression"
  },
  "generator": {
    "python": "scripts/gen_conditional_formatting_authoring.py",
    "arg_template": "--kind {rule.id} --out fixtures/xlsx/conditional-formatting-authoring--{rule.id}.xlsx"
  },
  "_expansion": {
    "parent_id": "xlsx/conditional-formatting-authoring",
    "bindings": {
      "rule": "expression"
    }
  },
  "assertions": [
    {
      "id": "authoring-cfrule-type-expression",
      "part": "xl/worksheets/sheet1.xml",
      "namespaces": {
        "x": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
      },
      "xpath": "string(//x:conditionalFormatting/x:cfRule/@type)",
      "must": "equal",
      "value": "expression",
      "description": "The worksheet must contain a <conditionalFormatting>/<cfRule> whose @type equals the expected ST_CfType enum value produced by the authoring factory."
    },
    {
      "id": "authoring-cfrule-sqref-expression",
      "part": "xl/worksheets/sheet1.xml",
      "namespaces": {
        "x": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
      },
      "xpath": "string(//x:conditionalFormatting/@sqref)",
      "must": "equal",
      "value": "A1:A10",
      "description": "Worksheet.add_conditional_formatting must attach the rule to the exact sqref the caller supplied."
    },
    {
      "id": "authoring-cfrule-detail-expression",
      "part": "xl/worksheets/sheet1.xml",
      "namespaces": {
        "x": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
      },
      "xpath": "count(//x:conditionalFormatting/x:cfRule/x:formula)",
      "must": "match",
      "value": "^1(\\.0+)?$",
      "description": "Type-specific invariant: cellIs operator, expression formula count, colorScale / dataBar cfvo counts, iconSet @iconSet, top10 @rank. (XPath count() returns a float — lxml stringifies as 'N.0', so count-based checks use regex match.)"
    }
  ]
}

Fixture

Download conditional-formatting-authoring--expression.xlsx (4.9 KB)

Reference preview

No rendered reference is available for this case.

Spec notes

This manifest focuses on the authoring API rather than every ST_CfType enum value (see xlsx/conditional-format-rule for that). It pins the six rule types python-xlsx exposes via first-class factory helpers: cellIs / expression / colorScale / dataBar / iconSet / top10. Each factory is the public surface a caller is expected to use; the manifest validates that the resulting cfRule @type lands on the correct enum value and that the accompanying structural child (colorScale / dataBar / iconSet) or attribute (rank for top10, operator+formula for cellIs) is present. SpreadsheetML parts use a default namespace with no prefix; XPath binds it as 'x'.