rocx 0.6.0 → 0.7.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/lib/rocx.rb +2 -0
  4. data/lib/rocx/elements/container.rb +2 -56
  5. data/lib/rocx/elements/paper_source.rb +11 -0
  6. data/lib/rocx/elements/paragraph.rb +16 -1
  7. data/lib/rocx/parts/document.rb +18 -4
  8. data/lib/rocx/properties.rb +1 -0
  9. data/lib/rocx/properties/column.rb +16 -0
  10. data/lib/rocx/properties/columns.rb +13 -0
  11. data/lib/rocx/properties/container_property.rb +63 -0
  12. data/lib/rocx/properties/document_grid.rb +20 -0
  13. data/lib/rocx/properties/form_protection.rb +7 -0
  14. data/lib/rocx/properties/line_numbering.rb +21 -0
  15. data/lib/rocx/properties/page_borders.rb +59 -0
  16. data/lib/rocx/properties/page_margins.rb +15 -0
  17. data/lib/rocx/properties/page_numbering.rb +87 -0
  18. data/lib/rocx/properties/page_size.rb +21 -0
  19. data/lib/rocx/properties/{borders.rb → paragraph_borders.rb} +3 -2
  20. data/lib/rocx/properties/rtl_gutter.rb +6 -0
  21. data/lib/rocx/properties/section_type.rb +13 -0
  22. data/lib/rocx/properties/tabs.rb +2 -41
  23. data/lib/rocx/properties/vertical_text_alignment.rb +12 -0
  24. data/lib/rocx/property_builder.rb +72 -0
  25. data/lib/rocx/section.rb +34 -0
  26. data/lib/rocx/version.rb +1 -1
  27. data/spec/elements/ruby_spec.rb +5 -5
  28. data/spec/parts/document_spec.rb +63 -0
  29. data/spec/properties/column_spec.rb +46 -0
  30. data/spec/properties/columns_spec.rb +174 -0
  31. data/spec/properties/document_grid_spec.rb +78 -0
  32. data/spec/properties/form_protection_spec.rb +23 -0
  33. data/spec/properties/line_numbering_spec.rb +96 -0
  34. data/spec/properties/page_borders_spec.rb +129 -0
  35. data/spec/properties/page_margins_spec.rb +150 -0
  36. data/spec/properties/page_numbering_spec.rb +395 -0
  37. data/spec/properties/page_size_spec.rb +90 -0
  38. data/spec/properties/paper_source_spec.rb +56 -0
  39. data/spec/properties/{borders_spec.rb → paragraph_borders_spec.rb} +1 -1
  40. data/spec/properties/rtl_gutter_spec.rb +23 -0
  41. data/spec/properties/section_type_spec.rb +33 -0
  42. data/spec/properties/vertical_text_alignment_spec.rb +28 -0
  43. data/spec/section_spec.rb +44 -0
  44. data/spec/support/data/parts/document_with_multiple_sections_part.xml +24 -0
  45. data/spec/support/data/parts/document_with_one_section_part.xml +16 -0
  46. data/spec/support/element_test_macros.rb +28 -8
  47. data/spec/support/part_test_macros.rb +1 -1
  48. data/spec/support/property_test_macros.rb +4 -4
  49. metadata +36 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e9bb4b4bab84d40e70d311607aa9fcf27ede7b44
4
- data.tar.gz: d2f2f6aa0ddf9e421ac86e31296554e68f53f8a9
3
+ metadata.gz: 087387779bf11613186b3a7e1192ed99ca739b52
4
+ data.tar.gz: c3277390bd9fbfd8fe17743ea8762849010fe559
5
5
  SHA512:
