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 (withlumMod="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:
- Looks up the base color in the alias map from
OfficeDefaultThemeColors - Applies shade (
themeShade) or tint (themeTint) modifiers usingColorMathutilities - 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 accent2 → ED7D31 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:
- Run properties default (
RunPropertiesDefault): Base font, size, color, and run-level settings - Paragraph properties default: Spacing, indentation, and alignment baselines
- 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 viaThemeColorResolver, withThemeHandlerensuring every document has a theme part for fallback. -
Default styling derives from
docDefaultsand the default paragraph style, accessed throughWordPageDefaultsand merged into effective formatting byWordHandler. -
The CLI pipeline (
ExtractThemeTail→ApplyBorderTheme/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →