rocx 0.5.6

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 (111) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/Gemfile +3 -0
  4. data/Gemfile.lock +48 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.md +34 -0
  7. data/Rakefile +9 -0
  8. data/lib/rocx.rb +8 -0
  9. data/lib/rocx/elements.rb +10 -0
  10. data/lib/rocx/elements/base_container.rb +65 -0
  11. data/lib/rocx/elements/base_element.rb +91 -0
  12. data/lib/rocx/elements/break.rb +10 -0
  13. data/lib/rocx/elements/paragraph.rb +31 -0
  14. data/lib/rocx/elements/run.rb +12 -0
  15. data/lib/rocx/elements/symbol.rb +10 -0
  16. data/lib/rocx/elements/text.rb +21 -0
  17. data/lib/rocx/package.rb +33 -0
  18. data/lib/rocx/parts.rb +8 -0
  19. data/lib/rocx/parts/base_part.rb +29 -0
  20. data/lib/rocx/parts/content_types.rb +46 -0
  21. data/lib/rocx/parts/document.rb +51 -0
  22. data/lib/rocx/parts/global_rels.rb +24 -0
  23. data/lib/rocx/parts/rels.rb +48 -0
  24. data/lib/rocx/parts/settings.rb +21 -0
  25. data/lib/rocx/parts/styles.rb +49 -0
  26. data/lib/rocx/properties.rb +12 -0
  27. data/lib/rocx/properties/alignment.rb +27 -0
  28. data/lib/rocx/properties/auto_adjust_right_indent.rb +15 -0
  29. data/lib/rocx/properties/auto_space_de.rb +15 -0
  30. data/lib/rocx/properties/auto_space_dn.rb +15 -0
  31. data/lib/rocx/properties/base_property.rb +35 -0
  32. data/lib/rocx/properties/bidi.rb +6 -0
  33. data/lib/rocx/properties/bold.rb +11 -0
  34. data/lib/rocx/properties/boolean_property.rb +15 -0
  35. data/lib/rocx/properties/conditional_formatting.rb +62 -0
  36. data/lib/rocx/properties/contextual_spacing.rb +6 -0
  37. data/lib/rocx/properties/div_id.rb +23 -0
  38. data/lib/rocx/properties/indentation.rb +31 -0
  39. data/lib/rocx/properties/italics.rb +11 -0
  40. data/lib/rocx/properties/keep_lines.rb +6 -0
  41. data/lib/rocx/properties/keep_next.rb +6 -0
  42. data/lib/rocx/properties/kinsoku.rb +6 -0
  43. data/lib/rocx/properties/mirror_indent.rb +6 -0
  44. data/lib/rocx/properties/on_off_property.rb +15 -0
  45. data/lib/rocx/properties/outline_level.rb +23 -0
  46. data/lib/rocx/properties/overflow_punctuation.rb +15 -0
  47. data/lib/rocx/properties/page_break_before.rb +6 -0
  48. data/lib/rocx/properties/snap_to_grid.rb +6 -0
  49. data/lib/rocx/properties/supress_auto_hyphens.rb +6 -0
  50. data/lib/rocx/properties/supress_line_numbers.rb +6 -0
  51. data/lib/rocx/properties/supress_overlap.rb +6 -0
  52. data/lib/rocx/properties/toggle_property.rb +15 -0
  53. data/lib/rocx/properties/widow_control.rb +6 -0
  54. data/lib/rocx/properties/word_wrap.rb +6 -0
  55. data/lib/rocx/style.rb +38 -0
  56. data/lib/rocx/version.rb +3 -0
  57. data/rocx.gemspec +30 -0
  58. data/test/data/elements/break_element.xml +4 -0
  59. data/test/data/elements/break_with_attributes_element.xml +4 -0
  60. data/test/data/elements/paragraph_element.xml +8 -0
  61. data/test/data/elements/paragraph_with_runs_element.xml +14 -0
  62. data/test/data/elements/run_element.xml +8 -0
  63. data/test/data/elements/symbol_element.xml +4 -0
  64. data/test/data/elements/text_element.xml +4 -0
  65. data/test/data/parts/content_types_part.xml +1 -0
  66. data/test/data/parts/document_with_children_part.xml +1 -0
  67. data/test/data/parts/empty_document_part.xml +1 -0
  68. data/test/data/parts/global_rels_part.xml +1 -0
  69. data/test/data/parts/rels_part.xml +1 -0
  70. data/test/data/parts/settings_part.xml +1 -0
  71. data/test/data/parts/styles_part.xml +1 -0
  72. data/test/data/parts/styles_with_custom_style_part.xml +1 -0
  73. data/test/data/styles/character_styles.xml +15 -0
  74. data/test/data/styles/paragraph_styles.xml +11 -0
  75. data/test/elements/break_test.rb +54 -0
  76. data/test/elements/paragraph_test.rb +37 -0
  77. data/test/elements/run_test.rb +18 -0
  78. data/test/elements/symbol_test.rb +23 -0
  79. data/test/elements/text_test.rb +26 -0
  80. data/test/package_test.rb +48 -0
  81. data/test/parts/content_types_test.rb +37 -0
  82. data/test/parts/document_test.rb +31 -0
  83. data/test/parts/global_rels_test.rb +13 -0
  84. data/test/parts/rels_test.rb +48 -0
  85. data/test/parts/settings_test.rb +13 -0
  86. data/test/parts/styles_test.rb +29 -0
  87. data/test/properties/auto_adjust_right_indent_test.rb +50 -0
  88. data/test/properties/auto_space_de_test.rb +50 -0
  89. data/test/properties/auto_space_dn_test.rb +50 -0
  90. data/test/properties/bidi_test.rb +50 -0
  91. data/test/properties/bold_test.rb +50 -0
  92. data/test/properties/conditional_formatting_test.rb +46 -0
  93. data/test/properties/contextual_spacing_test.rb +50 -0
  94. data/test/properties/div_id_test.rb +38 -0
  95. data/test/properties/italics_test.rb +50 -0
  96. data/test/properties/keep_lines_test.rb +50 -0
  97. data/test/properties/keep_next_test.rb +50 -0
  98. data/test/properties/kinsoku_test.rb +50 -0
  99. data/test/properties/mirror_indent_test.rb +50 -0
  100. data/test/properties/outline_level_test.rb +46 -0
  101. data/test/properties/overflow_punctuation_test.rb +50 -0
  102. data/test/properties/page_break_before_test.rb +50 -0
  103. data/test/properties/snap_to_grid_test.rb +50 -0
  104. data/test/properties/supress_auto_hyphens_test.rb +50 -0
  105. data/test/properties/supress_line_numbers_test.rb +50 -0
  106. data/test/properties/supress_overlap_test.rb +50 -0
  107. data/test/properties/widow_control_test.rb +50 -0
  108. data/test/properties/word_wrap_test.rb +50 -0
  109. data/test/style_test.rb +54 -0
  110. data/test/test_helper.rb +55 -0
  111. metadata +315 -0
