Class: Uniword::Wordprocessingml::DocumentRoot

Inherits:
Lutaml::Model::Serializable
  • Object
show all
Includes:
FeatureFacade
Defined in:
lib/uniword/wordprocessingml/document_root.rb,
lib/uniword/wordprocessingml/document_root/feature_facade.rb

Overview

Root element of a WordprocessingML document

Generated from OOXML schema: wordprocessingml.yml Element: <w:document>

Defined Under Namespace

Modules: FeatureFacade

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from FeatureFacade

#accept_all_changes, #add_comment, #add_footer, #add_header, #add_watermark, #clear_comments, #diff, #extract_images, #generate_toc, #insert_image, #insert_toc, #list_comments, #list_footers, #list_headers, #list_images, #list_watermarks, #protect, #protection_active?, #protection_info, #reject_all_changes, #remove_footers, #remove_headers, #remove_image, #remove_watermark, #spellcheck, #unprotect, #update_toc, #watermark?

Instance Attribute Details

#app_propertiesUniword::Ooxml::AppProperties

Get app_properties (lazy initialization)

Returns:



123
124
125
# File 'lib/uniword/wordprocessingml/document_root.rb', line 123

def app_properties
  @app_properties ||= Uniword::Ooxml::AppProperties.new
end

#bibliography_sourcesObject

Bibliography sources for sources.xml



111
112
113
# File 'lib/uniword/wordprocessingml/document_root.rb', line 111

def bibliography_sources
  @bibliography_sources
end

#bookmarksHash{String => Object}

Get bookmarks from document paragraphs

Returns:

  • (Hash{String => Object})

    Map of bookmark names to bookmark data



239
240
241
242
243
244
245
246
247
248
249
# File 'lib/uniword/wordprocessingml/document_root.rb', line 239

def bookmarks
  result = {}
  return result unless body&.paragraphs

  body.paragraphs.each do |para|
    para.bookmark_starts&.each do |bs|
      result[bs.name.to_s] = bs if bs.name
    end
  end
  result
end

#chart_partsObject

Chart parts to embed in the DOCX package Hash: r_id => { xml: String, target: String }



109
110
111
# File 'lib/uniword/wordprocessingml/document_root.rb', line 109

def chart_parts
  @chart_parts
end

#commentsObject

Additional attributes for DOCX metadata (not part of document.xml) These are stored in separate files within the DOCX package



94
95
96
# File 'lib/uniword/wordprocessingml/document_root.rb', line 94

def comments
  @comments
end

#content_typesObject

Round-trip parts (copied from DocxPackage during load)



113
114
115
# File 'lib/uniword/wordprocessingml/document_root.rb', line 113

def content_types
  @content_types
end

#core_propertiesUniword::Ooxml::CoreProperties

Get core_properties (lazy initialization)

Returns:



144
145
146
# File 'lib/uniword/wordprocessingml/document_root.rb', line 144

def core_properties
  @core_properties ||= Uniword::Ooxml::CoreProperties.new
end

#custom_propertiesObject

Round-trip parts (copied from DocxPackage during load)



113
114
115
# File 'lib/uniword/wordprocessingml/document_root.rb', line 113

def custom_properties
  @custom_properties
end

#custom_xml_itemsObject

Round-trip parts (copied from DocxPackage during load)



113
114
115
# File 'lib/uniword/wordprocessingml/document_root.rb', line 113

def custom_xml_items
  @custom_xml_items
end

#document_relsObject

Round-trip parts (copied from DocxPackage during load)



113
114
115
# File 'lib/uniword/wordprocessingml/document_root.rb', line 113

def document_rels
  @document_rels
end

#endnotesObject

Footnotes and endnotes (separate XML parts in DOCX package)



103
104
105
# File 'lib/uniword/wordprocessingml/document_root.rb', line 103

def endnotes
  @endnotes
end

#font_tableObject

Round-trip parts (copied from DocxPackage during load)



113
114
115
# File 'lib/uniword/wordprocessingml/document_root.rb', line 113

def font_table
  @font_table
end

#footersObject

Headers and footers (stored as hash: type => Header/Footer) Single-section only. For multi-section, use header_footer_parts.



97
98
99
# File 'lib/uniword/wordprocessingml/document_root.rb', line 97

def footers
  @footers
end

#footnotesObject

Footnotes and endnotes (separate XML parts in DOCX package)



103
104
105
# File 'lib/uniword/wordprocessingml/document_root.rb', line 103

def footnotes
  @footnotes
end

Multi-section headers/footers (ordered array): [“rIdH1”, target: “header1.xml”, rel_type: “…”,

content_type: "...", content: Header|Footer]


101
102
103
# File 'lib/uniword/wordprocessingml/document_root.rb', line 101

def header_footer_parts
  @header_footer_parts
end

#headersObject

Headers and footers (stored as hash: type => Header/Footer) Single-section only. For multi-section, use header_footer_parts.



97
98
99
# File 'lib/uniword/wordprocessingml/document_root.rb', line 97

