review 4.2.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby-win.yml +11 -5
- data/.rubocop.yml +113 -24
- data/NEWS.ja.md +94 -0
- data/NEWS.md +94 -0
- data/bin/review-catalog-converter +1 -1
- data/bin/review-check +2 -4
- data/bin/review-checkdep +1 -1
- data/bin/review-compile +8 -14
- data/bin/review-validate +1 -1
- data/doc/config.yml.sample +4 -1
- data/doc/config.yml.sample-simple +1 -1
- data/doc/format.ja.md +83 -4
- data/doc/format.md +84 -7
- data/doc/makeindex.ja.md +2 -2
- data/doc/quickstart.ja.md +3 -3
- data/doc/quickstart.md +2 -2
- data/lib/epubmaker/content.rb +3 -2
- data/lib/epubmaker/epubcommon.rb +33 -25
- data/lib/epubmaker/epubv2.rb +5 -6
- data/lib/epubmaker/epubv3.rb +20 -18
- data/lib/review/book.rb +2 -2
- data/lib/review/book/base.rb +61 -25
- data/lib/review/book/bib.rb +21 -0
- data/lib/review/book/book_unit.rb +155 -0
- data/lib/review/book/chapter.rb +30 -26
- data/lib/review/book/index.rb +23 -185
- data/lib/review/book/index/item.rb +7 -1
- data/lib/review/book/part.rb +21 -9
- data/lib/review/book/volume.rb +1 -1
- data/lib/review/builder.rb +68 -13
- data/lib/review/catalog.rb +2 -2
- data/lib/review/compiler.rb +159 -73
- data/lib/review/configure.rb +22 -1
- data/lib/review/converter.rb +1 -1
- data/lib/review/epub2html.rb +6 -1
- data/lib/review/epubmaker.rb +12 -23
- data/lib/review/htmlbuilder.rb +36 -7
- data/lib/review/htmlutils.rb +7 -10
- data/lib/review/i18n.rb +1 -1
- data/lib/review/idgxmlbuilder.rb +51 -6
- data/lib/review/idgxmlmaker.rb +9 -14
- data/lib/review/index_builder.rb +653 -0
- data/lib/review/init.rb +5 -13
- data/lib/review/latexbuilder.rb +65 -4
- data/lib/review/logger.rb +2 -2
- data/lib/review/makerhelper.rb +11 -0
- data/lib/review/markdownbuilder.rb +19 -1
- data/lib/review/pdfmaker.rb +17 -36
- data/lib/review/plaintextbuilder.rb +48 -2
- data/lib/review/preprocessor.rb +5 -5
- data/lib/review/rstbuilder.rb +25 -6
- data/lib/review/sec_counter.rb +13 -0
- data/lib/review/textmaker.rb +4 -12
- data/lib/review/tocprinter.rb +2 -3
- data/lib/review/topbuilder.rb +26 -0
- data/lib/review/update.rb +7 -7
- data/lib/review/version.rb +1 -1
- data/lib/review/volumeprinter.rb +2 -3
- data/lib/review/webmaker.rb +9 -20
- data/review.gemspec +2 -2
- data/samples/sample-book/src/config.yml +1 -1
- data/samples/syntax-book/Gemfile +1 -1
- data/samples/syntax-book/config.yml +1 -1
- data/templates/latex/config.erb +27 -23
- data/templates/latex/review-jlreq/README.md +3 -1
- data/templates/latex/review-jlreq/review-base.sty +31 -15
- data/templates/latex/review-jlreq/review-jlreq.cls +8 -24
- data/templates/latex/review-jsbook/README.md +7 -5
- data/templates/latex/review-jsbook/review-base.sty +34 -16
- data/templates/latex/review-jsbook/review-jsbook.cls +4 -2
- data/templates/web/html/layout-html5.html.erb +1 -1
- data/test/assets/test_template.tex +3 -3
- data/test/assets/test_template_backmatter.tex +3 -3
- data/test/book_test_helper.rb +11 -5
- data/test/test_book.rb +54 -63
- data/test/test_book_chapter.rb +93 -52
- data/test/test_builder.rb +24 -15
- data/test/test_converter.rb +1 -0
- data/test/test_epub3maker.rb +2 -2
- data/test/test_epubmaker.rb +8 -0
- data/test/test_helper.rb +4 -1
- data/test/test_htmlbuilder.rb +627 -56
- data/test/test_htmlutils.rb +0 -12
- data/test/test_i18n.rb +33 -33
- data/test/test_idgxmlbuilder.rb +358 -11
- data/test/test_idgxmlmaker_cmd.rb +1 -1
- data/test/test_index.rb +62 -52
- data/test/test_indexbuilder.rb +52 -0
- data/test/test_latexbuilder.rb +547 -10
- data/test/test_latexbuilder_v2.rb +43 -5
- data/test/test_logger.rb +7 -7
- data/test/test_makerhelper.rb +0 -12
- data/test/test_markdownbuilder.rb +3 -0
- data/test/test_pdfmaker.rb +13 -12
- data/test/test_pdfmaker_cmd.rb +1 -1
- data/test/test_plaintextbuilder.rb +422 -7
- data/test/test_review_ext.rb +2 -1
- data/test/test_rstbuilder.rb +25 -1
- data/test/test_sec_counter.rb +156 -0
- data/test/test_textmaker_cmd.rb +1 -1
- data/test/test_topbuilder.rb +187 -10
- data/test/test_update.rb +10 -10
- data/test/test_webtocprinter.rb +12 -12
- 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/Makefile +3 -2
- data/vendor/jsclasses/create_archive.sh +5 -5
- data/vendor/jsclasses/jis/Makefile +3 -2
- data/vendor/jsclasses/jis/jsarticle.cls +22 -18
- data/vendor/jsclasses/jis/jsbook.cls +22 -18
- data/vendor/jsclasses/jis/jsclasses.dtx +94 -13
- data/vendor/jsclasses/jis/jsclasses.ins +15 -5
- data/vendor/jsclasses/jis/jslogo.ins +9 -0
- data/vendor/jsclasses/jis/jslogo.sty +1 -13
- data/vendor/jsclasses/jis/jspf.cls +22 -18
- data/vendor/jsclasses/jis/jsreport.cls +22 -18
- data/vendor/jsclasses/jis/jsverb.ins +9 -0
- data/vendor/jsclasses/jis/jsverb.sty +1 -13
- data/vendor/jsclasses/jis/kiyou.cls +22 -18
- data/vendor/jsclasses/jis/minijs.sty +65 -22
- data/vendor/jsclasses/jis/okumacro.ins +9 -0
- data/vendor/jsclasses/jis/okumacro.sty +1 -13
- 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 +22 -18
- data/vendor/jsclasses/jsbook.cls +22 -18
- data/vendor/jsclasses/jsclasses.dtx +94 -13
- data/vendor/jsclasses/jsclasses.ins +15 -5
- data/vendor/jsclasses/jsclasses.pdf +0 -0
- data/vendor/jsclasses/jslogo.ins +9 -0
- data/vendor/jsclasses/jslogo.pdf +0 -0
- data/vendor/jsclasses/jslogo.sty +1 -13
- data/vendor/jsclasses/jspf.cls +22 -18
- data/vendor/jsclasses/jsreport.cls +22 -18
- 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 +22 -18
- data/vendor/jsclasses/minijs.sty +68 -22
- data/vendor/jsclasses/okumacro.ins +9 -0
- data/vendor/jsclasses/okumacro.pdf +0 -0
- data/vendor/jsclasses/okumacro.sty +1 -13
- 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 +14 -6
- data/.rubocop_todo.yml +0 -7
- data/lib/review/book/compilable.rb +0 -174
data/lib/review/book/part.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2009-
|
|
1
|
+
# Copyright (c) 2009-2020 Minero Aoki, Kenshi Muto, Masayoshi Takahashi
|
|
2
2
|
# 2002-2008 Minero Aoki
|
|
3
3
|
#
|
|
4
4
|
# This program is free software.
|
|
@@ -6,13 +6,11 @@
|
|
|
6
6
|
# the GNU LGPL, Lesser General Public License version 2.1.
|
|
7
7
|
# For details of the GNU LGPL, see the file "COPYING".
|
|
8
8
|
#
|
|
9
|
-
require 'review/book/
|
|
9
|
+
require 'review/book/book_unit'
|
|
10
10
|
|
|
11
11
|
module ReVIEW
|
|
12
12
|
module Book
|
|
13
|
-
class Part
|
|
14
|
-
include Compilable
|
|
15
|
-
|
|
13
|
+
class Part < BookUnit
|
|
16
14
|
def self.mkpart_from_namelistfile(book, path)
|
|
17
15
|
chaps = []
|
|
18
16
|
File.read(path, mode: 'rt:BOM|utf-8').split.each_with_index do |name, number|
|
|
@@ -30,7 +28,7 @@ module ReVIEW
|
|
|
30
28
|
end
|
|
31
29
|
|
|
32
30
|
def self.mkpart(chaps)
|
|
33
|
-
chaps.empty? ? nil : Part.new(
|
|
31
|
+
chaps.empty? ? nil : Part.new(chaps[0].book, nil, chaps)
|
|
34
32
|
end
|
|
35
33
|
|
|
36
34
|
# if Part is dummy, `number` is nil.
|
|
@@ -38,15 +36,16 @@ module ReVIEW
|
|
|
38
36
|
def initialize(book, number, chapters, name = '', io = nil)
|
|
39
37
|
@book = book
|
|
40
38
|
@number = number
|
|
41
|
-
@chapters = chapters
|
|
42
39
|
@name = name
|
|
40
|
+
@chapters = chapters
|
|
43
41
|
@path = name
|
|
44
|
-
@content = ''
|
|
45
42
|
if io
|
|
46
43
|
@content = io.read
|
|
47
44
|
elsif @path.present? && File.exist?(File.join(@book.config['contentdir'], @path))
|
|
48
45
|
@content = File.read(File.join(@book.config['contentdir'], @path), mode: 'rt:BOM|utf-8')
|
|
49
|
-
@name = File.basename(
|
|
46
|
+
@name = File.basename(name, '.re')
|
|
47
|
+
else
|
|
48
|
+
@content = ''
|
|
50
49
|
end
|
|
51
50
|
if file?
|
|
52
51
|
@title = nil
|
|
@@ -54,6 +53,19 @@ module ReVIEW
|
|
|
54
53
|
@title = name
|
|
55
54
|
end
|
|
56
55
|
@volume = nil
|
|
56
|
+
|
|
57
|
+
super()
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def generate_indexes
|
|
61
|
+
super
|
|
62
|
+
|
|
63
|
+
return unless content
|
|
64
|
+
|
|
65
|
+
@numberless_image_index = @indexes.numberless_image_index
|
|
66
|
+
@image_index = @indexes.image_index
|
|
67
|
+
@icon_index = @indexes.icon_index
|
|
68
|
+
@indepimage_index = @indexes.indepimage_index
|
|
57
69
|
end
|
|
58
70
|
|
|
59
71
|
attr_reader :number
|
data/lib/review/book/volume.rb
CHANGED
data/lib/review/builder.rb
CHANGED
|
@@ -11,7 +11,6 @@ require 'review/textutils'
|
|
|
11
11
|
require 'review/compiler'
|
|
12
12
|
require 'review/sec_counter'
|
|
13
13
|
require 'stringio'
|
|
14
|
-
require 'cgi'
|
|
15
14
|
require 'fileutils'
|
|
16
15
|
require 'tempfile'
|
|
17
16
|
require 'csv'
|
|
@@ -20,7 +19,7 @@ module ReVIEW
|
|
|
20
19
|
class Builder
|
|
21
20
|
include TextUtils
|
|
22
21
|
|
|
23
|
-
CAPTION_TITLES =
|
|
22
|
+
CAPTION_TITLES = Compiler.minicolumn_names
|
|
24
23
|
|
|
25
24
|
def pre_paragraph
|
|
26
25
|
nil
|
|
@@ -30,21 +29,17 @@ module ReVIEW
|
|
|
30
29
|
nil
|
|
31
30
|
end
|
|
32
31
|
|
|
33
|
-
attr_accessor :doc_status
|
|
32
|
+
attr_accessor :doc_status, :previous_list_type
|
|
34
33
|
|
|
35
|
-
def initialize(strict = false, *
|
|
34
|
+
def initialize(strict = false, *_args)
|
|
36
35
|
@strict = strict
|
|
37
36
|
@output = nil
|
|
38
37
|
@logger = ReVIEW.logger
|
|
39
38
|
@doc_status = {}
|
|
40
39
|
@dictionary = {}
|
|
41
|
-
|
|
40
|
+
@previous_list_type = nil
|
|
42
41
|
end
|
|
43
42
|
|
|
44
|
-
def builder_init(*args)
|
|
45
|
-
end
|
|
46
|
-
private :builder_init
|
|
47
|
-
|
|
48
43
|
def bind(compiler, chapter, location)
|
|
49
44
|
@compiler = compiler
|
|
50
45
|
@chapter = chapter
|
|
@@ -53,6 +48,10 @@ module ReVIEW
|
|
|
53
48
|
if @chapter.present?
|
|
54
49
|
@book = @chapter.book
|
|
55
50
|
end
|
|
51
|
+
@chapter.generate_indexes
|
|
52
|
+
if @book
|
|
53
|
+
@book.generate_indexes
|
|
54
|
+
end
|
|
56
55
|
@tabwidth = nil
|
|
57
56
|
@tsize = nil
|
|
58
57
|
if @book && @book.config
|
|
@@ -84,6 +83,7 @@ module ReVIEW
|
|
|
84
83
|
|
|
85
84
|
def builder_init_file
|
|
86
85
|
@sec_counter = SecCounter.new(5, @chapter)
|
|
86
|
+
@doc_status = {}
|
|
87
87
|
end
|
|
88
88
|
private :builder_init_file
|
|
89
89
|
|
|
@@ -91,8 +91,19 @@ module ReVIEW
|
|
|
91
91
|
false
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
+
def solve_nest(s)
|
|
95
|
+
check_nest
|
|
96
|
+
s.gsub(/\x01→.+?←\x01/, '')
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def check_nest
|
|
100
|
+
if @children && !@children.empty?
|
|
101
|
+
error "//beginchild of #{@children.reverse.join(',')} misses //endchild"
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
94
105
|
def result
|
|
95
|
-
@output.string
|
|
106
|
+
solve_nest(@output.string)
|
|
96
107
|
end
|
|
97
108
|
|
|
98
109
|
alias_method :raw_result, :result
|
|
@@ -211,7 +222,7 @@ module ReVIEW
|
|
|
211
222
|
sepidx = nil
|
|
212
223
|
rows = []
|
|
213
224
|
lines.each_with_index do |line, idx|
|
|
214
|
-
if /\A[
|
|
225
|
+
if /\A[=\-]{12}/ =~ line || /\A[={\-}]{12}/ =~ line
|
|
215
226
|
sepidx ||= idx
|
|
216
227
|
next
|
|
217
228
|
end
|
|
@@ -240,7 +251,7 @@ module ReVIEW
|
|
|
240
251
|
|
|
241
252
|
def adjust_n_cols(rows)
|
|
242
253
|
rows.each do |cols|
|
|
243
|
-
while cols.last
|
|
254
|
+
while cols.last && cols.last.strip.empty?
|
|
244
255
|
cols.pop
|
|
245
256
|
end
|
|
246
257
|
end
|
|
@@ -544,9 +555,36 @@ module ReVIEW
|
|
|
544
555
|
CAPTION_TITLES.each do |name|
|
|
545
556
|
class_eval %Q(
|
|
546
557
|
def #{name}(lines, caption = nil)
|
|
558
|
+
check_nested_minicolumn
|
|
547
559
|
captionblock("#{name}", lines, caption)
|
|
548
560
|
end
|
|
549
|
-
|
|
561
|
+
|
|
562
|
+
def #{name}_begin(caption = nil)
|
|
563
|
+
check_nested_minicolumn
|
|
564
|
+
@doc_status[:minicolumn] = '#{name}'
|
|
565
|
+
if caption
|
|
566
|
+
puts compile_inline(caption)
|
|
567
|
+
end
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
def #{name}_end
|
|
571
|
+
@doc_status[:minicolumn] = nil
|
|
572
|
+
end
|
|
573
|
+
), __FILE__, __LINE__ - 17
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
def check_nested_minicolumn
|
|
577
|
+
if @doc_status[:minicolumn]
|
|
578
|
+
error "#{@location}: nested mini-column is not allowed"
|
|
579
|
+
end
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
def in_minicolumn?
|
|
583
|
+
@doc_status[:minicolumn]
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
def minicolumn_block_name?(name)
|
|
587
|
+
CAPTION_TITLES.include?(name)
|
|
550
588
|
end
|
|
551
589
|
|
|
552
590
|
def graph(lines, id, command, caption = '')
|
|
@@ -687,6 +725,23 @@ EOTGNUPLOT
|
|
|
687
725
|
str
|
|
688
726
|
end
|
|
689
727
|
|
|
728
|
+
def beginchild
|
|
729
|
+
@children ||= []
|
|
730
|
+
unless @previous_list_type
|
|
731
|
+
error "//beginchild is shown, but previous element isn't ul, ol, or dl"
|
|
732
|
+
end
|
|
733
|
+
puts "\x01→#{@previous_list_type}←\x01"
|
|
734
|
+
@children.push(@previous_list_type)
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
def endchild
|
|
738
|
+
if @children.nil? || @children.empty?
|
|
739
|
+
error "//endchild is shown, but any opened //beginchild doesn't exist"
|
|
740
|
+
else
|
|
741
|
+
puts "\x01→/#{@children.pop}←\x01"
|
|
742
|
+
end
|
|
743
|
+
end
|
|
744
|
+
|
|
690
745
|
def caption_top?(type)
|
|
691
746
|
unless %w[top bottom].include?(@book.config['caption_position'][type])
|
|
692
747
|
warn("invalid caption_position/#{type} parameter. 'top' is assumed")
|
data/lib/review/catalog.rb
CHANGED
|
@@ -41,7 +41,7 @@ module ReVIEW
|
|
|
41
41
|
|
|
42
42
|
def replace_part(old_name, new_name)
|
|
43
43
|
@yaml['CHAPS'].map! do |e|
|
|
44
|
-
if e.is_a?(Hash)
|
|
44
|
+
if e.is_a?(Hash) && (e.keys.first == old_name)
|
|
45
45
|
e = { new_name => e.values.first }
|
|
46
46
|
end
|
|
47
47
|
e
|
|
@@ -89,7 +89,7 @@ module ReVIEW
|
|
|
89
89
|
filenames.concat(postdef)
|
|
90
90
|
end
|
|
91
91
|
filenames.each do |filename|
|
|
92
|
-
refile = File.join(
|
|
92
|
+
refile = File.expand_path(File.join(config['contentdir'], filename), basedir)
|
|
93
93
|
unless File.exist?(refile)
|
|
94
94
|
raise FileNotFound, "file not found in catalog.yml: #{refile}"
|
|
95
95
|
end
|
data/lib/review/compiler.rb
CHANGED
|
@@ -14,8 +14,8 @@ require 'strscan'
|
|
|
14
14
|
|
|
15
15
|
module ReVIEW
|
|
16
16
|
class Compiler
|
|
17
|
-
def initialize(
|
|
18
|
-
@
|
|
17
|
+
def initialize(builder)
|
|
18
|
+
@builder = builder
|
|
19
19
|
|
|
20
20
|
## commands which do not parse block lines in compiler
|
|
21
21
|
@non_parsed_commands = %i[embed texequation graph]
|
|
@@ -24,10 +24,15 @@ module ReVIEW
|
|
|
24
24
|
@command_name_stack = []
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
attr_reader :
|
|
27
|
+
attr_reader :builder, :previous_list_type
|
|
28
|
+
|
|
29
|
+
def strategy
|
|
30
|
+
error 'Compiler#strategy is obsoleted. Use Compiler#builder.'
|
|
31
|
+
@builder
|
|
32
|
+
end
|
|
28
33
|
|
|
29
34
|
def non_escaped_commands
|
|
30
|
-
if @
|
|
35
|
+
if @builder.highlight?
|
|
31
36
|
%i[list emlist listnum emlistnum cmd]
|
|
32
37
|
else
|
|
33
38
|
[]
|
|
@@ -37,7 +42,7 @@ module ReVIEW
|
|
|
37
42
|
def compile(chap)
|
|
38
43
|
@chapter = chap
|
|
39
44
|
do_compile
|
|
40
|
-
@
|
|
45
|
+
@builder.result
|
|
41
46
|
end
|
|
42
47
|
|
|
43
48
|
class SyntaxElement
|
|
@@ -68,12 +73,16 @@ module ReVIEW
|
|
|
68
73
|
end
|
|
69
74
|
end
|
|
70
75
|
|
|
76
|
+
def minicolumn?
|
|
77
|
+
@type == :minicolumn
|
|
78
|
+
end
|
|
79
|
+
|
|
71
80
|
def block_required?
|
|
72
|
-
@type == :block
|
|
81
|
+
@type == :block or @type == :minicolumn
|
|
73
82
|
end
|
|
74
83
|
|
|
75
84
|
def block_allowed?
|
|
76
|
-
@type == :block or @type == :optional
|
|
85
|
+
@type == :block or @type == :optional or @type == :minicolumn
|
|
77
86
|
end
|
|
78
87
|
end
|
|
79
88
|
|
|
@@ -83,6 +92,10 @@ module ReVIEW
|
|
|
83
92
|
defsyntax(name, (optional ? :optional : :block), argc, &block)
|
|
84
93
|
end
|
|
85
94
|
|
|
95
|
+
def self.defminicolumn(name, argc, _optional = false, &block)
|
|
96
|
+
defsyntax(name, :minicolumn, argc, &block)
|
|
97
|
+
end
|
|
98
|
+
|
|
86
99
|
def self.defsingle(name, argc, &block)
|
|
87
100
|
defsyntax(name, :line, argc, &block)
|
|
88
101
|
end
|
|
@@ -95,6 +108,16 @@ module ReVIEW
|
|
|
95
108
|
INLINE[name] = InlineSyntaxElement.new(name)
|
|
96
109
|
end
|
|
97
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
|
+
|
|
98
121
|
def syntax_defined?(name)
|
|
99
122
|
SYNTAX.key?(name.to_sym)
|
|
100
123
|
end
|
|
@@ -143,18 +166,19 @@ module ReVIEW
|
|
|
143
166
|
defblock :bpo, 0
|
|
144
167
|
defblock :flushright, 0
|
|
145
168
|
defblock :centering, 0
|
|
146
|
-
defblock :note, 0..1
|
|
147
|
-
defblock :memo, 0..1
|
|
148
|
-
defblock :info, 0..1
|
|
149
|
-
defblock :important, 0..1
|
|
150
|
-
defblock :caution, 0..1
|
|
151
|
-
defblock :notice, 0..1
|
|
152
|
-
defblock :warning, 0..1
|
|
153
|
-
defblock :tip, 0..1
|
|
154
169
|
defblock :box, 0..1
|
|
155
170
|
defblock :comment, 0..1, true
|
|
156
171
|
defblock :embed, 0..1
|
|
157
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
|
+
|
|
158
182
|
defsingle :footnote, 2
|
|
159
183
|
defsingle :noindent, 0
|
|
160
184
|
defsingle :blankline, 0
|
|
@@ -167,6 +191,8 @@ module ReVIEW
|
|
|
167
191
|
defsingle :include, 1
|
|
168
192
|
defsingle :olnum, 1
|
|
169
193
|
defsingle :firstlinenum, 1
|
|
194
|
+
defsingle :beginchild, 0
|
|
195
|
+
defsingle :endchild, 0
|
|
170
196
|
|
|
171
197
|
definline :chapref
|
|
172
198
|
definline :chap
|
|
@@ -231,39 +257,62 @@ module ReVIEW
|
|
|
231
257
|
|
|
232
258
|
def do_compile
|
|
233
259
|
f = LineInput.new(StringIO.new(@chapter.content))
|
|
234
|
-
@
|
|
260
|
+
@builder.bind(self, @chapter, Location.new(@chapter.basename, f))
|
|
261
|
+
|
|
262
|
+
## in minicolumn, such as note/info/alert...
|
|
263
|
+
@minicolumn_name = nil
|
|
235
264
|
|
|
236
265
|
tagged_section_init
|
|
237
266
|
while f.next?
|
|
238
267
|
case f.peek
|
|
239
268
|
when /\A\#@/
|
|
240
269
|
f.gets # Nothing to do
|
|
241
|
-
when /\A=+[\[\s
|
|
270
|
+
when /\A=+[\[\s{]/
|
|
242
271
|
compile_headline(f.gets)
|
|
272
|
+
@builder.previous_list_type = nil
|
|
243
273
|
when /\A\s+\*/
|
|
244
274
|
compile_ulist(f)
|
|
275
|
+
@builder.previous_list_type = 'ul'
|
|
245
276
|
when /\A\s+\d+\./
|
|
246
277
|
compile_olist(f)
|
|
278
|
+
@builder.previous_list_type = 'ol'
|
|
247
279
|
when /\A\s+:\s/
|
|
248
280
|
compile_dlist(f)
|
|
281
|
+
@builder.previous_list_type = 'dl'
|
|
249
282
|
when /\A\s*:\s/
|
|
250
283
|
warn 'Definition list starting with `:` is deprecated. It should start with ` : `.'
|
|
251
284
|
compile_dlist(f)
|
|
285
|
+
@builder.previous_list_type = 'dl'
|
|
252
286
|
when %r{\A//\}}
|
|
253
|
-
|
|
254
|
-
|
|
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
|
|
255
294
|
when %r{\A//[a-z]+}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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)
|
|
262
313
|
@command_name_stack.pop
|
|
263
|
-
next
|
|
264
314
|
end
|
|
265
|
-
|
|
266
|
-
@command_name_stack.pop
|
|
315
|
+
@builder.previous_list_type = nil
|
|
267
316
|
when %r{\A//}
|
|
268
317
|
line = f.gets
|
|
269
318
|
warn "`//' seen but is not valid command: #{line.strip.inspect}"
|
|
@@ -271,17 +320,46 @@ module ReVIEW
|
|
|
271
320
|
warn 'skipping block...'
|
|
272
321
|
read_block(f, false)
|
|
273
322
|
end
|
|
323
|
+
@builder.previous_list_type = nil
|
|
274
324
|
else
|
|
275
325
|
if f.peek.strip.empty?
|
|
276
326
|
f.gets
|
|
277
327
|
next
|
|
278
328
|
end
|
|
279
329
|
compile_paragraph(f)
|
|
330
|
+
@builder.previous_list_type = nil
|
|
280
331
|
end
|
|
281
332
|
end
|
|
282
333
|
close_all_tagged_section
|
|
283
334
|
end
|
|
284
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
|
+
|
|
285
363
|
def compile_headline(line)
|
|
286
364
|
@headline_indexs ||= [@chapter.number.to_i - 1]
|
|
287
365
|
m = /\A(=+)(?:\[(.+?)\])?(?:\{(.+?)\})?(.*)/.match(line)
|
|
@@ -317,18 +395,18 @@ module ReVIEW
|
|
|
317
395
|
end
|
|
318
396
|
@headline_indexs[index] += 1
|
|
319
397
|
close_current_tagged_section(level)
|
|
320
|
-
@
|
|
398
|
+
@builder.headline(level, label, caption)
|
|
321
399
|
end
|
|
322
400
|
end
|
|
323
401
|
|
|
324
402
|
def close_current_tagged_section(level)
|
|
325
|
-
while @tagged_section.last
|
|
403
|
+
while @tagged_section.last && (@tagged_section.last[1] >= level)
|
|
326
404
|
close_tagged_section(* @tagged_section.pop)
|
|
327
405
|
end
|
|
328
406
|
end
|
|
329
407
|
|
|
330
408
|
def headline(level, label, caption)
|
|
331
|
-
@
|
|
409
|
+
@builder.headline(level, label, caption)
|
|
332
410
|
end
|
|
333
411
|
|
|
334
412
|
def tagged_section_init
|
|
@@ -337,21 +415,21 @@ module ReVIEW
|
|
|
337
415
|
|
|
338
416
|
def open_tagged_section(tag, level, label, caption)
|
|
339
417
|
mid = "#{tag}_begin"
|
|
340
|
-
unless @
|
|
341
|
-
error "
|
|
418
|
+
unless @builder.respond_to?(mid)
|
|
419
|
+
error "builder does not support tagged section: #{tag}"
|
|
342
420
|
headline(level, label, caption)
|
|
343
421
|
return
|
|
344
422
|
end
|
|
345
423
|
@tagged_section.push([tag, level])
|
|
346
|
-
@
|
|
424
|
+
@builder.__send__(mid, level, label, caption)
|
|
347
425
|
end
|
|
348
426
|
|
|
349
427
|
def close_tagged_section(tag, level)
|
|
350
428
|
mid = "#{tag}_end"
|
|
351
|
-
if @
|
|
352
|
-
@
|
|
429
|
+
if @builder.respond_to?(mid)
|
|
430
|
+
@builder.__send__(mid, level)
|
|
353
431
|
else
|
|
354
|
-
error "
|
|
432
|
+
error "builder does not support block op: #{mid}"
|
|
355
433
|
end
|
|
356
434
|
end
|
|
357
435
|
|
|
@@ -374,38 +452,38 @@ module ReVIEW
|
|
|
374
452
|
line =~ /\A\s+(\*+)/
|
|
375
453
|
current_level = $1.size
|
|
376
454
|
if level == current_level
|
|
377
|
-
@
|
|
455
|
+
@builder.ul_item_end
|
|
378
456
|
# body
|
|
379
|
-
@
|
|
457
|
+
@builder.ul_item_begin(buf)
|
|
380
458
|
elsif level < current_level # down
|
|
381
459
|
level_diff = current_level - level
|
|
382
460
|
if level_diff != 1
|
|
383
461
|
error 'too many *.'
|
|
384
462
|
end
|
|
385
463
|
level = current_level
|
|
386
|
-
@
|
|
387
|
-
@
|
|
464
|
+
@builder.ul_begin { level }
|
|
465
|
+
@builder.ul_item_begin(buf)
|
|
388
466
|
elsif level > current_level # up
|
|
389
467
|
level_diff = level - current_level
|
|
390
468
|
level = current_level
|
|
391
469
|
(1..level_diff).to_a.reverse_each do |i|
|
|
392
|
-
@
|
|
393
|
-
@
|
|
470
|
+
@builder.ul_item_end
|
|
471
|
+
@builder.ul_end { level + i }
|
|
394
472
|
end
|
|
395
|
-
@
|
|
473
|
+
@builder.ul_item_end
|
|
396
474
|
# body
|
|
397
|
-
@
|
|
475
|
+
@builder.ul_item_begin(buf)
|
|
398
476
|
end
|
|
399
477
|
end
|
|
400
478
|
|
|
401
479
|
(1..level).to_a.reverse_each do |i|
|
|
402
|
-
@
|
|
403
|
-
@
|
|
480
|
+
@builder.ul_item_end
|
|
481
|
+
@builder.ul_end { i }
|
|
404
482
|
end
|
|
405
483
|
end
|
|
406
484
|
|
|
407
485
|
def compile_olist(f)
|
|
408
|
-
@
|
|
486
|
+
@builder.ol_begin
|
|
409
487
|
f.while_match(/\A\s+\d+\.|\A\#@/) do |line|
|
|
410
488
|
next if line =~ /\A\#@/
|
|
411
489
|
|
|
@@ -414,24 +492,24 @@ module ReVIEW
|
|
|
414
492
|
f.while_match(/\A\s+(?!\d+\.)\S/) do |cont|
|
|
415
493
|
buf.push(text(cont.strip))
|
|
416
494
|
end
|
|
417
|
-
@
|
|
495
|
+
@builder.ol_item(buf, num)
|
|
418
496
|
end
|
|
419
|
-
@
|
|
497
|
+
@builder.ol_end
|
|
420
498
|
end
|
|
421
499
|
|
|
422
500
|
def compile_dlist(f)
|
|
423
|
-
@
|
|
501
|
+
@builder.dl_begin
|
|
424
502
|
while /\A\s*:/ =~ f.peek
|
|
425
503
|
# defer compile_inline to handle footnotes
|
|
426
|
-
@
|
|
427
|
-
@
|
|
428
|
-
@
|
|
504
|
+
@builder.doc_status[:dt] = true
|
|
505
|
+
@builder.dt(text(f.gets.sub(/\A\s*:/, '').strip))
|
|
506
|
+
@builder.doc_status[:dt] = nil
|
|
429
507
|
desc = f.break(/\A(\S|\s*:|\s+\d+\.\s|\s+\*\s)/).map { |line| text(line.strip) }
|
|
430
|
-
@
|
|
508
|
+
@builder.dd(desc)
|
|
431
509
|
f.skip_blank_lines
|
|
432
510
|
f.skip_comment_lines
|
|
433
511
|
end
|
|
434
|
-
@
|
|
512
|
+
@builder.dl_end
|
|
435
513
|
end
|
|
436
514
|
|
|
437
515
|
def compile_paragraph(f)
|
|
@@ -440,7 +518,7 @@ module ReVIEW
|
|
|
440
518
|
break if line.strip.empty?
|
|
441
519
|
buf.push(text(line.sub(/^(\t+)\s*/) { |m| '<!ESCAPETAB!>' * m.size }.strip.gsub('<!ESCAPETAB!>', "\t")))
|
|
442
520
|
end
|
|
443
|
-
@
|
|
521
|
+
@builder.paragraph(buf)
|
|
444
522
|
end
|
|
445
523
|
|
|
446
524
|
def read_command(f)
|
|
@@ -449,9 +527,9 @@ module ReVIEW
|
|
|
449
527
|
ignore_inline = @non_parsed_commands.include?(name)
|
|
450
528
|
@command_name_stack.push(name)
|
|
451
529
|
args = parse_args(line.sub(%r{\A//[a-z]+}, '').rstrip.chomp('{'), name)
|
|
452
|
-
@
|
|
530
|
+
@builder.doc_status[name] = true
|
|
453
531
|
lines = block_open?(line) ? read_block(f, ignore_inline) : nil
|
|
454
|
-
@
|
|
532
|
+
@builder.doc_status[name] = nil
|
|
455
533
|
[name, args, lines]
|
|
456
534
|
end
|
|
457
535
|
|
|
@@ -496,8 +574,8 @@ module ReVIEW
|
|
|
496
574
|
end
|
|
497
575
|
|
|
498
576
|
def compile_command(syntax, args, lines)
|
|
499
|
-
unless @
|
|
500
|
-
error "
|
|
577
|
+
unless @builder.respond_to?(syntax.name)
|
|
578
|
+
error "builder does not support command: //#{syntax.name}"
|
|
501
579
|
compile_unknown_command(args, lines)
|
|
502
580
|
return
|
|
503
581
|
end
|
|
@@ -518,11 +596,11 @@ module ReVIEW
|
|
|
518
596
|
end
|
|
519
597
|
|
|
520
598
|
def compile_unknown_command(args, lines)
|
|
521
|
-
@
|
|
599
|
+
@builder.unknown_command(args, lines)
|
|
522
600
|
end
|
|
523
601
|
|
|
524
602
|
def compile_block(syntax, args, lines)
|
|
525
|
-
@
|
|
603
|
+
@builder.__send__(syntax.name, (lines || default_block(syntax)), *args)
|
|
526
604
|
end
|
|
527
605
|
|
|
528
606
|
def default_block(syntax)
|
|
@@ -533,7 +611,7 @@ module ReVIEW
|
|
|
533
611
|
end
|
|
534
612
|
|
|
535
613
|
def compile_single(syntax, args)
|
|
536
|
-
@
|
|
614
|
+
@builder.__send__(syntax.name, *args)
|
|
537
615
|
end
|
|
538
616
|
|
|
539
617
|
def replace_fence(str)
|
|
@@ -559,7 +637,7 @@ module ReVIEW
|
|
|
559
637
|
|
|
560
638
|
def text(str, block_mode = false)
|
|
561
639
|
return '' if str.empty?
|
|
562
|
-
words = replace_fence(str).split(/(@<\w+>\{(?:[
|
|
640
|
+
words = replace_fence(str).split(/(@<\w+>\{(?:[^}\\]|\\.)*?\})/, -1)
|
|
563
641
|
words.each do |w|
|
|
564
642
|
if w.scan(/@<\w+>/).size > 1 && !/\A@<raw>/.match(w)
|
|
565
643
|
error "`@<xxx>' seen but is not valid inline op: #{w}"
|
|
@@ -570,7 +648,7 @@ module ReVIEW
|
|
|
570
648
|
if in_non_escaped_command? && block_mode
|
|
571
649
|
result << revert_replace_fence(words.shift)
|
|
572
650
|
else
|
|
573
|
-
result << @
|
|
651
|
+
result << @builder.nofunc_text(revert_replace_fence(words.shift))
|
|
574
652
|
end
|
|
575
653
|
break if words.empty?
|
|
576
654
|
result << compile_inline(revert_replace_fence(words.shift.gsub(/\\\}/, '}').gsub(/\\\\/, '\\')))
|
|
@@ -579,28 +657,36 @@ module ReVIEW
|
|
|
579
657
|
rescue => e
|
|
580
658
|
error e.message
|
|
581
659
|
end
|
|
582
|
-
public :text # called from
|
|
660
|
+
public :text # called from builder
|
|
583
661
|
|
|
584
662
|
def compile_inline(str)
|
|
585
663
|
op, arg = /\A@<(\w+)>\{(.*?)\}\z/.match(str).captures
|
|
586
664
|
unless inline_defined?(op)
|
|
587
665
|
raise CompileError, "no such inline op: #{op}"
|
|
588
666
|
end
|
|
589
|
-
unless @
|
|
590
|
-
raise "
|
|
667
|
+
unless @builder.respond_to?("inline_#{op}")
|
|
668
|
+
raise "builder does not support inline op: @<#{op}>"
|
|
591
669
|
end
|
|
592
|
-
@
|
|
670
|
+
@builder.__send__("inline_#{op}", arg)
|
|
593
671
|
rescue => e
|
|
594
672
|
error e.message
|
|
595
|
-
@
|
|
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)
|
|
596
682
|
end
|
|
597
683
|
|
|
598
684
|
def warn(msg)
|
|
599
|
-
@
|
|
685
|
+
@builder.warn msg
|
|
600
686
|
end
|
|
601
687
|
|
|
602
688
|
def error(msg)
|
|
603
|
-
@
|
|
689
|
+
@builder.error msg
|
|
604
690
|
end
|
|
605
691
|
end
|
|
606
692
|
end # module ReVIEW
|