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
@@ -0,0 +1,21 @@
1
+ module Rocx
2
+ module Properties
3
+ class PageSize < ComplexProperty
4
+ tag :pgSz
5
+
6
+ attribute :code, expects: :integer
7
+ attribute :height, expects: :positive_integer, displays_as: :h
8
+ attribute :orientation, expects: :valid_orientation, displays_as: :orient
9
+ attribute :width, expects: :positive_integer, displays_as: :w
10
+
11
+ VALID_PAGE_ORIENTATIONS = %i(portrait landscape)
12
+
13
+ private
14
+
15
+ def valid_orientation(value)
16
+ valid_in? value, VALID_PAGE_ORIENTATIONS
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -1,6 +1,6 @@
1
1
  module Rocx
2
2
  module Properties
3
- class Borders < ComplexProperty
3
+ class ParagraphBorders < ComplexProperty
4
4
  attr_reader :left, :right, :top, :bottom, :between, :bar
5
5
 
6
6
  def initialize
@@ -13,9 +13,10 @@ module Rocx
13
13
  end
14
14
 
15
15
  tag :pBdr
16
+ name "borders"
16
17
 
17
18
  def render?
18
- !renderable_borders.length.zero?
19
+ renderable_borders.any?
19
20
  end
20
21
 
21
22
  def to_xml(xml)
@@ -0,0 +1,6 @@
1
+ module Rocx
2
+ module Properties
3
+ class RtlGutter < BooleanProperty
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ module Rocx
2
+ module Properties
3
+ class SectionType < ValueProperty
4
+ tag :type
5
+ name "type"
6
+
7
+ def ok_values
8
+ %i(continuous evenPage nextColumn nextPage oddPage)
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -1,46 +1,7 @@
1
1
  module Rocx
2
2
  module Properties
3
- class Tabs < BaseProperty
4
- include Enumerable
5
-
6
- def initialize
7
- @tabs = []
8
- end
9
-
10
- def <<(tab)
11
- raise ArgumentError, invalid_tab_message unless valid_tab?(tab)
12
- tabs << tab
13
- end
14
-
15
- def each(*args, &block)
16
- tabs.each *args, &block
17
- end
18
-
19
- def render?
20
- !tabs.length.zero?
21
- end
22
-
23
- def to_xml(xml)
24
- return unless render?
25
-
26
- xml["w"].public_send(tag) {
27
- each { |tab| tab.to_xml(xml) }
28
- }
29
- end
30
-
31
- protected
32
-
33
- attr_reader :tabs
34
-
35
- private
36
-
37
- def invalid_tab_message
38
- "Tabs must be instances of Rocx::Properties::Tab"
39
- end
40
-
41
- def valid_tab?(tab)
42
- tab.is_a?(Rocx::Properties::Tab)
43
- end
3
+ class Tabs < ContainerProperty
4
+ child_class :tab
44
5
 
45
6
  end
46
7
  end
