How Theme Colors and Default Styling Operate in OfficeCLI for Document Customization

OfficeCLI manages document styling through a two-tier system: a static canonical color palette for theme colors and document defaults (docDefaults) that provide base paragraph and run properties when no explicit style is set.

OfficeCLI is an open-source command-line interface for manipulating Office Open XML (OOXML) documents in Word, Excel, and PowerPoint. This guide examines how the project implements theme colors and default styling to ensure consistent, predictable document appearance across all supported formats.


How Theme Colors Work in OfficeCLI

Theme colors in OfficeCLI are not merely cosmetic—they form a resolution pipeline that bridges user commands to final OOXML output. The system guarantees that every document, even those created from scratch, contains a valid color reference framework.

The Canonical Palette: OfficeDefaultThemeColors

At the heart of the theme system lies OfficeDefaultThemeColors.cs, which defines the six accent colors, two dark/light variants, and hyperlink colors that Word, Excel, and PowerPoint expect.

// From src/officecli/Core/OfficeDefaultThemeColors.cs (lines 1-50)
// Colors are stored as 6-character OOXML hex strings without leading #
public static class OfficeDefaultThemeColors
{
    public const string Accent1 = "4472C4";
    public const string Accent2 = "ED7D31";
    // ... Accent3-6, Dark1, Light1, Dark2, Light2, 
    // Hyperlink, FollowedHyperlink
}

The class exposes two critical structures:

  • BuildAliasMap() (lines 58-72): Creates a case-insensitive dictionary mapping theme-color names (accent1, tx1, bg2, dark1, etc.) to their hex values. This map is consulted whenever the rendering pipeline encounters a <w:themeColor> attribute.

  • DefaultChartSeriesPalette: An array that reuses the six accent colors, then provides darker tints (with lumMod="75000") for slots 7-12. Both the OOXML chart builder and SVG preview renderer consume this array.

Ensuring Theme Part Existence: ThemeHandler

The ThemeHandler class in src/officecli/Core/ThemeHandler.cs solves a critical OOXML edge case: documents that lack a <a:theme> part. When processing such files, the handler injects a minimal ThemePart containing an empty <a:theme> element. This guarantees that downstream operations—such as RawXmlHelper.Execute—can safely replace or modify theme content without null reference failures.

Resolving Theme Colors: ThemeColorResolver

ThemeColorResolver in src/officecli/Core/ThemeColorResolver.cs performs the final color translation:

  1. Looks up the base color in the alias map from OfficeDefaultThemeColors
  2. Applies shade (themeShade) or tint (themeTint) modifiers using ColorMath utilities
  3. Writes the resolved hex value into the target OOXML element

The Theme Color Pipeline in Action

When you execute a CLI command with a theme-color selector, this sequence runs:

officecli set paragraph 1 border top single 2 themeColor=accent2
Step Component Action
Parsing ExtractThemeTail in WordHandler.Set.cs Splits single;2;themeColor=accent2 into positional part (single;2) and theme dictionary ({ "themeColor": "accent2" })
Application ApplyBorderTheme helper Sets w:themeColor="accent2" on the <w:top> element
Resolution ThemeColorResolver Converts accent2ED7D31 at render/save time
Persistence Document save Theme-color attributes preserved; resolves to concrete color if theme part is missing

How Default Styling Works in OfficeCLI

Default styling ensures that newly created or minimally styled documents maintain "Office-native" appearance without explicit user configuration.

Document Defaults: docDefaults

The WordPageDefaults class in src/officecli/Core/WordPageDefaults.cs extracts three critical structures from StyleDefinitionsPart:

  1. Run properties default (RunPropertiesDefault): Base font, size, color, and run-level settings
  2. Paragraph properties default: Spacing, indentation, and alignment baselines
  3. Table defaults: Default table cell margins and borders

These defaults merge into any style's RunPropertiesBaseStyle when computing effective formatting.

Default Paragraph Style Resolution

Within WordHandler.StyleList.cs, the handler identifies the default paragraph style by locating the <w:style> element with w:type="paragraph" and w:default="1". The code then follows the style inheritance chain to resolve all implied properties.

