rubyword 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +1 -0
- data/CHANGELOG.txt +10 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/README.md +125 -0
- data/Rakefile +4 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/doc/README.md +1 -0
- data/doc/text.md +1 -0
- data/lib/rubyword/configuration.rb +5 -0
- data/lib/rubyword/document.rb +81 -0
- data/lib/rubyword/element/base.rb +12 -0
- data/lib/rubyword/element/image.rb +45 -0
- data/lib/rubyword/element/link.rb +35 -0
- data/lib/rubyword/element/list.rb +35 -0
- data/lib/rubyword/element/page_break.rb +26 -0
- data/lib/rubyword/element/section.rb +67 -0
- data/lib/rubyword/element/text.rb +137 -0
- data/lib/rubyword/element/text_break.rb +20 -0
- data/lib/rubyword/version.rb +3 -0
- data/lib/rubyword/writer/part/base.rb +13 -0
- data/lib/rubyword/writer/part/content_types.rb +39 -0
- data/lib/rubyword/writer/part/doc_props_app.rb +20 -0
- data/lib/rubyword/writer/part/doc_props_core.rb +32 -0
- data/lib/rubyword/writer/part/doc_props_custom.rb +16 -0
- data/lib/rubyword/writer/part/document.rb +56 -0
- data/lib/rubyword/writer/part/font_table.rb +12 -0
- data/lib/rubyword/writer/part/footer.rb +50 -0
- data/lib/rubyword/writer/part/header.rb +40 -0
- data/lib/rubyword/writer/part/numbering.rb +51 -0
- data/lib/rubyword/writer/part/rels.rb +26 -0
- data/lib/rubyword/writer/part/rels_document.rb +31 -0
- data/lib/rubyword/writer/part/settings.rb +93 -0
- data/lib/rubyword/writer/part/styles.rb +91 -0
- data/lib/rubyword/writer/part/theme.rb +12 -0
- data/lib/rubyword/writer/part/toc.rb +89 -0
- data/lib/rubyword/writer/part/web_settings.rb +21 -0
- data/lib/rubyword/writer/style/base.rb +16 -0
- data/lib/rubyword/writer/style/section.rb +65 -0
- data/lib/rubyword/writer.rb +87 -0
- data/lib/rubyword.rb +9 -0
- data/rubyword.gemspec +27 -0
- data/sample/test.rb +78 -0
- data/spec/rubyword/document_spec.rb +11 -0
- data/spec/spec_helper.rb +32 -0
- data/template/fontTable.xml +54 -0
- data/template/theme.xml +284 -0
- metadata +197 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 94a411b43cd5b8e055aa0d391332d91e29b5a9eb
|
4
|
+
data.tar.gz: 3253a4e9f289ba99b9e62a0ab73b1cb43c223d58
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d67230b2cb422a7a5631c9844a1fa44b77a0739b683dfcecd86b9e090989ade5d625d7dfb8a1d17aef10c9a8290a59799a95fd092507b0bd40554aea31a28557
|
7
|
+
data.tar.gz: 82ebc3d3424424abc1293896448472dc53d76f41fbbb921e6eeb158793172c017992458c07819c011674d29737e4f7dff8e78c115c3181379a79bd9f389778b1
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/CHANGELOG.txt
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
CHANGELOG
|
2
|
+
Version 0.1.0:
|
3
|
+
* Support for setting the properties of the document, such as: title, subject, author and other information
|
4
|
+
* Support for generated TOC for the title
|
5
|
+
* Support for setting header and footer
|
6
|
+
* Support for insert title which is different attributes, such as: title, sub title, etc.
|
7
|
+
* Support for insert blank lines and blank page
|
8
|
+
* Support for insert multiple images
|
9
|
+
* Support for insert multiple lists
|
10
|
+
* Support for insert hyperlink
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Nicholas Frandsen
|
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,125 @@
|
|
1
|
+
# RubyWord: Microsoft Word Generation For Ruby
|
2
|
+
> RubyWord is a simple, efficient Word document generation gem and easy to generate docx file.
|
3
|
+
|
4
|
+
# Please Read Before Use
|
5
|
+
This project is under developing, and develop by myself until now, so the progress may be slow and there may be a lot of problems, but i will try my best to improve it and welcome everyone to join the development. Thanks for supporting.
|
6
|
+
|
7
|
+
# Installing RubyWord
|
8
|
+
```
|
9
|
+
gem install rubyword
|
10
|
+
```
|
11
|
+
or put this line in your Gemfile
|
12
|
+
```
|
13
|
+
gem 'rubyword'
|
14
|
+
```
|
15
|
+
# Features
|
16
|
+
+ Support for setting the properties of the document, such as: title, subject, author and other information
|
17
|
+
+ Support for generated TOC for the title
|
18
|
+
+ Support for setting header and footer
|
19
|
+
+ Support for insert title which is different attributes, such as: title, sub title, etc.
|
20
|
+
+ Support for insert blank lines and blank page
|
21
|
+
+ Support for insert multiple images
|
22
|
+
+ Support for insert multiple lists
|
23
|
+
+ Support for insert hyperlink
|
24
|
+
|
25
|
+
# Usage
|
26
|
+
```
|
27
|
+
require "rubyword"
|
28
|
+
Rubyword::Document::generate('hello.docx') {
|
29
|
+
# write the doc infomation
|
30
|
+
information({
|
31
|
+
company: 'ruby word',
|
32
|
+
creator: 'young',
|
33
|
+
title: 'example word file',
|
34
|
+
description: 'this is a example docx',
|
35
|
+
subject: 'how to create doc info',
|
36
|
+
keywords: 'remark',
|
37
|
+
category: 'category'
|
38
|
+
})
|
39
|
+
|
40
|
+
# Generate the directory structure
|
41
|
+
title_directory font_size: 24
|
42
|
+
|
43
|
+
# insert header
|
44
|
+
add_header 'rubyword'
|
45
|
+
|
46
|
+
# insert footer with number
|
47
|
+
add_footer nil, text_align: 'center', nums_type: 'number'
|
48
|
+
# insert text
|
49
|
+
# add_footer 'hello', text_align: 'center'
|
50
|
+
# initialize section and insert something in the section
|
51
|
+
section {
|
52
|
+
# insert title
|
53
|
+
title_1 "It's a title", ignore_dir: true
|
54
|
+
# insert subtitle
|
55
|
+
title_2 "It's a subtitle"
|
56
|
+
# insert title
|
57
|
+
title_1 'Database'
|
58
|
+
# insert subtitle
|
59
|
+
title_2 'MySQL'
|
60
|
+
# insert No.3 title
|
61
|
+
title_3 'NoSQL'
|
62
|
+
# text break
|
63
|
+
text_break 3
|
64
|
+
# insert text
|
65
|
+
text 'hello word', bgcolor: 'yellow', text_align: 'center'
|
66
|
+
# page break
|
67
|
+
page_break 2
|
68
|
+
# insert text
|
69
|
+
text 'hello word', indent_between: '1440-1440'
|
70
|
+
text 'title', { font_size: 62, color: '996699', blod: true, text_align: 'center' }
|
71
|
+
|
72
|
+
# insert title
|
73
|
+
title_1 'section2 title'
|
74
|
+
title_2 'section2 title'
|
75
|
+
title_3 'section2 title'
|
76
|
+
|
77
|
+
# add a link
|
78
|
+
link 'baidu', 'http://www.baidu.com', text_align: 'center'
|
79
|
+
}
|
80
|
+
|
81
|
+
section {
|
82
|
+
# insert a text
|
83
|
+
text 'another Section', bgcolor: 'yellow', text_align: 'center'
|
84
|
+
|
85
|
+
# insert a text
|
86
|
+
text 'hello word', indent_between: '1440-1440'
|
87
|
+
text 'title', { font_size: 62, color: '996699', blod: true, text_align: 'center' }
|
88
|
+
}
|
89
|
+
|
90
|
+
section {
|
91
|
+
list 'test1', 1
|
92
|
+
list 'test1', 2
|
93
|
+
list 'test3', 2
|
94
|
+
list 'test2', 1
|
95
|
+
list 'test2', 1
|
96
|
+
}
|
97
|
+
|
98
|
+
section {
|
99
|
+
# add a link
|
100
|
+
link 'baidu', 'http://www.baidu.com', text_align: 'center'
|
101
|
+
image 'http://www.baidu.com/img/bd_logo1.png'
|
102
|
+
}
|
103
|
+
}
|
104
|
+
```
|
105
|
+
|
106
|
+
# TODO
|
107
|
+
+ Support table
|
108
|
+
+ Support paragraph
|
109
|
+
+ Support more style
|
110
|
+
+ Support Markdown/HTML to docx
|
111
|
+
|
112
|
+
# Contributing
|
113
|
+
RubyWord is use my spare time to write, so it may has a lot of Bugs and welcome everyone to create Pull Request or Issue to improve this project together.
|
114
|
+
1. fork this project
|
115
|
+
2. git clone your fork project
|
116
|
+
3. git checkout -b fixed-something
|
117
|
+
4. git commit fixed some bug.
|
118
|
+
5. git push to your fork project
|
119
|
+
6. create a new pr to request merge
|
120
|
+
|
121
|
+
# Inspiration
|
122
|
+
Thanks [PHPWord](https://github.com/PHPOffice/PHPWord), I was very surprised when I saw the PHPWord project which is a very powerful project and provide a lot of features. But I can't find such as ruby project when i search in google and I decided to write and design by myself.
|
123
|
+
|
124
|
+
# License
|
125
|
+
RubyWord is licensed under [The MIT License](LICENSE)
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "rubyword"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/doc/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# keep
|
data/doc/text.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# keep
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require_relative "element/section"
|
3
|
+
require_relative "writer"
|
4
|
+
module Rubyword
|
5
|
+
class Document
|
6
|
+
attr_accessor :sections, :init_rid
|
7
|
+
attr_accessor :relation_rids, :content_types, :rels_documents, :images
|
8
|
+
attr_accessor :header, :footer
|
9
|
+
attr_accessor :doc_info, :toc
|
10
|
+
include Writer
|
11
|
+
|
12
|
+
def self.generate(filename, options = {}, &block)
|
13
|
+
rubyword = new(options, &block)
|
14
|
+
rubyword.save(filename)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(options={}, &block)
|
18
|
+
@sections, @toc, @init_rid, @doc_info = [], {}, 7, {}
|
19
|
+
@relation_rids = []
|
20
|
+
@content_types = []
|
21
|
+
@rels_documents = []
|
22
|
+
@images = []
|
23
|
+
instance_eval(&block) if block_given?
|
24
|
+
end
|
25
|
+
|
26
|
+
def section(style=nil, &block)
|
27
|
+
@section = Element::Section.new(@sections.count + 1, style, self)
|
28
|
+
self.sections << @section
|
29
|
+
@section.instance_eval(&block) if block_given?
|
30
|
+
end
|
31
|
+
|
32
|
+
def title_directory(option= {})
|
33
|
+
@toc.merge!(open: true)
|
34
|
+
@toc.merge!(option)
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_header(text, options={})
|
38
|
+
@header = {
|
39
|
+
id: 1,
|
40
|
+
text: text,
|
41
|
+
rid: self.init_rid,
|
42
|
+
text_align: options[:align] || 'center',
|
43
|
+
type: 'header'
|
44
|
+
}
|
45
|
+
self.content_types << {
|
46
|
+
"/word/header1.xml" => "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"
|
47
|
+
}
|
48
|
+
self.rels_documents << {
|
49
|
+
Id: "rId#{self.init_rid}",
|
50
|
+
Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
|
51
|
+
Target: "header1.xml"
|
52
|
+
}
|
53
|
+
self.init_rid = self.init_rid + 1
|
54
|
+
end
|
55
|
+
|
56
|
+
def add_footer(text=nil, options={})
|
57
|
+
@footer = {
|
58
|
+
id: 1,
|
59
|
+
text: text,
|
60
|
+
rid: self.init_rid,
|
61
|
+
text_align: options[:align] || 'center',
|
62
|
+
nums_type: options[:nums_type],
|
63
|
+
type: 'footer'
|
64
|
+
}
|
65
|
+
self.content_types << {
|
66
|
+
"/word/footer1.xml" => "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml"
|
67
|
+
}
|
68
|
+
self.rels_documents << {
|
69
|
+
Id: "rId#{self.init_rid}",
|
70
|
+
Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
|
71
|
+
Target: "footer1.xml"
|
72
|
+
}
|
73
|
+
self.init_rid = self.init_rid + 1
|
74
|
+
end
|
75
|
+
|
76
|
+
def information(options={})
|
77
|
+
@doc_info = options
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Rubyword
|
3
|
+
module Element
|
4
|
+
class Image < Base
|
5
|
+
attr_accessor :images
|
6
|
+
def save(url, style=nil)
|
7
|
+
@images ||= Queue.new
|
8
|
+
filename = url.split('/').last
|
9
|
+
width, height = FastImage.size(url)
|
10
|
+
image_params = {
|
11
|
+
rid: @rubyword.init_rid,
|
12
|
+
path: url,
|
13
|
+
width: width,
|
14
|
+
height: height,
|
15
|
+
filename: filename
|
16
|
+
}
|
17
|
+
@images << image_params
|
18
|
+
@rubyword.images << image_params
|
19
|
+
@rubyword.rels_documents << {
|
20
|
+
Id: "rId#{@rubyword.init_rid}",
|
21
|
+
Type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
|
22
|
+
Target: "media/#{filename}"
|
23
|
+
}
|
24
|
+
@rubyword.init_rid = @rubyword.init_rid + 1
|
25
|
+
end
|
26
|
+
|
27
|
+
def write(section=nil, xml=nil)
|
28
|
+
@xml = xml
|
29
|
+
image = self.images.pop
|
30
|
+
@xml.send('w:p') {
|
31
|
+
@xml.send('w:pPr')
|
32
|
+
@xml.send('w:r') {
|
33
|
+
@xml.send('w:pict') {
|
34
|
+
@xml.send('v:shape', 'type' => '#_x0000_t75', 'style' => "width:#{image[:width]}px; height:#{image[:height]}px; margin-left:0px; margin-top:0px; mso-position-horizontal:left; mso-position-vertical:top; mso-position-horizontal-relative:char; mso-position-vertical-relative:line;") {
|
35
|
+
@xml.send('w10:wrap', 'type' => 'inline', 'anchorx' => 'page', 'anchory' => 'page')
|
36
|
+
@xml.send('v:imagedata', 'r:id' => "rId#{image[:rid]}", 'o:title' => '')
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Rubyword
|
3
|
+
module Element
|
4
|
+
class Link < Base
|
5
|
+
attr_accessor :links
|
6
|
+
def save(text, link, style)
|
7
|
+
@links ||= Queue.new
|
8
|
+
return if text.nil?
|
9
|
+
@rubyword.rels_documents << {
|
10
|
+
Id: "rId#{@rubyword.init_rid}",
|
11
|
+
Type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
|
12
|
+
Target: link,
|
13
|
+
TargetMode: 'External'
|
14
|
+
}
|
15
|
+
@links << { rId: @rubyword.init_rid, text: text, link: link }
|
16
|
+
@rubyword.init_rid = @rubyword.init_rid + 1
|
17
|
+
end
|
18
|
+
|
19
|
+
def write(section=nil, xml=nil)
|
20
|
+
@xml = xml
|
21
|
+
link = self.links.pop
|
22
|
+
@xml.send('w:p') {
|
23
|
+
@xml.send('hyperlink', 'r:id' => "rId#{link[:rId]}", 'w:history' => '1') {
|
24
|
+
@xml.send('w:r') {
|
25
|
+
# TODO: add style
|
26
|
+
@xml.send('w:rPr')
|
27
|
+
@xml.send('w:t', {'xml:space' => 'preserve'}, link[:text])
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Rubyword
|
3
|
+
module Element
|
4
|
+
class List < Base
|
5
|
+
attr_accessor :lists
|
6
|
+
|
7
|
+
# write document and numbering
|
8
|
+
def save(text, level, style)
|
9
|
+
@lists ||= Queue.new
|
10
|
+
@lists << {
|
11
|
+
level: level.to_i - 1,
|
12
|
+
text: text
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def write(section=nil, xml=nil)
|
17
|
+
@xml = xml
|
18
|
+
list = self.lists.pop
|
19
|
+
@xml.send('w:p') {
|
20
|
+
@xml.send('w:pPr') {
|
21
|
+
@xml.send('w:numPr') {
|
22
|
+
@xml.send('w:ilvl', 'w:val' => list[:level])
|
23
|
+
@xml.send('w:numId', 'w:val' => 3)
|
24
|
+
}
|
25
|
+
}
|
26
|
+
@xml.send('w:r') {
|
27
|
+
@xml.send('w:rPr')
|
28
|
+
@xml.send('w:t', {'xml:space' => 'preserve'}, list[:text])
|
29
|
+
}
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Rubyword
|
3
|
+
module Element
|
4
|
+
class PageBreak < Base
|
5
|
+
attr_accessor :numbers
|
6
|
+
|
7
|
+
def save(numbers)
|
8
|
+
@numbers ||= Queue.new
|
9
|
+
@numbers << numbers.to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
def write(section=nil, xml=nil)
|
13
|
+
@xml = xml
|
14
|
+
page_break = self.numbers.pop
|
15
|
+
page_break.to_i.times.each do |i|
|
16
|
+
@xml.send('w:p') {
|
17
|
+
@xml.send('w:r') {
|
18
|
+
@xml.send('w:br', 'w:type' => 'page')
|
19
|
+
}
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require_relative 'base'
|
3
|
+
require_relative 'text'
|
4
|
+
require_relative 'link'
|
5
|
+
require_relative 'list'
|
6
|
+
require_relative 'image'
|
7
|
+
require_relative 'page_break'
|
8
|
+
require_relative 'text_break'
|
9
|
+
module Rubyword
|
10
|
+
module Element
|
11
|
+
class Section
|
12
|
+
attr_accessor :section_id, :style, :rubyword, :section_objects, :objects, :titles
|
13
|
+
def initialize(section_count, style = nil, rubyword=nil)
|
14
|
+
@section_id = section_count
|
15
|
+
@style = style
|
16
|
+
@rubyword = rubyword
|
17
|
+
@section_objects = []
|
18
|
+
@objects = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate(&block)
|
22
|
+
!block.nil? && block.arity < 1 ? instance_eval(&block) : block[self]
|
23
|
+
end
|
24
|
+
|
25
|
+
def text(text, style=nil)
|
26
|
+
object ||= Text.new(@rubyword, self)
|
27
|
+
object.save(text, __callee__.to_s, style)
|
28
|
+
@objects << object
|
29
|
+
end
|
30
|
+
alias :title_1 :text
|
31
|
+
alias :title_2 :text
|
32
|
+
alias :title_3 :text
|
33
|
+
alias :title_4 :text
|
34
|
+
|
35
|
+
def list(text, level, style=nil)
|
36
|
+
object ||= List.new(@rubyword)
|
37
|
+
object.save(text, level, style)
|
38
|
+
@objects << object
|
39
|
+
end
|
40
|
+
|
41
|
+
def image(url)
|
42
|
+
object ||= Image.new(@rubyword)
|
43
|
+
object.save(url)
|
44
|
+
@objects << object
|
45
|
+
end
|
46
|
+
|
47
|
+
def link(text, link, style=nil)
|
48
|
+
object ||= Link.new(@rubyword)
|
49
|
+
object.save(text, link, style)
|
50
|
+
@objects << object
|
51
|
+
end
|
52
|
+
|
53
|
+
def page_break(break_num=1)
|
54
|
+
object ||= PageBreak.new(@rubyword)
|
55
|
+
object.save(break_num)
|
56
|
+
@objects << object
|
57
|
+
end
|
58
|
+
|
59
|
+
def text_break(break_num=1)
|
60
|
+
object ||= TextBreak.new(@rubyword)
|
61
|
+
object.save(break_num)
|
62
|
+
@objects << object
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Rubyword
|
3
|
+
module Element
|
4
|
+
class Text < Base
|
5
|
+
attr_accessor :texts
|
6
|
+
|
7
|
+
IndentSize = 200
|
8
|
+
WordStyleList = {
|
9
|
+
font_size: 'w:sz',
|
10
|
+
color: 'w:color',
|
11
|
+
underline: 'w:u',
|
12
|
+
blod: 'w:b',
|
13
|
+
all_caps: 'w:caps',
|
14
|
+
italic: 'w:i',
|
15
|
+
bgcolor: 'w:highlight'
|
16
|
+
}.freeze
|
17
|
+
ParagraphStyleList = {
|
18
|
+
text_align: 'w:jc',
|
19
|
+
spacing: 'w:spacing',
|
20
|
+
indent_left: 'w:ind',
|
21
|
+
indent_right: 'w:ind',
|
22
|
+
indent_between: 'w:ind'
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
def save(text, type, style)
|
26
|
+
@texts ||= Queue.new
|
27
|
+
@section.titles ||= []
|
28
|
+
return if text.nil?
|
29
|
+
if type == 'text'
|
30
|
+
text(text, style)
|
31
|
+
else
|
32
|
+
self.send(type.to_sym, text, style)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def text(text, style)
|
37
|
+
@texts << { size: 'normal', text: text.to_s, style: style }
|
38
|
+
end
|
39
|
+
|
40
|
+
(1..4).each do |num|
|
41
|
+
define_method "title_#{num}" do |text, style|
|
42
|
+
@rubyword.relation_rids << {rid: @rubyword.init_rid, type: "title_#{num}"}
|
43
|
+
title_hs = {
|
44
|
+
indent: (num - 1) * IndentSize,
|
45
|
+
size: "title_#{num}",
|
46
|
+
text: text.to_s,
|
47
|
+
rid: @rubyword.init_rid,
|
48
|
+
style: style
|
49
|
+
}
|
50
|
+
@section.titles << title_hs if (style && !style[:ignore_dir]) || style.nil?
|
51
|
+
@texts << title_hs
|
52
|
+
@rubyword.init_rid = @rubyword.init_rid + 1
|
53
|
+
end
|
54
|
+
|
55
|
+
define_method "write_title_#{num}" do |args|
|
56
|
+
@xml.send('w:p') do
|
57
|
+
@xml.send('w:pPr') {
|
58
|
+
@xml.send('w:pStyle', 'w:val' => "Heading#{num}")
|
59
|
+
}
|
60
|
+
@xml.send('bookmarkStart', 'w:id' => args[:rid], 'w:name' => "_Toc#{args[:rid]}")
|
61
|
+
@xml.send('w:r') {
|
62
|
+
@xml.send('w:t', args[:text])
|
63
|
+
}
|
64
|
+
@xml.send('bookmarkEnd', 'w:id' => args[:rid])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def write(section=nil, xml=nil)
|
70
|
+
@xml = xml
|
71
|
+
text = self.texts.pop
|
72
|
+
eval "write_#{text[:size]}(text)"
|
73
|
+
end
|
74
|
+
|
75
|
+
def write_normal(text)
|
76
|
+
@xml.send('w:p') do
|
77
|
+
write_paragraph_style(text[:style])
|
78
|
+
@xml.send('w:r') do
|
79
|
+
write_word_style(text[:style])
|
80
|
+
@xml.send('w:t', {'xml:space' => 'preserve'}, text[:text])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def write_word_style(style)
|
86
|
+
if style.is_a?(Hash)
|
87
|
+
@xml.send('w:rPr') {
|
88
|
+
style.keys.each do |style_name|
|
89
|
+
style_name = style_name.to_sym
|
90
|
+
if WordStyleList.keys.include?(style_name)
|
91
|
+
value =style[style_name]
|
92
|
+
attribute = if !!value != value # not a bool type
|
93
|
+
{'w:val' => value}
|
94
|
+
else
|
95
|
+
nil
|
96
|
+
end
|
97
|
+
doc_style = WordStyleList[style_name]
|
98
|
+
@xml.send(doc_style, attribute)
|
99
|
+
@xml.send('w:szCs', attribute) if style_name == :font_size
|
100
|
+
end
|
101
|
+
end
|
102
|
+
}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def write_paragraph_style(style)
|
107
|
+
return unless style.is_a?(Hash)
|
108
|
+
@xml.send('w:pPr') {
|
109
|
+
style.keys.each do |style_name|
|
110
|
+
style_name = style_name.to_sym
|
111
|
+
next unless ParagraphStyleList.keys.include?(style_name)
|
112
|
+
value =style[style_name]
|
113
|
+
attribute = case style_name.to_s
|
114
|
+
when 'spacing'
|
115
|
+
{'w:after' => value}
|
116
|
+
when 'indent_left'
|
117
|
+
{'w:left' => value}
|
118
|
+
when 'indent_right'
|
119
|
+
{'w:right' => value}
|
120
|
+
when 'indent_between'
|
121
|
+
v = value.split '-'
|
122
|
+
next unless v.is_a?(Array)
|
123
|
+
{ 'w:left' => v[0].to_i, 'w:right' => v[1].to_i }
|
124
|
+
when !!value == value
|
125
|
+
nil
|
126
|
+
else
|
127
|
+
{'w:val' => value}
|
128
|
+
end
|
129
|
+
doc_style = ParagraphStyleList[style_name]
|
130
|
+
@xml.send(doc_style, attribute)
|
131
|
+
end
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|