ooxml_parser 0.33.0 → 0.34.1

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ooxml_parser/common_parser/common_data/alternate_content/drawing/docx_drawing.rb +9 -0
  3. data/lib/ooxml_parser/common_parser/common_data/alternate_content/drawing/drawing_properties/docx_drawing_properties.rb +6 -2
  4. data/lib/ooxml_parser/common_parser/common_data/alternate_content/drawing/drawing_properties/ooxml_coordinates.rb +15 -9
  5. data/lib/ooxml_parser/common_parser/common_data/alternate_content/drawing/graphic/docx_graphic.rb +2 -1
  6. data/lib/ooxml_parser/common_parser/common_data/alternate_content/drawing/graphic/shape/shape_properties/custom_geometry/docx_custom_geometry/docx_shape_line_path/docx_shape_line_element.rb +1 -1
  7. data/lib/ooxml_parser/common_parser/common_data/alternate_content/drawing/graphic/shape/shape_properties/docx_shape_size.rb +4 -4
  8. data/lib/ooxml_parser/common_parser/common_data/borders_properties.rb +2 -2
  9. data/lib/ooxml_parser/common_parser/common_data/color/color_helper.rb +14 -13
  10. data/lib/ooxml_parser/common_parser/common_data/color.rb +17 -13
  11. data/lib/ooxml_parser/common_parser/common_data/colors/color_alpha_channel.rb +19 -5
  12. data/lib/ooxml_parser/common_parser/common_data/colors/color_properties.rb +34 -12
  13. data/lib/ooxml_parser/common_parser/common_data/colors/image_fill.rb +2 -2
  14. data/lib/ooxml_parser/common_parser/common_data/hyperlink.rb +4 -0
  15. data/lib/ooxml_parser/common_parser/common_data/ooxml_document_object.rb +22 -1
  16. data/lib/ooxml_parser/common_parser/common_data/paragraph/paragraph_properties/numbering_properties.rb +22 -6
  17. data/lib/ooxml_parser/common_parser/common_data/paragraph/paragraph_properties.rb +4 -2
  18. data/lib/ooxml_parser/common_parser/common_data/paragraph/paragraph_run/run_properties/run_fonts.rb +26 -0
  19. data/lib/ooxml_parser/common_parser/common_data/paragraph/paragraph_run/run_properties.rb +12 -3
  20. data/lib/ooxml_parser/common_parser/common_data/table/margins/table_margins.rb +4 -4
  21. data/lib/ooxml_parser/common_parser/common_data/table/row/cell/cell_properties.rb +14 -4
  22. data/lib/ooxml_parser/common_parser/common_data/table/table_properties.rb +3 -2
  23. data/lib/ooxml_parser/common_parser/common_data/underline.rb +22 -1
  24. data/lib/ooxml_parser/common_parser/common_data/valued_child.rb +21 -2
  25. data/lib/ooxml_parser/common_parser/parser/ooxml_file.rb +10 -0
  26. data/lib/ooxml_parser/docx_parser/document_structure/default_style_helper.rb +84 -0
  27. data/lib/ooxml_parser/docx_parser/document_structure/document_background.rb +6 -1
  28. data/lib/ooxml_parser/docx_parser/document_structure/document_style.rb +9 -3
  29. data/lib/ooxml_parser/docx_parser/document_structure/docx_paragraph/docx_formula/accent.rb +9 -2
  30. data/lib/ooxml_parser/docx_parser/document_structure/docx_paragraph/docx_formula/bar.rb +9 -3
  31. data/lib/ooxml_parser/docx_parser/document_structure/docx_paragraph/docx_formula/group_char.rb +25 -4
  32. data/lib/ooxml_parser/docx_parser/document_structure/docx_paragraph/docx_formula/matrix.rb +2 -1
  33. data/lib/ooxml_parser/docx_parser/document_structure/docx_paragraph/docx_paragraph_run/docx_paragraph_run_helpers.rb +21 -13
  34. data/lib/ooxml_parser/docx_parser/document_structure/docx_paragraph/docx_paragraph_run/field_char.rb +22 -0
  35. data/lib/ooxml_parser/docx_parser/document_structure/docx_paragraph/docx_paragraph_run.rb +3 -1
  36. data/lib/ooxml_parser/docx_parser/document_structure/docx_paragraph/sdt/sdt_properties/form_properties.rb +1 -1
  37. data/lib/ooxml_parser/docx_parser/document_structure/docx_paragraph/sdt/sdt_properties/form_text_properties.rb +2 -2
  38. data/lib/ooxml_parser/docx_parser/document_structure/docx_paragraph.rb +25 -8
  39. data/lib/ooxml_parser/docx_parser/document_structure/header_footer.rb +14 -2
  40. data/lib/ooxml_parser/docx_parser/document_structure/page_properties/columns.rb +2 -2
  41. data/lib/ooxml_parser/docx_parser/document_structure/page_properties/note.rb +10 -11
  42. data/lib/ooxml_parser/docx_parser/document_structure/page_properties/page_properties/header_footer_reference.rb +27 -0
  43. data/lib/ooxml_parser/docx_parser/document_structure/page_properties/page_properties/page_borders.rb +26 -0
  44. data/lib/ooxml_parser/docx_parser/document_structure/page_properties/page_properties.rb +20 -12
  45. data/lib/ooxml_parser/docx_parser/document_structure/styles/document_defaults/paragraph_properties_default.rb +3 -0
  46. data/lib/ooxml_parser/docx_parser/document_structure/styles.rb +6 -0
  47. data/lib/ooxml_parser/docx_parser/document_structure.rb +2 -69
  48. data/lib/ooxml_parser/pptx_parser/presentation/presentation_comments/presentation_comment.rb +1 -1
  49. data/lib/ooxml_parser/pptx_parser/presentation/slide/graphic_frame/graphic_frame/chart_reference.rb +22 -0
  50. data/lib/ooxml_parser/pptx_parser/presentation/slide/graphic_frame/graphic_frame.rb +4 -1
  51. data/lib/ooxml_parser/version.rb +1 -1
  52. data/lib/ooxml_parser/xlsx_parser/workbook/pivot_table_definition/location.rb +6 -6
  53. data/lib/ooxml_parser/xlsx_parser/workbook/style_sheet/cell_xfs/cell_style/protection.rb +2 -2
  54. data/lib/ooxml_parser/xlsx_parser/workbook/style_sheet/cell_xfs/xf.rb +5 -5
  55. data/lib/ooxml_parser/xlsx_parser/workbook/workbook_properties.rb +1 -1
  56. data/lib/ooxml_parser/xlsx_parser/workbook/worksheet/sheet_view.rb +2 -2
  57. data/lib/ooxml_parser/xlsx_parser/workbook/worksheet/table_part.rb +9 -1
  58. data/lib/ooxml_parser/xlsx_parser/workbook/worksheet/xlsx_column_properties.rb +2 -2
  59. data/lib/ooxml_parser/xlsx_parser/workbook/worksheet/xlsx_header_footer.rb +4 -4
  60. data/lib/ooxml_parser/xlsx_parser/workbook/worksheet.rb +2 -1
  61. data/lib/ooxml_parser/xlsx_parser/workbook.rb +1 -1
  62. metadata +9 -3