6
- metadata.gz: dabe3d744f0c26832981c7c9bd9b265ef6684645a892cb190eb5c67d7e01a926234d370e9e8aa76839b3e2c0920a323bd567bd08234c96aa46b3db1663e615ed
7
- data.tar.gz: 558350fdb7d8bd5de5ba2c36cc5f3a2f49f3b5fcf8f38198d07f6d8ad6d6325471c0df7ce180ac59ec5e09afef00afc7e00a95fd61fa325ef7156719a5849a34
6
+ metadata.gz: 0b756fec89e558eae5aaec023459d78e223f2ee12d347d5c36f435fab62a31840708d2815131251f606d90afdc8ef2b65f223ab97acc9119af585075a9d743e4
7
+ data.tar.gz: 8174d565f6469b87d99a0bc4121bbd3fb886148d474049000ba562cbd2cc5abb45670d3c4e5fd7bb41cd82543396cbc5e75a15956d312547411bfef974a86cf1
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rocx (0.6.0)
4
+ rocx (0.7.0)
5
5
  nokogiri
6
6
  open_xml_package
7
7
 
@@ -1,8 +1,10 @@
1
1
  require "rocx/attribute_builder"
2
+ require "rocx/property_builder"
2
3
  require "rocx/properties"
3
4
  require "rocx/elements"
4
5
  require "rocx/package"
5
6
  require "rocx/parts"
7
+ require "rocx/section"
6
8
  require "rocx/style"
7
9
 
8
10
  module Rocx
@@ -1,51 +1,9 @@
1
1
  module Rocx
2
2
  module Elements
3
3
  class Container < Element
4
- attr_reader :children
5
-
6
- class << self
7
- def properties_tag(*args)
8
- @properties_tag = args.first if args.any?
9
- @properties_tag
10
- end
11
-
12
- def value_property(name, as: nil)
13
- attr_reader name
14
-
15
- properties[name] = (as || name).to_s
16
-
17
- class_eval <<-CODE, __FILE__, __LINE__ + 1
18
- def #{name}=(value)
19
- property_key = "#{name}".to_sym
20
- class_name = properties[property_key].split("_").map(&:capitalize).join
21
- prop_class = Rocx::Properties.const_get class_name
22
- instance_variable_set "@#{name}", prop_class.new(value)
23
- end
24
- CODE
25
- end
26
-
27
- def property(name, as: nil)
28
- properties[name] = (as || name).to_s
29
-
30
- class_eval <<-CODE, __FILE__, __LINE__ + 1
31
- def #{name}
32
- property_key = "#{name}".to_sym
33
- class_name = properties[property_key].split("_").map(&:capitalize).join
34
- prop_class = Rocx::Properties.const_get class_name
35
-
36
- if instance_variable_get("@#{name}").nil?
37
- instance_variable_set "@#{name}", prop_class.new
38
- end
4
+ include PropertyBuilder
39
5
 
40
- instance_variable_get "@#{name}"
41
- end
42
- CODE
43
- end
44
-
45
- def properties
46
- @properties ||= {}
47
- end
48
- end
6
+ attr_reader :children
49
7
 
50
8
  def initialize
51
9
  @children = []
@@ -64,18 +22,6 @@ module Rocx
64
22
 
65
23
  private
66
24
 
67
- def property_xml(xml)
68
- props = properties.keys.map(&method(:send)).compact
69
- return if props.none?(&:render?)
70
- xml[namespace].public_send(properties_tag) {
71
- props.each { |prop| prop.to_xml(xml) }
72
- }
73
- end
74
-
75
- def properties
76
- self.class.properties
77
- end
78
-
79
25
  def properties_tag
80
26
  self.class.properties_tag || default_properties_tag
81
27
  end
@@ -0,0 +1,11 @@
1
+ module Rocx
2
+ module Properties
3
+ class PaperSource < ComplexProperty
4
+ tag :paperSrc
5
+
6
+ attribute :first, expects: :integer
7
+ attribute :other, expects: :integer
8
+
9
+ end
10
+ end
11
+ end
@@ -1,6 +1,7 @@
1
1
  module Rocx
2
2
  module Elements
3
3
  class Paragraph < Container
