Class: Uniword::Wordprocessingml::DocumentRoot

Inherits:
Lutaml::Model::Serializable
  • Object
show all
Includes:
DocumentInput, 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:



126
127
128
# File 'lib/uniword/wordprocessingml/document_root.rb', line 126

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

#bibliography_sourcesObject

Bibliography sources for sources.xml



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

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



251
252
253
254
255
256
257
258
259
260
261
# File 'lib/uniword/wordprocessingml/document_root.rb', line 251

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 }



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

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



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

def comments
  @comments
end

#content_typesObject

Round-trip parts (copied from DocxPackage during load)



116
117
118
# File 'lib/uniword/wordprocessingml/document_root.rb', line 116

def content_types
  @content_types
end

#core_propertiesUniword::Ooxml::CoreProperties

Get core_properties (lazy initialization)

Returns:



147
148
149
# File 'lib/uniword/wordprocessingml/document_root.rb', line 147

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

#custom_propertiesObject

Round-trip parts (copied from DocxPackage during load)



116
117
118
# File 'lib/uniword/wordprocessingml/document_root.rb', line 116

def custom_properties
  @custom_properties
end

#custom_xml_itemsObject

Round-trip parts (copied from DocxPackage during load)



116
117
118
# File 'lib/uniword/wordprocessingml/document_root.rb', line 116

def custom_xml_items
  @custom_xml_items
end

#document_relsObject

Round-trip parts (copied from DocxPackage during load)



116
117
118
# File 'lib/uniword/wordprocessingml/document_root.rb', line 116

def document_rels
  @document_rels
end

#endnotesObject

Footnotes and endnotes (separate XML parts in DOCX package)



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

def endnotes
  @endnotes
end

#font_tableObject

Round-trip parts (copied from DocxPackage during load)



116
117
118
# File 'lib/uniword/wordprocessingml/document_root.rb', line 116

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.



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

def footers
  @footers
end

#footnotesObject

Footnotes and endnotes (separate XML parts in DOCX package)



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

def footnotes
  @footnotes
end

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

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


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

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.



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

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 }



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

def image_parts
  @image_parts
end

#numbering_configurationObject

Accessor for numbering_configuration (lazy init for builder API)



131
132
133
# File 'lib/uniword/wordprocessingml/document_root.rb', line 131

def numbering_configuration
  @numbering_configuration ||= NumberingConfiguration.new
end

#package_relsObject

Round-trip parts (copied from DocxPackage during load)



116
117
118
# File 'lib/uniword/wordprocessingml/document_root.rb', line 116

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



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

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



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

def revisions
  @revisions
end

#settingsObject

Round-trip parts (copied from DocxPackage during load)



116
117
118
# File 'lib/uniword/wordprocessingml/document_root.rb', line 116

def settings
  @settings
end

#styles_configurationObject

Lazy initialization for styles_configuration



157
158
159
# File 'lib/uniword/wordprocessingml/document_root.rb', line 157

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



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

def theme
  @theme
end

#theme_relsObject

Round-trip parts (copied from DocxPackage during load)



116
117
118
# File 'lib/uniword/wordprocessingml/document_root.rb', line 116

def theme_rels
  @theme_rels
end

#web_settingsObject

Round-trip parts (copied from DocxPackage during load)



116
117
118
# File 'lib/uniword/wordprocessingml/document_root.rb', line 116

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



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

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



308
309
310
311
312
# File 'lib/uniword/wordprocessingml/document_root.rb', line 308

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



355
356
357
358
359
360
361
# File 'lib/uniword/wordprocessingml/document_root.rb', line 355

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



274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/uniword/wordprocessingml/document_root.rb', line 274

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



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

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



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

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



324
325
326
# File 'lib/uniword/wordprocessingml/document_root.rb', line 324

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

#document_statsHash

Returns Document statistics (paragraphs, tables, images).

Returns:

  • (Hash)

    Document statistics (paragraphs, tables, images)



217
218
219
220
221
222
223
# File 'lib/uniword/wordprocessingml/document_root.rb', line 217

def document_stats
  {
    paragraphs: paragraphs.count,
    tables: tables.count,
    images: images.count,
  }
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



208
209
210
211
212
213
214
# File 'lib/uniword/wordprocessingml/document_root.rb', line 208

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



366
367
368
# File 'lib/uniword/wordprocessingml/document_root.rb', line 366

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)


140
141
142
# File 'lib/uniword/wordprocessingml/document_root.rb', line 140

def numbering_configuration_loaded?
  !!@numbering_configuration
end

#paragraphsArray<Paragraph>

Get all paragraphs (convenience accessor)

Returns:

  • (Array<Paragraph>)

    All paragraphs in document



193
194
195
# File 'lib/uniword/wordprocessingml/document_root.rb', line 193

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)



168
169
170
171
# File 'lib/uniword/wordprocessingml/document_root.rb', line 168

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



200
201
202
# File 'lib/uniword/wordprocessingml/document_root.rb', line 200

def tables
  body&.tables || []
end

#textString

Get all paragraph text

Returns:

  • (String)

    Combined text from all paragraphs



184
185
186
187
188
# File 'lib/uniword/wordprocessingml/document_root.rb', line 184

def text
  return "" unless body&.paragraphs

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

#titleObject

Get document title (delegates to core_properties)



152
153
154
# File 'lib/uniword/wordprocessingml/document_root.rb', line 152

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



177
178
179
# File 'lib/uniword/wordprocessingml/document_root.rb', line 177

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



373
374
375
# File 'lib/uniword/wordprocessingml/document_root.rb', line 373

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

#to_xml(options = {}) ⇒ Object

Override to_xml to sync element_order on child collections before serialization. lutaml-model’s compiled serializer may bypass child #to_xml when serializing nested elements, so we sync here at the DocumentRoot level.



88
89
90
91
92
93
# File 'lib/uniword/wordprocessingml/document_root.rb', line 88

def to_xml(options = {})
  body&.sync_element_order_for_serialization
  footnotes&.sync_element_order if footnotes
  endnotes&.sync_element_order if endnotes
  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



230
231
232
# File 'lib/uniword/wordprocessingml/document_root.rb', line 230

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

#validation_errorsArray<String>

Get structural validation errors.

Returns:

  • (Array<String>)

    Error messages



237
238
239
# File 'lib/uniword/wordprocessingml/document_root.rb', line 237

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

#validation_warningsArray<String>

Get structural validation warnings.

Returns:

  • (Array<String>)

    Warning messages



244
245
246
# File 'lib/uniword/wordprocessingml/document_root.rb', line 244

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