@@ -4,7 +4,7 @@ require_relative 'grid_span'
4
4
  module OoxmlParser
5
5
  # Class for parsing 'w:tcPr' element
6
6
  class CellProperties < OOXMLDocumentObject
7
- attr_accessor :fill, :color, :borders, :text_direction, :anchor, :table_cell_width, :borders_properties, :vertical_align
7
+ attr_accessor :fill, :color, :borders, :text_direction, :anchor, :table_cell_width, :borders_properties
8
8
  # @return [GridSpan] data about grid span
9
9
  attr_accessor :grid_span
10
10
  # @return [TableMargins] margins
@@ -22,6 +22,8 @@ module OoxmlParser
22
22
  # width is set to auto or pct, then the content of the cell will not wrap.
23
23
  # > ECMA-376, 3rd Edition (June, 2011), Fundamentals and Markup Language Reference 17.4.30.
24
24
  attr_accessor :no_wrap
25
+ # @return [ValuedChild] vertical align type
26
+ attr_reader :vertical_align_object
25
27
 
26
28
  alias table_cell_borders borders_properties
27
29
 
@@ -38,15 +40,16 @@ module OoxmlParser
38
40
  when 'vMerge'
39
41
  @vertical_merge = ValuedChild.new(:symbol, parent: self).parse(node_child)
40
42
  when 'vAlign'
41
- @vertical_align = node_child.attribute('val').value.to_sym
43
+ @vertical_align_object = ValuedChild.new(:symbol, parent: self).parse(node_child)
42
44
  when 'gridSpan'
43
45
  @grid_span = GridSpan.new(parent: self).parse(node_child)