Blank Document Creation

BlankDocCreator.cs seeds new documents with a complete styling foundation:

// From src/officecli/BlankDocCreator.cs
// Generates minimal theme1.xml with canonical palette
var themePart = document.AddNewPart<ThemePart>();
themePart.FeedData(GenerateDefaultThemeStream());

This ensures that themeColor references resolve immediately, and that the document's docDefaults produce a clean, professional appearance on first open.

CLI "Default" Keyword Handling

Many set commands accept default as a magic value. In WordHandler.Set.cs (lines 770-775), this maps to standard document parts:

officecli set header default  # Maps to /header[1], creates if absent

officecli set footer default  # Maps to /footer[1], creates if absent

Practical Examples for Theme Colors and Default Styling

Example 1: Apply Themed Border to a Paragraph


# 2pt single top border using Accent 2 (orange)

officecli set paragraph 1 border top single 2 themeColor=accent2

Internal result: <w:top w:val="single" w:sz="2" w:themeColor="accent2"/> → resolves to ED7D31

Example 2: Override Default Theme Color


# Replace Accent 1 with custom red

officecli set theme accent1=FF0000

Internal result: ThemeHandler ensures theme part exists; FF0000 written to <a:accent1>; all themeColor="accent1" references now use red.

Example 3: Create Document with Full Default Styling

officecli new word contract.docx

Internal result: BlankDocCreator emits theme1.xml with canonical palette + docDefaults with standard run/paragraph properties.


Key Source Files for Theme and Default Styling

File Purpose Path
OfficeDefaultThemeColors.cs Canonical palette, alias map, chart series colors src/officecli/Core/OfficeDefaultThemeColors.cs
ThemeHandler.cs Guarantees <a:theme> part existence src/officecli/Core/ThemeHandler.cs
ThemeColorResolver.cs Theme-color name → hex resolution with shade/tint src/officecli/Core/ThemeColorResolver.cs
WordPageDefaults.cs Reads and exposes docDefaults src/officecli/Core/WordPageDefaults.cs
WordHandler.Set.cs Parses theme tails, applies to borders/shading/color src/officecli/Handlers/Word/WordHandler.Set.cs
BlankDocCreator.cs Generates new documents with seeded theme and defaults src/officecli/BlankDocCreator.cs

Summary

  • Theme colors originate from a static canonical palette in OfficeDefaultThemeColors.cs, resolved at runtime via ThemeColorResolver, with ThemeHandler ensuring every document has a theme part for fallback.

  • Default styling derives from docDefaults and the default paragraph style, accessed through WordPageDefaults and merged into effective formatting by WordHandler.

  • The CLI pipeline (ExtractThemeTailApplyBorderTheme/ApplyShadingTheme/ApplyColorTheme) bridges user commands to OOXML attributes, preserving theme-color references for round-trip editing.

  • New documents automatically receive complete theme and default styling through BlankDocCreator, eliminating blank-document appearance issues.


Frequently Asked Questions

How does OfficeCLI handle documents that have no theme part?

ThemeHandler in src/officecli/Core/ThemeHandler.cs automatically creates a minimal ThemePart with an empty <a:theme> element. This allows subsequent processing to safely modify or replace theme content without encountering null reference errors.

Can I use theme colors with tints and shades in CLI commands?

Yes. Include themeShade or themeTint as key-value pairs: themeColor=accent1,themeShade=BF. The ThemeColorResolver applies these modifiers using ColorMath utilities before writing the final hex value.

What happens when I specify "default" instead of a specific color or value?

The CLI interprets default as a directive to use standard document structures. In WordHandler.Set.cs (lines 770-775), this maps to /header[1] or /footer[1] with automatic element creation if absent.

Why do new OfficeCLI documents look like native Office files?

BlankDocCreator.cs seeds every new document with the full canonical theme palette and docDefaults containing standard run and paragraph properties. This design replicates the styling foundation that Microsoft Office applies to blank documents.

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 →