Class: Uniword::Mhtml::Document

Inherits:
Lutaml::Model::Serializable
  • Object
show all
Includes:
DocumentInput
Defined in:
lib/uniword/mhtml/document.rb

Overview

MHTML Document — top-level model for .mht/.mhtml/.doc files.

This is COMPLETELY SEPARATE from OOXML Wordprocessingml::DocumentRoot. MHTML uses MIME multipart format with HTML content, not ZIP + OOXML XML.

Structure:

Mhtml::Document
├── html_part (HtmlPart) — main document HTML
├── parts[] (MimePart) — all MIME parts (images, XML, theme, etc.)
├── document_properties (Metadata::DocumentProperties)
├── word_document_settings (Metadata::WordDocumentSettings)
└── filelist_xml (String)

Instance Method Summary collapse

Instance Method Details

#add_part(part) ⇒ Object

Add a MIME part



156
157
158
159
# File 'lib/uniword/mhtml/document.rb', line 156

def add_part(part)
  parts << part
  self
end

#body_htmlObject

Body inner HTML



58
59
60
# File 'lib/uniword/mhtml/document.rb', line 58

def body_html
  html_part&.body_html
end

#color_scheme_mapping_partXmlPart?

Returns Color scheme mapping part.

Returns:

  • (XmlPart, nil)

    Color scheme mapping part



111
112
113
114
115
# File 'lib/uniword/mhtml/document.rb', line 111

def color_scheme_mapping_part
  parts.find do |p|
    p.is_a?(XmlPart) && p.filename&.include?("colorschememapping")
  end
end

#color_scheme_mapping_xmlString?

Returns Color scheme mapping XML.

Returns:

  • (String, nil)

    Color scheme mapping XML



118
119
120
# File 'lib/uniword/mhtml/document.rb', line 118

def color_scheme_mapping_xml
  color_scheme_mapping_part&.decoded_content
end

#css_stylesObject

CSS styles from HTML head



63
64
65
# File 'lib/uniword/mhtml/document.rb', line 63

def css_styles
  html_part&.css_styles
end

#document_statsHash

Returns Document statistics (paragraphs, tables, images).

Returns:

  • (Hash)

    Document statistics (paragraphs, tables, images)



168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/uniword/mhtml/document.rb', line 168

def document_stats
  html = raw_html || html_content
  if html
    {
      paragraphs: html.scan(/<p[\s>]/i).count,
      tables: html.scan(/<table/i).count,
      images: html.scan(/<img/i).count,
    }
  else
    { paragraphs: 0, tables: 0, images: 0 }
  end
end

#filelist_partXmlPart?

Returns Filelist XML part.

Returns:

  • (XmlPart, nil)

    Filelist XML part



101
102
103
# File 'lib/uniword/mhtml/document.rb', line 101

def filelist_part
  parts.find { |p| p.is_a?(XmlPart) && p.filename == "filelist.xml" }
end

#filelist_xmlString?

Returns Filelist XML content.

Returns:

  • (String, nil)

    Filelist XML content



106
107
108
# File 'lib/uniword/mhtml/document.rb', line 106

def filelist_xml
  filelist_part&.decoded_content
end

Returns Footer HTML (placeholder).

Returns:

  • (String, nil)

    Footer HTML (placeholder)



135
136
137
138
139
# File 'lib/uniword/mhtml/document.rb', line 135

def footer_html
  header_footer_parts.find do |p|
    p.filename&.include?("footer")
  end&.decoded_content
end

Returns Header/footer HTML parts.

Returns:



123
124
125
# File 'lib/uniword/mhtml/document.rb', line 123

def header_footer_parts
  parts.grep(HeaderFooterPart)
end

#header_htmlString?

Returns Header HTML.

Returns:

  • (String, nil)

    Header HTML



128
129
130
131
132
# File 'lib/uniword/mhtml/document.rb', line 128

def header_html
  header_footer_parts.find do |p|
    p.filename&.include?("header")
  end&.decoded_content
end

#htmlHtmlPart

Returns The main HTML part.

Returns:



41
42
43
# File 'lib/uniword/mhtml/document.rb', line 41

def html
  @html_part
end

#image_partsArray<ImagePart>

Returns All image parts.

Returns:



91
92
93
# File 'lib/uniword/mhtml/document.rb', line 91

def image_parts
  parts.grep(ImagePart)
end

#imagesHash

Returns Images as filename => decoded data.

Returns:

  • (Hash)

    Images as filename => decoded data



149
150
151
152
153
# File 'lib/uniword/mhtml/document.rb', line 149

def images
  image_parts.each_with_object({}) do |part, hash|
    hash[part.filename] = part.decoded_content if part.filename
  end
end

#inspectObject

Build a summary of the document structure



162
163
164
165
# File 'lib/uniword/mhtml/document.rb', line 162

def inspect
  "#<#{self.class} parts=#{parts.length} images=#{image_parts.length} " \
    "xml=#{xml_parts.length} theme=#{theme_part ? 'yes' : 'no'}>"
end

#placeholder_htmlString?

Returns Placeholder header HTML.

Returns:

  • (String, nil)

    Placeholder header HTML



142
143
144
145
146
# File 'lib/uniword/mhtml/document.rb', line 142

def placeholder_html
  header_footer_parts.find do |p|
    p.filename&.include?("plchdr")
  end&.decoded_content
end

#raw_htmlObject

Raw HTML string of the main HTML part



46
47
48
# File 'lib/uniword/mhtml/document.rb', line 46

def raw_html
  html_part&.decoded_content
end

#raw_html=(value) ⇒ Object



50
51
52
53
54
55
# File 'lib/uniword/mhtml/document.rb', line 50

def raw_html=(value)
  self.html_part ||= HtmlPart.new
  html_part.content_type = "text/html"
  html_part.content_transfer_encoding = "quoted-printable"
  html_part.raw_content = value
end

#textObject

Text content (stripped of HTML tags)



68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/uniword/mhtml/document.rb', line 68

def text
  return "" unless raw_html

  raw_html
    .gsub(/<[^>]+>/, " ")
    .gsub("&lt;", "<")
    .gsub("&gt;", ">")
    .gsub("&amp;", "&")
    .gsub("&quot;", '"')
    .gsub("&#39;", "'")
    .gsub("&nbsp;", " ")
    .gsub(/\s+/, " ")
    .strip
end

#theme_partThemePart?

Returns Theme data part.

Returns:



96
97
98
# File 'lib/uniword/mhtml/document.rb', line 96

def theme_part
  parts.find { |p| p.is_a?(ThemePart) }
end

#xml_partsArray<XmlPart>

Returns All XML parts.

Returns:

  • (Array<XmlPart>)

    All XML parts



86
87
88
# File 'lib/uniword/mhtml/document.rb', line 86

def xml_parts
  parts.grep(XmlPart)
end