44
46
  when 'tcW'
45
- @table_cell_width = OoxmlSize.new(node_child.attribute('w').value.to_f)
47
+ @table_cell_width = OoxmlSize.new.parse(node_child)
46
48
  when 'tcMar'
47
49
  @table_cell_margin = TableMargins.new(parent: self).parse(node_child)
48
50
  when 'textDirection'
49
- @text_direction = value_to_symbol(node_child.attribute('val'))
51
+ @text_direction_object = ValuedChild.new(:string, parent: self).parse(node_child)
52
+ @text_direction = value_to_symbol(@text_direction_object)
50
53
  when 'noWrap'
51
54
  @no_wrap = option_enabled?(node_child)
52
55
  when 'shd'
@@ -85,5 +88,12 @@ module OoxmlParser
85
88
  end
86
89
  self
87
90
  end
91
+
92
+ # @return [nil, Symbol] vertical align of cell
93
+ def vertical_align
94
+ return nil unless @vertical_align_object
95
+
96
+ @vertical_align_object.value
97
+ end
88
98
  end
89
99
  end
@@ -59,7 +59,8 @@ module OoxmlParser
59
59
  when 'tblW'
60
60
  @table_width = OoxmlSize.new.parse(node_child)
61
61
  when 'jc'
62
- @jc = node_child.attribute('val').text.to_sym
62
+ @justification_object = ValuedChild.new(:symbol, parent: self).parse(node_child)
63
+ @jc = @justification_object.value
63
64
  when 'shd'
64
65
  @shade = Shade.new(parent: self).parse(node_child)
65
66
  when 'solidFill'
@@ -67,7 +68,7 @@ module OoxmlParser
67
68
  when 'tblLook'
68
69
  @table_look = TableLook.new(parent: self).parse(node_child)
69
70
  when 'tblInd'
70
- @table_indent = OoxmlSize.new(node_child.attribute('w').text.to_f)
71
+ @table_indent = OoxmlSize.new(parent: self).parse(node_child)
71
72
  when 'tblpPr'
72
73
  @table_positon = TablePosition.new(parent: self).parse(node_child)
73
74
  when 'tblCellMar'
@@ -3,7 +3,11 @@
3
3
  module OoxmlParser
4
4
  # Class for parsing `u` tags
5
5
  class Underline < OOXMLDocumentObject
6
- attr_accessor :style, :color
6
+ attr_accessor :style
7
+ # @return [Color] color of underline
8
+ attr_accessor :color
9
+ # @return [Symbol] value of underline
10
+ attr_reader :value
7
11
 
8
12
  def initialize(style = :none, color = nil, parent: nil)
9
13
  @style = style == 'single' ? :single : style
@@ -38,6 +42,8 @@ module OoxmlParser
38
42
  # @param node [Nokogiri::XML:Element] node to parse
39
43
  # @return [Underline] result of parsing
40
44
  def parse(node)
45
+ parse_attributes(node) if node.is_a?(Nokogiri::XML::Element)
46
+
41
47
  case node
42
48
  when 'sng'
43
49
  @style = :single
@@ -46,5 +52,20 @@ module OoxmlParser
46
52
  end
47
53
  self
48
54
  end
55
+
56
+ private
57
+
58
+ # Parse attributes
59
+ # @param node [Nokogiri::XML:Element] node to parse
60
+ def parse_attributes(node)
61
+ node.attributes.each do |key, value|
62
+ case key
63
+ when 'color'
64
+ @color = Color.new(parent: self).parse_hex_string(value.value)
65
+ when 'val'
66
+ @value = value.value.to_sym
67
+ end
68
+ end
69
+ end
49
70
  end
50
71
  end
@@ -3,8 +3,6 @@
3
3
  module OoxmlParser
4
4
  # Class for working with any tag contained only value
5
5
  class ValuedChild < OOXMLDocumentObject
6
- # @return [String] value of tag
7
- attr_accessor :value
8
6
  # @return [String] type of value
9
7
  attr_reader :type
10
8
 
@@ -23,9 +21,30 @@ module OoxmlParser
23
21
  @value = value.value.to_s if type == :string
24
22
  @value = value_to_symbol(value) if type == :symbol
25
23
  @value = value.value.to_i if type == :integer
24
+ @value = value.value.to_f if type == :float
25
+ @value = parse_boolean(value.value.to_s) if type == :boolean
26
26
  end
27
27
  end
28
28
  self
29
29
  end
