ooxml_parser 0.33.0 → 0.34.1

Sign up to get free protection for your applications and to get access to all the features.
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]