docxify 0.1.7 → 0.1.9
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/CHANGELOG.md +16 -0
- data/README.md +1 -1
- data/lib/docxify/container.rb +23 -29
- data/lib/docxify/document.rb +1 -1
- data/lib/docxify/element/base.rb +7 -7
- data/lib/docxify/element/image.rb +1 -1
- data/lib/docxify/element/paragraph.rb +1 -1
- data/lib/docxify/element/table.rb +4 -4
- data/lib/docxify/element/table_cell.rb +6 -2
- data/lib/docxify/version.rb +1 -1
- metadata +5 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4756efeceb4cb1e99069cfe5f5a9a4c85bcb68b34338ef069f8abb156cd31c03
|
|
4
|
+
data.tar.gz: 0b0e85411642bd9fe5389718d28ba47c2d4916c705dd0417b183cf95ad6d8d0f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 69ca0622fba668674c8eb5d5de5f731dd165d9ad6f46b68ee1657990c9e991bcce426a7d5a3b585ec81c0583b24eeb9028571b9741dc24ba6a6e7a916717fd41
|
|
7
|
+
data.tar.gz: 6ddbdb78177426c2e34b9381b9cbbb361eecbf9654333753069c9e394385afd69eb4dd5d2de86762f8c1478ea14cc40a93b1d0d47f75952ce18297b5d5e11870
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 0.1.9
|
|
4
|
+
|
|
5
|
+
Security:
|
|
6
|
+
|
|
7
|
+
- Require rubyzip 3.6+ (`~> 3.6`), fixing CVE-2026-85396 (path traversal in `Zip::Entry#extract` before rubyzip 3.4.0)
|
|
8
|
+
|
|
9
|
+
Bugfix:
|
|
10
|
+
|
|
11
|
+
- Entry sizes are now declared up front when writing the docx package, so rubyzip 3 no longer adds ZIP64 headers (version needed to extract 4.5) that OPC readers such as Word and Google Docs reject
|
|
12
|
+
|
|
13
|
+
## 0.1.8
|
|
14
|
+
|
|
15
|
+
Bugfix:
|
|
16
|
+
|
|
17
|
+
- Fix FrozenError when used with `--enable=frozen-string-literal` (RUBYOPT); all mutable string accumulators now initialised with `+""` or `+<<~HEREDOC`
|
|
18
|
+
|
|
3
19
|
## 0.1.7
|
|
4
20
|
|
|
5
21
|
Feature:
|
data/README.md
CHANGED
|
@@ -31,7 +31,7 @@ gem install docxify
|
|
|
31
31
|
@docx.add_paragraph "Highlighted text", background: "#FFFF99"
|
|
32
32
|
@docx.add_paragraph "This won't show as <b>bold</b>", inline_styling: false
|
|
33
33
|
|
|
34
|
-
@docx.add_paragraph "\t1.1.1\tBody copy", tab_stops_cm: [1, 2]
|
|
34
|
+
@docx.add_paragraph "\t1.1.1\tBody copy", tab_stops_cm: [1, 2], hanging_cm: 2
|
|
35
35
|
@docx.add_paragraph "{CHECKBOX_EMPTY}\tEmpty checkbox", tab_stops_cm: [2]
|
|
36
36
|
@docx.add_paragraph "{CHECKBOX_CHECKED}\tChecked checkbox", tab_stops_cm: [2]
|
|
37
37
|
|
data/lib/docxify/container.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require "tempfile"
|
|
1
2
|
require "zip"
|
|
2
3
|
|
|
3
4
|
module DocXify
|
|
@@ -12,37 +13,19 @@ module DocXify
|
|
|
12
13
|
temp_file = Tempfile.new("docxify.zip")
|
|
13
14
|
|
|
14
15
|
Zip::OutputStream.open(temp_file) do |zip|
|
|
15
|
-
zip
|
|
16
|
-
zip.
|
|
17
|
-
|
|
18
|
-
zip
|
|
19
|
-
zip.
|
|
20
|
-
|
|
21
|
-
zip
|
|
22
|
-
zip.
|
|
23
|
-
|
|
24
|
-
zip.put_next_entry "word/fontTable.xml"
|
|
25
|
-
zip.write DocXify::Template.font_table
|
|
26
|
-
|
|
27
|
-
zip.put_next_entry "word/settings.xml"
|
|
28
|
-
zip.write DocXify::Template.settings
|
|
29
|
-
|
|
30
|
-
zip.put_next_entry "word/styles.xml"
|
|
31
|
-
zip.write DocXify::Template.styles
|
|
32
|
-
|
|
33
|
-
zip.put_next_entry "word/webSettings.xml"
|
|
34
|
-
zip.write DocXify::Template.web_settings
|
|
35
|
-
|
|
36
|
-
zip.put_next_entry "word/document.xml"
|
|
37
|
-
zip.write document.build_xml(self)
|
|
38
|
-
|
|
39
|
-
zip.put_next_entry "word/_rels/document.xml.rels"
|
|
40
|
-
zip.write document_xml_rels
|
|
16
|
+
write_entry zip, "_rels/.rels", DocXify::Template.top_level_rels
|
|
17
|
+
write_entry zip, "[Content_Types].xml", DocXify::Template.content_types
|
|
18
|
+
write_entry zip, "word/theme/theme1.xml", DocXify::Template.theme
|
|
19
|
+
write_entry zip, "word/fontTable.xml", DocXify::Template.font_table
|
|
20
|
+
write_entry zip, "word/settings.xml", DocXify::Template.settings
|
|
21
|
+
write_entry zip, "word/styles.xml", DocXify::Template.styles
|
|
22
|
+
write_entry zip, "word/webSettings.xml", DocXify::Template.web_settings
|
|
23
|
+
write_entry zip, "word/document.xml", document.build_xml(self)
|
|
24
|
+
write_entry zip, "word/_rels/document.xml.rels", document_xml_rels
|
|
41
25
|
|
|
42
26
|
@document.relationships.each do |relation|
|
|
43
27
|
if relation.is_a?(DocXify::Element::File)
|
|
44
|
-
zip
|
|
45
|
-
zip.write relation.data
|
|
28
|
+
write_entry zip, "word/media/#{relation.filename}", relation.data
|
|
46
29
|
end
|
|
47
30
|
end
|
|
48
31
|
end
|
|
@@ -56,7 +39,7 @@ module DocXify
|
|
|
56
39
|
end
|
|
57
40
|
|
|
58
41
|
def document_xml_rels
|
|
59
|
-
xml =
|
|
42
|
+
xml = +<<~XML
|
|
60
43
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
61
44
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
62
45
|
<Relationship Id="rId3" Target="webSettings.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings"/>
|
|
@@ -73,5 +56,16 @@ module DocXify
|
|
|
73
56
|
xml << "</Relationships>"
|
|
74
57
|
xml
|
|
75
58
|
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
# Word and other OPC readers reject Zip64 headers. Since rubyzip 3 defaults
|
|
63
|
+
# to Zip64 for any entry whose size is unknown while its local header is
|
|
64
|
+
# streamed out, declare the size up front (all entry data is already in
|
|
65
|
+
# memory) so entries stay in the classic zip format.
|
|
66
|
+
def write_entry(zip, name, data)
|
|
67
|
+
zip.put_next_entry Zip::Entry.new(nil, name, size: data.bytesize)
|
|
68
|
+
zip.write data
|
|
69
|
+
end
|
|
76
70
|
end
|
|
77
71
|
end
|
data/lib/docxify/document.rb
CHANGED
|
@@ -44,7 +44,7 @@ module DocXify
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def build_xml(container)
|
|
47
|
-
xml =
|
|
47
|
+
xml = +<<~XML
|
|
48
48
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
49
49
|
<w:document mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16du 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:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du" 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">
|
|
50
50
|
<w:body>
|
data/lib/docxify/element/base.rb
CHANGED
|
@@ -9,10 +9,10 @@ module DocXify
|
|
|
9
9
|
|
|
10
10
|
def parse_simple_html(html)
|
|
11
11
|
state = :text
|
|
12
|
-
tag = ""
|
|
13
|
-
content = ""
|
|
12
|
+
tag = +""
|
|
13
|
+
content = +""
|
|
14
14
|
result = []
|
|
15
|
-
text = ""
|
|
15
|
+
text = +""
|
|
16
16
|
last_char = ""
|
|
17
17
|
|
|
18
18
|
html.each_char do |char|
|
|
@@ -21,16 +21,16 @@ module DocXify
|
|
|
21
21
|
when :text # This is a text node, not part of an HTML tag
|
|
22
22
|
if char == "<"
|
|
23
23
|
state = :tag
|
|
24
|
-
tag = ""
|
|
24
|
+
tag = +""
|
|
25
25
|
result << text unless text.empty?
|
|
26
|
-
text = ""
|
|
26
|
+
text = +""
|
|
27
27
|
else
|
|
28
28
|
text << char
|
|
29
29
|
end
|
|
30
30
|
when :tag # Within an HTML tag itself
|
|
31
31
|
if char == ">"
|
|
32
32
|
state = :content
|
|
33
|
-
content = ""
|
|
33
|
+
content = +""
|
|
34
34
|
tag_name, *attributes = tag.split
|
|
35
35
|
tag_name.gsub!(/\s*\//, "")
|
|
36
36
|
attributes.delete_if { |attr| attr == "/" }
|
|
@@ -62,7 +62,7 @@ module DocXify
|
|
|
62
62
|
if char == "<"
|
|
63
63
|
state = :tag
|
|
64
64
|
result.last[:content] = content
|
|
65
|
-
content = ""
|
|
65
|
+
content = +""
|
|
66
66
|
else
|
|
67
67
|
content << char
|
|
68
68
|
end
|
|
@@ -28,7 +28,7 @@ module DocXify
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def to_s(_container = nil)
|
|
31
|
-
xml = ""
|
|
31
|
+
xml = +""
|
|
32
32
|
xml << table_element_start
|
|
33
33
|
xml << table_properties
|
|
34
34
|
xml << table_grid
|
|
@@ -44,7 +44,7 @@ module DocXify
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def table_properties
|
|
47
|
-
xml = ""
|
|
47
|
+
xml = +""
|
|
48
48
|
xml << "<w:tblPr>"
|
|
49
49
|
xml << '<w:tblStyle w:val="TableGrid"/>'
|
|
50
50
|
xml << '<w:tblW w:type="auto" w:w="0"/>'
|
|
@@ -63,7 +63,7 @@ module DocXify
|
|
|
63
63
|
default_equal_width = (@document.width / @rows.first.size).to_i
|
|
64
64
|
|
|
65
65
|
@column_widths = []
|
|
66
|
-
xml = "<w:tblGrid>"
|
|
66
|
+
xml = +"<w:tblGrid>"
|
|
67
67
|
@rows.first.each do |cell|
|
|
68
68
|
width = if cell.width_cm
|
|
69
69
|
DocXify.cm2dxa(cell.width_cm)
|
|
@@ -79,7 +79,7 @@ module DocXify
|
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
def table_row(row)
|
|
82
|
-
xml = "<w:tr>"
|
|
82
|
+
xml = +"<w:tr>"
|
|
83
83
|
widths = @column_widths.dup
|
|
84
84
|
row.each do |cell|
|
|
85
85
|
if cell.nil?
|
|
@@ -6,7 +6,7 @@ module DocXify
|
|
|
6
6
|
def initialize(content, options = {})
|
|
7
7
|
super()
|
|
8
8
|
@content = content
|
|
9
|
-
@valign = options[:valign] || :top
|
|
9
|
+
@valign = (options[:valign] if %i[top center bottom].include?(options[:valign])) || :top
|
|
10
10
|
@align = options[:align] || :left
|
|
11
11
|
@nowrap = options[:nowrap]
|
|
12
12
|
@colspan = options[:colspan]
|
|
@@ -15,11 +15,15 @@ module DocXify
|
|
|
15
15
|
@font = options[:font]
|
|
16
16
|
@size = options[:size]
|
|
17
17
|
@color = options[:color]
|
|
18
|
+
|
|
18
19
|
@borders = options[:borders]&.map(&:to_sym) || []
|
|
20
|
+
if @borders.include?(:all)
|
|
21
|
+
@borders = %i[top bottom left right]
|
|
22
|
+
end
|
|
19
23
|
end
|
|
20
24
|
|
|
21
25
|
def to_s
|
|
22
|
-
xml = "<w:tc>"
|
|
26
|
+
xml = +"<w:tc>"
|
|
23
27
|
xml << "<w:tcPr>"
|
|
24
28
|
xml << %Q(<w:tcW w:type="dxa" w:w="#{DocXify.cm2dxa(@width_cm)}"/>)
|
|
25
29
|
if !@colspan.nil? && @colspan.to_i > 1
|
data/lib/docxify/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: docxify
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andy Jeffries
|
|
8
8
|
- FounderCatalyst Ltd
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: exe
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: image_size
|
|
@@ -31,14 +30,14 @@ dependencies:
|
|
|
31
30
|
requirements:
|
|
32
31
|
- - "~>"
|
|
33
32
|
- !ruby/object:Gem::Version
|
|
34
|
-
version: '
|
|
33
|
+
version: '3.6'
|
|
35
34
|
type: :runtime
|
|
36
35
|
prerelease: false
|
|
37
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
38
37
|
requirements:
|
|
39
38
|
- - "~>"
|
|
40
39
|
- !ruby/object:Gem::Version
|
|
41
|
-
version: '
|
|
40
|
+
version: '3.6'
|
|
42
41
|
description: Using a relatively simple DSL, you can generate Word DocX documents from
|
|
43
42
|
Ruby.
|
|
44
43
|
email:
|
|
@@ -75,7 +74,6 @@ metadata:
|
|
|
75
74
|
source_code_uri: https://github.com/foundercatalyst/docxify
|
|
76
75
|
changelog_uri: https://github.com/foundercatalyst/docxify/CHANGELOG.md
|
|
77
76
|
rubygems_mfa_required: 'true'
|
|
78
|
-
post_install_message:
|
|
79
77
|
rdoc_options: []
|
|
80
78
|
require_paths:
|
|
81
79
|
- lib
|
|
@@ -90,8 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
90
88
|
- !ruby/object:Gem::Version
|
|
91
89
|
version: '0'
|
|
92
90
|
requirements: []
|
|
93
|
-
rubygems_version: 3.
|
|
94
|
-
signing_key:
|
|
91
|
+
rubygems_version: 3.6.9
|
|
95
92
|
specification_version: 4
|
|
96
93
|
summary: DocXify is a gem to help you generate Word documents from Ruby.
|
|
97
94
|
test_files: []
|