30
+
31
+ # @return [Object] value of parameter
32
+ def value
33
+ return true if type == :boolean && @value.nil?
34
+
35
+ @value
36
+ end
37
+
38
+ private
39
+
40
+ # Handle boolean value
41
+ # @param [String] value to parse
42
+ # @return [Boolean] result
43
+ def parse_boolean(value)
44
+ return true if value == '1'
45
+ return true if value == 'true'
46
+ return false if value == '0'
47
+ return false if value == 'false'
48
+ end
30
49
  end
31
50
  end
@@ -56,6 +56,7 @@ module OoxmlParser
56
56
  # @param password [String] password to file
57
57
  # @return [OoxmlFile] path to decrypted file
58
58
  def decrypt(password)
59
+ check_decryption_support
59
60
  file_name = File.basename(@path)
60
61
  tmp_folder = Dir.mktmpdir('ruby-ooxml-parser')
61
62
  decrypted_path = "#{tmp_folder}/#{file_name}"
@@ -64,5 +65,14 @@ module OoxmlParser
64
65
 
65
66
  OoxmlFile.new(decrypted_path)
66
67
  end
68
+
69
+ private
70
+
71
+ # Check if file can be decrypted
72
+ # @return [Boolean] is file encrypted
73
+ def check_decryption_support
74
+ # Because of https://github.com/woodbusy/ooxml_decrypt/issues/6
75
+ raise NotImplementedError, 'Cannot decrypt file on `jruby` platform' if RUBY_PLATFORM == 'java'
76
+ end
67
77
  end
68
78
  end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OoxmlParser
4
+ # Helper methods for parsing default style
5
+ module DefaultStyleHelper
6
+ # Parse default style
7
+ # @return [void]
8
+ def parse_default_style
9
+ parse_default_style_paragraph_properties
10
+ parse_default_style_run_properties
11
+ parse_default_character_style
12
+ DocumentStructure.default_table_paragraph_style = DocumentStructure.default_paragraph_style.dup
13
+ DocumentStructure.default_table_paragraph_style.spacing = Spacing.new(0, 0, 1, :auto)
14
+ DocumentStructure.default_table_run_style = DocumentStructure.default_run_style.dup
15
+ parse_default_table_style
16
+ end
17
+
18
+ # Perform parsing styles.xml
19
+ def parse_styles
20
+ file = "#{root_object.unpacked_folder}/word/styles.xml"
21
+ DocumentStructure.default_paragraph_style = DocxParagraph.new(parent: self)
22
+ DocumentStructure.default_table_paragraph_style = DocxParagraph.new(parent: self)
23
+ DocumentStructure.default_run_style = DocxParagraphRun.new(parent: self)
24
+ DocumentStructure.default_table_run_style = DocxParagraphRun.new(parent: self)
25
+
26
+ return unless File.exist?(file)
27
+
28
+ @styles = Styles.new(parent: self).parse
29
+ @numbering = Numbering.new(parent: self).parse
30
+
31
+ if @styles&.document_defaults&.paragraph_properties_default
32
+ DocumentStructure.default_paragraph_style = DocxParagraph.new(parent: self)
33
+ .parse(@styles.document_defaults
34
+ .paragraph_properties_default
35
+ .raw_node, 0)
36
+ end
37
+ if @styles&.document_defaults&.run_properties_default
38
+ DocumentStructure.default_run_style = DocxParagraphRun.new(parent: self)
39
+ .parse_properties(@styles
40
+ .document_defaults
41
+ .run_properties_default
42
+ .run_properties
43
+ .raw_node)
44
+ end
45
+ parse_default_style
46
+ end
47
+
48
+ private
49
+
50
+ def parse_default_style_paragraph_properties
51
+ return unless @styles&.default_style(:paragraph)&.paragraph_properties_node
52
+
53
+ DocxParagraph.new.parse_paragraph_style(@styles.default_style(:paragraph)
54
+ .paragraph_properties_node,
55
+ DocumentStructure.default_run_style)
56
+ end
57
+
58
+ def parse_default_style_run_properties
59
+ return unless @styles&.default_style(:paragraph)&.run_properties_node
60
+
61
+ DocumentStructure.default_run_style
62
+ .parse_properties(@styles.default_style(:paragraph)
63
+ .run_properties_node)
64
+ end
65
+
66
+ # Parse default character style
67
+ def parse_default_character_style
68
+ return unless @styles&.default_style(:character)&.run_properties_node
69
+
70
+ DocumentStructure.default_run_style
71
+ .parse_properties(@styles.default_style(:character)
72
+ .run_properties_node)
73
+ end
74
+
75
+ # Parse default table style
76
+ def parse_default_table_style
77
+ return unless @styles&.default_style(:table)&.run_properties_node
78
+
79
+ DocumentStructure.default_table_run_style
80
+ .parse_properties(@styles.default_style(:table)
81
+ .run_properties_node)
82
+ end
83
+ end
84
+ end
@@ -19,7 +19,12 @@ module OoxmlParser
19
19
  # @param node [Nokogiri::XML:Element] node to parse
