odf-converter 0.0.1
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.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +7 -0
- data/lib/odf-converter.rb +3 -0
- data/lib/odf/converter.rb +108 -0
- data/lib/odf/converter/families.rb +11 -0
- data/lib/odf/converter/filters/base_filter.rb +17 -0
- data/lib/odf/converter/filters/export.rb +115 -0
- data/lib/odf/converter/filters/import.rb +21 -0
- data/lib/odf/converter/hash.rb +11 -0
- data/lib/odf/converter/version.rb +5 -0
- data/odf-converter.gemspec +22 -0
- data/spec/odf/converter_spec.rb +42 -0
- metadata +107 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Daniel Vandersluis
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Opendoc::Converter
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'opendoc-converter'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install opendoc-converter
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
require "rubyuno"
|
2
|
+
require "odf/converter/version"
|
3
|
+
require "odf/converter/families"
|
4
|
+
require "odf/converter/filters/base_filter"
|
5
|
+
require "odf/converter/filters/import"
|
6
|
+
require "odf/converter/filters/export"
|
7
|
+
require "odf/converter/hash"
|
8
|
+
|
9
|
+
module ODF
|
10
|
+
PropertyValue = Rubyuno.uno_require "com.sun.star.beans.PropertyValue"
|
11
|
+
|
12
|
+
class Converter
|
13
|
+
class DocumentConversionError < Exception; end
|
14
|
+
|
15
|
+
attr_reader :ctx, :smgr, :desktop, :document
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@ctx = Uno::Connector.bootstrap("soffice", "socket", "localhost", 8100)
|
19
|
+
@smgr = @ctx.getServiceManager
|
20
|
+
@desktop = @smgr.createInstanceWithContext("com.sun.star.frame.Desktop", @ctx)
|
21
|
+
end
|
22
|
+
|
23
|
+
def convert(infile, options = {})
|
24
|
+
raise ArgumentError, "to option must be provided." unless options[:to]
|
25
|
+
|
26
|
+
if options[:to].is_a? Symbol #and Filters::Export[options[:to]]
|
27
|
+
outfile = get_output_name(infile, options[:to])
|
28
|
+
elsif options[:to].is_a? String
|
29
|
+
raise DocumentConversionError, "#{options[:to]} doesn't specify an extension" if File.extname(options[:to]).empty?
|
30
|
+
outfile = File.expand_path(options[:to])
|
31
|
+
else
|
32
|
+
raise DocumentConversionError, "not given a valid destination"
|
33
|
+
end
|
34
|
+
|
35
|
+
perform_conversion(infile, outfile) && outfile
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.convert(*args)
|
39
|
+
new.convert(*args)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def detect_family(doc)
|
44
|
+
return Families::WEB if doc.supportsService("com.sun.star.text.WebDocument")
|
45
|
+
return Families::TEXT if doc.supportsService("com.sun.star.text.GenericTextDocument")
|
46
|
+
return Families::SPREADSHEET if doc.supportsService("com.sun.star.sheet.SpreadsheetDocument")
|
47
|
+
return Families::PRESENTATION if doc.supportsService("com.sun.star.presentation.PresentationDocument")
|
48
|
+
return Families::DRAWING if doc.supportsService("com.sun.star.drawing.DrawingDocument")
|
49
|
+
raise DocumentConversionError, "unknown document family"
|
50
|
+
end
|
51
|
+
|
52
|
+
def file_url_for(file)
|
53
|
+
Rubyuno.system_path_to_file_url File.expand_path(file)
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_output_name(file, ext)
|
57
|
+
file = File.expand_path(file)
|
58
|
+
File.join(File.dirname(file), File.basename(file, File.extname(file)) + ".#{ext}")
|
59
|
+
end
|
60
|
+
|
61
|
+
def perform_conversion(infile, outfile)
|
62
|
+
begin
|
63
|
+
load(infile) && store(outfile)
|
64
|
+
ensure
|
65
|
+
@document.close(true)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def load(infile)
|
70
|
+
input_url = file_url_for(infile)
|
71
|
+
input_ext = File.extname(infile).gsub(/^\./, "")
|
72
|
+
props = { Hidden: true }.merge(Filters::Import[input_ext] || {})
|
73
|
+
|
74
|
+
begin
|
75
|
+
@document = desktop.loadComponentFromURL(input_url, "_blank", 0, props.to_uno_properties)
|
76
|
+
rescue Rubyuno::Com::Sun::Star::Lang::IllegalArgumentException => e
|
77
|
+
raise DocumentConversionError, e.message
|
78
|
+
end
|
79
|
+
|
80
|
+
@document.refresh
|
81
|
+
family = detect_family(@document)
|
82
|
+
|
83
|
+
if family == Families::SPREADSHEET
|
84
|
+
page_styles = @document.getStyleFamilies.getByName('PageStyles')
|
85
|
+
page_styles.getElementNames.each do |name|
|
86
|
+
page_style = pageStyles.getByName(name)
|
87
|
+
page_style.setPropertyValue("PageScale", 100)
|
88
|
+
page_style.setPropertyValue("PrintGrid", false)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
true
|
93
|
+
end
|
94
|
+
|
95
|
+
def store(outfile)
|
96
|
+
output_url = file_url_for(outfile)
|
97
|
+
output_ext = File.extname(outfile).gsub(/^\./, "")
|
98
|
+
|
99
|
+
family = detect_family(@document)
|
100
|
+
props = Filters::Export[output_ext] or raise DocumentConversionError, "unknown output format: #{output_ext}"
|
101
|
+
props = props[family] or raise DocumentConversionError, "unsupported conversion: from #{family} to #{output_ext}"
|
102
|
+
|
103
|
+
@document.storeToURL(output_url, props.to_uno_properties)
|
104
|
+
|
105
|
+
true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ODF
|
2
|
+
class Converter
|
3
|
+
module Filters
|
4
|
+
module BaseFilter
|
5
|
+
def self.included(klass)
|
6
|
+
klass.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def [](filter)
|
11
|
+
self.const_get(filter.to_s.upcase) rescue nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module ODF
|
2
|
+
class Converter
|
3
|
+
module Filters
|
4
|
+
module Export
|
5
|
+
include BaseFilter
|
6
|
+
|
7
|
+
# see http://wiki.services.openoffice.org/wiki/Framework/Article/Filter
|
8
|
+
# most formats are auto-detected; only those requiring options are defined here
|
9
|
+
PDF = {
|
10
|
+
ODF::Converter::Families::TEXT => {
|
11
|
+
FilterName: "writer_pdf_Export"
|
12
|
+
},
|
13
|
+
ODF::Converter::Families::WEB => {
|
14
|
+
FilterName: "writer_web_pdf_Export"
|
15
|
+
},
|
16
|
+
ODF::Converter::Families::SPREADSHEET => {
|
17
|
+
FilterName: "calc_pdf_Export"
|
18
|
+
},
|
19
|
+
ODF::Converter::Families::PRESENTATION => {
|
20
|
+
FilterName: "impress_pdf_Export"
|
21
|
+
},
|
22
|
+
ODF::Converter::Families::DRAWING => {
|
23
|
+
FilterName: "draw_pdf_Export"
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
HTML = {
|
28
|
+
ODF::Converter::Families::TEXT => {
|
29
|
+
FilterName: "HTML (StarWriter)"
|
30
|
+
},
|
31
|
+
ODF::Converter::Families::SPREADSHEET => {
|
32
|
+
FilterName: "HTML (StarCalc)"
|
33
|
+
},
|
34
|
+
ODF::Converter::Families::PRESENTATION => {
|
35
|
+
FilterName: "impress_html_Export"
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
ODT = {
|
40
|
+
ODF::Converter::Families::TEXT => {
|
41
|
+
FilterName: "writer8"
|
42
|
+
},
|
43
|
+
ODF::Converter::Families::WEB => {
|
44
|
+
FilterName: "writerweb8_writer"
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
DOC = {
|
49
|
+
ODF::Converter::Families::TEXT => {
|
50
|
+
FilterName: "MS Word 97"
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
DOCX = {
|
55
|
+
ODF::Converter::Families::TEXT => {
|
56
|
+
FilterName: "MS Word 2007 XML"
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
RTF = {
|
61
|
+
ODF::Converter::Families::TEXT => {
|
62
|
+
FilterName: "Rich Text Format"
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
TXT = {
|
67
|
+
ODF::Converter::Families::TEXT => {
|
68
|
+
FilterName: "Text",
|
69
|
+
FilterOptions: "utf8"
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
ODS = {
|
74
|
+
ODF::Converter::Families::SPREADSHEET => {
|
75
|
+
FilterName: "calc8"
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
XLS = {
|
80
|
+
ODF::Converter::Families::SPREADSHEET => {
|
81
|
+
FilterName: "MS Excel 97"
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
CSV = {
|
86
|
+
ODF::Converter::Families::SPREADSHEET => {
|
87
|
+
FilterName: "Text - txt - csv (StarCalc)",
|
88
|
+
FilterOptions: "44,34,0"
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
ODP = {
|
93
|
+
ODF::Converter::Families::PRESENTATION => {
|
94
|
+
FilterName: "impress8"
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
PPT = {
|
99
|
+
ODF::Converter::Families::PRESENTATION => {
|
100
|
+
FilterName: "MS PowerPoint 97"
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
SWF = {
|
105
|
+
ODF::Converter::Families::PRESENTATION => {
|
106
|
+
FilterName: "impress_flash_Export"
|
107
|
+
},
|
108
|
+
ODF::Converter::Families::DRAWING => {
|
109
|
+
FilterName: "draw_flash_Export"
|
110
|
+
}
|
111
|
+
}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ODF
|
2
|
+
class Converter
|
3
|
+
module Filters
|
4
|
+
module Import
|
5
|
+
include BaseFilter
|
6
|
+
|
7
|
+
# see http://wiki.services.openoffice.org/wiki/Framework/Article/Filter
|
8
|
+
# most formats are auto-detected; only those requiring options are defined here
|
9
|
+
TXT = {
|
10
|
+
FilterName: "Text (encoded)",
|
11
|
+
FilterOptions: "utf8"
|
12
|
+
}
|
13
|
+
|
14
|
+
CSV = {
|
15
|
+
FilterName: "Text - txt - csv (StarCalc)",
|
16
|
+
FilterOptions: "44,34,0"
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/odf/converter/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Daniel Vandersluis"]
|
6
|
+
gem.email = ["dvandersluis@selfmgmt.com"]
|
7
|
+
gem.description = %q{Ruby library for converting ODF files through OO.org}
|
8
|
+
gem.summary = %q{Uses a native Ruby-UNO bridge (rubyuno) to connect to OpenOffice.org running as a service and convert ODF documents to a different format.}
|
9
|
+
gem.homepage = "https://www.github.com/dvandersluis/odf-converter"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "odf-converter"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = ODF::Converter::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency "rubyuno"
|
19
|
+
gem.add_development_dependency "pry"
|
20
|
+
gem.add_development_dependency "pry-editline"
|
21
|
+
gem.add_development_dependency "rspec"
|
22
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'odf/converter'
|
2
|
+
|
3
|
+
describe ODF::Converter do
|
4
|
+
describe "#new" do
|
5
|
+
it "should initialize a connection" do
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#convert" do
|
10
|
+
let(:c) { ODF::Converter.new }
|
11
|
+
|
12
|
+
describe do
|
13
|
+
before { c.stub(:perform_conversion) { true } }
|
14
|
+
|
15
|
+
it "should raise an error if the to option is not given" do
|
16
|
+
expect { c.convert("infile.txt") }.to raise_error ArgumentError
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should raise an error if the to option is a string but doesn't look like a file with extension" do
|
20
|
+
expect { c.convert("infile.txt", to: "file") }.to raise_error ODF::Converter::DocumentConversionError
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should raise an error if the to option is not a string or a symbol" do
|
24
|
+
expect { c.convert("infile.txt", to: []) }.to raise_error ODF::Converter::DocumentConversionError
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should output to the input file name with the extension changed if to is set to a symbol" do
|
28
|
+
FileUtils.cd "/"
|
29
|
+
|
30
|
+
c.convert("infile.txt", to: :html).should == "/infile.html"
|
31
|
+
c.convert("/home/username/infile.txt", to: :html).should == "/home/username/infile.html"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should output to the given name if it's a valid filename" do
|
35
|
+
FileUtils.cd "/"
|
36
|
+
|
37
|
+
c.convert("infile.txt", to: "outfile.html").should == "/outfile.html"
|
38
|
+
c.convert("/home/username/infile.txt", to: "/home/username/outfile.html").should == "/home/username/outfile.html"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: odf-converter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Daniel Vandersluis
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rubyuno
|
16
|
+
requirement: &20530940 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *20530940
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: pry
|
27
|
+
requirement: &20530480 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *20530480
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: pry-editline
|
38
|
+
requirement: &20529660 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *20529660
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &20528780 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *20528780
|
58
|
+
description: Ruby library for converting ODF files through OO.org
|
59
|
+
email:
|
60
|
+
- dvandersluis@selfmgmt.com
|
61
|
+
executables: []
|
62
|
+
extensions: []
|
63
|
+
extra_rdoc_files: []
|
64
|
+
files:
|
65
|
+
- .gitignore
|
66
|
+
- Gemfile
|
67
|
+
- LICENSE
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- lib/odf-converter.rb
|
71
|
+
- lib/odf/converter.rb
|
72
|
+
- lib/odf/converter/families.rb
|
73
|
+
- lib/odf/converter/filters/base_filter.rb
|
74
|
+
- lib/odf/converter/filters/export.rb
|
75
|
+
- lib/odf/converter/filters/import.rb
|
76
|
+
- lib/odf/converter/hash.rb
|
77
|
+
- lib/odf/converter/version.rb
|
78
|
+
- odf-converter.gemspec
|
79
|
+
- spec/odf/converter_spec.rb
|
80
|
+
homepage: https://www.github.com/dvandersluis/odf-converter
|
81
|
+
licenses: []
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 1.8.12
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: Uses a native Ruby-UNO bridge (rubyuno) to connect to OpenOffice.org running
|
104
|
+
as a service and convert ODF documents to a different format.
|
105
|
+
test_files:
|
106
|
+
- spec/odf/converter_spec.rb
|
107
|
+
has_rdoc:
|