Module: Uniword::Wordprocessingml::DocumentStyling
- Included in:
- DocumentRoot
- Defined in:
- lib/uniword/wordprocessingml/document_styling.rb
Overview
Theme and style application for DocumentRoot — Word's Design/Layout/Styles surfaces as document-level API.
Extracted from DocumentRoot to keep the document model focused: bundled and file-based theme application, stylesets, font and color schemes, font replacement, page setup, and style management (rename/remove).
Instance Method Summary collapse
-
#apply_color_scheme(name) ⇒ self
Apply a bundled color scheme to the document's theme.
-
#apply_font_scheme(name) ⇒ self
Apply a bundled font scheme to the document's theme.
-
#apply_page_setup(size: nil, orientation: nil, margins: nil, top: nil, right: nil, bottom: nil, left: nil) ⇒ Integer
Apply uniform page setup to every section of the document.
-
#apply_styles_from(source_path, strategy: :keep_existing) ⇒ self
Apply styles from another document.
-
#apply_styleset(name, strategy: :keep_existing) ⇒ self
Apply StyleSet to document.
-
#apply_template(template_path, strategy: :keep_existing) ⇒ self
Apply both theme and styles from a template document.
-
#apply_theme(name, **options) ⇒ self
Applies a Uniword theme by name, updating doc defaults and built-in heading/hyperlink styles to reference the theme.
-
#apply_theme_file(path, variant: nil) ⇒ self
Apply theme from .thmx file.
-
#apply_theme_from(source_path) ⇒ self
Apply theme from another document.
-
#auto_transition_theme ⇒ Hash?
Auto-transition from MS theme to Uniword equivalent.
-
#find_replace(pattern, replacement, scope: :all, ignore_case: false) ⇒ FindReplace::Result
Find and replace text across document parts.
-
#lint(ruleset:) ⇒ Lint::Result
Run a lint ruleset against the document.
-
#redact(patterns: :pii, scope: :all) ⇒ Redact::Result
Redact PII patterns and/or custom regex across the document.
-
#remove_style(style_id) ⇒ Style?
Remove one style from the document's style definitions.
-
#remove_unused_styles ⇒ Array<String>
Remove every style that no content references — Word's Styles-pane decluttering as one call.
-
#rename_style(identifier, new_name) ⇒ Style?
Rename a style's display name (w:name) — Word's style rename.
-
#replace_font(from:, to:) ⇒ Integer
Replace one font family with another across the document.
-
#track_changes_enabled? ⇒ Boolean
True when change tracking is enabled.
-
#track_changes_off! ⇒ self
Turn change tracking off.
-
#track_changes_on! ⇒ self
Turn change tracking on.
Instance Method Details
#apply_color_scheme(name) ⇒ self
Apply a bundled color scheme to the document's theme
Mirrors Word's Design → Colors gallery: replaces only the theme's clrScheme — fonts and formats are untouched. Creates the theme part from the bundled Office theme when the document has none.
97 98 99 100 101 102 103 104 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 97 def apply_color_scheme(name) colors = Resource::ColorSchemeLoader.load(name.to_s) transformation = Themes::ThemeTransformation.new ensure_theme!(transformation) theme.theme_elements.clr_scheme = transformation.build_color_scheme(colors) self end |
#apply_font_scheme(name) ⇒ self
Apply a bundled font scheme to the document's theme
Mirrors Word's Design → Fonts gallery: replaces only the theme's fontScheme — colors and formats are untouched. Creates the theme part from the bundled Office theme when the document has none.
79 80 81 82 83 84 85 86 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 79 def apply_font_scheme(name) fonts = Resource::FontSchemeLoader.load(name.to_s) transformation = Themes::ThemeTransformation.new ensure_theme!(transformation) theme.theme_elements.font_scheme = transformation.build_font_scheme(fonts) self end |
#apply_page_setup(size: nil, orientation: nil, margins: nil, top: nil, right: nil, bottom: nil, left: nil) ⇒ Integer
Apply uniform page setup to every section of the document
Mirrors Word's Layout dialog: named paper sizes, orientation (with Word-style dimension swap), and margins.
211 212 213 214 215 216 217 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 211 def apply_page_setup(size: nil, orientation: nil, margins: nil, top: nil, right: nil, bottom: nil, left: nil) setup = PageSetup.new(size: size, orientation: orientation, margins: margins, top: top, right: right, bottom: bottom, left: left) setup.apply(self) end |
#apply_styles_from(source_path, strategy: :keep_existing) ⇒ self
Apply styles from another document
287 288 289 290 291 292 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 287 def apply_styles_from(source_path, strategy: :keep_existing) source_doc = Uniword.load(source_path) styles_configuration.merge(source_doc.styles_configuration, conflict_resolution: strategy) self end |
#apply_styleset(name, strategy: :keep_existing) ⇒ self
Apply StyleSet to document
63 64 65 66 67 68 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 63 def apply_styleset(name, strategy: :keep_existing) styleset = Uniword::Stylesets::YamlStyleSetLoader .load_bundled(name.to_s) styleset.apply_to(self, strategy: strategy) self end |
#apply_template(template_path, strategy: :keep_existing) ⇒ self
Apply both theme and styles from a template document
299 300 301 302 303 304 305 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 299 def apply_template(template_path, strategy: :keep_existing) template_doc = Uniword.load(template_path) self.theme = template_doc.theme.dup if template_doc.theme styles_configuration.merge(template_doc.styles_configuration, conflict_resolution: strategy) self end |
#apply_theme(name, **options) ⇒ self
Applies a Uniword theme by name, updating doc defaults and built-in heading/hyperlink styles to reference the theme.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 23 def apply_theme(name, **) friendly = Themes::Theme.load(name.to_s) [:colors]&.each do |key, value| friendly.color_scheme[key.to_s] = value end if [:major_font] friendly.font_scheme.major_font = [:major_font] end if [:minor_font] friendly.font_scheme.minor_font = [:minor_font] end word_theme = Themes::ThemeTransformation.new.to_word(friendly) Themes::ThemeApplicator.new.apply(word_theme, self) self end |
#apply_theme_file(path, variant: nil) ⇒ self
Apply theme from .thmx file
46 47 48 49 50 51 52 53 54 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 46 def apply_theme_file(path, variant: nil) loader = Themes::ThemeLoader.new self.theme = if variant loader.load_with_variant(path, variant) else loader.load(path) end self end |
#apply_theme_from(source_path) ⇒ self
Apply theme from another document
276 277 278 279 280 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 276 def apply_theme_from(source_path) source_doc = Uniword.load(source_path) self.theme = source_doc.theme.dup if source_doc.theme self end |
#auto_transition_theme ⇒ Hash?
Auto-transition from MS theme to Uniword equivalent
Detects the MS theme in the document's embedded theme and replaces it with the corresponding Uniword theme (font-substituted, renamed).
268 269 270 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 268 def auto_transition_theme Resource::ThemeTransition.auto_transition!(self) end |
#find_replace(pattern, replacement, scope: :all, ignore_case: false) ⇒ FindReplace::Result
Find and replace text across document parts.
Mirrors Word's Home → Replace dialog (without the GUI).
Replaces every non-overlapping match of pattern with
replacement across the configured scopes. Returns a
FindReplace::Result with per-scope counts.
v1 limitation: matches inside a single run only. Matches that span run boundaries are silently skipped (Word does the same in default mode).
141 142 143 144 145 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 141 def find_replace(pattern, replacement, scope: :all, ignore_case: false) matcher = build_find_replace_matcher(pattern, replacement, ignore_case) FindReplace::Engine.new(document: self, matcher: matcher, scopes: scope).run end |
#lint(ruleset:) ⇒ Lint::Result
Run a lint ruleset against the document.
194 195 196 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 194 def lint(ruleset:) Lint::Engine.new(document: self, ruleset: ruleset).run end |
#redact(patterns: :pii, scope: :all) ⇒ Redact::Result
Redact PII patterns and/or custom regex across the document.
Built on FindReplace. Default pattern library matches US
phone numbers, email, SSN, credit card numbers, IPv4
addresses. Pass patterns: :pii for defaults, or an array
of names ([:ssn, :email]) to select a subset.
184 185 186 187 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 184 def redact(patterns: :pii, scope: :all) Redact::Engine.new(document: self, patterns: patterns, scope: scope).run end |
#remove_style(style_id) ⇒ Style?
Remove one style from the document's style definitions
Default styles (w:default="1") are never removed.
226 227 228 229 230 231 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 226 def remove_style(style_id) style = styles_configuration.style(style_id) return unless StyleCleanup.new(self).remove?(style_id) style end |
#remove_unused_styles ⇒ Array<String>
Remove every style that no content references — Word's Styles-pane decluttering as one call. Default styles are kept.
253 254 255 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 253 def remove_unused_styles StyleCleanup.new(self).remove_unused end |
#rename_style(identifier, new_name) ⇒ Style?
Rename a style's display name (w:name) — Word's style rename. References (pStyle/rStyle/tblStyle) target the styleId, so they keep working unchanged.
241 242 243 244 245 246 247 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 241 def rename_style(identifier, new_name) style = styles_configuration.style(identifier) return unless style style.name = StyleName.new(val: new_name) style end |
#replace_font(from:, to:) ⇒ Integer
Replace one font family with another across the document
Mirrors Word's Home → Replace → Replace Fonts: rewrites rFonts references in styles and defaults, body content, headers, footers, notes, comments, and numbering. Theme font references (asciiTheme etc.) are untouched — use #apply_font_scheme for those.
117 118 119 120 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 117 def replace_font(from:, to:) replacer = FontReplacer.new(from: from, to: to) replacer.replace(self) end |
#track_changes_enabled? ⇒ Boolean
True when change tracking is enabled.
169 170 171 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 169 def track_changes_enabled? settings&.track_changes ? true : false end |
#track_changes_off! ⇒ self
Turn change tracking off. Existing tracked changes remain in the document; new edits are applied silently. Mirrors Word's Review → Track Changes → Off.
161 162 163 164 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 161 def track_changes_off! ensure_settings.track_changes = nil self end |
#track_changes_on! ⇒ self
Turn change tracking on. Every subsequent edit is recorded as a tracked change. Mirrors Word's Review → Track Changes → On.
151 152 153 154 |
# File 'lib/uniword/wordprocessingml/document_styling.rb', line 151 def track_changes_on! ensure_settings.track_changes = Wordprocessingml::TrackChanges.new self end |