20
20
  # @return [DocumentBackground] result of parsing
21
21
  def parse(node)
22
- @color1 = Color.new(parent: self).parse_hex_string(node.attribute('color').value)
22
+ node.attributes.each do |key, value|
23
+ case key
24
+ when 'color'
25
+ @color1 = Color.new(parent: self).parse_hex_string(value.value)
26
+ end
27
+ end
23
28
  node.xpath('v:background').each do |second_color|
24
29
  @size = second_color.attribute('targetscreensize').value.sub(',', 'x') unless second_color.attribute('targetscreensize').nil?
25
30
  second_color.xpath('*').each do |node_child|
@@ -39,6 +39,8 @@ module OoxmlParser
39
39
  # Used to determine if current style is visible in style list in editors
40
40
  # According to http://www.wordarticles.com/Articles/WordStyles/LatentStyles.php
41
41
  attr_accessor :q_format
42
+ # @return [Nokogiri::XML:Element] raw node value
43
+ attr_reader :raw_node
42
44
 
43
45
  alias visible? q_format
44
46
 
@@ -61,6 +63,7 @@ module OoxmlParser
61
63
  # Parse single document style
62
64
  # @return [DocumentStyle]
63
65
  def parse(node)
66
+ @raw_node = node
64
67
  node.attributes.each do |key, value|
65
68
  case key
66
69
  when 'type'
@@ -74,11 +77,14 @@ module OoxmlParser
74
77
  node.xpath('*').each do |subnode|
75
78
  case subnode.name
76
79
  when 'name'
77
- @name = subnode.attribute('val').value
80
+ @name_object = ValuedChild.new(:string, parent: self).parse(subnode)
81
+ @name = @name_object.value
78
82
  when 'basedOn'
79
- @based_on = subnode.attribute('val').value
83
+ @based_on_object = ValuedChild.new(:string, parent: self).parse(subnode)
84
+ @based_on = @based_on_object.value
80
85
  when 'next'
81
- @next_style = subnode.attribute('val').value
86
+ @next_style_object = ValuedChild.new(:string, parent: self).parse(subnode)
87
+ @next_style = @next_style_object.value
82
88
  when 'rPr'
83
89
  @run_properties_node = subnode
84
90
  @run_properties = DocxParagraphRun.new(parent: self).parse_properties(@run_properties_node)
@@ -3,7 +3,9 @@
3
3
  module OoxmlParser
4
4
  # Class for `acc` data
5
5
  class Accent < OOXMLDocumentObject
6
- attr_accessor :symbol, :element
6
+ # @return [ValuedChild] symbol object
7
+ attr_reader :symbol_object
8
+ attr_accessor :element
7
9
 
8
10
  # Parse Accent object
9
11
  # @param node [Nokogiri::XML:Element] node to parse
@@ -15,7 +17,7 @@ module OoxmlParser
15
17
  node_child.xpath('*').each do |node_child_child|
16
18
  case node_child_child.name
17
19
  when 'chr'
18
- @symbol = node_child_child.attribute('val').value
20
+ @symbol_object = ValuedChild.new(:string, parent: self).parse(node_child_child)
19
21
  end
20
22
  end
21
23
  end
@@ -23,5 +25,10 @@ module OoxmlParser
23
25
  @element = DocxFormula.new(parent: self).parse(node)
24
26
  self
25
27
  end
28
+
29
+ # @return [String] symbol value
30
+ def symbol
31
+ @symbol_object.value
32
+ end
26
33
  end
27
34
  end
@@ -3,10 +3,11 @@
3
3
  module OoxmlParser
4
4
  # Class for `bar` data
5
5
  class Bar < OOXMLDocumentObject
6
- attr_accessor :position, :element
6
+ # @return [ValuedChild] position object
7
+ attr_reader :position_object
8
+ attr_accessor :element
7
9
 
8
10
  def initialize(parent: nil)
