ydocx 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/Manifest.txt +12 -0
- data/README.txt +21 -0
- data/Rakefile +17 -0
- data/bin/docx2html +27 -0
- data/lib/docx2html/bin/docx2html +16 -0
- data/lib/docx2html/lib/docx2html/builder.rb +100 -0
- data/lib/docx2html/lib/docx2html/document.rb +51 -0
- data/lib/docx2html/lib/docx2html/html_methods.rb +15 -0
- data/lib/docx2html/lib/docx2html/parser.rb +213 -0
- data/lib/docx2html/lib/docx2html.rb +7 -0
- data/lib/fachinfo.rb +112 -0
- metadata +85 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
bin/docx2html
|
6
|
+
lib/docx2html/bin/docx2html
|
7
|
+
lib/docx2html/lib/docx2html.rb
|
8
|
+
lib/docx2html/lib/docx2html/builder.rb
|
9
|
+
lib/docx2html/lib/docx2html/document.rb
|
10
|
+
lib/docx2html/lib/docx2html/html_methods.rb
|
11
|
+
lib/docx2html/lib/docx2html/parser.rb
|
12
|
+
lib/fachinfo.rb
|
data/README.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
== ydocx - © ywesee GmbH
|
2
|
+
|
3
|
+
* https://github.com/zdavatz/ydocx
|
4
|
+
* Parsing docx files with Ruby and output them as HTML.
|
5
|
+
|
6
|
+
== Supports
|
7
|
+
|
8
|
+
* Tables
|
9
|
+
* Uppercase letters, numbers
|
10
|
+
* Lowercase letters, numbers
|
11
|
+
* Umlaute
|
12
|
+
* bold, italic, underline
|
13
|
+
|
14
|
+
== Using the great libraries
|
15
|
+
|
16
|
+
* nokogiri
|
17
|
+
* htmlentities
|
18
|
+
|
19
|
+
== License GPLv2.1
|
20
|
+
|
21
|
+
* http://www.gnu.org/licenses/lgpl-2.1.html
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
|
6
|
+
# Hoe.plugin :compiler
|
7
|
+
# Hoe.plugin :gem_prelude_sucks
|
8
|
+
# Hoe.plugin :inline
|
9
|
+
# Hoe.plugin :minitest
|
10
|
+
# Hoe.plugin :racc
|
11
|
+
# Hoe.plugin :rubyforge
|
12
|
+
|
13
|
+
Hoe.spec 'ydocx' do
|
14
|
+
|
15
|
+
developer('Yasuhiro Asaka, Zeno R.R. Davatz', 'yasaka@ywesee.com, zdavatz@ywesee.com')
|
16
|
+
|
17
|
+
end
|
data/bin/docx2html
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
VERSION = "1.0.0"
|
7
|
+
|
8
|
+
root = Pathname.new(__FILE__).realpath.parent.parent
|
9
|
+
%w(
|
10
|
+
lib/docx2html/lib
|
11
|
+
lib
|
12
|
+
).each do |lib|
|
13
|
+
$:.unshift root.join(lib) if $0 == __FILE__
|
14
|
+
end
|
15
|
+
require 'docx2html'
|
16
|
+
|
17
|
+
if file = ARGV.first
|
18
|
+
unless File.exist?(file)
|
19
|
+
exit
|
20
|
+
else
|
21
|
+
# TODO args handling
|
22
|
+
if true
|
23
|
+
require 'fachinfo'
|
24
|
+
end
|
25
|
+
Docx2html::Document.open(file).to_html file, :style => true
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
root = Pathname.new(__FILE__).realpath.parent.parent
|
7
|
+
$:.unshift root.join('lib/docx2html') if $0 == __FILE__
|
8
|
+
require 'docx2html'
|
9
|
+
|
10
|
+
if file = ARGV.first
|
11
|
+
unless File.exist?(file)
|
12
|
+
exit
|
13
|
+
else
|
14
|
+
Docx2html::Document.open(file).to_html file, :style => true
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'nokogiri'
|
5
|
+
require 'docx2html/html_methods'
|
6
|
+
|
7
|
+
module Docx2html
|
8
|
+
class Builder
|
9
|
+
include HtmlMethods
|
10
|
+
attr_accessor :body, :indecies, :style, :title
|
11
|
+
def initialize(body)
|
12
|
+
@body = body
|
13
|
+
@container = {}
|
14
|
+
@indecies = []
|
15
|
+
@style = false
|
16
|
+
@title = ''
|
17
|
+
init
|
18
|
+
if block_given?
|
19
|
+
yield self
|
20
|
+
end
|
21
|
+
end
|
22
|
+
def init
|
23
|
+
end
|
24
|
+
def build
|
25
|
+
if @container.has_key?(:content)
|
26
|
+
@container[:content] = @body
|
27
|
+
@body = [@container]
|
28
|
+
end
|
29
|
+
if before_content = build_before_content
|
30
|
+
@body.unshift before_content
|
31
|
+
end
|
32
|
+
if after_content = build_after_content
|
33
|
+
@body.push after_content
|
34
|
+
end
|
35
|
+
body = ''
|
36
|
+
@body.each do |e|
|
37
|
+
body << build_tag(e[:tag], e[:content], e[:attributes])
|
38
|
+
end
|
39
|
+
builder = Nokogiri::HTML::Builder.new do |doc|
|
40
|
+
doc.html {
|
41
|
+
doc.head {
|
42
|
+
doc.meta :charset => 'utf-8'
|
43
|
+
doc.title @title
|
44
|
+
doc.style { doc << style } if @style
|
45
|
+
}
|
46
|
+
doc.body { doc << body }
|
47
|
+
}
|
48
|
+
end
|
49
|
+
builder.to_html.gsub(/\n/, '')
|
50
|
+
end
|
51
|
+
private
|
52
|
+
def build_after_content
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
def build_before_content
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
def build_tag(tag, content, attributes)
|
59
|
+
return '' if content.empty?
|
60
|
+
_content = ''
|
61
|
+
if content.is_a? Array
|
62
|
+
content.each do |c|
|
63
|
+
next if c.nil? or c.empty?
|
64
|
+
if c.is_a? Hash
|
65
|
+
_content << build_tag(c[:tag], c[:content], c[:attributes])
|
66
|
+
elsif c.is_a? String
|
67
|
+
_content << c.chomp.to_s
|
68
|
+
end
|
69
|
+
end
|
70
|
+
elsif content.is_a? Hash
|
71
|
+
_content = build_tag(content[:tag], content[:content], content[:attributes])
|
72
|
+
elsif content.is_a? String
|
73
|
+
_content = content
|
74
|
+
end
|
75
|
+
_tag = tag.to_s
|
76
|
+
_attributes = ''
|
77
|
+
unless attributes.empty?
|
78
|
+
attributes.each_pair do |k, v|
|
79
|
+
_attributes << " #{k.to_s}=#{v.to_s}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
"<#{_tag}#{_attributes}>#{_content}</#{_tag}>"
|
83
|
+
end
|
84
|
+
def style
|
85
|
+
style = <<-CSS
|
86
|
+
table, tr, td {
|
87
|
+
border-collapse: collapse;
|
88
|
+
border: 1px solid gray;
|
89
|
+
}
|
90
|
+
table {
|
91
|
+
margin: 5px 0 5px 0;
|
92
|
+
}
|
93
|
+
td {
|
94
|
+
padding: 5px 10px;
|
95
|
+
}
|
96
|
+
CSS
|
97
|
+
style.gsub(/\s\s+|\n/, ' ')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'pathname'
|
5
|
+
require 'zip/zip'
|
6
|
+
require 'docx2html/parser'
|
7
|
+
require 'docx2html/builder'
|
8
|
+
|
9
|
+
module Docx2html
|
10
|
+
class Document
|
11
|
+
attr_reader :contents
|
12
|
+
def self.open(file)
|
13
|
+
self.new(file)
|
14
|
+
end
|
15
|
+
def initialize(file)
|
16
|
+
@contents = nil
|
17
|
+
@indecies = nil
|
18
|
+
read(file)
|
19
|
+
end
|
20
|
+
def to_html(file='', options={})
|
21
|
+
html = ''
|
22
|
+
Builder.new(@contents) do |builder|
|
23
|
+
builder.title = @path
|
24
|
+
builder.style = options[:style]
|
25
|
+
if @indecies
|
26
|
+
builder.indecies = @indecies
|
27
|
+
end
|
28
|
+
html = builder.build
|
29
|
+
end
|
30
|
+
unless file.empty?
|
31
|
+
path = Pathname.new(file).realpath.sub_ext('.html')
|
32
|
+
File.open(path, 'w:utf-8') do |f|
|
33
|
+
f.puts html
|
34
|
+
end
|
35
|
+
else
|
36
|
+
html
|
37
|
+
end
|
38
|
+
end
|
39
|
+
private
|
40
|
+
def read(file)
|
41
|
+
@path = File.expand_path(file)
|
42
|
+
@zip = Zip::ZipFile.open(@path)
|
43
|
+
stream = @zip.find_entry('word/document.xml').get_input_stream
|
44
|
+
Parser.new(stream) do |parser|
|
45
|
+
@contents = parser.parse
|
46
|
+
@indecies = parser.indecies
|
47
|
+
end
|
48
|
+
@zip.close
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'nokogiri'
|
5
|
+
require 'htmlentities'
|
6
|
+
require 'docx2html/html_methods'
|
7
|
+
|
8
|
+
module Docx2html
|
9
|
+
class Parser
|
10
|
+
include HtmlMethods
|
11
|
+
attr_accessor :indecies, :result
|
12
|
+
def initialize(stream)
|
13
|
+
@xml = Nokogiri::XML.parse(stream)
|
14
|
+
@coder = HTMLEntities.new
|
15
|
+
@indecies = []
|
16
|
+
@result = []
|
17
|
+
init
|
18
|
+
if block_given?
|
19
|
+
yield self
|
20
|
+
end
|
21
|
+
end
|
22
|
+
def init
|
23
|
+
end
|
24
|
+
def parse
|
25
|
+
@xml.xpath('//w:document//w:body').children.map do |node|
|
26
|
+
case node.node_name
|
27
|
+
when 'text'
|
28
|
+
@result << parse_paragraph(node)
|
29
|
+
when 'tbl'
|
30
|
+
@result << parse_table(node)
|
31
|
+
when 'image'
|
32
|
+
# pending
|
33
|
+
when 'p'
|
34
|
+
@result << parse_paragraph(node)
|
35
|
+
else
|
36
|
+
# skip
|
37
|
+
end
|
38
|
+
end
|
39
|
+
@result
|
40
|
+
end
|
41
|
+
private
|
42
|
+
def apply_fonts(rpr, text)
|
43
|
+
symbol = false
|
44
|
+
unless rpr.xpath('w:rFonts').empty?
|
45
|
+
rpr.xpath('w:rFonts').each do |font|
|
46
|
+
if font.values.include? 'Symbol'
|
47
|
+
symbol = true
|
48
|
+
end
|
49
|
+
break if symbol
|
50
|
+
end
|
51
|
+
end
|
52
|
+
if symbol
|
53
|
+
_text = ''
|
54
|
+
text.unpack('U*').each do |char|
|
55
|
+
_text << optional_replace(char.to_s(16))
|
56
|
+
end
|
57
|
+
text = _text
|
58
|
+
end
|
59
|
+
text
|
60
|
+
end
|
61
|
+
def apply_align(rpr, text)
|
62
|
+
unless rpr.xpath('w:vertAlign').empty?
|
63
|
+
script = rpr.xpath('w:vertAlign').first['val'].to_sym
|
64
|
+
if script == :subscript
|
65
|
+
text = tag(:sub, text)
|
66
|
+
elsif script == :superscript
|
67
|
+
text = tag(:sup, text)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
text
|
71
|
+
end
|
72
|
+
def parse_as_block(r, text)
|
73
|
+
nil # default no block element
|
74
|
+
end
|
75
|
+
def optional_escape(text)
|
76
|
+
return text = ' ' if text.empty?
|
77
|
+
text.force_encoding('utf-8')
|
78
|
+
# NOTE
|
79
|
+
# :named only for escape at Builder
|
80
|
+
text = @coder.encode(text, :named)
|
81
|
+
text
|
82
|
+
end
|
83
|
+
def optional_replace(code)
|
84
|
+
code = '0x' + code
|
85
|
+
# NOTE
|
86
|
+
# replace with rsemble html character ref
|
87
|
+
# Symbol Font to HTML Character named ref
|
88
|
+
case code
|
89
|
+
when '0xf020' # '61472'
|
90
|
+
""
|
91
|
+
when '0xf025' # '61477'
|
92
|
+
"%"
|
93
|
+
when '0xf02b' # '61482'
|
94
|
+
"*"
|
95
|
+
when '0xf02b' # '61483'
|
96
|
+
"+"
|
97
|
+
when '0xf02d' # '61485'
|
98
|
+
"-"
|
99
|
+
when '0xf02f' # '61487'
|
100
|
+
"/"
|
101
|
+
when '0xf03c' # '61500'
|
102
|
+
"<"
|
103
|
+
when '0xf03d' # '61501'
|
104
|
+
"="
|
105
|
+
when '0xf03e' # '61502'
|
106
|
+
">"
|
107
|
+
when '0xf040' # '61504'
|
108
|
+
"≅"
|
109
|
+
when '0xf068' # '61544'
|
110
|
+
"η"
|
111
|
+
when '0xf071' # '61553'
|
112
|
+
"θ"
|
113
|
+
when '0xf06d' # '61549'
|
114
|
+
"μ"
|
115
|
+
when '0xf0a3' # '61603'
|
116
|
+
"≤"
|
117
|
+
when '0xf0ab' # '61611'
|
118
|
+
"↔"
|
119
|
+
when '0xf0ac' # '61612'
|
120
|
+
"←"
|
121
|
+
when '0xf0ad' # '61613'
|
122
|
+
"↑"
|
123
|
+
when '0xf0ae' # '61614'
|
124
|
+
"→"
|
125
|
+
when '0xf0ad' # '61615'
|
126
|
+
"↓"
|
127
|
+
when '0xf0b1' # '61617'
|
128
|
+
"±"
|
129
|
+
when '0xf0b2' # '61618'
|
130
|
+
"″"
|
131
|
+
when '0xf0b3' # '61619'
|
132
|
+
"≥"
|
133
|
+
when '0xf0b4' # '61620'
|
134
|
+
"×"
|
135
|
+
when '0xf0b7' # '61623'
|
136
|
+
"⋅"
|
137
|
+
else
|
138
|
+
#p "code : " + ("&#%s;" % code)
|
139
|
+
#p "hex : " + code.hex.to_s
|
140
|
+
#p "char : " + @coder.decode("&#%s;" % code)
|
141
|
+
#@coder.decode("&#%s;" % code.hex.to_s)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
def parse_image
|
145
|
+
# pending
|
146
|
+
end
|
147
|
+
def parse_paragraph(node)
|
148
|
+
paragraph = tag :p
|
149
|
+
node.xpath('w:r').each do |r|
|
150
|
+
unless r.xpath('w:t').empty?
|
151
|
+
paragraph[:content] << parse_text(r)
|
152
|
+
else
|
153
|
+
unless r.xpath('w:tab').empty?
|
154
|
+
if paragraph[:content].last != ' ' # as a space
|
155
|
+
paragraph[:content] << optional_escape('')
|
156
|
+
end
|
157
|
+
end
|
158
|
+
unless r.xpath('w:sym').empty?
|
159
|
+
code = r.xpath('w:sym').first['char'].downcase # w:char
|
160
|
+
paragraph[:content] << optional_replace(code)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
paragraph
|
165
|
+
end
|
166
|
+
def parse_table(node)
|
167
|
+
table = tag :table
|
168
|
+
node.xpath('w:tr').each do |tr|
|
169
|
+
cells = tag :tr
|
170
|
+
tr.xpath('w:tc').each do |tc|
|
171
|
+
attributes = {}
|
172
|
+
tc.xpath('w:tcPr').each do |tcpr|
|
173
|
+
if span = tcpr.xpath('w:gridSpan') and !span.empty?
|
174
|
+
attributes[:colspan] = span.first['val'] # w:val
|
175
|
+
end
|
176
|
+
end
|
177
|
+
cell = tag :td, [], attributes
|
178
|
+
tc.xpath('w:p').each do |p|
|
179
|
+
cell[:content] << parse_paragraph(p)
|
180
|
+
end
|
181
|
+
cells[:content] << cell
|
182
|
+
end
|
183
|
+
table[:content] << cells
|
184
|
+
end
|
185
|
+
table
|
186
|
+
end
|
187
|
+
def parse_text(r)
|
188
|
+
text = r.xpath('w:t').map(&:text).join('')
|
189
|
+
text = optional_escape(text)
|
190
|
+
if rpr = r.xpath('w:rPr')
|
191
|
+
text = apply_fonts(rpr, text)
|
192
|
+
if block = parse_as_block(r, text)
|
193
|
+
block
|
194
|
+
else
|
195
|
+
# inline tag
|
196
|
+
text = apply_align(rpr, text)
|
197
|
+
unless rpr.xpath('w:u').empty?
|
198
|
+
text = tag(:span, text, {:style => "text-decoration:underline;"})
|
199
|
+
end
|
200
|
+
unless rpr.xpath('w:i').empty?
|
201
|
+
text = tag(:em, text)
|
202
|
+
end
|
203
|
+
unless rpr.xpath('w:b').empty?
|
204
|
+
text = tag(:strong, text)
|
205
|
+
end
|
206
|
+
text
|
207
|
+
end
|
208
|
+
else
|
209
|
+
text
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
data/lib/fachinfo.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
module Docx2html
|
7
|
+
class Parser
|
8
|
+
private
|
9
|
+
def parse_as_block(r, text)
|
10
|
+
if r.parent.previous.nil?
|
11
|
+
# first line is package name
|
12
|
+
return tag(:h2, text)
|
13
|
+
end
|
14
|
+
text = text.strip
|
15
|
+
# TODO
|
16
|
+
# Franzoesisch
|
17
|
+
chapters = {
|
18
|
+
'Dos./Anw.' => /^Dosierung\s*\/\s*Anwendung/u, # 5
|
19
|
+
'Eigensch.' => /^Eigenschaften\s*\/\s*Wirkungen($|\s*\(\s*(ATC\-Code|Wirkungsmechanismus|Pharmakodyamik|Klinische\s+Wirksamkeit)\s*\)\s*$)|^Propri.t.s/iu, # 13
|
20
|
+
'Galen.Form' => /^Galenische\s+Form\s+und\s+Wirkstoffmenge\s+pro\s+Einheit$|^Forme\s*gal.nique/iu, # 3
|
21
|
+
'Ind./Anw.mögl.' => /^Indikationen(\s+|\s*\/\s*)Anwendungsmöglichkeiten$|^Indications/u, # 4
|
22
|
+
'Interakt.' => /^Interaktionen$|^Interactions/u, # 8
|
23
|
+
'Kontraind.' => /^Kontraindikationen($|\s*\(\s*absolute\s+Kontraindikationen\s*\)$)/u, # 6
|
24
|
+
'Name' => /^Name\s+des\s+Präparates$/, # 1
|
25
|
+
'Packungen' => /^Packungen($|\s*\(\s*mit\s+Angabe\s+der\s+Abgabekategorie\s*\)$)/u, # 18
|
26
|
+
'Präklin.' => /^Präklinische\s+Daten$/u, # 15
|
27
|
+
'Pharm.kinetik' => /^Pharmakokinetik($|\s*\((Absorption,\s*Distribution,\s*Metabolisms,\s*Elimination\s|Kinetik\s+spezieller\s+Patientengruppen)*\)$)|^Pharmacocin.tique?/iu, # 14
|
28
|
+
'Sonstige H.' => /^Sonstige\s*Hinweise($|\s*\(\s*(Inkompatibilitäten|Beeinflussung\s*diagnostischer\s*Methoden|Haltbarkeit|Besondere\s*Lagerungshinweise|Hinweise\s+für\s+die\s+Handhabung)\s*\)$)|^Remarques/u, # 16
|
29
|
+
'Schwangerschaft' => /^Schwangerschaft(,\s*|\s*\/\s*)Stillzeit$/u, # 9
|
30
|
+
'Stand d. Info.' => /^Stand\s+der\s+Information$|^Mise\s+.\s+jour$/iu, # 20
|
31
|
+
'Unerw.Wirkungen' => /^Unerwünschte\s+Wirkungen$/u, # 11
|
32
|
+
'Überdos.' => /^Überdosierung$|^Surdosage$/u, # 12
|
33
|
+
'Warn.hinw.' => /^Warnhinweise\s+und\s+Vorsichtsmassnahmen($|\s*\/\s*(relative\s+Kontraindikationen|Warnhinweise\s*und\s*Vorsichtsmassnahmen)$)/u, # 7
|
34
|
+
'Fahrtücht.' => /^Wirkung\s+auf\s+die\s+Fahrtüchtigkeit\s+und\s+auf\s+das\s+Bedienen\s+von\s+Maschinen$/u, # 10
|
35
|
+
'Swissmedic-Nr.' => /^Zulassungsnummer($|\s*\(\s*Swissmedic\s*\)$)/u, # 17
|
36
|
+
'Reg.Inhaber' => /^Zulassungsinhaberin($|\s*\(\s*Firma\s+und\s+Sitz\s+gemäss\s*Handelsregisterauszug\s*\))/u, # 19
|
37
|
+
'Zusammens.' => /^Zusammensetzung($|\s*\/\s*(Wirkstoffe|Hilsstoffe)$)/u, # 2
|
38
|
+
}.each_pair do |chapter, regexp|
|
39
|
+
if text =~ regexp
|
40
|
+
next unless r.next.nil? # without line break
|
41
|
+
id = CGI.escape(text.gsub(/&(.)uml;/, '\1').gsub(/\s*\/\s*|\/|\s+/, '_').downcase)
|
42
|
+
@indecies << {:text => chapter, :id => id}
|
43
|
+
return tag(:h3, text, {:id => id})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
class Builder
|
50
|
+
def init
|
51
|
+
@container = tag(:div, [], {:id => 'container'})
|
52
|
+
end
|
53
|
+
private
|
54
|
+
def build_after_content
|
55
|
+
link = tag(:a, 'Top', {:href => ''})
|
56
|
+
tag(:div, link, {:id => 'footer'})
|
57
|
+
end
|
58
|
+
def build_before_content
|
59
|
+
if @indecies
|
60
|
+
indices = []
|
61
|
+
@indecies.each do |index|
|
62
|
+
indices << tag(:li, tag(:a, index[:text], {:href => "#" + index[:id]}))
|
63
|
+
end
|
64
|
+
tag(:div, tag(:ul, indices), {:id => 'indecies'})
|
65
|
+
end
|
66
|
+
end
|
67
|
+
def style
|
68
|
+
style = <<-CSS
|
69
|
+
table, tr, td {
|
70
|
+
border-collapse: collapse;
|
71
|
+
border: 1px solid gray;
|
72
|
+
}
|
73
|
+
table {
|
74
|
+
margin: 5px 0 5px 0;
|
75
|
+
}
|
76
|
+
td {
|
77
|
+
padding: 5px 10px;
|
78
|
+
}
|
79
|
+
body {
|
80
|
+
position: relative;
|
81
|
+
padding: 0 0 20px 0;
|
82
|
+
margin: 0px;
|
83
|
+
width: 100%;
|
84
|
+
height: auto;
|
85
|
+
}
|
86
|
+
div#indecies {
|
87
|
+
position: relative;
|
88
|
+
padding: 0px;
|
89
|
+
float: left;
|
90
|
+
width: 200px;
|
91
|
+
}
|
92
|
+
div#indecies ul {
|
93
|
+
margin: 0;
|
94
|
+
padding: 0 0 0 25px;
|
95
|
+
}
|
96
|
+
div#container {
|
97
|
+
position: relative;
|
98
|
+
padding: 0px;
|
99
|
+
float: top left;
|
100
|
+
margin-left: 200px;
|
101
|
+
}
|
102
|
+
div#footer {
|
103
|
+
position: relative;
|
104
|
+
float: bottom right;
|
105
|
+
text-align: right;
|
106
|
+
padding-right: 25px;
|
107
|
+
}
|
108
|
+
CSS
|
109
|
+
style.gsub(/\s\s+|\n/, ' ')
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ydocx
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Yasuhiro Asaka, Zeno R.R. Davatz
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rdoc
|
16
|
+
requirement: &21539280 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.10'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *21539280
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hoe
|
27
|
+
requirement: &21538860 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.13'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *21538860
|
36
|
+
description: ''
|
37
|
+
email:
|
38
|
+
- yasaka@ywesee.com, zdavatz@ywesee.com
|
39
|
+
executables:
|
40
|
+
- docx2html
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files:
|
43
|
+
- History.txt
|
44
|
+
- Manifest.txt
|
45
|
+
- README.txt
|
46
|
+
files:
|
47
|
+
- History.txt
|
48
|
+
- Manifest.txt
|
49
|
+
- README.txt
|
50
|
+
- Rakefile
|
51
|
+
- bin/docx2html
|
52
|
+
- lib/docx2html/bin/docx2html
|
53
|
+
- lib/docx2html/lib/docx2html.rb
|
54
|
+
- lib/docx2html/lib/docx2html/builder.rb
|
55
|
+
- lib/docx2html/lib/docx2html/document.rb
|
56
|
+
- lib/docx2html/lib/docx2html/html_methods.rb
|
57
|
+
- lib/docx2html/lib/docx2html/parser.rb
|
58
|
+
- lib/fachinfo.rb
|
59
|
+
homepage: https://github.com/zdavatz/ydocx
|
60
|
+
licenses: []
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options:
|
63
|
+
- --main
|
64
|
+
- README.txt
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project: ydocx
|
81
|
+
rubygems_version: 1.8.15
|
82
|
+
signing_key:
|
83
|
+
specification_version: 3
|
84
|
+
summary: ''
|
85
|
+
test_files: []
|