4
+ attr_reader :section_properties
4
5
  tag :p
5
6
 
6
7
  value_property :alignment
@@ -28,7 +29,7 @@ module Rocx
28
29
  value_property :widow_control
29
30
  value_property :word_wrap
30
31
 
31
- property :borders
32
+ property :borders, as: :paragraph_borders
32
33
  property :conditional_formatting
33
34
  property :frame
34
35
  property :indentation
@@ -36,6 +37,20 @@ module Rocx
36
37
  property :shading
37
38
  property :spacing
38
39
  property :tabs
40
+
41
+ def section_properties=(section)
42
+ raise ArgumentError, "Section properties must be an instance of Rocx::Section" unless section.is_a?(Rocx::Section)
43
+ @section_properties = section
44
+ end
45
+
46
+ def to_xml(xml)
47
+ xml[namespace].public_send(tag, xml_attributes) {
48
+ section_properties.to_xml(xml) unless section_properties.nil?
49
+ property_xml(xml)
50
+ children.each { |child| child.to_xml(xml) }
51
+ }
52
+ end
53
+
39
54
  end
40
55
  end
41
56
  end
@@ -1,22 +1,36 @@
1
1
  module Rocx
2
2
  module Parts
3
3
  class Document < BasePart
4
- attr_reader :children
4
+ attr_reader :children, :current_section
5
5
 
6
6
  def initialize
7
7
  @children = []
8
8
  end
9
9
 
10
10
  def <<(child)
11
- children << child
11
+ if child.is_a?(Rocx::Section)
12
+ set_section(child)
13
+ else
14
+ children << child
15
+ end
16
+ end
17
+
18
+ def set_section(section)
19
+ if current_section.nil?
20
+ @current_section = section
21
+ else
22
+ children.last.section_properties = current_section
23
+ @current_section = section
24
+ end
12
25
  end
13
26
 
14
27
  def to_xml
15
28
  build_xml do |xml|