@@ -0,0 +1,12 @@
1
+ module Rocx
2
+ module Properties
3
+ class VerticalTextAlignment < ValueProperty
4
+ tag :vAlign
5
+
6
+ def ok_values
7
+ %i(both bottom center top)
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,72 @@
1
+ module Rocx
2
+ module PropertyBuilder
3
+
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def properties_tag(*args)
10
+ @properties_tag = args.first if args.any?
11
+ @properties_tag
12
+ end
13
+
14
+ def value_property(name, as: nil)
15
+ attr_reader name
16
+
17
+ properties[name] = (as || name).to_s
18
+
19
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
20
+ def #{name}=(value)
21
+ property_key = "#{name}".to_sym
22
+ class_name = properties[property_key].split("_").map(&:capitalize).join
23
+ prop_class = Rocx::Properties.const_get class_name
24
+ instance_variable_set "@#{name}", prop_class.new(value)
25
+ end
26
+ CODE
27
+ end
28
+
29
+ def property(name, as: nil)
30
+ properties[name] = (as || name).to_s
31
+
32
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
33
+ def #{name}
34
+ property_key = "#{name}".to_sym
35
+ class_name = properties[property_key].split("_").map(&:capitalize).join
36
+ prop_class = Rocx::Properties.const_get class_name
37
+
38
+ if instance_variable_get("@#{name}").nil?
39
+ instance_variable_set "@#{name}", prop_class.new
40
+ end
41
+
42
+ instance_variable_get "@#{name}"
43
+ end
44
+ CODE
45
+ end
46
+
47
+ def properties
48
+ @properties ||= {}
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def property_xml(xml)
55
+ props = properties.keys.map(&method(:send)).compact
56
+ return if props.none?(&:render?)
57
+
58
+ xml[namespace].public_send(properties_tag) {
59
+ props.each { |prop| prop.to_xml(xml) }
60
+ }
61
+ end
62
+
63
+ def properties
64
+ self.class.properties
65
+ end
66
+
67
+ def properties_tag
68
+ self.class.properties_tag
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,34 @@
1
+ module Rocx
2
+ class Section
3
+ include PropertyBuilder
4
+
5
+ properties_tag :sectPr
6
+
7
+ property :columns
8
+ property :document_grid
9
+ property :line_numbering
10
+ property :page_borders
11
+ property :page_margins
12
+ property :page_numbering
13
+ property :page_size
14
+ property :paper_source
15
+
16
+ value_property :bidi
17
+ value_property :form_protection
18
+ value_property :rtl_gutter
19
+ value_property :text_direction
20
+ value_property :type, as: :section_type
21
+ value_property :vertical_alignment, as: :vertical_text_alignment
22
+
23
+ def to_xml(xml)
24
+ property_xml xml
25
+ end
26
+
27
+ private
28
+
29
+ def namespace
30
+ :w
31
+ end
32
+
33
+ end
34
+ end
@@ -1,3 +1,3 @@
1
1
  module Rocx
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -5,11 +5,11 @@ describe Rocx::Elements::Ruby do
5
5
 
6
6
  it_should_use tag: :ruby, name: "ruby"
7
7
 
8
- it_should_have_property :font_size, as_instance_of: :phonetic_guide_font_size, with_value: 1
9
- it_should_have_property :base_font_size, as_instance_of: :phonetic_guide_base_font_size, with_value: 1
10
- it_should_have_property :font_size_raise, as_instance_of: :phonetic_guide_font_size_raise, with_value: 1
11
- it_should_have_property :language, as_instance_of: :phonetic_guide_language, with_value: "ja-JP"
12
- it_should_have_property :alignment, as_instance_of: :phonetic_guide_alignment, with_value: :left
8
+ it_should_have_value_property :font_size, as_instance_of: :phonetic_guide_font_size, with_value: 1
9
+ it_should_have_value_property :base_font_size, as_instance_of: :phonetic_guide_base_font_size, with_value: 1
10
+ it_should_have_value_property :font_size_raise, as_instance_of: :phonetic_guide_font_size_raise, with_value: 1
11
+ it_should_have_value_property :language, as_instance_of: :phonetic_guide_language, with_value: "ja-JP"
12
+ it_should_have_value_property :alignment, as_instance_of: :phonetic_guide_alignment, with_value: :left
13
13
 
14
14
  context "for base text" do
15
15
  before(:each) do
@@ -29,4 +29,67 @@ describe Rocx::Parts::Document do
29
29
 
30
30
  it_should_output_correct_xml part: "empty_document"
31
31
  end
