docxify 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +22 -11
- data/lib/docxify/container.rb +7 -5
- data/lib/docxify/document.rb +6 -5
- data/lib/docxify/element/base.rb +3 -3
- data/lib/docxify/element/file.rb +4 -0
- data/lib/docxify/element/paragraph.rb +68 -20
- data/lib/docxify/element/table.rb +99 -1
- data/lib/docxify/element/table_cell.rb +66 -0
- data/lib/docxify/element/web_address.rb +20 -0
- data/lib/docxify/version.rb +1 -1
- data/lib/docxify.rb +10 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb6c9076520d0776ed132e2abbc42166a6ff0106fce181d5d178ecf3abff1a96
|
4
|
+
data.tar.gz: 042d1e27e5572cd0b4868eb9af065d1b3831e25d80569eafd2086bda130ab7b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83ee99a55280b56efd7f571c00c8cb09eb026345b821173c389f40f3bffb907bc2f4b57ce08d6d587a0bc653cdbc4efc630a1400dd48e3dee78f005bf574469e
|
7
|
+
data.tar.gz: 62a9965149dde87c65db3877642fff5e6cf0cc8f02f373ab59422b78ca9a645522c2df45125268140f8b1e36b29a105b500ea06489f0fc5fee6056bff740bd6a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 0.0.7
|
4
|
+
|
5
|
+
Features:
|
6
|
+
|
7
|
+
- Table support
|
8
|
+
|
9
|
+
## 0.0.6
|
10
|
+
|
11
|
+
Features:
|
12
|
+
|
13
|
+
- Tab stops and hanging indents done
|
14
|
+
- Replacing of {CHECKBOX_EMPTY} and {CHECKBOX_CHECKED} with correct UTF-8 characters done
|
15
|
+
|
3
16
|
## 0.0.5
|
4
17
|
|
5
18
|
Features:
|
data/README.md
CHANGED
@@ -35,21 +35,32 @@ gem install docxify
|
|
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
|
|
38
|
-
@docx.add_page_break
|
39
38
|
@docx.add_divider
|
40
39
|
|
41
40
|
@docx.add_image "file_path or data", align: :right, height_cm: 2, width_cm: 4
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
]
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
42
|
+
@docx.add_page_break
|
43
|
+
|
44
|
+
@docx.container page_width: DocXify::A4_PORTRAIT_HEIGHT, page_height: DocXify::A4_PORTRAIT_WIDTH do |container|
|
45
|
+
rows = []
|
46
|
+
rows << [
|
47
|
+
DocXify::Element::TableCell.new("<b>Header 1</b>"),
|
48
|
+
DocXify::Element::TableCell.new("<b>Header 2</b>")
|
49
|
+
DocXify::Element::TableCell.new("<b>Header 3</b>")
|
50
|
+
DocXify::Element::TableCell.new("<b>Header 4</b>", width_cm: 10)
|
51
|
+
]
|
52
|
+
rows << [
|
53
|
+
DocXify::Element::TableCell.new("Content 1", valign: :center, align: :left, nowrap: true, colspan: 3),
|
54
|
+
DocXify::Element::TableCell.new("Rowspan <b>here</b>", rowspan: true) # merges until a "nil" cell
|
55
|
+
]
|
56
|
+
rows << [
|
57
|
+
DocXify::Element::TableCell.new("Secondary 1")
|
58
|
+
DocXify::Element::TableCell.new("Secondary 2")
|
59
|
+
DocXify::Element::TableCell.new("Secondary 3")
|
60
|
+
DocXify::Element::TableCell.new(nil) # Word requires that there's an empty cell merged with the previous rowspan
|
61
|
+
]
|
62
|
+
container.add_table rows
|
63
|
+
end
|
53
64
|
|
54
65
|
docx_binary_data = @docx.render
|
55
66
|
# or
|
data/lib/docxify/container.rb
CHANGED
@@ -39,9 +39,11 @@ module DocXify
|
|
39
39
|
zip.put_next_entry "word/_rels/document.xml.rels"
|
40
40
|
zip.write document_xml_rels
|
41
41
|
|
42
|
-
@document.
|
43
|
-
|
44
|
-
|
42
|
+
@document.relationships.each do |relation|
|
43
|
+
if relation.is_a?(DocXify::Element::File)
|
44
|
+
zip.put_next_entry "word/media/#{relation.filename}"
|
45
|
+
zip.write relation.data
|
46
|
+
end
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
@@ -64,8 +66,8 @@ module DocXify
|
|
64
66
|
<Relationship Id="rId4" Target="fontTable.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable"/>
|
65
67
|
XML
|
66
68
|
|
67
|
-
@document.
|
68
|
-
xml <<
|
69
|
+
@document.relationships.each do |relation|
|
70
|
+
xml << relation.to_s
|
69
71
|
end
|
70
72
|
|
71
73
|
xml << "</Relationships>"
|
data/lib/docxify/document.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
module DocXify
|
2
2
|
class Document
|
3
3
|
attr_accessor :font, :size, :color, :background
|
4
|
-
attr_reader :content, :
|
4
|
+
attr_reader :content, :relationships, :width
|
5
5
|
|
6
6
|
def initialize(options = {})
|
7
7
|
@content = []
|
8
|
-
@
|
8
|
+
@relationships = []
|
9
9
|
@width = options[:width] || A4_PORTRAIT_WIDTH
|
10
10
|
@height = options[:height] || A4_PORTRAIT_HEIGHT
|
11
11
|
@font = options[:font] || "Times New Roman"
|
@@ -74,7 +74,7 @@ module DocXify
|
|
74
74
|
|
75
75
|
def add_file(file_path_or_data)
|
76
76
|
file = DocXify::Element::File.new(file_path_or_data)
|
77
|
-
@
|
77
|
+
@relationships << file
|
78
78
|
file
|
79
79
|
end
|
80
80
|
|
@@ -91,8 +91,9 @@ module DocXify
|
|
91
91
|
add DocXify::Element::Paragraph.new(text, options)
|
92
92
|
end
|
93
93
|
|
94
|
-
def add_table(
|
95
|
-
|
94
|
+
def add_table(rows, options = {})
|
95
|
+
options[:document] = self
|
96
|
+
add DocXify::Element::Table.new(rows, options)
|
96
97
|
end
|
97
98
|
end
|
98
99
|
end
|
data/lib/docxify/element/base.rb
CHANGED
@@ -22,7 +22,7 @@ module DocXify
|
|
22
22
|
if char == "<"
|
23
23
|
state = :tag
|
24
24
|
tag = ""
|
25
|
-
result << text
|
25
|
+
result << text unless text.empty?
|
26
26
|
text = ""
|
27
27
|
else
|
28
28
|
text << char
|
@@ -61,7 +61,7 @@ module DocXify
|
|
61
61
|
when :content # With the content of an HTML tag
|
62
62
|
if char == "<"
|
63
63
|
state = :tag
|
64
|
-
result.last[:content] = content
|
64
|
+
result.last[:content] = content
|
65
65
|
content = ""
|
66
66
|
else
|
67
67
|
content << char
|
@@ -71,7 +71,7 @@ module DocXify
|
|
71
71
|
last_char = char
|
72
72
|
end
|
73
73
|
|
74
|
-
result << text
|
74
|
+
result << text unless text.empty?
|
75
75
|
result
|
76
76
|
end
|
77
77
|
end
|
data/lib/docxify/element/file.rb
CHANGED
@@ -34,6 +34,10 @@ module DocXify
|
|
34
34
|
"image-#{Digest::SHA1.hexdigest(@data)[0, 8]}"
|
35
35
|
end
|
36
36
|
|
37
|
+
def to_s
|
38
|
+
"<Relationship Id=\"#{reference}\" Target=\"media/#{filename}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\"/>"
|
39
|
+
end
|
40
|
+
|
37
41
|
def contains_png_image?(data)
|
38
42
|
data[0, 8] == PNG_SIGNATURE
|
39
43
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module DocXify
|
2
2
|
module Element
|
3
3
|
class Paragraph < Base
|
4
|
-
attr_accessor :text, :font, :size, :color, :background, :align, :inline_styling, :tab_stops_cm
|
4
|
+
attr_accessor :text, :font, :size, :color, :background, :align, :inline_styling, :tab_stops_cm, :hanging_cm
|
5
5
|
|
6
6
|
def initialize(text, options = {})
|
7
7
|
super()
|
@@ -14,38 +14,86 @@ module DocXify
|
|
14
14
|
@background = options[:background] if options[:background]
|
15
15
|
@background ||= @document&.background if @document&.background
|
16
16
|
@align = options[:align] || :left
|
17
|
-
@inline_styling = options[:inline_styling]
|
17
|
+
@inline_styling = options.key?(:inline_styling) ? options[:inline_styling] : true
|
18
18
|
@tab_stops_cm = options[:tab_stops_cm] || []
|
19
|
+
@hanging_cm = options[:hanging_cm] || 0
|
19
20
|
end
|
20
21
|
|
21
22
|
def to_s(_container = nil)
|
22
23
|
nodes = if @inline_styling
|
23
24
|
parse_simple_html(@text)
|
24
25
|
else
|
25
|
-
[@text]
|
26
|
+
[@text.gsub("<", "<").gsub(">", ">")]
|
26
27
|
end
|
27
28
|
|
28
29
|
xml = "<w:p>"
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
30
|
+
|
31
|
+
xml << "<w:pPr>"
|
32
|
+
xml << "<w:jc w:val=\"#{@align}\"/>" if @align != :left
|
33
|
+
|
34
|
+
if tab_stops_cm.any?
|
35
|
+
xml << "<w:tabs>"
|
36
|
+
tab_stops_cm.each do |stop|
|
37
|
+
xml << "<w:tab w:pos=\"#{DocXify.cm2dxa(stop)}\" w:val=\"left\"/>"
|
38
|
+
end
|
39
|
+
xml << "</w:tabs>"
|
40
|
+
end
|
41
|
+
|
42
|
+
if @hanging_cm&.positive?
|
43
|
+
xml << "<w:ind w:hanging=\"#{DocXify.cm2dxa(@hanging_cm)}\" w:left=\"#{DocXify.cm2dxa(@hanging_cm)}\"/>"
|
44
|
+
end
|
45
|
+
|
46
|
+
xml << "</w:pPr>"
|
44
47
|
|
45
48
|
nodes.each do |node|
|
46
|
-
|
49
|
+
if node.is_a?(Hash) && node[:tag] == "a"
|
50
|
+
xml << "<w:hyperlink r:id=\"#{ref_for_href(node[:attributes][:href])}\">"
|
51
|
+
end
|
52
|
+
|
53
|
+
xml << "<w:r>"
|
54
|
+
xml << <<~XML
|
55
|
+
<w:rPr>
|
56
|
+
<w:rFonts w:ascii="#{@font}" w:cs="#{@font}" w:hAnsi="#{@font}"/>
|
57
|
+
<w:color w:val="#{@color.gsub("#", "")}"/>
|
58
|
+
<w:sz w:val="#{DocXify.pt2halfpt(@size)}"/>
|
59
|
+
<w:szCs w:val="#{DocXify.pt2halfpt(@size)}"/>
|
60
|
+
#{"<w:highlight w:val=\"yellow\"/>" if @highlight}
|
61
|
+
#{"<w:b/><w:bCs/>" if node.is_a?(Hash) && node[:tag] == "b"}
|
62
|
+
#{"<w:i/><w:iCs/>" if node.is_a?(Hash) && node[:tag] == "i"}
|
63
|
+
#{"<w:u w:val=\"single\"/>" if node.is_a?(Hash) && (node[:tag] == "u" || node[:tag] == "a")}
|
64
|
+
#{"<w:rStyle w:val=\"Hyperlink\"/>" if node.is_a?(Hash) && node[:tag] == "a"}
|
65
|
+
</w:rPr>
|
66
|
+
XML
|
67
|
+
|
68
|
+
content = node.is_a?(Hash) ? node[:content] : node
|
69
|
+
content = content.gsub("{CHECKBOX_EMPTY}", "☐").gsub("{CHECKBOX_CHECKED}", "☒")
|
70
|
+
xml << "<w:t xml:space=\"preserve\">#{content}</w:t>"
|
71
|
+
xml << "</w:r>"
|
72
|
+
|
73
|
+
if node.is_a?(Hash) && node[:tag] == "a"
|
74
|
+
xml << "</w:hyperlink>"
|
75
|
+
end
|
47
76
|
end
|
48
|
-
|
77
|
+
|
78
|
+
xml << "</w:p>"
|
79
|
+
end
|
80
|
+
|
81
|
+
def ref_for_href(href)
|
82
|
+
relation = nil
|
83
|
+
|
84
|
+
@document.relationships.select { |r| r.is_a?(DocXify::Element::WebAddress) }.each do |r|
|
85
|
+
if r.target == href
|
86
|
+
relation = r
|
87
|
+
break
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
if relation.nil?
|
92
|
+
relation = DocXify::Element::WebAddress.new(href)
|
93
|
+
@document.relationships << relation
|
94
|
+
end
|
95
|
+
|
96
|
+
relation.reference
|
49
97
|
end
|
50
98
|
end
|
51
99
|
end
|
@@ -1,8 +1,106 @@
|
|
1
|
+
# Structure of a table element looks something like this
|
2
|
+
# <w:tbl> - Table element
|
3
|
+
# <w:tblPr> - Table properties
|
4
|
+
# <w:tblGrid> - Table grid (column widths)
|
5
|
+
# <w:tr> - Table row
|
6
|
+
# <w:tc> - Table cell
|
7
|
+
# <w:tcPr> - Table cell properties
|
8
|
+
# <w:tcW w:type="dxa" w:w="1502"/> - Table cell width
|
9
|
+
# <w:vMerge w:val="restart"/> - Something about merging TODO - figure out
|
10
|
+
# <w:tcBorders> - Overriding table cell borders
|
11
|
+
# <w:top w:val="nil"/>
|
12
|
+
# <w:bottom w:color="auto" w:space="0" w:sz="4" w:val="single"/>
|
13
|
+
# <w:right w:val="nil"/>
|
14
|
+
# </w:tcBorders>
|
15
|
+
# <w:vAlign w:val="bottom"/>
|
16
|
+
# </w:tcPr>
|
17
|
+
# <w:p> - Paragraph element
|
18
|
+
|
1
19
|
module DocXify
|
2
20
|
module Element
|
3
21
|
class Table < Base
|
22
|
+
attr_accessor :rows, :column_widths
|
23
|
+
|
24
|
+
def initialize(rows, options = {})
|
25
|
+
super()
|
26
|
+
@document = options[:document]
|
27
|
+
@rows = rows
|
28
|
+
end
|
29
|
+
|
4
30
|
def to_s(_container = nil)
|
5
|
-
|
31
|
+
xml = ""
|
32
|
+
xml << table_element_start
|
33
|
+
xml << table_properties
|
34
|
+
xml << table_grid
|
35
|
+
@rows.each do |row|
|
36
|
+
xml << table_row(row)
|
37
|
+
end
|
38
|
+
xml << table_element_end
|
39
|
+
xml
|
40
|
+
end
|
41
|
+
|
42
|
+
def table_element_start
|
43
|
+
"<w:tbl>"
|
44
|
+
end
|
45
|
+
|
46
|
+
def table_properties
|
47
|
+
xml = ""
|
48
|
+
xml << "<w:tblPr>"
|
49
|
+
xml << '<w:tblStyle w:val="TableGrid"/>'
|
50
|
+
xml << '<w:tblW w:type="auto" w:w="0"/>'
|
51
|
+
xml << "<w:tblBorders>"
|
52
|
+
xml << '<w:top w:color="auto" w:space="0" w:sz="0" w:val="none"/>'
|
53
|
+
xml << '<w:left w:color="auto" w:space="0" w:sz="0" w:val="none"/>'
|
54
|
+
xml << '<w:bottom w:color="auto" w:space="0" w:sz="0" w:val="none"/>'
|
55
|
+
xml << '<w:right w:color="auto" w:space="0" w:sz="0" w:val="none"/>'
|
56
|
+
xml << "</w:tblBorders>"
|
57
|
+
xml << '<w:tblLook w:firstColumn="1" w:firstRow="1" w:lastColumn="0" w:lastRow="0" w:noHBand="0" w:noVBand="1" w:val="04A0"/>'
|
58
|
+
xml << "</w:tblPr>"
|
59
|
+
xml
|
60
|
+
end
|
61
|
+
|
62
|
+
def table_grid
|
63
|
+
default_equal_width = (@document.width / @rows.first.size).to_i
|
64
|
+
|
65
|
+
@column_widths = []
|
66
|
+
xml = "<w:tblGrid>"
|
67
|
+
@rows.first.each do |cell|
|
68
|
+
width = if cell.width_cm
|
69
|
+
DocXify.cm2dxa(cell.width_cm)
|
70
|
+
else
|
71
|
+
default_equal_width
|
72
|
+
end
|
73
|
+
xml << "<w:gridCol w:w=\"#{width}\"/>"
|
74
|
+
@column_widths << width
|
75
|
+
end
|
76
|
+
|
77
|
+
xml << "</w:tblGrid>"
|
78
|
+
xml
|
79
|
+
end
|
80
|
+
|
81
|
+
def table_row(row)
|
82
|
+
xml = "<w:tr>"
|
83
|
+
widths = @column_widths.dup
|
84
|
+
row.each do |cell|
|
85
|
+
if cell.nil?
|
86
|
+
cell = DocXify::Element::TableCell.new(nil)
|
87
|
+
end
|
88
|
+
|
89
|
+
if cell.width_cm.nil?
|
90
|
+
cell.width_cm = 0
|
91
|
+
(cell.colspan || 1).times do
|
92
|
+
cell.width_cm += DocXify.dxa2cm(widths.shift)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
xml << cell.to_s
|
97
|
+
end
|
98
|
+
xml << "</w:tr>"
|
99
|
+
xml
|
100
|
+
end
|
101
|
+
|
102
|
+
def table_element_end
|
103
|
+
"</w:tbl>"
|
6
104
|
end
|
7
105
|
end
|
8
106
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module DocXify
|
2
|
+
module Element
|
3
|
+
class TableCell < Base
|
4
|
+
attr_accessor :content, :valign, :align, :nowrap, :colspan, :width_cm, :borders, :font, :size, :colour
|
5
|
+
|
6
|
+
def initialize(content, options = {})
|
7
|
+
super()
|
8
|
+
@content = content
|
9
|
+
@valign = options[:valign] || :top
|
10
|
+
@align = options[:align] || :left
|
11
|
+
@nowrap = options[:nowrap]
|
12
|
+
@colspan = options[:colspan]
|
13
|
+
@rowspan = options[:rowspan]
|
14
|
+
@width_cm = options[:width_cm]
|
15
|
+
@font = options[:font]
|
16
|
+
@size = options[:size]
|
17
|
+
@color = options[:color]
|
18
|
+
@borders = options[:borders]&.map(&:to_sym) || []
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
xml = "<w:tc>"
|
23
|
+
xml << "<w:tcPr>"
|
24
|
+
xml << %Q(<w:tcW w:type="dxa" w:w="#{DocXify.cm2dxa(@width_cm)}"/>)
|
25
|
+
if !@colspan.nil? && @colspan.to_i > 1
|
26
|
+
xml << %Q(<w:gridSpan w:val="#{@colspan}"/>')
|
27
|
+
end
|
28
|
+
|
29
|
+
if borders.any?
|
30
|
+
xml << "<w:tcBorders>"
|
31
|
+
xml << (borders.include?(:top) ? '<w:top w:color="auto" w:space="0" w:sz="4" w:val="single"/>' : '<w:top w:val="nil"/>')
|
32
|
+
xml << (borders.include?(:bottom) ? '<w:bottom w:color="auto" w:space="0" w:sz="4" w:val="single"/>' : '<w:bottom w:val="nil"/>')
|
33
|
+
xml << (borders.include?(:left) ? '<w:left w:color="auto" w:space="0" w:sz="4" w:val="single"/>' : '<w:left w:val="nil"/>')
|
34
|
+
xml << (borders.include?(:right) ? '<w:right w:color="auto" w:space="0" w:sz="4" w:val="single"/>' : '<w:right w:val="nil"/>')
|
35
|
+
xml << "</w:tcBorders>"
|
36
|
+
end
|
37
|
+
|
38
|
+
if @valign != :top
|
39
|
+
xml << %Q(<w:vAlign w:val="#{@valign}"/>)
|
40
|
+
end
|
41
|
+
|
42
|
+
if @nowrap
|
43
|
+
xml << "<w:noWrap/>"
|
44
|
+
end
|
45
|
+
|
46
|
+
if @content.nil?
|
47
|
+
@content = "" # Nil is useful for rowspan, but we need to output something or Word breaks
|
48
|
+
end
|
49
|
+
|
50
|
+
if @rowspan
|
51
|
+
xml << '<w:vMerge w:val="restart"/>'
|
52
|
+
elsif @content == ""
|
53
|
+
xml << "<w:vMerge/>"
|
54
|
+
end
|
55
|
+
|
56
|
+
xml << "</w:tcPr>"
|
57
|
+
|
58
|
+
xml << DocXify::Element::Paragraph.new(@content, document: @document, font: @font, size: @size, color: @color, align: @align).to_s
|
59
|
+
|
60
|
+
xml << "</w:tc>"
|
61
|
+
|
62
|
+
xml
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module DocXify
|
2
|
+
module Element
|
3
|
+
class WebAddress < Base
|
4
|
+
attr_accessor :target
|
5
|
+
|
6
|
+
def initialize(target)
|
7
|
+
super()
|
8
|
+
@target = target
|
9
|
+
end
|
10
|
+
|
11
|
+
def reference
|
12
|
+
"url-#{Digest::SHA1.hexdigest(target)[0, 8]}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
"<Relationship Id=\"#{reference}\" Target=\"#{target}/\" TargetMode=\"External\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\"/>"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/docxify/version.rb
CHANGED
data/lib/docxify.rb
CHANGED
@@ -10,6 +10,8 @@ require_relative "docxify/element/image"
|
|
10
10
|
require_relative "docxify/element/page_break"
|
11
11
|
require_relative "docxify/element/paragraph"
|
12
12
|
require_relative "docxify/element/table"
|
13
|
+
require_relative "docxify/element/table_cell"
|
14
|
+
require_relative "docxify/element/web_address"
|
13
15
|
|
14
16
|
module DocXify
|
15
17
|
class Error < StandardError; end
|
@@ -28,6 +30,14 @@ module DocXify
|
|
28
30
|
(value * UNITS_PER_CM).to_i
|
29
31
|
end
|
30
32
|
|
33
|
+
# Inverse of cm2dxa
|
34
|
+
def self.dxa2cm(value)
|
35
|
+
value = value.to_f
|
36
|
+
raise ArgumentError.new("Value must be greater than or equal to 0") if value.negative?
|
37
|
+
|
38
|
+
(value / UNITS_PER_CM).to_i
|
39
|
+
end
|
40
|
+
|
31
41
|
# Used for font sizes
|
32
42
|
def self.pt2halfpt(value)
|
33
43
|
value = value.to_f
|
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.7
|
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-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -48,6 +48,8 @@ files:
|
|
48
48
|
- lib/docxify/element/page_break.rb
|
49
49
|
- lib/docxify/element/paragraph.rb
|
50
50
|
- lib/docxify/element/table.rb
|
51
|
+
- lib/docxify/element/table_cell.rb
|
52
|
+
- lib/docxify/element/web_address.rb
|
51
53
|
- lib/docxify/template.rb
|
52
54
|
- lib/docxify/version.rb
|
53
55
|
homepage: https://github.com/foundercatalyst/docxify
|