16
29
  xml.document(root_namespaces) {
17
- xml.parent.namespace = xml.parent.namespace_definitions.find { |ns| ns.prefix == 'w' }
18
- xml['w'].body {
30
+ xml.parent.namespace = xml.parent.namespace_definitions.find { |ns| ns.prefix == "w" }
31
+ xml["w"].body {
19
32
  children.each { |child| child.to_xml(xml) }
33
+ current_section.to_xml(xml) unless current_section.nil?
20
34
  }
21
35
  }
22
36
  end
@@ -11,6 +11,7 @@ require "rocx/properties/integer_property"
11
11
  require "rocx/properties/positive_integer_property"
12
12
  require "rocx/properties/on_off_property"
13
13
  require "rocx/properties/toggle_property"
14
+ require "rocx/properties/container_property"
14
15
  require "rocx/properties/style"
15
16
  Dir.glob("#{File.join(File.dirname(__FILE__), "properties", "*.rb")}").each do |file|
16
17
  require file
@@ -0,0 +1,16 @@
1
+ module Rocx
2
+ module Properties
3
+ class Column < ComplexProperty
4
+ tag :col
5
+
6
+ attribute :space, expects: :positive_integer
7
+ attribute :width, expects: :positive_integer, displays_as: :w
8
+
9
+ def initialize(space, width)
10
+ self.space = space
11
+ self.width = width
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ module Rocx
2
+ module Properties
3
+ class Columns < ContainerProperty
4
+ tag :cols
5
+ child_class :column
6
+
7
+ attribute :equal_width, expects: :true_or_false
8
+ attribute :number, expects: :integer, displays_as: :num
9
+ attribute :separator, expects: :true_or_false, displays_as: :sep
10
+ attribute :space, expects: :integer
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,63 @@
1
+ module Rocx
2
+ module Properties
3
+ class ContainerProperty < BaseProperty
4
+ include Enumerable
5
+ include AttributeBuilder
6
+
7
+ class << self
8
+ def child_class(*args)
9
+ if args.any?
10
+ prop_name = args.first.to_s.capitalize
11
+ child_class_obj = Rocx::Properties.const_get prop_name
12
+ @child_class = Rocx::Properties.const_get prop_name
13
+ end
14
+
15
+ @child_class
16
+ end
17
+ end
18
+
19
+ def initialize
20
+ @children = []
21
+ end
22
+
23
+ def <<(child)
24
+ raise ArgumentError, invalid_child_message unless valid_child?(child)
25
+ children << child
26
+ end
27
+
28
+ def each(*args, &block)
29
+ children.each *args, &block
30
+ end
31
+
32
+ def render?
33
+ !children.length.zero?
34
+ end
35
+
36
+ def to_xml(xml)
37
+ return unless render?
38
+
39
+ xml["w"].public_send(tag, xml_attributes) {
40
+ each { |child| child.to_xml(xml) }
41
+ }
42
+ end
43
+
44
+ private
45
+
46
+ attr_reader :children
47
+
48
+ def invalid_child_message
49
+ class_name = self.class.to_s.split(/::/).last
50
+ "#{class_name} must be instances of Rocx::Properties::#{child_class}"
51
+ end
52
+
53
+ def valid_child?(child)
54
+ child.is_a?(child_class)
55
+ end
56
+
57
+ def child_class
58
+ self.class.child_class
59
+ end
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,20 @@
1
+ module Rocx
2
+ module Properties
3
+ class DocumentGrid < ComplexProperty
4
+ tag :docGrid
5
+
6
+ attribute :char_space, expects: :integer
7
+ attribute :line_pitch, expects: :integer
8
+ attribute :type, expects: :valid_grid_type
9
+
10
+ VALID_GRID_TYPES = %i(default lines linesAndChars snapToChars)
11
+
12
+ private
13
+
14
+ def valid_grid_type(value)
15
+ valid_in? value, VALID_GRID_TYPES
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ module Rocx
2
+ module Properties
3
+ class FormProtection < ToggleProperty
4
+ tag :formProt
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ module Rocx
2
+ module Properties
3
+ class LineNumbering < ComplexProperty
4
+ tag :lnNumType
5
+
6
+ attribute :count_by, expects: :integer
7
+ attribute :distance, expects: :positive_integer
8
+ attribute :restart, expects: :valid_line_numbering_restart
9
+ attribute :start, expects: :integer
10
+
11
+ VALID_LINE_NUMBERING_RESTARTS = %i(continuous newPage newSection)
12
+
13
+ private
14
+
15
+ def valid_line_numbering_restart(value)
16
+ valid_in? value, VALID_LINE_NUMBERING_RESTARTS
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,59 @@
1
+ module Rocx
2
+ module Properties
3
+ class PageBorders < ComplexProperty
4
+ attr_reader :left, :right, :top, :bottom
5
+
6
+ tag :pgBorders
7
+ attribute :display, expects: :valid_display
8
+ attribute :offset_from, expects: :valid_offset
9
+ attribute :z_order, expects: :valid_z_order
10
+
11
+ def initialize
12
+ @left = new_border :left
13
+ @right = new_border :right
14
+ @top = new_border :top
15
+ @bottom = new_border :bottom
16
+ end
17
+
18
+ def render?
19
+ renderable_borders.any?
20
+ end
21
+
22
+ def to_xml(xml)
23
+ return unless render?
24
+ xml["w"].public_send(tag, xml_attributes) { render_borders_xml(xml) }
25
+ end
26
+
27
+ VALID_DISPLAYS = %i(allPages firstPage notFirstPage)
28
+ VALID_OFFSETS = %i(page text)
29
+ VALID_Z_ORDERS = %i(front back)
30
+
31
+ private
32
+
33
+ def render_borders_xml(xml)
34
+ renderable_borders.each { |border| border.to_xml(xml) }
35
+ end
36
+
37
+ def renderable_borders
38
+ [@left, @right, @top, @bottom].select(&:render?)
39
+ end
40
+
41
+ def new_border(direction)
42
+ Rocx::Properties::Border.new direction
43
+ end
44
+
45
+ def valid_display(value)
46
+ valid_in? value, VALID_DISPLAYS
47
+ end
48
+
49
+ def valid_offset(value)
50
+ valid_in? value, VALID_OFFSETS
51
+ end
52
+
53
+ def valid_z_order(value)
54
+ valid_in? value, VALID_Z_ORDERS
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,15 @@
1
+ module Rocx
2
+ module Properties
3
+ class PageMargins < ComplexProperty
4
+ tag :pgMar
5
+
6
+ attribute :bottom, expects: :integer
7
+ attribute :footer, expects: :positive_integer
8
+ attribute :gutter, expects: :positive_integer
9
+ attribute :header, expects: :positive_integer
10
+ attribute :left, expects: :positive_integer
11
+ attribute :right, expects: :positive_integer
12
+ attribute :top, expects: :integer
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,87 @@
1
+ module Rocx
2
+ module Properties
3
+ class PageNumbering < ComplexProperty
4
+ tag :pgNumType
5
+
6
+ attribute :chapter_separator, expects: :valid_chapter_separator, displays_as: :chapSep
7
+ attribute :chapter_style, expects: :integer, displays_as: :chapStyle
8
+ attribute :format, expects: :valid_page_number_format, displays_as: :fmt
9
+ attribute :start, expects: :integer
10
+
11
+ VALID_CHAPTER_SEPARATORS = %i(colon emDash enDash hyphen period)
12
+ VALID_PAGE_NUMBER_FORMATS = %i(aiueo
13
+ aiueoFullWidth
14
+ arabicAbjad
15
+ arabicAlpha
16
+ bahtText
17
+ bullet
18
+ cardinalText
19
+ chicago
20
+ chineseCounting
21
+ chineseCountingThousand
22
+ chineseLegalSimplified
23
+ chosung
24
+ custom
25
+ decimal
26
+ decimalEnclosedCircle
27
+ decimalEnclosedCircleChinese
28
+ decimalEnclosedFullstop
29
+ decimalEnclosedParen
30
+ decimalFullWidth
31
+ decimalHalfWidth
32
+ decimalZero
33
+ dollarText
34
+ ganada
35
+ hebrew1
36
+ hebrew2
37
+ hex
38
+ hindiConsonants
39
+ hindiCounting
40
+ hindiNumbers
41
+ hindiVowels
42
+ ideographDigital
43
+ ideographEnclosedCircle
44
+ taiwaneseDigital
45
+ ideographLegalTraditional
46
+ ideographTraditional
47
+ ideographZodiac
48
+ ideographZodiacTraditional
49
+ iroha
50
+ irohaFullWidth
51
+ japaneseCounting
52
+ japaneseDigitalTenThousand
53
+ japaneseLegal
54
+ koreanCounting
55
+ koreanDigital
56
+ koreanDigital2
57
+ koreanLegal
58
+ lowerLetter
59
+ lowerRoman
60
+ none
61
+ numberInDash
62
+ ordinal
63
+ ordinalText
64
+ russianLower
65
+ russianUpper
66
+ taiwaneseCounting
67
+ taiwaneseCountingThousand
68
+ thaiCounting
69
+ thaiLetters
70
+ thaiNumbers
71
+ upperLetter
72
+ upperRoman
73
+ vietnameseCounting)
74
+
75
+ private
76
+
77
+ def valid_chapter_separator(value)
78
+ valid_in? value, VALID_CHAPTER_SEPARATORS
79
+ end
80
+
81
+ def valid_page_number_format(value)
82
+ valid_in? value, VALID_PAGE_NUMBER_FORMATS
83
+ end
84
+
85
+ end
86
+ end
87
+ end