uniword 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/data/themes/office_format_scheme.xml +137 -0
- data/data/themes/office_theme.xml +2 -0
- data/lib/uniword/builder/comment_builder.rb +2 -1
- data/lib/uniword/builder/footnote_builder.rb +4 -2
- data/lib/uniword/builder/run_builder.rb +5 -0
- data/lib/uniword/document_input.rb +7 -0
- data/lib/uniword/document_writer.rb +1 -5
- data/lib/uniword/docx/package.rb +18 -0
- data/lib/uniword/docx/package_serialization.rb +38 -0
- data/lib/uniword/docx/reconciler.rb +159 -4
- data/lib/uniword/format_converter.rb +4 -19
- data/lib/uniword/has_run_position.rb +9 -0
- data/lib/uniword/lazy_loader.rb +1 -1
- data/lib/uniword/math/o_math.rb +3 -0
- data/lib/uniword/mhtml/document.rb +18 -0
- data/lib/uniword/properties/bold.rb +3 -33
- data/lib/uniword/properties/boolean_element_factory.rb +66 -0
- data/lib/uniword/properties/boolean_formatting.rb +15 -215
- data/lib/uniword/properties/italic.rb +3 -33
- data/lib/uniword/properties.rb +8 -3
- data/lib/uniword/schema/schema_loader.rb +1 -1
- data/lib/uniword/transformation/mhtml_element_renderer.rb +1 -1
- data/lib/uniword/version.rb +1 -1
- data/lib/uniword/wordprocessingml/attached_template.rb +18 -0
- data/lib/uniword/wordprocessingml/body.rb +18 -36
- data/lib/uniword/wordprocessingml/brk_bin.rb +17 -0
- data/lib/uniword/wordprocessingml/brk_bin_sub.rb +17 -0
- data/lib/uniword/wordprocessingml/character_spacing_control.rb +17 -0
- data/lib/uniword/wordprocessingml/clr_scheme_mapping.rb +39 -0
- data/lib/uniword/wordprocessingml/compat.rb +16 -0
- data/lib/uniword/wordprocessingml/decimal_symbol.rb +17 -0
- data/lib/uniword/wordprocessingml/def_jc.rb +17 -0
- data/lib/uniword/wordprocessingml/default_tab_stop.rb +17 -0
- data/lib/uniword/wordprocessingml/disp_def.rb +14 -0
- data/lib/uniword/wordprocessingml/do_not_display_page_boundaries.rb +14 -0
- data/lib/uniword/wordprocessingml/do_not_include_subdocs_in_stats.rb +17 -0
- data/lib/uniword/wordprocessingml/doc_vars.rb +36 -0
- data/lib/uniword/wordprocessingml/document_root.rb +17 -5
- data/lib/uniword/wordprocessingml/endnote_pr.rb +18 -0
- data/lib/uniword/wordprocessingml/endnotes.rb +18 -0
- data/lib/uniword/wordprocessingml/even_and_odd_headers.rb +17 -0
- data/lib/uniword/wordprocessingml/footnote_pos.rb +17 -0
- data/lib/uniword/wordprocessingml/footnote_pr.rb +20 -0
- data/lib/uniword/wordprocessingml/footnotes.rb +18 -0
- data/lib/uniword/wordprocessingml/hdr_shape_defaults.rb +19 -0
- data/lib/uniword/wordprocessingml/hyperlink.rb +3 -0
- data/lib/uniword/wordprocessingml/hyphenation_zone.rb +20 -0
- data/lib/uniword/wordprocessingml/int_lim.rb +17 -0
- data/lib/uniword/wordprocessingml/l_margin.rb +17 -0
- data/lib/uniword/wordprocessingml/list_separator.rb +17 -0
- data/lib/uniword/wordprocessingml/math_font.rb +17 -0
- data/lib/uniword/wordprocessingml/math_pr.rb +49 -0
- data/lib/uniword/wordprocessingml/mirror_margins.rb +17 -0
- data/lib/uniword/wordprocessingml/nary_lim.rb +17 -0
- data/lib/uniword/wordprocessingml/proof_state.rb +19 -0
- data/lib/uniword/wordprocessingml/r_margin.rb +17 -0
- data/lib/uniword/wordprocessingml/rsid.rb +17 -0
- data/lib/uniword/wordprocessingml/rsid_root.rb +17 -0
- data/lib/uniword/wordprocessingml/rsids.rb +22 -0
- data/lib/uniword/wordprocessingml/settings.rb +45 -511
- data/lib/uniword/wordprocessingml/shape_defaults.rb +21 -0
- data/lib/uniword/wordprocessingml/small_frac.rb +17 -0
- data/lib/uniword/wordprocessingml/style_pane_format_filter.rb +50 -0
- data/lib/uniword/wordprocessingml/style_pane_sort_method.rb +20 -0
- data/lib/uniword/wordprocessingml/table_cell.rb +6 -0
- data/lib/uniword/wordprocessingml/table_row_properties.rb +2 -0
- data/lib/uniword/wordprocessingml/theme_font_lang.rb +19 -0
- data/lib/uniword/wordprocessingml/w14_doc_id.rb +17 -0
- data/lib/uniword/wordprocessingml/w15_chart_tracking_ref_based.rb +14 -0
- data/lib/uniword/wordprocessingml/w15_doc_id.rb +17 -0
- data/lib/uniword/wordprocessingml/wrap_indent.rb +17 -0
- data/lib/uniword/wordprocessingml.rb +42 -56
- data/lib/uniword.rb +12 -5
- metadata +52 -3
- data/lib/uniword/ooxml/types/on_off_type.rb +0 -64
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a7feae85851d80946524005c3cc6419419d492c717e559628093494ee7532cd9
|
|
4
|
+
data.tar.gz: eba8d3d3d433aa158b5a4214659e6afd0e12d74e3fada13997da066021a78f9d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 940e11bb305505cd3e6acdc6e9cca98e002d151a0f75e7c8872d613353b4c5d85b424062a661572b14474c342b62db3072d2cc081cb9e924f95bb8fdf80e6c39
|
|
7
|
+
data.tar.gz: 3ca3c9bea8133f7a18e64897b687ef8dd10843c85aa2e4422dabceed5152ae5a5f9cce56fdff8999f03e734f8510b919732f9f5b5b0d5ac0e9470c8dd0db11fb
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<a:fmtScheme name="Office">
|
|
2
|
+
<a:fillStyleLst>
|
|
3
|
+
<a:solidFill>
|
|
4
|
+
<a:schemeClr val="phClr"/>
|
|
5
|
+
</a:solidFill>
|
|
6
|
+
<a:gradFill rotWithShape="1">
|
|
7
|
+
<a:gsLst>
|
|
8
|
+
<a:gs pos="0">
|
|
9
|
+
<a:schemeClr val="phClr">
|
|
10
|
+
<a:lumMod val="110000"/>
|
|
11
|
+
<a:satMod val="105000"/>
|
|
12
|
+
<a:tint val="67000"/>
|
|
13
|
+
</a:schemeClr>
|
|
14
|
+
</a:gs>
|
|
15
|
+
<a:gs pos="50000">
|
|
16
|
+
<a:schemeClr val="phClr">
|
|
17
|
+
<a:lumMod val="105000"/>
|
|
18
|
+
<a:satMod val="103000"/>
|
|
19
|
+
<a:tint val="73000"/>
|
|
20
|
+
</a:schemeClr>
|
|
21
|
+
</a:gs>
|
|
22
|
+
<a:gs pos="100000">
|
|
23
|
+
<a:schemeClr val="phClr">
|
|
24
|
+
<a:lumMod val="105000"/>
|
|
25
|
+
<a:satMod val="109000"/>
|
|
26
|
+
<a:tint val="81000"/>
|
|
27
|
+
</a:schemeClr>
|
|
28
|
+
</a:gs>
|
|
29
|
+
</a:gsLst>
|
|
30
|
+
<a:lin ang="5400000" scaled="0"/>
|
|
31
|
+
</a:gradFill>
|
|
32
|
+
<a:gradFill rotWithShape="1">
|
|
33
|
+
<a:gsLst>
|
|
34
|
+
<a:gs pos="0">
|
|
35
|
+
<a:schemeClr val="phClr">
|
|
36
|
+
<a:satMod val="103000"/>
|
|
37
|
+
<a:lumMod val="102000"/>
|
|
38
|
+
<a:tint val="94000"/>
|
|
39
|
+
</a:schemeClr>
|
|
40
|
+
</a:gs>
|
|
41
|
+
<a:gs pos="50000">
|
|
42
|
+
<a:schemeClr val="phClr">
|
|
43
|
+
<a:satMod val="110000"/>
|
|
44
|
+
<a:lumMod val="100000"/>
|
|
45
|
+
<a:shade val="100000"/>
|
|
46
|
+
</a:schemeClr>
|
|
47
|
+
</a:gs>
|
|
48
|
+
<a:gs pos="100000">
|
|
49
|
+
<a:schemeClr val="phClr">
|
|
50
|
+
<a:lumMod val="99000"/>
|
|
51
|
+
<a:satMod val="120000"/>
|
|
52
|
+
<a:shade val="78000"/>
|
|
53
|
+
</a:schemeClr>
|
|
54
|
+
</a:gs>
|
|
55
|
+
</a:gsLst>
|
|
56
|
+
<a:lin ang="5400000" scaled="0"/>
|
|
57
|
+
</a:gradFill>
|
|
58
|
+
</a:fillStyleLst>
|
|
59
|
+
<a:lnStyleLst>
|
|
60
|
+
<a:ln w="12700" cap="flat" cmpd="sng" algn="ctr">
|
|
61
|
+
<a:solidFill>
|
|
62
|
+
<a:schemeClr val="phClr"/>
|
|
63
|
+
</a:solidFill>
|
|
64
|
+
<a:prstDash val="solid"/>
|
|
65
|
+
<a:miter lim="800000"/>
|
|
66
|
+
</a:ln>
|
|
67
|
+
<a:ln w="19050" cap="flat" cmpd="sng" algn="ctr">
|
|
68
|
+
<a:solidFill>
|
|
69
|
+
<a:schemeClr val="phClr"/>
|
|
70
|
+
</a:solidFill>
|
|
71
|
+
<a:prstDash val="solid"/>
|
|
72
|
+
<a:miter lim="800000"/>
|
|
73
|
+
</a:ln>
|
|
74
|
+
<a:ln w="25400" cap="flat" cmpd="sng" algn="ctr">
|
|
75
|
+
<a:solidFill>
|
|
76
|
+
<a:schemeClr val="phClr"/>
|
|
77
|
+
</a:solidFill>
|
|
78
|
+
<a:prstDash val="solid"/>
|
|
79
|
+
<a:miter lim="800000"/>
|
|
80
|
+
</a:ln>
|
|
81
|
+
</a:lnStyleLst>
|
|
82
|
+
<a:effectStyleLst>
|
|
83
|
+
<a:effectStyle>
|
|
84
|
+
<a:effectLst/>
|
|
85
|
+
</a:effectStyle>
|
|
86
|
+
<a:effectStyle>
|
|
87
|
+
<a:effectLst/>
|
|
88
|
+
</a:effectStyle>
|
|
89
|
+
<a:effectStyle>
|
|
90
|
+
<a:effectLst>
|
|
91
|
+
<a:outerShdw blurRad="57150" dist="19050" dir="5400000" algn="ctr" rotWithShape="0">
|
|
92
|
+
<a:srgbClr val="000000">
|
|
93
|
+
<a:alpha val="63000"/>
|
|
94
|
+
</a:srgbClr>
|
|
95
|
+
</a:outerShdw>
|
|
96
|
+
</a:effectLst>
|
|
97
|
+
</a:effectStyle>
|
|
98
|
+
</a:effectStyleLst>
|
|
99
|
+
<a:bgFillStyleLst>
|
|
100
|
+
<a:solidFill>
|
|
101
|
+
<a:schemeClr val="phClr"/>
|
|
102
|
+
</a:solidFill>
|
|
103
|
+
<a:solidFill>
|
|
104
|
+
<a:schemeClr val="phClr">
|
|
105
|
+
<a:tint val="95000"/>
|
|
106
|
+
<a:satMod val="170000"/>
|
|
107
|
+
</a:schemeClr>
|
|
108
|
+
</a:solidFill>
|
|
109
|
+
<a:gradFill rotWithShape="1">
|
|
110
|
+
<a:gsLst>
|
|
111
|
+
<a:gs pos="0">
|
|
112
|
+
<a:schemeClr val="phClr">
|
|
113
|
+
<a:tint val="93000"/>
|
|
114
|
+
<a:satMod val="150000"/>
|
|
115
|
+
<a:shade val="98000"/>
|
|
116
|
+
<a:lumMod val="102000"/>
|
|
117
|
+
</a:schemeClr>
|
|
118
|
+
</a:gs>
|
|
119
|
+
<a:gs pos="50000">
|
|
120
|
+
<a:schemeClr val="phClr">
|
|
121
|
+
<a:tint val="98000"/>
|
|
122
|
+
<a:satMod val="130000"/>
|
|
123
|
+
<a:shade val="90000"/>
|
|
124
|
+
<a:lumMod val="103000"/>
|
|
125
|
+
</a:schemeClr>
|
|
126
|
+
</a:gs>
|
|
127
|
+
<a:gs pos="100000">
|
|
128
|
+
<a:schemeClr val="phClr">
|
|
129
|
+
<a:shade val="63000"/>
|
|
130
|
+
<a:satMod val="120000"/>
|
|
131
|
+
</a:schemeClr>
|
|
132
|
+
</a:gs>
|
|
133
|
+
</a:gsLst>
|
|
134
|
+
<a:lin ang="5400000" scaled="0"/>
|
|
135
|
+
</a:gradFill>
|
|
136
|
+
</a:bgFillStyleLst>
|
|
137
|
+
</a:fmtScheme>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
2
|
+
<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme"><a:themeElements><a:clrScheme name="Office"><a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1><a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="0E2841"/></a:dk2><a:lt2><a:srgbClr val="E8E8E8"/></a:lt2><a:accent1><a:srgbClr val="156082"/></a:accent1><a:accent2><a:srgbClr val="E97132"/></a:accent2><a:accent3><a:srgbClr val="196B24"/></a:accent3><a:accent4><a:srgbClr val="0F9ED5"/></a:accent4><a:accent5><a:srgbClr val="A02B93"/></a:accent5><a:accent6><a:srgbClr val="4EA72E"/></a:accent6><a:hlink><a:srgbClr val="467886"/></a:hlink><a:folHlink><a:srgbClr val="96607D"/></a:folHlink></a:clrScheme><a:fontScheme name="Office"><a:majorFont><a:latin typeface="Aptos Display" panose="02110004020202020204"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="游ゴシック Light"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="等线 Light"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Times New Roman"/><a:font script="Hebr" typeface="Times New Roman"/><a:font script="Thai" typeface="Angsana New"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="MoolBoran"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Times New Roman"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/><a:font script="Armn" typeface="Arial"/><a:font script="Bugi" typeface="Leelawadee UI"/><a:font script="Bopo" typeface="Microsoft JhengHei"/><a:font script="Java" typeface="Javanese Text"/><a:font script="Lisu" typeface="Segoe UI"/><a:font script="Mymr" typeface="Myanmar Text"/><a:font script="Nkoo" typeface="Ebrima"/><a:font script="Olck" typeface="Nirmala UI"/><a:font script="Osma" typeface="Ebrima"/><a:font script="Phag" typeface="Phagspa"/><a:font script="Syrn" typeface="Estrangelo Edessa"/><a:font script="Syrj" typeface="Estrangelo Edessa"/><a:font script="Syre" typeface="Estrangelo Edessa"/><a:font script="Sora" typeface="Nirmala UI"/><a:font script="Tale" typeface="Microsoft Tai Le"/><a:font script="Talu" typeface="Microsoft New Tai Lue"/><a:font script="Tfng" typeface="Ebrima"/></a:majorFont><a:minorFont><a:latin typeface="Aptos" panose="02110004020202020204"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="游明朝"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="等线"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Arial"/><a:font script="Hebr" typeface="Arial"/><a:font script="Thai" typeface="Cordia New"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="DaunPenh"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Arial"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/><a:font script="Armn" typeface="Arial"/><a:font script="Bugi" typeface="Leelawadee UI"/><a:font script="Bopo" typeface="Microsoft JhengHei"/><a:font script="Java" typeface="Javanese Text"/><a:font script="Lisu" typeface="Segoe UI"/><a:font script="Mymr" typeface="Myanmar Text"/><a:font script="Nkoo" typeface="Ebrima"/><a:font script="Olck" typeface="Nirmala UI"/><a:font script="Osma" typeface="Ebrima"/><a:font script="Phag" typeface="Phagspa"/><a:font script="Syrn" typeface="Estrangelo Edessa"/><a:font script="Syrj" typeface="Estrangelo Edessa"/><a:font script="Syre" typeface="Estrangelo Edessa"/><a:font script="Sora" typeface="Nirmala UI"/><a:font script="Tale" typeface="Microsoft Tai Le"/><a:font script="Talu" typeface="Microsoft New Tai Lue"/><a:font script="Tfng" typeface="Ebrima"/></a:minorFont></a:fontScheme><a:fmtScheme name="Office"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:lumMod val="110000"/><a:satMod val="105000"/><a:tint val="67000"/></a:schemeClr></a:gs><a:gs pos="50000"><a:schemeClr val="phClr"><a:lumMod val="105000"/><a:satMod val="103000"/><a:tint val="73000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:lumMod val="105000"/><a:satMod val="109000"/><a:tint val="81000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="5400000" scaled="0"/></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:satMod val="103000"/><a:lumMod val="102000"/><a:tint val="94000"/></a:schemeClr></a:gs><a:gs pos="50000"><a:schemeClr val="phClr"><a:satMod val="110000"/><a:lumMod val="100000"/><a:shade val="100000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:lumMod val="99000"/><a:satMod val="120000"/><a:shade val="78000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="5400000" scaled="0"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w="12700" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/><a:miter lim="800000"/></a:ln><a:ln w="19050" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/><a:miter lim="800000"/></a:ln><a:ln w="25400" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/><a:miter lim="800000"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="57150" dist="19050" dir="5400000" algn="ctr" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="63000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"><a:tint val="95000"/><a:satMod val="170000"/></a:schemeClr></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="93000"/><a:satMod val="150000"/><a:shade val="98000"/><a:lumMod val="102000"/></a:schemeClr></a:gs><a:gs pos="50000"><a:schemeClr val="phClr"><a:tint val="98000"/><a:satMod val="130000"/><a:shade val="90000"/><a:lumMod val="103000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="63000"/><a:satMod val="120000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="5400000" scaled="0"/></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults><a:lnDef><a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="2"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="0"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="1"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="tx1"/></a:fontRef></a:style></a:lnDef></a:objectDefaults><a:extraClrSchemeLst/><a:extLst><a:ext uri="{05A4C25C-085E-4340-85A3-A5531E510DB2}"><thm15:themeFamily xmlns:thm15="http://schemas.microsoft.com/office/thememl/2012/main" name="Office Theme" id="{2E142A2C-CD16-42D6-873A-C26D2A0506FA}" vid="{1BDDFF52-6CD6-40A5-AB3C-68EB2F1E4D0A}"/></a:ext></a:extLst></a:theme>
|
|
@@ -11,7 +11,8 @@ module Uniword
|
|
|
11
11
|
class CommentBuilder
|
|
12
12
|
attr_reader :model
|
|
13
13
|
|
|
14
|
-
def initialize(model: nil, author: nil, comment_id: nil, date: nil,
|
|
14
|
+
def initialize(model: nil, author: nil, comment_id: nil, date: nil,
|
|
15
|
+
initials: nil)
|
|
15
16
|
@model = model || Comment.new(
|
|
16
17
|
author: author,
|
|
17
18
|
comment_id: comment_id,
|
|
@@ -75,7 +75,9 @@ module Uniword
|
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def create_footnote_entry(id, text, &block)
|
|
78
|
-
|
|
78
|
+
# OOXML spec: regular footnotes must NOT have w:type.
|
|
79
|
+
# Only separator/continuationSeparator use w:type.
|
|
80
|
+
entry = Wordprocessingml::Footnote.new(id: id.to_s)
|
|
79
81
|
para = ParagraphBuilder.new
|
|
80
82
|
if block_given?
|
|
81
83
|
block.call(para)
|
|
@@ -87,7 +89,7 @@ module Uniword
|
|
|
87
89
|
end
|
|
88
90
|
|
|
89
91
|
def create_endnote_entry(id, text, &block)
|
|
90
|
-
entry = Wordprocessingml::Endnote.new(id: id.to_s
|
|
92
|
+
entry = Wordprocessingml::Endnote.new(id: id.to_s)
|
|
91
93
|
para = ParagraphBuilder.new
|
|
92
94
|
if block_given?
|
|
93
95
|
block.call(para)
|
|
@@ -22,6 +22,11 @@ module Uniword
|
|
|
22
22
|
self
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def character_style(value)
|
|
26
|
+
ensure_properties.style = Properties::RunStyleReference.new(value: value)
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
|
|
25
30
|
def bold(value = true)
|
|
26
31
|
ensure_properties.bold = Properties::Bold.new(value: value)
|
|
27
32
|
self
|
|
@@ -136,11 +136,7 @@ module Uniword
|
|
|
136
136
|
# @raise [ArgumentError] if document is invalid
|
|
137
137
|
def validate_document(doc)
|
|
138
138
|
raise ArgumentError, "Document cannot be nil" if doc.nil?
|
|
139
|
-
|
|
140
|
-
# Accept OOXML Document
|
|
141
|
-
return if doc.is_a?(Uniword::Wordprocessingml::DocumentRoot)
|
|
142
|
-
# Accept MHTML Document
|
|
143
|
-
return if doc.is_a?(Uniword::Mhtml::Document)
|
|
139
|
+
return if doc.is_a?(Uniword::DocumentInput)
|
|
144
140
|
|
|
145
141
|
raise ArgumentError, "Must be a Document instance"
|
|
146
142
|
end
|
data/lib/uniword/docx/package.rb
CHANGED
|
@@ -87,6 +87,7 @@ module Uniword
|
|
|
87
87
|
|
|
88
88
|
# Non-serialized attributes (DOCX packaging helpers)
|
|
89
89
|
attr_accessor :chart_parts, :bibliography_sources, :profile
|
|
90
|
+
attr_accessor :settings_rels, :embeddings
|
|
90
91
|
|
|
91
92
|
# Load DOCX package from file
|
|
92
93
|
#
|
|
@@ -194,6 +195,13 @@ module Uniword
|
|
|
194
195
|
)
|
|
195
196
|
end
|
|
196
197
|
|
|
198
|
+
if zip_content["word/_rels/settings.xml.rels"]
|
|
199
|
+
package.settings_rels =
|
|
200
|
+
Ooxml::Relationships::PackageRelationships.from_xml(
|
|
201
|
+
zip_content["word/_rels/settings.xml.rels"]
|
|
202
|
+
)
|
|
203
|
+
end
|
|
204
|
+
|
|
197
205
|
if zip_content["word/fontTable.xml"]
|
|
198
206
|
package.font_table = Uniword::Wordprocessingml::FontTable.from_xml(
|
|
199
207
|
zip_content["word/fontTable.xml"]
|
|
@@ -272,6 +280,16 @@ module Uniword
|
|
|
272
280
|
# Extract image parts from word/media/ directory
|
|
273
281
|
extract_image_parts(zip_content, package, zip_path)
|
|
274
282
|
|
|
283
|
+
# Extract OLE/embedded object binaries from word/embeddings/
|
|
284
|
+
embedding_files = zip_content.keys.grep(%r{^word/embeddings/.+$})
|
|
285
|
+
if embedding_files.any?
|
|
286
|
+
package.embeddings = {}
|
|
287
|
+
embedding_files.each do |emb_path|
|
|
288
|
+
target = emb_path.sub("word/", "")
|
|
289
|
+
package.embeddings[target] = zip_content[emb_path]
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
275
293
|
package
|
|
276
294
|
end
|
|
277
295
|
|
|
@@ -26,6 +26,7 @@ document_rels)
|
|
|
26
26
|
inject_notes(content_types, document_rels)
|
|
27
27
|
inject_theme(content_types, document_rels)
|
|
28
28
|
inject_numbering(content_types, document_rels)
|
|
29
|
+
inject_embeddings(content_types, document_rels)
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
# Serialize all package parts to XML and add to content hash
|
|
@@ -88,6 +89,10 @@ document_rels)
|
|
|
88
89
|
content["word/settings.xml"] =
|
|
89
90
|
serialize_part(settings)
|
|
90
91
|
end
|
|
92
|
+
if settings_rels
|
|
93
|
+
content["word/_rels/settings.xml.rels"] =
|
|
94
|
+
serialize_infrastructure(settings_rels)
|
|
95
|
+
end
|
|
91
96
|
if font_table
|
|
92
97
|
content["word/fontTable.xml"] =
|
|
93
98
|
serialize_part(font_table)
|
|
@@ -131,6 +136,9 @@ document_rels)
|
|
|
131
136
|
serialize_headers(content)
|
|
132
137
|
serialize_footers(content)
|
|
133
138
|
serialize_header_footer_parts(content)
|
|
139
|
+
|
|
140
|
+
# OLE/embedded object binaries
|
|
141
|
+
serialize_embeddings(content)
|
|
134
142
|
end
|
|
135
143
|
|
|
136
144
|
# Serialize an OOXML document part with standard encoding
|
|
@@ -409,6 +417,28 @@ document_rels)
|
|
|
409
417
|
)
|
|
410
418
|
end
|
|
411
419
|
|
|
420
|
+
def inject_embeddings(content_types, document_rels)
|
|
421
|
+
return unless embeddings && !embeddings.empty?
|
|
422
|
+
|
|
423
|
+
embeddings.each_with_index do |(target, _data), idx|
|
|
424
|
+
part_name = "/word/#{target}"
|
|
425
|
+
next if content_types.overrides.any? { |o| o.part_name == part_name }
|
|
426
|
+
|
|
427
|
+
content_types.overrides << Uniword::ContentTypes::Override.new(
|
|
428
|
+
part_name: part_name,
|
|
429
|
+
content_type: "application/vnd.openxmlformats-officedocument.oleObject",
|
|
430
|
+
)
|
|
431
|
+
|
|
432
|
+
next if document_rels.relationships.any? { |r| r.target == target }
|
|
433
|
+
|
|
434
|
+
document_rels.relationships << Ooxml::Relationships::Relationship.new(
|
|
435
|
+
id: "rIdEmbedding#{idx + 1}",
|
|
436
|
+
type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject",
|
|
437
|
+
target: target,
|
|
438
|
+
)
|
|
439
|
+
end
|
|
440
|
+
end
|
|
441
|
+
|
|
412
442
|
def wire_header_reference(type, r_id)
|
|
413
443
|
return unless document&.body
|
|
414
444
|
|
|
@@ -467,6 +497,14 @@ document_rels)
|
|
|
467
497
|
serialize_part(part[:content])
|
|
468
498
|
end
|
|
469
499
|
end
|
|
500
|
+
|
|
501
|
+
def serialize_embeddings(content)
|
|
502
|
+
return unless embeddings && !embeddings.empty?
|
|
503
|
+
|
|
504
|
+
embeddings.each do |target, data|
|
|
505
|
+
content["word/#{target}"] = data
|
|
506
|
+
end
|
|
507
|
+
end
|
|
470
508
|
end
|
|
471
509
|
end
|
|
472
510
|
end
|
|
@@ -28,6 +28,7 @@ module Uniword
|
|
|
28
28
|
reconcile_section_properties
|
|
29
29
|
reconcile_footnotes
|
|
30
30
|
reconcile_endnotes
|
|
31
|
+
reconcile_note_references
|
|
31
32
|
repair_theme
|
|
32
33
|
|
|
33
34
|
# Group 2: Support parts (profile-dependent)
|
|
@@ -85,14 +86,13 @@ module Uniword
|
|
|
85
86
|
].compact
|
|
86
87
|
|
|
87
88
|
parts.each do |part|
|
|
88
|
-
part.pending_namespace_data = nil
|
|
89
89
|
part.import_declaration_plan = nil
|
|
90
90
|
part.pending_plan_root_element = nil
|
|
91
|
-
# TODO: @xml_input_namespaces has no public accessor in lutaml-model.
|
|
92
|
-
# Replace with public API once lutaml-model exposes one.
|
|
93
|
-
part.instance_variable_set(:@xml_input_namespaces, nil)
|
|
94
91
|
end
|
|
92
|
+
|
|
93
|
+
parts.each(&:clear_xml_parse_state!)
|
|
95
94
|
end
|
|
95
|
+
|
|
96
96
|
def reconcile_section_properties
|
|
97
97
|
return unless package.document&.body
|
|
98
98
|
|
|
@@ -173,6 +173,114 @@ module Uniword
|
|
|
173
173
|
ensure_separators(package.endnotes, :endnote) if package.endnotes
|
|
174
174
|
end
|
|
175
175
|
|
|
176
|
+
# -- Note reference consistency --
|
|
177
|
+
|
|
178
|
+
def reconcile_note_references
|
|
179
|
+
reconcile_footnote_references
|
|
180
|
+
reconcile_endnote_references
|
|
181
|
+
reconcile_note_definition_integrity
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def reconcile_footnote_references
|
|
185
|
+
return unless package.document&.body
|
|
186
|
+
|
|
187
|
+
referenced = collect_note_ids(:footnote)
|
|
188
|
+
return if referenced.empty?
|
|
189
|
+
|
|
190
|
+
ensure_footnotes_part
|
|
191
|
+
defined = package.footnotes.footnote_entries.each_with_object(Set.new) do |fn, s|
|
|
192
|
+
s << fn.id
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
missing = referenced.to_set - defined
|
|
196
|
+
return if missing.empty?
|
|
197
|
+
|
|
198
|
+
missing.each do |id|
|
|
199
|
+
package.footnotes.footnote_entries << Wordprocessingml::Footnote.new(
|
|
200
|
+
id: id, paragraphs: [Wordprocessingml::Paragraph.new],
|
|
201
|
+
)
|
|
202
|
+
end
|
|
203
|
+
record_fix("R10",
|
|
204
|
+
"Added #{missing.size} missing footnote definition(s) " \
|
|
205
|
+
"for orphaned footnoteReference IDs: #{missing.sort.join(', ')}")
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def reconcile_endnote_references
|
|
209
|
+
return unless package.document&.body
|
|
210
|
+
|
|
211
|
+
referenced = collect_note_ids(:endnote)
|
|
212
|
+
return if referenced.empty?
|
|
213
|
+
|
|
214
|
+
ensure_endnotes_part
|
|
215
|
+
defined = package.endnotes.endnote_entries.each_with_object(Set.new) do |en, s|
|
|
216
|
+
s << en.id
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
missing = referenced.to_set - defined
|
|
220
|
+
return if missing.empty?
|
|
221
|
+
|
|
222
|
+
missing.each do |id|
|
|
223
|
+
package.endnotes.endnote_entries << Wordprocessingml::Endnote.new(
|
|
224
|
+
id: id, paragraphs: [Wordprocessingml::Paragraph.new],
|
|
225
|
+
)
|
|
226
|
+
end
|
|
227
|
+
record_fix("R10",
|
|
228
|
+
"Added #{missing.size} missing endnote definition(s) " \
|
|
229
|
+
"for orphaned endnoteReference IDs: #{missing.sort.join(', ')}")
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Validates structural integrity of footnote/endnote definitions.
|
|
233
|
+
def reconcile_note_definition_integrity
|
|
234
|
+
strip_invalid_note_types(:footnote)
|
|
235
|
+
strip_invalid_note_types(:endnote)
|
|
236
|
+
deduplicate_note_ids(:footnote)
|
|
237
|
+
deduplicate_note_ids(:endnote)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# R15: Regular footnotes/endnotes must NOT have w:type.
|
|
241
|
+
# Only separator (id=-1) and continuationSeparator (id=0) use w:type.
|
|
242
|
+
def strip_invalid_note_types(type)
|
|
243
|
+
notes = package.public_send(:"#{type}s")
|
|
244
|
+
return unless notes
|
|
245
|
+
|
|
246
|
+
entries = notes.public_send(:"#{type}_entries")
|
|
247
|
+
invalid = entries.select do |e|
|
|
248
|
+
e.type && e.id != "-1" && e.id != "0"
|
|
249
|
+
end
|
|
250
|
+
return if invalid.empty?
|
|
251
|
+
|
|
252
|
+
invalid.each { |e| e.type = nil }
|
|
253
|
+
record_fix("R15",
|
|
254
|
+
"Removed invalid w:type from #{invalid.size} " \
|
|
255
|
+
"regular #{type} definition(s): " \
|
|
256
|
+
"IDs #{invalid.map(&:id).sort.join(', ')}")
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# R16: Duplicate IDs in footnotes.xml/endnotes.xml are invalid.
|
|
260
|
+
# Keeps the first occurrence, removes subsequent duplicates.
|
|
261
|
+
def deduplicate_note_ids(type)
|
|
262
|
+
notes = package.public_send(:"#{type}s")
|
|
263
|
+
return unless notes
|
|
264
|
+
|
|
265
|
+
entries = notes.public_send(:"#{type}_entries")
|
|
266
|
+
seen = Set.new
|
|
267
|
+
dupes = []
|
|
268
|
+
entries.reject! do |e|
|
|
269
|
+
if seen.include?(e.id)
|
|
270
|
+
dupes << e
|
|
271
|
+
true
|
|
272
|
+
else
|
|
273
|
+
seen << e.id
|
|
274
|
+
false
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
return if dupes.empty?
|
|
278
|
+
|
|
279
|
+
record_fix("R16",
|
|
280
|
+
"Removed #{dupes.size} duplicate #{type} ID(s): " \
|
|
281
|
+
"#{dupes.map(&:id).sort.join(', ')}")
|
|
282
|
+
end
|
|
283
|
+
|
|
176
284
|
# -- Builders --
|
|
177
285
|
|
|
178
286
|
def minimal_footnotes
|
|
@@ -215,6 +323,53 @@ module Uniword
|
|
|
215
323
|
entries.unshift(continuation_entry(type)) unless ids.include?("0")
|
|
216
324
|
end
|
|
217
325
|
|
|
326
|
+
def collect_note_ids(type)
|
|
327
|
+
ref_attr = type == :footnote ? :footnote_reference : :endnote_reference
|
|
328
|
+
ids = []
|
|
329
|
+
collect_note_ids_from_element(package.document.body, ref_attr, ids)
|
|
330
|
+
ids
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
def collect_note_ids_from_element(element, ref_attr, ids)
|
|
334
|
+
return unless element
|
|
335
|
+
|
|
336
|
+
collect_note_ids_from_paragraphs(element.paragraphs, ref_attr, ids)
|
|
337
|
+
|
|
338
|
+
tables = element.tables
|
|
339
|
+
return unless tables
|
|
340
|
+
tables.each do |tbl|
|
|
341
|
+
tbl.rows.each do |row|
|
|
342
|
+
row.cells.each do |cell|
|
|
343
|
+
collect_note_ids_from_paragraphs(cell.paragraphs, ref_attr, ids)
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
def collect_note_ids_from_paragraphs(paragraphs, ref_attr, ids)
|
|
350
|
+
return unless paragraphs
|
|
351
|
+
paragraphs.each do |p|
|
|
352
|
+
(p.runs || []).each do |r|
|
|
353
|
+
ref = r.public_send(ref_attr)
|
|
354
|
+
ids << ref.id if ref&.id
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
def ensure_footnotes_part
|
|
360
|
+
return if package.footnotes
|
|
361
|
+
|
|
362
|
+
package.footnotes = minimal_footnotes
|
|
363
|
+
record_fix("R9", "Created footnotes.xml for orphaned references")
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
def ensure_endnotes_part
|
|
367
|
+
return if package.endnotes
|
|
368
|
+
|
|
369
|
+
package.endnotes = minimal_endnotes
|
|
370
|
+
record_fix("R9", "Created endnotes.xml for orphaned references")
|
|
371
|
+
end
|
|
372
|
+
|
|
218
373
|
# -- Group 2: Support parts (profile-dependent) --
|
|
219
374
|
|
|
220
375
|
def reconcile_theme
|
|
@@ -277,30 +277,15 @@ module Uniword
|
|
|
277
277
|
# @param document [Object] Document (OOXML or MHTML)
|
|
278
278
|
# @return [Hash] Statistics hash
|
|
279
279
|
def document_stats(document)
|
|
280
|
-
|
|
281
|
-
if document.is_a?(Uniword::Wordprocessingml::DocumentRoot) || document.is_a?(Uniword::Wordprocessingml::Body)
|
|
280
|
+
if document.is_a?(Uniword::Wordprocessingml::Body)
|
|
282
281
|
return {
|
|
283
282
|
paragraphs: document.paragraphs.count,
|
|
284
|
-
tables:
|
|
285
|
-
images:
|
|
283
|
+
tables: 0,
|
|
284
|
+
images: 0
|
|
286
285
|
}
|
|
287
286
|
end
|
|
288
287
|
|
|
289
|
-
|
|
290
|
-
html = if document.is_a?(Mhtml::Document) && document.raw_html
|
|
291
|
-
document.raw_html
|
|
292
|
-
elsif document.is_a?(Mhtml::Document) && document.html_content
|
|
293
|
-
document.html_content
|
|
294
|
-
end
|
|
295
|
-
if html
|
|
296
|
-
{
|
|
297
|
-
paragraphs: html.scan(/<p[\s>]/i).count,
|
|
298
|
-
tables: html.scan(/<table/i).count,
|
|
299
|
-
images: html.scan(/<img/i).count
|
|
300
|
-
}
|
|
301
|
-
else
|
|
302
|
-
{ paragraphs: 0, tables: 0, images: 0 }
|
|
303
|
-
end
|
|
288
|
+
document.document_stats
|
|
304
289
|
end
|
|
305
290
|
|
|
306
291
|
# Validate conversion parameters
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Uniword
|
|
4
|
+
# Tagging module for elements that track their position among sibling runs.
|
|
5
|
+
# Used by the MHTML renderer to interleave hyperlinks and math objects
|
|
6
|
+
# at the correct position within a paragraph.
|
|
7
|
+
module HasRunPosition
|
|
8
|
+
end
|
|
9
|
+
end
|
data/lib/uniword/lazy_loader.rb
CHANGED
data/lib/uniword/math/o_math.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "lutaml/model"
|
|
4
|
+
require_relative "../has_run_position"
|
|
4
5
|
|
|
5
6
|
module Uniword
|
|
6
7
|
module Math
|
|
@@ -9,6 +10,8 @@ module Uniword
|
|
|
9
10
|
# Generated from OOXML schema: math.yml
|
|
10
11
|
# Element: <m:oMath>
|
|
11
12
|
class OMath < Lutaml::Model::Serializable
|
|
13
|
+
include Uniword::HasRunPosition
|
|
14
|
+
|
|
12
15
|
# Pattern 0: Attributes BEFORE xml mappings
|
|
13
16
|
attribute :runs, MathRun, collection: true, initialize_empty: true
|
|
14
17
|
attribute :functions, Function, collection: true, initialize_empty: true
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
require "lutaml/model"
|
|
4
4
|
|
|
5
|
+
require_relative "../document_input"
|
|
6
|
+
|
|
5
7
|
module Uniword
|
|
6
8
|
module Mhtml
|
|
7
9
|
# MHTML Document — top-level model for .mht/.mhtml/.doc files.
|
|
@@ -17,6 +19,8 @@ module Uniword
|
|
|
17
19
|
# ├── word_document_settings (Metadata::WordDocumentSettings)
|
|
18
20
|
# └── filelist_xml (String)
|
|
19
21
|
class Document < Lutaml::Model::Serializable
|
|
22
|
+
include Uniword::DocumentInput
|
|
23
|
+
|
|
20
24
|
# MIME headers
|
|
21
25
|
attribute :mime_version, :string, default: -> { "1.0" }
|
|
22
26
|
attribute :boundary, :string
|
|
@@ -161,6 +165,20 @@ module Uniword
|
|
|
161
165
|
"#<#{self.class} parts=#{parts.length} images=#{image_parts.length} " \
|
|
162
166
|
"xml=#{xml_parts.length} theme=#{theme_part ? 'yes' : 'no'}>"
|
|
163
167
|
end
|
|
168
|
+
|
|
169
|
+
# @return [Hash] Document statistics (paragraphs, tables, images)
|
|
170
|
+
def document_stats
|
|
171
|
+
html = raw_html || html_content
|
|
172
|
+
if html
|
|
173
|
+
{
|
|
174
|
+
paragraphs: html.scan(/<p[\s>]/i).count,
|
|
175
|
+
tables: html.scan(/<table/i).count,
|
|
176
|
+
images: html.scan(/<img/i).count,
|
|
177
|
+
}
|
|
178
|
+
else
|
|
179
|
+
{ paragraphs: 0, tables: 0, images: 0 }
|
|
180
|
+
end
|
|
181
|
+
end
|
|
164
182
|
end
|
|
165
183
|
end
|
|
166
184
|
end
|