How OfficeCLI ThemeColorResolver Handles Office and User-Defined Theme Colors

The ThemeColorResolver is a static utility in OfficeCLI that converts OOXML ColorScheme objects into validated hexadecimal color dictionaries, supporting both standard Office theme slots and user-defined color schemes with format-specific aliases for PowerPoint and Word.

OfficeCLI is an open-source command-line tool for manipulating Office documents, and one of its critical components is the ThemeColorResolver located in src/officecli/Core/ThemeColorResolver.cs. This utility bridges the gap between Office's complex XML-based color schemes and the plain hexadecimal values needed for rendering, ensuring safe color extraction across PowerPoint and Word pipelines.

Input Validation and Safety Checks

The ThemeColorResolver begins its workflow in the BuildColorMap method with rigorous input validation. When receiving a Drawing.ColorScheme? object (the theme definition) and the includePptAliases flag, the resolver immediately returns an empty dictionary if the scheme is null, preventing null reference exceptions downstream.

Before any color values enter the system, the private helper IsHex performs a security validation on lines 24-31. This method guarantees that every color value is a valid 3-, 6-, or 8-character hexadecimal string. This validation serves as a critical security barrier, preventing malformed or malicious theme files from injecting XSS vectors into CSS-style strings that could compromise rendering pipelines.

Core Scheme Color Extraction

The resolver extracts colors from eleven standard scheme slots defined in the OOXML specification: dk1, dk2, lt1, lt2, accent1 through accent6, hlink, and folHlink. For each slot in the Add local function (lines 39-50), the code performs the following sequence:

  1. Retrieves the first child RgbColorModelHex element for explicit RGB values
  2. Falls back to SystemColor for theme-defined system colors
  3. Selects the first non-null hexadecimal value (rgb ?? srgb)
  4. Validates through IsHex before adding to the dictionary

The actual population occurs in lines 52-64, where each validated color is inserted into a case-insensitive dictionary under its canonical name.

Alias Management for Word and PowerPoint

To make the color map ergonomically usable across different Office formats, ThemeColorResolver automatically generates shared aliases on lines 65-69. These aliases map technical scheme names to practical usage names:

  • dk1tx1, dark1
  • dk2dark2
  • lt1bg1, light1
  • lt2bg2, light2

These aliases apply to both Word and PowerPoint processing, ensuring consistent naming conventions when downstream code references text colors (tx1) or background colors (bg1).

PowerPoint-Specific Extensions

When the includePptAliases parameter is set to true—which the PowerPoint pipeline passes on lines 71-78—the resolver appends additional aliases that reflect PowerPoint's specific naming conventions:

  • dk1text1
  • dk2text2, tx2
  • lt1background1
  • lt2background2

This conditional block isolates PowerPoint-specific terminology from Word's slimmer alias set, allowing the same core resolver to serve both formats without polluting Word's color map with unused PowerPoint names.

Usage Examples

Word Document Color Extraction

For Word documents, call BuildColorMap without PowerPoint aliases:

using DocumentFormat.OpenXml.Presentation;
using OfficeCli.Core;

// themePart is the OpenXml part containing the theme definition
var colorScheme = themePart.Theme?.ThemeElements?.ColorScheme;
var map = ThemeColorResolver.BuildColorMap(colorScheme);
// map contains: "dk1", "accent3", "tx1", "bg2", etc.

PowerPoint Slide Color Extraction

For PowerPoint processing, enable the format-specific aliases:

using DocumentFormat.OpenXml.Presentation;
using OfficeCli.Core;

// themePart comes from the PPTX package
var colorScheme = themePart.Theme?.ThemeElements?.ColorScheme;
var map = ThemeColorResolver.BuildColorMap(colorScheme, includePptAliases: true);
// map additionally contains: "text1", "background2", etc.

Safe HTML Generation

Use the validated map to generate CSS-safe color styles:

string hex = map["accent1"];               // e.g., "FF5733"
string style = $"color: #{hex};";          // safe because hex was validated
htmlBuilder.Append($"<p style=\"{style}\">Content</p>");

Implementation Details and Security

The ThemeColorResolver architecture emphasizes three core principles:

  • Safety through validation: The IsHex check eliminates malformed theme data before string interpolation, mitigating XSS risks.
  • Format extensibility: Working on the generic Drawing.ColorScheme type allows any future Office format exposing compatible OOXML color schemes to reuse this logic.
  • Pure function design: The resolver contains no UI or file-IO dependencies, making it trivial to unit test with mocked color scheme objects.

Summary

  • ThemeColorResolver in src/officecli/Core/ThemeColorResolver.cs provides a static BuildColorMap method for converting OOXML themes to hexadecimal dictionaries.
  • The IsHex validation ensures all output colors are safe 3-, 6-, or 8-character hexadecimal strings before entering rendering pipelines.
  • The resolver handles eleven standard color slots including dk1, lt2, and accent1 through accent6.
  • Shared aliases (tx1, bg1, dark1, etc.) support both Word and PowerPoint, while optional PowerPoint-specific aliases (text1, background2) activate via the includePptAliases parameter.
  • User-defined themes from theme1.xml files process identically to built-in Office themes, as both expose the same ColorScheme object structure.

Frequently Asked Questions

What is ThemeColorResolver in OfficeCLI?

ThemeColorResolver is a static helper class located in src/officecli/Core/ThemeColorResolver.cs that translates OOXML ColorScheme objects into sanitized dictionaries mapping color names to hexadecimal values. It serves as the central authority for color extraction across OfficeCLI's PowerPoint and Word processing modules.

How does ThemeColorResolver validate color safety?

The resolver uses a private IsHex method (lines 24-31) to verify that every color value is a valid 3-, 6-, or 8-character hexadecimal string before adding it to the output dictionary. This prevents malformed or malicious theme data from propagating into CSS strings that could become XSS vectors.

What is the difference between Word and PowerPoint color handling in OfficeCLI?

Word processing uses the base color map with shared aliases like tx1 and bg1, while PowerPoint processing passes includePptAliases: true to BuildColorMap to receive additional format-specific names such as text1, text2, and background1. This allows both formats to use intuitive naming conventions while sharing the same underlying validation logic.

Does ThemeColorResolver support custom user-defined themes?

Yes. The resolver processes any Drawing.ColorScheme object that follows the OOXML specification, including user-defined themes from custom theme1.xml files. Since the extraction logic relies on the standard OOXML structure rather than hardcoded Office defaults, custom accent colors and modified dark/light variants resolve identically to built-in themes.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →