prophecy 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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/Overview.md +44 -0
- data/README.md +35 -0
- data/Rakefile +1 -0
- data/bin/kindlegen +18 -0
- data/bin/kindlegen.exe +0 -0
- data/bin/kindlegen_linux +0 -0
- data/bin/kindlegen_mac +0 -0
- data/bin/prophecy +4 -0
- data/docs/licenses/kindlegen/.empty_directory +0 -0
- data/docs/licenses/kindlegen/EULA.txt +61 -0
- data/docs/licenses/kindlegen/KindleGen Legal Notices 2009-11-10 Linux.txt +21 -0
- data/docs/licenses/kindlegen/KindleGen Legal Notices 2009-11-10 Mac.txt +21 -0
- data/docs/licenses/kindlegen/KindleGen OSS Notices 2009-07-29-Windows.txt +19 -0
- data/features/assets.feature +14 -0
- data/features/book.feature +10 -0
- data/features/generator.feature +15 -0
- data/features/support/hooks.rb +5 -0
- data/features/support/setup.rb +3 -0
- data/lib/prophecy/assets/.gitignore +2 -0
- data/lib/prophecy/assets/config.rb +20 -0
- data/lib/prophecy/assets/epub_template/META-INF/com.apple.ibooks.display-options.xml +6 -0
- data/lib/prophecy/assets/epub_template/META-INF/container.xml +6 -0
- data/lib/prophecy/assets/epub_template/OEBPS/.gitkeep +0 -0
- data/lib/prophecy/assets/epub_template/OEBPS/chapters/.gitkeep +0 -0
- data/lib/prophecy/assets/epub_template/OEBPS/content.opf.erb +114 -0
- data/lib/prophecy/assets/epub_template/OEBPS/toc.ncx.erb +18 -0
- data/lib/prophecy/assets/epub_template/mimetype +1 -0
- data/lib/prophecy/assets/fonts/Crimson-Bold.otf +0 -0
- data/lib/prophecy/assets/fonts/Crimson-BoldItalic.otf +0 -0
- data/lib/prophecy/assets/fonts/Crimson-Italic.otf +0 -0
- data/lib/prophecy/assets/fonts/Crimson-Roman.otf +0 -0
- data/lib/prophecy/assets/fonts/Crimson-Semibold.otf +0 -0
- data/lib/prophecy/assets/fonts/Crimson-SemiboldItalic.otf +0 -0
- data/lib/prophecy/assets/fonts/GenBasB.ttf +0 -0
- data/lib/prophecy/assets/fonts/GenBasBI.ttf +0 -0
- data/lib/prophecy/assets/fonts/GenBasI.ttf +0 -0
- data/lib/prophecy/assets/fonts/GenBasR.ttf +0 -0
- data/lib/prophecy/assets/fonts/GenBkBasB.ttf +0 -0
- data/lib/prophecy/assets/fonts/GenBkBasBI.ttf +0 -0
- data/lib/prophecy/assets/fonts/GenBkBasI.ttf +0 -0
- data/lib/prophecy/assets/fonts/GenBkBasR.ttf +0 -0
- data/lib/prophecy/assets/fonts/GentiumPlus-I.ttf +0 -0
- data/lib/prophecy/assets/fonts/GentiumPlus-R.ttf +0 -0
- data/lib/prophecy/assets/helpers/check_typos.sh +27 -0
- data/lib/prophecy/assets/helpers/helpers.rb +0 -0
- data/lib/prophecy/assets/helpers/pali_typos +2 -0
- data/lib/prophecy/assets/helpers/sed_chars +5 -0
- data/lib/prophecy/assets/helpers/sed_dumb_ebook +18 -0
- data/lib/prophecy/assets/helpers/sed_tex2uni +62 -0
- data/lib/prophecy/assets/helpers/tex2html.sh +112 -0
- data/lib/prophecy/assets/helpers/tex2md.sh +10 -0
- data/lib/prophecy/assets/helpers/tidy_quotes +1 -0
- data/lib/prophecy/assets/helpers/tidy_quotes.sh +8 -0
- data/lib/prophecy/assets/helpers/to-html.sh +9 -0
- data/lib/prophecy/assets/latex_template/Makefile +37 -0
- data/lib/prophecy/assets/latex_template/anecdote.cls +163 -0
- data/lib/prophecy/assets/latex_template/book-core-first.sty +673 -0
- data/lib/prophecy/assets/latex_template/book-core-last.sty +40 -0
- data/lib/prophecy/assets/latex_template/book_main.tex.erb +31 -0
- data/lib/prophecy/assets/latex_template/booklet_main.tex +15 -0
- data/lib/prophecy/assets/latex_template/chapters/.gitkeep +0 -0
- data/lib/prophecy/assets/latex_template/cover_main.tex +48 -0
- data/lib/prophecy/assets/latex_template/mylayout.sty +2 -0
- data/lib/prophecy/assets/layouts/page.xhtml.erb +20 -0
- data/lib/prophecy/assets/sass/_booktheme.sass +3 -0
- data/lib/prophecy/assets/sass/_byronic.sass +263 -0
- data/lib/prophecy/assets/sass/_colors.sass +7 -0
- data/lib/prophecy/assets/sass/_epub-css-starter-kit.sass +734 -0
- data/lib/prophecy/assets/sass/_font-existence.scss +12 -0
- data/lib/prophecy/assets/sass/_font-source-sans-pro.scss +75 -0
- data/lib/prophecy/assets/sass/_fontfaces.scss +11 -0
- data/lib/prophecy/assets/sass/_mixins.sass +4 -0
- data/lib/prophecy/assets/sass/print.sass +6 -0
- data/lib/prophecy/assets/sass/style-epub.sass +7 -0
- data/lib/prophecy/assets/sass/style-mobi-kf8.sass +7 -0
- data/lib/prophecy/assets/sass/style-mobi.sass +9 -0
- data/lib/prophecy/assets/stylesheets/print.css +3 -0
- data/lib/prophecy/assets/stylesheets/style-epub.css +401 -0
- data/lib/prophecy/assets/stylesheets/style-mobi-kf8.css +401 -0
- data/lib/prophecy/assets/stylesheets/style-mobi.css +317 -0
- data/lib/prophecy/assets/webfonts/existence-light.ttf +0 -0
- data/lib/prophecy/assets/webfonts/sourcesanspro-bold.ttf +0 -0
- data/lib/prophecy/assets/webfonts/sourcesanspro-extralight.ttf +0 -0
- data/lib/prophecy/assets/webfonts/sourcesanspro-italic.ttf +0 -0
- data/lib/prophecy/assets/webfonts/sourcesanspro-light.ttf +0 -0
- data/lib/prophecy/assets/webfonts/sourcesanspro-lightitalic.ttf +0 -0
- data/lib/prophecy/assets/webfonts/sourcesanspro-regular.ttf +0 -0
- data/lib/prophecy/assets/webfonts-extra/sourcesanspro-bolditalic.ttf +0 -0
- data/lib/prophecy/assets/webfonts-extra/sourcesanspro-extralightitalic.ttf +0 -0
- data/lib/prophecy/assets/webfonts-extra/sourcesanspro-semibold.ttf +0 -0
- data/lib/prophecy/assets/webfonts-extra/sourcesanspro-semibolditalic.ttf +0 -0
- data/lib/prophecy/book.rb +281 -0
- data/lib/prophecy/chapter.rb +359 -0
- data/lib/prophecy/cli.rb +144 -0
- data/lib/prophecy/generators/assets.rb +29 -0
- data/lib/prophecy/generators/book/.gitignore +7 -0
- data/lib/prophecy/generators/book/LICENSE.txt +5 -0
- data/lib/prophecy/generators/book/README.md.tt +4 -0
- data/lib/prophecy/generators/book/book.yml.tt +55 -0
- data/lib/prophecy/generators/book/build/epub/.empty_directory +0 -0
- data/lib/prophecy/generators/book/build/latex/.empty_directory +0 -0
- data/lib/prophecy/generators/book/build/mobi/.empty_directory +0 -0
- data/lib/prophecy/generators/book/epub_mobi.yml +26 -0
- data/lib/prophecy/generators/book/example-book.yml +78 -0
- data/lib/prophecy/generators/book/images/cover.jpg +0 -0
- data/lib/prophecy/generators/book/images/cover.xcf +0 -0
- data/lib/prophecy/generators/book/images/publisher-logo.jpg +0 -0
- data/lib/prophecy/generators/book/manuscript/glossary.md +7 -0
- data/lib/prophecy/generators/book/manuscript/nameless-labyrinth.markdown +34 -0
- data/lib/prophecy/generators/book/manuscript/preface.md +5 -0
- data/lib/prophecy/generators/book/manuscript/the-sway-of-reason.markdown +22 -0
- data/lib/prophecy/generators/book/manuscript/unhuman-massiveness.markdown +27 -0
- data/lib/prophecy/generators/book/manuscript/xhtml/.gitkeep +0 -0
- data/lib/prophecy/generators/book/manuscript/xhtml/cover.xhtml.erb +21 -0
- data/lib/prophecy/generators/book/manuscript/xhtml/titlepage.xhtml.erb +31 -0
- data/lib/prophecy/generators/book/manuscript/xhtml/toc.xhtml.erb +16 -0
- data/lib/prophecy/generators/new.rb +22 -0
- data/lib/prophecy/manifest.rb +72 -0
- data/lib/prophecy/version.rb +3 -0
- data/lib/prophecy.rb +18 -0
- data/prophecy.gemspec +36 -0
- data/spec/book_spec.rb +9 -0
- data/spec/chapter_spec.rb +0 -0
- data/spec/manifest_spec.rb +0 -0
- metadata +366 -0
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,281 @@
|
|
1
|
+
|
2
|
+
module Prophecy
|
3
|
+
|
4
|
+
class Book
|
5
|
+
|
6
|
+
attr_reader :config, :chapters, :manifest
|
7
|
+
|
8
|
+
attr_reader :title, :subtitle, :author, :publisher, :publisher_atag,
|
9
|
+
:publisher_logo, :book_atag, :isbn, :uuid, :version, :edition,
|
10
|
+
:lang, :lang_iso_639_2, :build_dir, :template_dir, :layouts_dir,
|
11
|
+
:assets_dir, :tex_dir, :markdown_dir, :xhtml_dir, :chapter_layout,
|
12
|
+
:include_assets, :exclude_assets, :toc, :output_format, :bookid,
|
13
|
+
:rights, :creator, :subject, :source, :contributors, :cover_image,
|
14
|
+
:date, :compile_name
|
15
|
+
|
16
|
+
def initialize(config)
|
17
|
+
@config = config.clone
|
18
|
+
|
19
|
+
c = config
|
20
|
+
|
21
|
+
@output_format = c['output_format'] || nil
|
22
|
+
@title = c['title'] || "The Title"
|
23
|
+
@subtitle = c['subtitle'] || nil
|
24
|
+
@author = c['author'] || "The Author"
|
25
|
+
@creator = c['creator'] || @author
|
26
|
+
@publisher = c['publisher'] || nil
|
27
|
+
@publisher_atag = c['publisher_atag'] || nil
|
28
|
+
@publisher_logo = c['publisher_logo'] || nil
|
29
|
+
@book_atag = c['book_atag'] || nil
|
30
|
+
@isbn = c['isbn'] || nil
|
31
|
+
@uuid = c['uuid'] || nil
|
32
|
+
@version = c['version'] || 'v0.1'
|
33
|
+
@edition = c['edition'] || nil
|
34
|
+
@lang = c['lang'] || 'en-GB'
|
35
|
+
@lang_iso_639_2 = c['lang_iso_639_2'] || @lang.downcase.sub(/-.*$/, '')
|
36
|
+
@tex_dir = c['tex_dir'] || find_format_dir('tex')
|
37
|
+
@markdown_dir = c['markdown_dir'] || find_format_dir('markdown')
|
38
|
+
@xhtml_dir = c['xhtml_dir'] || find_format_dir('xhtml')
|
39
|
+
@build_dir = c['build_dir'] || File.join('./build', @output_format)
|
40
|
+
@assets_dir = c['assets_dir'] || find_assets_dir
|
41
|
+
@template_dir = c['template_dir'] || find_template_dir
|
42
|
+
@layouts_dir = c['layouts_dir'] || File.join(@assets_dir, 'layouts')
|
43
|
+
@chapter_layout = c['chapter_layout'] || 'page.xhtml.erb'
|
44
|
+
@include_assets = format_include_assets(c['include_assets'])
|
45
|
+
@exclude_assets = format_exclude_assets(c['exclude_assets'])
|
46
|
+
@toc = c['toc'] || nil
|
47
|
+
@bookid = c['bookid'] || nil
|
48
|
+
@rights = c['rights'] || nil
|
49
|
+
@subject = c['subject'] || nil
|
50
|
+
@source = c['source'] || nil
|
51
|
+
@contributors = c['contributors'] || nil
|
52
|
+
@cover_image = c['cover_image'] || nil
|
53
|
+
@date = c['date'] || Time.now.strftime("%Y-%m-%d")
|
54
|
+
|
55
|
+
@compile_name = "#{self.author}-#{self.title}-#{Time.now.strftime("%FT%T")}".gsub(/[^a-zA-Z0-9-]/, '-').gsub(/--*/, '-')
|
56
|
+
|
57
|
+
@manifest = nil
|
58
|
+
@chapters = []
|
59
|
+
Chapter.section_name = config['section_names'] if config['section_names']
|
60
|
+
if @toc
|
61
|
+
@toc.each do |ch|
|
62
|
+
if ch.is_a?(String)
|
63
|
+
ch = { 'src' => ch }
|
64
|
+
end
|
65
|
+
|
66
|
+
if ch.has_key?('target')
|
67
|
+
if ch['target'].include?(@output_format) || ch['target'] == @output_format
|
68
|
+
@chapters << Chapter.new(self, ch)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
c = Chapter.new(self, ch)
|
72
|
+
@chapters << c unless c.render_path.nil?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
@navpoints = @chapters.flat_map{|c| c.navpoints}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def generate_build
|
80
|
+
case self.output_format
|
81
|
+
when 'epub'
|
82
|
+
self.build_epub_mobi
|
83
|
+
when 'mobi'
|
84
|
+
self.build_epub_mobi
|
85
|
+
when 'latex'
|
86
|
+
self.build_latex
|
87
|
+
else
|
88
|
+
warn "Don't know how to build output format: " + self.output_format
|
89
|
+
raise "Unknown Output Format Error"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def build_latex
|
94
|
+
FileUtils.cp_r(File.join(@template_dir, '.'), @build_dir)
|
95
|
+
FileUtils.cp_r(@include_assets, @build_dir)
|
96
|
+
|
97
|
+
# For ERB binding.
|
98
|
+
book = self
|
99
|
+
|
100
|
+
Dir.glob(File.join(@build_dir, '**/*'), File::FNM_DOTMATCH).each do |f|
|
101
|
+
if File.extname(f) == '.erb'
|
102
|
+
template = ERB.new(IO.read(f))
|
103
|
+
text = template.result(binding)
|
104
|
+
File.open(f.sub(/\.erb$/, ''), "w"){|file| file << text }
|
105
|
+
FileUtils.rm(f)
|
106
|
+
end
|
107
|
+
|
108
|
+
@exclude_assets.each do |ex|
|
109
|
+
if File.fnmatch(ex, f) || File.fnmatch(ex, File.basename(f))
|
110
|
+
FileUtils.rm(f)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
@chapters.each do |ch|
|
116
|
+
next if ch.src.nil?
|
117
|
+
unless File.extname(ch.src) == '.tex'
|
118
|
+
File.open(ch.render_path, "w"){|f| f << ch.to_tex }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def build_epub_mobi
|
124
|
+
FileUtils.cp_r(File.join(@template_dir, '.'), @build_dir)
|
125
|
+
FileUtils.cp_r(@include_assets, File.join(@build_dir, 'OEBPS'))
|
126
|
+
|
127
|
+
content_opf_path = nil
|
128
|
+
|
129
|
+
# For ERB binding.
|
130
|
+
book = self
|
131
|
+
|
132
|
+
Dir.glob(File.join(@build_dir, '**/*'), File::FNM_DOTMATCH).each do |f|
|
133
|
+
if File.extname(f) == '.erb'
|
134
|
+
if File.basename(f) == 'content.opf.erb'
|
135
|
+
content_opf_path = File.expand_path(f)
|
136
|
+
next
|
137
|
+
end
|
138
|
+
template = ERB.new(IO.read(f))
|
139
|
+
text = template.result(binding)
|
140
|
+
File.open(f.sub(/\.erb$/, ''), "w"){|file| file << text }
|
141
|
+
FileUtils.rm(f)
|
142
|
+
end
|
143
|
+
|
144
|
+
@exclude_assets.each do |ex|
|
145
|
+
if File.fnmatch(ex, f) || File.fnmatch(ex, File.basename(f))
|
146
|
+
FileUtils.rm(f)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
@chapters.each do |ch|
|
152
|
+
File.open(ch.render_path, "w"){|f| f << ch.to_html }
|
153
|
+
end
|
154
|
+
|
155
|
+
@manifest = Manifest.new(self)
|
156
|
+
|
157
|
+
# Rendering content.opf.erb at the end.
|
158
|
+
unless content_opf_path.nil?
|
159
|
+
template = ERB.new(IO.read(content_opf_path))
|
160
|
+
text = template.result(binding)
|
161
|
+
File.open(content_opf_path.sub(/\.erb$/, ''), "w"){|file| file << text }
|
162
|
+
FileUtils.rm(content_opf_path)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def format_dir(src)
|
167
|
+
case File.extname(src)
|
168
|
+
when '.md', '.mkd', '.markdown'
|
169
|
+
self.markdown_dir
|
170
|
+
when '.tex'
|
171
|
+
self.tex_dir
|
172
|
+
when '.xhtml'
|
173
|
+
self.xhtml_dir
|
174
|
+
when '.html'
|
175
|
+
self.xhtml_dir
|
176
|
+
when '.erb'
|
177
|
+
self.format_dir(src.sub(/\.erb$/, ''))
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def render_navpoints
|
182
|
+
ret = ""
|
183
|
+
@navpoints.each_with_index do |nav, idx|
|
184
|
+
ret += "<navPoint id='nav#{nav['playOrder']}' playOrder='#{nav['playOrder']}'>\n"
|
185
|
+
ret += "<navLabel><text>#{nav['text']}</text></navLabel>\n"
|
186
|
+
ret += "<content src='#{nav['src']}'/>"
|
187
|
+
|
188
|
+
next_nav = @navpoints[idx+1]
|
189
|
+
if !next_nav.nil? && next_nav['level'] < nav['level']
|
190
|
+
d = nav['level'] - next_nav['level'] + 1
|
191
|
+
d.times{ ret += "</navPoint>\n" }
|
192
|
+
elsif next_nav.nil? || next_nav['level'] == nav['level']
|
193
|
+
ret += "</navPoint>\n"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
ret
|
197
|
+
end
|
198
|
+
|
199
|
+
def personal_name_first(lastname_comma_name)
|
200
|
+
n = lastname_comma_name.split(/, */)
|
201
|
+
"#{n[1]} #{n[0]}"
|
202
|
+
end
|
203
|
+
|
204
|
+
def epub?
|
205
|
+
self.output_format == 'epub'
|
206
|
+
end
|
207
|
+
|
208
|
+
def mobi?
|
209
|
+
self.output_format == 'mobi'
|
210
|
+
end
|
211
|
+
|
212
|
+
def latex?
|
213
|
+
self.output_format == 'latex'
|
214
|
+
end
|
215
|
+
|
216
|
+
private
|
217
|
+
|
218
|
+
def find_format_dir(format)
|
219
|
+
if Dir.exists?("./manuscript/#{format}/")
|
220
|
+
"./manuscript/#{format}/"
|
221
|
+
else
|
222
|
+
'./manuscript/'
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def find_assets_dir
|
227
|
+
if Dir.exists?('./assets/')
|
228
|
+
File.join('.', 'assets')
|
229
|
+
else
|
230
|
+
File.join(File.expand_path(File.dirname(__FILE__)), 'assets')
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def format_include_assets(config_include)
|
235
|
+
case (self.output_format)
|
236
|
+
when 'epub', 'mobi'
|
237
|
+
inc = [
|
238
|
+
File.join(self.assets_dir, 'webfonts'),
|
239
|
+
File.join('.', 'images'),
|
240
|
+
File.join(self.assets_dir, 'stylesheets')
|
241
|
+
]
|
242
|
+
when 'latex'
|
243
|
+
inc = []
|
244
|
+
end
|
245
|
+
|
246
|
+
if config_include.nil?
|
247
|
+
inc
|
248
|
+
else
|
249
|
+
inc.concat(config_include).uniq
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def format_exclude_assets(config_exclude)
|
254
|
+
case (self.output_format)
|
255
|
+
when 'epub'
|
256
|
+
ex = [ 'ie.css', 'print.css', 'style-mobi.css', '*.swp', '.gitkeep' ]
|
257
|
+
when 'mobi'
|
258
|
+
ex = [ 'ie.css', 'print.css', 'style-epub.css', '*.swp', '.gitkeep' ]
|
259
|
+
when 'latex'
|
260
|
+
ex = []
|
261
|
+
end
|
262
|
+
|
263
|
+
if config_exclude.nil?
|
264
|
+
ex
|
265
|
+
else
|
266
|
+
ex.concat(config_exclude).uniq
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def find_template_dir
|
271
|
+
case (self.output_format)
|
272
|
+
when 'epub', 'mobi'
|
273
|
+
File.join(self.assets_dir, 'epub_template')
|
274
|
+
when 'latex'
|
275
|
+
File.join(self.assets_dir, 'latex_template')
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
@@ -0,0 +1,359 @@
|
|
1
|
+
|
2
|
+
module Prophecy
|
3
|
+
|
4
|
+
class Chapter
|
5
|
+
|
6
|
+
attr_accessor :title, :id, :idref, :lang, :class, :book, :level,
|
7
|
+
:layout, :src, :path, :render_name, :render_path, :href, :type,
|
8
|
+
:linear, :prefix, :postfix, :insert, :section_name,
|
9
|
+
:section_number, :navpoints
|
10
|
+
|
11
|
+
# Array index corresponds to level, levels index from 0 too. In the
|
12
|
+
# .yml you give the level: N attrib as if they were indexed from 1,
|
13
|
+
# makes more sense there, but we compensate for it in the class.
|
14
|
+
|
15
|
+
@@section_name = [ "Chapter", ]
|
16
|
+
@@section_number = [ 0, ]
|
17
|
+
@@toc_from_headers = false
|
18
|
+
@@playOrder = 1
|
19
|
+
|
20
|
+
@@the_matter = 'frontmatter'
|
21
|
+
|
22
|
+
def initialize(book, config)
|
23
|
+
@book = book
|
24
|
+
|
25
|
+
if @book.output_format == 'mobi'
|
26
|
+
unless config['level'].nil?
|
27
|
+
lvl = config['level'].to_i - 1
|
28
|
+
if lvl > 1
|
29
|
+
@level = 1
|
30
|
+
else
|
31
|
+
@level = lvl
|
32
|
+
end
|
33
|
+
else
|
34
|
+
@level = 0
|
35
|
+
end
|
36
|
+
else
|
37
|
+
if config['level'].nil?
|
38
|
+
@level = 0
|
39
|
+
else
|
40
|
+
@level = config['level'].to_i - 1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
if config['the_matter']
|
45
|
+
@the_matter = config['the_matter']
|
46
|
+
@@the_matter = config['the_matter']
|
47
|
+
else
|
48
|
+
@the_matter = @@the_matter
|
49
|
+
end
|
50
|
+
|
51
|
+
@linear = config['linear'] || nil
|
52
|
+
|
53
|
+
@src = nil
|
54
|
+
if config.is_a?(String)
|
55
|
+
@src = config
|
56
|
+
elsif config.is_a?(Hash) && config.has_key?('src')
|
57
|
+
@src = config['src']
|
58
|
+
end
|
59
|
+
|
60
|
+
ext_for_output = {
|
61
|
+
'epub' => '.xhtml',
|
62
|
+
'mobi' => '.xhtml',
|
63
|
+
'latex' => '.tex',
|
64
|
+
'web' => '.html'
|
65
|
+
}
|
66
|
+
|
67
|
+
chapters_dir_for_output = {
|
68
|
+
'epub' => File.join('OEBPS', 'chapters'),
|
69
|
+
'mobi' => File.join('OEBPS', 'chapters'),
|
70
|
+
'latex' => 'chapters',
|
71
|
+
'web' => 'chapters',
|
72
|
+
}
|
73
|
+
|
74
|
+
@path = nil
|
75
|
+
@href = nil
|
76
|
+
|
77
|
+
unless @src.nil?
|
78
|
+
@render_ext = ext_for_output[book.output_format]
|
79
|
+
|
80
|
+
@path = File.expand_path(File.join(
|
81
|
+
book.format_dir(@src), @src))
|
82
|
+
@render_name = File.basename(@path).sub(/\.erb$/, '').sub(/\.[^\.]+$/, @render_ext)
|
83
|
+
@render_path = File.expand_path(
|
84
|
+
File.join(
|
85
|
+
self.book.build_dir,
|
86
|
+
chapters_dir_for_output[book.output_format],
|
87
|
+
@render_name
|
88
|
+
)
|
89
|
+
)
|
90
|
+
|
91
|
+
a = Pathname.new(self.render_path)
|
92
|
+
b = Pathname.new(File.expand_path(
|
93
|
+
File.join(
|
94
|
+
self.book.build_dir,
|
95
|
+
chapters_dir_for_output[book.output_format],
|
96
|
+
'..'
|
97
|
+
)
|
98
|
+
))
|
99
|
+
@href = a.relative_path_from(b)
|
100
|
+
end
|
101
|
+
|
102
|
+
@type = config['type'] || nil
|
103
|
+
@title = config['title'] || self.first_header_text || ""
|
104
|
+
@class = config['class'] || ""
|
105
|
+
@class += " #{@type}" if @type
|
106
|
+
@id = config['id'] || 'chapter_' + @title.downcase.gsub(/[^a-z0-9-]/, '-').gsub(/--+/, '-')
|
107
|
+
@lang = config['lang'] || book.lang
|
108
|
+
@prefix = config['prefix'] || nil
|
109
|
+
@postfix = config['postfix'] || nil
|
110
|
+
@insert = config['insert'] || nil
|
111
|
+
|
112
|
+
if config['section_name']
|
113
|
+
@@section_name[@level] = config['section_name']
|
114
|
+
else
|
115
|
+
end
|
116
|
+
if config['section_number']
|
117
|
+
@@section_number[@level] = config['section_number'].to_i - 1
|
118
|
+
elsif @@section_number[@level].nil?
|
119
|
+
@@section_number[@level] = 1
|
120
|
+
elsif !@path.nil?
|
121
|
+
@@section_number[@level] += 1
|
122
|
+
end
|
123
|
+
@section_name = @@section_name[@level]
|
124
|
+
@section_number = @@section_number[@level]
|
125
|
+
|
126
|
+
@@toc_from_headers = config['toc_from_headers'] unless config['toc_from_headers'].nil?
|
127
|
+
|
128
|
+
@navpoints = []
|
129
|
+
if @path
|
130
|
+
if @@toc_from_headers
|
131
|
+
doc = Nokogiri::HTML(self.to_html)
|
132
|
+
headers = doc.xpath("//*[name()='h1' or name()='h2' or name()='h3' or name()='h4']")
|
133
|
+
headers.each do |h|
|
134
|
+
# skip links (<a href=""> tag) in header (possibly end- or footnote references)
|
135
|
+
t = ""
|
136
|
+
h.children.select{|i| i.name != 'a'}.each{|s| t += s}
|
137
|
+
@navpoints << {
|
138
|
+
'text' => CGI.escapeHTML(t),
|
139
|
+
'src' => "chapters/#{@render_name}##{h.attributes['id']}",
|
140
|
+
'playOrder' => @@playOrder,
|
141
|
+
'level' => @level,
|
142
|
+
}
|
143
|
+
@@playOrder += 1
|
144
|
+
end
|
145
|
+
else
|
146
|
+
@navpoints << {
|
147
|
+
'text' => @title,
|
148
|
+
'src' => "chapters/#{@render_name}",
|
149
|
+
'playOrder' => @@playOrder,
|
150
|
+
'level' => @level,
|
151
|
+
}
|
152
|
+
@@playOrder += 1
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
if config['layout'].nil?
|
157
|
+
@layout_path = File.join(book.layouts_dir, book.chapter_layout)
|
158
|
+
elsif config['layout'] == 'nil' || config['layout'] == 'none'
|
159
|
+
@layout_path = nil
|
160
|
+
else
|
161
|
+
@layout_path = File.join(book.layouts_dir, config['layout'])
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def idref
|
166
|
+
self.book.manifest.items.select do |i|
|
167
|
+
File.expand_path(i.path) == self.render_path
|
168
|
+
end.first.id
|
169
|
+
end
|
170
|
+
|
171
|
+
def first_header_text
|
172
|
+
if @path
|
173
|
+
doc = Nokogiri::HTML(self.to_html)
|
174
|
+
h = doc.xpath("//*[name()='h1' or name()='h2' or name()='h3' or name()='h4']").first
|
175
|
+
h.text.strip if h
|
176
|
+
else
|
177
|
+
nil
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def to_guide_reference
|
182
|
+
return "" if @type.nil?
|
183
|
+
ret = "<reference href='#{@href}' title=\"#{@title.gsub('"', "'")}\""
|
184
|
+
ret += " type='#{@type}'"
|
185
|
+
ret += " />"
|
186
|
+
end
|
187
|
+
|
188
|
+
def to_html(format = nil, text = nil, layout_path = @layout_path)
|
189
|
+
format ||= File.extname(@path)
|
190
|
+
text ||= IO.read(@path)
|
191
|
+
# for ERB binding
|
192
|
+
book = self.book
|
193
|
+
chapter = self
|
194
|
+
|
195
|
+
ret = nil
|
196
|
+
|
197
|
+
case format
|
198
|
+
when '.html', '.xhtml'
|
199
|
+
ret = text
|
200
|
+
when '.md', '.mkd', '.markdown'
|
201
|
+
ret = Kramdown::Document.new(text).to_html
|
202
|
+
when '.tex'
|
203
|
+
File.open('./temp-chapter.tex', 'w'){|f| f << text }
|
204
|
+
r = system 'pandoc --smart --normalize --from=latex --to=html -o ./temp-chapter.xhtml ./temp-chapter.tex'
|
205
|
+
warn "WARNING: pandoc returned non-zero for #{self.to_s}" unless r
|
206
|
+
ret = IO.read('./temp-chapter.xhtml')
|
207
|
+
FileUtils.rm(['./temp-chapter.tex', './temp-chapter.xhtml'])
|
208
|
+
when '.erb'
|
209
|
+
template = ERB.new(text)
|
210
|
+
fmt = File.extname(@path.sub(/#{format}$/, ''))
|
211
|
+
return self.to_html(format = fmt, text = template.result(binding))
|
212
|
+
else
|
213
|
+
warn "Don't know how to render: #{@src}"
|
214
|
+
raise "Error while rendering chapter"
|
215
|
+
end
|
216
|
+
|
217
|
+
unless layout_path.nil?
|
218
|
+
template = ERB.new(IO.read(layout_path))
|
219
|
+
content = ret
|
220
|
+
template.result(binding)
|
221
|
+
else
|
222
|
+
ret
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def to_tex(format = nil, text = nil, layout_path = @layout_path)
|
227
|
+
format ||= File.extname(@path)
|
228
|
+
text ||= IO.read(@path)
|
229
|
+
# for ERB binding
|
230
|
+
book = self.book
|
231
|
+
chapter = self
|
232
|
+
|
233
|
+
ret = nil
|
234
|
+
|
235
|
+
case format
|
236
|
+
when '.html', '.xhtml'
|
237
|
+
File.open('./temp-chapter.html', 'w'){|f| f << text }
|
238
|
+
system 'pandoc --smart --normalize --chapters --from=html --to=latex -o ./temp-chapter.tex ./temp-chapter.html'
|
239
|
+
ret = IO.read('./temp-chapter.tex')
|
240
|
+
FileUtils.rm(['./temp-chapter.tex', './temp-chapter.html'])
|
241
|
+
when '.md'
|
242
|
+
ret = Kramdown::Document.new(text, options = {:latex_headers => %w{chapter section subsection subsubsection paragraph subparagraph}}).to_latex
|
243
|
+
when '.tex'
|
244
|
+
ret = text
|
245
|
+
when '.erb'
|
246
|
+
template = ERB.new(text)
|
247
|
+
fmt = File.extname(@path.sub(/#{format}$/, ''))
|
248
|
+
ret = self.to_tex(format = fmt, text = template.result(binding))
|
249
|
+
else
|
250
|
+
warn "Don't know how to render: #{@src}"
|
251
|
+
raise "Error while rendering chapter"
|
252
|
+
end
|
253
|
+
|
254
|
+
ret
|
255
|
+
end
|
256
|
+
|
257
|
+
def to_spineitem
|
258
|
+
ret = "<itemref idref='#{self.idref}' "
|
259
|
+
ret += "linear='#{self.linear}'" unless self.linear.nil?
|
260
|
+
ret += " />"
|
261
|
+
end
|
262
|
+
|
263
|
+
def to_chapterlist
|
264
|
+
return "#{@insert}" if @insert
|
265
|
+
ret = ""
|
266
|
+
ret += @prefix + "\n" if @prefix
|
267
|
+
|
268
|
+
if @src
|
269
|
+
ret += "% #{@title}\n" unless @title.empty?
|
270
|
+
if File.extname(@src) == '.tex'
|
271
|
+
ret += "\\input{" + File.join('..', '..', @book.tex_dir, @src) + "}"
|
272
|
+
else
|
273
|
+
ret += "\\input{#{@href}}"
|
274
|
+
end
|
275
|
+
end
|
276
|
+
ret += "\n" + @postfix if @postfix
|
277
|
+
ret
|
278
|
+
end
|
279
|
+
|
280
|
+
def to_toc_li
|
281
|
+
"<li><a href='../chapters/#{@render_name}'><span>#{@title}</span></a></li>"
|
282
|
+
end
|
283
|
+
|
284
|
+
def to_toc_tr
|
285
|
+
ret = ""
|
286
|
+
@navpoints.each do |nav|
|
287
|
+
ret += "<tr>\n"
|
288
|
+
# Section name and number
|
289
|
+
ret += "<td class='section'>\n"
|
290
|
+
if self.mainmatter? && !@section_name.nil? && !@section_name.empty?
|
291
|
+
ret += "#{@section_name} #{@section_number}"
|
292
|
+
end
|
293
|
+
ret += "</td>\n"
|
294
|
+
# Separator
|
295
|
+
ret += "<td class='separator'>"
|
296
|
+
if self.mainmatter? && !@section_name.nil? && !@section_name.empty?
|
297
|
+
ret += " · "
|
298
|
+
end
|
299
|
+
ret += "</td>\n"
|
300
|
+
# Title
|
301
|
+
ret += "<td class='title #{@the_matter}'>\n"
|
302
|
+
ret += "<a href='#{File.join('..', 'chapters', File.basename(nav['src']))}'><span>#{nav['text']}</span></a>\n"
|
303
|
+
ret += "</td>\n"
|
304
|
+
ret += "</tr>"
|
305
|
+
end
|
306
|
+
ret
|
307
|
+
end
|
308
|
+
|
309
|
+
def frontmatter?
|
310
|
+
@the_matter == 'frontmatter'
|
311
|
+
end
|
312
|
+
|
313
|
+
def mainmatter?
|
314
|
+
@the_matter == 'mainmatter'
|
315
|
+
end
|
316
|
+
|
317
|
+
def backmatter?
|
318
|
+
@the_matter == 'backmatter'
|
319
|
+
end
|
320
|
+
|
321
|
+
def self.section_name
|
322
|
+
@@section_name
|
323
|
+
end
|
324
|
+
|
325
|
+
def self.section_name=(a)
|
326
|
+
@@section_name = a
|
327
|
+
end
|
328
|
+
|
329
|
+
def self.section_number
|
330
|
+
@@section_number
|
331
|
+
end
|
332
|
+
|
333
|
+
def self.section_number=(a)
|
334
|
+
@@section_number = a
|
335
|
+
end
|
336
|
+
|
337
|
+
def self.toc_from_headers
|
338
|
+
@@toc_from_headers
|
339
|
+
end
|
340
|
+
|
341
|
+
def self.toc_from_headers=(b)
|
342
|
+
@@toc_from_headers = b
|
343
|
+
end
|
344
|
+
|
345
|
+
def self.the_matter
|
346
|
+
@@the_matter
|
347
|
+
end
|
348
|
+
|
349
|
+
def self.the_matter=(s)
|
350
|
+
@@the_matter = s
|
351
|
+
end
|
352
|
+
|
353
|
+
def to_s
|
354
|
+
[@title, @path].join(", ")
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
end
|
359
|
+
|