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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +48 -0
- data/LICENSE.txt +20 -0
- data/README.md +34 -0
- data/Rakefile +9 -0
- data/lib/rocx.rb +8 -0
- data/lib/rocx/elements.rb +10 -0
- data/lib/rocx/elements/base_container.rb +65 -0
- data/lib/rocx/elements/base_element.rb +91 -0
- data/lib/rocx/elements/break.rb +10 -0
- data/lib/rocx/elements/paragraph.rb +31 -0
- data/lib/rocx/elements/run.rb +12 -0
- data/lib/rocx/elements/symbol.rb +10 -0
- data/lib/rocx/elements/text.rb +21 -0
- data/lib/rocx/package.rb +33 -0
- data/lib/rocx/parts.rb +8 -0
- data/lib/rocx/parts/base_part.rb +29 -0
- data/lib/rocx/parts/content_types.rb +46 -0
- data/lib/rocx/parts/document.rb +51 -0
- data/lib/rocx/parts/global_rels.rb +24 -0
- data/lib/rocx/parts/rels.rb +48 -0
- data/lib/rocx/parts/settings.rb +21 -0
- data/lib/rocx/parts/styles.rb +49 -0
- data/lib/rocx/properties.rb +12 -0
- data/lib/rocx/properties/alignment.rb +27 -0
- data/lib/rocx/properties/auto_adjust_right_indent.rb +15 -0
- data/lib/rocx/properties/auto_space_de.rb +15 -0
- data/lib/rocx/properties/auto_space_dn.rb +15 -0
- data/lib/rocx/properties/base_property.rb +35 -0
- data/lib/rocx/properties/bidi.rb +6 -0
- data/lib/rocx/properties/bold.rb +11 -0
- data/lib/rocx/properties/boolean_property.rb +15 -0
- data/lib/rocx/properties/conditional_formatting.rb +62 -0
- data/lib/rocx/properties/contextual_spacing.rb +6 -0
- data/lib/rocx/properties/div_id.rb +23 -0
- data/lib/rocx/properties/indentation.rb +31 -0
- data/lib/rocx/properties/italics.rb +11 -0
- data/lib/rocx/properties/keep_lines.rb +6 -0
- data/lib/rocx/properties/keep_next.rb +6 -0
- data/lib/rocx/properties/kinsoku.rb +6 -0
- data/lib/rocx/properties/mirror_indent.rb +6 -0
- data/lib/rocx/properties/on_off_property.rb +15 -0
- data/lib/rocx/properties/outline_level.rb +23 -0
- data/lib/rocx/properties/overflow_punctuation.rb +15 -0
- data/lib/rocx/properties/page_break_before.rb +6 -0
- data/lib/rocx/properties/snap_to_grid.rb +6 -0
- data/lib/rocx/properties/supress_auto_hyphens.rb +6 -0
- data/lib/rocx/properties/supress_line_numbers.rb +6 -0
- data/lib/rocx/properties/supress_overlap.rb +6 -0
- data/lib/rocx/properties/toggle_property.rb +15 -0
- data/lib/rocx/properties/widow_control.rb +6 -0
- data/lib/rocx/properties/word_wrap.rb +6 -0
- data/lib/rocx/style.rb +38 -0
- data/lib/rocx/version.rb +3 -0
- data/rocx.gemspec +30 -0
- data/test/data/elements/break_element.xml +4 -0
- data/test/data/elements/break_with_attributes_element.xml +4 -0
- data/test/data/elements/paragraph_element.xml +8 -0
- data/test/data/elements/paragraph_with_runs_element.xml +14 -0
- data/test/data/elements/run_element.xml +8 -0
- data/test/data/elements/symbol_element.xml +4 -0
- data/test/data/elements/text_element.xml +4 -0
- data/test/data/parts/content_types_part.xml +1 -0
- data/test/data/parts/document_with_children_part.xml +1 -0
- data/test/data/parts/empty_document_part.xml +1 -0
- data/test/data/parts/global_rels_part.xml +1 -0
- data/test/data/parts/rels_part.xml +1 -0
- data/test/data/parts/settings_part.xml +1 -0
- data/test/data/parts/styles_part.xml +1 -0
- data/test/data/parts/styles_with_custom_style_part.xml +1 -0
- data/test/data/styles/character_styles.xml +15 -0
- data/test/data/styles/paragraph_styles.xml +11 -0
- data/test/elements/break_test.rb +54 -0
- data/test/elements/paragraph_test.rb +37 -0
- data/test/elements/run_test.rb +18 -0
- data/test/elements/symbol_test.rb +23 -0
- data/test/elements/text_test.rb +26 -0
- data/test/package_test.rb +48 -0
- data/test/parts/content_types_test.rb +37 -0
- data/test/parts/document_test.rb +31 -0
- data/test/parts/global_rels_test.rb +13 -0
- data/test/parts/rels_test.rb +48 -0
- data/test/parts/settings_test.rb +13 -0
- data/test/parts/styles_test.rb +29 -0
- data/test/properties/auto_adjust_right_indent_test.rb +50 -0
- data/test/properties/auto_space_de_test.rb +50 -0
- data/test/properties/auto_space_dn_test.rb +50 -0
- data/test/properties/bidi_test.rb +50 -0
- data/test/properties/bold_test.rb +50 -0
- data/test/properties/conditional_formatting_test.rb +46 -0
- data/test/properties/contextual_spacing_test.rb +50 -0
- data/test/properties/div_id_test.rb +38 -0
- data/test/properties/italics_test.rb +50 -0
- data/test/properties/keep_lines_test.rb +50 -0
- data/test/properties/keep_next_test.rb +50 -0
- data/test/properties/kinsoku_test.rb +50 -0
- data/test/properties/mirror_indent_test.rb +50 -0
- data/test/properties/outline_level_test.rb +46 -0
- data/test/properties/overflow_punctuation_test.rb +50 -0
- data/test/properties/page_break_before_test.rb +50 -0
- data/test/properties/snap_to_grid_test.rb +50 -0
- data/test/properties/supress_auto_hyphens_test.rb +50 -0
- data/test/properties/supress_line_numbers_test.rb +50 -0
- data/test/properties/supress_overlap_test.rb +50 -0
- data/test/properties/widow_control_test.rb +50 -0
- data/test/properties/word_wrap_test.rb +50 -0
- data/test/style_test.rb +54 -0
- data/test/test_helper.rb +55 -0
- 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,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,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
|