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/textmaker.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2018-
|
1
|
+
# Copyright (c) 2018-2021 Kenshi Muto
|
2
2
|
#
|
3
3
|
# This program is free software.
|
4
4
|
# You can distribute or modify this program under the terms of
|
@@ -16,10 +16,13 @@ require 'review/yamlloader'
|
|
16
16
|
require 'review/topbuilder'
|
17
17
|
require 'review/version'
|
18
18
|
require 'review/makerhelper'
|
19
|
+
require 'review/img_math'
|
20
|
+
require 'review/loggable'
|
19
21
|
|
20
22
|
module ReVIEW
|
21
23
|
class TEXTMaker
|
22
24
|
include MakerHelper
|
25
|
+
include Loggable
|
23
26
|
|
24
27
|
attr_accessor :config, :basedir
|
25
28
|
|
@@ -27,15 +30,8 @@ module ReVIEW
|
|
27
30
|
@basedir = nil
|
28
31
|
@logger = ReVIEW.logger
|
29
32
|
@plaintext = nil
|
30
|
-
|
31
|
-
|
32
|
-
def error(msg)
|
33
|
-
@logger.error msg
|
34
|
-
exit 1
|
35
|
-
end
|
36
|
-
|
37
|
-
def warn(msg)
|
38
|
-
@logger.warn msg
|
33
|
+
@img_math = nil
|
34
|
+
@compile_errors = nil
|
39
35
|
end
|
40
36
|
|
41
37
|
def self.execute(*args)
|
@@ -70,29 +66,31 @@ module ReVIEW
|
|
70
66
|
end
|
71
67
|
|
72
68
|
def remove_old_files(path)
|
73
|
-
cleanup_mathimg
|
69
|
+
@img_math.cleanup_mathimg
|
74
70
|
FileUtils.rm_rf(path)
|
75
71
|
end
|
76
72
|
|
77
73
|
def execute(*args)
|
78
74
|
cmd_config, yamlfile = parse_opts(args)
|
79
|
-
error "#{yamlfile} not found." unless File.exist?(yamlfile)
|
75
|
+
error! "#{yamlfile} not found." unless File.exist?(yamlfile)
|
80
76
|
|
81
77
|
@config = ReVIEW::Configure.create(maker: 'textmaker',
|
82
78
|
yamlfile: yamlfile,
|
83
79
|
config: cmd_config)
|
80
|
+
@img_math = ReVIEW::ImgMath.new(@config, path_name: '_review_math_text')
|
84
81
|
|
85
82
|
I18n.setup(@config['language'])
|
86
83
|
begin
|
87
84
|
generate_text_files(yamlfile)
|
85
|
+
@logger.success("built #{build_path}")
|
88
86
|
rescue ApplicationError => e
|
89
87
|
raise if @config['debug']
|
90
|
-
|
88
|
+
|
89
|
+
error! e.message
|
91
90
|
end
|
92
91
|
|
93
|
-
|
94
|
-
|
95
|
-
make_math_images(math_dir)
|
92
|
+
if @config['math_format'] == 'imgmath'
|
93
|
+
@img_math.make_math_images
|
96
94
|
end
|
97
95
|
end
|
98
96
|
|
@@ -105,15 +103,19 @@ module ReVIEW
|
|
105
103
|
@book = ReVIEW::Book::Base.new(@basedir, config: @config)
|
106
104
|
|
107
105
|
build_body(@path, yamlfile)
|
106
|
+
|
107
|
+
if @compile_errors
|
108
|
+
app_error 'compile error, No TEXT file output.'
|
109
|
+
end
|
108
110
|
end
|
109
111
|
|
110
112
|
def build_body(basetmpdir, _yamlfile)
|
111
113
|
base_path = Pathname.new(@basedir)
|
112
114
|
builder = nil
|
113
115
|
if @plaintext
|
114
|
-
builder = ReVIEW::PLAINTEXTBuilder.new
|
116
|
+
builder = ReVIEW::PLAINTEXTBuilder.new(img_math: @img_math)
|
115
117
|
else
|
116
|
-
builder = ReVIEW::TOPBuilder.new
|
118
|
+
builder = ReVIEW::TOPBuilder.new(img_math: @img_math)
|
117
119
|
end
|
118
120
|
@converter = ReVIEW::Converter.new(@book, builder)
|
119
121
|
@book.parts.each do |part|
|
@@ -158,8 +160,9 @@ module ReVIEW
|
|
158
160
|
begin
|
159
161
|
@converter.convert(filename, File.join(basetmpdir, textfile))
|
160
162
|
rescue => e
|
161
|
-
|
162
|
-
|
163
|
+
@compile_errors = true
|
164
|
+
error "compile error in #{filename} (#{e.class})"
|
165
|
+
error e.message
|
163
166
|
end
|
164
167
|
end
|
165
168
|
end
|
data/lib/review/textutils.rb
CHANGED
@@ -15,7 +15,7 @@ module ReVIEW
|
|
15
15
|
add = 0
|
16
16
|
len = nil
|
17
17
|
str.gsub("\t") do
|
18
|
-
len = ts - ($`.size + add) % ts
|
18
|
+
len = ts - (($`.size + add) % ts)
|
19
19
|
add += len - 1
|
20
20
|
' ' * len
|
21
21
|
end
|
@@ -51,6 +51,7 @@ module ReVIEW
|
|
51
51
|
if tail.nil? || head.nil?
|
52
52
|
return nil
|
53
53
|
end
|
54
|
+
|
54
55
|
space = true
|
55
56
|
# rule 2
|
56
57
|
if %i[F W H].include?(Unicode::Eaw.property(tail)) &&
|
@@ -71,12 +72,13 @@ module ReVIEW
|
|
71
72
|
end
|
72
73
|
|
73
74
|
# lazy than rule 3, but it looks better
|
74
|
-
if lazy
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
75
|
+
if lazy
|
76
|
+
if (%i[F W H].include?(Unicode::Eaw.property(tail)) &&
|
77
|
+
tail !~ /\p{Hangul}/) ||
|
78
|
+
(%i[F W H].include?(Unicode::Eaw.property(head)) &&
|
79
|
+
head !~ /\p{Hangul}/)
|
80
|
+
space = nil
|
81
|
+
end
|
80
82
|
end
|
81
83
|
end
|
82
84
|
space
|
@@ -86,6 +88,7 @@ module ReVIEW
|
|
86
88
|
unless @book.config['join_lines_by_lang']
|
87
89
|
return lines.join
|
88
90
|
end
|
91
|
+
|
89
92
|
lazy = true
|
90
93
|
lang = 'ja'
|
91
94
|
0.upto(lines.size - 2) do |n|
|
@@ -96,16 +99,6 @@ module ReVIEW
|
|
96
99
|
lines.join
|
97
100
|
end
|
98
101
|
|
99
|
-
def defer_math_image(str, path, key)
|
100
|
-
# for Re:VIEW >3
|
101
|
-
File.open(File.join(File.dirname(path), "__IMGMATH_BODY__#{key}.tex"), 'w') do |f|
|
102
|
-
f.puts str
|
103
|
-
end
|
104
|
-
File.open(File.join(File.dirname(path), '__IMGMATH_BODY__.map'), 'a+') do |f|
|
105
|
-
f.puts key
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
102
|
private
|
110
103
|
|
111
104
|
# remove elements at the back of `lines` if element is empty string
|
data/lib/review/tocprinter.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2008-
|
1
|
+
# Copyright (c) 2008-2021 Minero Aoki, Kenshi Muto
|
2
2
|
# 1999-2007 Minero Aoki
|
3
3
|
#
|
4
4
|
# This program is free software.
|
@@ -36,34 +36,50 @@ module ReVIEW
|
|
36
36
|
end
|
37
37
|
|
38
38
|
class TOCPrinter
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
class Counter
|
40
|
+
def initialize(name: nil, level: nil, headline: nil, lines: nil, chars: nil, list_lines: nil, text_lines: nil, part: nil)
|
41
|
+
@name = name
|
42
|
+
@level = level
|
43
|
+
@headline = headline
|
44
|
+
@lines = lines
|
45
|
+
@chars = chars
|
46
|
+
@list_lines = list_lines
|
47
|
+
@text_lines = text_lines
|
48
|
+
@part = part
|
43
49
|
end
|
50
|
+
|
51
|
+
attr_accessor :name, :level, :headline, :lines, :chars, :list_lines, :text_lines, :part
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.execute(*args)
|
44
55
|
new.execute(*args)
|
45
|
-
rescue Errno::EPIPE
|
46
|
-
exit 0
|
47
56
|
end
|
48
57
|
|
49
58
|
def initialize
|
50
59
|
@logger = ReVIEW.logger
|
51
|
-
@config = ReVIEW::Configure.values
|
52
60
|
@yamlfile = 'config.yml'
|
53
|
-
@book = ReVIEW::Book::Base.new('.', config: @config)
|
54
61
|
@upper = 4
|
55
62
|
@indent = true
|
56
63
|
@buildonly = nil
|
57
64
|
@detail = nil
|
65
|
+
@calc_char_width = nil
|
58
66
|
end
|
59
67
|
|
68
|
+
attr_accessor :calc_char_width
|
69
|
+
|
60
70
|
def execute(*args)
|
61
71
|
parse_options(args)
|
62
|
-
|
63
|
-
@
|
72
|
+
begin
|
73
|
+
@config = ReVIEW::Configure.create(yamlfile: @yamlfile)
|
74
|
+
@book = ReVIEW::Book::Base.new('.', config: @config)
|
75
|
+
unless File.readable?(@yamlfile)
|
76
|
+
raise ReVIEW::FileNotFound, "No such fiile or can't open #{@yamlfile}."
|
77
|
+
end
|
78
|
+
rescue ReVIEW::ConfigError, ReVIEW::FileNotFound, ReVIEW::CompileError, ReVIEW::ApplicationError => e
|
79
|
+
@logger.error e.message
|
64
80
|
exit 1
|
65
81
|
end
|
66
|
-
|
82
|
+
|
67
83
|
I18n.setup(@config['language'])
|
68
84
|
|
69
85
|
if @detail
|
@@ -84,27 +100,27 @@ module ReVIEW
|
|
84
100
|
begin
|
85
101
|
@book.parts.each do |part|
|
86
102
|
if part.name.present? && (@buildonly.nil? || @buildonly.include?(part.name))
|
87
|
-
result_array.push(
|
103
|
+
result_array.push(Counter.new(part: 'start'))
|
88
104
|
if part.file?
|
89
|
-
|
90
|
-
result_array
|
105
|
+
content = build_chap(part)
|
106
|
+
result_array.concat(parse_contents(part.name, @upper, content))
|
91
107
|
else
|
92
108
|
title = part.format_number + I18n.t('chapter_postfix') + part.title
|
93
|
-
result_array
|
94
|
-
|
95
|
-
|
96
|
-
|
109
|
+
result_array.push(
|
110
|
+
Counter.new(name: '', lines: 1, chars: title.size, list_lines: 0, text_lines: 1),
|
111
|
+
Counter.new(level: 0, headline: title, lines: 1, chars: title.size, list_lines: 0, text_lines: 1)
|
112
|
+
)
|
97
113
|
end
|
98
114
|
end
|
99
115
|
|
100
116
|
part.chapters.each do |chap|
|
101
117
|
if @buildonly.nil? || @buildonly.include?(chap.name)
|
102
|
-
|
103
|
-
result_array
|
118
|
+
content = build_chap(chap)
|
119
|
+
result_array.concat(parse_contents(chap.name, @upper, content))
|
104
120
|
end
|
105
121
|
end
|
106
122
|
if part.name.present? && (@buildonly.nil? || @buildonly.include?(part.name))
|
107
|
-
result_array.push(
|
123
|
+
result_array.push(Counter.new(part: 'end'))
|
108
124
|
end
|
109
125
|
end
|
110
126
|
rescue ReVIEW::FileNotFound, ReVIEW::CompileError => e
|
@@ -117,15 +133,15 @@ module ReVIEW
|
|
117
133
|
|
118
134
|
def print_result(result_array)
|
119
135
|
result_array.each do |result|
|
120
|
-
if result
|
136
|
+
if result.part
|
121
137
|
next
|
122
138
|
end
|
123
139
|
|
124
|
-
if result
|
140
|
+
if result.name
|
125
141
|
# file information
|
126
142
|
if @detail
|
127
143
|
puts '============================='
|
128
|
-
printf("%6dC %5dL %5dP %s\n", result
|
144
|
+
printf("%6dC %5dL %5dP %s\n", result.chars, result.lines, calc_pages(result).ceil, result.name)
|
129
145
|
puts '-----------------------------'
|
130
146
|
end
|
131
147
|
next
|
@@ -133,42 +149,39 @@ module ReVIEW
|
|
133
149
|
|
134
150
|
# section information
|
135
151
|
if @detail
|
136
|
-
printf('%6dC %5dL %5.1fP ', result
|
152
|
+
printf('%6dC %5dL %5.1fP ', result.chars, result.lines, calc_pages(result))
|
137
153
|
end
|
138
|
-
if @indent && result
|
139
|
-
print ' ' * (result
|
154
|
+
if @indent && result.level
|
155
|
+
print ' ' * (result.level == 0 ? 0 : result.level - 1)
|
140
156
|
end
|
141
|
-
puts result
|
157
|
+
puts result.headline
|
142
158
|
end
|
143
159
|
end
|
144
160
|
|
145
161
|
def calc_pages(result)
|
146
|
-
|
147
|
-
|
148
|
-
p += result[:text_lines].to_f / @book.page_metric.text.n_lines
|
149
|
-
p
|
162
|
+
(result.list_lines.to_f / @book.page_metric.list.n_lines) +
|
163
|
+
(result.text_lines.to_f / @book.page_metric.text.n_lines)
|
150
164
|
end
|
151
165
|
|
152
|
-
def calc_linesize(
|
153
|
-
return
|
154
|
-
|
155
|
-
|
166
|
+
def calc_linesize(line)
|
167
|
+
return line.size unless @calc_char_width
|
168
|
+
|
169
|
+
line.each_char.inject(0) do |result, char|
|
156
170
|
# XXX: should include A also?
|
157
|
-
if %i[Na H N].include?(Unicode::Eaw.property(
|
158
|
-
|
171
|
+
if %i[Na H N].include?(Unicode::Eaw.property(char))
|
172
|
+
result + 0.5 # halfwidth
|
159
173
|
else
|
160
|
-
|
174
|
+
result + 1
|
161
175
|
end
|
162
176
|
end
|
163
|
-
w
|
164
177
|
end
|
165
178
|
|
166
179
|
def parse_contents(name, upper, content)
|
167
180
|
headline_array = []
|
168
|
-
counter =
|
181
|
+
counter = Counter.new(lines: 0, chars: 0, list_lines: 0, text_lines: 0)
|
169
182
|
listmode = nil
|
170
183
|
|
171
|
-
content.
|
184
|
+
content.each_line(chomp: true) do |l|
|
172
185
|
if l.start_with?("\x01STARTLIST\x01")
|
173
186
|
listmode = true
|
174
187
|
next
|
@@ -180,58 +193,67 @@ module ReVIEW
|
|
180
193
|
level = $1.to_i
|
181
194
|
l = $'
|
182
195
|
if level <= upper
|
183
|
-
if counter
|
196
|
+
if counter.chars > 0
|
184
197
|
headline_array.push(counter)
|
185
198
|
end
|
186
199
|
headline = l
|
187
|
-
counter =
|
200
|
+
counter = Counter.new(
|
188
201
|
level: level,
|
189
202
|
headline: headline,
|
190
203
|
lines: 1,
|
191
204
|
chars: headline.size,
|
192
205
|
list_lines: 0,
|
193
206
|
text_lines: 1
|
194
|
-
|
207
|
+
)
|
195
208
|
next
|
196
209
|
end
|
197
210
|
end
|
198
211
|
|
199
|
-
counter
|
200
|
-
counter
|
212
|
+
counter.lines += 1
|
213
|
+
counter.chars += l.size
|
201
214
|
|
202
215
|
if listmode
|
203
216
|
# code list: calculate line wrapping
|
204
|
-
|
205
|
-
counter[:list_lines] += 1
|
206
|
-
else
|
207
|
-
counter[:list_lines] += (calc_linesize(l) - 1) / @book.page_metric.list.n_columns + 1
|
208
|
-
end
|
217
|
+
counter.list_lines += calc_line_wrapping(l, mode: :list)
|
209
218
|
else
|
210
219
|
# normal paragraph: calculate line wrapping
|
211
|
-
|
212
|
-
counter[:text_lines] += 1
|
213
|
-
else
|
214
|
-
counter[:text_lines] += (calc_linesize(l) - 1) / @book.page_metric.text.n_columns + 1
|
215
|
-
end
|
220
|
+
counter.text_lines += calc_line_wrapping(l, mode: :text)
|
216
221
|
end
|
217
222
|
end
|
218
223
|
headline_array.push(counter)
|
219
224
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
225
|
+
total = calc_total_count(name, headline_array)
|
226
|
+
headline_array.unshift(total)
|
227
|
+
end
|
228
|
+
|
229
|
+
def calc_line_wrapping(line, mode:)
|
230
|
+
return 1 if line.size == 0
|
231
|
+
|
232
|
+
case mode
|
233
|
+
when :list
|
234
|
+
((calc_linesize(line) - 1) / @book.page_metric.list.n_columns) + 1
|
235
|
+
else # mode == :text
|
236
|
+
((calc_linesize(line) - 1) / @book.page_metric.text.n_columns) + 1
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def calc_total_count(name, headline_array)
|
241
|
+
total = Counter.new(name: name,
|
242
|
+
lines: 0,
|
243
|
+
chars: 0,
|
244
|
+
list_lines: 0,
|
245
|
+
text_lines: 0)
|
224
246
|
|
225
247
|
headline_array.each do |h|
|
226
|
-
next unless h
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
248
|
+
next unless h.lines
|
249
|
+
|
250
|
+
total.lines += h.lines
|
251
|
+
total.chars += h.chars
|
252
|
+
total.list_lines += h.list_lines
|
253
|
+
total.text_lines += h.text_lines
|
231
254
|
end
|
232
255
|
|
233
|
-
|
234
|
-
unshift({ name: name, lines: total_lines, chars: total_chars, list_lines: total_list_lines, text_lines: total_text_lines })
|
256
|
+
total
|
235
257
|
end
|
236
258
|
|
237
259
|
def build_chap(chap)
|
@@ -239,8 +261,8 @@ module ReVIEW
|
|
239
261
|
begin
|
240
262
|
compiler.compile(@book.chapter(chap.name))
|
241
263
|
rescue ReVIEW::ApplicationError => e
|
242
|
-
@logger.error e
|
243
|
-
|
264
|
+
@logger.error e.message
|
265
|
+
''
|
244
266
|
end
|
245
267
|
end
|
246
268
|
|
data/lib/review/topbuilder.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2008-
|
1
|
+
# Copyright (c) 2008-2021 Minero Aoki, Kenshi Muto
|
2
2
|
# 2002-2006 Minero Aoki
|
3
3
|
#
|
4
4
|
# This program is free software.
|
@@ -78,7 +78,7 @@ module ReVIEW
|
|
78
78
|
|
79
79
|
def dd(lines)
|
80
80
|
split_paragraph(lines).each do |paragraph|
|
81
|
-
puts "\t#{paragraph.
|
81
|
+
puts "\t#{paragraph.delete("\n")}"
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
@@ -105,7 +105,7 @@ module ReVIEW
|
|
105
105
|
list_header(id, caption, lang)
|
106
106
|
end
|
107
107
|
rescue KeyError
|
108
|
-
|
108
|
+
app_error "no such list: #{id}"
|
109
109
|
end
|
110
110
|
puts "◆→終了:#{@titles['list']}←◆"
|
111
111
|
blank
|
@@ -178,7 +178,7 @@ module ReVIEW
|
|
178
178
|
list_header(id, caption, lang)
|
179
179
|
end
|
180
180
|
rescue KeyError
|
181
|
-
|
181
|
+
app_error "no such list: #{id}"
|
182
182
|
end
|
183
183
|
puts "◆→終了:#{@titles['list']}←◆"
|
184
184
|
blank
|
@@ -202,7 +202,7 @@ module ReVIEW
|
|
202
202
|
if @chapter.image_bound?(id)
|
203
203
|
puts "◆→#{@chapter.image(id).path}#{metrics}←◆"
|
204
204
|
else
|
205
|
-
warn "image not bound: #{id}"
|
205
|
+
warn "image not bound: #{id}", location: location
|
206
206
|
lines.each do |line|
|
207
207
|
puts line
|
208
208
|
end
|
@@ -228,15 +228,12 @@ module ReVIEW
|
|
228
228
|
puts "◆→開始:#{@titles['texequation']}←◆"
|
229
229
|
texequation_header(id, caption) if caption_top?('equation')
|
230
230
|
|
231
|
-
if @book.config['imgmath'
|
231
|
+
if @book.config['math_format'] == 'imgmath'
|
232
232
|
fontsize = @book.config['imgmath_options']['fontsize'].to_f
|
233
233
|
lineheight = @book.config['imgmath_options']['lineheight'].to_f
|
234
234
|
math_str = "\\begin{equation*}\n\\fontsize{#{fontsize}}{#{lineheight}}\\selectfont\n#{lines.join("\n")}\n\\end{equation*}\n"
|
235
235
|
key = Digest::SHA256.hexdigest(math_str)
|
236
|
-
|
237
|
-
Dir.mkdir(math_dir) unless Dir.exist?(math_dir)
|
238
|
-
img_path = File.join(math_dir, "_gen_#{key}.#{@book.config['imgmath_options']['format']}")
|
239
|
-
defer_math_image(math_str, img_path, key)
|
236
|
+
img_path = @img_math.defer_math_image(math_str, key)
|
240
237
|
puts "◆→math:#{File.basename(img_path)}←◆"
|
241
238
|
else
|
242
239
|
puts lines.join("\n")
|
@@ -274,6 +271,7 @@ module ReVIEW
|
|
274
271
|
|
275
272
|
def comment(lines, comment = nil)
|
276
273
|
return unless @book.config['draft']
|
274
|
+
|
277
275
|
lines ||= []
|
278
276
|
unless comment.blank?
|
279
277
|
lines.unshift(comment)
|
@@ -289,7 +287,25 @@ module ReVIEW
|
|
289
287
|
def inline_fn(id)
|
290
288
|
"【注#{@chapter.footnote(id).number}】"
|
291
289
|
rescue KeyError
|
292
|
-
|
290
|
+
app_error "unknown footnote: #{id}"
|
291
|
+
end
|
292
|
+
|
293
|
+
def inline_endnote(id)
|
294
|
+
"【後注#{@chapter.endnote(id).number}】"
|
295
|
+
rescue KeyError
|
296
|
+
app_error "unknown endnote: #{id}"
|
297
|
+
end
|
298
|
+
|
299
|
+
def endnote_begin
|
300
|
+
puts '◆→開始:後注←◆'
|
301
|
+
end
|
302
|
+
|
303
|
+
def endnote_end
|
304
|
+
puts '◆→終了:後注←◆'
|
305
|
+
end
|
306
|
+
|
307
|
+
def endnote_item(id)
|
308
|
+
puts "【後注#{@chapter.endnote(id).number}】#{compile_inline(@chapter.endnote(id).content)}"
|
293
309
|
end
|
294
310
|
|
295
311
|
def compile_ruby(base, ruby)
|
@@ -367,11 +383,23 @@ module ReVIEW
|
|
367
383
|
"@#{str}@◆→@〜@部分に下線←◆"
|
368
384
|
end
|
369
385
|
|
386
|
+
def inline_ins(str)
|
387
|
+
"◆→開始:挿入表現←◆#{str}◆→終了:挿入表現←◆"
|
388
|
+
end
|
389
|
+
|
390
|
+
def inline_del(str)
|
391
|
+
"◆→開始:削除表現←◆#{str}◆→終了:削除表現←◆"
|
392
|
+
end
|
393
|
+
|
394
|
+
def inline_tcy(str)
|
395
|
+
"◆→開始:回転←◆#{str}◆→終了:縦回転←◆"
|
396
|
+
end
|
397
|
+
|
370
398
|
def inline_icon(id)
|
371
399
|
begin
|
372
400
|
"◆→画像 #{@chapter.image(id).path.sub(%r{\A\./}, '')}←◆"
|
373
401
|
rescue
|
374
|
-
warn "image not bound: #{id}"
|
402
|
+
warn "image not bound: #{id}", location: location
|
375
403
|
"◆→画像 #{id}←◆"
|
376
404
|
end
|
377
405
|
end
|
@@ -397,13 +425,10 @@ module ReVIEW
|
|
397
425
|
end
|
398
426
|
|
399
427
|
def inline_m(str)
|
400
|
-
if @book.config['imgmath'
|
428
|
+
if @book.config['math_format'] == 'imgmath'
|
401
429
|
math_str = '$' + str + '$'
|
402
430
|
key = Digest::SHA256.hexdigest(str)
|
403
|
-
|
404
|
-
Dir.mkdir(math_dir) unless Dir.exist?(math_dir)
|
405
|
-
img_path = File.join(math_dir, "_gen_#{key}.#{@book.config['imgmath_options']['format']}")
|
406
|
-
defer_math_image(math_str, img_path, key)
|
431
|
+
img_path = @img_math.defer_math_image(math_str, key)
|
407
432
|
%Q(◆→TeX式ここから←◆◆→math:#{File.basename(img_path)}←◆◆→TeX式ここまで←◆)
|
408
433
|
else
|
409
434
|
%Q(◆→TeX式ここから←◆#{str}◆→TeX式ここまで←◆)
|
@@ -418,7 +443,7 @@ module ReVIEW
|
|
418
443
|
def inline_bib(id)
|
419
444
|
%Q([#{@chapter.bibpaper(id).number}])
|
420
445
|
rescue KeyError
|
421
|
-
|
446
|
+
app_error "unknown bib: #{id}"
|
422
447
|
end
|
423
448
|
|
424
449
|
def noindent
|
@@ -480,7 +505,7 @@ module ReVIEW
|
|
480
505
|
begin
|
481
506
|
puts "◆→画像 #{@chapter.image(id).path.sub(%r{\A\./}, '')}#{metrics}←◆"
|
482
507
|
rescue
|
483
|
-
warn "image not bound: #{id}"
|
508
|
+
warn "image not bound: #{id}", location: location
|
484
509
|
puts "◆→画像 #{id}←◆"
|
485
510
|
end
|
486
511
|
if !caption_top?('image') && caption.present?
|
data/lib/review/update.rb
CHANGED
@@ -301,6 +301,7 @@ module ReVIEW
|
|
301
301
|
if !config['htmlversion'].present? || config['htmlversion'].to_f >= HTML_VERSION.to_f
|
302
302
|
next
|
303
303
|
end
|
304
|
+
|
304
305
|
if confirm("%s: Update '%s' to '%s' from '%s'?", [File.basename(yml), 'htmlversion', HTML_VERSION, config['htmlversion']])
|
305
306
|
rewrite_yml(yml, 'htmlversion', HTML_VERSION)
|
306
307
|
end
|
@@ -313,6 +314,7 @@ module ReVIEW
|
|
313
314
|
if !config['chapter_quote'].present? || config['chapter_quote'].scan('%s').size != 1
|
314
315
|
next
|
315
316
|
end
|
317
|
+
|
316
318
|
v = config['chapter_quote'].sub('%s', '%s %s')
|
317
319
|
if confirm("%s: 'chapter_quote' now takes 2 values. Update '%s' to '%s'?", [File.basename(yml), config['chapter_quote'], v])
|
318
320
|
rewrite_yml(yml, 'chapter_quote', v)
|
@@ -414,9 +416,7 @@ module ReVIEW
|
|
414
416
|
opts << "paper=#{v.sub('j', '').sub('paper', '')}"
|
415
417
|
when /[\d.]+ptj/ # not cared...
|
416
418
|
opts << "fontsize=#{v.sub('j', '')}"
|
417
|
-
when /[\d.]+pt/
|
418
|
-
opts << "fontsize=#{v}"
|
419
|
-
when /[\d.]+Q/
|
419
|
+
when /[\d.]+pt/, /[\d.]+Q/
|
420
420
|
opts << "fontsize=#{v}"
|
421
421
|
when 'landscape', 'oneside', 'twoside', 'vartwoside', 'onecolumn',
|
422
422
|
'twocolumn', 'titlepage', 'notitlepage', 'openright',
|
@@ -442,9 +442,7 @@ module ReVIEW
|
|
442
442
|
opts << "paper=#{v.sub('j', '').sub('paper', '')}"
|
443
443
|
when /[\d.]+ptj/ # not cared...
|
444
444
|
opts << "fontsize=#{v.sub('j', '')}"
|
445
|
-
when /[\d.]+pt/
|
446
|
-
opts << "fontsize=#{v}"
|
447
|
-
when /[\d.]+Q/
|
445
|
+
when /[\d.]+pt/, /[\d.]+Q/
|
448
446
|
opts << "fontsize=#{v}"
|
449
447
|
when 'landscape', 'oneside', 'twoside', 'onecolumn', 'twocolumn', 'titlepage', 'notitlepage', 'openright', 'openany', 'leqno', 'fleqn', 'draft', 'final', 'report'
|
450
448
|
# pass-through
|
@@ -516,6 +514,7 @@ module ReVIEW
|
|
516
514
|
if !config['texcommand'] || config['texcommand'] !~ /\s+-/
|
517
515
|
next
|
518
516
|
end
|
517
|
+
|
519
518
|
# option should be moved to texoptions
|
520
519
|
cmd, opts = config['texcommand'].split(/\s+-/, 2)
|
521
520
|
opts = "-#{opts}"
|
data/lib/review/version.rb
CHANGED