docxify 0.0.2 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +309 -0
- data/CHANGELOG.md +20 -0
- data/LICENSE.md +9 -0
- data/README.md +4 -5
- data/Rakefile +3 -3
- data/lib/docxify/container.rb +4 -1
- data/lib/docxify/document.rb +17 -16
- data/lib/docxify/element/base.rb +70 -0
- data/lib/docxify/element/divider.rb +18 -0
- data/lib/docxify/element/file.rb +46 -0
- data/lib/docxify/element/image.rb +88 -0
- data/lib/docxify/element/page_break.rb +16 -0
- data/lib/docxify/element/paragraph.rb +36 -9
- data/lib/docxify/element/table.rb +9 -0
- data/lib/docxify/template.rb +2 -0
- data/lib/docxify/version.rb +1 -1
- data/lib/docxify.rb +8 -7
- metadata +6 -4
- data/.standard.yml +0 -3
- data/lib/docxify/element/numbered_list_item.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19220bad643ba9281144f2af8122d7c3300befdef7ed3dff796b81ccb493850c
|
4
|
+
data.tar.gz: fd960d429aedf127bfdca4eaf1d7a2aeda5a7c18577081a9f280169ccc74c23e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ef5802312027442107a8541ab7e34be20b8309403c12506b2d48ae77eaeaeb3c2a19877a20ac54dbcc88af3a92869dbc4e718a7647b1abecfce677a05ace286
|
7
|
+
data.tar.gz: b79ab3fc2a484c4882a0330c8bc25471ecb5304e8efa9260de945cdce57cd2ec2dae71133adaf7a10cf385f72d02c8f4f9255e0025ce47a442ce752f674939ec
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,309 @@
|
|
1
|
+
AllCops:
|
2
|
+
SuggestExtensions: false
|
3
|
+
NewCops: enable
|
4
|
+
Exclude:
|
5
|
+
- 'Gemfile'
|
6
|
+
- 'Rakefile'
|
7
|
+
- 'spec/**/*.rb'
|
8
|
+
- 'vendor/**/*'
|
9
|
+
Style/FormatStringToken:
|
10
|
+
EnforcedStyle: unannotated
|
11
|
+
Style/FetchEnvVar:
|
12
|
+
Enabled: false
|
13
|
+
Style/StringChars:
|
14
|
+
Enabled: false
|
15
|
+
Naming/BlockForwarding:
|
16
|
+
EnforcedStyle: explicit
|
17
|
+
Metrics/ClassLength:
|
18
|
+
Enabled: false
|
19
|
+
Naming/MethodParameterName:
|
20
|
+
Enabled: false
|
21
|
+
Lint/SuppressedException:
|
22
|
+
Enabled: false
|
23
|
+
Metrics/ParameterLists:
|
24
|
+
Enabled: false
|
25
|
+
Metrics/BlockNesting:
|
26
|
+
Enabled: false
|
27
|
+
Metrics/BlockLength:
|
28
|
+
Enabled: false
|
29
|
+
Metrics/ModuleLength:
|
30
|
+
Enabled: false
|
31
|
+
Metrics/CyclomaticComplexity:
|
32
|
+
Enabled: false
|
33
|
+
Metrics/PerceivedComplexity:
|
34
|
+
Enabled: false
|
35
|
+
Metrics/MethodLength:
|
36
|
+
Enabled: false
|
37
|
+
Layout/HashAlignment:
|
38
|
+
Enabled: false
|
39
|
+
Layout/ArgumentAlignment:
|
40
|
+
Enabled: false
|
41
|
+
Layout/LineLength:
|
42
|
+
Enabled: false
|
43
|
+
Layout/SpaceAroundMethodCallOperator:
|
44
|
+
Enabled: true
|
45
|
+
Lint/RaiseException:
|
46
|
+
Enabled: true
|
47
|
+
Lint/StructNewOverride:
|
48
|
+
Enabled: true
|
49
|
+
Style/ExponentialNotation:
|
50
|
+
Enabled: true
|
51
|
+
Style/HashEachMethods:
|
52
|
+
Enabled: true
|
53
|
+
Style/Documentation:
|
54
|
+
Enabled: false
|
55
|
+
Bundler/OrderedGems:
|
56
|
+
Enabled: false
|
57
|
+
Style/FrozenStringLiteralComment:
|
58
|
+
Enabled: false
|
59
|
+
Style/TrailingCommaInHashLiteral:
|
60
|
+
Enabled: false
|
61
|
+
Layout/SpaceBeforeSemicolon:
|
62
|
+
Enabled: false
|
63
|
+
Style/ClassAndModuleChildren:
|
64
|
+
Enabled: false
|
65
|
+
Metrics/AbcSize:
|
66
|
+
Enabled: false
|
67
|
+
Lint/RescueException:
|
68
|
+
Enabled: false
|
69
|
+
Layout/MultilineMethodCallIndentation:
|
70
|
+
Enabled: false
|
71
|
+
|
72
|
+
# Prefer &&/|| over and/or.
|
73
|
+
Style/AndOr:
|
74
|
+
Enabled: true
|
75
|
+
|
76
|
+
Style/FormatString:
|
77
|
+
EnforcedStyle: percent
|
78
|
+
|
79
|
+
# Align `when` with `case`.
|
80
|
+
Layout/CaseIndentation:
|
81
|
+
Enabled: false
|
82
|
+
|
83
|
+
Layout/ClosingHeredocIndentation:
|
84
|
+
Enabled: true
|
85
|
+
|
86
|
+
# Align comments with method definitions.
|
87
|
+
Layout/CommentIndentation:
|
88
|
+
Enabled: true
|
89
|
+
|
90
|
+
Layout/ElseAlignment:
|
91
|
+
Enabled: true
|
92
|
+
|
93
|
+
Style/RedundantRegexpEscape:
|
94
|
+
Enabled: false
|
95
|
+
|
96
|
+
Style/RaiseArgs:
|
97
|
+
EnforcedStyle: compact
|
98
|
+
|
99
|
+
# Align `end` with the matching keyword or starting expression except for
|
100
|
+
# assignments, where it should be aligned with the LHS.
|
101
|
+
Layout/EndAlignment:
|
102
|
+
Enabled: true
|
103
|
+
EnforcedStyleAlignWith: variable
|
104
|
+
AutoCorrect: true
|
105
|
+
|
106
|
+
Layout/EmptyLineAfterMagicComment:
|
107
|
+
Enabled: true
|
108
|
+
|
109
|
+
Layout/EmptyLinesAroundAccessModifier:
|
110
|
+
Enabled: false
|
111
|
+
|
112
|
+
Layout/EmptyLinesAroundBlockBody:
|
113
|
+
Enabled: true
|
114
|
+
|
115
|
+
# In a regular class definition, no empty lines around the body.
|
116
|
+
Layout/EmptyLinesAroundClassBody:
|
117
|
+
Enabled: true
|
118
|
+
|
119
|
+
# In a regular method definition, no empty lines around the body.
|
120
|
+
Layout/EmptyLinesAroundMethodBody:
|
121
|
+
Enabled: true
|
122
|
+
|
123
|
+
# In a regular module definition, no empty lines around the body.
|
124
|
+
Layout/EmptyLinesAroundModuleBody:
|
125
|
+
Enabled: true
|
126
|
+
|
127
|
+
# Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
|
128
|
+
Style/HashSyntax:
|
129
|
+
Enabled: true
|
130
|
+
EnforcedShorthandSyntax: never
|
131
|
+
|
132
|
+
Layout/FirstArgumentIndentation:
|
133
|
+
Enabled: true
|
134
|
+
|
135
|
+
Style/RescueModifier:
|
136
|
+
Enabled: false
|
137
|
+
|
138
|
+
# Method definitions after `private` or `protected` isolated calls need one
|
139
|
+
# extra level of indentation.
|
140
|
+
Layout/IndentationConsistency:
|
141
|
+
Enabled: false
|
142
|
+
|
143
|
+
# Two spaces, no tabs (for indentation).
|
144
|
+
Layout/IndentationWidth:
|
145
|
+
Enabled: true
|
146
|
+
|
147
|
+
Layout/LeadingCommentSpace:
|
148
|
+
Enabled: true
|
149
|
+
|
150
|
+
Layout/SpaceAfterColon:
|
151
|
+
Enabled: true
|
152
|
+
|
153
|
+
Layout/SpaceAfterComma:
|
154
|
+
Enabled: true
|
155
|
+
|
156
|
+
Layout/SpaceAfterSemicolon:
|
157
|
+
Enabled: true
|
158
|
+
|
159
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
160
|
+
Enabled: true
|
161
|
+
|
162
|
+
Layout/SpaceAroundKeyword:
|
163
|
+
Enabled: true
|
164
|
+
|
165
|
+
Layout/SpaceBeforeComma:
|
166
|
+
Enabled: true
|
167
|
+
|
168
|
+
Layout/SpaceBeforeComment:
|
169
|
+
Enabled: true
|
170
|
+
|
171
|
+
Layout/SpaceBeforeFirstArg:
|
172
|
+
Enabled: true
|
173
|
+
|
174
|
+
Style/DefWithParentheses:
|
175
|
+
Enabled: true
|
176
|
+
|
177
|
+
Style/MethodDefParentheses:
|
178
|
+
Enabled: true
|
179
|
+
|
180
|
+
Style/RedundantFreeze:
|
181
|
+
Enabled: true
|
182
|
+
|
183
|
+
# Use `foo {}` not `foo{}`.
|
184
|
+
Layout/SpaceBeforeBlockBraces:
|
185
|
+
Enabled: true
|
186
|
+
|
187
|
+
# Use `foo { bar }` not `foo {bar}`.
|
188
|
+
Layout/SpaceInsideBlockBraces:
|
189
|
+
Enabled: true
|
190
|
+
EnforcedStyleForEmptyBraces: space
|
191
|
+
|
192
|
+
# Use `{ a: 1 }` not `{a:1}`.
|
193
|
+
Layout/SpaceInsideHashLiteralBraces:
|
194
|
+
Enabled: true
|
195
|
+
|
196
|
+
Layout/SpaceInsideParens:
|
197
|
+
Enabled: true
|
198
|
+
|
199
|
+
# Check quotes usage according to lint rule below.
|
200
|
+
Style/StringLiterals:
|
201
|
+
Enabled: true
|
202
|
+
EnforcedStyle: double_quotes
|
203
|
+
SupportedStyles:
|
204
|
+
- single_quotes
|
205
|
+
- double_quotes
|
206
|
+
|
207
|
+
Style/StringLiteralsInInterpolation:
|
208
|
+
Enabled: false
|
209
|
+
|
210
|
+
Style/HashLikeCase:
|
211
|
+
Enabled: false
|
212
|
+
|
213
|
+
Style/IfUnlessModifier:
|
214
|
+
Enabled: false
|
215
|
+
|
216
|
+
# Detect hard tabs, no hard tabs.
|
217
|
+
Layout/IndentationStyle:
|
218
|
+
Enabled: true
|
219
|
+
|
220
|
+
# Empty lines should not have any spaces.
|
221
|
+
Layout/TrailingEmptyLines:
|
222
|
+
Enabled: true
|
223
|
+
|
224
|
+
# No trailing whitespace.
|
225
|
+
Layout/TrailingWhitespace:
|
226
|
+
Enabled: true
|
227
|
+
|
228
|
+
# Use quotes for string literals when they are enough.
|
229
|
+
Style/RedundantPercentQ:
|
230
|
+
Enabled: true
|
231
|
+
|
232
|
+
Lint/AmbiguousOperator:
|
233
|
+
Enabled: true
|
234
|
+
|
235
|
+
Lint/AmbiguousRegexpLiteral:
|
236
|
+
Enabled: true
|
237
|
+
|
238
|
+
Lint/ErbNewArguments:
|
239
|
+
Enabled: true
|
240
|
+
|
241
|
+
Lint/ParenthesesAsGroupedExpression:
|
242
|
+
Enabled: false
|
243
|
+
|
244
|
+
# Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
|
245
|
+
Lint/RequireParentheses:
|
246
|
+
Enabled: true
|
247
|
+
|
248
|
+
Lint/ShadowingOuterLocalVariable:
|
249
|
+
Enabled: true
|
250
|
+
|
251
|
+
Lint/RedundantStringCoercion:
|
252
|
+
Enabled: true
|
253
|
+
|
254
|
+
Lint/UriEscapeUnescape:
|
255
|
+
Enabled: true
|
256
|
+
|
257
|
+
Lint/UselessAssignment:
|
258
|
+
Enabled: true
|
259
|
+
|
260
|
+
Lint/DeprecatedClassMethods:
|
261
|
+
Enabled: true
|
262
|
+
|
263
|
+
Style/GuardClause:
|
264
|
+
Enabled: false
|
265
|
+
|
266
|
+
Style/ParenthesesAroundCondition:
|
267
|
+
Enabled: true
|
268
|
+
|
269
|
+
Style/HashTransformKeys:
|
270
|
+
Enabled: true
|
271
|
+
|
272
|
+
Style/HashTransformValues:
|
273
|
+
Enabled: true
|
274
|
+
|
275
|
+
Style/RedundantBegin:
|
276
|
+
Enabled: true
|
277
|
+
|
278
|
+
Style/RedundantReturn:
|
279
|
+
Enabled: true
|
280
|
+
AllowMultipleReturnValues: true
|
281
|
+
|
282
|
+
Style/Semicolon:
|
283
|
+
Enabled: true
|
284
|
+
AllowAsExpressionSeparator: true
|
285
|
+
|
286
|
+
# Prefer Foo.method over Foo::method
|
287
|
+
Style/ColonMethodCall:
|
288
|
+
Enabled: true
|
289
|
+
|
290
|
+
Style/TrivialAccessors:
|
291
|
+
Enabled: true
|
292
|
+
|
293
|
+
Style/BarePercentLiterals:
|
294
|
+
Enabled: false
|
295
|
+
|
296
|
+
Style/IfInsideElse:
|
297
|
+
Enabled: false
|
298
|
+
|
299
|
+
Style/RegexpLiteral:
|
300
|
+
Enabled: false
|
301
|
+
|
302
|
+
Style/ParallelAssignment:
|
303
|
+
Enabled: false
|
304
|
+
|
305
|
+
Style/RedundantParentheses:
|
306
|
+
Enabled: false
|
307
|
+
|
308
|
+
Layout/FirstHashElementIndentation:
|
309
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 0.0.5
|
4
|
+
|
5
|
+
Features:
|
6
|
+
|
7
|
+
- Paragraph font name, size, colour and yellow highlight done
|
8
|
+
- Document level default font name, size and colour done
|
9
|
+
|
10
|
+
## 0.0.4
|
11
|
+
|
12
|
+
Features:
|
13
|
+
|
14
|
+
- Image insertion is working
|
15
|
+
|
16
|
+
## 0.0.3
|
17
|
+
|
18
|
+
Features:
|
19
|
+
|
20
|
+
- Dividers and page breaks implemented
|
21
|
+
- Simple HTML parsing (for paragraphs) implemented
|
22
|
+
|
3
23
|
## 0.0.2
|
4
24
|
|
5
25
|
Features:
|
data/LICENSE.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# MIT License
|
2
|
+
|
3
|
+
Copyright ©️2024 FounderCatalyst IP Ltd
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -25,17 +25,16 @@ gem install docxify
|
|
25
25
|
|
26
26
|
@docx.add_paragraph "Title", font: "Something", size: 18, color: "#00000"
|
27
27
|
@docx.add_paragraph "Body copy"
|
28
|
-
@docx.add_paragraph "This is <b>bold</b>, <i>Italic</i> and <u>Underlined</u>.
|
28
|
+
@docx.add_paragraph "This is <b>bold</b>, <i>Italic</i> and <u>Underlined</u>."
|
29
|
+
@docx.add_paragraph "Text can also contain <a href='foo'>Links</a>."
|
29
30
|
@docx.add_paragraph "Centred text", align: :center
|
30
31
|
@docx.add_paragraph "Highlighted text", background: "#FFFF99"
|
31
|
-
@docx.add_paragraph "This
|
32
|
+
@docx.add_paragraph "This won't show as <b>bold</b>", inline_styling: false
|
32
33
|
|
33
|
-
@docx.add_paragraph "
|
34
|
+
@docx.add_paragraph "\t1.1.1\tBody copy", tab_stops_cm: [1, 2]
|
34
35
|
@docx.add_paragraph "{CHECKBOX_EMPTY}\tEmpty checkbox", tab_stops_cm: [2]
|
35
36
|
@docx.add_paragraph "{CHECKBOX_CHECKED}\tChecked checkbox", tab_stops_cm: [2]
|
36
37
|
|
37
|
-
@docx.add_numbered_list_item "This is a list item", level: 0
|
38
|
-
|
39
38
|
@docx.add_page_break
|
40
39
|
@docx.add_divider
|
41
40
|
|
data/Rakefile
CHANGED
data/lib/docxify/container.rb
CHANGED
@@ -36,9 +36,12 @@ module DocXify
|
|
36
36
|
zip.put_next_entry "word/document.xml"
|
37
37
|
zip.write document.build_xml(self)
|
38
38
|
|
39
|
+
zip.put_next_entry "word/_rels/document.xml.rels"
|
40
|
+
zip.write document_xml_rels
|
41
|
+
|
39
42
|
@document.images.each do |image|
|
40
43
|
zip.put_next_entry "word/media/#{image.filename}"
|
41
|
-
zip.write image.
|
44
|
+
zip.write image.data
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
data/lib/docxify/document.rb
CHANGED
@@ -12,7 +12,7 @@ module DocXify
|
|
12
12
|
@size = options[:size] || 12
|
13
13
|
@color = options[:color] || 12
|
14
14
|
@background = options[:background] if options[:background]
|
15
|
-
@margins = {top: 2, bottom: 2, left: 2, right: 2}
|
15
|
+
@margins = { top: 2, bottom: 2, left: 2, right: 2 }
|
16
16
|
end
|
17
17
|
|
18
18
|
def default_styling(options = {})
|
@@ -37,7 +37,7 @@ module DocXify
|
|
37
37
|
def build_xml(container)
|
38
38
|
xml = <<~XML
|
39
39
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
40
|
-
<w:document mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
|
40
|
+
<w:document mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
|
41
41
|
<w:body>
|
42
42
|
XML
|
43
43
|
|
@@ -64,34 +64,35 @@ module DocXify
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def add_image(file_path_or_data, options = {})
|
67
|
-
file = DocXify::Element::File
|
68
|
-
|
69
|
-
|
67
|
+
file = if file_path_or_data.is_a?(DocXify::Element::File)
|
68
|
+
file_path_or_data
|
69
|
+
else
|
70
|
+
add_file(file_path_or_data)
|
71
|
+
end
|
72
|
+
add DocXify::Element::Image.new(file, options)
|
70
73
|
end
|
71
74
|
|
72
|
-
def
|
73
|
-
|
75
|
+
def add_file(file_path_or_data)
|
76
|
+
file = DocXify::Element::File.new(file_path_or_data)
|
77
|
+
@images << file
|
78
|
+
file
|
74
79
|
end
|
75
80
|
|
76
81
|
def add_page_break
|
77
|
-
add DocXify::Element::PageBreak.new
|
82
|
+
add DocXify::Element::PageBreak.new
|
78
83
|
end
|
79
84
|
|
80
85
|
def add_divider
|
81
|
-
add DocXify::Element::Divider.new
|
86
|
+
add DocXify::Element::Divider.new
|
82
87
|
end
|
83
88
|
|
84
89
|
def add_paragraph(text, options = {})
|
85
|
-
|
90
|
+
options[:document] = self
|
91
|
+
add DocXify::Element::Paragraph.new(text, options)
|
86
92
|
end
|
87
93
|
|
88
94
|
def add_table(headers, rows, options = {})
|
89
|
-
add DocXify::Element::Table.new(
|
95
|
+
add DocXify::Element::Table.new(headers, rows, options)
|
90
96
|
end
|
91
|
-
|
92
|
-
# MARK: Private
|
93
|
-
|
94
|
-
private
|
95
|
-
|
96
97
|
end
|
97
98
|
end
|
data/lib/docxify/element/base.rb
CHANGED
@@ -4,6 +4,76 @@ module DocXify
|
|
4
4
|
def to_s(container = nil)
|
5
5
|
raise NotImplementedError
|
6
6
|
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def parse_simple_html(html)
|
11
|
+
state = :text
|
12
|
+
tag = ""
|
13
|
+
content = ""
|
14
|
+
result = []
|
15
|
+
text = ""
|
16
|
+
last_char = ""
|
17
|
+
|
18
|
+
html.each_char do |char|
|
19
|
+
# puts "State: #{state}, Char: #{char}, Tag: #{tag}, Content: #{content}, Text: #{text}"
|
20
|
+
case state
|
21
|
+
when :text # This is a text node, not part of an HTML tag
|
22
|
+
if char == "<"
|
23
|
+
state = :tag
|
24
|
+
tag = ""
|
25
|
+
result << text.strip unless text.strip.empty?
|
26
|
+
text = ""
|
27
|
+
else
|
28
|
+
text << char
|
29
|
+
end
|
30
|
+
when :tag # Within an HTML tag itself
|
31
|
+
if char == ">"
|
32
|
+
state = :content
|
33
|
+
content = ""
|
34
|
+
tag_name, *attributes = tag.split
|
35
|
+
tag_name.gsub!(/\s*\//, "")
|
36
|
+
attributes.delete_if { |attr| attr == "/" }
|
37
|
+
if attributes.any?
|
38
|
+
attrs = {}
|
39
|
+
attributes.each do |attribute|
|
40
|
+
name, value = attribute.split("=")
|
41
|
+
value = value.to_s[1..-2] if value
|
42
|
+
attrs[name.to_sym] = value
|
43
|
+
end
|
44
|
+
result << { tag: tag_name, attributes: attrs, content: "" }
|
45
|
+
else
|
46
|
+
result << { tag: tag_name, content: "" }
|
47
|
+
end
|
48
|
+
|
49
|
+
if last_char == "/"
|
50
|
+
state = :text
|
51
|
+
end
|
52
|
+
elsif char == "/" && last_char == "<"
|
53
|
+
state = :closing_tag
|
54
|
+
else
|
55
|
+
tag << char
|
56
|
+
end
|
57
|
+
when :closing_tag
|
58
|
+
if char == ">"
|
59
|
+
state = :text
|
60
|
+
end
|
61
|
+
when :content # With the content of an HTML tag
|
62
|
+
if char == "<"
|
63
|
+
state = :tag
|
64
|
+
result.last[:content] = content.strip
|
65
|
+
content = ""
|
66
|
+
else
|
67
|
+
content << char
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
last_char = char
|
72
|
+
end
|
73
|
+
|
74
|
+
result << text.strip unless text.strip.empty?
|
75
|
+
result
|
76
|
+
end
|
7
77
|
end
|
8
78
|
end
|
9
79
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module DocXify
|
2
|
+
module Element
|
3
|
+
class Divider < Base
|
4
|
+
def to_s(_container = nil)
|
5
|
+
<<~XML
|
6
|
+
<w:p>
|
7
|
+
<w:pPr>
|
8
|
+
<w:pBdr>
|
9
|
+
<w:bottom w:color="auto" w:space="1" w:sz="6" w:val="single"/>
|
10
|
+
</w:pBdr>
|
11
|
+
</w:pPr>
|
12
|
+
</w:p>
|
13
|
+
<w:p/>
|
14
|
+
XML
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "digest/sha1"
|
2
|
+
|
3
|
+
module DocXify
|
4
|
+
module Element
|
5
|
+
class File < Base
|
6
|
+
PNG_SIGNATURE = "\x89PNG\r\n\u001A\n".b.freeze
|
7
|
+
JPEG_START = "\xFF\xD8".b.freeze
|
8
|
+
JPEG_END = "\xFF\xD9".b.freeze
|
9
|
+
|
10
|
+
attr_accessor :data, :filename
|
11
|
+
|
12
|
+
def initialize(file_path_or_data)
|
13
|
+
super()
|
14
|
+
load_file_data(file_path_or_data)
|
15
|
+
end
|
16
|
+
|
17
|
+
def load_file_data(file_path_or_data)
|
18
|
+
if contains_png_image?(file_path_or_data)
|
19
|
+
@data = file_path_or_data
|
20
|
+
@filename = "#{Digest::SHA1.hexdigest(@data)}.png"
|
21
|
+
elsif contains_jpeg_image?(file_path_or_data)
|
22
|
+
@data = file_path_or_data
|
23
|
+
@filename = "#{Digest::SHA1.hexdigest(@data)}.jpg"
|
24
|
+
elsif ::File.exist?(file_path_or_data)
|
25
|
+
@filename = ::File.basename(file_path_or_data)
|
26
|
+
@data = ::File.read(file_path_or_data, mode: "rb")
|
27
|
+
raise ArgumentError.new("Unsupported file type - images must be PNG or JPEG") unless contains_png_image?(@data) || contains_jpeg_image?(@data)
|
28
|
+
else
|
29
|
+
raise ArgumentError.new("Unsupported file type - images must be PNG or JPEG")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def reference
|
34
|
+
"image-#{Digest::SHA1.hexdigest(@data)[0, 8]}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def contains_png_image?(data)
|
38
|
+
data[0, 8] == PNG_SIGNATURE
|
39
|
+
end
|
40
|
+
|
41
|
+
def contains_jpeg_image?(data)
|
42
|
+
data[0..1] == JPEG_START && data[-2..] == JPEG_END
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module DocXify
|
2
|
+
module Element
|
3
|
+
class Image < Base
|
4
|
+
attr_accessor :file, :align, :height_cm, :width_cm
|
5
|
+
|
6
|
+
def initialize(file, options = {})
|
7
|
+
super()
|
8
|
+
@file = file
|
9
|
+
|
10
|
+
@align = options[:align] || :left
|
11
|
+
@height_cm = options[:height_cm] || 5
|
12
|
+
@width_cm = options[:width_cm] || 5
|
13
|
+
end
|
14
|
+
|
15
|
+
def id
|
16
|
+
rand(1_000_000_000)
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s(_container = nil)
|
20
|
+
xml = "<w:p>"
|
21
|
+
|
22
|
+
if @align == :right
|
23
|
+
xml << <<~XML
|
24
|
+
<w:pPr>
|
25
|
+
<w:jc w:val="right"/>
|
26
|
+
</w:pPr>
|
27
|
+
XML
|
28
|
+
elsif @align == :center
|
29
|
+
xml << <<~XML
|
30
|
+
<w:pPr>
|
31
|
+
<w:jc w:val="center"/>
|
32
|
+
</w:pPr>
|
33
|
+
XML
|
34
|
+
end
|
35
|
+
|
36
|
+
xml << <<~XML
|
37
|
+
<w:r>
|
38
|
+
<w:rPr>
|
39
|
+
<w:noProof/>
|
40
|
+
</w:rPr>
|
41
|
+
<w:drawing>
|
42
|
+
<wp:inline distB="0" distL="0" distR="0" distT="0">
|
43
|
+
<wp:extent cx="#{DocXify.cm2emu(@width_cm)}" cy="#{DocXify.cm2emu(@height_cm)}"/>
|
44
|
+
<wp:effectExtent b="0" l="0" r="0" t="0"/>
|
45
|
+
<wp:docPr id="#{id}" name="Picture 1"/>
|
46
|
+
<wp:cNvGraphicFramePr>
|
47
|
+
<a:graphicFrameLocks noChangeAspect="1" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"/>
|
48
|
+
</wp:cNvGraphicFramePr>
|
49
|
+
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
|
50
|
+
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
|
51
|
+
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
|
52
|
+
<pic:nvPicPr>
|
53
|
+
<pic:cNvPr id="#{id}" name="Picture #{id}"/>
|
54
|
+
<pic:cNvPicPr/>
|
55
|
+
</pic:nvPicPr>
|
56
|
+
<pic:blipFill>
|
57
|
+
<a:blip cstate="print" r:embed="#{@file.reference}">
|
58
|
+
<a:extLst>
|
59
|
+
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
|
60
|
+
<a14:useLocalDpi val="0" xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main"/>
|
61
|
+
</a:ext>
|
62
|
+
</a:extLst>
|
63
|
+
</a:blip>
|
64
|
+
<a:stretch>
|
65
|
+
<a:fillRect/>
|
66
|
+
</a:stretch>
|
67
|
+
</pic:blipFill>
|
68
|
+
<pic:spPr>
|
69
|
+
<a:xfrm>
|
70
|
+
<a:off x="0" y="0"/>
|
71
|
+
<a:ext cx="#{DocXify.cm2emu(@width_cm)}" cy="#{DocXify.cm2emu(@height_cm)}"/>
|
72
|
+
</a:xfrm>
|
73
|
+
<a:prstGeom prst="rect">
|
74
|
+
<a:avLst/>
|
75
|
+
</a:prstGeom>
|
76
|
+
</pic:spPr>
|
77
|
+
</pic:pic>
|
78
|
+
</a:graphicData>
|
79
|
+
</a:graphic>
|
80
|
+
</wp:inline>
|
81
|
+
</w:drawing>
|
82
|
+
</w:r>
|
83
|
+
</w:p>
|
84
|
+
XML
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -3,22 +3,49 @@ module DocXify
|
|
3
3
|
class Paragraph < Base
|
4
4
|
attr_accessor :text, :font, :size, :color, :background, :align, :inline_styling, :tab_stops_cm
|
5
5
|
|
6
|
-
def initialize(
|
7
|
-
|
6
|
+
def initialize(text, options = {})
|
7
|
+
super()
|
8
|
+
@document = options[:document]
|
8
9
|
@text = text
|
9
|
-
@font = options[:font] || document
|
10
|
-
@size = options[:size] || document
|
11
|
-
@color = options[:color] || document
|
10
|
+
@font = options[:font] || @document&.font || "Times New Roman"
|
11
|
+
@size = options[:size] || @document&.size || 14
|
12
|
+
@color = options[:color] || @document&.color || "#000000"
|
13
|
+
@highlight = options[:highlight] || false
|
12
14
|
@background = options[:background] if options[:background]
|
13
|
-
@background ||= document
|
15
|
+
@background ||= @document&.background if @document&.background
|
14
16
|
@align = options[:align] || :left
|
15
17
|
@inline_styling = options[:inline_styling] || true
|
16
18
|
@tab_stops_cm = options[:tab_stops_cm] || []
|
17
19
|
end
|
18
20
|
|
19
|
-
def to_s(
|
20
|
-
|
21
|
-
|
21
|
+
def to_s(_container = nil)
|
22
|
+
nodes = if @inline_styling
|
23
|
+
parse_simple_html(@text)
|
24
|
+
else
|
25
|
+
[@text]
|
26
|
+
end
|
27
|
+
|
28
|
+
xml = "<w:p>"
|
29
|
+
xml << <<~XML
|
30
|
+
<w:pPr>
|
31
|
+
<w:jc w:val="#{@align}"/>
|
32
|
+
</w:pPr>
|
33
|
+
XML
|
34
|
+
xml << "<w:r>"
|
35
|
+
xml << <<~XML
|
36
|
+
<w:rPr>
|
37
|
+
<w:rFonts w:ascii="#{@font}" w:cs="#{@font}" w:hAnsi="#{@font}"/>
|
38
|
+
<w:color w:val="#{@color.gsub("#", "")}"/>
|
39
|
+
<w:sz w:val="#{DocXify.pt2halfpt(@size)}"/>
|
40
|
+
<w:szCs w:val="#{DocXify.pt2halfpt(@size)}"/>
|
41
|
+
#{"<w:highlight w:val=\"yellow\"/>" if @highlight}
|
42
|
+
</w:rPr>
|
43
|
+
XML
|
44
|
+
|
45
|
+
nodes.each do |node|
|
46
|
+
xml << "<w:t xml:space=\"preserve\">#{node}</w:t>"
|
47
|
+
end
|
48
|
+
xml << "</w:r></w:p>"
|
22
49
|
end
|
23
50
|
end
|
24
51
|
end
|
data/lib/docxify/template.rb
CHANGED
@@ -15,6 +15,8 @@ module DocXify
|
|
15
15
|
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
16
16
|
<Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/>
|
17
17
|
<Default ContentType="application/xml" Extension="xml"/>
|
18
|
+
<Default ContentType="image/png" Extension="png"/>
|
19
|
+
<Default ContentType="image/jpeg" Extension="jpg"/>
|
18
20
|
<Override ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" PartName="/word/document.xml"/>
|
19
21
|
<Override ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" PartName="/word/styles.xml"/>
|
20
22
|
<Override ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml" PartName="/word/settings.xml"/>
|
data/lib/docxify/version.rb
CHANGED
data/lib/docxify.rb
CHANGED
@@ -2,10 +2,11 @@ require_relative "docxify/version"
|
|
2
2
|
require_relative "docxify/document"
|
3
3
|
require_relative "docxify/container"
|
4
4
|
require_relative "docxify/template"
|
5
|
+
|
5
6
|
require_relative "docxify/element/base"
|
6
7
|
require_relative "docxify/element/divider"
|
8
|
+
require_relative "docxify/element/file"
|
7
9
|
require_relative "docxify/element/image"
|
8
|
-
require_relative "docxify/element/numbered_list_item"
|
9
10
|
require_relative "docxify/element/page_break"
|
10
11
|
require_relative "docxify/element/paragraph"
|
11
12
|
require_relative "docxify/element/table"
|
@@ -22,24 +23,24 @@ module DocXify
|
|
22
23
|
# Used for most sizes
|
23
24
|
def self.cm2dxa(value)
|
24
25
|
value = value.to_f
|
25
|
-
raise ArgumentError
|
26
|
+
raise ArgumentError.new("Value must be greater than or equal to 0") if value.negative?
|
26
27
|
|
27
|
-
value * UNITS_PER_CM
|
28
|
+
(value * UNITS_PER_CM).to_i
|
28
29
|
end
|
29
30
|
|
30
31
|
# Used for font sizes
|
31
32
|
def self.pt2halfpt(value)
|
32
33
|
value = value.to_f
|
33
|
-
raise ArgumentError
|
34
|
+
raise ArgumentError.new("Value must be greater than or equal to 0") if value.negative?
|
34
35
|
|
35
|
-
value * 2
|
36
|
+
(value * 2).to_i
|
36
37
|
end
|
37
38
|
|
38
39
|
# Used for image sizes
|
39
40
|
def self.cm2emu(value)
|
40
41
|
value = value.to_f
|
41
|
-
raise ArgumentError
|
42
|
+
raise ArgumentError.new("Value must be greater than or equal to 0") if value.negative?
|
42
43
|
|
43
|
-
value *
|
44
|
+
(value * 360_000).to_i
|
44
45
|
end
|
45
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: docxify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Jeffries
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -33,8 +33,9 @@ extensions: []
|
|
33
33
|
extra_rdoc_files: []
|
34
34
|
files:
|
35
35
|
- ".rspec"
|
36
|
-
- ".
|
36
|
+
- ".rubocop.yml"
|
37
37
|
- CHANGELOG.md
|
38
|
+
- LICENSE.md
|
38
39
|
- README.md
|
39
40
|
- Rakefile
|
40
41
|
- lib/docxify.rb
|
@@ -42,8 +43,8 @@ files:
|
|
42
43
|
- lib/docxify/document.rb
|
43
44
|
- lib/docxify/element/base.rb
|
44
45
|
- lib/docxify/element/divider.rb
|
46
|
+
- lib/docxify/element/file.rb
|
45
47
|
- lib/docxify/element/image.rb
|
46
|
-
- lib/docxify/element/numbered_list_item.rb
|
47
48
|
- lib/docxify/element/page_break.rb
|
48
49
|
- lib/docxify/element/paragraph.rb
|
49
50
|
- lib/docxify/element/table.rb
|
@@ -55,6 +56,7 @@ metadata:
|
|
55
56
|
homepage_uri: https://github.com/foundercatalyst/docxify
|
56
57
|
source_code_uri: https://github.com/foundercatalyst/docxify
|
57
58
|
changelog_uri: https://github.com/foundercatalyst/docxify/CHANGELOG.md
|
59
|
+
rubygems_mfa_required: 'true'
|
58
60
|
post_install_message:
|
59
61
|
rdoc_options: []
|
60
62
|
require_paths:
|
data/.standard.yml
DELETED
File without changes
|