9
- @position = :bottom
10
11
  super
11
12
  end
12
13
 
@@ -20,7 +21,7 @@ module OoxmlParser
20
21
  node_child.xpath('*').each do |node_child_child|
21
22
  case node_child_child.name
22
23
  when 'pos'
23
- @position = node_child_child.attribute('val').value.to_sym
24
+ @position_object = ValuedChild.new(:symbol, parent: self).parse(node_child_child)
24
25
  end
25
26
  end
26
27
  end
@@ -28,5 +29,10 @@ module OoxmlParser
28
29
  @element = DocxFormula.new(parent: self).parse(node)
29
30
  self
30
31
  end
32
+
33
+ # @return [Symbol] position of bar
34
+ def position
35
+ @position_object.value
36
+ end
31
37
  end
32
38
  end
@@ -3,7 +3,13 @@
3
3
  module OoxmlParser
4
4
  # Class for `groupChr` data
5
5
  class GroupChar < OOXMLDocumentObject
6
- attr_accessor :symbol, :position, :vertical_align, :element
6
+ # @return [ValuedChild] symbol object
7
+ attr_reader :symbol_object
8
+ # @return [ValuedChild] position object
9
+ attr_reader :position_object
10
+ # @return [ValuedChild] vertical align object
11
+ attr_reader :vertical_align_object
12
+ attr_accessor :element
7
13
 
8
14
  # Parse GroupChar object
9
15
  # @param node [Nokogiri::XML:Element] node to parse
@@ -15,11 +21,11 @@ module OoxmlParser
15
21
  node_child.xpath('*').each do |node_child_child|
16
22
  case node_child_child.name
17
23
  when 'chr'
18
- @symbol = node_child_child.attribute('val').value
24
+ @symbol_object = ValuedChild.new(:string, parent: self).parse(node_child_child)
19
25
  when 'pos'
20
- @position = node_child_child.attribute('val').value
26
+ @position_object = ValuedChild.new(:string, parent: self).parse(node_child_child)
21
27
  when 'vertJc'
22
- @vertical_align = node_child_child.attribute('val').value
28
+ @vertical_align_object = ValuedChild.new(:string, parent: self).parse(node_child_child)
23
29
  end
24
30
  end
25
31
  end
@@ -27,5 +33,20 @@ module OoxmlParser
27
33
  @element = DocxFormula.new(parent: self).parse(node)
28
34
  self
29
35
  end
36
+
37
+ # @return [String] symbol value
38
+ def symbol
39
+ @symbol_object.value
40
+ end
41
+
42
+ # @return [String] position value
43
+ def position
44
+ @position_object.value
45
+ end
46
+
47
+ # @return [String] vertical align value
48
+ def vertical_align
49
+ @vertical_align_object.value
50
+ end
30
51
  end
31
52
  end
@@ -22,7 +22,8 @@ module OoxmlParser
22
22
  mcs.xpath('m:mc').each do |mc|
23
23
  mc.xpath('m:mcPr').each do |mc_pr|
24
24
  mc_pr.xpath('m:count').each do |count|
25
- columns_count = count.attribute('val').value.to_i
25
+ count_object = ValuedChild.new(:integer, parent: self).parse(count)
26
+ columns_count = count_object.value
26
27
  end
27
28
  end
28
29
  end
@@ -11,33 +11,40 @@ module OoxmlParser
11
11
  node.xpath('*').each do |node_child|
12
12
  case node_child.name
13
13
  when 'rFonts'
14
+ run_fonts = RunFonts.new(parent: self).parse(node_child)
14
15
  node_child.attributes.each do |font_attribute, value|
15
16
  case font_attribute
16
17
  when 'asciiTheme'
17
- theme = node_child.attribute('asciiTheme').value
18
18
  next unless root_object.theme
19
19
 
20
- self.font = root_object.theme.font_scheme.major_font.latin.typeface if theme.include?('major')
21
- self.font = root_object.theme.font_scheme.minor_font.latin.typeface if theme.include?('minor')
20
+ self.font = root_object.theme.font_scheme.major_font.latin.typeface if run_fonts.ascii_theme.include?('major')
21
+ self.font = root_object.theme.font_scheme.minor_font.latin.typeface if run_fonts.ascii_theme.include?('minor')
22
22
  when 'ascii'
23
23
  self.font = value.value
24
24
  break
25
25
  end
26
26
  end
27
27
  when 'sz'