def headers
  @headers
end

#image_partsObject

Image parts to embed in the DOCX package Hash: r_id => { path: String, data: String, content_type: String, target: String }



106
107
108
# File 'lib/uniword/wordprocessingml/document_root.rb', line 106

def image_parts
  @image_parts
end

#numbering_configurationObject

Accessor for numbering_configuration (lazy init for builder API)



128
129
130
# File 'lib/uniword/wordprocessingml/document_root.rb', line 128

def numbering_configuration
  @numbering_configuration ||= NumberingConfiguration.new
end

#package_relsObject

Round-trip parts (copied from DocxPackage during load)



113
114
115
# File 'lib/uniword/wordprocessingml/document_root.rb', line 113

def package_rels
  @package_rels
end

#raw_htmlObject

Additional attributes for DOCX metadata (not part of document.xml) These are stored in separate files within the DOCX package



94
95
96
# File 'lib/uniword/wordprocessingml/document_root.rb', line 94

def raw_html
  @raw_html
end

#revisionsObject

Additional attributes for DOCX metadata (not part of document.xml) These are stored in separate files within the DOCX package



94
95
96
# File 'lib/uniword/wordprocessingml/document_root.rb', line 94

def revisions
  @revisions
end

#settingsObject

Round-trip parts (copied from DocxPackage during load)



113
114
115
# File 'lib/uniword/wordprocessingml/document_root.rb', line 113

def settings
  @settings
end

#styles_configurationObject

Lazy initialization for styles_configuration



154
155
156
# File 'lib/uniword/wordprocessingml/document_root.rb', line 154

def styles_configuration
  @styles_configuration ||= StylesConfiguration.new
end

#themeObject

Additional attributes for DOCX metadata (not part of document.xml) These are stored in separate files within the DOCX package



94
95
96
# File 'lib/uniword/wordprocessingml/document_root.rb', line 94

def theme
  @theme
end

#theme_relsObject

Round-trip parts (copied from DocxPackage during load)



113
114
115
# File 'lib/uniword/wordprocessingml/document_root.rb', line 113

def theme_rels
  @theme_rels
end

#web_settingsObject

Round-trip parts (copied from DocxPackage during load)



113
114
115
# File 'lib/uniword/wordprocessingml/document_root.rb', line 113

def web_settings
  @web_settings
end

Instance Method Details

#apply_styles_from(source_path, strategy: :keep_existing) ⇒ self

Apply styles from another document

Parameters:

  • source_path (String)

    Path to source .docx file

  • strategy (Symbol) (defaults to: :keep_existing)

    Conflict resolution strategy

Returns:

  • (self)

    For method chaining



331
332
333
334
335
336
# File 'lib/uniword/wordprocessingml/document_root.rb', line 331

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

Parameters:

  • name (String, Symbol)

    StyleSet slug (e.g., ‘signature’, ‘heritage’)

  • strategy (Symbol) (defaults to: :keep_existing)

    Application strategy (:keep_existing, :replace, :rename)

Returns:

  • (self)

    For method chaining



296
297
298
299
300
# File 'lib/uniword/wordprocessingml/document_root.rb', line 296

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

Parameters:

  • template_path (String)

    Path to template .docx file

  • strategy (Symbol) (defaults to: :keep_existing)

    Conflict resolution strategy for styles

Returns:

  • (self)

    For method chaining



343
344
345
346
347
348
349
# File 'lib/uniword/wordprocessingml/document_root.rb', line 343

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

Apply theme to document

Applies a Uniword theme by name, updating doc defaults and built-in heading/hyperlink styles to reference the theme.

Parameters:

  • name (String, Symbol)

    Theme slug (e.g., ‘meridian’, ‘corporate’)

  • options (Hash)

    optional overrides

Options Hash (**options):

  • :colors (Hash)

    override specific color keys

  • :major_font (String)

    override major font

  • :minor_font (String)

    override minor font

Returns:

  • (self)

    For method chaining



262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/uniword/wordprocessingml/document_root.rb', line 262

def apply_theme(name, **options)
  friendly = Themes::Theme.load(name.to_s)

  options[:colors]&.each do |key, value|
    friendly.color_scheme[key.to_s] = value
  end
  friendly.font_scheme.major_font = options[:major_font] if options[:major_font]
  friendly.font_scheme.minor_font = options[:minor_font] if options[:minor_font]

  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

Parameters:

  • path (String)

    Path to .thmx file

  • variant (String, Integer, nil) (defaults to: nil)

    Optional variant

Returns:

  • (self)

    For method chaining



281
282
283
284
285
286
287
288
289
# File 'lib/uniword/wordprocessingml/document_root.rb', line 281

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

Parameters:

  • source_path (String)

    Path to source .docx file

Returns:

  • (self)

    For method chaining



320
321
322
323
324
# File 'lib/uniword/wordprocessingml/document_root.rb', line 320

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_themeHash?

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).

Examples:

