xpub 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,370 @@
1
+ module Xpub
2
+ class CallBook
3
+ class CallBuilder
4
+ attr_reader :name, :theme, :output
5
+
6
+ def initialize name, book
7
+ @name = name
8
+ @book = book
9
+ @theme = "default"
10
+ end
11
+
12
+ def output output
13
+ @output = output
14
+ end
15
+
16
+ def theme theme
17
+ @theme = theme
18
+ end
19
+
20
+ def build
21
+ raise "This method is not implement."
22
+ end
23
+
24
+ def validate
25
+ if @book.src_files.count == 0
26
+ raise "src_file is empty."
27
+ end
28
+ end
29
+
30
+ def src_path file
31
+ "#{Dir::getwd}/src/#{file}"
32
+ end
33
+
34
+ def tmp_path file
35
+ "#{Dir::getwd}/tmp/#{file}"
36
+ end
37
+
38
+ def output_path file
39
+ "#{Dir::getwd}/output/#{file}"
40
+ end
41
+
42
+ def copy_to_tmp files
43
+ files.each { |file|
44
+ pn = Pathname.new tmp_path(file.file)
45
+ FileUtils.mkdir_p(pn.dirname) unless FileTest.exist?(pn.dirname)
46
+
47
+ unless FileTest.exist?(tmp_path(file.file)) && File::mtime(src_path(file.file)) <= File::mtime(tmp_path(file.file))
48
+ puts "copy #{file.file} to tmp/".color :white
49
+ FileUtils.copy_entry(src_path(file.file), tmp_path(file.file))
50
+ end
51
+ }
52
+ end
53
+
54
+ def cmd_exec cmd, args, option
55
+
56
+ cmd_line = cmd + " " + args.map { |arg|
57
+ Shellwords.shellescape(arg)
58
+ }.join(" ")
59
+ puts cmd_line.color :cyan
60
+ stdout, stderr, status = Open3.capture3 cmd_line
61
+ if option[:v] || status != 0
62
+ puts stdout.color :green
63
+ end
64
+ if status != 0
65
+ puts stderr.color :red
66
+ puts "error!".color :red
67
+ exit
68
+ end
69
+ end
70
+ end
71
+
72
+ class CallEpubBuilder < CallBuilder
73
+ def initialize name, book
74
+ @vars = []
75
+ @meta = []
76
+ @template = "template.html"
77
+ @filter = "pandoc-filter.rb"
78
+ @stylesheet = "epub.css"
79
+ @metadata = "metadata.dat"
80
+ @page_progression_direction = "rtl"
81
+ @cover_image = nil
82
+
83
+ if book.title != ""
84
+ @vars << ["title", book.title]
85
+ end
86
+ super name, book
87
+ end
88
+
89
+ def page_progression_direction param
90
+ @page_progression_direction = param
91
+ end
92
+
93
+ def template param
94
+ @template = param
95
+ end
96
+
97
+ def filter param
98
+ @filter = param
99
+ end
100
+
101
+ def stylesheet param
102
+ @stylesheet = param
103
+ end
104
+
105
+ def metadata param
106
+ @metadata = param
107
+ end
108
+
109
+ def cover_image param
110
+ @cover_image = param
111
+ end
112
+
113
+ def meta_option
114
+ result = []
115
+ @meta.concat([["page-progression-direction", @page_progression_direction]]).each { |m|
116
+ result << "-M"
117
+ result << "#{m[0]}=#{m[1]}"
118
+ }
119
+ result
120
+ end
121
+
122
+ def vars_option
123
+ result = []
124
+ @vars.concat([[:book_name, @book.name]]).each { |v|
125
+ result << "-V"
126
+ result << "#{v[0]}=#{v[1]}"
127
+ }
128
+ result
129
+ end
130
+
131
+ def template_option
132
+ "--template=#{Dir::getwd}/theme/#{@theme}/#{@name}/#{@template}"
133
+ end
134
+
135
+ def filter_option
136
+ "--filter=#{Dir::getwd}/theme/#{@theme}/#{@name}/#{@filter}"
137
+ end
138
+
139
+ def stylesheet_option
140
+ "--epub-stylesheet=#{Dir::getwd}/theme/#{@theme}/#{@name}/#{@stylesheet}"
141
+ end
142
+
143
+ def metadata_option
144
+ "--epub-metadata=" + metadata_path
145
+ end
146
+
147
+ def metadata_path
148
+ tmp_path("#{@book.name}.#{@metadata}")
149
+ end
150
+
151
+ def metadata_template_path
152
+ "#{Dir::getwd}/theme/#{@theme}/#{@name}/#{@metadata}.erb"
153
+ end
154
+
155
+ def epub_path
156
+ output_path(@book.name) + '.epub'
157
+ end
158
+
159
+ def json_path
160
+ tmp_path(@book.name) + '.json'
161
+ end
162
+
163
+ def _build_resource files, option
164
+ copy_to_tmp files
165
+ end
166
+
167
+ def pandoc_cmd
168
+ "pandoc"
169
+ end
170
+
171
+ def pandoc_option option
172
+ option = [
173
+ "--epub-chapter-level=1",
174
+ "--toc",
175
+ "-f",
176
+ "markdown_phpextra+hard_line_breaks+raw_html",
177
+ "-s",
178
+ template_option,
179
+ filter_option,
180
+ stylesheet_option,
181
+ metadata_option
182
+ ]
183
+ if @cover_image
184
+ option << "--epub-cover-image=" + src_path(@cover_image)
185
+ end
186
+ option
187
+ end
188
+
189
+ def build_epub_metadata option
190
+ f = open metadata_template_path
191
+ erb = ERB.new f.read, nil, "-"
192
+ f.close
193
+ f = open metadata_path, "w"
194
+ f.write erb.result(binding)
195
+ f.close
196
+ end
197
+
198
+ def build option
199
+ build_epub_metadata option
200
+
201
+ if option['pandoc-json-output']
202
+ cmd_exec "cd #{tmp_path ""};"+ pandoc_cmd, ["-o", json_path, "-t", "json"].concat(pandoc_option option).concat(vars_option).concat(meta_option).concat(@book.src_files.map{ |f| f.full_path }), option
203
+ end
204
+ cmd_exec "cd #{tmp_path ""};"+ pandoc_cmd, ["-o", epub_path, "-t", "epub3"].concat(pandoc_option option).concat(vars_option).concat(meta_option).concat(@book.src_files.map{ |f| f.full_path }), option
205
+ end
206
+ end
207
+
208
+ class CallLatexBuilder < CallBuilder
209
+ attr_reader :template
210
+
211
+ def initialize name, book
212
+ @vars = []
213
+ @template = "template.tex"
214
+ @filter = "pandoc-filter.rb"
215
+ @hyoushi = []
216
+ @urahyoushi = []
217
+ super name, book
218
+ end
219
+
220
+ def documentclass param
221
+ @vars << [:documentclass, param]
222
+ end
223
+
224
+ def classoption param
225
+ @vars << [:classoption, param]
226
+ end
227
+
228
+ def prepartname param
229
+ @vars << [:prepartname, param]
230
+ end
231
+
232
+ def postpartname param
233
+ @vars << [:postpartname, param]
234
+ end
235
+
236
+ def prechaptername param
237
+ @vars << [:prechaptername, param]
238
+ end
239
+
240
+ def postchaptername param
241
+ @vars << [:postchaptername, param]
242
+ end
243
+
244
+ def template param
245
+ @template = param
246
+ end
247
+
248
+ def filter param
249
+ @filter = param
250
+ end
251
+
252
+ def vars_option
253
+ result = []
254
+ @vars.concat([[:book_name, @book.name]]).each { |v|
255
+ result << "-V"
256
+ result << "#{v[0]}=#{v[1]}"
257
+ }
258
+ result
259
+ end
260
+
261
+ def template_option
262
+ "--template=#{Dir::getwd}/theme/#{@theme}/#{@name}/#{@template}"
263
+ end
264
+
265
+ def filter_option
266
+ "--filter=#{Dir::getwd}/theme/#{@theme}/#{@name}/#{@filter}"
267
+ end
268
+
269
+ def tex_path
270
+ tmp_path(@book.name) + '.tex'
271
+ end
272
+
273
+ def json_path
274
+ tmp_path(@book.name) + '.json'
275
+ end
276
+
277
+ def dvi_path
278
+ tmp_path(@book.name) + '.dvi'
279
+ end
280
+
281
+ def pdf_path
282
+ if @output
283
+ output_path(@output) + '.pdf'
284
+ else
285
+ output_path(@book.name) + '.pdf'
286
+ end
287
+ end
288
+
289
+ def extractbb_cmd
290
+ "extractbb"
291
+ end
292
+
293
+ def _build_resource files, option
294
+ copy_to_tmp files
295
+ files.each { |file|
296
+ xbb = File.dirname(tmp_path(file.file)) + "/" + File.basename(tmp_path(file.file), ".*") + ".xbb"
297
+ unless FileTest.exist?(xbb) && File::mtime(tmp_path(file.file)) <= File::mtime(xbb)
298
+ cmd_exec extractbb_cmd, [tmp_path(file.file)], option
299
+ end
300
+ }
301
+ end
302
+
303
+ def build_resource option
304
+ _build_resource @book.resource_files, option
305
+ end
306
+
307
+ def pandoc_cmd
308
+ "pandoc"
309
+ end
310
+
311
+ def pandoc_option option
312
+ [
313
+ "--chapters",
314
+ "-f",
315
+ "markdown_phpextra+hard_line_breaks+raw_tex",
316
+ "-s",
317
+ template_option,
318
+ filter_option
319
+ ]
320
+ end
321
+
322
+ def latex_cmd
323
+ "uplatex"
324
+ end
325
+
326
+ def dvipdfm_cmd
327
+ "dvipdfmx"
328
+ end
329
+
330
+ def build option
331
+ if option['pandoc-json-output']
332
+ cmd_exec pandoc_cmd, ["-o", json_path, "-t", "json"].concat(pandoc_option option).concat(vars_option).concat(@book.src_files.map{ |f| f.full_path }), option
333
+ end
334
+ cmd_exec pandoc_cmd, ["-o", tex_path, "-t", "latex"].concat(pandoc_option option).concat(vars_option).concat(@book.src_files.map{ |f| f.full_path }), option
335
+
336
+ build_resource option
337
+
338
+ f = open(tmp_path(@book.name + ".before_body.tex"), "w") do |io|
339
+ io.puts @hyoushi.map { |h| h.latex @book, self} .join()
340
+ end
341
+
342
+ f = open(tmp_path(@book.name + ".after_body.tex"), "w") do |io|
343
+ io.puts @urahyoushi.map { |h| h.latex @book, self }.join()
344
+ end
345
+ cmd_exec latex_cmd, ["-output-directory=#{tmp_path ""}", tex_path], option
346
+ cmd_exec latex_cmd, ["-output-directory=#{tmp_path ""}", tex_path], option
347
+ unless FileTest.exist?(pdf_path) && (File::mtime(dvi_path) <= File::mtime(pdf_path))
348
+ cmd_exec "cd #{Shellwords.shellescape(tmp_path "")};#{dvipdfm_cmd}", ["-o", pdf_path, dvi_path], option
349
+ end
350
+ end
351
+ end
352
+ def epub_builder name, &block
353
+ call = CallEpubBuilder.new name, self
354
+ if block
355
+ call.instance_eval &block
356
+ end
357
+ call.validate
358
+ @builders << call
359
+ end
360
+
361
+ def latex_builder name, &block
362
+ call = CallLatexBuilder.new name, self
363
+ if block
364
+ call.instance_eval &block
365
+ end
366
+ call.validate
367
+ @builders << call
368
+ end
369
+ end
370
+ end
@@ -0,0 +1,159 @@
1
+ module Xpub
2
+ class CallBook
3
+ class CallLatexBuilder
4
+ class CallLatexOp
5
+ def initialize name, book, builder
6
+ @name = name
7
+ @book = book
8
+ @builder = builder
9
+ end
10
+ def validate
11
+ end
12
+
13
+ def template_path
14
+ "#{Dir::getwd}/theme/#{@builder.theme}/#{@name}/#{@metadata}.erb"
15
+ end
16
+
17
+ def latex book, builder
18
+ f = open template_path
19
+ erb = ERB.new f.read, nil, "-"
20
+ f.close
21
+ erb.result(binding)
22
+ end
23
+
24
+ end
25
+
26
+ class CallImgPageLatexOp < CallLatexOp
27
+ def initialize name, book, builder
28
+ @topoffset = "0in"
29
+ @leftoffset = "0in"
30
+ super name, book, builder
31
+ end
32
+
33
+ def topoffset param
34
+ @topoffset = param
35
+ end
36
+
37
+ def leftoffset param
38
+ @leftoffset = param
39
+ end
40
+
41
+ def file param
42
+ @file = param
43
+ end
44
+
45
+ def latex book, builder
46
+ <<"EOS"
47
+ \\enlargethispage{200truemm}%
48
+ \\thispagestyle{empty}%
49
+ \\vspace*{-1truein}
50
+ \\vspace*{-\\hoffset}
51
+ \\vspace*{-\\oddsidemargin}
52
+ \\vspace*{#{@leftoffset}}
53
+ \\noindent\\hspace*{-1in}\\hspace*{-\\voffset}\\hspace*{-\\topmargin}\\hspace*{-\\headheight}\\hspace*{-\\headsep}\\hspace*{#{@topoffset}}
54
+ \\includegraphics[width=\\paperheight,height=\\paperwidth]{#{@file}}
55
+ \\clearpage\n
56
+ EOS
57
+ end
58
+ end
59
+
60
+ class CallEmptyPageLatexOp < CallLatexOp
61
+ def initialize name, book, builder
62
+ @no_page_number = false
63
+ super name, book, builder
64
+ end
65
+
66
+ def no_page_number
67
+ @no_page_number = true
68
+ end
69
+
70
+ def latex book, builder
71
+ (@no_page_number ? "\\thispagestyle{empty}" : "") + " \\clearpage\n"
72
+ end
73
+ end
74
+
75
+ class CallInnerTitlePageLatexOp < CallLatexOp
76
+ def initialize name, book, builder
77
+ super name, book, builder
78
+ end
79
+
80
+ def latex book, builder
81
+ <<"EOS"
82
+ \\makeatletter
83
+ {
84
+ \\thispagestyle{empty}%
85
+ \\if@twocolumn\\@restonecoltrue\\onecolumn
86
+ \\else\\@restonecolfalse\\newpage\\fi
87
+ \\begin{minipage}<y>[c]{\\textheight}
88
+ \\begin{center}
89
+ \\vspace*{2.5cm}
90
+ {\\bf \\Huge #{book.title}}
91
+ \\end{center}
92
+ \\vspace*{0.5cm}
93
+ \\begin{center}
94
+ {\\bf \\Large #{book.subtitle}}
95
+ \\end{center}
96
+ \\vspace*{1.5cm}
97
+ \\begin{center}
98
+ {\\Large #{book.creators.map { |c| c.name }.join " "}}
99
+ \\end{center}
100
+ \\vspace*{1.5cm}
101
+ \\begin{flushleft}
102
+ #{book.description}
103
+ \\end{flushleft}
104
+ \\end{minipage}
105
+ \\if@restonecol\\twocolumn\\else\\newpage\\fi
106
+ }%
107
+ \\makeatother
108
+ EOS
109
+ end
110
+ end
111
+
112
+ def hyoushi_image_page name, &block
113
+ call = CallImgPageLatexOp.new name, @book, self
114
+ if block
115
+ call.instance_eval &block
116
+ end
117
+ call.validate
118
+ @hyoushi << call
119
+ end
120
+
121
+ def hyoushi_empty_page name, &block
122
+ call = CallEmptyPageLatexOp.new name, @book, self
123
+ if block
124
+ call.instance_eval &block
125
+ end
126
+ call.validate
127
+ @hyoushi << call
128
+ end
129
+
130
+ def hyoushi_inner_title_page name, &block
131
+ call = CallInnerTitlePageLatexOp.new name, @book, self
132
+ if block
133
+ call.instance_eval &block
134
+ end
135
+ call.validate
136
+ @hyoushi << call
137
+ end
138
+
139
+ def urahyoushi_image_page name, &block
140
+ call = CallImgPageLatexOp.new name, @book, self
141
+ if block
142
+ call.instance_eval &block
143
+ end
144
+ call.validate
145
+ @urahyoushi << call
146
+ end
147
+
148
+ def urahyoushi_empty_page name, &block
149
+ call = CallEmptyPageLatexOp.new name, @book, self
150
+ if block
151
+ call.instance_eval &block
152
+ end
153
+ call.validate
154
+ @urahyoushi << call
155
+ end
156
+
157
+ end
158
+ end
159
+ end