odf 0.2.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 (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +76 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/lib/odf.rb +65 -0
  12. data/lib/odf/component/abstract.rb +23 -0
  13. data/lib/odf/component/content.rb +35 -0
  14. data/lib/odf/component/image_set.rb +42 -0
  15. data/lib/odf/component/manifest.rb +33 -0
  16. data/lib/odf/component/meta.rb +25 -0
  17. data/lib/odf/component/mime_type.rb +11 -0
  18. data/lib/odf/component/settings.rb +15 -0
  19. data/lib/odf/component/styles.rb +26 -0
  20. data/lib/odf/component/xml_component.rb +29 -0
  21. data/lib/odf/document/abstract.rb +67 -0
  22. data/lib/odf/document/presentation.rb +13 -0
  23. data/lib/odf/document/spreadsheet.rb +13 -0
  24. data/lib/odf/document/text.rb +17 -0
  25. data/lib/odf/element/abstract.rb +34 -0
  26. data/lib/odf/element/abstract_contenteable.rb +11 -0
  27. data/lib/odf/element/binary_data.rb +13 -0
  28. data/lib/odf/element/draw_frame.rb +50 -0
  29. data/lib/odf/element/draw_page.rb +15 -0
  30. data/lib/odf/element/draw_text_box.rb +38 -0
  31. data/lib/odf/element/heading.rb +18 -0
  32. data/lib/odf/element/image.rb +41 -0
  33. data/lib/odf/element/number.rb +14 -0
  34. data/lib/odf/element/paragraph.rb +14 -0
  35. data/lib/odf/element/table.rb +19 -0
  36. data/lib/odf/element/table_cell.rb +30 -0
  37. data/lib/odf/element/table_row.rb +16 -0
  38. data/lib/odf/element/text_list.rb +21 -0
  39. data/lib/odf/element/text_list_item.rb +29 -0
  40. data/lib/odf/utils/file.rb +45 -0
  41. data/lib/odf/utils/xml.rb +13 -0
  42. data/lib/odf/version.rb +3 -0
  43. data/odf.gemspec +32 -0
  44. data/templates/default_style.xml +2 -0
  45. metadata +185 -0
@@ -0,0 +1,29 @@
1
+ module Odf::Component
2
+ module XmlComponent
3
+
4
+ def self.included(base)
5
+ base.class_eval { attr_reader :xml }
6
+ end
7
+
8
+ def initialize(document)
9
+ super
10
+ initialize_xml
11
+ end
12
+
13
+ def content
14
+ wrap_xml
15
+ xml.to_xml
16
+ end
17
+
18
+ private
19
+ def initialize_xml
20
+ @xml = Odf::Utils::Xml.new
21
+ xml.encoding = "UTF-8"
22
+ end
23
+
24
+ def wrap_xml
25
+ true
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,67 @@
1
+ module Odf::Document
2
+ class Abstract
3
+
4
+ COMPONENTS = [:content, :manifest, :meta, :mime_type, :styles, :settings]
5
+
6
+ attr_reader *(COMPONENTS + [:image_set])
7
+ attr_writer :creator
8
+
9
+ alias :document :itself
10
+
11
+ def initialize
12
+ @content = Odf::Component::Content.new(self)
13
+ @image_set = Odf::Component::ImageSet.new(self)
14
+ @manifest = Odf::Component::Manifest.new(self)
15
+ @meta = Odf::Component::Meta.new(self)
16
+ @mime_type = Odf::Component::MimeType.new(self)
17
+ @settings = Odf::Component::Settings.new(self)
18
+ @styles = Odf::Component::Styles.new(self)
19
+ end
20
+
21
+ # Returns the mime type of document.
22
+ # All subclasses of this abstract class
23
+ # should define the +MIME_TYPE+ constant.
24
+ def media_type
25
+ self.class::MIME_TYPE
26
+ end
27
+
28
+ # Returns the file extension for
29
+ # open document format.
30
+ def extension
31
+ self.class::EXTENSION
32
+ end
33
+
34
+ def wrapper
35
+ self.class::WRAPPER
36
+ end
37
+
38
+ # Returns the components of the document.
39
+ def components
40
+ COMPONENTS
41
+ end
42
+
43
+ # Returns the creator information.
44
+ def creator
45
+ @creator || Odf.creator
46
+ end
47
+
48
+ # Serialize the document to given path.
49
+ def serialize(file_name)
50
+ Odf::Utils::File.serialize(file_name, self) && true
51
+ end
52
+
53
+ # Returns the output stream.
54
+ def to_blob
55
+ Odf::Utils::File.output_stream(self)
56
+ end
57
+
58
+ def add_image(uri)
59
+ image_set << uri
60
+ end
61
+
62
+ def root
63
+ content.root
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,13 @@
1
+ module Odf::Document
2
+ class Presentation < Abstract
3
+
4
+ MIME_TYPE = 'application/vnd.oasis.opendocument.presentation'.freeze
5
+ EXTENSION = 'odp'.freeze
6
+ WRAPPER = 'office:presentation'.freeze
7
+
8
+ def add_page(options = {})
9
+ Odf::Element::DrawPage.build(self, options)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Odf::Document
2
+ class Spreadsheet < Abstract
3
+
4
+ MIME_TYPE = 'application/vnd.oasis.opendocument.spreadsheet'.freeze
5
+ EXTENSION = 'ods'.freeze
6
+ WRAPPER = 'office:spreadsheet'.freeze
7
+
8
+ def add_table(options = {})
9
+ Odf::Element::Table.build(self, options)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ module Odf::Document
2
+ class Text < Abstract
3
+
4
+ MIME_TYPE = 'application/vnd.oasis.opendocument.text'.freeze
5
+ EXTENSION = 'odt'.freeze
6
+ WRAPPER = 'office:text'.freeze
7
+
8
+ def add_heading(text, options = {})
9
+ Odf::Element::Heading.build(self, text, options)
10
+ end
11
+
12
+ def add_paragraph(text, options = {})
13
+ Odf::Element::Paragraph.build(self, text, options)
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ module Odf::Element
2
+ class Abstract
3
+
4
+ attr_reader :parent, :root
5
+
6
+ def initialize(parent, options = {})
7
+ @parent = parent
8
+ @root = document.content.xml.create_element(xml_tag, fetch_options(options))
9
+ @parent.root.add_child(@root)
10
+ end
11
+
12
+ # Accessor for valid options of element
13
+ def valid_options
14
+ @valid_options ||= defined?(self.class::VALID_OPTIONS) ? self.class::VALID_OPTIONS : {}
15
+ end
16
+
17
+ def xml_tag
18
+ self.class::XML_TAG
19
+ end
20
+
21
+ def document
22
+ parent.document
23
+ end
24
+
25
+ private
26
+ def fetch_options(options)
27
+ options.reduce({}) do |ret, (k, v)|
28
+ option = valid_options.fetch(k, k)
29
+ ret.merge(option => v)
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ module Odf::Element
2
+ module AbstractContenteable
3
+
4
+ def initialize(parent, content, options = {})
5
+ @parent = parent
6
+ @root = document.content.xml.create_element(xml_tag, content, fetch_options(options))
7
+ @parent.root.add_child(@root)
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Odf::Element
2
+ class BinaryData < Abstract
3
+
4
+ include AbstractContenteable
5
+
6
+ XML_TAG = 'office:binary-data'.freeze
7
+
8
+ def self.build(parent, content, options = {})
9
+ new(parent, content, options)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,50 @@
1
+ module Odf::Element
2
+ class DrawFrame < Abstract
3
+
4
+ VALID_OPTIONS = {
5
+ caption_id: 'draw:caption-id',
6
+ class_names: 'draw:class-names',
7
+ copy_of: 'draw:copy-of',
8
+ id: 'draw:id',
9
+ name: 'draw:name',
10
+ style_name: 'draw:style-name',
11
+ text_style_name: 'draw:text-style-name',
12
+ transform: 'draw:transform',
13
+ z_index: 'draw:z-index',
14
+ p_class: 'presentation:class',
15
+ p_class_names: 'presentation:class-names',
16
+ placeholder: 'presentation:placeholder',
17
+ p_style_name: 'presentation:style-name',
18
+ user_transformed: 'presentation:user-transformed',
19
+ rel_height: 'style:rel-height',
20
+ rel_width: 'style:rel-width',
21
+ height: 'svg:height',
22
+ width: 'svg:width',
23
+ x: 'svg:x',
24
+ y: 'svg:y',
25
+ end_cell_address: 'table:end-cell-address',
26
+ end_x: 'table:end-x',
27
+ end_y: 'table:end-y',
28
+ table_background: 'table:table-background',
29
+ anchor_page_number: 'table:anchor-page-number',
30
+ anchor_type: 'table:anchor-type',
31
+ xml_id: 'xml:id',
32
+ layer: 'draw:layer'
33
+ }
34
+
35
+ XML_TAG = 'draw:frame'.freeze
36
+
37
+ def self.build(parent, options = {})
38
+ new(parent, options)
39
+ end
40
+
41
+ def add_text_box(options = {})
42
+ Odf::Element::DrawTextBox.build(self, options)
43
+ end
44
+
45
+ def add_image(options = {})
46
+ Odf::Element::Image.build(self, options)
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,15 @@
1
+ module Odf::Element
2
+ class DrawPage < Abstract
3
+
4
+ XML_TAG = 'draw:page'.freeze
5
+
6
+ def self.build(document, options = {})
7
+ new(document, options)
8
+ end
9
+
10
+ def add_frame(options = {})
11
+ Odf::Element::DrawFrame.build(self, options)
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,38 @@
1
+ module Odf::Element
2
+ class DrawTextBox < Abstract
3
+
4
+ VALID_OPTIONS = {
5
+ next_name: 'draw:chain-next-name',
6
+ corner_radius: 'draw:corner-radius',
7
+ max_height: 'fo:max-height',
8
+ max_width: 'fo:max-width',
9
+ min_height: 'fo:min-height',
10
+ min_width: 'fo:min-width',
11
+ text_id: 'text:id',
12
+ xml_id: 'xml:id'
13
+ }
14
+
15
+ XML_TAG = 'draw:text-box'.freeze
16
+
17
+ def self.build(parent, options = {})
18
+ new(parent, options)
19
+ end
20
+
21
+ def add_frame(options = {})
22
+ Odf::Element::DrawFrame.build(self, options)
23
+ end
24
+
25
+ def add_heading(text, options = {})
26
+ Odf::Element::Heading.build(self, text, options)
27
+ end
28
+
29
+ def add_paragraph(text, options = {})
30
+ Odf::Element::Paragraph.build(self, text, options)
31
+ end
32
+
33
+ def add_text_list(options = {})
34
+ Odf::Element::TextList.build(self, options)
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,18 @@
1
+ module Odf::Element
2
+ class Heading < Abstract
3
+
4
+ include AbstractContenteable
5
+
6
+ XML_TAG = 'text:h'.freeze
7
+
8
+ def self.build(parent, text, options = {})
9
+ new(parent, text, options)
10
+ end
11
+
12
+ def initialize(parent, content, options = {})
13
+ options = { level: 1 }.merge(options)
14
+ super(parent, content, options)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ module Odf::Element
2
+ class Image < Abstract
3
+
4
+ VALID_OPTIONS = {
5
+ filter_name: 'draw:filter-name',
6
+ actuate: 'xlink:actuate',
7
+ href: 'xlink:href',
8
+ show: 'xlink:show',
9
+ type: 'xlink:type',
10
+ xml_id: 'xml:id'
11
+ }
12
+
13
+ XML_TAG = 'draw:image'.freeze
14
+
15
+ def self.build(parent, options = {})
16
+ new(parent, options)
17
+ end
18
+
19
+ def initialize(parent, options)
20
+ @parent = parent
21
+
22
+ # Save image under Pictures directory
23
+ if options.fetch(:save, true) && options[:href]
24
+ uri = save_image(options[:href])
25
+ options.merge!({ href: uri, show: 'embed' })
26
+ end
27
+
28
+ super(parent, options)
29
+ end
30
+
31
+ def add_paragraph(text, options = {})
32
+ Odf::Element::Paragraph.build(self, text, options)
33
+ end
34
+
35
+ private
36
+ def save_image(href)
37
+ document.add_image(href)
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,14 @@
1
+ module Odf::Element
2
+ class Number < Abstract
3
+
4
+ include AbstractContenteable
5
+
6
+ VALID_OPTIONS = {}
7
+ XML_TAG = 'text:number'.freeze
8
+
9
+ def self.build(parent, text, options)
10
+ new(parent, text, options)
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Odf::Element
2
+ class Paragraph < Abstract
3
+
4
+ include AbstractContenteable
5
+
6
+ VALID_OPTIONS = {}
7
+ XML_TAG = 'text:p'.freeze
8
+
9
+ def self.build(parent, text, options = {})
10
+ new(parent, text, options)
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module Odf::Element
2
+ class Table < Abstract
3
+
4
+ VALID_OPTIONS = {
5
+ table_name: 'table:name'
6
+ }
7
+
8
+ XML_TAG = 'table:table'.freeze
9
+
10
+ def self.build(parent, options = {})
11
+ new(parent, options)
12
+ end
13
+
14
+ def add_table_row(options = {})
15
+ Odf::Element::TableRow.build(self, options)
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ module Odf::Element
2
+ class TableCell < Abstract
3
+
4
+ TYPE_MAP = {
5
+ Fixnum => 'float',
6
+ Float => 'float',
7
+ String => 'string'
8
+ }
9
+
10
+ VALID_OPTIONS = {}
11
+ XML_TAG = 'table:table-cell'.freeze
12
+
13
+ def self.build(parent, content, options = {})
14
+ type = options[:type] || infer_type(content)
15
+ self_opts = {
16
+ 'office:value-type' => type,
17
+ 'office:value' => content
18
+ }.merge(options)
19
+ this = new(parent, self_opts)
20
+
21
+ Odf::Element::Paragraph.build(this, content, options)
22
+ this
23
+ end
24
+
25
+ def self.infer_type(content)
26
+ TYPE_MAP[content.class] || 'string'
27
+ end
28
+
29
+ end
30
+ end