28
- self.size = node_child.attribute('val').value.to_i / 2.0
28
+ @size_object = ValuedChild.new(:integer, parent: self).parse(node_child)
29
+ self.size = @size_object.value.to_i / 2.0
29
30
  when 'highlight'
30
- self.highlight = node_child.attribute('val').value
31
+ @highlight_object = ValuedChild.new(:string, parent: self).parse(node_child)
32
+ self.highlight = @highlight_object.value
31
33
  when 'vertAlign'
32
- self.vertical_align = node_child.attribute('val').value.to_sym
34
+ @vertical_align_object = ValuedChild.new(:symbol, parent: self).parse(node_child)
35
+ self.vertical_align = @vertical_align_object.value
33
36
  when 'effect'
34
- self.effect = node_child.attribute('val').value
37
+ @effect_object = ValuedChild.new(:string, parent: self).parse(node_child)
38
+ self.effect = @effect_object.value
35
39
  when 'position'
36
- self.position = (node_child.attribute('val').value.to_f / (28.0 + (1.0 / 3.0)) / 2.0).round(1)
40
+ @position_object = ValuedChild.new(:integer, parent: self).parse(node_child)
41
+ self.position = (@position_object.value.to_f / (28.0 + (1.0 / 3.0)) / 2.0).round(1)
37
42
  when 'em'
38
- self.em = node_child.attribute('val').value
43
+ @em_object = ValuedChild.new(:string, parent: self).parse(node_child)
44
+ self.em = @em_object.value
39
45
  when 'spacing'
40
- self.spacing = (node_child.attribute('val').value.to_f / 566.9).round(1)
46
+ @spacing_object = RunSpacing.new(parent: self).parse(node_child)
47
+ self.spacing = (@spacing_object.value.value.to_f / 566.9).round(1)
41
48
  when 'textFill'
42
49
  self.text_fill = TextFill.new(parent: self).parse(node_child)
43
50
  when 'textOutline'
@@ -98,12 +105,13 @@ module OoxmlParser
98
105
  # @param node [Nokogiri::XML:Element] node to parse
99
106
  # @return [nil]
100
107
  def parse_underline(node)
108
+ underline_object = Underline.new.parse(node)
101
109
  font_style.underlined = Underline.new
102
110
 
103
- return unless option_enabled?(node)
111
+ return unless underline_object.value
104
112
 
105
- font_style.underlined.style = node.attribute('val').value
106
- font_style.underlined.color = Color.new(parent: font_style.underlined).parse_hex_string(node.attribute('color').value) unless node.attribute('color').nil?
113
+ font_style.underlined.style = underline_object.value
114
+ font_style.underlined.color = underline_object.color if underline_object.color
107
115
  end
108
116
  end
109
117
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OoxmlParser
4
+ # Class for parsing `w:fldChar` object
5
+ class FieldChar < OOXMLDocumentObject
6
+ # @return [Symbol] type of field char
7
+ attr_accessor :type
8
+
9
+ # Parse FieldChar
10
+ # @param [Nokogiri::XML:Node] node with FieldChar
11
+ # @return [FieldChar] result of parsing
12
+ def parse(node)
13
+ node.attributes.each do |key, value|
14
+ case key
15
+ when 'fldCharType'
16
+ @type = value.value.to_sym
17
+ end
18
+ end
19
+ self
20
+ end
21
+ end
22
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'docx_paragraph_run/docx_paragraph_run_helpers'
4
+ require_relative 'docx_paragraph_run/field_char'
4
5
  require_relative 'docx_paragraph_run/instruction_text'
5
6
  require_relative 'docx_paragraph_run/object'
6
7
  require_relative 'docx_paragraph_run/text_outline'
@@ -103,7 +104,8 @@ module OoxmlParser
103
104
  @text = '*PAGE NUMBER*'
104
105
  end
105
106
  when 'fldChar'
106
- @fld_char = node_child.attribute('fldCharType').value.to_sym
107
+ @field_char_object = FieldChar.new(parent: self).parse(node_child)
108
+ @fld_char = @field_char_object.type
107
109
  when 't'
108
110
  @text += node_child.text
109
111
  when 'noBreakHyphen'
@@ -30,7 +30,7 @@ module OoxmlParser
30
30
  when 'helpText'
31
31
  @help_text = value.value
32
32
  when 'required'
33
- @required = option_enabled?(value)
33
+ @required = boolean_attribute_value(value)
34
34
  end
35
35
  end
36
36
 
@@ -23,9 +23,9 @@ module OoxmlParser
23
23
  node.attributes.each do |key, value|
