review 5.0.0 → 5.3.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 +35 -0
- data/.github/workflows/ruby-win.yml +8 -4
- data/.github/workflows/ruby.yml +6 -2
- data/.rubocop.yml +24 -9
- data/NEWS.ja.md +215 -0
- data/NEWS.md +215 -1
- data/README.md +7 -6
- data/Rakefile +7 -2
- data/bin/review +2 -4
- data/bin/review-catalog-converter +3 -3
- data/bin/review-check +6 -8
- data/bin/review-checkdep +1 -4
- data/bin/review-compile +10 -20
- data/bin/review-epub2html +1 -4
- data/bin/review-epubmaker +3 -4
- data/bin/review-idgxmlmaker +1 -3
- data/bin/review-index +11 -5
- data/bin/review-init +1 -4
- data/bin/review-pdfmaker +1 -3
- data/bin/review-preproc +30 -38
- data/bin/review-textmaker +1 -3
- data/bin/review-update +1 -4
- data/bin/review-validate +3 -3
- data/bin/review-vol +1 -4
- data/bin/review-webmaker +1 -3
- data/doc/config.yml.sample +23 -5
- data/doc/config.yml.sample-simple +1 -1
- data/doc/format.ja.md +49 -12
- data/doc/format.md +52 -12
- data/doc/quickstart.ja.md +11 -1
- data/doc/quickstart.md +11 -2
- data/doc/writing_vertical.ja.md +6 -0
- data/lib/review/book/base.rb +4 -0
- data/lib/review/book/book_unit.rb +15 -2
- data/lib/review/book/chapter.rb +3 -0
- data/lib/review/book/index.rb +5 -1
- data/lib/review/book/volume.rb +1 -0
- data/lib/review/builder.rb +90 -54
- data/lib/review/call_hook.rb +20 -0
- data/lib/review/catalog.rb +2 -0
- data/lib/review/compiler.rb +88 -52
- data/lib/review/configure.rb +64 -7
- data/lib/review/epubmaker/content.rb +113 -0
- data/lib/review/epubmaker/epubcommon.rb +372 -0
- data/lib/review/epubmaker/epubv2.rb +178 -0
- data/lib/review/epubmaker/epubv3.rb +231 -0
- data/lib/review/epubmaker/producer.rb +167 -0
- data/lib/review/epubmaker/reviewheaderlistener.rb +12 -2
- data/lib/review/epubmaker/zip_exporter.rb +84 -0
- data/lib/review/epubmaker.rb +114 -129
- data/lib/review/exception.rb +13 -0
- data/lib/review/htmlbuilder.rb +109 -67
- data/lib/review/htmlutils.rb +1 -1
- data/lib/review/i18n.rb +1 -0
- data/lib/review/i18n.yml +6 -0
- data/lib/review/idgxmlbuilder.rb +72 -48
- data/lib/review/idgxmlmaker.rb +15 -14
- data/lib/review/img_math.rb +239 -0
- data/lib/review/index_builder.rb +90 -32
- data/lib/review/init.rb +4 -4
- data/lib/review/latexbox.rb +58 -0
- data/lib/review/latexbuilder.rb +79 -58
- data/lib/review/latexutils.rb +9 -1
- data/lib/review/lineinput.rb +112 -2
- data/lib/review/loggable.rb +27 -0
- data/lib/review/logger.rb +89 -2
- data/lib/review/makerhelper.rb +7 -206
- data/lib/review/markdownbuilder.rb +44 -4
- data/lib/review/pdfmaker.rb +70 -51
- data/lib/review/plaintextbuilder.rb +20 -11
- data/lib/review/preprocessor/directive.rb +35 -0
- data/lib/review/preprocessor/line.rb +34 -0
- data/lib/review/preprocessor/repository.rb +177 -0
- data/lib/review/preprocessor.rb +105 -301
- data/lib/review/rstbuilder.rb +13 -4
- data/lib/review/sec_counter.rb +1 -0
- data/lib/review/template.rb +11 -1
- data/lib/review/textmaker.rb +23 -20
- data/lib/review/textutils.rb +10 -17
- data/lib/review/tocprinter.rb +93 -71
- data/lib/review/topbuilder.rb +44 -19
- data/lib/review/update.rb +5 -6
- data/lib/review/version.rb +1 -1
- data/lib/review/volumeprinter.rb +11 -12
- data/lib/review/webmaker.rb +31 -27
- data/lib/review/webtocprinter.rb +10 -9
- data/lib/review/yamlloader.rb +2 -1
- data/lib/review.rb +1 -1
- data/review.gemspec +5 -3
- data/samples/sample-book/src/config-epub2.yml +1 -1
- data/samples/sample-book/src/config.yml +1 -1
- data/samples/sample-book/src/lib/tasks/review.rake +19 -1
- data/samples/sample-book/src/lib/tasks/z01_copy_sty.rake +2 -1
- data/samples/syntax-book/ch01.re +1 -1
- data/samples/syntax-book/ch02.re +30 -6
- data/samples/syntax-book/ch03.re +1 -1
- data/samples/syntax-book/images/img3-2.png +0 -0
- data/samples/syntax-book/lib/tasks/z01_copy_sty.rake +2 -1
- data/templates/html/_colophon.html.erb +23 -0
- data/templates/html/_colophon_history.html.erb +9 -0
- data/templates/html/_cover.html.erb +10 -0
- data/templates/html/_part_body.html.erb +6 -0
- data/templates/html/_titlepage.html.erb +20 -0
- data/templates/html/layout-html5.html.erb +6 -0
- data/templates/html/layout-xhtml1.html.erb +6 -0
- data/templates/latex/config.erb +11 -0
- data/templates/latex/review-jlreq/review-base.sty +7 -9
- data/templates/latex/review-jlreq/review-jlreq.cls +48 -6
- data/templates/latex/review-jlreq/review-style.sty +6 -1
- data/templates/latex/review-jlreq/review-tcbox.sty +348 -0
- data/templates/latex/review-jlreq/reviewmacro.sty +5 -0
- data/templates/latex/review-jsbook/review-base.sty +13 -9
- data/templates/latex/review-jsbook/review-jsbook.cls +41 -6
- data/templates/latex/review-jsbook/review-style.sty +6 -1
- data/templates/latex/review-jsbook/review-tcbox.sty +348 -0
- data/templates/latex/review-jsbook/reviewmacro.sty +5 -0
- data/templates/opf/epubv2.opf.erb +7 -7
- data/templates/opf/epubv3.opf.erb +7 -7
- data/templates/opf/opf_manifest_epubv2.opf.erb +10 -0
- data/templates/opf/opf_manifest_epubv3.opf.erb +10 -0
- data/templates/opf/opf_metainfo_epubv2.opf.erb +17 -0
- data/templates/opf/opf_metainfo_epubv3.opf.erb +49 -0
- data/templates/opf/opf_tocx_epubv2.opf.erb +9 -0
- data/templates/opf/opf_tocx_epubv3.opf.erb +17 -0
- data/templates/web/html/layout-html5.html.erb +6 -5
- data/templates/web/html/layout-xhtml1.html.erb +6 -0
- data/test/assets/header_listener.html +35 -0
- data/test/assets/img_math/img1.png +0 -0
- data/test/assets/img_math/img2.png +0 -0
- data/test/assets/img_math/img3.png +0 -0
- data/test/assets/syntax_book_index_detail.txt +60 -0
- data/test/assets/test_template.tex +7 -1
- data/test/assets/test_template_backmatter.tex +7 -1
- data/test/run_test.rb +1 -1
- data/test/test_book_chapter.rb +27 -4
- data/test/test_builder.rb +10 -8
- data/test/test_catalog_converter_cmd.rb +1 -1
- data/test/test_epub3maker.rb +168 -124
- data/test/test_epubmaker.rb +248 -131
- data/test/test_epubmaker_cmd.rb +15 -4
- data/test/test_helper.rb +5 -4
- data/test/test_htmlbuilder.rb +170 -31
- data/test/test_idgxmlbuilder.rb +44 -23
- data/test/test_idgxmlmaker_cmd.rb +7 -3
- data/test/test_img_math.rb +111 -0
- data/test/test_index.rb +30 -4
- data/test/test_indexbuilder.rb +5 -5
- data/test/test_latexbuilder.rb +151 -26
- data/test/test_latexbuilder_v2.rb +18 -10
- data/test/test_lineinput.rb +20 -93
- data/test/test_markdownbuilder.rb +42 -0
- data/test/test_pdfmaker.rb +90 -0
- data/test/test_pdfmaker_cmd.rb +2 -2
- data/test/test_plaintextbuilder.rb +56 -40
- data/test/test_preprocessor.rb +188 -1
- data/test/test_reviewheaderlistener.rb +49 -0
- data/test/test_rstbuilder.rb +13 -0
- data/test/test_template.rb +12 -2
- data/test/test_textmaker_cmd.rb +5 -1
- data/test/test_tocprinter.rb +46 -0
- data/test/test_topbuilder.rb +50 -19
- data/test/test_update.rb +34 -34
- data/test/test_zip_exporter.rb +5 -6
- metadata +95 -17
- data/lib/epubmaker/content.rb +0 -111
- data/lib/epubmaker/epubcommon.rb +0 -449
- data/lib/epubmaker/epubv2.rb +0 -142
- data/lib/epubmaker/epubv3.rb +0 -235
- data/lib/epubmaker/producer.rb +0 -375
- data/lib/epubmaker/zip_exporter.rb +0 -81
- data/lib/epubmaker.rb +0 -23
- data/lib/lineinput.rb +0 -155
data/lib/review/latexbuilder.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Copyright (c) 2002-2007 Minero Aoki
|
2
2
|
# 2008-2009 Minero Aoki, Kenshi Muto
|
3
|
-
# 2010-
|
3
|
+
# 2010-2021 Minero Aoki, Kenshi Muto, TAKAHASHI Masayoshi
|
4
4
|
#
|
5
5
|
# This program is free software.
|
6
6
|
# You can distribute or modify this program under the terms of
|
@@ -28,6 +28,7 @@ module ReVIEW
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def builder_init_file
|
31
|
+
super
|
31
32
|
@chapter.book.image_types = %w[.ai .eps .pdf .tif .tiff .png .bmp .jpg .jpeg .gif]
|
32
33
|
@blank_needed = false
|
33
34
|
@latex_tsize = nil
|
@@ -35,7 +36,6 @@ module ReVIEW
|
|
35
36
|
@cellwidth = nil
|
36
37
|
@ol_num = nil
|
37
38
|
@first_line_num = nil
|
38
|
-
@sec_counter = SecCounter.new(5, @chapter)
|
39
39
|
@foottext = {}
|
40
40
|
setup_index
|
41
41
|
initialize_metachars(@book.config['texcommand'])
|
@@ -51,6 +51,7 @@ module ReVIEW
|
|
51
51
|
@index_db = load_idxdb(@book.config['pdfmaker']['makeindex_dic'])
|
52
52
|
end
|
53
53
|
return true unless @book.config['pdfmaker']['makeindex_mecab']
|
54
|
+
|
54
55
|
begin
|
55
56
|
begin
|
56
57
|
require 'MeCab'
|
@@ -60,7 +61,7 @@ module ReVIEW
|
|
60
61
|
require 'nkf'
|
61
62
|
@index_mecab = MeCab::Tagger.new(@book.config['pdfmaker']['makeindex_mecab_opts'])
|
62
63
|
rescue LoadError
|
63
|
-
warn 'not found MeCab'
|
64
|
+
warn 'not found MeCab', location: location
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
@@ -97,6 +98,8 @@ module ReVIEW
|
|
97
98
|
private :puts
|
98
99
|
|
99
100
|
def result
|
101
|
+
check_printendnotes
|
102
|
+
|
100
103
|
if @chapter.is_a?(ReVIEW::Book::Part) && !@book.config.check_version('2', exception: false)
|
101
104
|
puts '\end{reviewpart}'
|
102
105
|
end
|
@@ -155,7 +158,7 @@ module ReVIEW
|
|
155
158
|
puts macro('label', label) if label
|
156
159
|
end
|
157
160
|
rescue
|
158
|
-
|
161
|
+
app_error "unknown level: #{level}"
|
159
162
|
end
|
160
163
|
|
161
164
|
def nonum_begin(level, _label, caption)
|
@@ -180,10 +183,10 @@ module ReVIEW
|
|
180
183
|
end
|
181
184
|
|
182
185
|
def nodisp_begin(level, _label, caption)
|
183
|
-
if @output.pos
|
184
|
-
blank
|
185
|
-
else
|
186
|
+
if @output.pos == 0
|
186
187
|
puts macro('clearpage')
|
188
|
+
else
|
189
|
+
blank
|
187
190
|
end
|
188
191
|
puts macro('addcontentsline', 'toc', HEADLINE[level], compile_inline(caption))
|
189
192
|
# FIXME: headings
|
@@ -334,6 +337,7 @@ module ReVIEW
|
|
334
337
|
blank
|
335
338
|
puts '\begin{enumerate}'
|
336
339
|
return true unless @ol_num
|
340
|
+
|
337
341
|
puts "\\setcounter{enumi}{#{@ol_num - 1}}"
|
338
342
|
@ol_num = nil
|
339
343
|
end
|
@@ -478,7 +482,7 @@ module ReVIEW
|
|
478
482
|
captionstr = macro('reviewlistcaption', "#{I18n.t('list')}#{I18n.t('format_number_header', [get_chap, @chapter.list(id).number])}#{I18n.t('caption_prefix')}#{compile_inline(caption)}")
|
479
483
|
end
|
480
484
|
rescue KeyError
|
481
|
-
|
485
|
+
app_error "no such list: #{id}"
|
482
486
|
end
|
483
487
|
end
|
484
488
|
end
|
@@ -557,6 +561,7 @@ module ReVIEW
|
|
557
561
|
if @book.config['pdfmaker']['use_original_image_size'] && s.empty? && !metric.present?
|
558
562
|
return ' ' # pass empty to \reviewincludegraphics
|
559
563
|
end
|
564
|
+
|
560
565
|
s
|
561
566
|
end
|
562
567
|
|
@@ -564,6 +569,7 @@ module ReVIEW
|
|
564
569
|
if @book.config['pdfmaker']['image_scale2width'] && str =~ /\Ascale=([\d.]+)\Z/
|
565
570
|
return "width=#{$1}\\maxwidth"
|
566
571
|
end
|
572
|
+
|
567
573
|
str
|
568
574
|
end
|
569
575
|
|
@@ -571,13 +577,13 @@ module ReVIEW
|
|
571
577
|
array.join(',')
|
572
578
|
end
|
573
579
|
|
574
|
-
def image_image(id, caption, metric)
|
580
|
+
def image_image(id, caption = '', metric = nil)
|
575
581
|
captionstr = nil
|
576
582
|
@doc_status[:caption] = true
|
577
583
|
if @book.config.check_version('2', exception: false)
|
578
|
-
captionstr = macro('caption', compile_inline(caption)) + "\n"
|
584
|
+
captionstr = macro('caption', compile_inline(caption)) + "\n"
|
579
585
|
else
|
580
|
-
captionstr = macro('reviewimagecaption', compile_inline(caption)) + "\n"
|
586
|
+
captionstr = macro('reviewimagecaption', compile_inline(caption)) + "\n"
|
581
587
|
end
|
582
588
|
captionstr << macro('label', image_label(id))
|
583
589
|
@doc_status[:caption] = nil
|
@@ -586,7 +592,7 @@ module ReVIEW
|
|
586
592
|
# image is always bound here
|
587
593
|
puts "\\begin{reviewimage}%%#{id}"
|
588
594
|
|
589
|
-
if caption_top?('image')
|
595
|
+
if caption_top?('image')
|
590
596
|
puts captionstr
|
591
597
|
end
|
592
598
|
|
@@ -601,7 +607,7 @@ module ReVIEW
|
|
601
607
|
puts "\\#{command}[width=\\maxwidth]{#{@chapter.image(id).path}}"
|
602
608
|
end
|
603
609
|
|
604
|
-
|
610
|
+
unless caption_top?('image')
|
605
611
|
puts captionstr
|
606
612
|
end
|
607
613
|
|
@@ -609,19 +615,19 @@ module ReVIEW
|
|
609
615
|
end
|
610
616
|
|
611
617
|
def image_dummy(id, caption, lines)
|
612
|
-
warn "image not bound: #{id}"
|
618
|
+
warn "image not bound: #{id}", location: location
|
613
619
|
puts '\begin{reviewdummyimage}'
|
614
|
-
|
615
|
-
puts "--[[path = #{id} (#{existence(id)})]]--"
|
620
|
+
puts escape("--[[path = #{id} (#{existence(id)})]]--")
|
616
621
|
lines.each do |line|
|
622
|
+
puts "\n"
|
617
623
|
puts detab(line.rstrip)
|
618
624
|
end
|
619
625
|
puts macro('label', image_label(id))
|
620
626
|
@doc_status[:caption] = true
|
621
627
|
if @book.config.check_version('2', exception: false)
|
622
628
|
puts macro('caption', compile_inline(caption)) if caption.present?
|
623
|
-
|
624
|
-
puts macro('reviewimagecaption', compile_inline(caption))
|
629
|
+
elsif caption.present?
|
630
|
+
puts macro('reviewimagecaption', compile_inline(caption))
|
625
631
|
end
|
626
632
|
@doc_status[:caption] = nil
|
627
633
|
puts '\end{reviewdummyimage}'
|
@@ -696,10 +702,11 @@ module ReVIEW
|
|
696
702
|
puts "\\#{command}[width=\\maxwidth]{#{@chapter.image(id).path}}"
|
697
703
|
end
|
698
704
|
else
|
699
|
-
warn "image not bound: #{id}"
|
705
|
+
warn "image not bound: #{id}", location: location
|
700
706
|
puts '\begin{reviewdummyimage}'
|
701
|
-
puts "--[[path = #{escape(id)} (#{existence(id)})]]--"
|
707
|
+
puts escape("--[[path = #{escape(id)} (#{existence(id)})]]--")
|
702
708
|
lines.each do |line|
|
709
|
+
puts "\n"
|
703
710
|
puts detab(line.rstrip)
|
704
711
|
end
|
705
712
|
end
|
@@ -732,7 +739,7 @@ module ReVIEW
|
|
732
739
|
table_header(id, caption)
|
733
740
|
end
|
734
741
|
rescue KeyError
|
735
|
-
|
742
|
+
app_error "no such table: #{id}"
|
736
743
|
end
|
737
744
|
table_begin(rows.first.size)
|
738
745
|
table_rows(sepidx, rows)
|
@@ -817,7 +824,7 @@ module ReVIEW
|
|
817
824
|
ret = []
|
818
825
|
s = ''
|
819
826
|
brace = nil
|
820
|
-
size.
|
827
|
+
size.chars.each do |ch|
|
821
828
|
case ch
|
822
829
|
when '|'
|
823
830
|
next
|
@@ -830,15 +837,11 @@ module ReVIEW
|
|
830
837
|
ret << s
|
831
838
|
s = ''
|
832
839
|
else
|
833
|
-
if brace
|
840
|
+
if brace || s.empty?
|
834
841
|
s << ch
|
835
842
|
else
|
836
|
-
|
837
|
-
|
838
|
-
else
|
839
|
-
ret << s
|
840
|
-
s = ch
|
841
|
-
end
|
843
|
+
ret << s
|
844
|
+
s = ch
|
842
845
|
end
|
843
846
|
end
|
844
847
|
end
|
@@ -898,7 +901,7 @@ module ReVIEW
|
|
898
901
|
|
899
902
|
def imgtable(lines, id, caption = nil, metric = nil)
|
900
903
|
unless @chapter.image_bound?(id)
|
901
|
-
warn "image not bound: #{id}"
|
904
|
+
warn "image not bound: #{id}", location: location
|
902
905
|
image_dummy(id, caption, lines)
|
903
906
|
return
|
904
907
|
end
|
@@ -916,7 +919,7 @@ module ReVIEW
|
|
916
919
|
end
|
917
920
|
puts macro('label', table_label(id))
|
918
921
|
rescue ReVIEW::KeyError
|
919
|
-
|
922
|
+
app_error "no such table: #{id}"
|
920
923
|
end
|
921
924
|
imgtable_image(id, caption, metric)
|
922
925
|
|
@@ -1007,6 +1010,7 @@ module ReVIEW
|
|
1007
1010
|
|
1008
1011
|
def direct(lines, fmt)
|
1009
1012
|
return unless fmt == 'latex'
|
1013
|
+
|
1010
1014
|
lines.each do |line|
|
1011
1015
|
puts line
|
1012
1016
|
end
|
@@ -1014,6 +1018,7 @@ module ReVIEW
|
|
1014
1018
|
|
1015
1019
|
def comment(lines, comment = nil)
|
1016
1020
|
return true unless @book.config['draft']
|
1021
|
+
|
1017
1022
|
lines ||= []
|
1018
1023
|
unless comment.blank?
|
1019
1024
|
lines.unshift(escape(comment))
|
@@ -1045,35 +1050,35 @@ module ReVIEW
|
|
1045
1050
|
def inline_chapref(id)
|
1046
1051
|
title = super
|
1047
1052
|
if @book.config['chapterlink']
|
1048
|
-
"\\
|
1053
|
+
"\\reviewchapref{#{title}}{chap:#{id}}"
|
1049
1054
|
else
|
1050
1055
|
title
|
1051
1056
|
end
|
1052
1057
|
rescue KeyError
|
1053
|
-
|
1058
|
+
app_error "unknown chapter: #{id}"
|
1054
1059
|
nofunc_text("[UnknownChapter:#{id}]")
|
1055
1060
|
end
|
1056
1061
|
|
1057
1062
|
def inline_chap(id)
|
1058
1063
|
if @book.config['chapterlink']
|
1059
|
-
"\\
|
1064
|
+
"\\reviewchapref{#{@book.chapter_index.number(id)}}{chap:#{id}}"
|
1060
1065
|
else
|
1061
1066
|
@book.chapter_index.number(id)
|
1062
1067
|
end
|
1063
1068
|
rescue KeyError
|
1064
|
-
|
1069
|
+
app_error "unknown chapter: #{id}"
|
1065
1070
|
nofunc_text("[UnknownChapter:#{id}]")
|
1066
1071
|
end
|
1067
1072
|
|
1068
1073
|
def inline_title(id)
|
1069
1074
|
title = super
|
1070
1075
|
if @book.config['chapterlink']
|
1071
|
-
"\\
|
1076
|
+
"\\reviewchapref{#{title}}{chap:#{id}}"
|
1072
1077
|
else
|
1073
1078
|
title
|
1074
1079
|
end
|
1075
1080
|
rescue KeyError
|
1076
|
-
|
1081
|
+
app_error "unknown chapter: #{id}"
|
1077
1082
|
nofunc_text("[UnknownChapter:#{id}]")
|
1078
1083
|
end
|
1079
1084
|
|
@@ -1090,7 +1095,7 @@ module ReVIEW
|
|
1090
1095
|
macro('reviewlistref', I18n.t('format_number', [get_chap(chapter), chapter.list(id).number]))
|
1091
1096
|
end
|
1092
1097
|
rescue KeyError
|
1093
|
-
|
1098
|
+
app_error "unknown list: #{id}"
|
1094
1099
|
end
|
1095
1100
|
|
1096
1101
|
def inline_table(id)
|
@@ -1101,7 +1106,7 @@ module ReVIEW
|
|
1101
1106
|
macro('reviewtableref', I18n.t('format_number', [get_chap(chapter), chapter.table(id).number]), table_label(id, chapter))
|
1102
1107
|
end
|
1103
1108
|
rescue KeyError
|
1104
|
-
|
1109
|
+
app_error "unknown table: #{id}"
|
1105
1110
|
end
|
1106
1111
|
|
1107
1112
|
def inline_img(id)
|
@@ -1112,7 +1117,7 @@ module ReVIEW
|
|
1112
1117
|
macro('reviewimageref', I18n.t('format_number', [get_chap(chapter), chapter.image(id).number]), image_label(id, chapter))
|
1113
1118
|
end
|
1114
1119
|
rescue KeyError
|
1115
|
-
|
1120
|
+
app_error "unknown image: #{id}"
|
1116
1121
|
end
|
1117
1122
|
|
1118
1123
|
def inline_eq(id)
|
@@ -1123,13 +1128,13 @@ module ReVIEW
|
|
1123
1128
|
macro('reviewequationref', I18n.t('format_number', [get_chap(chapter), chapter.equation(id).number]))
|
1124
1129
|
end
|
1125
1130
|
rescue KeyError
|
1126
|
-
|
1131
|
+
app_error "unknown equation: #{id}"
|
1127
1132
|
end
|
1128
1133
|
|
1129
1134
|
def footnote(id, content)
|
1130
1135
|
if @book.config['footnotetext'] || @foottext[id]
|
1131
1136
|
if @doc_status[:column]
|
1132
|
-
warn "//footnote[#{id}] is in the column block. It is recommended to move out of the column block."
|
1137
|
+
warn "//footnote[#{id}] is in the column block. It is recommended to move out of the column block.", location: location
|
1133
1138
|
end
|
1134
1139
|
puts macro("footnotetext[#{@chapter.footnote(id).number}]", compile_inline(content.strip))
|
1135
1140
|
end
|
@@ -1145,7 +1150,20 @@ module ReVIEW
|
|
1145
1150
|
macro('footnote', compile_inline(@chapter.footnote(id).content.strip))
|
1146
1151
|
end
|
1147
1152
|
rescue KeyError
|
1148
|
-
|
1153
|
+
app_error "unknown footnote: #{id}"
|
1154
|
+
end
|
1155
|
+
|
1156
|
+
def inline_endnote(id)
|
1157
|
+
macro('endnote', compile_inline(@chapter.endnote(id).content.strip))
|
1158
|
+
rescue KeyError
|
1159
|
+
app_error "unknown footnote: #{id}"
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
def printendnotes
|
1163
|
+
@shown_endnotes = true
|
1164
|
+
blank
|
1165
|
+
puts '\theendnotes'
|
1166
|
+
blank
|
1149
1167
|
end
|
1150
1168
|
|
1151
1169
|
BOUTEN = '・'.freeze
|
@@ -1231,6 +1249,10 @@ module ReVIEW
|
|
1231
1249
|
end
|
1232
1250
|
end
|
1233
1251
|
|
1252
|
+
def inline_ins(str)
|
1253
|
+
macro('reviewinsert', escape(str))
|
1254
|
+
end
|
1255
|
+
|
1234
1256
|
def inline_del(str)
|
1235
1257
|
macro('reviewstrike', escape(str))
|
1236
1258
|
end
|
@@ -1263,7 +1285,7 @@ module ReVIEW
|
|
1263
1285
|
str = I18n.t('hd_quote_without_number', compile_inline(chap.headline(id).caption))
|
1264
1286
|
end
|
1265
1287
|
if @book.config['chapterlink']
|
1266
|
-
anchor = n.
|
1288
|
+
anchor = n.tr('.', '-')
|
1267
1289
|
macro('reviewsecref', str, sec_label(anchor))
|
1268
1290
|
else
|
1269
1291
|
str
|
@@ -1275,7 +1297,7 @@ module ReVIEW
|
|
1275
1297
|
I18n.t('column', compile_inline(chapter.column(id).caption)),
|
1276
1298
|
column_label(id, chapter))
|
1277
1299
|
rescue KeyError
|
1278
|
-
|
1300
|
+
app_error "unknown column: #{id}"
|
1279
1301
|
end
|
1280
1302
|
|
1281
1303
|
def inline_raw(str) # rubocop:disable Lint/UselessMethodDefinition
|
@@ -1314,7 +1336,7 @@ module ReVIEW
|
|
1314
1336
|
end
|
1315
1337
|
macro(command, @chapter.image(id).path)
|
1316
1338
|
else
|
1317
|
-
warn "image not bound: #{id}"
|
1339
|
+
warn "image not bound: #{id}", location: location
|
1318
1340
|
"\\verb|--[[path = #{id} (#{existence(id)})]]--|"
|
1319
1341
|
end
|
1320
1342
|
end
|
@@ -1338,7 +1360,7 @@ module ReVIEW
|
|
1338
1360
|
end
|
1339
1361
|
|
1340
1362
|
def inline_tcy(str)
|
1341
|
-
macro('
|
1363
|
+
macro('reviewtcy', escape(str))
|
1342
1364
|
end
|
1343
1365
|
|
1344
1366
|
def inline_balloon(str)
|
@@ -1361,23 +1383,22 @@ module ReVIEW
|
|
1361
1383
|
end
|
1362
1384
|
|
1363
1385
|
def index(str)
|
1386
|
+
# XXX: mendex/upmendex specific
|
1364
1387
|
sa = str.split('<<>>')
|
1365
1388
|
|
1366
1389
|
sa.map! do |item|
|
1367
1390
|
if @index_db[item]
|
1368
|
-
escape_index(
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
"#{escape_index(item)}@#{esc_item}"
|
1374
|
-
else
|
1375
|
-
esc_item
|
1376
|
-
end
|
1391
|
+
escape_mendex_key(escape_index(@index_db[item])) + '@' + escape_mendex_display(escape_index(escape(item)))
|
1392
|
+
elsif item =~ /\A[[:ascii:]]+\Z/ || @index_mecab.nil?
|
1393
|
+
esc_item = escape_mendex_display(escape_index(escape(item)))
|
1394
|
+
if esc_item == item
|
1395
|
+
esc_item
|
1377
1396
|
else
|
1378
|
-
|
1379
|
-
escape_index(escape(yomi)) + '@' + escape_index(escape(item))
|
1397
|
+
"#{escape_mendex_key(escape_index(item))}@#{esc_item}"
|
1380
1398
|
end
|
1399
|
+
else
|
1400
|
+
yomi = NKF.nkf('-w --hiragana', @index_mecab.parse(item).force_encoding('UTF-8').chomp)
|
1401
|
+
escape_mendex_key(escape_index(yomi)) + '@' + escape_mendex_display(escape_index(escape(item)))
|
1381
1402
|
end
|
1382
1403
|
end
|
1383
1404
|
|
data/lib/review/latexutils.rb
CHANGED
@@ -59,7 +59,7 @@ module ReVIEW
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
@metachars_re = /[#{Regexp.escape(@metachars.keys.join(''))}]/u
|
62
|
+
@metachars_re = /[#{Regexp.escape(@metachars.keys.join(''))}]/u # rubocop:disable Style/RedundantArgument
|
63
63
|
|
64
64
|
@metachars_invert = @metachars.invert
|
65
65
|
end
|
@@ -81,6 +81,14 @@ module ReVIEW
|
|
81
81
|
str.gsub(/[@!|"]/) { |s| '"' + s }
|
82
82
|
end
|
83
83
|
|
84
|
+
def escape_mendex_key(str)
|
85
|
+
str.gsub('"|', '|').tr('{', '{').tr('}', '}')
|
86
|
+
end
|
87
|
+
|
88
|
+
def escape_mendex_display(str)
|
89
|
+
str.gsub('\{', '\reviewleftcurlybrace{}').gsub('\}', '\reviewrightcurlybrace{}')
|
90
|
+
end
|
91
|
+
|
84
92
|
def escape_url(str)
|
85
93
|
str.gsub(/[\#%]/) { |s| '\\' + s }
|
86
94
|
end
|
data/lib/review/lineinput.rb
CHANGED
@@ -1,7 +1,33 @@
|
|
1
|
-
|
1
|
+
#
|
2
|
+
# Copyright (c) 2002-2020 Minero Aoki, Masayoshi Takahashi, Kenshi Muto
|
3
|
+
#
|
4
|
+
# This program is free software.
|
5
|
+
# You can distribute/modify this program under the terms of
|
6
|
+
# the GNU LGPL, Lesser General Public License version 2.1.
|
7
|
+
#
|
8
|
+
require 'review/exception'
|
2
9
|
|
3
10
|
module ReVIEW
|
4
|
-
class LineInput
|
11
|
+
class LineInput
|
12
|
+
INVALID_CHARACTER_PATTERN = /[\x00-\x08\x0b-\x0c\x0e-\x1f]/ # accept 0x09: TAB, 0x0a: LF, 0x0d: CR
|
13
|
+
|
14
|
+
attr_reader :lineno
|
15
|
+
|
16
|
+
def initialize(f)
|
17
|
+
@input = f
|
18
|
+
@buf = []
|
19
|
+
@lineno = 0
|
20
|
+
@eof_p = false
|
21
|
+
end
|
22
|
+
|
23
|
+
def inspect
|
24
|
+
"\#<#{self.class} file=#{@input.inspect} line=#{lineno}>"
|
25
|
+
end
|
26
|
+
|
27
|
+
def eof?
|
28
|
+
@eof_p
|
29
|
+
end
|
30
|
+
|
5
31
|
def skip_comment_lines
|
6
32
|
n = 0
|
7
33
|
while line = gets
|
@@ -13,5 +39,89 @@ module ReVIEW
|
|
13
39
|
end
|
14
40
|
n
|
15
41
|
end
|
42
|
+
|
43
|
+
def gets
|
44
|
+
unless @buf.empty?
|
45
|
+
@lineno += 1
|
46
|
+
return @buf.pop
|
47
|
+
end
|
48
|
+
return nil if @eof_p # to avoid ARGF blocking.
|
49
|
+
|
50
|
+
line = @input.gets
|
51
|
+
@eof_p = true unless line
|
52
|
+
@lineno += 1
|
53
|
+
invalid_char = lookup_invalid_char(line)
|
54
|
+
if invalid_char
|
55
|
+
raise SyntaxError, "found invalid control-sequence character (#{sprintf('%#x', invalid_char.codepoints[0])})."
|
56
|
+
end
|
57
|
+
|
58
|
+
line
|
59
|
+
end
|
60
|
+
|
61
|
+
def peek
|
62
|
+
line = gets
|
63
|
+
ungets(line) if line
|
64
|
+
line
|
65
|
+
end
|
66
|
+
|
67
|
+
def next?
|
68
|
+
peek ? true : false
|
69
|
+
end
|
70
|
+
|
71
|
+
def skip_blank_lines
|
72
|
+
n = 0
|
73
|
+
while line = gets
|
74
|
+
unless line.strip.empty?
|
75
|
+
ungets(line)
|
76
|
+
return n
|
77
|
+
end
|
78
|
+
n += 1
|
79
|
+
end
|
80
|
+
n
|
81
|
+
end
|
82
|
+
|
83
|
+
def each
|
84
|
+
while line = gets
|
85
|
+
yield line
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def while_match(re)
|
90
|
+
while line = gets
|
91
|
+
unless re =~ line
|
92
|
+
ungets(line)
|
93
|
+
return
|
94
|
+
end
|
95
|
+
yield line
|
96
|
+
end
|
97
|
+
nil
|
98
|
+
end
|
99
|
+
|
100
|
+
def until_match(re)
|
101
|
+
while line = gets
|
102
|
+
if re =~ line
|
103
|
+
ungets(line)
|
104
|
+
return
|
105
|
+
end
|
106
|
+
yield line
|
107
|
+
end
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def ungets(line)
|
114
|
+
return unless line
|
115
|
+
|
116
|
+
@lineno -= 1
|
117
|
+
@buf.push(line)
|
118
|
+
line
|
119
|
+
end
|
120
|
+
|
121
|
+
def lookup_invalid_char(line)
|
122
|
+
if line =~ INVALID_CHARACTER_PATTERN
|
123
|
+
$&
|
124
|
+
end
|
125
|
+
end
|
16
126
|
end
|
17
127
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ReVIEW
|
2
|
+
module Loggable
|
3
|
+
attr_reader :logger
|
4
|
+
|
5
|
+
def error(msg, location: nil)
|
6
|
+
logger.error(msg, location: location)
|
7
|
+
end
|
8
|
+
|
9
|
+
def app_error(msg)
|
10
|
+
raise ApplicationError, msg
|
11
|
+
end
|
12
|
+
|
13
|
+
def error!(msg, location: nil)
|
14
|
+
logger.error(msg, location: location)
|
15
|
+
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
|
19
|
+
def warn(msg, location: nil)
|
20
|
+
logger.warn(msg, location: location)
|
21
|
+
end
|
22
|
+
|
23
|
+
def debug(msg, location: nil)
|
24
|
+
logger.debug(msg, location: location)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/review/logger.rb
CHANGED
@@ -6,10 +6,97 @@ module ReVIEW
|
|
6
6
|
super(io, progname: progname)
|
7
7
|
self.formatter = ->(severity, _datetime, name, msg) { "#{severity} #{name}: #{msg}\n" }
|
8
8
|
end
|
9
|
+
|
10
|
+
def warn(msg, location: nil)
|
11
|
+
if location
|
12
|
+
super("#{location}: #{msg}")
|
13
|
+
else
|
14
|
+
super(msg)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def error(msg, location: nil)
|
19
|
+
if location
|
20
|
+
super("#{location}: #{msg}")
|
21
|
+
else
|
22
|
+
super(msg)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def debug(msg, location: nil)
|
27
|
+
if location
|
28
|
+
super("#{location}: #{msg}")
|
29
|
+
else
|
30
|
+
super(msg)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def ttylogger?
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def success(_log)
|
39
|
+
# empty (for backward compatibility)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
begin
|
44
|
+
require 'tty-logger'
|
45
|
+
class TTYLogger < ::TTY::Logger
|
46
|
+
def warn(msg, location: nil)
|
47
|
+
if location
|
48
|
+
super("#{location}: #{msg}")
|
49
|
+
else
|
50
|
+
super(msg)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def error(msg, location: nil)
|
55
|
+
if location
|
56
|
+
super("#{location}: #{msg}")
|
57
|
+
else
|
58
|
+
super(msg)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def debug(msg, location: nil)
|
63
|
+
if location
|
64
|
+
super("#{location}: #{msg}")
|
65
|
+
else
|
66
|
+
super(msg)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def ttylogger?
|
71
|
+
true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
rescue LoadError
|
75
|
+
nil
|
9
76
|
end
|
10
77
|
|
11
|
-
def self.logger
|
12
|
-
|
78
|
+
def self.logger(level: 'info')
|
79
|
+
if const_defined?(:TTYLogger)
|
80
|
+
@logger ||= 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
|
+
@logger ||= ReVIEW::Logger.new($stderr, progname: File.basename($PROGRAM_NAME, '.*'))
|
99
|
+
end
|
13
100
|
end
|
14
101
|
|
15
102
|
def self.logger=(logger)
|