@@ -0,0 +1,29 @@
1
+ require 'nokogiri'
2
+
3
+ module Rocx
4
+ module Parts
5
+ class BasePart
6
+ include ::Nokogiri
7
+
8
+ def build_xml
9
+ XML::Builder.new(encoding: "utf-8") { |xml| yield xml }.to_xml
10
+ end
11
+
12
+ def build_standalone_xml
13
+ xml = Nokogiri::XML("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>")
14
+ XML::Builder.with(xml) { |xml| yield xml }.to_xml
15
+ end
16
+
17
+ def read
18
+ raise NotImplementedError
19
+ end
20
+
21
+ protected
22
+
23
+ def strip_whitespace(xml)
24
+ xml.lines.map(&:strip).join
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,46 @@
1
+ module Rocx
2
+ module Parts
3
+ class ContentTypes < BasePart
4
+ attr_reader :defaults, :overrides
5
+
6
+ def initialize
7
+ @defaults, @overrides = [], []
8
+ install_preset_defaults
9
+ install_preset_overrides
10
+ end
11
+
12
+ def install_preset_defaults
13
+ default "xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"
14
+ default "rels", "application/vnd.openxmlformats-package.relationships+xml"
15
+ default "png", "image/png"
16
+ end
17
+
18
+ def install_preset_overrides
19
+ override "/word/styles.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"
20
+ override "/word/settings.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"
21
+ end
22
+
23
+ def default(extension, content_type)
24
+ defaults << {"Extension" => extension, "ContentType" => content_type}
25
+ end
26
+
27
+ def override(part_name, content_type)
28
+ overrides << {"PartName" => part_name, "ContentType" => content_type}
29
+ end
30
+
31
+ def read
32
+ xml = build_xml do |xml|
33
+ xml.Types(xmlns: "http://schemas.openxmlformats.org/package/2006/content-types") {
34
+ defaults.each { |default| xml.Default(default) }
35
+ overrides.each { |override| xml.Override(override) }
36
+ }
37
+ end
38
+ strip_whitespace(xml)
39
+ end
40
+
41
+ end
42
+ end
43
+ end
44
+
45
+
46
+
@@ -0,0 +1,51 @@
1
+ module Rocx
2
+ module Parts
3
+ class Document < BasePart
4
+ attr_reader :children
5
+
6
+ def initialize
7
+ @children = []
8
+ end
9
+
10
+ def <<(child)
11
+ children << child
12
+ end
13
+
14
+ def read
15
+ xml = build_xml do |xml|
16
+ xml.document(root_namespaces) {
17
+ xml.parent.namespace = xml.parent.namespace_definitions.find { |ns| ns.prefix == 'w' }
18
+ xml['w'].body {
19
+ children.each { |child| child.to_xml(xml) }
20
+ }
21
+ }
22
+ end
23
+ strip_whitespace(xml)
24
+ end
25
+
26
+ private
27
+
28
+ def root_namespaces
29
+ { "xmlns:wpc" => 'http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas',
30
+ "xmlns:mo" => 'http://schemas.microsoft.com/office/mac/office/2008/main',
31
+ "xmlns:mv" => 'urn:schemas-microsoft-com:mac:vml',
32
+ "xmlns:o" => 'urn:schemas-microsoft-com:office:office',
33
+ "xmlns:r" => 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',
34
+ "xmlns:m" => 'http://schemas.openxmlformats.org/officeDocument/2006/math',
35
+ "xmlns:v" => 'urn:schemas-microsoft-com:vml',
36
+ "xmlns:wp14" => 'http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing',
37
+ "xmlns:wp" => 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing',
38
+ "xmlns:w10" => 'urn:schemas-microsoft-com:office:word',
39
+ "xmlns:w14" => 'http://schemas.microsoft.com/office/word/2010/wordml',
40
+ "xmlns:wpg" => 'http://schemas.microsoft.com/office/word/2010/wordprocessingGroup',
41
+ "xmlns:wpi" => 'http://schemas.microsoft.com/office/word/2010/wordprocessingInk',
42
+ "xmlns:wne" => 'http://schemas.microsoft.com/office/word/2006/wordml',
43
+ "xmlns:wps" => 'http://schemas.microsoft.com/office/word/2010/wordprocessingShape',
44
+ "xmlns:w" => "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
45
+ "xmlns:mc" => "http://schemas.openxmlformats.org/markup-compatibility/2006",
46
+ "mc:Ignorable" => "w14 wp14" }
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,24 @@
1
+ module Rocx
2
+ module Parts
3
+ class GlobalRels < BasePart
4
+
5
+ def read
6
+ xml = build_xml do |xml|
7
+ xml.Relationships(xmlns: "http://schemas.openxmlformats.org/package/2006/relationships") {
8
+ xml.Relationship(document_relation_attributes)
9
+ }
10
+ end
11
+ strip_whitespace(xml)
12
+ end
13
+
14
+ private
15
+
16
+ def document_relation_attributes
17
+ { "Type" => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
18
+ "Target" => "/word/document.xml",
19
+ "Id" => "R08806881ac3c45ac" }
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,48 @@
1
+ require "securerandom"
2
+
3
+ module Rocx
4
+ module Parts
5
+ class Rels < BasePart
6
+ attr_reader :relationships
7
+
8
+ def initialize
9
+ @relationships = []
10
+ install_defaults
11
+ end
12
+
13
+ def install_defaults
14
+ defaults.each do |default|
15
+ relationship *default.values
16
+ end
17
+ end
18
+
19
+ def relationship(type, target, id=nil)
20
+ id = "R#{SecureRandom.hex}" unless id
21
+ relationships << {"Type" => type, "Target" => target, "Id" => id}
22
+ end
23
+
24
+ def read
25
+ xml = build_xml do |xml|
26
+ xml.Relationships(xmlns: "http://schemas.openxmlformats.org/package/2006/relationships") {
27
+ relationships.each do |rel|
28
+ xml.Relationship(rel)
29
+ end
30
+ }
31
+ end
32
+ strip_whitespace(xml)
33
+ end
34
+
35
+ private
36
+
37
+ def defaults
38
+ [{ type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
39
+ target: "/word/styles.xml",
40
+ id: "Rf06246a95c004384" },
41
+ { type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",
42
+ target: "/word/settings.xml",
43
+ id: "R1efaa81aac7a4831" }]
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,21 @@
1
+ module Rocx
2
+ module Parts
3
+ class Settings < BasePart
4
+ attr_reader :settings
5
+
6
+ def initialize
7
+ @settings = []
8
+ end
9
+
10
+ def read
11
+ xml = build_standalone_xml do |xml|
12
+ xml.settings("xmlns:w" => "http://schemas.openxmlformats.org/wordprocessingml/2006/main") {
13
+ xml.parent.namespace = xml.parent.namespace_definitions.find { |ns| ns.prefix == "w" }
14
+ }
15
+ end
16
+ strip_whitespace(xml)
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,49 @@
1
+ module Rocx
2
+ module Parts
3
+ class Styles < BasePart
4
+ attr_reader :styles
5
+
6
+ def initialize
7
+ @styles = []
8
+ end
9
+
10
+ def <<(style)
11
+ @styles << style
12
+ end
13
+
14
+ def read
15
+ xml = build_standalone_xml do |xml|
16
+ xml.styles(root_namespaces) {
17
+ xml.parent.namespace = xml.parent.namespace_definitions.find { |ns| ns.prefix == "w" }
18
+ add_default_styles(xml)
19
+ styles.each { |style| style.build_xml(xml) }
20
+ }
21
+ end
22
+ strip_whitespace(xml)
23
+ end
24
+
25
+ private
26
+
27
+ def add_default_styles(xml)
28
+ xml["w"].docDefaults {
29
+ xml["w"].rPrDefault {
30
+ xml["w"].rPr {
31
+ xml["w"].lang("w:bidi" => "ar-SA", "w:eastAsia" => "en-US", "w:val" => "en-US")
32
+ }
33
+ }
34
+ xml["w"].pPrDefault {
35
+ xml["w"].pPr {
36
+ xml["w"].spacing("w:after" => "0", "w:line" => "240", "w:lineRule" => "auto")
37
+ }
38
+ }
39
+ }
40
+ end
41
+
42
+ def root_namespaces
43
+ { "xmlns:r" => "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
44
+ "xmlns:w" => "http://schemas.openxmlformats.org/wordprocessingml/2006/main" }
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,12 @@
1
+ module Rocx
2
+ module Properties
3
+ end
4
+ end
5
+
6
+ require "rocx/properties/base_property"
7
+ require "rocx/properties/boolean_property"
8
+ require "rocx/properties/on_off_property"
9
+ require "rocx/properties/toggle_property"
10
+ Dir.glob("#{File.join(File.dirname(__FILE__), "properties", "*.rb")}").each do |file|
11
+ require file
12
+ end
@@ -0,0 +1,27 @@
1
+ module Rocx
2
+ module Properties
3
+ class Alignment
4
+ attr_reader :value
5
+
6
+ OK_VALUES = [:both, :center, :distribute, :end, :highKashida, :lowKashida, :mediumKashida, :numTab, :start, :thaiDistribute]
7
+
8
+ def initialize(value)
9
+ @value = value
10
+ raise ArgumentError invalid_message unless valid?
11
+ end
12
+
13
+ def invalid_message
14
+ "Invalid value for alignment; acceptable values are #{OK_VALUES.join(", ")}"
15
+ end
16
+
17
+ def valid?
18
+ OK_VALUES.member? value
19
+ end
20
+
21
+ def to_xml(xml)
22
+ xml["w"].jc("w:val" => value) if value
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ module Rocx
2
+ module Properties
3
+ class AutoAdjustRightIndent < BooleanProperty
4
+
5
+ def name
6
+ "auto_adjust_right_ind"
7
+ end
8
+
9
+ def tag
10
+ :adjustRightInd
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Rocx
2
+ module Properties
3
+ class AutoSpaceDe < BooleanProperty
4
+
5
+ def name
6
+ "auto_space_de"
7
+ end
8
+
9
+ def tag
10
+ :autoSpaceDE
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Rocx
2
+ module Properties
3
+ class AutoSpaceDn < BooleanProperty
4
+
5
+ def name
6
+ "auto_space_dn"
7
+ end
8
+
9
+ def tag
10
+ :autoSpaceDN
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ module Rocx
2
+ module Properties
3
+ class BaseProperty
4
+ attr_reader :value
5
+
6
+ def initialize(value)
7
+ @value = value
8
+ raise ArgumentError, invalid_message unless valid?
9
+ end
10
+
11
+ def valid?
12
+ ok_values.member? value
13
+ end
14
+
15
+ def invalid_message
16
+ "Invalid value for #{name}; acceptable values are #{ok_values.join(", ")}"
17
+ end
18
+
19
+ def name
20
+ class_name.gsub(/(.)([A-Z])/, '\1_\2').downcase
21
+ end
22
+
23
+ def tag
24
+ (class_name[0, 1].downcase + class_name[1..-1]).to_sym
25
+ end
26
+
27
+ private
28
+
29
+ def class_name
30
+ self.class.to_s.split(/::/).last
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,6 @@
1
+ module Rocx
2
+ module Properties
3
+ class Bidi < ToggleProperty
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ module Rocx
2
+ module Properties
3
+ class Bold < ToggleProperty
4
+
5
+ def tag
6
+ :b
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module Rocx
2
+ module Properties
3
+ class BooleanProperty < BaseProperty
4
+
5
+ def ok_values
6
+ [nil, true, false]
7
+ end
8
+
9
+ def to_xml(xml)
10
+ xml["w"].public_send(tag, "w:val" => value) if value
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,62 @@
1
+ module Rocx
2
+ module Properties
3
+ class ConditionalFormatting < BaseProperty
4
+ VALID_ARGUMENTS = %i(even_h
5
+ even_v
6
+ odd_h
7
+ odd_v
8
+ first_column
9
+ first_row
10
+ last_column
11
+ last_row
12
+ first_row_first_column
13
+ first_row_last_column
14
+ last_row_first_column
15
+ last_row_last_column)
16
+
17
+ VALID_ARGUMENTS.each do |arg|
18
+ attr_accessor arg
19
+ end
20
+
21
+ def initialize(**args)
22
+ check_arguments(args)
23
+ assign_arguments(args)
24
+ end
25
+
26
+ def tag
27
+ :cnfStyle
28
+ end
29
+
30
+ def to_xml(xml)
31
+ xml["w"].public_send(tag, xml_properties)
32
+ end
33
+
34
+ private
35
+
36
+ def check_arguments(args)
37
+
38
+ args.keys.each do |key|
39
+ raise ArgumentError, "Invalid argument for conditional formatting" unless VALID_ARGUMENTS.member?(key)
40
+ end
41
+
42
+ args.values.each do |value|
43
+ raise ArgumentError, "Invalid value for conditional formatting" unless [true, false].member?(value)
44
+ end
45
+ end
46
+
47
+ def assign_arguments(args)
48
+ args.each do |key, val|
49
+ send "#{key}=", val
50
+ end
51
+ end
52
+
53
+ def xml_properties
54
+ VALID_ARGUMENTS.each_with_object({}) do |arg, props|
55
+ value = send(arg)
56
+ props["w:#{arg}"] = value if value
57
+ end
58
+ end
59
+
60
+ end
61
+ end
62
+ end