24
24
  case key
25
25
  when 'multiLine'
26
- @multiline = option_enabled?(value)
26
+ @multiline = boolean_attribute_value(value)
27
27
  when 'autoFit'
28
- @autofit = option_enabled?(value)
28
+ @autofit = boolean_attribute_value(value)
29
29
  end
30
30
  end
31
31
 
@@ -16,7 +16,7 @@ module OoxmlParser
16
16
  # Class for data of DocxParagraph
17
17
  class DocxParagraph < OOXMLDocumentObject
18
18
  include DocxParagraphHelper
19
- attr_accessor :number, :align, :spacing, :ind, :numbering,
19
+ attr_accessor :number, :align, :numbering,
20
20
  :character_style_array, :page_break, :borders, :keep_lines,
21
21
  :contextual_spacing, :sector_properties, :page_numbering, :section_break, :style, :keep_next,
22
22
  :orphan_control
@@ -32,6 +32,8 @@ module OoxmlParser
32
32
  attr_accessor :paragraph_id
33
33
  # @return [MathParagraph] math paragraph
34
34
  attr_reader :math_paragraph
35
+ # Set spacing value
36
+ attr_writer :spacing
35
37
  # @return [Integer] id of text (for comment)
36
38
  attr_accessor :text_id
37
39
 
@@ -59,7 +61,7 @@ module OoxmlParser
59
61
  def initialize_copy(source)
60
62
  super
61
63
  @character_style_array = source.character_style_array.clone
62
- @spacing = source.spacing.clone
64
+ @spacing = source.instance_variable_get(:@spacing).clone
63
65
  end
64
66
 
65
67
  # @return [Array<OOXMLDocumentObject>] array of child objects that contains data
@@ -147,10 +149,10 @@ module OoxmlParser
147
149
  @hyperlink = Hyperlink.new(parent: self).parse(node_child)
148
150
  character_style = default_character_style.dup
149
151
  character_style.parent = self
150
- if node_child.attribute('id')
152
+ if @hyperlink.id
151
153
  character_style.link = Hyperlink.new(parent: character_style).parse(node_child)
152
- elsif node_child.attribute('anchor')
153
- character_style.link = node_child.attribute('anchor').value
154
+ elsif @hyperlink.anchor
155
+ character_style.link = @hyperlink.anchor
154
156
  end
155
157
  node_child.xpath('w:r').each do |r_tag|
156
158
  character_style.parse(r_tag, char_number, parent: self)
@@ -204,12 +206,13 @@ module OoxmlParser
204
206
  @paragraph_style_ref = ParagraphStyleRef.new(parent: self).parse(node_child)
205
207
  fill_style_data(default_char_style)
206
208
  when 'ind'
207
- @ind = DocumentStructure.default_paragraph_style.ind.dup.parse(node_child)
209
+ @ind = DocumentStructure.default_paragraph_style.instance_variable_get(:@ind).dup.parse(node_child)
208
210
  when 'numPr'
209
211
  @numbering = NumberingProperties.new(parent: self).parse(node_child)
210
212
  when 'jc'
211
- @align = node_child.attribute('val').value.to_sym unless node_child.attribute('val').nil?
212
- @align = :justify if node_child.attribute('val').value == 'both'
213
+ @justification_object = ValuedChild.new(:string, parent: self).parse(node_child)
214
+ @align = @justification_object.value.to_sym unless @justification_object.value.nil?
215
+ @align = :justify if @justification_object.value == 'both'
213
216
  when 'spacing'
214
217
  @valued_spacing = ParagraphSpacing.new(parent: self).parse(node_child)
215
218
  @spacing = @spacing.fetch_from_valued_spacing(@valued_spacing)
@@ -229,6 +232,20 @@ module OoxmlParser
229
232
  self
230
233
  end
231
234
 
235
+ def spacing
236
+ style_spacing = root_object.styles&.default_style(:paragraph)&.paragraph_properties&.spacing
237
+ return Spacing.new.fetch_from_valued_spacing(style_spacing) if style_spacing
238
+
239
+ @spacing
240
+ end
241
+
242
+ # @return [Indents] value of indents
243
+ def ind
244
+ return @ind if @ind != Indents.new
245
+
246
+ root_object.styles&.default_style(:paragraph)&.paragraph_properties&.indent
247
+ end
248
+
232
249
  # Fill data from styles
233
250
  # @param character_style [DocxParagraphRun] style to parse
234
251
  # @return [void]