review-retrovert 0.9.11 → 0.11.3
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 +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +1 -1
- data/Rakefile +15 -0
- data/lib/review/retrovert/cli.rb +6 -0
- data/lib/review/retrovert/converter.rb +38 -0
- data/lib/review/retrovert/version.rb +1 -1
- data/lib/review/retrovert/yamlconfig.rb +38 -1
- metadata +49 -146
- data/.dockerignore +0 -9
- data/.editorconfig +0 -16
- data/.gitattributes +0 -5
- data/.github/FUNDING.yml +0 -4
- data/.github/workflows/docker-build.yml +0 -26
- data/.github/workflows/release.yml +0 -26
- data/.github/workflows/retrovert.yml +0 -91
- data/.gitignore +0 -15
- data/.rspec +0 -3
- data/.ruby-version +0 -1
- data/.vscode/launch.json +0 -48
- data/Dockerfile +0 -5
- data/Gemfile +0 -8
- data/Gemfile.lock +0 -118
- data/Makefile +0 -31
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/docker/review.Dockerfile +0 -10
- data/hooks/post_push +0 -8
- data/package-lock.json +0 -6
- data/package.json +0 -1
- data/review-retrovert.code-workspace +0 -8
- data/review-retrovert.gemspec +0 -37
- data/testdata/mybook/.gitignore +0 -13
- data/testdata/mybook/.textlintrc +0 -11
- data/testdata/mybook/README.md +0 -43
- data/testdata/mybook/Rakefile +0 -24
- data/testdata/mybook/catalog.yml +0 -60
- data/testdata/mybook/config-noretrovert.yml +0 -404
- data/testdata/mybook/config-retrovert.yml +0 -16
- data/testdata/mybook/config-starter.yml +0 -264
- data/testdata/mybook/config.yml +0 -404
- data/testdata/mybook/contents/00-preface.re +0 -129
- data/testdata/mybook/contents/01-install.re +0 -305
- data/testdata/mybook/contents/02-tutorial.re +0 -1228
- data/testdata/mybook/contents/03-syntax.re +0 -4610
- data/testdata/mybook/contents/04-customize.re +0 -1064
- data/testdata/mybook/contents/05-faq.re +0 -606
- data/testdata/mybook/contents/06-bestpractice.re +0 -1343
- data/testdata/mybook/contents/91-compare.re +0 -418
- data/testdata/mybook/contents/92-filelist.re +0 -125
- data/testdata/mybook/contents/93-background.re +0 -267
- data/testdata/mybook/contents/99-postface.re +0 -39
- data/testdata/mybook/contents/r0-inner.re +0 -2
- data/testdata/mybook/contents/r0-root.re +0 -49
- data/testdata/mybook/contents/table.csv +0 -4
- data/testdata/mybook/contents/test.txt +0 -1
- data/testdata/mybook/contents/ut.re +0 -5
- data/testdata/mybook/css/normalize.css +0 -349
- data/testdata/mybook/css/webstyle.css +0 -692
- data/testdata/mybook/data/terms.txt +0 -3
- data/testdata/mybook/data/words.txt +0 -15
- data/testdata/mybook/images/03-syntax/favicon-16x16.png +0 -0
- data/testdata/mybook/images/03-syntax/figure_heretop.png +0 -0
- data/testdata/mybook/images/03-syntax/index-page.png +0 -0
- data/testdata/mybook/images/03-syntax/order-detail.png +0 -0
- data/testdata/mybook/images/03-syntax/tw-icon1.jpg +0 -0
- data/testdata/mybook/images/03-syntax/tw-icon2.jpg +0 -0
- data/testdata/mybook/images/03-syntax/tw-icon3.jpg +0 -0
- data/testdata/mybook/images/03-syntax/tw-icon4.jpg +0 -0
- data/testdata/mybook/images/04-customize/caption_pagebreak.png +0 -0
- data/testdata/mybook/images/04-customize/chaptitlepage_sample.png +0 -0
- data/testdata/mybook/images/04-customize/section_decoration_samples.png +0 -0
- data/testdata/mybook/images/05-faq/codeblock_rpadding1.png +0 -0
- data/testdata/mybook/images/05-faq/codeblock_rpadding2.png +0 -0
- data/testdata/mybook/images/05-faq/dummy-image.png +0 -0
- data/testdata/mybook/images/06-bestpractice/figure_heretop.png +0 -0
- data/testdata/mybook/images/06-bestpractice/font_beramono.png +0 -0
- data/testdata/mybook/images/06-bestpractice/heading_design1.png +0 -0
- data/testdata/mybook/images/06-bestpractice/heading_design2.png +0 -0
- data/testdata/mybook/images/06-bestpractice/margin_book.png +0 -0
- data/testdata/mybook/images/06-bestpractice/multiline-title.png +0 -0
- data/testdata/mybook/images/06-bestpractice/preface_numbered.png +0 -0
- data/testdata/mybook/images/06-bestpractice/program_border.png +0 -0
- data/testdata/mybook/images/06-bestpractice/sechead_design_4.png +0 -0
- data/testdata/mybook/images/06-bestpractice/section_title_wlines.png +0 -0
- data/testdata/mybook/images/06-bestpractice/titlepage-samples.png +0 -0
- data/testdata/mybook/images/93-background/bug913.png +0 -0
- data/testdata/mybook/images/93-background/slide2.png +0 -0
- data/testdata/mybook/images/avatar-b.png +0 -0
- data/testdata/mybook/images/avatar-g.png +0 -0
- data/testdata/mybook/images/avatar-r.png +0 -0
- data/testdata/mybook/images/caution-icon.png +0 -0
- data/testdata/mybook/images/cover_a5.pdf +0 -0
- data/testdata/mybook/images/cover_b5.pdf +0 -0
- data/testdata/mybook/images/info-icon.png +0 -0
- data/testdata/mybook/images/tw-icon.jpg +0 -0
- data/testdata/mybook/images/warning-icon.png +0 -0
- data/testdata/mybook/layouts/layout.epub.erb +0 -29
- data/testdata/mybook/layouts/layout.html5.erb +0 -108
- data/testdata/mybook/layouts/layout.tex.erb +0 -432
- data/testdata/mybook/layouts/layout.tex.erb.orig +0 -386
- data/testdata/mybook/lib/hooks/beforetexcompile.rb +0 -55
- data/testdata/mybook/lib/ruby/review-book.rb +0 -64
- data/testdata/mybook/lib/ruby/review-builder.rb +0 -1342
- data/testdata/mybook/lib/ruby/review-cli.rb +0 -58
- data/testdata/mybook/lib/ruby/review-compiler.rb +0 -1176
- data/testdata/mybook/lib/ruby/review-epubbuilder.rb +0 -33
- data/testdata/mybook/lib/ruby/review-epubmaker.rb +0 -609
- data/testdata/mybook/lib/ruby/review-htmlbuilder.rb +0 -949
- data/testdata/mybook/lib/ruby/review-latexbuilder.rb +0 -1065
- data/testdata/mybook/lib/ruby/review-maker.rb +0 -346
- data/testdata/mybook/lib/ruby/review-markdownbuilder.rb +0 -945
- data/testdata/mybook/lib/ruby/review-markdownmaker.rb +0 -91
- data/testdata/mybook/lib/ruby/review-monkeypatch.rb +0 -93
- data/testdata/mybook/lib/ruby/review-pdfmaker.rb +0 -546
- data/testdata/mybook/lib/ruby/review-textbuilder.rb +0 -36
- data/testdata/mybook/lib/ruby/review-tocparser.rb +0 -285
- data/testdata/mybook/lib/ruby/review-webmaker.rb +0 -448
- data/testdata/mybook/lib/tasks/mytasks.rake +0 -31
- data/testdata/mybook/lib/tasks/review.rake +0 -156
- data/testdata/mybook/lib/tasks/review.rake.orig +0 -72
- data/testdata/mybook/lib/tasks/starter.rake +0 -470
- data/testdata/mybook/locale.yml +0 -6
- data/testdata/mybook/review-ext.rb +0 -206
- data/testdata/mybook/sty/indexstyle.ist +0 -25
- data/testdata/mybook/sty/jumoline.sty +0 -310
- data/testdata/mybook/sty/mycolophon.sty +0 -81
- data/testdata/mybook/sty/mystyle.sty +0 -8
- data/testdata/mybook/sty/mytextsize.sty +0 -94
- data/testdata/mybook/sty/mytitlepage.sty +0 -126
- data/testdata/mybook/sty/review-base.sty +0 -276
- data/testdata/mybook/sty/reviewmacro.sty +0 -60
- data/testdata/mybook/sty/starter-codeblock.sty +0 -463
- data/testdata/mybook/sty/starter-color.sty +0 -134
- data/testdata/mybook/sty/starter-font.sty +0 -112
- data/testdata/mybook/sty/starter-heading.sty +0 -561
- data/testdata/mybook/sty/starter-misc.sty +0 -894
- data/testdata/mybook/sty/starter-note.sty +0 -180
- data/testdata/mybook/sty/starter-section.sty +0 -262
- data/testdata/mybook/sty/starter-talklist.sty +0 -105
- data/testdata/mybook/sty/starter-toc.sty +0 -72
- data/testdata/mybook/sty/starter-util.sty +0 -39
- data/testdata/mybook/sty/starter.sty +0 -36
- data/testdata/mybook/sty/ut.sty +0 -26
- data/testdata/mybook/style.css +0 -597
- data/testdata/mybook/ut-catalog.yml +0 -61
- data/testdata/mybook/ut-config-starter.yml +0 -3
- data/testdata/mybook/ut-config.yml +0 -404
|
@@ -1,546 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
## ReVIEW::PDFMakerのソースコードがいろいろひどいので、書き直す。
|
|
5
|
-
## 具体的には、もとのコードではPDFMakerクラスの責務が大きすぎるので、分割する。
|
|
6
|
-
## ・CLIクラス … コマンドラインオプションの解析
|
|
7
|
-
## ・Makerクラス … PDFに限定されない機能(設定ファイルの読み込み等)
|
|
8
|
-
## ・PDFMakerクラス … 原稿ファイルを読み込んでPDFファイルを生成する機能
|
|
9
|
-
## ・LATEXRendererクラス … layout.tex.erbのレンダリング
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
require 'date'
|
|
13
|
-
require 'pathname'
|
|
14
|
-
require 'digest/md5'
|
|
15
|
-
require 'rbconfig'
|
|
16
|
-
require 'review/pdfmaker'
|
|
17
|
-
|
|
18
|
-
require_relative './review-cli'
|
|
19
|
-
require_relative './review-maker'
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
module ReVIEW
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
remove_const :PDFMaker if defined?(PDFMaker)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class PDFMaker < Maker
|
|
29
|
-
|
|
30
|
-
SCRIPT_NAME = "review-pdfmaker"
|
|
31
|
-
|
|
32
|
-
def generate()
|
|
33
|
-
remove_old_file()
|
|
34
|
-
@build_dir = make_build_dir()
|
|
35
|
-
begin
|
|
36
|
-
book = load_book() # also loads 'review-ext.rb'
|
|
37
|
-
#
|
|
38
|
-
converter = ReVIEW::Converter.new(book, new_builder())
|
|
39
|
-
errors = create_input_files(converter, book)
|
|
40
|
-
if errors && !errors.empty?
|
|
41
|
-
#FileUtils.rm_f pdf_filepath() ###
|
|
42
|
-
handle_compile_errors(errors)
|
|
43
|
-
end
|
|
44
|
-
#
|
|
45
|
-
prepare_files()
|
|
46
|
-
build_pdf(book)
|
|
47
|
-
ensure
|
|
48
|
-
FileUtils.remove_entry_secure(@build_dir) unless @config['debug']
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
protected
|
|
53
|
-
|
|
54
|
-
def new_builder()
|
|
55
|
-
return ReVIEW::LATEXBuilder.new
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def pdf_filepath()
|
|
59
|
-
return File.join(@basedir, pdf_filename())
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def pdf_filename()
|
|
63
|
-
return "#{@config['bookname']}.pdf"
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def remove_old_file
|
|
67
|
-
#FileUtils.rm_f(pdf_filepath()) # don't delete pdf file
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def make_build_dir()
|
|
71
|
-
dir = "#{@config['bookname']}-pdf"
|
|
72
|
-
if !File.directory?(dir)
|
|
73
|
-
Dir.mkdir(dir)
|
|
74
|
-
else
|
|
75
|
-
## 目次と相互参照と索引に関するファイルだけを残し、あとは削除
|
|
76
|
-
Pathname.new(dir).children.each do |x|
|
|
77
|
-
next if x.basename.to_s =~ /\.(aux|toc|out|idx|ind|mtc\d*|maf)\z/
|
|
78
|
-
x.rmtree()
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
return dir
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def create_input_files(converter, book)
|
|
85
|
-
errors = []
|
|
86
|
-
book.each_input_file do |part, chap|
|
|
87
|
-
if part
|
|
88
|
-
err = output_chaps(converter, part.name) if part.file?
|
|
89
|
-
elsif chap
|
|
90
|
-
filename = File.basename(chap.path, '.*')
|
|
91
|
-
err = output_chaps(converter, filename)
|
|
92
|
-
end
|
|
93
|
-
errors << err if err
|
|
94
|
-
end
|
|
95
|
-
return errors
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def output_chaps(converter, filename)
|
|
99
|
-
contdir = @config['contentdir']
|
|
100
|
-
infile = "#{filename}.re"
|
|
101
|
-
infile = File.join(contdir, infile) if contdir.present?
|
|
102
|
-
outfile = "#{filename}.tex"
|
|
103
|
-
$stderr.puts "compiling #{outfile}"
|
|
104
|
-
begin
|
|
105
|
-
converter.convert(infile, File.join(@build_dir, outfile))
|
|
106
|
-
nil
|
|
107
|
-
## 文法エラーだけキャッチし、それ以外のエラーはキャッチしないよう変更
|
|
108
|
-
## (LATEXBuilderで起こったエラーのスタックトレースを表示する)
|
|
109
|
-
rescue ApplicationError => ex
|
|
110
|
-
warn "compile error in #{outfile} (#{ex.class})"
|
|
111
|
-
warn colored_errmsg(ex.message)
|
|
112
|
-
ex.message
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def handle_compile_errors(errors)
|
|
117
|
-
return if errors.nil? || errors.empty?
|
|
118
|
-
if @config['ignore-errors']
|
|
119
|
-
$stderr.puts 'compile error, but try to generate PDF file'
|
|
120
|
-
else
|
|
121
|
-
error 'compile error, No PDF file output.'
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def build_pdf(book)
|
|
126
|
-
base = "book"
|
|
127
|
-
#
|
|
128
|
-
texfile = File.join(@build_dir, "#{base}.tex")
|
|
129
|
-
new_renderer(book).generate_file(texfile)
|
|
130
|
-
#
|
|
131
|
-
Dir.chdir(@build_dir) do
|
|
132
|
-
if ENV['REVIEW_SAFE_MODE'].to_i & 4 > 0
|
|
133
|
-
warn 'command configuration is prohibited in safe mode. ignored.'
|
|
134
|
-
config = ReVIEW::Configure
|
|
135
|
-
else
|
|
136
|
-
config = @config
|
|
137
|
-
end
|
|
138
|
-
compile_latex_files(base, config)
|
|
139
|
-
end
|
|
140
|
-
#
|
|
141
|
-
return File.join(@build_dir, "#{base}.pdf")
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def absolute_path(filename)
|
|
145
|
-
return nil unless filename.present?
|
|
146
|
-
#filepath = File.absolute_path(filename, @basedir)
|
|
147
|
-
filepath = File.absolute_path(filename, '..')
|
|
148
|
-
return File.exist?(filepath) ? filepath : nil
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def compile_latex_files(base, config)
|
|
152
|
-
latex_cmd = config['texcommand']
|
|
153
|
-
latex_opt = config['texoptions']
|
|
154
|
-
dvipdf_cmd = config['dvicommand']
|
|
155
|
-
dvipdf_opt = config['dvioptions']
|
|
156
|
-
mkidx_p = config['pdfmaker']['makeindex']
|
|
157
|
-
mkidx_cmd = config['pdfmaker']['makeindex_command']
|
|
158
|
-
mkidx_opt = config['pdfmaker']['makeindex_options']
|
|
159
|
-
mkidx_sty = absolute_path(config['pdfmaker']['makeindex_sty'])
|
|
160
|
-
mkidx_dic = absolute_path(config['pdfmaker']['makeindex_dic'])
|
|
161
|
-
#
|
|
162
|
-
latex = "#{latex_cmd} #{latex_opt}"
|
|
163
|
-
dvipdf = "#{dvipdf_cmd} #{dvipdf_opt}"
|
|
164
|
-
mkidx = "#{mkidx_cmd} #{mkidx_opt}"
|
|
165
|
-
mkidx << " -s #{mkidx_sty}" if mkidx_sty
|
|
166
|
-
mkidx << " -d #{mkidx_dic}" if mkidx_dic
|
|
167
|
-
#
|
|
168
|
-
texfile = "#{base}.tex"
|
|
169
|
-
idxfile = "#{base}.idx"
|
|
170
|
-
dvifile = "#{base}.dvi"
|
|
171
|
-
pdffile = pdf_filename()
|
|
172
|
-
#
|
|
173
|
-
call_hook('hook_beforetexcompile')
|
|
174
|
-
#
|
|
175
|
-
print_latex_version(latex_cmd)
|
|
176
|
-
if (v = ENV['STARTER_COMPILETIMES']).present?
|
|
177
|
-
compile_ntimes = v.to_i
|
|
178
|
-
elsif ENV['STARTER_CHAPTER'].present?
|
|
179
|
-
compile_ntimes = 1
|
|
180
|
-
else
|
|
181
|
-
compile_ntimes = nil
|
|
182
|
-
end
|
|
183
|
-
run_latex(latex, texfile, compile_ntimes)
|
|
184
|
-
#
|
|
185
|
-
if mkidx_p # 索引を作る場合
|
|
186
|
-
changed = _files_changed?('*.ind') do
|
|
187
|
-
call_hook('hook_beforemakeindex')
|
|
188
|
-
usr_bin_time { run_cmd!("#{mkidx} #{base}") } if File.exist?(idxfile)
|
|
189
|
-
call_hook('hook_aftermakeindex')
|
|
190
|
-
end
|
|
191
|
-
if changed
|
|
192
|
-
run_latex(latex, texfile)
|
|
193
|
-
else
|
|
194
|
-
puts "[pdfmaker]### (info): index file not changed. skip latex compilation."
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
call_hook('hook_aftertexcompile')
|
|
198
|
-
return unless File.exist?(dvifile)
|
|
199
|
-
usr_bin_time { run_cmd!("#{dvipdf} -o ../#{pdffile} #{dvifile}") }
|
|
200
|
-
call_hook('hook_afterdvipdf')
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
## コンパイルメッセージを減らすために、uplatexコマンドをバッチモードで起動する。
|
|
204
|
-
## エラーがあったら、バッチモードにせずに再コンパイルしてエラーメッセージを出す。
|
|
205
|
-
def run_latex(latex, file, max_ntimes=nil)
|
|
206
|
-
max_ntimes ||= 3
|
|
207
|
-
ok = true
|
|
208
|
-
cmd = "#{latex} -interaction=batchmode #{file}"
|
|
209
|
-
hash1 = _hash_auxfiles()
|
|
210
|
-
max_ntimes.times do
|
|
211
|
-
## invoke latex command with batchmode option in order to suppress
|
|
212
|
-
## compilation message (in other words, to be quiet mode).
|
|
213
|
-
#ok = run_cmd("#{latex} -interaction=batchmode #{file}")
|
|
214
|
-
_output, ok = usr_bin_time { run_cmd_capturing_output(cmd, " > /dev/null") }
|
|
215
|
-
break unless ok
|
|
216
|
-
hash2 = _hash_auxfiles()
|
|
217
|
-
auxfiles_changed = hash1 != hash2
|
|
218
|
-
break unless auxfiles_changed
|
|
219
|
-
hash1 = hash2
|
|
220
|
-
end
|
|
221
|
-
unless ok
|
|
222
|
-
## latex command with batchmode option doesn't show any error,
|
|
223
|
-
## therefore we must invoke latex command again without batchmode option
|
|
224
|
-
## in order to show error.
|
|
225
|
-
$stderr.puts "*"
|
|
226
|
-
$stderr.puts "* latex command failed; retry without batchmode option to show error."
|
|
227
|
-
$stderr.puts "*"
|
|
228
|
-
run_cmd!("#{latex} #{file}")
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
private
|
|
233
|
-
|
|
234
|
-
def _hash_auxfiles()
|
|
235
|
-
return _hash_files(Dir.glob('*.{aux,toc,idx}'))
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
def _files_changed?(filepat)
|
|
239
|
-
before = _hash_files(Dir.glob(filepat))
|
|
240
|
-
yield
|
|
241
|
-
after = _hash_files(Dir.glob(filepat))
|
|
242
|
-
return before != after
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
def _hash_files(filenames)
|
|
246
|
-
return filenames.each_with_object({}) do |filename, dict|
|
|
247
|
-
s = File.read(filename)
|
|
248
|
-
dict[filename] = Digest::SHA1.hexdigest(s)
|
|
249
|
-
end
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
protected
|
|
253
|
-
|
|
254
|
-
def print_latex_version(latex_cmd)
|
|
255
|
-
output, ok = run_cmd_capturing_output("#{latex_cmd} --version", " | head -1")
|
|
256
|
-
ok or
|
|
257
|
-
raise BuildError.new("latex command seemds not exist.")
|
|
258
|
-
puts output.each_line.first
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
def prepare_files()
|
|
262
|
-
## copy image files
|
|
263
|
-
copy_images(@config['imagedir'], File.join(@build_dir, @config['imagedir']))
|
|
264
|
-
## copy style files
|
|
265
|
-
stydir = File.join(Dir.pwd, 'sty')
|
|
266
|
-
copy_sty(stydir, @build_dir)
|
|
267
|
-
copy_sty(stydir, @build_dir, 'fd')
|
|
268
|
-
copy_sty(stydir, @build_dir, 'cls')
|
|
269
|
-
copy_sty(Dir.pwd, @build_dir, 'tex')
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
def copy_images(from, to)
|
|
273
|
-
return unless File.exist?(from)
|
|
274
|
-
FileUtils.mkdir_p(to)
|
|
275
|
-
ReVIEW::MakerHelper.copy_images_to_dir(from, to)
|
|
276
|
-
## extractbb コマンドは、最近のLaTeX処理系では必要ないだけでなく、
|
|
277
|
-
## XeTeX において図がずれる原因になるので、使わない。
|
|
278
|
-
#|Dir.chdir(to) do
|
|
279
|
-
#| images = Dir.glob('**/*.{jpg,jpeg,png,pdf,ai,eps,tif,tiff}')
|
|
280
|
-
#| images = images.find_all {|f| File.file?(f) }
|
|
281
|
-
#| break if images.empty?
|
|
282
|
-
#| d = @config[@maker_name]
|
|
283
|
-
#| if d['bbox']
|
|
284
|
-
#| system('extractbb', '-B', d['bbox'], *images)
|
|
285
|
-
#| system_or_raise('ebb', '-B', d['bbox'], *images) unless system('extractbb', '-B', d['bbox'], '-m', *images)
|
|
286
|
-
#| else
|
|
287
|
-
#| system('extractbb', *images)
|
|
288
|
-
#| system_or_raise('ebb', *images) unless system('extractbb', '-m', *images)
|
|
289
|
-
#| end
|
|
290
|
-
#|end
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
def copy_sty(dirname, copybase, extname = 'sty')
|
|
294
|
-
unless File.directory?(dirname)
|
|
295
|
-
warn "No such directory - #{dirname}"
|
|
296
|
-
return
|
|
297
|
-
end
|
|
298
|
-
Dir.open(dirname) do |dir|
|
|
299
|
-
dir.each do |fname|
|
|
300
|
-
if File.extname(fname).downcase == '.' + extname
|
|
301
|
-
FileUtils.mkdir_p(copybase)
|
|
302
|
-
FileUtils.cp File.join(dirname, fname), copybase
|
|
303
|
-
end
|
|
304
|
-
end
|
|
305
|
-
end
|
|
306
|
-
end
|
|
307
|
-
|
|
308
|
-
def new_renderer(book)
|
|
309
|
-
return LATEXRenderer.new(@config, book, @basedir, @starter_config)
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
## layout.tex.erb をレンダリングする
|
|
314
|
-
class LATEXRenderer < BaseRenderer
|
|
315
|
-
include ReVIEW::LaTeXUtils
|
|
316
|
-
|
|
317
|
-
## LaTeXUtils#escape() だと、'-' を '{-}' に変換する。
|
|
318
|
-
## そのため、たとえば「x-small」が「x{-}small」になってしまう。
|
|
319
|
-
## これは設定値にとって都合が悪いので、書き直す。
|
|
320
|
-
def escape(v)
|
|
321
|
-
case v
|
|
322
|
-
when nil ; return ''
|
|
323
|
-
#when true ; return 'Y'
|
|
324
|
-
#when false ; return ''
|
|
325
|
-
when Numeric ; return v.to_s
|
|
326
|
-
else
|
|
327
|
-
v.to_s.gsub(/[#$%&{}_^~\\]/, LATEX_ESCAPE_CHARS)
|
|
328
|
-
end
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
LATEX_ESCAPE_CHARS = {
|
|
332
|
-
'%' => '\%',
|
|
333
|
-
'#' => '\#',
|
|
334
|
-
'$' => '\$',
|
|
335
|
-
'&' => '\&',
|
|
336
|
-
'_' => '\_',
|
|
337
|
-
'{' => '\{',
|
|
338
|
-
'}' => '\}',
|
|
339
|
-
'\\' => '{\textbackslash}',
|
|
340
|
-
'^' => '{\textasciicircum}',
|
|
341
|
-
'~' => '{\textasciitilde}',
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
def layout_template_name
|
|
345
|
-
return './latex/layout.tex.erb'
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
def initialize(*args)
|
|
349
|
-
super
|
|
350
|
-
setup()
|
|
351
|
-
end
|
|
352
|
-
|
|
353
|
-
def setup()
|
|
354
|
-
@input_files = make_input_files(@book)
|
|
355
|
-
#
|
|
356
|
-
dclass = @config['texdocumentclass'] || []
|
|
357
|
-
@documentclass = dclass[0] || 'jsbook'
|
|
358
|
-
@documentclassoption = dclass[1] || 'uplatex,oneside'
|
|
359
|
-
|
|
360
|
-
@okuduke = make_colophon()
|
|
361
|
-
@authors = make_authors()
|
|
362
|
-
#
|
|
363
|
-
sep = I18n.t('names_splitter')
|
|
364
|
-
@book_author = @config.names_of('aut').join(sep)
|
|
365
|
-
@book_supervisor = @config.names_of('csl').join(sep)
|
|
366
|
-
@book_translator = @config.names_of('trl').join(sep)
|
|
367
|
-
#
|
|
368
|
-
@custom_titlepage = make_custom_page(@config['cover']) || make_custom_page(@config['coverfile'])
|
|
369
|
-
@custom_originaltitlepage = make_custom_page(@config['originaltitlefile'])
|
|
370
|
-
@custom_creditpage = make_custom_page(@config['creditfile'])
|
|
371
|
-
|
|
372
|
-
@custom_profilepage = make_custom_page(@config['profile'])
|
|
373
|
-
@custom_advfilepage = make_custom_page(@config['advfile'])
|
|
374
|
-
@custom_colophonpage = make_custom_page(@config['colophon']) if @config['colophon'] && @config['colophon'].is_a?(String)
|
|
375
|
-
@custom_backcoverpage = make_custom_page(@config['backcover'])
|
|
376
|
-
|
|
377
|
-
if @config['pubhistory']
|
|
378
|
-
warn 'pubhistory is oboleted. use history.'
|
|
379
|
-
else
|
|
380
|
-
@config['pubhistory'] = make_history_list().join("\n")
|
|
381
|
-
end
|
|
382
|
-
|
|
383
|
-
@coverimageoption =
|
|
384
|
-
if @documentclass == 'ubook' || @documentclass == 'utbook'
|
|
385
|
-
'width=\\textheight,height=\\textwidth,keepaspectratio,angle=90'
|
|
386
|
-
else
|
|
387
|
-
'width=\\textwidth,height=\\textheight,keepaspectratio'
|
|
388
|
-
end
|
|
389
|
-
|
|
390
|
-
part_tuple = I18n.get('part' ).split(/\%[A-Za-z]{1,3}/, 2)
|
|
391
|
-
chapter_tuple = I18n.get('chapter' ).split(/\%[A-Za-z]{1,3}/, 2)
|
|
392
|
-
appendix_tuple = I18n.get('appendix').split(/\%[A-Za-z]{1,3}/, 2)
|
|
393
|
-
@locale_latex = {
|
|
394
|
-
'prepartname' => part_tuple[0],
|
|
395
|
-
'postpartname' => part_tuple[1],
|
|
396
|
-
'prechaptername' => chapter_tuple[0],
|
|
397
|
-
'postchaptername' => chapter_tuple[1],
|
|
398
|
-
'preappendixname' => appendix_tuple[0],
|
|
399
|
-
'postappendixname' => appendix_tuple[1],
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
@texcompiler = File.basename(@config['texcommand'], '.*')
|
|
403
|
-
#
|
|
404
|
-
return self
|
|
405
|
-
end
|
|
406
|
-
|
|
407
|
-
private
|
|
408
|
-
|
|
409
|
-
def chapter_key(chap)
|
|
410
|
-
return 'PREDEF' if chap.on_predef?
|
|
411
|
-
return 'CHAPS' if chap.on_chaps?
|
|
412
|
-
return 'APPENDIX' if chap.on_appendix?
|
|
413
|
-
return 'POSTDEF' if chap.on_postdef?
|
|
414
|
-
return nil
|
|
415
|
-
end
|
|
416
|
-
|
|
417
|
-
def make_input_files(book)
|
|
418
|
-
input_files = {'PREDEF'=>"", 'CHAPS'=>"", 'APPENDIX'=>"", 'POSTDEF'=>""}
|
|
419
|
-
book.each_input_file do |part, chap|
|
|
420
|
-
if part
|
|
421
|
-
key = 'CHAPS'
|
|
422
|
-
latex_code = (part.file? ? "\\input{#{part.name}.tex}\n"
|
|
423
|
-
: "\\part{#{part.name}}\n")
|
|
424
|
-
elsif chap
|
|
425
|
-
key = chapter_key(chap) # 'PREDEF', 'CHAPS', 'APPENDEX', or 'POSTDEF'
|
|
426
|
-
latex_code = "\\input{#{File.basename(chap.path, '.*')}.tex}\n"
|
|
427
|
-
end
|
|
428
|
-
input_files[key] << latex_code if key
|
|
429
|
-
end
|
|
430
|
-
return input_files
|
|
431
|
-
end
|
|
432
|
-
|
|
433
|
-
def make_custom_page(file)
|
|
434
|
-
file_sty = file.to_s.sub(/\.[^.]+\Z/, '.tex')
|
|
435
|
-
return File.read(file_sty) if File.exist?(file_sty)
|
|
436
|
-
nil
|
|
437
|
-
end
|
|
438
|
-
|
|
439
|
-
def join_with_separator(value, sep)
|
|
440
|
-
return [value].flatten.join(sep)
|
|
441
|
-
end
|
|
442
|
-
|
|
443
|
-
def make_colophon_role(role)
|
|
444
|
-
return nil unless @config[role].present?
|
|
445
|
-
initialize_metachars(@config['texcommand'])
|
|
446
|
-
names = @config.names_of(role)
|
|
447
|
-
sep = i18n('names_splitter')
|
|
448
|
-
str = [names].flatten.join(sep)
|
|
449
|
-
return i18n(role), escape(str)
|
|
450
|
-
end
|
|
451
|
-
|
|
452
|
-
def make_colophon()
|
|
453
|
-
kv_list = []
|
|
454
|
-
@config['colophon_order'].each do |role|
|
|
455
|
-
if role == 'prt' # 印刷所の前に追加情報を入れる
|
|
456
|
-
_each_additional_kvs() {|k, v| kv_list << [k, v] }
|
|
457
|
-
end
|
|
458
|
-
kv = make_colophon_role(role)
|
|
459
|
-
kv_list << kv if kv
|
|
460
|
-
end
|
|
461
|
-
#
|
|
462
|
-
return kv_list.map {|k, v|
|
|
463
|
-
#"#{i18n(role)} & #{escape_latex(str)} \\\\\n"
|
|
464
|
-
"\\startercolophonrow{#{k}}{#{v}}\n"
|
|
465
|
-
}.join()
|
|
466
|
-
end
|
|
467
|
-
|
|
468
|
-
def _each_additional_kvs(&b)
|
|
469
|
-
dicts = @config['additional']
|
|
470
|
-
dicts.each do |d|
|
|
471
|
-
key = d['key']; val = d['value']
|
|
472
|
-
next unless key.present? && val.present?
|
|
473
|
-
k = escape(key.to_s)
|
|
474
|
-
[val].flatten.compact.each do |v|
|
|
475
|
-
case v
|
|
476
|
-
when /\A\@[-\w]+\z/
|
|
477
|
-
url = "https://twitter.com/#{escape(v[1..-1])}"
|
|
478
|
-
s = "{#{escape(v)}} (\\starterurl{#{url}}{#{url}})"
|
|
479
|
-
#s = "\textsf{#{escape(v)}} (\\starterurl{#{url}}{#{url}})"
|
|
480
|
-
#s = "\\starterurl{#{url}}{#{url}}"
|
|
481
|
-
yield k, s
|
|
482
|
-
when /\Ahttps?:\/\//
|
|
483
|
-
url = escape(v)
|
|
484
|
-
s = "\\starterurl{#{url}}{#{url}}"
|
|
485
|
-
yield k, s
|
|
486
|
-
else
|
|
487
|
-
yield k, escape(v.to_s)
|
|
488
|
-
end
|
|
489
|
-
k = nil
|
|
490
|
-
end
|
|
491
|
-
end if dicts
|
|
492
|
-
end
|
|
493
|
-
|
|
494
|
-
def make_authors
|
|
495
|
-
sep = i18n('names_splitter')
|
|
496
|
-
pr = proc do |key, labelkey, linebreak|
|
|
497
|
-
@config[key].present? ? \
|
|
498
|
-
linebreak + i18n(labelkey, names_of(key, sep)) : ""
|
|
499
|
-
end
|
|
500
|
-
authors = ''
|
|
501
|
-
authors << pr.call('aut', 'author_with_label', '')
|
|
502
|
-
authors << pr.call('csl', 'supervisor_with_label', " \\\\\n")
|
|
503
|
-
authors << pr.call('trl', 'translator_with_label', " \\\\\n")
|
|
504
|
-
return authors
|
|
505
|
-
end
|
|
506
|
-
|
|
507
|
-
def names_of(key, sep)
|
|
508
|
-
return @config.names_of(key).map {|s| escape_latex(s) }.join(sep)
|
|
509
|
-
end
|
|
510
|
-
|
|
511
|
-
def make_history_list
|
|
512
|
-
buf = []
|
|
513
|
-
if @config['history']
|
|
514
|
-
@config['history'].each_with_index do |items, edit|
|
|
515
|
-
items.each_with_index do |item, rev|
|
|
516
|
-
editstr = edit == 0 ? i18n('first_edition') : i18n('nth_edition', (edit + 1).to_s)
|
|
517
|
-
revstr = i18n('nth_impression', (rev + 1).to_s)
|
|
518
|
-
if item =~ /\A\d+\-\d+\-\d+\Z/
|
|
519
|
-
buf << i18n('published_by1', [date_to_s(item), editstr + revstr])
|
|
520
|
-
elsif item =~ /\A(\d+\-\d+\-\d+)[\s ](.+)/
|
|
521
|
-
# custom date with string
|
|
522
|
-
item.match(/\A(\d+\-\d+\-\d+)[\s ](.+)/) { |m| buf << i18n('published_by3', [date_to_s(m[1]), m[2]]) }
|
|
523
|
-
else
|
|
524
|
-
# free format
|
|
525
|
-
buf << item
|
|
526
|
-
end
|
|
527
|
-
end
|
|
528
|
-
end
|
|
529
|
-
elsif @config['date']
|
|
530
|
-
buf << i18n('published_by2', date_to_s(@config['date']))
|
|
531
|
-
end
|
|
532
|
-
buf
|
|
533
|
-
end
|
|
534
|
-
|
|
535
|
-
def date_to_s(date)
|
|
536
|
-
d = Date.parse(date)
|
|
537
|
-
d.strftime(i18n('date_format'))
|
|
538
|
-
end
|
|
539
|
-
|
|
540
|
-
end
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
end
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
end
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
|
|
3
|
-
###
|
|
4
|
-
### ReVIEW::TEXTBuilderクラスを拡張する
|
|
5
|
-
###
|
|
6
|
-
|
|
7
|
-
require 'review/textbuilder'
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
module ReVIEW
|
|
11
|
-
|
|
12
|
-
defined?(TEXTBuilder) or raise "internal error: TEXTBuilder not found."
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class TEXTBuilder
|
|
16
|
-
|
|
17
|
-
## ファイル名
|
|
18
|
-
def inline_file(str)
|
|
19
|
-
on_inline_file { escape(str) }
|
|
20
|
-
end
|
|
21
|
-
def on_inline_file
|
|
22
|
-
yield
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
## ユーザ入力
|
|
26
|
-
def inline_userinput(str)
|
|
27
|
-
on_inline_input { escape(str) }
|
|
28
|
-
end
|
|
29
|
-
def on_inline_userinput
|
|
30
|
-
yield
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
end
|