32
+
33
+ context "with only one section" do
34
+ before(:each) do
35
+ @doc = described_class.new
36
+
37
+ section = Rocx::Section.new
38
+ section.bidi = true
39
+
40
+ doc << section
41
+
42
+ paragraph = Rocx::Elements::Paragraph.new
43
+
44
+ first_run = Rocx::Elements::Run.new
45
+ first_run << Rocx::Elements::Text.new("This is just a test run.")
46
+ paragraph << first_run
47
+
48
+ second_run = Rocx::Elements::Run.new
49
+ second_run << Rocx::Elements::Text.new("But this isn't!")
50
+ paragraph << second_run
51
+
52
+ doc << paragraph
53
+ end
54
+
55
+ it_should_output_correct_xml part: "document_with_one_section"
56
+ end
57
+
58
+ context "with multiple sections" do
59
+ before(:each) do
60
+ @doc = described_class.new
61
+
62
+ section = Rocx::Section.new
63
+ section.bidi = true
64
+
65
+ doc << section
66
+
67
+ paragraph = Rocx::Elements::Paragraph.new
68
+
69
+ first_run = Rocx::Elements::Run.new
70
+ first_run << Rocx::Elements::Text.new("This is just a test run.")
71
+ paragraph << first_run
72
+
73
+ second_run = Rocx::Elements::Run.new
74
+ second_run << Rocx::Elements::Text.new("But this isn't!")
75
+ paragraph << second_run
76
+
77
+ doc << paragraph
78
+
79
+ section = Rocx::Section.new
80
+ section.text_direction = :lr
81
+
82
+ doc << section
83
+
84
+ paragraph = Rocx::Elements::Paragraph.new
85
+
86
+ first_run = Rocx::Elements::Run.new
87
+ first_run << Rocx::Elements::Text.new("This is just a test run.")
88
+ paragraph << first_run
89
+
90
+ doc << paragraph
91
+ end
92
+
93
+ it_should_output_correct_xml part: "document_with_multiple_sections"
94
+ end
32
95
  end