result = doc.auto_transition_theme
puts "Transitioned from #{result[:ms_name]} to #{result[:uniword_slug]}"

Returns:

  • (Hash, nil)

    { uniword_slug:, ms_name: } or nil if no match



312
313
314
# File 'lib/uniword/wordprocessingml/document_root.rb', line 312

def auto_transition_theme
  Resource::ThemeTransition.auto_transition!(self)
end

#imagesArray<Drawing>

Get all drawings (image references) from the document. Walks all paragraphs and collects Drawing elements from runs.

Returns:

  • (Array<Drawing>)

    All drawing elements in document



205
206
207
208
209
210
211
# File 'lib/uniword/wordprocessingml/document_root.rb', line 205

def images
  return [] unless body&.paragraphs

  body.paragraphs.flat_map do |para|
    (para.runs || []).flat_map(&:drawings)
  end.compact
end

#inspectString

Custom inspect for readable output

Returns:

  • (String)

    Human-readable representation



354
355
356
# File 'lib/uniword/wordprocessingml/document_root.rb', line 354

def inspect
  "#<#{self.class} @body=...>"
end

#numbering_configuration_loaded?Boolean

Whether numbering_configuration was explicitly loaded from source (vs lazily created for builder API)

Returns:

  • (Boolean)


137
138
139
# File 'lib/uniword/wordprocessingml/document_root.rb', line 137

def numbering_configuration_loaded?
  !!@numbering_configuration
end

#paragraphsArray<Paragraph>

Get all paragraphs (convenience accessor)

Returns:

  • (Array<Paragraph>)

    All paragraphs in document



190
191
192
# File 'lib/uniword/wordprocessingml/document_root.rb', line 190

def paragraphs
  body&.paragraphs || []
end

#save(path, format: :auto, profile: nil) ⇒ Object

Save document to file

Parameters:

  • path (String)

    Output file path

  • format (Symbol) (defaults to: :auto)

    Format (:docx, :mhtml, :auto)



165
166
167
168
# File 'lib/uniword/wordprocessingml/document_root.rb', line 165

def save(path, format: :auto, profile: nil)
  writer = DocumentWriter.new(self)
  writer.save(path, format: format, profile: profile)
end

#tablesArray<Table>

Get all tables (convenience accessor)

Returns:

  • (Array<Table>)

    All tables in document



197
198
199
# File 'lib/uniword/wordprocessingml/document_root.rb', line 197

def tables
  body&.tables || []
end

#textString

Get all paragraph text

Returns:

  • (String)

    Combined text from all paragraphs



181
182
183
184
185
# File 'lib/uniword/wordprocessingml/document_root.rb', line 181

def text
  return "" unless body&.paragraphs

  body.paragraphs.map(&:text).join("\n")
end

#titleObject

Get document title (delegates to core_properties)



149
150
151
# File 'lib/uniword/wordprocessingml/document_root.rb', line 149

def title
  core_properties.title
end

#to_file(path, profile: nil) ⇒ Object

Save document to DOCX file using DocxPackage

Parameters:

  • path (String)

    Output file path

  • profile (Docx::Profile, nil) (defaults to: nil)

    Profile for reconciliation



174
175
176
# File 'lib/uniword/wordprocessingml/document_root.rb', line 174

def to_file(path, profile: nil)
  Docx::Package.to_file(self, path, profile: profile)
end

#to_html_documentString

Convert OOXML document to HTML document

Returns:

  • (String)

    HTML document content



361
362
363
# File 'lib/uniword/wordprocessingml/document_root.rb', line 361

def to_html_document
  Uniword::Transformation::OoxmlToHtmlConverter.document_to_html(self)
end

#to_xml(options = {}) ⇒ Object

Override to_xml to sync body element_order before serialization. lutaml-model’s compiled serializer may bypass Body#to_xml when serializing Body as a child element, so we sync here at the DocumentRoot level to ensure programmatically added paragraphs and tables are included.



87
88
89
90
# File 'lib/uniword/wordprocessingml/document_root.rb', line 87

def to_xml(options = {})
  body&.sync_element_order_for_serialization
  super
end

#valid?Boolean

Check if document structure is valid. Runs structural checks via Validation::StructuralValidator. Use the verify CLI command for full OPC + XSD + semantic validation.

Returns:

  • (Boolean)

    true if document has valid structure



218
219
220
# File 'lib/uniword/wordprocessingml/document_root.rb', line 218

def valid?
  Validation::StructuralValidator.new(self).valid?
end

#validation_errorsArray<String>

Get structural validation errors.

Returns:

  • (Array<String>)

    Error messages



225
226
227
# File 'lib/uniword/wordprocessingml/document_root.rb', line 225

def validation_errors
  Validation::StructuralValidator.new(self).errors
end

#validation_warningsArray<String>

Get structural validation warnings.

Returns:

  • (Array<String>)

    Warning messages



232
233
234
# File 'lib/uniword/wordprocessingml/document_root.rb', line 232

def validation_warnings
  Validation::StructuralValidator.new(self).warnings
end