goldendocx 0.2.2 → 0.3.0
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/.rubocop.yml +1 -1
- data/.ruby-version +1 -0
- data/CHANGELOG.md +8 -2
- data/Gemfile.lock +3 -1
- data/README.md +10 -2
- data/Rakefile +14 -3
- data/demo/tables/create_embed_image_table.rb +3 -3
- data/demo/templates/generate_codes.rb +10 -0
- data/demo/templates/xml_to_class.rb +97 -0
- data/demo/texts/append_plain_text.rb +1 -1
- data/demo/texts/append_styled_text.rb +1 -2
- data/demo/texts/create_text.rb +14 -0
- data/lib/extensions/active_support_extensions.rb +16 -0
- data/lib/extensions/nokogiri_extensions.rb +41 -0
- data/lib/extensions/ox_extensions.rb +35 -0
- data/lib/extensions/xml_serialize_extensions.rb +45 -0
- data/lib/goldendocx/charts/properties.rb +1 -1
- data/lib/goldendocx/charts/series.rb +2 -2
- data/lib/goldendocx/charts.rb +1 -1
- data/lib/goldendocx/components/bar_chart.rb +2 -2
- data/lib/goldendocx/components/chart.rb +6 -6
- data/lib/goldendocx/components/column_chart.rb +2 -2
- data/lib/goldendocx/components/doughnut_chart.rb +2 -2
- data/lib/goldendocx/components/line_chart.rb +2 -2
- data/lib/goldendocx/components/properties/font_property.rb +19 -0
- data/lib/goldendocx/components/properties/language_property.rb +18 -0
- data/lib/goldendocx/components/properties/run_property.rb +2 -0
- data/lib/goldendocx/components/properties.rb +1 -1
- data/lib/goldendocx/components/table.rb +2 -2
- data/lib/goldendocx/components.rb +1 -1
- data/lib/goldendocx/content_types/default.rb +2 -6
- data/lib/goldendocx/content_types/override.rb +2 -6
- data/lib/goldendocx/document.rb +9 -28
- data/lib/goldendocx/documents/body.rb +23 -14
- data/lib/goldendocx/documents/document.rb +2 -4
- data/lib/goldendocx/documents/latent_styles.rb +12 -0
- data/lib/goldendocx/documents/properties/default_style_property.rb +17 -0
- data/lib/goldendocx/documents/properties/page_margin_property.rb +37 -0
- data/lib/goldendocx/documents/properties/page_size_property.rb +17 -0
- data/lib/goldendocx/documents/properties/paragraph_default_style_property.rb +16 -0
- data/lib/goldendocx/documents/properties/run_default_style_property.rb +22 -0
- data/lib/goldendocx/documents/properties/section_property.rb +17 -0
- data/lib/goldendocx/documents/properties/style_name_property.rb +16 -0
- data/lib/goldendocx/documents/properties.rb +12 -0
- data/lib/goldendocx/documents/settings.rb +23 -0
- data/lib/goldendocx/documents/style.rb +10 -10
- data/lib/goldendocx/documents/styles.rb +9 -33
- data/lib/goldendocx/documents.rb +1 -1
- data/lib/goldendocx/docx.rb +55 -12
- data/lib/goldendocx/element.rb +33 -140
- data/lib/goldendocx/has_associations.rb +54 -0
- data/lib/goldendocx/has_attributes.rb +67 -0
- data/lib/goldendocx/has_children.rb +116 -0
- data/lib/goldendocx/images/picture.rb +1 -1
- data/lib/goldendocx/images/properties.rb +1 -1
- data/lib/goldendocx/images.rb +1 -1
- data/lib/goldendocx/{documents → models}/relationship.rb +1 -1
- data/lib/goldendocx/models/relationships.rb +31 -0
- data/lib/goldendocx/models.rb +10 -0
- data/lib/goldendocx/parts/app.rb +46 -0
- data/lib/goldendocx/parts/content_types.rb +16 -30
- data/lib/goldendocx/parts/core.rb +46 -0
- data/lib/goldendocx/parts/documents.rb +27 -14
- data/lib/goldendocx/parts/media.rb +1 -1
- data/lib/goldendocx/parts/properties/created_at_property.rb +17 -0
- data/lib/goldendocx/parts/properties/creator_property.rb +16 -0
- data/lib/goldendocx/parts/properties/revision_property.rb +16 -0
- data/lib/goldendocx/parts/properties/updated_at_property.rb +17 -0
- data/lib/goldendocx/parts/properties/updater_property.rb +16 -0
- data/lib/goldendocx/parts/properties.rb +12 -0
- data/lib/goldendocx/parts.rb +1 -1
- data/lib/goldendocx/tables/header_cell.rb +1 -1
- data/lib/goldendocx/tables/properties.rb +1 -1
- data/lib/goldendocx/tables/row.rb +1 -1
- data/lib/goldendocx/tables.rb +1 -1
- data/lib/goldendocx/version.rb +1 -1
- data/lib/goldendocx/xml_serializers/nokogiri.rb +32 -24
- data/lib/goldendocx/xml_serializers/ox.rb +15 -25
- data/lib/goldendocx.rb +14 -2
- metadata +54 -9
- data/lib/goldendocx/documents/element.rb +0 -23
- data/lib/goldendocx/documents/relationships.rb +0 -39
- data/lib/goldendocx/documents/unparsed_style.rb +0 -17
@@ -6,13 +6,9 @@ module Goldendocx
|
|
6
6
|
include Goldendocx::Element
|
7
7
|
|
8
8
|
tag :Override
|
9
|
-
attribute :part_name, alias_name: :PartName, readonly: true
|
10
|
-
attribute :content_type, alias_name: :ContentType, readonly: true
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
@content_type = content_type
|
15
|
-
end
|
10
|
+
attribute :part_name, alias_name: :PartName
|
11
|
+
attribute :content_type, alias_name: :ContentType
|
16
12
|
|
17
13
|
def ==(other)
|
18
14
|
part_name == other.part_name && content_type == other.content_type
|
data/lib/goldendocx/document.rb
CHANGED
@@ -3,49 +3,30 @@
|
|
3
3
|
# Just to mark a element as a root document node
|
4
4
|
module Goldendocx
|
5
5
|
module Document
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
include Goldendocx::Element
|
8
|
+
|
9
|
+
included do
|
10
|
+
class_attribute :concerned_namespaces, default: []
|
11
|
+
class_attribute :ignorable_namespaces, default: []
|
9
12
|
end
|
10
13
|
|
11
|
-
|
14
|
+
class_methods do
|
12
15
|
def concern_namespaces(*namespaces)
|
13
16
|
namespaces.each do |namespace|
|
14
17
|
concerned_namespaces << namespace unless concerned_namespaces.include?(namespace)
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
18
|
-
def concerned_namespaces
|
19
|
-
@concerned_namespaces ||= []
|
20
|
-
end
|
21
|
-
|
22
21
|
def ignore_namespaces(*namespaces)
|
23
22
|
namespaces.each do |namespace|
|
24
23
|
ignorable_namespaces << namespace.to_sym unless ignorable_namespaces.include?(namespace)
|
25
24
|
end
|
26
25
|
end
|
27
|
-
|
28
|
-
def ignorable_namespaces
|
29
|
-
@ignorable_namespaces ||= []
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def concerned_namespaces
|
34
|
-
self.class.concerning_ancestors.flat_map(&:concerned_namespaces)
|
35
|
-
end
|
36
|
-
|
37
|
-
def ignorable_namespaces
|
38
|
-
self.class.concerning_ancestors.flat_map(&:ignorable_namespaces)
|
39
26
|
end
|
40
27
|
|
41
|
-
def to_document_xml
|
42
|
-
Goldendocx.xml_serializer.build_document_xml(
|
43
|
-
attributes.each { |name, value| xml[name] = value }
|
44
|
-
|
45
|
-
yield(xml) if block_given?
|
46
|
-
|
47
|
-
children.each { |child| xml << child }
|
48
|
-
end
|
28
|
+
def to_document_xml(&)
|
29
|
+
Goldendocx.xml_serializer.build_document_xml(tag_name, concerned_namespaces, ignorable_namespaces) { |xml| build_element(xml, &) }
|
49
30
|
end
|
50
31
|
end
|
51
32
|
end
|
@@ -7,40 +7,49 @@ module Goldendocx
|
|
7
7
|
|
8
8
|
XML_PATH = 'word/document.xml'
|
9
9
|
|
10
|
-
attr_reader :components, :
|
10
|
+
attr_reader :components, :charts
|
11
11
|
|
12
12
|
namespace :w
|
13
13
|
tag :body
|
14
14
|
|
15
|
+
# TODO: Try to distinguish these paragraphs
|
15
16
|
embeds_many :texts, class_name: 'Goldendocx::Components::Text'
|
16
17
|
embeds_many :images, class_name: 'Goldendocx::Components::Image'
|
18
|
+
|
17
19
|
embeds_many :tables, class_name: 'Goldendocx::Components::Table'
|
18
20
|
|
21
|
+
embeds_one :section_property, class_name: 'Goldendocx::Documents::Properties::SectionProperty', auto_build: true
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def read_from(xml_node)
|
25
|
+
document = super(xml_node)
|
26
|
+
|
27
|
+
component_tags = %w[w:p w:tbl]
|
28
|
+
xml_node.children.map do |node|
|
29
|
+
document.components << node if component_tags.include?(node.tag_name)
|
30
|
+
end
|
31
|
+
|
32
|
+
document
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
19
36
|
def initialize
|
20
37
|
@components = []
|
21
38
|
@charts = []
|
22
39
|
end
|
23
40
|
|
24
|
-
def read_from(docx_file)
|
25
|
-
Goldendocx.xml_serializer.parse(docx_file.read(XML_PATH), %w[w:document w:body *]).map do |node|
|
26
|
-
element = Goldendocx::Documents::Element.new(node)
|
27
|
-
@components << element if element.component?
|
28
|
-
@properties = element if element.properties?
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
41
|
# FIXME: Override for children not in correctly order
|
33
42
|
def to_element(**_context)
|
34
|
-
Goldendocx.xml_serializer.build_element(
|
43
|
+
Goldendocx.xml_serializer.build_element(tag_name) do |xml|
|
35
44
|
components.each { |component| xml << component }
|
36
|
-
xml <<
|
45
|
+
xml << section_property if section_property
|
37
46
|
|
38
47
|
yield(xml) if block_given?
|
39
48
|
end
|
40
49
|
end
|
41
50
|
|
42
51
|
def create_text(text, options = {})
|
43
|
-
text = build_text(text
|
52
|
+
text = build_text(text:, **options.slice(:align, :color, :bold))
|
44
53
|
|
45
54
|
components << text
|
46
55
|
|
@@ -57,7 +66,7 @@ module Goldendocx
|
|
57
66
|
end
|
58
67
|
|
59
68
|
def create_image(relationship_id, options)
|
60
|
-
image = build_image(relationship_id
|
69
|
+
image = build_image(relationship_id:, width: options[:width], height: options[:height])
|
61
70
|
|
62
71
|
components << image
|
63
72
|
|
@@ -65,7 +74,7 @@ module Goldendocx
|
|
65
74
|
end
|
66
75
|
|
67
76
|
def create_embed_image(relationship_id, options)
|
68
|
-
Goldendocx::Components::Image.new(relationship_id
|
77
|
+
Goldendocx::Components::Image.new(relationship_id:, width: options[:width], height: options[:height])
|
69
78
|
end
|
70
79
|
|
71
80
|
def ensure_chart_type(chart_type)
|
@@ -5,7 +5,9 @@ module Goldendocx
|
|
5
5
|
class Document
|
6
6
|
include Goldendocx::Document
|
7
7
|
|
8
|
+
TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument'
|
8
9
|
XML_PATH = 'word/document.xml'
|
10
|
+
CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml'
|
9
11
|
|
10
12
|
namespace :w
|
11
13
|
tag :document
|
@@ -16,10 +18,6 @@ module Goldendocx
|
|
16
18
|
|
17
19
|
embeds_one :body, class_name: 'Goldendocx::Documents::Body', auto_build: true
|
18
20
|
|
19
|
-
def read_from(docx_file)
|
20
|
-
body.read_from(docx_file)
|
21
|
-
end
|
22
|
-
|
23
21
|
def write_to(zos)
|
24
22
|
zos.put_next_entry XML_PATH
|
25
23
|
zos.write to_document_xml
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Goldendocx
|
4
|
+
module Documents
|
5
|
+
module Properties
|
6
|
+
class DefaultStyleProperty
|
7
|
+
include Goldendocx::Element
|
8
|
+
|
9
|
+
namespace :w
|
10
|
+
tag :docDefaults
|
11
|
+
|
12
|
+
embeds_one :run_default, class_name: 'Goldendocx::Documents::Properties::RunDefaultStyleProperty', auto_build: true
|
13
|
+
embeds_one :paragraph_default, class_name: 'Goldendocx::Documents::Properties::ParagraphDefaultStyleProperty', auto_build: true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Goldendocx
|
4
|
+
module Documents
|
5
|
+
module Properties
|
6
|
+
class PageMarginProperty
|
7
|
+
include Goldendocx::Element
|
8
|
+
|
9
|
+
namespace :w
|
10
|
+
tag :pgMar
|
11
|
+
|
12
|
+
attribute :top, namespace: :w, default: 1440
|
13
|
+
attribute :bottom, namespace: :w, default: 1440
|
14
|
+
attribute :left, namespace: :w, default: 1800
|
15
|
+
attribute :right, namespace: :w, default: 1800
|
16
|
+
attribute :header, namespace: :w, default: 851
|
17
|
+
attribute :footer, namespace: :w, default: 992
|
18
|
+
attribute :gutter, namespace: :w, default: 0
|
19
|
+
|
20
|
+
# Follow html margin style setting
|
21
|
+
def margin=(*args)
|
22
|
+
args = Array(*args)
|
23
|
+
raise StandardError("wrong number of arguments (given #{args.length}, expected 1..4)") unless (1..4).cover?(args.length)
|
24
|
+
|
25
|
+
margins =
|
26
|
+
case args.length
|
27
|
+
when 1 then [args.first] * 4
|
28
|
+
when 2 then [args.first, args.last, args.first, args.last]
|
29
|
+
when 3 then [args.first, args.second, args.last, args.second]
|
30
|
+
else args
|
31
|
+
end
|
32
|
+
assign_attributes(**%i[top right bottom left].zip(margins).to_h)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Goldendocx
|
4
|
+
module Documents
|
5
|
+
module Properties
|
6
|
+
class PageSizeProperty
|
7
|
+
include Goldendocx::Element
|
8
|
+
|
9
|
+
namespace :w
|
10
|
+
tag :pgSz
|
11
|
+
|
12
|
+
attribute :width, alias_name: :w, namespace: :w, default: 11906
|
13
|
+
attribute :height, alias_name: :h, namespace: :w, default: 16838
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Goldendocx
|
4
|
+
module Documents
|
5
|
+
module Properties
|
6
|
+
class ParagraphDefaultStyleProperty
|
7
|
+
include Goldendocx::Element
|
8
|
+
|
9
|
+
namespace :w
|
10
|
+
tag :pPrDefault
|
11
|
+
|
12
|
+
embeds_one :property, class_name: 'Goldendocx::Components::Properties::Property'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Goldendocx
|
4
|
+
module Documents
|
5
|
+
module Properties
|
6
|
+
class RunDefaultStyleProperty
|
7
|
+
include Goldendocx::Element
|
8
|
+
|
9
|
+
namespace :w
|
10
|
+
tag :rPrDefault
|
11
|
+
|
12
|
+
embeds_one :property, class_name: 'Goldendocx::Components::Properties::RunProperty'
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
build_property
|
16
|
+
property.build_language
|
17
|
+
property.build_font
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Goldendocx
|
4
|
+
module Documents
|
5
|
+
module Properties
|
6
|
+
class SectionProperty
|
7
|
+
include Goldendocx::Element
|
8
|
+
|
9
|
+
namespace :w
|
10
|
+
tag :sectPr
|
11
|
+
|
12
|
+
embeds_one :size, class_name: 'Goldendocx::Documents::Properties::PageSizeProperty', auto_build: true
|
13
|
+
embeds_one :margin, class_name: 'Goldendocx::Documents::Properties::PageMarginProperty', auto_build: true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Goldendocx
|
4
|
+
module Documents
|
5
|
+
module Properties
|
6
|
+
class StyleNameProperty
|
7
|
+
include Goldendocx::Element
|
8
|
+
|
9
|
+
namespace :w
|
10
|
+
tag :name
|
11
|
+
|
12
|
+
attribute :name, alias_name: :val, namespace: :w
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Goldendocx
|
4
|
+
module Documents
|
5
|
+
class Settings
|
6
|
+
include Goldendocx::Document
|
7
|
+
|
8
|
+
XML_PATH = 'word/settings.xml'
|
9
|
+
TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings'
|
10
|
+
CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml'
|
11
|
+
|
12
|
+
namespace :w
|
13
|
+
tag :settings
|
14
|
+
concern_namespaces :mc, :o, :r, :m, :v, :w10, :w, :w14, :w15, :w16cid, :w16se, :sl
|
15
|
+
ignore_namespaces :w14, :w15, :w16se, :w16cid
|
16
|
+
|
17
|
+
def write_to(zos)
|
18
|
+
zos.put_next_entry XML_PATH
|
19
|
+
zos.write to_document_xml
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -3,18 +3,18 @@
|
|
3
3
|
module Goldendocx
|
4
4
|
module Documents
|
5
5
|
class Style
|
6
|
-
|
6
|
+
include Goldendocx::Element
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
namespace :w
|
9
|
+
tag :style
|
10
|
+
|
11
|
+
attribute :id, alias_name: :styleId, namespace: :w
|
12
|
+
attribute :type, namespace: :w
|
13
|
+
|
14
|
+
embeds_one :style_name, class_name: 'Goldendocx::Documents::Properties::StyleNameProperty', auto_build: true
|
15
15
|
|
16
|
-
def
|
17
|
-
|
16
|
+
def name
|
17
|
+
style_name.name
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -6,42 +6,22 @@ module Goldendocx
|
|
6
6
|
include Goldendocx::Document
|
7
7
|
|
8
8
|
XML_PATH = 'word/styles.xml'
|
9
|
+
TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles'
|
10
|
+
CONTENT_TYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml'
|
9
11
|
|
10
12
|
tag :styles
|
11
13
|
namespace :w
|
12
14
|
concern_namespaces :mc, :r, :w, :w14, :w15
|
13
15
|
ignore_namespaces :w14, :w15
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@styles = []
|
19
|
-
end
|
17
|
+
embeds_one :defaults, class_name: 'Goldendocx::Documents::Properties::DefaultStyleProperty', auto_build: true
|
18
|
+
embeds_one :latentStyles, class_name: 'Goldendocx::Documents::LatentStyles'
|
19
|
+
embeds_many :styles, class_name: 'Goldendocx::Documents::Style'
|
20
20
|
|
21
21
|
def size
|
22
22
|
styles.size
|
23
23
|
end
|
24
24
|
|
25
|
-
def read_from(docx_file)
|
26
|
-
@styles = Goldendocx.xml_serializer.parse(docx_file.read(XML_PATH), %w[w:styles w:style]).map do |node|
|
27
|
-
Goldendocx::Documents::Style.new(node)
|
28
|
-
end
|
29
|
-
@doc_defaults = Goldendocx.xml_serializer.parse(docx_file.read(XML_PATH), %w[w:styles w:docDefaults]).map do |node|
|
30
|
-
Goldendocx::Documents::UnparsedStyle.new(node)
|
31
|
-
end
|
32
|
-
@latent_styles = Goldendocx.xml_serializer.parse(docx_file.read(XML_PATH), %w[w:styles w:latentStyles]).map do |node|
|
33
|
-
Goldendocx::Documents::UnparsedStyle.new(node)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def to_document_xml
|
38
|
-
super do |xml|
|
39
|
-
@doc_defaults&.each { |element| xml << element }
|
40
|
-
@latent_styles&.each { |element| xml << element }
|
41
|
-
styles.each { |style| xml << style }
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
25
|
def write_to(zos)
|
46
26
|
zos.put_next_entry XML_PATH
|
47
27
|
zos.write to_document_xml
|
@@ -60,14 +40,10 @@ module Goldendocx
|
|
60
40
|
end
|
61
41
|
|
62
42
|
def add_style(fragment)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
style = Goldendocx.xml_serializer.parse(fragment)
|
68
|
-
style['w:styleId'] = style_id if style['w:styleId'].nil? || style['w:styleId'].empty?
|
69
|
-
@styles << Goldendocx::Documents::Style.new(style)
|
70
|
-
style_id
|
43
|
+
style = Goldendocx::Documents::Style.parse(fragment)
|
44
|
+
style.id = (styles.size + 1).to_s # Rearrange id to prevent duplicates
|
45
|
+
styles << style
|
46
|
+
style.id
|
71
47
|
end
|
72
48
|
end
|
73
49
|
end
|
data/lib/goldendocx/documents.rb
CHANGED
data/lib/goldendocx/docx.rb
CHANGED
@@ -1,32 +1,54 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'goldendocx/
|
4
|
-
require 'goldendocx/element'
|
5
|
-
require 'goldendocx/document'
|
6
|
-
|
3
|
+
require 'goldendocx/models'
|
7
4
|
require 'goldendocx/components'
|
8
5
|
require 'goldendocx/documents'
|
9
6
|
require 'goldendocx/parts'
|
10
7
|
|
11
8
|
module Goldendocx
|
12
9
|
class Docx
|
13
|
-
|
10
|
+
include Goldendocx::HasAssociations
|
11
|
+
|
12
|
+
attr_reader :unstructured_entries, :documents
|
13
|
+
|
14
|
+
RELATIONSHIPS_XML_PATH = '_rels/.rels'
|
14
15
|
|
15
16
|
STRUCTURED_ENTRIES = [
|
17
|
+
RELATIONSHIPS_XML_PATH,
|
18
|
+
|
16
19
|
Goldendocx::Parts::ContentTypes::XML_PATH,
|
20
|
+
Goldendocx::Parts::App::XML_PATH,
|
21
|
+
Goldendocx::Parts::Core::XML_PATH,
|
22
|
+
|
23
|
+
Goldendocx::Parts::Documents::RELATIONSHIPS_XML_PATH,
|
17
24
|
|
18
|
-
Goldendocx::Documents::
|
19
|
-
Goldendocx::Documents::
|
25
|
+
Goldendocx::Documents::Document::XML_PATH,
|
26
|
+
Goldendocx::Documents::Settings::XML_PATH,
|
20
27
|
Goldendocx::Documents::Styles::XML_PATH
|
21
28
|
].freeze
|
22
29
|
|
23
|
-
|
30
|
+
relationships_at RELATIONSHIPS_XML_PATH
|
31
|
+
associate :app, class_name: 'Goldendocx::Parts::App'
|
32
|
+
associate :core, class_name: 'Goldendocx::Parts::Core'
|
33
|
+
associate :content_types, class_name: 'Goldendocx::Parts::ContentTypes', isolate: true
|
34
|
+
|
35
|
+
def initialize(file_path = nil)
|
36
|
+
file_path.present? ? read_from(file_path) : build_default
|
37
|
+
end
|
38
|
+
|
39
|
+
def read_from(file_path)
|
24
40
|
docx_file = Zip::File.new(file_path)
|
41
|
+
|
42
|
+
read_relationships(docx_file)
|
43
|
+
read_associations(docx_file)
|
44
|
+
|
25
45
|
@documents = Goldendocx::Parts::Documents.read_from(docx_file)
|
26
|
-
|
46
|
+
|
27
47
|
@unstructured_entries = docx_file.entries.filter_map do |entry|
|
28
48
|
UnStructuredEntry.new(entry) unless STRUCTURED_ENTRIES.include?(entry.name)
|
29
49
|
end
|
50
|
+
|
51
|
+
self
|
30
52
|
end
|
31
53
|
|
32
54
|
def write_to(new_path)
|
@@ -65,6 +87,25 @@ module Goldendocx
|
|
65
87
|
|
66
88
|
private
|
67
89
|
|
90
|
+
def build_default
|
91
|
+
associations.each do |association, options|
|
92
|
+
association_class = options.class_name.constantize
|
93
|
+
instance_variable_set("@#{association}", association_class.new)
|
94
|
+
add_relationship association_class::TYPE, association_class::XML_PATH unless options.isolate
|
95
|
+
end
|
96
|
+
|
97
|
+
content_types.add_override "/#{Goldendocx::Parts::App::XML_PATH}", Goldendocx::Parts::App::CONTENT_TYPE
|
98
|
+
content_types.add_override "/#{Goldendocx::Parts::Core::XML_PATH}", Goldendocx::Parts::Core::CONTENT_TYPE
|
99
|
+
content_types.add_override "/#{Goldendocx::Documents::Styles::XML_PATH}", Goldendocx::Documents::Styles::CONTENT_TYPE
|
100
|
+
content_types.add_override "/#{Goldendocx::Documents::Settings::XML_PATH}", Goldendocx::Documents::Settings::CONTENT_TYPE
|
101
|
+
|
102
|
+
@documents = Goldendocx::Parts::Documents.new
|
103
|
+
add_relationship Goldendocx::Documents::Document::TYPE, Goldendocx::Documents::Document::XML_PATH
|
104
|
+
content_types.add_override "/#{Goldendocx::Documents::Document::XML_PATH}", Goldendocx::Documents::Document::CONTENT_TYPE
|
105
|
+
|
106
|
+
@unstructured_entries = []
|
107
|
+
end
|
108
|
+
|
68
109
|
def ensure_image_content_type!(_image_data)
|
69
110
|
extension = 'png'
|
70
111
|
content_type = 'image/png'
|
@@ -79,10 +120,12 @@ module Goldendocx
|
|
79
120
|
|
80
121
|
def to_stream
|
81
122
|
Zip::OutputStream.write_buffer do |zos|
|
82
|
-
zos
|
83
|
-
|
123
|
+
write_relationships(zos)
|
124
|
+
|
125
|
+
associations.each_key do |association|
|
126
|
+
send(association).write_to(zos)
|
127
|
+
end
|
84
128
|
|
85
|
-
zos.put_next_entry Goldendocx::Parts::Documents::XML_PATH
|
86
129
|
documents.write_stream(zos)
|
87
130
|
|
88
131
|
@unstructured_entries.each { |unstructured_entry| unstructured_entry.write_to(zos) }
|