@@ -0,0 +1,46 @@
1
+ require "spec_helper"
2
+
3
+ describe Rocx::Properties::Column do
4
+ include PropertyTestMacros
5
+
6
+ it_should_use tag: :col, name: "column", value: [1, 1]
7
+
8
+ for_attribute(:space) do
9
+ with_value(2) do
10
+ it_should_assign_successfully 1, 1
11
+ it_should_output "<w:col w:space=\"2\" w:w=\"1\"/>", 1, 1
12
+ end
13
+
14
+ with_value(-1) do
15
+ it_should_raise_an_exception
16
+ end
17
+
18
+ with_value(12.1) do
19
+ it_should_raise_an_exception
20
+ end
21
+
22
+ with_value(:big) do
23
+ it_should_raise_an_exception
24
+ end
25
+ end
26
+
27
+ for_attribute(:width) do
28
+ with_value(2) do
29
+ it_should_assign_successfully 1, 1
30
+ it_should_output "<w:col w:space=\"1\" w:w=\"2\"/>", 1, 1
31
+ end
32
+
33
+ with_value(-1) do
34
+ it_should_raise_an_exception
35
+ end
36
+
37
+ with_value(12.1) do
38
+ it_should_raise_an_exception
39
+ end
40
+
41
+ with_value(:big) do
42
+ it_should_raise_an_exception
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,174 @@
1
+ require "spec_helper"
2
+
3
+ describe Rocx::Properties::Columns do
4
+ include PropertyTestMacros
5
+
6
+ it_should_use tag: :cols, name: "columns"
7
+
8
+ context "when trying to add columns, it" do
9
+ before(:each) do
10
+ @instance = described_class.new
11
+ end
12
+
13
+ it "should raise an exception if the column to be added isn't a column at all" do
14
+ expect { instance << [] }.to raise_error(ArgumentError)
15
+ end
16
+ end
17
+
18
+ context "when there are no columns" do
19
+ before(:each) do
20
+ @instance = described_class.new
21
+ end
22
+
23
+ it "should not output any XML" do
24
+ expect(xml(instance)).to eq("")
25
+ end
26
+ end
27
+
28
+ context "when there are columns" do
29
+ before(:each) do
30
+ @instance = described_class.new
31
+ instance << Rocx::Properties::Column.new(1234, 5678)
32
+ instance << Rocx::Properties::Column.new(8765, 4321)
33
+ end
34
+
35
+ it "should output the correct XML" do
36
+ expect(xml(instance)).to eq("<w:cols>\n <w:col w:space=\"1234\" w:w=\"5678\"/>\n <w:col w:space=\"8765\" w:w=\"4321\"/>\n </w:cols>")
37
+ end
38
+ end
39
+
40
+ for_attribute(:equal_width) do
41
+ before(:each) do
42
+ @instance = described_class.new
43
+ @instance << Rocx::Properties::Column.new(1, 1)
44
+ end
45
+
46
+ context "when the value is true" do
47
+ before(:each) do
48
+ @value = true
49
+ end
50
+
51
+ it "should accept the value" do
52
+ expect { instance.send("#{attribute}=", value) }.to_not raise_error
53
+ end
54
+
55
+ it "should output the correct value" do
56
+ instance.send("#{attribute}=", value)
57
+ expect(xml(instance)).to eq("<w:cols w:equalWidth=\"true\">\n <w:col w:space=\"1\" w:w=\"1\"/>\n </w:cols>")
58
+ end
59
+ end
60
+
61
+ for_attribute(:number) do
62
+ before(:each) do
63
+ @instance = described_class.new
64
+ @instance << Rocx::Properties::Column.new(1, 1)
65
+ end
66
+
67
+ context "when the value is 1" do
68
+ before(:each) do
69
+ @value = 1
70
+ end
71
+
72
+ it "should accept the value" do
73
+ expect { instance.send("#{attribute}=", value) }.to_not raise_error
74
+ end
75
+
76
+ it "should output the correct value" do
77
+ instance.send("#{attribute}=", value)
78
+ expect(xml(instance)).to eq("<w:cols w:num=\"1\">\n <w:col w:space=\"1\" w:w=\"1\"/>\n </w:cols>")
79
+ end
80
+ end
81
+
82
+ context "when the value is -1" do
83
+ before(:each) do
84
+ @value = -1
85
+ end
86
+
87
+ it "should accept the value" do
88
+ expect { instance.send("#{attribute}=", value) }.to_not raise_error
89
+ end
90
+
91
+ it "should output the correct value" do
92
+ instance.send("#{attribute}=", value)
93
+ expect(xml(instance)).to eq("<w:cols w:num=\"-1\">\n <w:col w:space=\"1\" w:w=\"1\"/>\n </w:cols>")
94
+ end
95
+ end
96
+
97
+ with_value(1.3) do
98
+ it_should_raise_an_exception
99
+ end
100
+
101
+ with_value(:a_lot) do
102
+ it_should_raise_an_exception
103
+ end
104
+ end
105
+
106
+ for_attribute(:separator) do
107
+ before(:each) do
108
+ @instance = described_class.new
109
+ @instance << Rocx::Properties::Column.new(1, 1)
110
+ end
111
+
112
+ context "when the value is true" do
113
+ before(:each) do
114
+ @value = true
115
+ end
116
+
117
+ it "should accept the value" do
118
+ expect { instance.send("#{attribute}=", value) }.to_not raise_error
119
+ end
120
+
121
+ it "should output the correct value" do
122
+ instance.send("#{attribute}=", value)
123
+ expect(xml(instance)).to eq("<w:cols w:sep=\"true\">\n <w:col w:space=\"1\" w:w=\"1\"/>\n </w:cols>")
124
+ end
125
+ end
126
+ end
127
+
128
+ for_attribute(:space) do
129
+ before(:each) do
130
+ @instance = described_class.new
131
+ @instance << Rocx::Properties::Column.new(1, 1)
132
+ end
133
+
134
+ context "when the value is 1" do
135
+ before(:each) do
136
+ @value = 1
137
+ end
138
+
139
+ it "should accept the value" do
140
+ expect { instance.send("#{attribute}=", value) }.to_not raise_error
141
+ end
142
+
143
+ it "should output the correct value" do
144
+ instance.send("#{attribute}=", value)
145
+ expect(xml(instance)).to eq("<w:cols w:space=\"1\">\n <w:col w:space=\"1\" w:w=\"1\"/>\n </w:cols>")
146
+ end
147
+ end
148
+
149
+ context "when the value is -1" do
150
+ before(:each) do
151
+ @value = -1
152
+ end
153
+
154
+ it "should accept the value" do
155
+ expect { instance.send("#{attribute}=", value) }.to_not raise_error
156
+ end
157
+
158
+ it "should output the correct value" do
159
+ instance.send("#{attribute}=", value)
160
+ expect(xml(instance)).to eq("<w:cols w:space=\"-1\">\n <w:col w:space=\"1\" w:w=\"1\"/>\n </w:cols>")
161
+ end
162
+ end
163
+
164
+ with_value(1.3) do
165
+ it_should_raise_an_exception
166
+ end
167
+
168
+ with_value(:a_lot) do
169
+ it_should_raise_an_exception
170
+ end
171
+ end
172
+
173
+ end
174
+ end