review 5.3.0 → 5.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby-tex.yml +1 -1
- data/.github/workflows/ruby.yml +1 -1
- data/.rubocop.yml +1 -322
- data/NEWS.ja.md +48 -0
- data/NEWS.md +48 -0
- data/README.md +9 -8
- data/bin/review +1 -1
- data/bin/review-catalog-converter +15 -15
- data/bin/review-check +7 -7
- data/bin/review-compile +6 -8
- data/bin/review-index +1 -1
- data/bin/review-preproc +1 -1
- data/bin/review-validate +2 -2
- data/doc/config.yml.sample +7 -1
- data/doc/config.yml.sample-simple +1 -1
- data/lib/review/book/base.rb +3 -3
- data/lib/review/book/book_unit.rb +1 -1
- data/lib/review/book/chapter.rb +1 -1
- data/lib/review/book/index.rb +3 -3
- data/lib/review/book/part.rb +12 -13
- data/lib/review/book/volume.rb +1 -1
- data/lib/review/builder.rb +10 -12
- data/lib/review/catalog.rb +5 -5
- data/lib/review/compiler.rb +13 -13
- data/lib/review/configure.rb +5 -2
- data/lib/review/epub2html.rb +12 -12
- data/lib/review/epubmaker/content.rb +1 -1
- data/lib/review/epubmaker/epubcommon.rb +44 -42
- data/lib/review/epubmaker/epubv2.rb +2 -1
- data/lib/review/epubmaker/epubv3.rb +5 -4
- data/lib/review/epubmaker/producer.rb +3 -3
- data/lib/review/epubmaker/reviewheaderlistener.rb +1 -1
- data/lib/review/epubmaker.rb +32 -31
- data/lib/review/extentions/string.rb +1 -1
- data/lib/review/htmlbuilder.rb +16 -15
- data/lib/review/htmlutils.rb +17 -17
- data/lib/review/i18n.rb +3 -3
- data/lib/review/idgxmlbuilder.rb +22 -21
- data/lib/review/idgxmlmaker.rb +15 -13
- data/lib/review/index_builder.rb +4 -20
- data/lib/review/init.rb +4 -4
- data/lib/review/latexbuilder.rb +30 -32
- data/lib/review/lineinput.rb +3 -3
- data/lib/review/location.rb +1 -1
- data/lib/review/logger.rb +21 -21
- data/lib/review/makerhelper.rb +3 -3
- data/lib/review/markdownbuilder.rb +6 -6
- data/lib/review/pdfmaker.rb +23 -19
- data/lib/review/plaintextbuilder.rb +5 -5
- data/lib/review/preprocessor/repository.rb +1 -1
- data/lib/review/preprocessor.rb +5 -5
- data/lib/review/textmaker.rb +20 -18
- data/lib/review/textutils.rb +3 -5
- data/lib/review/topbuilder.rb +71 -12
- data/lib/review/update.rb +16 -8
- data/lib/review/version.rb +1 -1
- data/lib/review/webmaker.rb +32 -32
- data/lib/review/webtocprinter.rb +10 -10
- data/lib/review/yamlloader.rb +35 -2
- data/review.gemspec +1 -0
- data/samples/sample-book/src/config.yml +0 -1
- data/templates/html/_titlepage.html.erb +9 -17
- data/templates/opf/opf_manifest_epubv2.opf.erb +1 -1
- data/templates/opf/opf_manifest_epubv3.opf.erb +1 -1
- data/test/book_test_helper.rb +10 -10
- data/test/test_epub3maker.rb +3 -3
- data/test/test_epubmaker.rb +14 -29
- data/test/test_epubmaker_cmd.rb +2 -2
- data/test/test_htmlbuilder.rb +4 -5
- data/test/test_idgxmlbuilder.rb +10 -10
- data/test/test_idgxmlmaker_cmd.rb +1 -1
- data/test/test_img_math.rb +11 -2
- data/test/test_latexbuilder.rb +2 -3
- data/test/test_pdfmaker_cmd.rb +10 -10
- data/test/test_textmaker_cmd.rb +1 -1
- data/test/test_topbuilder.rb +151 -11
- data/test/test_yamlloader.rb +28 -42
- metadata +8 -7
data/lib/review/idgxmlbuilder.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2008-
|
1
|
+
# Copyright (c) 2008-2022 Minero Aoki, Kenshi Muto
|
2
2
|
# 2002-2007 Minero Aoki
|
3
3
|
#
|
4
4
|
# This program is free software.
|
@@ -86,7 +86,7 @@ module ReVIEW
|
|
86
86
|
s += '</sect3>' if @subsubsection > 0
|
87
87
|
s += '</sect2>' if @subsection > 0
|
88
88
|
s += '</sect>' if @section > 0
|
89
|
-
s += '</chapter>'
|
89
|
+
s += '</chapter>'
|
90
90
|
end
|
91
91
|
solve_nest(@output.string) + s + "</#{@rootelement}>\n"
|
92
92
|
end
|
@@ -457,11 +457,11 @@ module ReVIEW
|
|
457
457
|
caption_str = nil
|
458
458
|
if id
|
459
459
|
puts '<equationblock>'
|
460
|
-
if get_chap.nil?
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
460
|
+
caption_str = if get_chap.nil?
|
461
|
+
%Q(<caption>#{I18n.t('equation')}#{I18n.t('format_number_without_chapter', [@chapter.equation(id).number])}#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}</caption>)
|
462
|
+
else
|
463
|
+
%Q(<caption>#{I18n.t('equation')}#{I18n.t('format_number', [get_chap, @chapter.equation(id).number])}#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}</caption>)
|
464
|
+
end
|
465
465
|
puts caption_str if caption_top?('equation')
|
466
466
|
end
|
467
467
|
|
@@ -480,7 +480,7 @@ module ReVIEW
|
|
480
480
|
def table(lines, id = nil, caption = nil)
|
481
481
|
@tablewidth = nil
|
482
482
|
if @book.config['tableopt']
|
483
|
-
@tablewidth = @book.config['tableopt'].split(',')[0].to_f / @book.config['pt_to_mm_unit'].to_f
|
483
|
+
@tablewidth = @book.config['tableopt'].split(',')[0].to_f / @book.config['pt_to_mm_unit'].to_f # rubocop:disable Style/FloatDivision
|
484
484
|
end
|
485
485
|
@col = 0
|
486
486
|
|
@@ -515,7 +515,7 @@ module ReVIEW
|
|
515
515
|
sepidx = nil
|
516
516
|
rows = []
|
517
517
|
lines.each_with_index do |line, idx|
|
518
|
-
if /\A[=\-]{12}
|
518
|
+
if /\A[=\-]{12}/.match?(line)
|
519
519
|
sepidx ||= idx
|
520
520
|
next
|
521
521
|
end
|
@@ -540,7 +540,7 @@ module ReVIEW
|
|
540
540
|
cellwidth = @tsize.split(/\s*,\s*/)
|
541
541
|
totallength = 0
|
542
542
|
cellwidth.size.times do |n|
|
543
|
-
cellwidth[n] = cellwidth[n].to_f / @book.config['pt_to_mm_unit'].to_f
|
543
|
+
cellwidth[n] = cellwidth[n].to_f / @book.config['pt_to_mm_unit'].to_f # rubocop:disable Style/FloatDivision
|
544
544
|
totallength += cellwidth[n]
|
545
545
|
warn "total length exceeds limit for table: #{@table_id}", location: location if totallength > @tablewidth
|
546
546
|
end
|
@@ -687,8 +687,9 @@ module ReVIEW
|
|
687
687
|
def compile_kw(word, alt)
|
688
688
|
'<keyword>' +
|
689
689
|
if alt
|
690
|
-
|
691
|
-
else
|
690
|
+
escape("#{word}(#{alt.strip})")
|
691
|
+
else
|
692
|
+
escape(word)
|
692
693
|
end +
|
693
694
|
'</keyword>' +
|
694
695
|
%Q(<index value="#{escape(word)}" />) +
|
@@ -724,15 +725,15 @@ module ReVIEW
|
|
724
725
|
end
|
725
726
|
|
726
727
|
def inline_maru(str)
|
727
|
-
if
|
728
|
+
if /\A\d+\Z/.match?(str)
|
728
729
|
sprintf('&#x%x;', 9311 + str.to_i)
|
729
|
-
elsif
|
730
|
+
elsif /\A[A-Z]\Z/.match?(str)
|
730
731
|
begin
|
731
732
|
sprintf('&#x%x;', 9398 + str.codepoints.to_a[0] - 65)
|
732
733
|
rescue NoMethodError
|
733
734
|
sprintf('&#x%x;', 9398 + str[0] - 65)
|
734
735
|
end
|
735
|
-
elsif
|
736
|
+
elsif /\A[a-z]\Z/.match?(str)
|
736
737
|
begin
|
737
738
|
sprintf('&#x%x;', 9392 + str.codepoints.to_a[0] - 65)
|
738
739
|
rescue NoMethodError
|
@@ -800,7 +801,7 @@ module ReVIEW
|
|
800
801
|
def inline_icon(id)
|
801
802
|
begin
|
802
803
|
%Q(<Image href="file://#{@chapter.image(id).path.sub(%r{\A\./}, '')}" type="inline" />)
|
803
|
-
rescue
|
804
|
+
rescue StandardError
|
804
805
|
warn "image not bound: #{id}", location: location
|
805
806
|
''
|
806
807
|
end
|
@@ -1142,16 +1143,16 @@ module ReVIEW
|
|
1142
1143
|
def indepimage(_lines, id, caption = nil, metric = nil)
|
1143
1144
|
metrics = parse_metric('idgxml', metric)
|
1144
1145
|
puts '<img>'
|
1145
|
-
if caption_top?('image')
|
1146
|
-
puts %Q(<caption>#{compile_inline(caption)}</caption>)
|
1146
|
+
if caption_top?('image') && caption.present?
|
1147
|
+
puts %Q(<caption>#{compile_inline(caption)}</caption>)
|
1147
1148
|
end
|
1148
1149
|
begin
|
1149
1150
|
puts %Q(<Image href="file://#{@chapter.image(id).path.sub(%r{\A\./}, '')}"#{metrics} />)
|
1150
|
-
rescue
|
1151
|
+
rescue StandardError
|
1151
1152
|
warn %Q(image not bound: #{id}), location: location
|
1152
1153
|
end
|
1153
|
-
|
1154
|
-
puts %Q(<caption>#{compile_inline(caption)}</caption>)
|
1154
|
+
if !caption_top?('image') && caption.present?
|
1155
|
+
puts %Q(<caption>#{compile_inline(caption)}</caption>)
|
1155
1156
|
end
|
1156
1157
|
puts '</img>'
|
1157
1158
|
end
|
data/lib/review/idgxmlmaker.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2019-
|
1
|
+
# Copyright (c) 2019-2022 Kenshi Muto
|
2
2
|
#
|
3
3
|
# This program is free software.
|
4
4
|
# You can distribute or modify this program under the terms of
|
@@ -74,9 +74,13 @@ module ReVIEW
|
|
74
74
|
cmd_config, yamlfile = parse_opts(args)
|
75
75
|
error! "#{yamlfile} not found." unless File.exist?(yamlfile)
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
|
77
|
+
begin
|
78
|
+
@config = ReVIEW::Configure.create(maker: 'idgxmlmaker',
|
79
|
+
yamlfile: yamlfile,
|
80
|
+
config: cmd_config)
|
81
|
+
rescue ReVIEW::ConfigError => e
|
82
|
+
error! e.message
|
83
|
+
end
|
80
84
|
I18n.setup(@config['language'])
|
81
85
|
begin
|
82
86
|
generate_idgxml_files(yamlfile)
|
@@ -119,7 +123,7 @@ module ReVIEW
|
|
119
123
|
if s.success?
|
120
124
|
File.write(xmlfile, o) # override
|
121
125
|
end
|
122
|
-
rescue => e
|
126
|
+
rescue StandardError => e
|
123
127
|
warn("filter error for #{xmlfile}: #{e.message}")
|
124
128
|
end
|
125
129
|
end
|
@@ -159,13 +163,11 @@ module ReVIEW
|
|
159
163
|
end
|
160
164
|
|
161
165
|
def build_chap(chap, base_path, basetmpdir, ispart)
|
162
|
-
filename =
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
filename = Pathname.new(chap.path).relative_path_from(base_path).to_s
|
168
|
-
end
|
166
|
+
filename = if ispart.present?
|
167
|
+
chap.path
|
168
|
+
else
|
169
|
+
Pathname.new(chap.path).relative_path_from(base_path).to_s
|
170
|
+
end
|
169
171
|
id = File.basename(filename).sub(/\.re\Z/, '')
|
170
172
|
if @buildonly && !@buildonly.include?(id)
|
171
173
|
warn "skip #{id}.re"
|
@@ -177,7 +179,7 @@ module ReVIEW
|
|
177
179
|
begin
|
178
180
|
@converter.convert(filename, File.join(basetmpdir, xmlfile))
|
179
181
|
apply_filter(File.join(basetmpdir, xmlfile))
|
180
|
-
rescue => e
|
182
|
+
rescue StandardError => e
|
181
183
|
@compile_errors = true
|
182
184
|
error "compile error in #{filename} (#{e.class})"
|
183
185
|
error e.message
|
data/lib/review/index_builder.rb
CHANGED
@@ -101,11 +101,7 @@ module ReVIEW
|
|
101
101
|
|
102
102
|
cursor = level - 2
|
103
103
|
|
104
|
-
|
105
|
-
@headline_stack[cursor] = label
|
106
|
-
else
|
107
|
-
@headline_stack[cursor] = caption
|
108
|
-
end
|
104
|
+
@headline_stack[cursor] = (label || caption)
|
109
105
|
if @headline_stack.size > cursor + 1
|
110
106
|
@headline_stack = @headline_stack.take(cursor + 1)
|
111
107
|
end
|
@@ -123,11 +119,7 @@ module ReVIEW
|
|
123
119
|
|
124
120
|
cursor = level - 2
|
125
121
|
|
126
|
-
|
127
|
-
@headline_stack[cursor] = label
|
128
|
-
else
|
129
|
-
@headline_stack[cursor] = caption
|
130
|
-
end
|
122
|
+
@headline_stack[cursor] = (label || caption)
|
131
123
|
if @headline_stack.size > cursor + 1
|
132
124
|
@headline_stack = @headline_stack.take(cursor + 1)
|
133
125
|
end
|
@@ -147,11 +139,7 @@ module ReVIEW
|
|
147
139
|
|
148
140
|
cursor = level - 2
|
149
141
|
|
150
|
-
|
151
|
-
@headline_stack[cursor] = label
|
152
|
-
else
|
153
|
-
@headline_stack[cursor] = caption
|
154
|
-
end
|
142
|
+
@headline_stack[cursor] = (label || caption)
|
155
143
|
if @headline_stack.size > cursor + 1
|
156
144
|
@headline_stack = @headline_stack.take(cursor + 1)
|
157
145
|
end
|
@@ -171,11 +159,7 @@ module ReVIEW
|
|
171
159
|
|
172
160
|
cursor = level - 2
|
173
161
|
|
174
|
-
|
175
|
-
@headline_stack[cursor] = label
|
176
|
-
else
|
177
|
-
@headline_stack[cursor] = caption
|
178
|
-
end
|
162
|
+
@headline_stack[cursor] = (label || caption)
|
179
163
|
if @headline_stack.size > cursor + 1
|
180
164
|
@headline_stack = @headline_stack.take(cursor + 1)
|
181
165
|
end
|
data/lib/review/init.rb
CHANGED
@@ -179,12 +179,12 @@ EOS
|
|
179
179
|
content = content.split("\n").delete_if { |l| l.strip.start_with?('#') || l.strip.empty? }.join("\n")
|
180
180
|
end
|
181
181
|
|
182
|
-
File.
|
182
|
+
File.write(File.join(dir, 'config.yml'), content)
|
183
183
|
if @webui && !@web_result[2].empty?
|
184
184
|
File.open(File.join(dir, 'config-ebook.yml'), 'w') do |f|
|
185
185
|
f.puts <<EOT
|
186
186
|
# for ebook PDF
|
187
|
-
# REVIEW_CONFIG_FILE=config.yml rake pdf
|
187
|
+
# REVIEW_CONFIG_FILE=config-ebook.yml rake pdf
|
188
188
|
inherit: ["config.yml"]
|
189
189
|
# bookname: book-ebook
|
190
190
|
texdocumentclass: ["#{@web_result[0]}", "#{@web_result[2]}"]
|
@@ -257,7 +257,7 @@ EOS
|
|
257
257
|
exit 1
|
258
258
|
end
|
259
259
|
|
260
|
-
if
|
260
|
+
if %r{\Ahttps?://}.match?(filename)
|
261
261
|
begin
|
262
262
|
@logger.info "Downloading from #{filename}"
|
263
263
|
zipdata = Net::HTTP.get(URI.parse(filename))
|
@@ -334,7 +334,7 @@ EOS
|
|
334
334
|
# validation
|
335
335
|
if @web_result
|
336
336
|
@web_result.each do |s|
|
337
|
-
|
337
|
+
unless /\A[a-z0-9=_,.-]*\Z/i.match?(s)
|
338
338
|
@web_result = nil
|
339
339
|
break
|
340
340
|
end
|
data/lib/review/latexbuilder.rb
CHANGED
@@ -157,7 +157,7 @@ module ReVIEW
|
|
157
157
|
puts macro('label', sec_label(anchor))
|
158
158
|
puts macro('label', label) if label
|
159
159
|
end
|
160
|
-
rescue
|
160
|
+
rescue StandardError
|
161
161
|
app_error "unknown level: #{level}"
|
162
162
|
end
|
163
163
|
|
@@ -199,12 +199,11 @@ module ReVIEW
|
|
199
199
|
blank
|
200
200
|
@doc_status[:column] = true
|
201
201
|
|
202
|
-
target =
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
end
|
202
|
+
target = if label
|
203
|
+
"\\hypertarget{#{column_label(label)}}{}"
|
204
|
+
else
|
205
|
+
"\\hypertarget{#{column_label(caption)}}{}"
|
206
|
+
end
|
208
207
|
|
209
208
|
@doc_status[:caption] = true
|
210
209
|
if @book.config.check_version('2', exception: false)
|
@@ -476,11 +475,11 @@ module ReVIEW
|
|
476
475
|
captionstr = macro(command + 'caption', compile_inline(caption))
|
477
476
|
else
|
478
477
|
begin
|
479
|
-
if get_chap.nil?
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
478
|
+
captionstr = if get_chap.nil?
|
479
|
+
macro('reviewlistcaption', "#{I18n.t('list')}#{I18n.t('format_number_header_without_chapter', [@chapter.list(id).number])}#{I18n.t('caption_prefix')}#{compile_inline(caption)}")
|
480
|
+
else
|
481
|
+
macro('reviewlistcaption', "#{I18n.t('list')}#{I18n.t('format_number_header', [get_chap, @chapter.list(id).number])}#{I18n.t('caption_prefix')}#{compile_inline(caption)}")
|
482
|
+
end
|
484
483
|
rescue KeyError
|
485
484
|
app_error "no such list: #{id}"
|
486
485
|
end
|
@@ -578,13 +577,12 @@ module ReVIEW
|
|
578
577
|
end
|
579
578
|
|
580
579
|
def image_image(id, caption = '', metric = nil)
|
581
|
-
captionstr = nil
|
582
580
|
@doc_status[:caption] = true
|
583
|
-
if @book.config.check_version('2', exception: false)
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
581
|
+
captionstr = if @book.config.check_version('2', exception: false)
|
582
|
+
macro('caption', compile_inline(caption)) + "\n"
|
583
|
+
else
|
584
|
+
macro('reviewimagecaption', compile_inline(caption)) + "\n"
|
585
|
+
end
|
588
586
|
captionstr << macro('label', image_label(id))
|
589
587
|
@doc_status[:caption] = nil
|
590
588
|
|
@@ -805,7 +803,7 @@ module ReVIEW
|
|
805
803
|
end
|
806
804
|
|
807
805
|
if @tsize
|
808
|
-
if
|
806
|
+
if /\A[\d., ]+\Z/.match?(@tsize)
|
809
807
|
@cellwidth = @tsize.split(/\s*,\s*/)
|
810
808
|
@cellwidth.collect! { |i| "p{#{i}mm}" }
|
811
809
|
puts macro('begin', 'reviewtable', '|' + @cellwidth.join('|') + '|')
|
@@ -858,7 +856,7 @@ module ReVIEW
|
|
858
856
|
end
|
859
857
|
|
860
858
|
def th(s, cellwidth = 'l')
|
861
|
-
if
|
859
|
+
if /\\\\/.match?(s)
|
862
860
|
if !@book.config.check_version('2', exception: false) && cellwidth =~ /\{/
|
863
861
|
macro('reviewth', s.gsub("\\\\\n", '\\newline{}'))
|
864
862
|
else
|
@@ -871,7 +869,7 @@ module ReVIEW
|
|
871
869
|
end
|
872
870
|
|
873
871
|
def td(s, cellwidth = 'l')
|
874
|
-
if
|
872
|
+
if /\\\\/.match?(s)
|
875
873
|
if !@book.config.check_version('2', exception: false) && cellwidth =~ /\{/
|
876
874
|
s.gsub("\\\\\n", '\\newline{}')
|
877
875
|
else
|
@@ -970,11 +968,11 @@ module ReVIEW
|
|
970
968
|
|
971
969
|
if id
|
972
970
|
puts macro('begin', 'reviewequationblock')
|
973
|
-
if get_chap.nil?
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
971
|
+
captionstr = if get_chap.nil?
|
972
|
+
macro('reviewequationcaption', "#{I18n.t('equation')}#{I18n.t('format_number_header_without_chapter', [@chapter.equation(id).number])}#{I18n.t('caption_prefix')}#{compile_inline(caption)}")
|
973
|
+
else
|
974
|
+
macro('reviewequationcaption', "#{I18n.t('equation')}#{I18n.t('format_number_header', [get_chap, @chapter.equation(id).number])}#{I18n.t('caption_prefix')}#{compile_inline(caption)}")
|
975
|
+
end
|
978
976
|
end
|
979
977
|
|
980
978
|
if caption_top?('equation') && captionstr
|
@@ -1279,11 +1277,11 @@ module ReVIEW
|
|
1279
1277
|
|
1280
1278
|
def inline_hd_chap(chap, id)
|
1281
1279
|
n = chap.headline_index.number(id)
|
1282
|
-
if n.present? && chap.number && over_secnolevel?(n)
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1280
|
+
str = if n.present? && chap.number && over_secnolevel?(n)
|
1281
|
+
I18n.t('hd_quote', [chap.headline_index.number(id), compile_inline(chap.headline(id).caption)])
|
1282
|
+
else
|
1283
|
+
I18n.t('hd_quote_without_number', compile_inline(chap.headline(id).caption))
|
1284
|
+
end
|
1287
1285
|
if @book.config['chapterlink']
|
1288
1286
|
anchor = n.tr('.', '-')
|
1289
1287
|
macro('reviewsecref', str, sec_label(anchor))
|
@@ -1414,7 +1412,7 @@ module ReVIEW
|
|
1414
1412
|
end
|
1415
1413
|
|
1416
1414
|
def compile_href(url, label)
|
1417
|
-
if /\A[a-z]
|
1415
|
+
if /\A[a-z]+:/.match?(url)
|
1418
1416
|
if label
|
1419
1417
|
macro('href', escape_url(url), escape(label))
|
1420
1418
|
else
|
data/lib/review/lineinput.rb
CHANGED
@@ -31,7 +31,7 @@ module ReVIEW
|
|
31
31
|
def skip_comment_lines
|
32
32
|
n = 0
|
33
33
|
while line = gets
|
34
|
-
unless line.strip
|
34
|
+
unless /\A\#@/.match?(line.strip)
|
35
35
|
ungets(line)
|
36
36
|
return n
|
37
37
|
end
|
@@ -88,7 +88,7 @@ module ReVIEW
|
|
88
88
|
|
89
89
|
def while_match(re)
|
90
90
|
while line = gets
|
91
|
-
unless re
|
91
|
+
unless re&.match?(line)
|
92
92
|
ungets(line)
|
93
93
|
return
|
94
94
|
end
|
@@ -99,7 +99,7 @@ module ReVIEW
|
|
99
99
|
|
100
100
|
def until_match(re)
|
101
101
|
while line = gets
|
102
|
-
if re
|
102
|
+
if re&.match?(line)
|
103
103
|
ungets(line)
|
104
104
|
return
|
105
105
|
end
|
data/lib/review/location.rb
CHANGED
data/lib/review/logger.rb
CHANGED
@@ -76,27 +76,27 @@ module ReVIEW
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def self.logger(level: 'info')
|
79
|
-
if const_defined?(:TTYLogger)
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
79
|
+
@logger ||= if const_defined?(:TTYLogger)
|
80
|
+
TTYLogger.new do |config|
|
81
|
+
config.level = level.to_sym
|
82
|
+
config.handlers = [
|
83
|
+
[:console,
|
84
|
+
{
|
85
|
+
styles: {
|
86
|
+
debug: { label: 'DEBUG' },
|
87
|
+
info: { label: 'INFO', color: :magenta },
|
88
|
+
success: { label: 'SUCCESS' },
|
89
|
+
wait: { label: 'WAIT' },
|
90
|
+
warn: { label: 'WARN' },
|
91
|
+
error: { label: 'ERROR' },
|
92
|
+
fatal: { label: 'FATAL' }
|
93
|
+
}
|
94
|
+
}]
|
95
|
+
]
|
96
|
+
end
|
97
|
+
else
|
98
|
+
ReVIEW::Logger.new($stderr, progname: File.basename($PROGRAM_NAME, '.*'))
|
99
|
+
end
|
100
100
|
end
|
101
101
|
|
102
102
|
def self.logger=(logger)
|
data/lib/review/makerhelper.rb
CHANGED
@@ -11,7 +11,7 @@ require 'yaml'
|
|
11
11
|
|
12
12
|
begin
|
13
13
|
require 'cgi/escape'
|
14
|
-
rescue
|
14
|
+
rescue StandardError
|
15
15
|
require 'cgi/util'
|
16
16
|
end
|
17
17
|
|
@@ -43,7 +43,7 @@ module ReVIEW
|
|
43
43
|
|
44
44
|
Dir.open(from_dir) do |dir|
|
45
45
|
dir.each do |fname|
|
46
|
-
next if fname
|
46
|
+
next if /^\./.match?(fname)
|
47
47
|
|
48
48
|
if FileTest.directory?("#{from_dir}/#{fname}")
|
49
49
|
image_files += copy_images_to_dir("#{from_dir}/#{fname}", "#{to_dir}/#{fname}", options)
|
@@ -52,7 +52,7 @@ module ReVIEW
|
|
52
52
|
|
53
53
|
is_converted = false
|
54
54
|
(options[:convert] || {}).each do |orig_type, conv_type|
|
55
|
-
next unless /\.#{orig_type}
|
55
|
+
next unless /\.#{orig_type}$/.match?(fname)
|
56
56
|
|
57
57
|
is_converted = system("convert #{from_dir}/#{fname} #{to_dir}/#{fname}.#{conv_type}")
|
58
58
|
image_files << "#{from_dir}/#{fname}.#{conv_type}"
|
@@ -255,11 +255,11 @@ module ReVIEW
|
|
255
255
|
|
256
256
|
def inline_hd_chap(chap, id)
|
257
257
|
n = chap.headline_index.number(id)
|
258
|
-
if n.present? && chap.number && over_secnolevel?(n)
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
258
|
+
str = if n.present? && chap.number && over_secnolevel?(n)
|
259
|
+
I18n.t('hd_quote', [n, compile_inline(chap.headline(id).caption)])
|
260
|
+
else
|
261
|
+
I18n.t('hd_quote_without_number', compile_inline(chap.headline(id).caption))
|
262
|
+
end
|
263
263
|
if @book.config['chapterlink']
|
264
264
|
if @chapter == chap
|
265
265
|
anchor = 'h' + n.tr('.', '-')
|
@@ -409,7 +409,7 @@ module ReVIEW
|
|
409
409
|
def inline_icon(id)
|
410
410
|
begin
|
411
411
|
"![](#{@chapter.image(id).path.sub(%r{\A\./}, '')})"
|
412
|
-
rescue
|
412
|
+
rescue StandardError
|
413
413
|
warn "image not bound: #{id}", location: location
|
414
414
|
%Q(<pre>missing image: #{id}</pre>)
|
415
415
|
end
|
data/lib/review/pdfmaker.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2010-
|
1
|
+
# Copyright (c) 2010-2022 Kenshi Muto and Masayoshi Takahashi
|
2
2
|
#
|
3
3
|
# This program is free software.
|
4
4
|
# You can distribute or modify this program under the terms of
|
@@ -121,9 +121,13 @@ module ReVIEW
|
|
121
121
|
cmd_config, yamlfile = parse_opts(args)
|
122
122
|
error! "#{yamlfile} not found." unless File.exist?(yamlfile)
|
123
123
|
|
124
|
-
|
125
|
-
|
126
|
-
|
124
|
+
begin
|
125
|
+
@config = ReVIEW::Configure.create(maker: 'pdfmaker',
|
126
|
+
yamlfile: yamlfile,
|
127
|
+
config: cmd_config)
|
128
|
+
rescue ReVIEW::ConfigError => e
|
129
|
+
error! e.message
|
130
|
+
end
|
127
131
|
|
128
132
|
I18n.setup(@config['language'])
|
129
133
|
@basedir = File.absolute_path(File.dirname(yamlfile))
|
@@ -136,11 +140,11 @@ module ReVIEW
|
|
136
140
|
|
137
141
|
# version 2 compatibility
|
138
142
|
unless @config['texdocumentclass']
|
139
|
-
if @config.check_version(2, exception: false)
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
143
|
+
@config['texdocumentclass'] = if @config.check_version(2, exception: false)
|
144
|
+
['jsbook', 'uplatex,oneside']
|
145
|
+
else
|
146
|
+
@config['_texdocumentclass']
|
147
|
+
end
|
144
148
|
end
|
145
149
|
|
146
150
|
begin
|
@@ -193,7 +197,7 @@ module ReVIEW
|
|
193
197
|
def build_pdf
|
194
198
|
template = template_content
|
195
199
|
Dir.chdir(@path) do
|
196
|
-
File.
|
200
|
+
File.write("./#{@mastertex}.tex", template)
|
197
201
|
|
198
202
|
call_hook('hook_beforetexcompile', Dir.pwd, @basedir, base_dir: @basedir)
|
199
203
|
|
@@ -297,7 +301,7 @@ module ReVIEW
|
|
297
301
|
@logger.info "compiling #{filename}.tex"
|
298
302
|
begin
|
299
303
|
@converter.convert(filename + '.re', File.join(@path, filename + '.tex'))
|
300
|
-
rescue => e
|
304
|
+
rescue StandardError => e
|
301
305
|
@compile_errors = true
|
302
306
|
error "compile error in #{filename}.tex (#{e.class})"
|
303
307
|
error e.message
|
@@ -377,9 +381,9 @@ module ReVIEW
|
|
377
381
|
items.each_with_index do |item, rev|
|
378
382
|
editstr = edit == 0 ? ReVIEW::I18n.t('first_edition') : ReVIEW::I18n.t('nth_edition', (edit + 1).to_s)
|
379
383
|
revstr = ReVIEW::I18n.t('nth_impression', (rev + 1).to_s)
|
380
|
-
if
|
384
|
+
if /\A\d+-\d+-\d+\Z/.match?(item)
|
381
385
|
buf << ReVIEW::I18n.t('published_by1', [date_to_s(item), editstr + revstr])
|
382
|
-
elsif
|
386
|
+
elsif /\A(\d+-\d+-\d+)[\s ](.+)/.match?(item)
|
383
387
|
# custom date with string
|
384
388
|
item.match(/\A(\d+-\d+-\d+)[\s ](.+)/) { |m| buf << ReVIEW::I18n.t('published_by3', [date_to_s(m[1]), m[2]]) }
|
385
389
|
else
|
@@ -483,18 +487,18 @@ module ReVIEW
|
|
483
487
|
|
484
488
|
def template_content
|
485
489
|
template_dir = ReVIEW::Template::TEMPLATE_DIR
|
486
|
-
if @config.check_version('2', exception: false)
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
490
|
+
template_path = if @config.check_version('2', exception: false)
|
491
|
+
'./latex-compat2/layout.tex.erb'
|
492
|
+
else
|
493
|
+
'./latex/layout.tex.erb'
|
494
|
+
end
|
491
495
|
layout_file = File.join(@basedir, 'layouts', 'layout.tex.erb')
|
492
496
|
if File.exist?(layout_file)
|
493
497
|
template_dir = @basedir
|
494
498
|
template_path = 'layouts/layout.tex.erb'
|
495
499
|
end
|
496
500
|
ReVIEW::Template.generate(path: template_path, mode: '-', binding: binding, template_dir: template_dir)
|
497
|
-
rescue => e
|
501
|
+
rescue StandardError => e
|
498
502
|
if defined?(e.full_message)
|
499
503
|
error! "template or configuration error: #{e.full_message(highlight: false)}"
|
500
504
|
else
|
@@ -86,7 +86,7 @@ module ReVIEW
|
|
86
86
|
if l =~ /\A\x01→(dl|ul|ol)←\x01/
|
87
87
|
clevel.push($1)
|
88
88
|
lines.push("\x01→END←\x01")
|
89
|
-
elsif
|
89
|
+
elsif %r{\A\x01→/(dl|ul|ol)←\x01}.match?(l)
|
90
90
|
clevel.pop
|
91
91
|
lines.push("\x01→END←\x01")
|
92
92
|
else
|
@@ -214,14 +214,14 @@ module ReVIEW
|
|
214
214
|
|
215
215
|
def emlistnum(lines, caption = nil, _lang = nil)
|
216
216
|
blank
|
217
|
-
if caption_top?('list')
|
218
|
-
puts compile_inline(caption)
|
217
|
+
if caption_top?('list') && caption.present?
|
218
|
+
puts compile_inline(caption)
|
219
219
|
end
|
220
220
|
lines.each_with_index do |line, i|
|
221
221
|
puts((i + 1).to_s.rjust(2) + ": #{line}")
|
222
222
|
end
|
223
|
-
|
224
|
-
puts compile_inline(caption)
|
223
|
+
if !caption_top?('list') && caption.present?
|
224
|
+
puts compile_inline(caption)
|
225
225
|
end
|
226
226
|
blank
|
227
227
|
end
|