Skip to content

Commit

Permalink
Extracted from openxml-docx
Browse files Browse the repository at this point in the history
Amos King @adkron <amos@binarynoggin.com>
Bob Lail @boblail <bob.lailfamily@gmail.com>
  • Loading branch information
adkron committed Mar 31, 2017
0 parents commit 2bc7595
Show file tree
Hide file tree
Showing 119 changed files with 3,288 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.ruby-version
.DS_Store
rocx-0.1.0.gem
*.gem
.rspec-local
/coverage
TODO.md
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# .travis.yml
language: ruby
rvm:
- 2.3.0
script:
- bundle exec rake spec
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source 'https://rubygems.org'

gemspec
65 changes: 65 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
PATH
remote: .
specs:
openxml-drawingml (0.1.0)
nokogiri
openxml-package (>= 0.2.2)

GEM
remote: https://rubygems.org/
specs:
coderay (1.1.1)
diff-lcs (1.2.5)
docile (1.1.5)
json (1.8.3)
method_source (0.8.2)
mini_portile2 (2.1.0)
nokogiri (1.7.1)
mini_portile2 (~> 2.1.0)
openxml-package (0.2.7)
nokogiri
ox
rubyzip (~> 1.2.1)
ox (2.4.11)
pry (0.10.3)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
rake (11.1.2)
rr (1.1.2)
rspec (3.4.0)
rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0)
rspec-core (3.4.4)
rspec-support (~> 3.4.0)
rspec-expectations (3.4.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-mocks (3.4.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-support (3.4.1)
rubyzip (1.2.1)
simplecov (0.11.2)
docile (~> 1.1.0)
json (~> 1.8)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
slop (3.6.0)
timecop (0.8.1)

PLATFORMS
ruby

DEPENDENCIES
openxml-drawingml!
pry
rake
rr
rspec
simplecov
timecop

BUNDLED WITH
1.14.6
20 changes: 20 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2013 Gene Doyel

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
93 changes: 93 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# OpenXml::Docx

[![Gem Version](https://badge.fury.io/rb/openxml-docx.svg)](https://rubygems.org/gems/openxml-docx)
[![Code Climate](https://codeclimate.com/github/openxml/openxml-docx.svg)](https://codeclimate.com/github/openxml/openxml-docx)
[![Build Status](https://travis-ci.org/openxml/openxml-docx.svg)](https://travis-ci.org/openxml/openxml-docx)

OpenXml::Docx is a gem for creating .docx (Office Open XML) files. It's designed to validate _before_ the document is generated, so (hopefully) any errors are caught prior to opening the file using software that can handle OOXML (like Microsoft Word, Apache Open Office, Google Docs, etc).

An example:

```ruby
require "openxml/docx"

text = OpenXml::Docx::Elements::Text.new("Some text that I want to include in my new OOXML document")
run = OpenXml::Docx::Elements::Run.new
run.bold = true
run << text
paragraph = OpenXml::Docx::Elements::Paragraph.new
paragraph << run

document = OpenXml::Docx::Package.new
document.document << paragraph
document.save("/path/where/i/save/things/test.docx")
```


## Installation

Add this line to your application's Gemfile:

```ruby
gem 'openxml-docx'
```

And then execute:

$ bundle

Or install it yourself as:

$ gem install openxml-docx


## Current features

- Paragraphs
- Runs and text
- Formatting and styles for the paragraphs, runs, and text


## Roadmap

It's important to note that lists goes off into the future quite a bit, therefore it's very likely that it will change. That being said, this is the plan for future releases:

- 0.7.0: Sections
- 0.8.0: Increased support for styles and fonts
- 0.9.0: Images and movies
- 0.10.0: Numbering and lists
- 0.11.0: Headers and footers
- 0.12.0: Footnotes and endnotes
- 0.13.0: Glossary documents
- 0.14.0: Annotations
- 0.15.0: Increased support for document-level settings
- 0.16.0: Tables
- 0.17.0: Embedded custom markup
- 0.18.0: Fields and hyperlinks
- 0.19.0: Mail merge
- 0.20.0: Layer on a DSL for making the whole thing smoother



## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.

Reference for WordprocessingML can be found in Part 1 of the Fourth Edition of [ECMA-376](http://www.ecma-international.org/publications/standards/Ecma-376.htm) (the Office Open XML Standard).

To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).


## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/openxml/openxml-docx.


## Changelog

- 0.6.0: Added additional run content
- 0.5.8: Added run properties
- 0.5.7: Added paragraph properties
- 0.5.0: First version with document content (i.e. paragraphs)
- 0.4.0: Rudimentary support for styles
- 0.3.0: First version supporting outputting in target format
6 changes: 6 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require "rspec/core/rake_task"

RSpec::Core::RakeTask.new
task default: :spec
task test: :spec
require "bundler/gem_tasks"
14 changes: 14 additions & 0 deletions bin/console
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env ruby

require "bundler/setup"
require "openxml/drawingml"

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.

# (If you use this, don't forget to add pry to your Gemfile!)
# require "pry"
# Pry.start

require "irb"
IRB.start
8 changes: 8 additions & 0 deletions bin/setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
set -vx

bundle install

# Do any other automated setup that you need to do here
130 changes: 130 additions & 0 deletions lib/extract/attribute_builder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
module OpenXml
module AttributeBuilder

def self.included(base)
base.extend(ClassMethods)
end

module ClassMethods
def attribute(name, expects: nil, one_of: nil, displays_as: nil, namespace: nil, matches: nil, deprecated: false)
bad_names = %w(tag name namespace properties_tag)
raise ArgumentError if bad_names.member? name

attr_reader name

define_method "#{name}=" do |value|
valid_in?(value, one_of) unless one_of.nil?
send(expects, value) unless expects.nil?
matches?(value, matches) unless matches.nil?
instance_variable_set "@#{name}", value
end

camelized_name = name.to_s.gsub(/_([a-z])/i) { $1.upcase }.to_sym
attributes[name] = [displays_as || camelized_name, namespace || @attribute_namespace]
end

def attributes
@attributes ||= {}
end

def with_namespace(namespace, &block)
@attribute_namespace = namespace
instance_eval(&block)
end
end

def render?
attributes.keys.map(&method(:send)).any?
end

def attributes
self.class.attributes
end

private

def xml_attributes
attributes.each_with_object({}) do |(name, options), attrs|
display, namespace = options
value = send(name)
attr_name = "#{namespace}:#{display}"
attr_name = "#{display}" if namespace.nil?
attrs[attr_name] = value unless value.nil?
end
end

def boolean(value)
message = "Invalid #{name}: frame must be true or false"
raise ArgumentError, message unless [true, false].member? value
end

def hex_color(value)
message = "Invalid #{name}: must be :auto or a hex color, e.g. 4F1B8C"
raise ArgumentError, message unless value == :auto || value =~ /^[0-9A-F]{6}$/
end

def hex_digit(value)
message = "Invalid #{name}: must be a two-digit hex number, e.g. BF"
raise ArgumentError, message unless value =~ /^[0-9A-F]{2}$/
end

def hex_digit_4(value)
message = "Invalid #{name}: must be a four-digit hex number, e.g. BF12"
raise ArgumentError, message unless value =~ /^[0-9A-F]{4}$/
end

def long_hex_number(value)
message = "Invalid #{name}: must be an eight-digit hex number, e.g., FFAC0013"
raise ArgumentError, message unless value =~ /^[0-9A-F]{8}$/
end

def hex_string(value)
message = "Invalid #{name}: must be a string of hexadecimal numbers, e.g. FFA23C6E"
raise ArgumentError, message unless value =~ /^[0-9A-F]+$/
end

def integer(value)
message = "Invalid #{name}: must be an integer"
raise ArgumentError, message unless value.is_a?(Integer)
end

def positive_integer(value)
message = "Invalid #{name}: must be a positive integer"
raise ArgumentError, message unless value.is_a?(Integer) && value >= 0
end

def string(value)
message = "Invalid #{name}: must be a string"
raise ArgumentError, message if !value.is_a?(String) || value.length.zero?
end

def percentage(value)
message = "Invalid #{name}: must be a percentage"
raise ArgumentError, message unless value.is_a?(String) && value =~ /-?[0-9]+(\.[0-9]+)?%/ # Regex supplied in sec. 22.9.2.9 of Office Open XML docs
end

def on_or_off(value)
valid_in? value, [:on, :off]
end

def valid_theme_color(value)
valid_in? value, VALID_THEME_COLORS
end

def valid_type(value)
valid_in? value, VALID_TYPES
end

def valid_in?(value, list)
message = "Invalid #{name}: must be one of #{list.join(", ")} (was #{value.inspect})"
raise ArgumentError, message unless list.member?(value)
end

def matches?(value, regexp)
message = "Value does not match #{regexp}"
raise ArgumentError, message unless value =~ regexp
end

end
end

34 changes: 34 additions & 0 deletions lib/extract/container.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require "extract/property_builder"

module OpenXml
class Container < Element
include PropertyBuilder
attr_reader :children

def initialize
@children = []
end

def <<(child)
children << child
end

def to_xml(xml)
xml[namespace].public_send(tag, xml_attributes) {
property_xml(xml)
children.each { |child| child.to_xml(xml) }
}
end

private

def properties_tag
self.class.properties_tag || default_properties_tag
end

def default_properties_tag
:"#{tag}Pr"
end

end
end
Loading

0 comments on commit 2bc7595

Please sign in to comment.