review 3.1.0 → 5.0.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-win.yml +45 -0
- data/.github/workflows/ruby.yml +27 -0
- data/.rubocop.yml +161 -34
- data/.travis.yml +16 -15
- data/Dockerfile +21 -5
- data/NEWS.ja.md +394 -0
- data/NEWS.md +395 -1
- data/README.md +10 -7
- data/appveyor.yml +1 -3
- data/bin/review-catalog-converter +5 -5
- data/bin/review-check +10 -12
- data/bin/review-checkdep +2 -2
- data/bin/review-compile +17 -23
- data/bin/review-epubmaker +3 -35
- data/bin/review-idgxmlmaker +16 -0
- data/bin/review-index +2 -89
- data/bin/review-preproc +13 -13
- data/bin/review-validate +4 -4
- data/bin/review-vol +4 -78
- data/doc/config.yml.sample +47 -12
- data/doc/config.yml.sample-simple +3 -2
- data/doc/format.ja.md +120 -17
- data/doc/format.md +119 -27
- data/doc/makeindex.ja.md +2 -2
- data/doc/pdfmaker.ja.md +43 -1
- data/doc/pdfmaker.md +42 -1
- data/doc/quickstart.ja.md +45 -25
- data/doc/quickstart.md +37 -16
- data/lib/epubmaker/content.rb +3 -2
- data/lib/epubmaker/epubcommon.rb +34 -27
- data/lib/epubmaker/epubv2.rb +5 -6
- data/lib/epubmaker/epubv3.rb +21 -18
- data/lib/epubmaker/producer.rb +2 -1
- data/lib/review/book.rb +2 -2
- data/lib/review/book/base.rb +91 -96
- data/lib/review/book/bib.rb +21 -0
- data/lib/review/book/book_unit.rb +155 -0
- data/lib/review/book/chapter.rb +48 -29
- data/lib/review/book/index.rb +46 -240
- data/lib/review/book/index/item.rb +46 -0
- data/lib/review/book/page_metric.rb +7 -7
- data/lib/review/book/part.rb +45 -10
- data/lib/review/book/volume.rb +4 -5
- data/lib/review/builder.rb +172 -56
- data/lib/review/catalog.rb +14 -17
- data/lib/review/compiler.rb +219 -121
- data/lib/review/configure.rb +39 -7
- data/lib/review/converter.rb +1 -1
- data/lib/review/epub2html.rb +43 -5
- data/lib/review/epubmaker.rb +69 -27
- data/lib/review/extentions/string.rb +0 -4
- data/lib/review/htmlbuilder.rb +112 -101
- data/lib/review/htmlutils.rb +9 -13
- data/lib/review/i18n.rb +3 -3
- data/lib/review/idgxmlbuilder.rb +202 -78
- data/lib/review/idgxmlmaker.rb +186 -0
- data/lib/review/index_builder.rb +653 -0
- data/lib/review/init-web/finish.html +10 -0
- data/lib/review/init-web/index.html +190 -0
- data/lib/review/init-web/review-layout-design.js +691 -0
- data/lib/review/init.rb +129 -46
- data/lib/review/latexbuilder.rb +255 -92
- data/lib/review/lineinput.rb +1 -1
- data/lib/review/location.rb +32 -0
- data/lib/review/logger.rb +4 -8
- data/lib/review/makerhelper.rb +35 -5
- data/lib/review/markdownbuilder.rb +50 -38
- data/lib/review/md2inaobuilder.rb +3 -5
- data/lib/review/pdfmaker.rb +60 -57
- data/lib/review/plaintextbuilder.rb +154 -87
- data/lib/review/preprocessor.rb +20 -42
- data/lib/review/rstbuilder.rb +57 -38
- data/lib/review/sec_counter.rb +13 -0
- data/lib/review/textmaker.rb +23 -15
- data/lib/review/textutils.rb +76 -2
- data/lib/review/tocprinter.rb +230 -102
- data/lib/review/topbuilder.rb +139 -60
- data/lib/review/update.rb +24 -24
- data/lib/review/version.rb +1 -1
- data/lib/review/volumeprinter.rb +98 -0
- data/lib/review/webmaker.rb +20 -24
- data/lib/review/webtocprinter.rb +38 -35
- data/lib/review/yamlloader.rb +26 -16
- data/review.gemspec +6 -4
- data/samples/sample-book/README.md +7 -2
- data/samples/sample-book/src/.gitignore +154 -0
- data/samples/sample-book/src/config-ebook.yml +4 -0
- data/samples/sample-book/src/config-jlreq-ebook.yml +4 -0
- data/samples/sample-book/src/config-jlreq.yml +6 -0
- data/samples/sample-book/src/config.yml +2 -2
- data/samples/sample-book/src/lib/tasks/review.rake +29 -14
- data/samples/sample-book/src/lib/tasks/z01_copy_sty.rake +14 -8
- data/samples/syntax-book/Gemfile +1 -1
- data/samples/syntax-book/ch01.re +4 -2
- data/samples/syntax-book/ch02.re +8 -16
- data/samples/syntax-book/ch03.re +3 -6
- data/samples/syntax-book/config-jlreq-lualatex.yml +4 -0
- data/samples/syntax-book/config-jlreq.yml +5 -0
- data/samples/syntax-book/config-print.yml +3 -0
- data/samples/syntax-book/config.yml +1 -1
- data/samples/syntax-book/lib/tasks/review.rake +30 -15
- data/samples/syntax-book/lib/tasks/z01_copy_sty.rake +14 -8
- data/templates/latex/config.erb +39 -25
- data/templates/latex/layout.tex.erb +1 -0
- data/templates/latex/review-jlreq/README.md +3 -1
- data/templates/latex/review-jlreq/review-base.sty +161 -50
- data/templates/latex/review-jlreq/review-jlreq.cls +21 -22
- data/templates/latex/review-jlreq/review-style.sty +4 -1
- data/templates/latex/review-jsbook/README.md +46 -5
- data/templates/latex/review-jsbook/review-base.sty +123 -35
- data/templates/latex/review-jsbook/review-jsbook.cls +10 -4
- data/templates/latex/review-jsbook/review-style.sty +5 -2
- data/templates/opf/epubv3.opf.erb +1 -0
- data/templates/web/html/layout-html5.html.erb +3 -3
- data/test/assets/test_template.tex +19 -7
- data/test/assets/test_template_backmatter.tex +19 -7
- data/test/book_test_helper.rb +11 -5
- data/test/test_book.rb +124 -79
- data/test/test_book_chapter.rb +97 -54
- data/test/test_book_part.rb +3 -3
- data/test/test_builder.rb +38 -13
- data/test/test_catalog.rb +24 -42
- data/test/test_catalog_converter_cmd.rb +1 -1
- data/test/test_converter.rb +1 -0
- data/test/test_epub3maker.rb +2 -2
- data/test/test_epubmaker.rb +8 -0
- data/test/test_epubmaker_cmd.rb +14 -7
- data/test/test_helper.rb +18 -7
- data/test/test_htmlbuilder.rb +1491 -205
- data/test/test_htmlutils.rb +0 -12
- data/test/test_i18n.rb +37 -37
- data/test/test_idgxmlbuilder.rb +744 -42
- data/test/test_idgxmlmaker_cmd.rb +46 -0
- data/test/test_image_finder.rb +52 -70
- data/test/test_index.rb +94 -44
- data/test/test_indexbuilder.rb +52 -0
- data/test/test_latexbuilder.rb +1784 -161
- data/test/test_latexbuilder_v2.rb +671 -102
- data/test/test_logger.rb +17 -4
- data/test/test_makerhelper.rb +2 -14
- data/test/test_markdownbuilder.rb +137 -16
- data/test/test_md2inaobuilder.rb +32 -9
- data/test/test_pdfmaker.rb +30 -12
- data/test/test_pdfmaker_cmd.rb +100 -6
- data/test/test_plaintextbuilder.rb +791 -30
- data/test/test_preprocessor.rb +2 -16
- data/test/test_review_ext.rb +2 -1
- data/test/test_rstbuilder.rb +274 -27
- data/test/test_sec_counter.rb +156 -0
- data/test/test_textmaker_cmd.rb +54 -0
- data/test/test_textutils.rb +109 -2
- data/test/test_topbuilder.rb +724 -34
- data/test/test_update.rb +20 -11
- data/test/test_webtocprinter.rb +75 -43
- data/test/test_yamlloader.rb +13 -0
- data/vendor/gentombow/LICENSE +1 -1
- data/vendor/gentombow/Makefile +0 -1
- data/vendor/gentombow/bounddvi-en.pdf +0 -0
- data/vendor/gentombow/bounddvi-en.tex +1 -0
- data/vendor/gentombow/bounddvi.pdf +0 -0
- data/vendor/gentombow/bounddvi.sty +30 -7
- data/vendor/gentombow/bounddvi.tex +1 -0
- data/vendor/gentombow/create_archive.sh +1 -0
- data/vendor/gentombow/gentombow-ja.pdf +0 -0
- data/vendor/gentombow/gentombow-ja.tex +9 -0
- data/vendor/gentombow/gentombow.pdf +0 -0
- data/vendor/gentombow/gentombow.sty +32 -10
- data/vendor/gentombow/gentombow.tex +8 -0
- data/vendor/gentombow/tests/gentombow-01-pdfx.tex +8 -0
- data/vendor/gentombow/tests/gentombow-02-pdfx.tex +8 -0
- data/vendor/jsclasses/LICENSE +1 -1
- data/vendor/jsclasses/Makefile +3 -2
- data/vendor/jsclasses/create_archive.sh +5 -5
- data/vendor/jsclasses/jis/Makefile +3 -2
- data/vendor/jsclasses/jis/jsarticle.cls +74 -31
- data/vendor/jsclasses/jis/jsbook.cls +74 -31
- data/vendor/jsclasses/jis/jsclasses.dtx +176 -36
- data/vendor/jsclasses/jis/jsclasses.ins +15 -5
- data/vendor/jsclasses/jis/jslogo.dtx +4 -4
- data/vendor/jsclasses/jis/jslogo.ins +9 -0
- data/vendor/jsclasses/jis/jslogo.sty +4 -16
- data/vendor/jsclasses/jis/jspf.cls +73 -30
- data/vendor/jsclasses/jis/jsreport.cls +74 -31
- data/vendor/jsclasses/jis/jsverb.ins +9 -0
- data/vendor/jsclasses/jis/jsverb.sty +1 -13
- data/vendor/jsclasses/jis/kiyou.cls +74 -31
- data/vendor/jsclasses/jis/minijs.sty +65 -22
- data/vendor/jsclasses/jis/okumacro.dtx +4 -5
- data/vendor/jsclasses/jis/okumacro.ins +9 -0
- data/vendor/jsclasses/jis/okumacro.sty +4 -17
- data/vendor/jsclasses/jis/okuverb.ins +9 -0
- data/vendor/jsclasses/jis/okuverb.sty +1 -13
- data/vendor/jsclasses/jis/winjis.sty +23 -19
- data/vendor/jsclasses/jsarticle.cls +74 -31
- data/vendor/jsclasses/jsbook.cls +74 -31
- data/vendor/jsclasses/jsclasses.dtx +176 -36
- data/vendor/jsclasses/jsclasses.ins +15 -5
- data/vendor/jsclasses/jsclasses.pdf +0 -0
- data/vendor/jsclasses/jslogo.dtx +4 -4
- data/vendor/jsclasses/jslogo.ins +9 -0
- data/vendor/jsclasses/jslogo.pdf +0 -0
- data/vendor/jsclasses/jslogo.sty +4 -16
- data/vendor/jsclasses/jspf.cls +73 -30
- data/vendor/jsclasses/jsreport.cls +74 -31
- data/vendor/jsclasses/jsverb.ins +9 -0
- data/vendor/jsclasses/jsverb.pdf +0 -0
- data/vendor/jsclasses/jsverb.sty +1 -13
- data/vendor/jsclasses/kiyou.cls +74 -31
- data/vendor/jsclasses/minijs.sty +68 -22
- data/vendor/jsclasses/okumacro.dtx +4 -5
- data/vendor/jsclasses/okumacro.ins +9 -0
- data/vendor/jsclasses/okumacro.pdf +0 -0
- data/vendor/jsclasses/okumacro.sty +4 -17
- data/vendor/jsclasses/okuverb.ins +9 -0
- data/vendor/jsclasses/okuverb.pdf +0 -0
- data/vendor/jsclasses/okuverb.sty +1 -13
- data/vendor/jsclasses/tests/relfont.tex +10 -0
- data/vendor/jsclasses/winjis.sty +23 -19
- metadata +65 -12
- data/.rubocop_todo.yml +0 -7
- data/lib/review/book/compilable.rb +0 -173
- data/lib/review/tocparser.rb +0 -271
- data/samples/syntax-book/review-ext.rb +0 -14
- data/test/test_tocparser.rb +0 -25
data/lib/review/catalog.rb
CHANGED
@@ -3,8 +3,8 @@ require 'yaml'
|
|
3
3
|
module ReVIEW
|
4
4
|
class Catalog
|
5
5
|
def initialize(file)
|
6
|
-
if file.respond_to?
|
7
|
-
@yaml = YAML.
|
6
|
+
if file.respond_to?(:read)
|
7
|
+
@yaml = YAML.safe_load(file.read, [Date])
|
8
8
|
else ## as Object
|
9
9
|
@yaml = file
|
10
10
|
end
|
@@ -12,12 +12,11 @@ module ReVIEW
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def predef
|
15
|
-
|
16
|
-
@yaml['PREDEF'].join("\n")
|
15
|
+
@yaml['PREDEF'] || []
|
17
16
|
end
|
18
17
|
|
19
18
|
def chaps
|
20
|
-
return
|
19
|
+
return [] unless @yaml['CHAPS']
|
21
20
|
|
22
21
|
@yaml['CHAPS'].map do |entry|
|
23
22
|
if entry.is_a?(String)
|
@@ -25,11 +24,11 @@ module ReVIEW
|
|
25
24
|
elsif entry.is_a?(Hash)
|
26
25
|
entry.values # chaps in a part
|
27
26
|
end
|
28
|
-
end.flatten
|
27
|
+
end.flatten
|
29
28
|
end
|
30
29
|
|
31
30
|
def parts
|
32
|
-
return
|
31
|
+
return [] unless @yaml['CHAPS']
|
33
32
|
|
34
33
|
part_list = @yaml['CHAPS'].map do |entry|
|
35
34
|
if entry.is_a?(Hash)
|
@@ -37,12 +36,12 @@ module ReVIEW
|
|
37
36
|
end
|
38
37
|
end
|
39
38
|
|
40
|
-
part_list.flatten.compact
|
39
|
+
part_list.flatten.compact
|
41
40
|
end
|
42
41
|
|
43
42
|
def replace_part(old_name, new_name)
|
44
43
|
@yaml['CHAPS'].map! do |e|
|
45
|
-
if e.is_a?(Hash)
|
44
|
+
if e.is_a?(Hash) && (e.keys.first == old_name)
|
46
45
|
e = { new_name => e.values.first }
|
47
46
|
end
|
48
47
|
e
|
@@ -55,13 +54,11 @@ module ReVIEW
|
|
55
54
|
end
|
56
55
|
|
57
56
|
def appendix
|
58
|
-
|
59
|
-
@yaml['APPENDIX'].join("\n")
|
57
|
+
@yaml['APPENDIX'] || []
|
60
58
|
end
|
61
59
|
|
62
60
|
def postdef
|
63
|
-
|
64
|
-
@yaml['POSTDEF'].join("\n")
|
61
|
+
@yaml['POSTDEF'] || []
|
65
62
|
end
|
66
63
|
|
67
64
|
def to_s
|
@@ -71,7 +68,7 @@ module ReVIEW
|
|
71
68
|
def validate!(config, basedir)
|
72
69
|
filenames = []
|
73
70
|
if predef.present?
|
74
|
-
filenames.concat(predef
|
71
|
+
filenames.concat(predef)
|
75
72
|
end
|
76
73
|
parts_with_chaps.each do |chap|
|
77
74
|
if chap.is_a?(Hash)
|
@@ -86,13 +83,13 @@ module ReVIEW
|
|
86
83
|
end
|
87
84
|
end
|
88
85
|
if appendix.present?
|
89
|
-
filenames.concat(appendix
|
86
|
+
filenames.concat(appendix)
|
90
87
|
end
|
91
88
|
if postdef.present?
|
92
|
-
filenames.concat(postdef
|
89
|
+
filenames.concat(postdef)
|
93
90
|
end
|
94
91
|
filenames.each do |filename|
|
95
|
-
refile = File.join(
|
92
|
+
refile = File.expand_path(File.join(config['contentdir'], filename), basedir)
|
96
93
|
unless File.exist?(refile)
|
97
94
|
raise FileNotFound, "file not found in catalog.yml: #{refile}"
|
98
95
|
end
|
data/lib/review/compiler.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2009-
|
1
|
+
# Copyright (c) 2009-2020 Minero Aoki, Kenshi Muto
|
2
2
|
# Copyright (c) 2002-2007 Minero Aoki
|
3
3
|
#
|
4
4
|
# This program is free software.
|
@@ -9,43 +9,40 @@
|
|
9
9
|
require 'review/extentions'
|
10
10
|
require 'review/preprocessor'
|
11
11
|
require 'review/exception'
|
12
|
+
require 'review/location'
|
12
13
|
require 'strscan'
|
13
14
|
|
14
15
|
module ReVIEW
|
15
|
-
class
|
16
|
-
def initialize(
|
17
|
-
@
|
18
|
-
@f = f
|
19
|
-
end
|
16
|
+
class Compiler
|
17
|
+
def initialize(builder)
|
18
|
+
@builder = builder
|
20
19
|
|
21
|
-
|
20
|
+
## commands which do not parse block lines in compiler
|
21
|
+
@non_parsed_commands = %i[embed texequation graph]
|
22
22
|
|
23
|
-
|
24
|
-
@
|
23
|
+
## to decide escaping/non-escaping for text
|
24
|
+
@command_name_stack = []
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
begin
|
29
|
-
"#{@filename}:#{@f.lineno}"
|
30
|
-
rescue
|
31
|
-
"#{@filename}:nil"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
alias_method :to_s, :string
|
36
|
-
end
|
27
|
+
attr_reader :builder, :previous_list_type
|
37
28
|
|
38
|
-
|
39
|
-
|
40
|
-
@
|
29
|
+
def strategy
|
30
|
+
error 'Compiler#strategy is obsoleted. Use Compiler#builder.'
|
31
|
+
@builder
|
41
32
|
end
|
42
33
|
|
43
|
-
|
34
|
+
def non_escaped_commands
|
35
|
+
if @builder.highlight?
|
36
|
+
%i[list emlist listnum emlistnum cmd]
|
37
|
+
else
|
38
|
+
[]
|
39
|
+
end
|
40
|
+
end
|
44
41
|
|
45
42
|
def compile(chap)
|
46
43
|
@chapter = chap
|
47
44
|
do_compile
|
48
|
-
@
|
45
|
+
@builder.result
|
49
46
|
end
|
50
47
|
|
51
48
|
class SyntaxElement
|
@@ -76,23 +73,31 @@ module ReVIEW
|
|
76
73
|
end
|
77
74
|
end
|
78
75
|
|
76
|
+
def minicolumn?
|
77
|
+
@type == :minicolumn
|
78
|
+
end
|
79
|
+
|
79
80
|
def block_required?
|
80
|
-
@type == :block
|
81
|
+
@type == :block or @type == :minicolumn
|
81
82
|
end
|
82
83
|
|
83
84
|
def block_allowed?
|
84
|
-
@type == :block or @type == :optional
|
85
|
+
@type == :block or @type == :optional or @type == :minicolumn
|
85
86
|
end
|
86
87
|
end
|
87
88
|
|
88
89
|
SYNTAX = {}
|
89
90
|
|
90
91
|
def self.defblock(name, argc, optional = false, &block)
|
91
|
-
defsyntax
|
92
|
+
defsyntax(name, (optional ? :optional : :block), argc, &block)
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.defminicolumn(name, argc, _optional = false, &block)
|
96
|
+
defsyntax(name, :minicolumn, argc, &block)
|
92
97
|
end
|
93
98
|
|
94
99
|
def self.defsingle(name, argc, &block)
|
95
|
-
defsyntax
|
100
|
+
defsyntax(name, :line, argc, &block)
|
96
101
|
end
|
97
102
|
|
98
103
|
def self.defsyntax(name, type, argc, &block)
|
@@ -103,6 +108,16 @@ module ReVIEW
|
|
103
108
|
INLINE[name] = InlineSyntaxElement.new(name)
|
104
109
|
end
|
105
110
|
|
111
|
+
def self.minicolumn_names
|
112
|
+
buf = []
|
113
|
+
SYNTAX.each do |name, syntax|
|
114
|
+
if syntax.minicolumn?
|
115
|
+
buf << name.to_s
|
116
|
+
end
|
117
|
+
end
|
118
|
+
buf
|
119
|
+
end
|
120
|
+
|
106
121
|
def syntax_defined?(name)
|
107
122
|
SYNTAX.key?(name.to_sym)
|
108
123
|
end
|
@@ -131,7 +146,7 @@ module ReVIEW
|
|
131
146
|
defblock :emlist, 0..2
|
132
147
|
defblock :cmd, 0..1
|
133
148
|
defblock :table, 0..2
|
134
|
-
defblock :imgtable, 0..
|
149
|
+
defblock :imgtable, 0..3
|
135
150
|
defblock :emtable, 0..1
|
136
151
|
defblock :quote, 0
|
137
152
|
defblock :image, 2..3, true
|
@@ -151,18 +166,19 @@ module ReVIEW
|
|
151
166
|
defblock :bpo, 0
|
152
167
|
defblock :flushright, 0
|
153
168
|
defblock :centering, 0
|
154
|
-
defblock :note, 0..1
|
155
|
-
defblock :memo, 0..1
|
156
|
-
defblock :info, 0..1
|
157
|
-
defblock :important, 0..1
|
158
|
-
defblock :caution, 0..1
|
159
|
-
defblock :notice, 0..1
|
160
|
-
defblock :warning, 0..1
|
161
|
-
defblock :tip, 0..1
|
162
169
|
defblock :box, 0..1
|
163
170
|
defblock :comment, 0..1, true
|
164
171
|
defblock :embed, 0..1
|
165
172
|
|
173
|
+
defminicolumn :note, 0..1
|
174
|
+
defminicolumn :memo, 0..1
|
175
|
+
defminicolumn :tip, 0..1
|
176
|
+
defminicolumn :info, 0..1
|
177
|
+
defminicolumn :warning, 0..1
|
178
|
+
defminicolumn :important, 0..1
|
179
|
+
defminicolumn :caution, 0..1
|
180
|
+
defminicolumn :notice, 0..1
|
181
|
+
|
166
182
|
defsingle :footnote, 2
|
167
183
|
defsingle :noindent, 0
|
168
184
|
defsingle :blankline, 0
|
@@ -175,6 +191,8 @@ module ReVIEW
|
|
175
191
|
defsingle :include, 1
|
176
192
|
defsingle :olnum, 1
|
177
193
|
defsingle :firstlinenum, 1
|
194
|
+
defsingle :beginchild, 0
|
195
|
+
defsingle :endchild, 0
|
178
196
|
|
179
197
|
definline :chapref
|
180
198
|
definline :chap
|
@@ -239,32 +257,62 @@ module ReVIEW
|
|
239
257
|
|
240
258
|
def do_compile
|
241
259
|
f = LineInput.new(StringIO.new(@chapter.content))
|
242
|
-
@
|
260
|
+
@builder.bind(self, @chapter, Location.new(@chapter.basename, f))
|
261
|
+
|
262
|
+
## in minicolumn, such as note/info/alert...
|
263
|
+
@minicolumn_name = nil
|
264
|
+
|
243
265
|
tagged_section_init
|
244
266
|
while f.next?
|
245
267
|
case f.peek
|
246
268
|
when /\A\#@/
|
247
269
|
f.gets # Nothing to do
|
248
|
-
when /\A=+[\[\s
|
249
|
-
compile_headline
|
270
|
+
when /\A=+[\[\s{]/
|
271
|
+
compile_headline(f.gets)
|
272
|
+
@builder.previous_list_type = nil
|
250
273
|
when /\A\s+\*/
|
251
|
-
compile_ulist
|
274
|
+
compile_ulist(f)
|
275
|
+
@builder.previous_list_type = 'ul'
|
252
276
|
when /\A\s+\d+\./
|
253
|
-
compile_olist
|
277
|
+
compile_olist(f)
|
278
|
+
@builder.previous_list_type = 'ol'
|
279
|
+
when /\A\s+:\s/
|
280
|
+
compile_dlist(f)
|
281
|
+
@builder.previous_list_type = 'dl'
|
254
282
|
when /\A\s*:\s/
|
255
|
-
|
283
|
+
warn 'Definition list starting with `:` is deprecated. It should start with ` : `.'
|
284
|
+
compile_dlist(f)
|
285
|
+
@builder.previous_list_type = 'dl'
|
256
286
|
when %r{\A//\}}
|
257
|
-
|
258
|
-
|
287
|
+
if in_minicolumn?
|
288
|
+
_line = f.gets
|
289
|
+
compile_minicolumn_end
|
290
|
+
else
|
291
|
+
f.gets
|
292
|
+
error 'block end seen but not opened'
|
293
|
+
end
|
259
294
|
when %r{\A//[a-z]+}
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
295
|
+
line = f.peek
|
296
|
+
matched = line =~ %r|\A//([a-z]+)(:?\[.*\])?{\s*$|
|
297
|
+
if matched && minicolumn_block_name?($1)
|
298
|
+
line = f.gets
|
299
|
+
name = $1
|
300
|
+
args = parse_args(line.sub(%r{\A//[a-z]+}, '').rstrip.chomp('{'), name)
|
301
|
+
compile_minicolumn_begin(name, *args)
|
302
|
+
else
|
303
|
+
# @command_name_stack.push(name) ## <- move into read_command() to use name
|
304
|
+
name, args, lines = read_command(f)
|
305
|
+
syntax = syntax_descriptor(name)
|
306
|
+
unless syntax
|
307
|
+
error "unknown command: //#{name}"
|
308
|
+
compile_unknown_command(args, lines)
|
309
|
+
@command_name_stack.pop
|
310
|
+
next
|
311
|
+
end
|
312
|
+
compile_command(syntax, args, lines)
|
313
|
+
@command_name_stack.pop
|
266
314
|
end
|
267
|
-
|
315
|
+
@builder.previous_list_type = nil
|
268
316
|
when %r{\A//}
|
269
317
|
line = f.gets
|
270
318
|
warn "`//' seen but is not valid command: #{line.strip.inspect}"
|
@@ -272,17 +320,46 @@ module ReVIEW
|
|
272
320
|
warn 'skipping block...'
|
273
321
|
read_block(f, false)
|
274
322
|
end
|
323
|
+
@builder.previous_list_type = nil
|
275
324
|
else
|
276
325
|
if f.peek.strip.empty?
|
277
326
|
f.gets
|
278
327
|
next
|
279
328
|
end
|
280
|
-
compile_paragraph
|
329
|
+
compile_paragraph(f)
|
330
|
+
@builder.previous_list_type = nil
|
281
331
|
end
|
282
332
|
end
|
283
333
|
close_all_tagged_section
|
284
334
|
end
|
285
335
|
|
336
|
+
def compile_minicolumn_begin(name, caption = nil)
|
337
|
+
mid = "#{name}_begin"
|
338
|
+
unless @builder.respond_to?(mid)
|
339
|
+
error "strategy does not support minicolumn: #{name}"
|
340
|
+
end
|
341
|
+
|
342
|
+
if @minicolumn_name
|
343
|
+
error "minicolumn cannot be nested: #{name}"
|
344
|
+
return
|
345
|
+
end
|
346
|
+
@minicolumn_name = name
|
347
|
+
|
348
|
+
@builder.__send__(mid, caption)
|
349
|
+
end
|
350
|
+
|
351
|
+
def compile_minicolumn_end
|
352
|
+
unless @minicolumn_name
|
353
|
+
error "minicolumn is not used: #{name}"
|
354
|
+
return
|
355
|
+
end
|
356
|
+
name = @minicolumn_name
|
357
|
+
|
358
|
+
mid = "#{name}_end"
|
359
|
+
@builder.__send__(mid)
|
360
|
+
@minicolumn_name = nil
|
361
|
+
end
|
362
|
+
|
286
363
|
def compile_headline(line)
|
287
364
|
@headline_indexs ||= [@chapter.number.to_i - 1]
|
288
365
|
m = /\A(=+)(?:\[(.+?)\])?(?:\{(.+?)\})?(.*)/.match(line)
|
@@ -318,18 +395,18 @@ module ReVIEW
|
|
318
395
|
end
|
319
396
|
@headline_indexs[index] += 1
|
320
397
|
close_current_tagged_section(level)
|
321
|
-
@
|
398
|
+
@builder.headline(level, label, caption)
|
322
399
|
end
|
323
400
|
end
|
324
401
|
|
325
402
|
def close_current_tagged_section(level)
|
326
|
-
while @tagged_section.last
|
403
|
+
while @tagged_section.last && (@tagged_section.last[1] >= level)
|
327
404
|
close_tagged_section(* @tagged_section.pop)
|
328
405
|
end
|
329
406
|
end
|
330
407
|
|
331
408
|
def headline(level, label, caption)
|
332
|
-
@
|
409
|
+
@builder.headline(level, label, caption)
|
333
410
|
end
|
334
411
|
|
335
412
|
def tagged_section_init
|
@@ -338,21 +415,21 @@ module ReVIEW
|
|
338
415
|
|
339
416
|
def open_tagged_section(tag, level, label, caption)
|
340
417
|
mid = "#{tag}_begin"
|
341
|
-
unless @
|
342
|
-
error "
|
343
|
-
headline
|
418
|
+
unless @builder.respond_to?(mid)
|
419
|
+
error "builder does not support tagged section: #{tag}"
|
420
|
+
headline(level, label, caption)
|
344
421
|
return
|
345
422
|
end
|
346
|
-
@tagged_section.push
|
347
|
-
@
|
423
|
+
@tagged_section.push([tag, level])
|
424
|
+
@builder.__send__(mid, level, label, caption)
|
348
425
|
end
|
349
426
|
|
350
427
|
def close_tagged_section(tag, level)
|
351
428
|
mid = "#{tag}_end"
|
352
|
-
if @
|
353
|
-
@
|
429
|
+
if @builder.respond_to?(mid)
|
430
|
+
@builder.__send__(mid, level)
|
354
431
|
else
|
355
|
-
error "
|
432
|
+
error "builder does not support block op: #{mid}"
|
356
433
|
end
|
357
434
|
end
|
358
435
|
|
@@ -369,87 +446,90 @@ module ReVIEW
|
|
369
446
|
|
370
447
|
buf = [text(line.sub(/\*+/, '').strip)]
|
371
448
|
f.while_match(/\A\s+(?!\*)\S/) do |cont|
|
372
|
-
buf.push
|
449
|
+
buf.push(text(cont.strip))
|
373
450
|
end
|
374
451
|
|
375
452
|
line =~ /\A\s+(\*+)/
|
376
453
|
current_level = $1.size
|
377
454
|
if level == current_level
|
378
|
-
@
|
455
|
+
@builder.ul_item_end
|
379
456
|
# body
|
380
|
-
@
|
457
|
+
@builder.ul_item_begin(buf)
|
381
458
|
elsif level < current_level # down
|
382
459
|
level_diff = current_level - level
|
383
|
-
|
384
|
-
|
385
|
-
@strategy.ul_begin { i }
|
386
|
-
@strategy.ul_item_begin []
|
460
|
+
if level_diff != 1
|
461
|
+
error 'too many *.'
|
387
462
|
end
|
388
|
-
|
389
|
-
@
|
463
|
+
level = current_level
|
464
|
+
@builder.ul_begin { level }
|
465
|
+
@builder.ul_item_begin(buf)
|
390
466
|
elsif level > current_level # up
|
391
467
|
level_diff = level - current_level
|
392
468
|
level = current_level
|
393
469
|
(1..level_diff).to_a.reverse_each do |i|
|
394
|
-
@
|
395
|
-
@
|
470
|
+
@builder.ul_item_end
|
471
|
+
@builder.ul_end { level + i }
|
396
472
|
end
|
397
|
-
@
|
473
|
+
@builder.ul_item_end
|
398
474
|
# body
|
399
|
-
@
|
475
|
+
@builder.ul_item_begin(buf)
|
400
476
|
end
|
401
477
|
end
|
402
478
|
|
403
479
|
(1..level).to_a.reverse_each do |i|
|
404
|
-
@
|
405
|
-
@
|
480
|
+
@builder.ul_item_end
|
481
|
+
@builder.ul_end { i }
|
406
482
|
end
|
407
483
|
end
|
408
484
|
|
409
485
|
def compile_olist(f)
|
410
|
-
@
|
486
|
+
@builder.ol_begin
|
411
487
|
f.while_match(/\A\s+\d+\.|\A\#@/) do |line|
|
412
488
|
next if line =~ /\A\#@/
|
413
489
|
|
414
490
|
num = line.match(/(\d+)\./)[1]
|
415
491
|
buf = [text(line.sub(/\d+\./, '').strip)]
|
416
492
|
f.while_match(/\A\s+(?!\d+\.)\S/) do |cont|
|
417
|
-
buf.push
|
493
|
+
buf.push(text(cont.strip))
|
418
494
|
end
|
419
|
-
@
|
495
|
+
@builder.ol_item(buf, num)
|
420
496
|
end
|
421
|
-
@
|
497
|
+
@builder.ol_end
|
422
498
|
end
|
423
499
|
|
424
500
|
def compile_dlist(f)
|
425
|
-
@
|
501
|
+
@builder.dl_begin
|
426
502
|
while /\A\s*:/ =~ f.peek
|
427
|
-
|
503
|
+
# defer compile_inline to handle footnotes
|
504
|
+
@builder.doc_status[:dt] = true
|
505
|
+
@builder.dt(text(f.gets.sub(/\A\s*:/, '').strip))
|
506
|
+
@builder.doc_status[:dt] = nil
|
428
507
|
desc = f.break(/\A(\S|\s*:|\s+\d+\.\s|\s+\*\s)/).map { |line| text(line.strip) }
|
429
|
-
@
|
508
|
+
@builder.dd(desc)
|
430
509
|
f.skip_blank_lines
|
431
510
|
f.skip_comment_lines
|
432
511
|
end
|
433
|
-
@
|
512
|
+
@builder.dl_end
|
434
513
|
end
|
435
514
|
|
436
515
|
def compile_paragraph(f)
|
437
516
|
buf = []
|
438
517
|
f.until_match(%r{\A//|\A\#@}) do |line|
|
439
518
|
break if line.strip.empty?
|
440
|
-
buf.push
|
519
|
+
buf.push(text(line.sub(/^(\t+)\s*/) { |m| '<!ESCAPETAB!>' * m.size }.strip.gsub('<!ESCAPETAB!>', "\t")))
|
441
520
|
end
|
442
|
-
@
|
521
|
+
@builder.paragraph(buf)
|
443
522
|
end
|
444
523
|
|
445
524
|
def read_command(f)
|
446
525
|
line = f.gets
|
447
526
|
name = line.slice(/[a-z]+/).to_sym
|
448
|
-
ignore_inline = (name
|
527
|
+
ignore_inline = @non_parsed_commands.include?(name)
|
528
|
+
@command_name_stack.push(name)
|
449
529
|
args = parse_args(line.sub(%r{\A//[a-z]+}, '').rstrip.chomp('{'), name)
|
450
|
-
@
|
530
|
+
@builder.doc_status[name] = true
|
451
531
|
lines = block_open?(line) ? read_block(f, ignore_inline) : nil
|
452
|
-
@
|
532
|
+
@builder.doc_status[name] = nil
|
453
533
|
[name, args, lines]
|
454
534
|
end
|
455
535
|
|
@@ -462,12 +542,12 @@ module ReVIEW
|
|
462
542
|
buf = []
|
463
543
|
f.until_match(%r{\A//\}}) do |line|
|
464
544
|
if ignore_inline
|
465
|
-
buf.push
|
545
|
+
buf.push(line.chomp)
|
466
546
|
elsif line !~ /\A\#@/
|
467
|
-
buf.push
|
547
|
+
buf.push(text(line.rstrip, true))
|
468
548
|
end
|
469
549
|
end
|
470
|
-
unless
|
550
|
+
unless f.peek.to_s.start_with?('//}')
|
471
551
|
error "unexpected EOF (block begins at: #{head})"
|
472
552
|
return buf
|
473
553
|
end
|
@@ -494,33 +574,33 @@ module ReVIEW
|
|
494
574
|
end
|
495
575
|
|
496
576
|
def compile_command(syntax, args, lines)
|
497
|
-
unless @
|
498
|
-
error "
|
499
|
-
compile_unknown_command
|
577
|
+
unless @builder.respond_to?(syntax.name)
|
578
|
+
error "builder does not support command: //#{syntax.name}"
|
579
|
+
compile_unknown_command(args, lines)
|
500
580
|
return
|
501
581
|
end
|
502
582
|
begin
|
503
|
-
syntax.check_args
|
504
|
-
rescue CompileError =>
|
505
|
-
error
|
583
|
+
syntax.check_args(args)
|
584
|
+
rescue CompileError => e
|
585
|
+
error e.message
|
506
586
|
args = ['(NoArgument)'] * syntax.min_argc
|
507
587
|
end
|
508
588
|
if syntax.block_allowed?
|
509
|
-
compile_block
|
589
|
+
compile_block(syntax, args, lines)
|
510
590
|
else
|
511
591
|
if lines
|
512
592
|
error "block is not allowed for command //#{syntax.name}; ignore"
|
513
593
|
end
|
514
|
-
compile_single
|
594
|
+
compile_single(syntax, args)
|
515
595
|
end
|
516
596
|
end
|
517
597
|
|
518
598
|
def compile_unknown_command(args, lines)
|
519
|
-
@
|
599
|
+
@builder.unknown_command(args, lines)
|
520
600
|
end
|
521
601
|
|
522
602
|
def compile_block(syntax, args, lines)
|
523
|
-
@
|
603
|
+
@builder.__send__(syntax.name, (lines || default_block(syntax)), *args)
|
524
604
|
end
|
525
605
|
|
526
606
|
def default_block(syntax)
|
@@ -531,7 +611,7 @@ module ReVIEW
|
|
531
611
|
end
|
532
612
|
|
533
613
|
def compile_single(syntax, args)
|
534
|
-
@
|
614
|
+
@builder.__send__(syntax.name, *args)
|
535
615
|
end
|
536
616
|
|
537
617
|
def replace_fence(str)
|
@@ -550,45 +630,63 @@ module ReVIEW
|
|
550
630
|
str.gsub("\x01", '@').gsub("\x02", '\\').gsub("\x03", '{').gsub("\x04", '}')
|
551
631
|
end
|
552
632
|
|
553
|
-
def
|
633
|
+
def in_non_escaped_command?
|
634
|
+
current_command = @command_name_stack.last
|
635
|
+
current_command && non_escaped_commands.include?(current_command)
|
636
|
+
end
|
637
|
+
|
638
|
+
def text(str, block_mode = false)
|
554
639
|
return '' if str.empty?
|
555
|
-
words = replace_fence(str).split(/(@<\w+>\{(?:[
|
640
|
+
words = replace_fence(str).split(/(@<\w+>\{(?:[^}\\]|\\.)*?\})/, -1)
|
556
641
|
words.each do |w|
|
557
642
|
if w.scan(/@<\w+>/).size > 1 && !/\A@<raw>/.match(w)
|
558
643
|
error "`@<xxx>' seen but is not valid inline op: #{w}"
|
559
644
|
end
|
560
645
|
end
|
561
|
-
result =
|
646
|
+
result = ''
|
562
647
|
until words.empty?
|
648
|
+
if in_non_escaped_command? && block_mode
|
649
|
+
result << revert_replace_fence(words.shift)
|
650
|
+
else
|
651
|
+
result << @builder.nofunc_text(revert_replace_fence(words.shift))
|
652
|
+
end
|
653
|
+
break if words.empty?
|
563
654
|
result << compile_inline(revert_replace_fence(words.shift.gsub(/\\\}/, '}').gsub(/\\\\/, '\\')))
|
564
|
-
result << @strategy.nofunc_text(revert_replace_fence(words.shift))
|
565
655
|
end
|
566
656
|
result
|
567
|
-
rescue =>
|
568
|
-
error
|
657
|
+
rescue => e
|
658
|
+
error e.message
|
569
659
|
end
|
570
|
-
public :text # called from
|
660
|
+
public :text # called from builder
|
571
661
|
|
572
662
|
def compile_inline(str)
|
573
663
|
op, arg = /\A@<(\w+)>\{(.*?)\}\z/.match(str).captures
|
574
664
|
unless inline_defined?(op)
|
575
665
|
raise CompileError, "no such inline op: #{op}"
|
576
666
|
end
|
577
|
-
unless @
|
578
|
-
raise "
|
667
|
+
unless @builder.respond_to?("inline_#{op}")
|
668
|
+
raise "builder does not support inline op: @<#{op}>"
|
579
669
|
end
|
580
|
-
@
|
581
|
-
rescue =>
|
582
|
-
error
|
583
|
-
@
|
670
|
+
@builder.__send__("inline_#{op}", arg)
|
671
|
+
rescue => e
|
672
|
+
error e.message
|
673
|
+
@builder.nofunc_text(str)
|
674
|
+
end
|
675
|
+
|
676
|
+
def in_minicolumn?
|
677
|
+
@builder.in_minicolumn?
|
678
|
+
end
|
679
|
+
|
680
|
+
def minicolumn_block_name?(name)
|
681
|
+
@builder.minicolumn_block_name?(name)
|
584
682
|
end
|
585
683
|
|
586
684
|
def warn(msg)
|
587
|
-
@
|
685
|
+
@builder.warn msg
|
588
686
|
end
|
589
687
|
|
590
688
|
def error(msg)
|
591
|
-
@
|
689
|
+
@builder.error msg
|
592
690
|
end
|
593
691
|
end
|
594
692
|
end # module ReVIEW
|