diff --git a/.rubocop.yml b/.rubocop.yml
index a98f8c2c1..931b5ef09 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -2,6 +2,7 @@ AllCops:
Exclude:
- lib/lineinput.rb
- lib/uuid.rb
+ - lib/review/compiler.rb
DisplayCopNames: true
inherit_from: .rubocop_todo.yml
@@ -49,6 +50,10 @@ Style/OpMethod:
Style/VariableName:
Enabled: true
+# Configuration parameters: CountComments.
+Metrics/ClassLength:
+ Max: 4500
+
Style/ConditionalAssignment:
Enabled: false
diff --git a/Gemfile b/Gemfile
index 2fae854ea..20fec56ca 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,3 +3,4 @@ source 'https://rubygems.org'
# Specify your gem's dependencies in review.gemspec
gemspec
+gem "json"
diff --git a/Rakefile b/Rakefile
index bbaac0002..2983b8697 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,3 +1,5 @@
+require 'fileutils'
+
begin
require 'bundler'
Bundler::GemHelper.install_tasks
@@ -20,6 +22,11 @@ task :rubocop do
end
end
+task :kpeg do
+ FileUtils.rm_f "lib/review/compiler.rb"
+ sh "kpeg -s lib/review/review.kpeg -o lib/review/compiler.rb"
+end
+
Rake::TestTask.new("test") do |t|
t.libs << "test"
t.test_files = Dir.glob("test/**/test_*.rb")
diff --git a/bin/review-catalog-converter b/bin/review-catalog-converter-peg
similarity index 100%
rename from bin/review-catalog-converter
rename to bin/review-catalog-converter-peg
diff --git a/bin/review-check b/bin/review-check-peg
similarity index 100%
rename from bin/review-check
rename to bin/review-check-peg
diff --git a/bin/review-checkdep b/bin/review-checkdep-peg
similarity index 100%
rename from bin/review-checkdep
rename to bin/review-checkdep-peg
diff --git a/bin/review-compile b/bin/review-compile-peg
similarity index 98%
rename from bin/review-compile
rename to bin/review-compile-peg
index 6b3de8ec3..57f97a6a3 100755
--- a/bin/review-compile
+++ b/bin/review-compile-peg
@@ -107,7 +107,7 @@ def _main
exit 1
end
- begin
+## begin
loader = ReVIEW::YAMLLoader.new
if config["yaml"]
config.deep_merge!(loader.load_file(config["yaml"]))
@@ -166,11 +166,11 @@ def _main
else
raise "must not happen: #{mode}"
end
- rescue ReVIEW::ApplicationError => err
- raise if $DEBUG
- error err.message
- exit 1
- end
+# rescue ReVIEW::ApplicationError => err
+# raise if $DEBUG
+# error err.message
+# exit 1
+# end
end
def error(msg)
diff --git a/bin/review-epubmaker b/bin/review-epubmaker-peg
similarity index 100%
rename from bin/review-epubmaker
rename to bin/review-epubmaker-peg
diff --git a/bin/review-index b/bin/review-index-peg
similarity index 100%
rename from bin/review-index
rename to bin/review-index-peg
diff --git a/bin/review-init b/bin/review-init-peg
similarity index 100%
rename from bin/review-init
rename to bin/review-init-peg
diff --git a/bin/review-pdfmaker b/bin/review-pdfmaker-peg
similarity index 100%
rename from bin/review-pdfmaker
rename to bin/review-pdfmaker-peg
diff --git a/bin/review-preproc b/bin/review-preproc-peg
similarity index 100%
rename from bin/review-preproc
rename to bin/review-preproc-peg
diff --git a/bin/review-validate b/bin/review-validate-peg
similarity index 100%
rename from bin/review-validate
rename to bin/review-validate-peg
diff --git a/bin/review-vol b/bin/review-vol-peg
similarity index 100%
rename from bin/review-vol
rename to bin/review-vol-peg
diff --git a/lib/lineinput.rb b/lib/lineinput.rb
index 73932ee8c..80da99f3e 100644
--- a/lib/lineinput.rb
+++ b/lib/lineinput.rb
@@ -58,36 +58,6 @@ def next?
peek() ? true : false
end
- def skip_blank_lines
- n = 0
- while line = gets()
- unless line.strip.empty?
- ungets line
- return n
- end
- n += 1
- end
- n
- end
-
- def gets_if(re)
- line = gets()
- if not line or not (re =~ line)
- ungets line
- return nil
- end
- line
- end
-
- def gets_unless(re)
- line = gets()
- if not line or re =~ line
- ungets line
- return nil
- end
- line
- end
-
def each
while line = gets()
yield line
@@ -144,12 +114,4 @@ def until_terminator(re)
nil
end
- def getblock(term_re)
- buf = []
- until_terminator(term_re) do |line|
- buf.push line
- end
- buf
- end
-
end
diff --git a/lib/review/book/index.rb b/lib/review/book/index.rb
index 081a660d9..d62259147 100644
--- a/lib/review/book/index.rb
+++ b/lib/review/book/index.rb
@@ -92,10 +92,14 @@ def item_type
end
def number(id)
- chapter = @index.fetch(id)
- chapter.format_number
+ chapter = @index.fetch(id, nil)
+ if chapter
+ return chapter.format_number
+ else
+ return "#{I18n.t("part", chapter.number)}"
+ end
rescue # part
- "#{I18n.t("part", chapter.number)}"
+ raise "invalid number error: id:#{id}, capter:#{chapter}"
end
def title(id)
diff --git a/lib/review/builder.rb b/lib/review/builder.rb
index 7da04f0d0..57bfe2c25 100644
--- a/lib/review/builder.rb
+++ b/lib/review/builder.rb
@@ -22,6 +22,9 @@ class Builder
CAPTION_TITLES = %w(note memo tip info warning important caution notice)
+ attr_accessor :output
+ attr_accessor :ast
+
def pre_paragraph
nil
end
@@ -43,6 +46,7 @@ def bind(compiler, chapter, location)
@compiler = compiler
@chapter = chapter
@location = location
+ @ast = nil
@output = StringIO.new
@book = @chapter.book if @chapter.present?
@tabwidth = nil
@@ -64,11 +68,11 @@ def result
alias_method :raw_result, :result
def print(*s)
- @output.print(*s)
+ raise NotImplementedError, "XXX: `print` method is obsoleted. Do not use it."
end
def puts(*s)
- @output.puts(*s)
+ raise NotImplementedError, "XXX: `puts` method is obsoleted. Do not use it."
end
def target_name
@@ -83,27 +87,33 @@ def headline_prefix(level)
end
private :headline_prefix
- def list(lines, id, caption, lang = nil)
+ def list(lines, id, caption = nil, lang = nil)
+ buf = ""
begin
- list_header id, caption, lang
+ buf << list_header(id, caption, lang)
rescue KeyError
error "no such list: #{id}"
end
- list_body id, lines, lang
+ buf << list_body(id, lines, lang)
+ buf
end
- def listnum(lines, id, caption, lang = nil)
+ def listnum(lines, id, caption = nil, lang = nil)
+ buf = ""
begin
- list_header id, caption, lang
+ buf << list_header(id, caption, lang)
rescue KeyError
error "no such list: #{id}"
end
- listnum_body lines, lang
+ buf << listnum_body(lines, lang)
+ buf
end
- def source(lines, caption, lang = nil)
- source_header caption
- source_body lines, lang
+ def source(lines, caption = nil)
+ buf = ""
+ buf << source_header(caption)
+ buf << source_body(lines, lang)
+ buf
end
def image(lines, id, caption, metric = nil)
@@ -116,6 +126,7 @@ def image(lines, id, caption, metric = nil)
end
def table(lines, id = nil, caption = nil)
+ buf = ""
rows = []
sepidx = nil
lines.each_with_index do |line, idx|
@@ -130,26 +141,27 @@ def table(lines, id = nil, caption = nil)
rows = adjust_n_cols(rows)
begin
- table_header id, caption unless caption.nil?
+ buf << table_header(id, caption) unless caption.nil?
rescue KeyError
error "no such table: #{id}"
end
- return if rows.empty?
- table_begin rows.first.size
+ return buf if rows.empty?
+ buf << table_begin(rows.first.size)
if sepidx
sepidx.times do
- tr rows.shift.map {|s| th(s) }
+ buf << tr(rows.shift.map {|s| th(s) })
end
rows.each do |cols|
- tr cols.map {|s| td(s) }
+ buf << tr(cols.map {|s| td(s) })
end
else
rows.each do |cols|
h, *cs = *cols
- tr [th(h)] + cs.map {|s| td(s) }
+ buf << tr([th(h)] + cs.map {|s| td(s) })
end
end
- table_end
+ buf << table_end
+ buf
end
def adjust_n_cols(rows)
@@ -178,12 +190,12 @@ def adjust_n_cols(rows)
# footnote_end
#end
- def compile_inline(s)
- @compiler.text(s)
- end
+# def compile_inline(s)
+# @compiler.text(s)
+# end
def inline_chapref(id)
- compile_inline @book.chapter_index.display_string(id)
+ @book.chapter_index.display_string(id)
rescue KeyError
error "unknown chapter: #{id}"
nofunc_text("[UnknownChapter:#{id}]")
@@ -197,7 +209,7 @@ def inline_chap(id)
end
def inline_title(id)
- compile_inline @book.chapter_index.title(id)
+ @book.chapter_index.title(id)
rescue KeyError
error "unknown chapter: #{id}"
nofunc_text("[UnknownChapter:#{id}]")
@@ -217,8 +229,14 @@ def inline_img(id)
nofunc_text("[UnknownImage:#{id}]")
end
- def inline_imgref(id)
- img = inline_img(id)
+ def node_inline_img(node)
+ id = node[0].to_raw
+ inline_img(id)
+ end
+
+ def node_inline_imgref(node)
+ id = node[0].to_raw
+ img = node_inline_img(node)
if @chapter.image(id).caption
"#{img}#{I18n.t('image_quote', @chapter.image(id).caption)}"
@@ -245,22 +263,17 @@ def inline_bou(str)
text(str)
end
- def inline_ruby(arg)
- base, *ruby = *arg.scan(/(?:(?:(?:\\\\)*\\,)|[^,\\]+)+/)
- base = base.gsub(/\\,/, ",") if base
- ruby = ruby.join(",").gsub(/\\,/, ",") if ruby
+ def inline_ruby(base, ruby)
compile_ruby(base, ruby)
end
- def inline_kw(arg)
- word, alt = *arg.split(',', 2)
+ def inline_kw(word, alt = nil)
compile_kw(word, alt)
end
- def inline_href(arg)
- url, label = *arg.scan(/(?:(?:(?:\\\\)*\\,)|[^,\\]+)+/).map(&:lstrip)
- url = url.gsub(/\\,/, ",").strip
- label = label.gsub(/\\,/, ",").strip if label
+ def inline_href(url, label = nil)
+ url = url.strip
+ label = label.strip if label
compile_href(url, label)
end
@@ -269,15 +282,18 @@ def text(str)
end
def bibpaper(lines, id, caption)
- bibpaper_header id, caption
+ buf = ""
+ buf << bibpaper_header(id, caption)
unless lines.empty?
- puts ""
- bibpaper_bibpaper id, caption, lines
+ buf << "\n"
+ buf << bibpaper_bibpaper(id, caption, lines)
end
- puts ""
+ buf << "\n"
+ buf
end
- def inline_hd(id)
+ def node_inline_hd(nodelist)
+ id = nodelist[0].to_raw
m = /\A([^|]+)\|(.+)/.match(id)
if m && m[1]
chapter = @book.contents.detect{|chap| chap.id == m[1]}
@@ -318,12 +334,12 @@ def raw(str)
builders = matched[1].split(/,/).map{|i| i.gsub(/\s/, '') }
c = target_name
if builders.include?(c)
- print matched[2].gsub("\\n", "\n")
+ matched[2].gsub("\\n", "\n")
else
""
end
else
- print str.gsub("\\n", "\n")
+ str.gsub("\\n", "\n")
end
end
@@ -332,7 +348,7 @@ def warn(msg)
end
def error(msg)
- raise ApplicationError, "#{@location}: error: #{msg}"
+ raise ApplicationError, "error: #{msg} at #{@compiler.show_pos} \n (#{@compiler.failure_oneline})"
end
def handle_metric(str)
@@ -418,8 +434,9 @@ def image_ext
raise NotImplementedError
end
+ ### XXX
def inline_include(file_name)
- compile_inline File.read(file_name)
+ File.read(file_name)
end
def include(file_name)
@@ -433,6 +450,7 @@ def ul_item_begin(lines)
end
def ul_item_end
+ ""
end
def inline_raw(args)
diff --git a/lib/review/compiler.rb b/lib/review/compiler.rb
index e51b4e123..67f2d5dea 100644
--- a/lib/review/compiler.rb
+++ b/lib/review/compiler.rb
@@ -1,51 +1,405 @@
-# encoding: utf-8
-#
-# Copyright (c) 2002-2007 Minero Aoki
-# Copyright (c) 2009-2016 Minero Aoki, Kenshi Muto
-#
-# This program is free software.
-# You can distribute or modify this program under the terms of
-# the GNU LGPL, Lesser General Public License version 2.1.
-#
+# coding: UTF-8
+class ReVIEW::Compiler
+ # :stopdoc:
-require 'review/extentions'
-require 'review/preprocessor'
-require 'review/exception'
-require 'strscan'
+ # This is distinct from setup_parser so that a standalone parser
+ # can redefine #initialize and still have access to the proper
+ # parser setup code.
+ def initialize(str, debug=false)
+ setup_parser(str, debug)
+ end
+
+
+
+ # Prepares for parsing +str+. If you define a custom initialize you must
+ # call this method before #parse
+ def setup_parser(str, debug=false)
+ set_string str, 0
+ @memoizations = Hash.new { |h,k| h[k] = {} }
+ @result = nil
+ @failed_rule = nil
+ @failing_rule_offset = -1
+
+ setup_foreign_grammar
+ end
+
+ attr_reader :string
+ attr_reader :failing_rule_offset
+ attr_accessor :result, :pos
+
+ def current_column(target=pos)
+ if c = string.rindex("\n", target-1)
+ return target - c - 1
+ end
+
+ target + 1
+ end
+
+ def current_line(target=pos)
+ if @sizes_memo.respond_to?(:bsearch)
+ offset = @sizes_memo.bsearch{|line, cur_offset| cur_offset >= target}
+ if offset
+ return offset[0]
+ end
+ else
+ @sizes_memo.each do |line, cur_offset|
+ if cur_offset >= target
+ return cur_offset
+ end
+ end
+ end
+
+ -1
+ end
+
+ def lines
+ @lines_memo
+ end
+
+
+
+ def get_text(start)
+ @string[start..@pos-1]
+ end
+
+ # Sets the string and current parsing position for the parser.
+ def set_string string, pos
+ @string = string.freeze
+ @pos = pos
+ @sizes_memo = []
+ if string
+ @string_size = string.size
+ @lines_memo = string.lines
+ cur_offset = cur_line = 0
+ @lines_memo.each do |line|
+ cur_line += 1
+ cur_offset += line.size
+ @sizes_memo << [cur_line, cur_offset]
+ end
+ else
+ @string_size = 0
+ @lines_memo = []
+ end
+ end
+
+ def show_pos
+ width = 10
+ if @pos < width
+ "#{@pos} (\"#{@string[0,@pos]}\" @ \"#{@string[@pos,width]}\")"
+ else
+ "#{@pos} (\"... #{@string[@pos - width, width]}\" @ \"#{@string[@pos,width]}\")"
+ end
+ end
+
+ def failure_info
+ l = current_line @failing_rule_offset
+ c = current_column @failing_rule_offset
+
+ if @failed_rule.kind_of? Symbol
+ info = self.class::Rules[@failed_rule]
+ "line #{l}, column #{c}: failed rule '#{info.name}' = '#{info.rendered}'"
+ else
+ "line #{l}, column #{c}: failed rule '#{@failed_rule}'"
+ end
+ end
+
+ def failure_caret
+ l = current_line @failing_rule_offset
+ c = current_column @failing_rule_offset
+
+ line = lines[l-1]
+ "#{line}\n#{' ' * (c - 1)}^"
+ end
+
+ def failure_character
+ l = current_line @failing_rule_offset
+ c = current_column @failing_rule_offset
+ lines[l-1][c-1, 1]
+ end
+
+ def failure_oneline
+ l = current_line @failing_rule_offset
+ c = current_column @failing_rule_offset
+
+ char = lines[l-1][c-1, 1]
+
+ if @failed_rule.kind_of? Symbol
+ info = self.class::Rules[@failed_rule]
+ "@#{l}:#{c} failed rule '#{info.name}', got '#{char}'"
+ else
+ "@#{l}:#{c} failed rule '#{@failed_rule}', got '#{char}'"
+ end
+ end
+
+ class ParseError < RuntimeError
+ end
+
+ def raise_error
+ raise ParseError, failure_oneline
+ end
+
+ def show_error(io=STDOUT)
+ error_pos = @failing_rule_offset
+ line_no = current_line(error_pos)
+ col_no = current_column(error_pos)
+
+ io.puts "On line #{line_no}, column #{col_no}:"
+
+ if @failed_rule.kind_of? Symbol
+ info = self.class::Rules[@failed_rule]
+ io.puts "Failed to match '#{info.rendered}' (rule '#{info.name}')"
+ else
+ io.puts "Failed to match rule '#{@failed_rule}'"
+ end
+
+ io.puts "Got: #{string[error_pos,1].inspect}"
+ line = lines[line_no-1]
+ io.puts "=> #{line}"
+ io.print(" " * (col_no + 3))
+ io.puts "^"
+ end
-module ReVIEW
+ def set_failed_rule(name)
+ if @pos > @failing_rule_offset
+ @failed_rule = name
+ @failing_rule_offset = @pos
+ end
+ end
+
+ attr_reader :failed_rule
+
+ def match_string(str)
+ len = str.size
+ if @string[pos,len] == str
+ @pos += len
+ return str
+ end
+
+ return nil
+ end
+
+ def scan(reg)
+ if m = reg.match(@string[@pos..-1])
+ width = m.end(0)
+ @pos += width
+ return true
+ end
+
+ return nil
+ end
+
+ if "".respond_to? :ord
+ def get_byte
+ if @pos >= @string_size
+ return nil
+ end
+
+ s = @string[@pos].ord
+ @pos += 1
+ s
+ end
+ else
+ def get_byte
+ if @pos >= @string_size
+ return nil
+ end
- class Location
- def initialize(filename, f)
- @filename = filename
- @f = f
+ s = @string[@pos]
+ @pos += 1
+ s
+ end
+ end
+
+ def parse(rule=nil)
+ # We invoke the rules indirectly via apply
+ # instead of by just calling them as methods because
+ # if the rules use left recursion, apply needs to
+ # manage that.
+
+ if !rule
+ apply(:_root)
+ else
+ method = rule.gsub("-","_hyphen_")
+ apply :"_#{method}"
+ end
end
- attr_reader :filename
+ class MemoEntry
+ def initialize(ans, pos)
+ @ans = ans
+ @pos = pos
+ @result = nil
+ @set = false
+ @left_rec = false
+ end
+
+ attr_reader :ans, :pos, :result, :set
+ attr_accessor :left_rec
- def lineno
- @f.lineno
+ def move!(ans, pos, result)
+ @ans = ans
+ @pos = pos
+ @result = result
+ @set = true
+ @left_rec = false
+ end
end
- def string
+ def external_invoke(other, rule, *args)
+ old_pos = @pos
+ old_string = @string
+
+ set_string other.string, other.pos
+
begin
- "#{@filename}:#{@f.lineno}"
- rescue
- "#{@filename}:nil"
+ if val = __send__(rule, *args)
+ other.pos = @pos
+ other.result = @result
+ else
+ other.set_failed_rule "#{self.class}##{rule}"
+ end
+ val
+ ensure
+ set_string old_string, old_pos
end
end
- alias_method :to_s, :string
- end
+ def apply_with_args(rule, *args)
+ memo_key = [rule, args]
+ if m = @memoizations[memo_key][@pos]
+ @pos = m.pos
+ if !m.set
+ m.left_rec = true
+ return nil
+ end
+
+ @result = m.result
+
+ return m.ans
+ else
+ m = MemoEntry.new(nil, @pos)
+ @memoizations[memo_key][@pos] = m
+ start_pos = @pos
+
+ ans = __send__ rule, *args
+
+ lr = m.left_rec
+
+ m.move! ans, @pos, @result
+
+ # Don't bother trying to grow the left recursion
+ # if it's failing straight away (thus there is no seed)
+ if ans and lr
+ return grow_lr(rule, args, start_pos, m)
+ else
+ return ans
+ end
+
+ return ans
+ end
+ end
+
+ def apply(rule)
+ if m = @memoizations[rule][@pos]
+ @pos = m.pos
+ if !m.set
+ m.left_rec = true
+ return nil
+ end
+
+ @result = m.result
+
+ return m.ans
+ else
+ m = MemoEntry.new(nil, @pos)
+ @memoizations[rule][@pos] = m
+ start_pos = @pos
+
+ ans = __send__ rule
+
+ lr = m.left_rec
+
+ m.move! ans, @pos, @result
+
+ # Don't bother trying to grow the left recursion
+ # if it's failing straight away (thus there is no seed)
+ if ans and lr
+ return grow_lr(rule, nil, start_pos, m)
+ else
+ return ans
+ end
+
+ return ans
+ end
+ end
+
+ def grow_lr(rule, args, start_pos, m)
+ while true
+ @pos = start_pos
+ @result = m.result
+
+ if args
+ ans = __send__ rule, *args
+ else
+ ans = __send__ rule
+ end
+ return nil unless ans
+
+ break if @pos <= m.pos
+
+ m.move! ans, @pos, @result
+ end
+ @result = m.result
+ @pos = m.pos
+ return m.ans
+ end
+
+ class RuleInfo
+ def initialize(name, rendered)
+ @name = name
+ @rendered = rendered
+ end
+
+ attr_reader :name, :rendered
+ end
+
+ def self.rule_info(name, rendered)
+ RuleInfo.new(name, rendered)
+ end
- class Compiler
- def initialize(strategy)
- @strategy = strategy
+ # :startdoc:
+
+
+ class Error; end
+ class Position
+ attr_accessor :pos, :line, :col
+ def initialize(compiler)
+ @pos = compiler.pos
+ @line = compiler.current_line
+ @col = compiler.current_column
end
+ end
+
+# rubocop:disable all
+require 'review/location'
+require 'review/extentions'
+require 'review/preprocessor'
+require 'review/exception'
+require 'review/node'
+ require 'lineinput'
+ # require 'review/compiler/literals_1_9'
+ # require 'review/compiler/literals_1_8'
+
+ ## redifine Compiler.new
+ def initialize(strategy)
+ @strategy = strategy
+ @current_column = nil
+ @chapter = nil
+ end
- attr_reader :strategy
+ attr_accessor :strategy
def compile(chap)
@chapter = chap
@@ -53,11 +407,72 @@ def compile(chap)
@strategy.result
end
+ def do_compile
+ @strategy.bind self, @chapter, ReVIEW::Location.new(@chapter.basename, self)
+ setup_parser(@chapter.content)
+ parse()
+ convert_ast
+ end
+
+ def convert_ast
+ ast = @strategy.ast
+ convert_column(ast)
+ if $DEBUG
+ File.open("review-dump.json","w") do |f|
+ f.write(ast.to_json)
+ end
+ end
+ @strategy.output << ast.to_doc
+ end
+
+ def flush_column(new_content)
+ if @current_column
+ new_content << @current_column
+ @current_column = nil
+ end
+ end
+
+ def convert_column(ast)
+ @column_stack = []
+ content = ast.content
+ new_content = []
+ @current_content = new_content
+ content.each do |elem|
+ if elem.kind_of?(ReVIEW::HeadlineNode) && elem.cmd && elem.cmd.to_doc == "column"
+ flush_column(new_content)
+ @current_content = []
+ @current_column = ReVIEW::ColumnNode.new(elem.compiler, elem.position, elem.level,
+ elem.label, elem.content, @current_content)
+ next
+ elsif elem.kind_of?(ReVIEW::HeadlineNode) && elem.cmd && elem.cmd.to_doc =~ %r|^/|
+ cmd_name = elem.cmd.to_doc[1..-1]
+ if cmd_name != "column"
+ raise ReVIEW::CompileError, "#{cmd_name} is not opened."
+ end
+ flush_column(new_content)
+ @current_content = new_content
+ next
+ elsif elem.kind_of?(ReVIEW::HeadlineNode) && @current_column && elem.level <= @current_column.level
+ flush_column(new_content)
+ @current_content = new_content
+ end
+ @current_content << elem
+ end
+ flush_column(new_content)
+ ast.content = new_content
+ ast
+ end
+
+ def compile_text(text)
+ @strategy.nofunc_text(text)
+ end
+
class SyntaxElement
- def initialize(name, type, argc, &block)
+ def initialize(name, type, argc, esc, &block)
@name = name
@type = type
@argc_spec = argc
+ @esc_patterns = esc
@checker = block
end
@@ -65,7 +480,7 @@ def initialize(name, type, argc, &block)
def check_args(args)
unless @argc_spec === args.size
- raise CompileError, "wrong # of parameters (block command //#{@name}, expect #{@argc_spec} but #{args.size})"
+ raise ReVIEW::CompileError, "wrong # of parameters (block command //#{@name}, expect #{@argc_spec} but #{args.size})"
end
@checker.call(*args) if @checker
end
@@ -79,27 +494,49 @@ def min_argc
end
end
+ def parse_args(args)
+ if @esc_patterns
+ args.map.with_index do |pattern, i|
+ if @esc_patterns[i]
+ args[i].__send__("to_#{@esc_patterns[i]}")
+ else
+ args[i].to_doc
+ end
+ end
+ else
+ args.map(&:to_doc)
+ end
+ end
+
def block_required?
- @type == :block
+ @type == :block or @type == :code_block
end
def block_allowed?
- @type == :block or @type == :optional
+ @type == :block or @type == :code_block or @type == :optional or @type == :optional_code_block
+ end
+
+ def code_block?
+ @type == :code_block or @type == :optional_code_block
end
end
SYNTAX = {}
- def Compiler.defblock(name, argc, optional = false, &block)
- defsyntax name, (optional ? :optional : :block), argc, &block
+ def self.defblock(name, argc, optional = false, esc = nil, &block)
+ defsyntax(name, (optional ? :optional : :block), argc, esc, &block)
+ end
+
+ def self.defcodeblock(name, argc, optional = false, esc = nil, &block)
+ defsyntax(name, (optional ? :optional_code_block : :code_block), argc, esc, &block)
end
- def Compiler.defsingle(name, argc, &block)
- defsyntax name, :line, argc, &block
+ def self.defsingle(name, argc, esc = nil, &block)
+ defsyntax name, :line, argc, esc, &block
end
- def Compiler.defsyntax(name, type, argc, &block)
- SYNTAX[name] = SyntaxElement.new(name, type, argc, &block)
+ def self.defsyntax(name, type, argc, esc = nil, &block)
+ SYNTAX[name] = SyntaxElement.new(name, type, argc, esc, &block)
end
def syntax_defined?(name)
@@ -119,32 +556,39 @@ def initialize(name)
end
INLINE = {}
+ COMPLEX_INLINE = {}
- def Compiler.definline(name)
+ def self.definline(name)
INLINE[name] = InlineSyntaxElement.new(name)
end
+ def self.defcomplexinline(name)
+ COMPLEX_INLINE[name] = InlineSyntaxElement.new(name)
+ end
+
def inline_defined?(name)
- INLINE.key?(name.to_sym)
+ INLINE.key?(name.to_sym) || COMPLEX_INLINE.key?(name.to_sym)
end
defblock :read, 0
defblock :lead, 0
- defblock :list, 2..3
- defblock :emlist, 0..2
- defblock :cmd, 0..1
- defblock :table, 0..2
- defblock :imgtable, 0..2
defblock :quote, 0
- defblock :image, 2..3, true
- defblock :source, 0..2
- defblock :listnum, 2..3
- defblock :emlistnum, 0..2
- defblock :bibpaper, 2..3, true
- defblock :doorquote, 1
+ defblock :bibpaper, 2..3, true, [:raw, :doc, :doc]
+ defblock :doorquote, 1, false, [:doc]
defblock :talk, 0
- defblock :texequation, 0
- defblock :graph, 1..3
+ defblock :graph, 1..3, false, [:raw, :raw, :doc]
+
+ defcodeblock :emlist, 0..2, false, [:doc, :raw]
+ defcodeblock :cmd, 0..1, false, [:doc]
+ defcodeblock :source, 0..2, false, [:doc, :raw]
+ defcodeblock :list, 2..4, false, [:raw, :doc, :raw, :raw]
+ defcodeblock :listnum, 2..3, false, [:raw, :doc, :raw]
+ defcodeblock :emlistnum, 0..2, false, [:doc, :raw]
+ defcodeblock :texequation, 0, false
+ defcodeblock :table, 0..2, false, [:raw, :doc]
+ defcodeblock :imgtable, 0..2, false, [:raw, :doc]
+ defcodeblock :image, 2..3, true, [:raw,:doc,:raw]
+ defcodeblock :box, 0..1, false, [:doc]
defblock :address, 0
defblock :blockquote, 0
@@ -159,22 +603,21 @@ def inline_defined?(name)
defblock :notice, 0..1
defblock :warning, 0..1
defblock :tip, 0..1
- defblock :box, 0..1
defblock :comment, 0..1, true
- defsingle :footnote, 2
+ defsingle :footnote, 2, [:raw, :doc]
defsingle :noindent, 0
defsingle :linebreak, 0
defsingle :pagebreak, 0
- defsingle :indepimage, 1..3
- defsingle :numberlessimage, 1..3
+ defsingle :indepimage, 1..3, [:raw, :doc, :raw]
+ defsingle :numberlessimage, 1..3, [:raw, :doc, :raw]
defsingle :hr, 0
defsingle :parasep, 0
- defsingle :label, 1
- defsingle :raw, 1
- defsingle :tsize, 1
- defsingle :include, 1
- defsingle :olnum, 1
+ defsingle :label, 1, [:raw]
+ defsingle :raw, 1, [:raw]
+ defsingle :tsize, 1, [:raw]
+ defsingle :include, 1, [:raw]
+ defsingle :olnum, 1, [:raw]
definline :chapref
definline :chap
@@ -185,8 +628,6 @@ def inline_defined?(name)
definline :list
definline :table
definline :fn
- definline :kw
- definline :ruby
definline :bou
definline :ami
definline :b
@@ -194,7 +635,6 @@ def inline_defined?(name)
definline :code
definline :bib
definline :hd
- definline :href
definline :recipe
definline :column
definline :tcy
@@ -230,330 +670,4494 @@ def inline_defined?(name)
definline :include
definline :tcy
- private
+ defcomplexinline :kw
+ defcomplexinline :ruby
+ defcomplexinline :href
- def do_compile
- f = LineInput.new(Preprocessor::Strip.new(StringIO.new(@chapter.content)))
- @strategy.bind self, @chapter, Location.new(@chapter.basename, f)
- tagged_section_init
- while f.next?
- case f.peek
- when /\A\#@/
- f.gets # Nothing to do
- when /\A=+[\[\s\{]/
- compile_headline f.gets
- when %r<\A\s+\*>
- compile_ulist f
- when %r<\A\s+\d+\.>
- compile_olist f
- when %r<\A\s*:\s>
- compile_dlist f
- when %r<\A//\}>
- f.gets
- error 'block end seen but not opened'
- when %r<\A//[a-z]+>
- name, args, lines = read_command(f)
- syntax = syntax_descriptor(name)
- unless syntax
- error "unknown command: //#{name}"
- compile_unknown_command args, lines
- next
- end
- compile_command syntax, args, lines
- when %r<\A//>
- line = f.gets
- warn "`//' seen but is not valid command: #{line.strip.inspect}"
- if block_open?(line)
- warn "skipping block..."
- read_block(f)
- end
- else
- if f.peek.strip.empty?
- f.gets
- next
- end
- compile_paragraph f
- end
- end
- close_all_tagged_section
+ def compile_column(level, label, caption, content)
+ buf = ""
+ buf << @strategy.__send__("column_begin", level, label, caption)
+ buf << content.to_doc
+ buf << @strategy.__send__("column_end", level)
+ buf
end
- def compile_headline(line)
- @headline_indexs ||= [@chapter.number.to_i - 1]
- m = /\A(=+)(?:\[(.+?)\])?(?:\{(.+?)\})?(.*)/.match(line)
- level = m[1].size
- tag = m[2]
- label = m[3]
- caption = m[4].strip
- index = level - 1
- if tag
- if tag !~ /\A\//
- close_current_tagged_section(level)
- open_tagged_section(tag, level, label, caption)
- else
- open_tag = tag[1..-1]
- prev_tag_info = @tagged_section.pop
- unless prev_tag_info.first == open_tag
- raise CompileError, "#{open_tag} is not opened."
- end
- close_tagged_section(*prev_tag_info)
- end
- else
- if @headline_indexs.size > (index + 1)
- @headline_indexs = @headline_indexs[0..index]
- end
- @headline_indexs[index] = 0 if @headline_indexs[index].nil?
- @headline_indexs[index] += 1
- close_current_tagged_section(level)
- @strategy.headline level, label, caption
+ def compile_command(name, args, lines, node)
+ syntax = syntax_descriptor(name)
+ if !syntax || (!@strategy.respond_to?(syntax.name) && !@strategy.respond_to?("node_#{syntax.name}"))
+ error "strategy does not support command: //#{name}"
+ compile_unknown_command args, lines
+ return
end
- end
-
- def close_current_tagged_section(level)
- while @tagged_section.last and @tagged_section.last[1] >= level
- close_tagged_section(* @tagged_section.pop)
+ begin
+ syntax.check_args args
+ rescue ReVIEW::CompileError => err
+ error err.message
+ args = ['(NoArgument)'] * syntax.min_argc
end
- end
-
- def headline(level, label, caption)
- @strategy.headline level, label, caption
- end
-
- def tagged_section_init
- @tagged_section = []
- end
-
- def open_tagged_section(tag, level, label, caption)
- mid = "#{tag}_begin"
- unless @strategy.respond_to?(mid)
- error "strategy does not support tagged section: #{tag}"
- headline level, label, caption
- return
+ if syntax.block_allowed?
+ compile_block(syntax, args, lines, node)
+ else
+ if lines
+ error "block is not allowed for command //#{syntax.name}; ignore"
+ end
+ compile_single(syntax, args, node)
end
- @tagged_section.push [tag, level]
- @strategy.__send__ mid, level, label, caption
end
- def close_tagged_section(tag, level)
- mid = "#{tag}_end"
- if @strategy.respond_to?(mid)
- @strategy.__send__ mid, level
- else
- error "strategy does not support block op: #{mid}"
+ def compile_headline(level, tag, label, caption)
+ buf = ""
+ @headline_indexs ||= [0] ## XXX
+ caption ||= ""
+ caption.strip!
+ index = level - 1
+ if @headline_indexs.size > (index + 1)
+ @headline_indexs = @headline_indexs[0..index]
end
+ @headline_indexs[index] = 0 if @headline_indexs[index].nil?
+ @headline_indexs[index] += 1
+ buf << @strategy.headline(level, label, caption)
+ buf
end
- def close_all_tagged_section
- until @tagged_section.empty?
- close_tagged_section(* @tagged_section.pop)
- end
+ def comment(text)
+ @strategy.comment(text)
end
- def compile_ulist(f)
+ def compile_ulist(content)
+ buf0 = ""
level = 0
- f.while_match(/\A\s+\*|\A\#@/) do |line|
- next if line =~ /\A\#@/
-
- buf = [text(line.sub(/\*+/, '').strip)]
- f.while_match(/\A\s+(?!\*)\S/) do |cont|
- buf.push text(cont.strip)
- end
-
- line =~ /\A\s+(\*+)/
- current_level = $1.size
+ content.each do |element|
+ current_level = element.level
+ buf = element.to_doc
if level == current_level
- @strategy.ul_item_end
+ buf0 << @strategy.ul_item_end
# body
- @strategy.ul_item_begin buf
+ buf0 << @strategy.ul_item_begin([buf])
elsif level < current_level # down
level_diff = current_level - level
level = current_level
(1..(level_diff - 1)).to_a.reverse_each do |i|
- @strategy.ul_begin {i}
- @strategy.ul_item_begin []
+ buf0 << @strategy.ul_begin{i}
+ buf0 << @strategy.ul_item_begin([])
end
- @strategy.ul_begin {level}
- @strategy.ul_item_begin buf
+ buf0 << @strategy.ul_begin{level}
+ buf0 << @strategy.ul_item_begin([buf])
elsif level > current_level # up
level_diff = level - current_level
level = current_level
(1..level_diff).to_a.reverse_each do |i|
- @strategy.ul_item_end
- @strategy.ul_end {level + i}
+ buf0 << @strategy.ul_item_end
+ buf0 << @strategy.ul_end{level + i}
end
- @strategy.ul_item_end
+ buf0 << @strategy.ul_item_end
# body
- @strategy.ul_item_begin buf
+ buf0 <<@strategy.ul_item_begin([buf])
end
end
(1..level).to_a.reverse_each do |i|
- @strategy.ul_item_end
- @strategy.ul_end {i}
+ buf0 << @strategy.ul_item_end
+ buf0 << @strategy.ul_end{i}
end
+ buf0
end
- def compile_olist(f)
- @strategy.ol_begin
- f.while_match(/\A\s+\d+\.|\A\#@/) do |line|
- next if line =~ /\A\#@/
-
- num = line.match(/(\d+)\./)[1]
- buf = [text(line.sub(/\d+\./, '').strip)]
- f.while_match(/\A\s+(?!\d+\.)\S/) do |cont|
- buf.push text(cont.strip)
- end
- @strategy.ol_item buf, num
+ def compile_olist(content)
+ buf0 = ""
+ buf0 << @strategy.ol_begin
+ content.each do |element|
+ ## XXX 1st arg should be String, not Array
+ buf0 << @strategy.ol_item(element.to_doc.split(/\n/), element.num)
end
- @strategy.ol_end
+ buf0 << @strategy.ol_end
+ buf0
end
- def compile_dlist(f)
- @strategy.dl_begin
- while /\A\s*:/ =~ f.peek
- @strategy.dt text(f.gets.sub(/\A\s*:/, '').strip)
- @strategy.dd f.break(/\A(\S|\s*:)/).map {|line| text(line.strip) }
- f.skip_blank_lines
- f.skip_comment_lines
+ def compile_dlist(content)
+ buf = ""
+ buf << @strategy.dl_begin
+ content.each do |element|
+ buf << @strategy.dt(element.text.to_doc)
+ buf << @strategy.dd(element.content.map{|s| s.to_doc})
end
- @strategy.dl_end
+ buf << @strategy.dl_end
+ buf
end
- def compile_paragraph(f)
- buf = []
- f.until_match(%r<\A//|\A\#@>) do |line|
- break if line.strip.empty?
- buf.push text(line.sub(/^(\t+)\s*/) {|m| "" * m.size}.strip.gsub(//, "\t"))
- end
- @strategy.paragraph buf
- end
- def read_command(f)
- line = f.gets
- name = line.slice(/[a-z]+/).to_sym
- args = parse_args(line.sub(%r<\A//[a-z]+>, '').rstrip.chomp('{'), name)
- lines = block_open?(line) ? read_block(f) : nil
- return name, args, lines
+ def compile_unknown_command(args, lines)
+ @strategy.unknown_command(args, lines)
end
- def block_open?(line)
- line.rstrip[-1,1] == '{'
+ def compile_block(syntax, args, lines, node)
+ node_name = "node_#{syntax.name}".to_sym
+ if @strategy.respond_to?(node_name)
+ @strategy.__send__(node_name, node)
+ else
+ args_conv = syntax.parse_args(args)
+ @strategy.__send__(syntax.name, (lines || default_block(syntax)), *args_conv)
+ end
end
- def read_block(f)
- head = f.lineno
- buf = []
- f.until_match(%r<\A//\}>) do |line|
- unless line =~ /\A\#@/
- buf.push text(line.rstrip)
- end
- end
- unless %r<\A//\}> =~ f.peek
- error "unexpected EOF (block begins at: #{head})"
- return buf
+ def default_block(syntax)
+ if syntax.block_required?
+ error "block is required for //#{syntax.name}; use empty block"
end
- f.gets # discard terminator
- buf
+ []
end
- def parse_args(str, name=nil)
- return [] if str.empty?
- scanner = StringScanner.new(str)
- words = []
- while word = scanner.scan(/(\[\]|\[.*?[^\\]\])/)
- w2 = word[1..-2].gsub(/\\(.)/){
- ch = $1
- (ch == "]" or ch == "\\") ? ch : "\\" + ch
- }
- words << w2
- end
- if !scanner.eos?
- error "argument syntax error: #{scanner.rest} in #{str.inspect}"
- return []
+ def compile_single(syntax, args, node)
+ node_name = "node_#{syntax.name}".to_sym
+ if @strategy.respond_to?(node_name)
+ @strategy.__send__(node_name, node)
+ else
+ args_conv = syntax.parse_args(args)
+ @strategy.__send__(syntax.name, *args_conv)
end
- return words
end
- def compile_command(syntax, args, lines)
- unless @strategy.respond_to?(syntax.name)
- error "strategy does not support command: //#{syntax.name}"
- compile_unknown_command args, lines
- return
+
+ def compile_inline(op, args)
+ unless inline_defined?(op)
+ raise ReVIEW::CompileError, "no such inline op: #{op}"
end
- begin
- syntax.check_args args
- rescue CompileError => err
- error err.message
- args = ['(NoArgument)'] * syntax.min_argc
+ if @strategy.respond_to?("node_inline_#{op}")
+ return @strategy.__send__("node_inline_#{op}", args)
end
- if syntax.block_allowed?
- compile_block syntax, args, lines
+ unless @strategy.respond_to?("inline_#{op}")
+ raise "strategy does not support inline op: @<#{op}>"
+ end
+ if !args
+ @strategy.__send__("inline_#{op}", "")
else
- if lines
- error "block is not allowed for command //#{syntax.name}; ignore"
- end
- compile_single syntax, args
+ @strategy.__send__("inline_#{op}", *(args.map(&:to_doc)))
end
+# rescue => err
+# error err.message
end
- def compile_unknown_command(args, lines)
- @strategy.unknown_command args, lines
+ def compile_paragraph(buf)
+ @strategy.paragraph buf
end
- def compile_block(syntax, args, lines)
- @strategy.__send__(syntax.name, (lines || default_block(syntax)), *args)
+ def compile_raw(builders, content)
+ c = @strategy.class.to_s.gsub(/ReVIEW::/, '').gsub(/Builder/, '').downcase
+ if !builders || builders.include?(c)
+ content.gsub("\\n", "\n")
+ else
+ ""
+ end
end
- def default_block(syntax)
- if syntax.block_required?
- error "block is required for //#{syntax.name}; use empty block"
- end
- []
+ def warn(msg)
+ @strategy.warn msg
+ end
+
+ def error(msg)
+ @strategy.error msg
+ end
+
+ def check_indent(s)
+ s.size >= @list_stack.last.size
+ end
+
+ def check_nested_indent(s)
+ s.size >= @list_stack.last.size + 2
+ end
+
+ def check_inline_element_symbol(name)
+ INLINE.key?(name.to_sym)
+ end
+
+ def check_complex_inline_element_symbol(name)
+ COMPLEX_INLINE.key?(name.to_sym)
end
- def compile_single(syntax, args)
- @strategy.__send__(syntax.name, *args)
+ def position
+ Position.new(self)
end
- def text(str)
- return '' if str.empty?
- words = str.split(/(@<\w+>\{(?:[^\}\\]|\\.)*?\})/, -1)
- words.each do |w|
- error "`@' seen but is not valid inline op: #{w}" if w.scan(/@<\w+>/).size > 1 && !/\A@/.match(w)
+
+
+
+ # :stopdoc:
+
+ module ::ReVIEW
+ class Node; end
+ class BlockElementNode < Node
+ def initialize(compiler, position, name, args, content)
+ @compiler = compiler
+ @position = position
+ @name = name
+ @args = args
+ @content = content
end
- result = @strategy.nofunc_text(words.shift)
- until words.empty?
- result << compile_inline(words.shift.gsub(/\\\}/, '}'))
- result << @strategy.nofunc_text(words.shift)
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :name
+ attr_reader :args
+ attr_reader :content
+ end
+ class BraceNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
end
- result
- rescue => err
- error err.message
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
end
- public :text # called from strategy
-
- def compile_inline(str)
- op, arg = /\A@<(\w+)>\{(.*?)\}\z/.match(str).captures
- unless inline_defined?(op)
- raise CompileError, "no such inline op: #{op}"
+ class BracketArgNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
end
- unless @strategy.respond_to?("inline_#{op}")
- raise "strategy does not support inline op: @<#{op}>"
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
+ end
+ class CodeBlockElementNode < Node
+ def initialize(compiler, position, name, args, content)
+ @compiler = compiler
+ @position = position
+ @name = name
+ @args = args
+ @content = content
end
- @strategy.__send__("inline_#{op}", arg)
- rescue => err
- error err.message
- @strategy.nofunc_text(str)
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :name
+ attr_reader :args
+ attr_reader :content
end
-
- def warn(msg)
- @strategy.warn msg
+ class ColumnNode < Node
+ def initialize(compiler, position, level, label, caption, content)
+ @compiler = compiler
+ @position = position
+ @level = level
+ @label = label
+ @caption = caption
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :level
+ attr_reader :label
+ attr_reader :caption
+ attr_reader :content
end
-
- def error(msg)
- @strategy.error msg
+ class ComplexInlineElementNode < Node
+ def initialize(compiler, position, symbol, content)
+ @compiler = compiler
+ @position = position
+ @symbol = symbol
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :symbol
+ attr_reader :content
+ end
+ class ComplexInlineElementContentNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
+ end
+ class DlistNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
+ end
+ class DlistElementNode < Node
+ def initialize(compiler, position, text, content)
+ @compiler = compiler
+ @position = position
+ @text = text
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :text
+ attr_reader :content
+ end
+ class DocumentNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
+ end
+ class HeadlineNode < Node
+ def initialize(compiler, position, level, cmd, label, content)
+ @compiler = compiler
+ @position = position
+ @level = level
+ @cmd = cmd
+ @label = label
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :level
+ attr_reader :cmd
+ attr_reader :label
+ attr_reader :content
+ end
+ class InlineElementNode < Node
+ def initialize(compiler, position, symbol, content)
+ @compiler = compiler
+ @position = position
+ @symbol = symbol
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :symbol
+ attr_reader :content
+ end
+ class InlineElementContentNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
+ end
+ class NewLineNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
+ end
+ class OlistNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
+ end
+ class OlistElementNode < Node
+ def initialize(compiler, position, num, content)
+ @compiler = compiler
+ @position = position
+ @num = num
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :num
+ attr_reader :content
+ end
+ class ParagraphNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
+ end
+ class RawNode < Node
+ def initialize(compiler, builder, position, content)
+ @compiler = compiler
+ @builder = builder
+ @position = position
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :builder
+ attr_reader :position
+ attr_reader :content
+ end
+ class SinglelineCommentNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
end
+ class SinglelineContentNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
+ end
+ class TextNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
+ end
+ class UlistNode < Node
+ def initialize(compiler, position, content)
+ @compiler = compiler
+ @position = position
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :content
+ end
+ class UlistElementNode < Node
+ def initialize(compiler, position, level, content)
+ @compiler = compiler
+ @position = position
+ @level = level
+ @content = content
+ end
+ attr_reader :compiler
+ attr_reader :position
+ attr_reader :level
+ attr_reader :content
+ end
+ end
+ module ::ReVIEWConstruction
+ def block_element(compiler, position, name, args, content)
+ ::ReVIEW::BlockElementNode.new(compiler, position, name, args, content)
+ end
+ def brace(compiler, position, content)
+ ::ReVIEW::BraceNode.new(compiler, position, content)
+ end
+ def bracket_arg(compiler, position, content)
+ ::ReVIEW::BracketArgNode.new(compiler, position, content)
+ end
+ def code_block_element(compiler, position, name, args, content)
+ ::ReVIEW::CodeBlockElementNode.new(compiler, position, name, args, content)
+ end
+ def column(compiler, position, level, label, caption, content)
+ ::ReVIEW::ColumnNode.new(compiler, position, level, label, caption, content)
+ end
+ def complex_inline_element(compiler, position, symbol, content)
+ ::ReVIEW::ComplexInlineElementNode.new(compiler, position, symbol, content)
+ end
+ def complex_inline_element_content(compiler, position, content)
+ ::ReVIEW::ComplexInlineElementContentNode.new(compiler, position, content)
+ end
+ def dlist(compiler, position, content)
+ ::ReVIEW::DlistNode.new(compiler, position, content)
+ end
+ def dlist_element(compiler, position, text, content)
+ ::ReVIEW::DlistElementNode.new(compiler, position, text, content)
+ end
+ def document(compiler, position, content)
+ ::ReVIEW::DocumentNode.new(compiler, position, content)
+ end
+ def headline(compiler, position, level, cmd, label, content)
+ ::ReVIEW::HeadlineNode.new(compiler, position, level, cmd, label, content)
+ end
+ def inline_element(compiler, position, symbol, content)
+ ::ReVIEW::InlineElementNode.new(compiler, position, symbol, content)
+ end
+ def inline_element_content(compiler, position, content)
+ ::ReVIEW::InlineElementContentNode.new(compiler, position, content)
+ end
+ def newline(compiler, position, content)
+ ::ReVIEW::NewLineNode.new(compiler, position, content)
+ end
+ def olist(compiler, position, content)
+ ::ReVIEW::OlistNode.new(compiler, position, content)
+ end
+ def olist_element(compiler, position, num, content)
+ ::ReVIEW::OlistElementNode.new(compiler, position, num, content)
+ end
+ def paragraph(compiler, position, content)
+ ::ReVIEW::ParagraphNode.new(compiler, position, content)
+ end
+ def raw(compiler, builder, position, content)
+ ::ReVIEW::RawNode.new(compiler, builder, position, content)
+ end
+ def singleline_comment(compiler, position, content)
+ ::ReVIEW::SinglelineCommentNode.new(compiler, position, content)
+ end
+ def singleline_content(compiler, position, content)
+ ::ReVIEW::SinglelineContentNode.new(compiler, position, content)
+ end
+ def text(compiler, position, content)
+ ::ReVIEW::TextNode.new(compiler, position, content)
+ end
+ def ulist(compiler, position, content)
+ ::ReVIEW::UlistNode.new(compiler, position, content)
+ end
+ def ulist_element(compiler, position, level, content)
+ ::ReVIEW::UlistElementNode.new(compiler, position, level, content)
+ end
+ end
+ include ::ReVIEWConstruction
+ def setup_foreign_grammar; end
+
+ # root = Start
+ def _root
+ _tmp = apply(:_Start)
+ set_failed_rule :_root unless _tmp
+ return _tmp
+ end
+
+ # Start = &. { @list_stack = Array.new } Document:c { @strategy.ast = c }
+ def _Start
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _tmp = get_byte
+ self.pos = _save1
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; @list_stack = Array.new ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Document)
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; @strategy.ast = c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_Start unless _tmp
+ return _tmp
+ end
+
+ # Document = BOM? Block*:c {document(self, position, c)}
+ def _Document
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _tmp = apply(:_BOM)
+ unless _tmp
+ _tmp = true
+ self.pos = _save1
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _ary = []
+ while true
+ _tmp = apply(:_Block)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; document(self, position, c); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_Document unless _tmp
+ return _tmp
+ end
+
+ # Block = BlankLine*:c { c } (SinglelineComment:c | Headline:c | BlockElement:c | Ulist:c | Olist:c | Dlist:c | Paragraph:c) { c }
+ def _Block
+
+ _save = self.pos
+ while true # sequence
+ _ary = []
+ while true
+ _tmp = apply(:_BlankLine)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+
+ _save2 = self.pos
+ while true # choice
+ _tmp = apply(:_SinglelineComment)
+ c = @result
+ break if _tmp
+ self.pos = _save2
+ _tmp = apply(:_Headline)
+ c = @result
+ break if _tmp
+ self.pos = _save2
+ _tmp = apply(:_BlockElement)
+ c = @result
+ break if _tmp
+ self.pos = _save2
+ _tmp = apply(:_Ulist)
+ c = @result
+ break if _tmp
+ self.pos = _save2
+ _tmp = apply(:_Olist)
+ c = @result
+ break if _tmp
+ self.pos = _save2
+ _tmp = apply(:_Dlist)
+ c = @result
+ break if _tmp
+ self.pos = _save2
+ _tmp = apply(:_Paragraph)
+ c = @result
+ break if _tmp
+ self.pos = _save2
+ break
+ end # end choice
+
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_Block unless _tmp
+ return _tmp
+ end
+
+ # BlankLine = Newline
+ def _BlankLine
+ _tmp = apply(:_Newline)
+ set_failed_rule :_BlankLine unless _tmp
+ return _tmp
+ end
+
+ # SinglelineComment = "#@" < NonNewline+ > EOL {singleline_comment(self, position, text)}
+ def _SinglelineComment
+
+ _save = self.pos
+ while true # sequence
+ _tmp = match_string("\#@")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _text_start = self.pos
+ _save1 = self.pos
+ _tmp = apply(:_NonNewline)
+ if _tmp
+ while true
+ _tmp = apply(:_NonNewline)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save1
+ end
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_EOL)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; singleline_comment(self, position, text); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_SinglelineComment unless _tmp
+ return _tmp
+ end
+
+ # Headline = HeadlinePrefix:level BracketArg?:cmd BraceArg?:label Space* SinglelineContent?:caption EOL {headline(self, position, level, cmd, label, caption)}
+ def _Headline
+
+ _save = self.pos
+ while true # sequence
+ _tmp = apply(:_HeadlinePrefix)
+ level = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save1 = self.pos
+ _tmp = apply(:_BracketArg)
+ @result = nil unless _tmp
+ unless _tmp
+ _tmp = true
+ self.pos = _save1
+ end
+ cmd = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _tmp = apply(:_BraceArg)
+ @result = nil unless _tmp
+ unless _tmp
+ _tmp = true
+ self.pos = _save2
+ end
+ label = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save4 = self.pos
+ _tmp = apply(:_SinglelineContent)
+ @result = nil unless _tmp
+ unless _tmp
+ _tmp = true
+ self.pos = _save4
+ end
+ caption = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_EOL)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; headline(self, position, level, cmd, label, caption); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_Headline unless _tmp
+ return _tmp
+ end
+
+ # HeadlinePrefix = < /={1,5}/ > { text.length }
+ def _HeadlinePrefix
+
+ _save = self.pos
+ while true # sequence
+ _text_start = self.pos
+ _tmp = scan(/\A(?-mix:={1,5})/)
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; text.length ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_HeadlinePrefix unless _tmp
+ return _tmp
+ end
+
+ # Paragraph = ParagraphLine+:c {paragraph(self, position, c.flatten)}
+ def _Paragraph
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_ParagraphLine)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_ParagraphLine)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; paragraph(self, position, c.flatten); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_Paragraph unless _tmp
+ return _tmp
+ end
+
+ # ParagraphLine = !Headline !SinglelineComment !BlockElement !Ulist !Olist !Dlist SinglelineContent:c Newline { c }
+ def _ParagraphLine
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _tmp = apply(:_Headline)
+ _tmp = _tmp ? nil : true
+ self.pos = _save1
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _tmp = apply(:_SinglelineComment)
+ _tmp = _tmp ? nil : true
+ self.pos = _save2
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save3 = self.pos
+ _tmp = apply(:_BlockElement)
+ _tmp = _tmp ? nil : true
+ self.pos = _save3
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save4 = self.pos
+ _tmp = apply(:_Ulist)
+ _tmp = _tmp ? nil : true
+ self.pos = _save4
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save5 = self.pos
+ _tmp = apply(:_Olist)
+ _tmp = _tmp ? nil : true
+ self.pos = _save5
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save6 = self.pos
+ _tmp = apply(:_Dlist)
+ _tmp = _tmp ? nil : true
+ self.pos = _save6
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_SinglelineContent)
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Newline)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_ParagraphLine unless _tmp
+ return _tmp
+ end
+
+ # BlockElement = ("//raw[" RawBlockBuilderSelect?:b RawBlockElementArg*:r1 "]" Space* EOL {raw(self, b, position, r1)} | !"//raw" "//" ElementName:symbol &{ syntax = syntax_descriptor(symbol); syntax && syntax.code_block? } BracketArg*:args "{" Space* Newline CodeBlockElementContents:contents "//}" Space* EOL {code_block_element(self, position, symbol, args, contents)} | !"//raw" "//" ElementName:symbol BracketArg*:args "{" Space* Newline BlockElementContents:contents "//}" Space* EOL {block_element(self, position, symbol, args, contents)} | !"//raw" "//" ElementName:symbol BracketArg*:args Space* EOL {block_element(self, position, symbol, args, nil)})
+ def _BlockElement
+
+ _save = self.pos
+ while true # choice
+
+ _save1 = self.pos
+ while true # sequence
+ _tmp = match_string("//raw[")
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ _save2 = self.pos
+ _tmp = apply(:_RawBlockBuilderSelect)
+ @result = nil unless _tmp
+ unless _tmp
+ _tmp = true
+ self.pos = _save2
+ end
+ b = @result
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ _ary = []
+ while true
+ _tmp = apply(:_RawBlockElementArg)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ r1 = @result
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ _tmp = match_string("]")
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ _tmp = apply(:_EOL)
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ @result = begin; raw(self, b, position, r1); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save5 = self.pos
+ while true # sequence
+ _save6 = self.pos
+ _tmp = match_string("//raw")
+ _tmp = _tmp ? nil : true
+ self.pos = _save6
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = match_string("//")
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = apply(:_ElementName)
+ symbol = @result
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _save7 = self.pos
+ _tmp = begin; syntax = syntax_descriptor(symbol); syntax && syntax.code_block? ; end
+ self.pos = _save7
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _ary = []
+ while true
+ _tmp = apply(:_BracketArg)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ args = @result
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = match_string("{")
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = apply(:_Newline)
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = apply(:_CodeBlockElementContents)
+ contents = @result
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = match_string("//}")
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = apply(:_EOL)
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ @result = begin; code_block_element(self, position, symbol, args, contents); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save5
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save11 = self.pos
+ while true # sequence
+ _save12 = self.pos
+ _tmp = match_string("//raw")
+ _tmp = _tmp ? nil : true
+ self.pos = _save12
+ unless _tmp
+ self.pos = _save11
+ break
+ end
+ _tmp = match_string("//")
+ unless _tmp
+ self.pos = _save11
+ break
+ end
+ _tmp = apply(:_ElementName)
+ symbol = @result
+ unless _tmp
+ self.pos = _save11
+ break
+ end
+ _ary = []
+ while true
+ _tmp = apply(:_BracketArg)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ args = @result
+ unless _tmp
+ self.pos = _save11
+ break
+ end
+ _tmp = match_string("{")
+ unless _tmp
+ self.pos = _save11
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save11
+ break
+ end
+ _tmp = apply(:_Newline)
+ unless _tmp
+ self.pos = _save11
+ break
+ end
+ _tmp = apply(:_BlockElementContents)
+ contents = @result
+ unless _tmp
+ self.pos = _save11
+ break
+ end
+ _tmp = match_string("//}")
+ unless _tmp
+ self.pos = _save11
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save11
+ break
+ end
+ _tmp = apply(:_EOL)
+ unless _tmp
+ self.pos = _save11
+ break
+ end
+ @result = begin; block_element(self, position, symbol, args, contents); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save11
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save16 = self.pos
+ while true # sequence
+ _save17 = self.pos
+ _tmp = match_string("//raw")
+ _tmp = _tmp ? nil : true
+ self.pos = _save17
+ unless _tmp
+ self.pos = _save16
+ break
+ end
+ _tmp = match_string("//")
+ unless _tmp
+ self.pos = _save16
+ break
+ end
+ _tmp = apply(:_ElementName)
+ symbol = @result
+ unless _tmp
+ self.pos = _save16
+ break
+ end
+ _ary = []
+ while true
+ _tmp = apply(:_BracketArg)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ args = @result
+ unless _tmp
+ self.pos = _save16
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save16
+ break
+ end
+ _tmp = apply(:_EOL)
+ unless _tmp
+ self.pos = _save16
+ break
+ end
+ @result = begin; block_element(self, position, symbol, args, nil); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save16
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_BlockElement unless _tmp
+ return _tmp
+ end
+
+ # RawBlockBuilderSelect = "|" Space* RawBlockBuilderSelectSub:c Space* "|" { c }
+ def _RawBlockBuilderSelect
+
+ _save = self.pos
+ while true # sequence
+ _tmp = match_string("|")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_RawBlockBuilderSelectSub)
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = match_string("|")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_RawBlockBuilderSelect unless _tmp
+ return _tmp
+ end
+
+ # RawBlockBuilderSelectSub = (< AlphanumericAscii+ >:c1 Space* "," Space* RawBlockBuilderSelectSub:c2 { [text] + c2 } | < AlphanumericAscii+ >:c1 { [text] })
+ def _RawBlockBuilderSelectSub
+
+ _save = self.pos
+ while true # choice
+
+ _save1 = self.pos
+ while true # sequence
+ _text_start = self.pos
+ _save2 = self.pos
+ _tmp = apply(:_AlphanumericAscii)
+ if _tmp
+ while true
+ _tmp = apply(:_AlphanumericAscii)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save2
+ end
+ if _tmp
+ text = get_text(_text_start)
+ end
+ c1 = @result
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ _tmp = match_string(",")
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ _tmp = apply(:_RawBlockBuilderSelectSub)
+ c2 = @result
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ @result = begin; [text] + c2 ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save5 = self.pos
+ while true # sequence
+ _text_start = self.pos
+ _save6 = self.pos
+ _tmp = apply(:_AlphanumericAscii)
+ if _tmp
+ while true
+ _tmp = apply(:_AlphanumericAscii)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save6
+ end
+ if _tmp
+ text = get_text(_text_start)
+ end
+ c1 = @result
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ @result = begin; [text] ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save5
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_RawBlockBuilderSelectSub unless _tmp
+ return _tmp
+ end
+
+ # RawBlockElementArg = !"]" ("\\]" { "]" } | "\\n" { "\n" } | < NonNewline > { text })
+ def _RawBlockElementArg
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _tmp = match_string("]")
+ _tmp = _tmp ? nil : true
+ self.pos = _save1
+ unless _tmp
+ self.pos = _save
+ break
+ end
+
+ _save2 = self.pos
+ while true # choice
+
+ _save3 = self.pos
+ while true # sequence
+ _tmp = match_string("\\]")
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ @result = begin; "]" ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save3
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save2
+
+ _save4 = self.pos
+ while true # sequence
+ _tmp = match_string("\\n")
+ unless _tmp
+ self.pos = _save4
+ break
+ end
+ @result = begin; "\n" ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save4
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save2
+
+ _save5 = self.pos
+ while true # sequence
+ _text_start = self.pos
+ _tmp = apply(:_NonNewline)
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ @result = begin; text ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save5
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save2
+ break
+ end # end choice
+
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_RawBlockElementArg unless _tmp
+ return _tmp
+ end
+
+ # BracketArg = "[" BracketArgInline*:content "]" {bracket_arg(self, position, content)}
+ def _BracketArg
+
+ _save = self.pos
+ while true # sequence
+ _tmp = match_string("[")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _ary = []
+ while true
+ _tmp = apply(:_BracketArgInline)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ content = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = match_string("]")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; bracket_arg(self, position, content); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_BracketArg unless _tmp
+ return _tmp
+ end
+
+ # BracketArgInline = (InlineElement:c { c } | "\\]" {text(self, position, "]")} | "\\\\" {text(self, position, "\\")} | < /[^\r\n\]]/ > {text(self, position, text)})
+ def _BracketArgInline
+
+ _save = self.pos
+ while true # choice
+
+ _save1 = self.pos
+ while true # sequence
+ _tmp = apply(:_InlineElement)
+ c = @result
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save2 = self.pos
+ while true # sequence
+ _tmp = match_string("\\]")
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ @result = begin; text(self, position, "]"); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save2
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save3 = self.pos
+ while true # sequence
+ _tmp = match_string("\\\\")
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ @result = begin; text(self, position, "\\"); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save3
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save4 = self.pos
+ while true # sequence
+ _text_start = self.pos
+ _tmp = scan(/\A(?-mix:[^\r\n\]])/)
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save4
+ break
+ end
+ @result = begin; text(self, position, text); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save4
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_BracketArgInline unless _tmp
+ return _tmp
+ end
+
+ # BraceArg = "{" < /([^\r\n}\\]|\\[^\r\n])*/ > "}" { text }
+ def _BraceArg
+
+ _save = self.pos
+ while true # sequence
+ _tmp = match_string("{")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _text_start = self.pos
+ _tmp = scan(/\A(?-mix:([^\r\n}\\]|\\[^\r\n])*)/)
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = match_string("}")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; text ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_BraceArg unless _tmp
+ return _tmp
+ end
+
+ # BlockElementContents = BlockElementContent*:c { c }
+ def _BlockElementContents
+
+ _save = self.pos
+ while true # sequence
+ _ary = []
+ while true
+ _tmp = apply(:_BlockElementContent)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_BlockElementContents unless _tmp
+ return _tmp
+ end
+
+ # BlockElementContent = (SinglelineComment:c { c } | BlockElement:c { c } | Ulist:c | Dlist:c | Olist:c | BlankLine:c { c } | BlockElementParagraph:c { c })
+ def _BlockElementContent
+
+ _save = self.pos
+ while true # choice
+
+ _save1 = self.pos
+ while true # sequence
+ _tmp = apply(:_SinglelineComment)
+ c = @result
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save2 = self.pos
+ while true # sequence
+ _tmp = apply(:_BlockElement)
+ c = @result
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save2
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+ _tmp = apply(:_Ulist)
+ c = @result
+ break if _tmp
+ self.pos = _save
+ _tmp = apply(:_Dlist)
+ c = @result
+ break if _tmp
+ self.pos = _save
+ _tmp = apply(:_Olist)
+ c = @result
+ break if _tmp
+ self.pos = _save
+
+ _save3 = self.pos
+ while true # sequence
+ _tmp = apply(:_BlankLine)
+ c = @result
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save3
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save4 = self.pos
+ while true # sequence
+ _tmp = apply(:_BlockElementParagraph)
+ c = @result
+ unless _tmp
+ self.pos = _save4
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save4
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_BlockElementContent unless _tmp
+ return _tmp
+ end
+
+ # BlockElementParagraph = BlockElementParagraphLine+:c {paragraph(self, position, c.flatten)}
+ def _BlockElementParagraph
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_BlockElementParagraphLine)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_BlockElementParagraphLine)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; paragraph(self, position, c.flatten); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_BlockElementParagraph unless _tmp
+ return _tmp
+ end
+
+ # BlockElementParagraphLine = !"//}" !BlankLine !SinglelineComment !BlockElement !Ulist !Olist !Dlist SinglelineContent:c Newline { c }
+ def _BlockElementParagraphLine
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _tmp = match_string("//}")
+ _tmp = _tmp ? nil : true
+ self.pos = _save1
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _tmp = apply(:_BlankLine)
+ _tmp = _tmp ? nil : true
+ self.pos = _save2
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save3 = self.pos
+ _tmp = apply(:_SinglelineComment)
+ _tmp = _tmp ? nil : true
+ self.pos = _save3
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save4 = self.pos
+ _tmp = apply(:_BlockElement)
+ _tmp = _tmp ? nil : true
+ self.pos = _save4
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save5 = self.pos
+ _tmp = apply(:_Ulist)
+ _tmp = _tmp ? nil : true
+ self.pos = _save5
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save6 = self.pos
+ _tmp = apply(:_Olist)
+ _tmp = _tmp ? nil : true
+ self.pos = _save6
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save7 = self.pos
+ _tmp = apply(:_Dlist)
+ _tmp = _tmp ? nil : true
+ self.pos = _save7
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_SinglelineContent)
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Newline)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_BlockElementParagraphLine unless _tmp
+ return _tmp
+ end
+
+ # CodeBlockElementContents = CodeBlockElementContent+:c { c }
+ def _CodeBlockElementContents
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_CodeBlockElementContent)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_CodeBlockElementContent)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_CodeBlockElementContents unless _tmp
+ return _tmp
+ end
+
+ # CodeBlockElementContent = (SinglelineComment:c { c } | BlankLine:c { ::ReVIEW::TextNode.new(self, position, "\n") } | !"//}" SinglelineContent:c Newline { [c, ::ReVIEW::TextNode.new(self, position, "\n")] })
+ def _CodeBlockElementContent
+
+ _save = self.pos
+ while true # choice
+
+ _save1 = self.pos
+ while true # sequence
+ _tmp = apply(:_SinglelineComment)
+ c = @result
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save2 = self.pos
+ while true # sequence
+ _tmp = apply(:_BlankLine)
+ c = @result
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ @result = begin; ::ReVIEW::TextNode.new(self, position, "\n") ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save2
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save3 = self.pos
+ while true # sequence
+ _save4 = self.pos
+ _tmp = match_string("//}")
+ _tmp = _tmp ? nil : true
+ self.pos = _save4
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ _tmp = apply(:_SinglelineContent)
+ c = @result
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ _tmp = apply(:_Newline)
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ @result = begin; [c, ::ReVIEW::TextNode.new(self, position, "\n")] ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save3
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_CodeBlockElementContent unless _tmp
+ return _tmp
+ end
+
+ # Bullet = "*"
+ def _Bullet
+ _tmp = match_string("*")
+ set_failed_rule :_Bullet unless _tmp
+ return _tmp
+ end
+
+ # Enumerator = < /[0-9]+/ > { num = text } "." { num.to_i }
+ def _Enumerator
+
+ _save = self.pos
+ while true # sequence
+ _text_start = self.pos
+ _tmp = scan(/\A(?-mix:[0-9]+)/)
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; num = text ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = match_string(".")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; num.to_i ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_Enumerator unless _tmp
+ return _tmp
+ end
+
+ # Ulist = Indent+:s Bullet+:b Space+ { @list_stack.push(s) } UlistItemBlock:item { if b.size > 1 then item.level = b.size end } (UlistItem | UlistItemMore | NestedList)*:items &{ s == @list_stack.pop } {ulist(self, position, items.unshift(item))}
+ def _Ulist
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_Indent)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_Indent)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ s = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _ary = []
+ _tmp = apply(:_Bullet)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_Bullet)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save2
+ end
+ b = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save3 = self.pos
+ _tmp = apply(:_Space)
+ if _tmp
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save3
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; @list_stack.push(s) ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_UlistItemBlock)
+ item = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; if b.size > 1 then item.level = b.size end ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _ary = []
+ while true
+
+ _save5 = self.pos
+ while true # choice
+ _tmp = apply(:_UlistItem)
+ break if _tmp
+ self.pos = _save5
+ _tmp = apply(:_UlistItemMore)
+ break if _tmp
+ self.pos = _save5
+ _tmp = apply(:_NestedList)
+ break if _tmp
+ self.pos = _save5
+ break
+ end # end choice
+
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ items = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save6 = self.pos
+ _tmp = begin; s == @list_stack.pop ; end
+ self.pos = _save6
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; ulist(self, position, items.unshift(item)); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_Ulist unless _tmp
+ return _tmp
+ end
+
+ # Olist = Indent+:s Enumerator:e Space+ { @list_stack.push(s) } OlistItemBlock:item { item.num = e } (OlistItem | NestedList)*:items &{ s == @list_stack.pop } {olist(self, position, items.unshift(item))}
+ def _Olist
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_Indent)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_Indent)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ s = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Enumerator)
+ e = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _tmp = apply(:_Space)
+ if _tmp
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save2
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; @list_stack.push(s) ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_OlistItemBlock)
+ item = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; item.num = e ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _ary = []
+ while true
+
+ _save4 = self.pos
+ while true # choice
+ _tmp = apply(:_OlistItem)
+ break if _tmp
+ self.pos = _save4
+ _tmp = apply(:_NestedList)
+ break if _tmp
+ self.pos = _save4
+ break
+ end # end choice
+
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ items = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save5 = self.pos
+ _tmp = begin; s == @list_stack.pop ; end
+ self.pos = _save5
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; olist(self, position, items.unshift(item)); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_Olist unless _tmp
+ return _tmp
+ end
+
+ # UlistItemBlock = ListItemFirstLine:c ListItemLine*:d {ulist_element(self, position, @list_stack.size, d.unshift(c))}
+ def _UlistItemBlock
+
+ _save = self.pos
+ while true # sequence
+ _tmp = apply(:_ListItemFirstLine)
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _ary = []
+ while true
+ _tmp = apply(:_ListItemLine)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ d = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; ulist_element(self, position, @list_stack.size, d.unshift(c)); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_UlistItemBlock unless _tmp
+ return _tmp
+ end
+
+ # OlistItemBlock = ListItemFirstLine:c ListItemLine*:d {olist_element(self, position, 0, d.unshift(c))}
+ def _OlistItemBlock
+
+ _save = self.pos
+ while true # sequence
+ _tmp = apply(:_ListItemFirstLine)
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _ary = []
+ while true
+ _tmp = apply(:_ListItemLine)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ d = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; olist_element(self, position, 0, d.unshift(c)); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_OlistItemBlock unless _tmp
+ return _tmp
+ end
+
+ # ListItemFirstLine = SinglelineContent:c Newline { c }
+ def _ListItemFirstLine
+
+ _save = self.pos
+ while true # sequence
+ _tmp = apply(:_SinglelineContent)
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Newline)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_ListItemFirstLine unless _tmp
+ return _tmp
+ end
+
+ # ListItemLine = Indent+:s !Bullet !Enumerator !Space SinglelineContent:c &{ check_indent(s) } Newline { c }
+ def _ListItemLine
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_Indent)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_Indent)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ s = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _tmp = apply(:_Bullet)
+ _tmp = _tmp ? nil : true
+ self.pos = _save2
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save3 = self.pos
+ _tmp = apply(:_Enumerator)
+ _tmp = _tmp ? nil : true
+ self.pos = _save3
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save4 = self.pos
+ _tmp = apply(:_Space)
+ _tmp = _tmp ? nil : true
+ self.pos = _save4
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_SinglelineContent)
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save5 = self.pos
+ _tmp = begin; check_indent(s) ; end
+ self.pos = _save5
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Newline)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_ListItemLine unless _tmp
+ return _tmp
+ end
+
+ # UlistItemMore = Indent+:s Bullet Bullet+:b Space+ &{ check_indent(s) } UlistItemBlock:item { item.level = b.size+1; item }
+ def _UlistItemMore
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_Indent)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_Indent)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ s = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Bullet)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _ary = []
+ _tmp = apply(:_Bullet)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_Bullet)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save2
+ end
+ b = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save3 = self.pos
+ _tmp = apply(:_Space)
+ if _tmp
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save3
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save4 = self.pos
+ _tmp = begin; check_indent(s) ; end
+ self.pos = _save4
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_UlistItemBlock)
+ item = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; item.level = b.size+1; item ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_UlistItemMore unless _tmp
+ return _tmp
+ end
+
+ # UlistItem = Indent+:s Bullet Space+ &{ check_indent(s) } UlistItemBlock:item { item }
+ def _UlistItem
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_Indent)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_Indent)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ s = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Bullet)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _tmp = apply(:_Space)
+ if _tmp
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save2
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save3 = self.pos
+ _tmp = begin; check_indent(s) ; end
+ self.pos = _save3
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_UlistItemBlock)
+ item = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; item ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_UlistItem unless _tmp
+ return _tmp
+ end
+
+ # OlistItem = Indent+:s Enumerator:e Space+ &{ check_indent(s) } OlistItemBlock:item { item.num = e; item }
+ def _OlistItem
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_Indent)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_Indent)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ s = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Enumerator)
+ e = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _tmp = apply(:_Space)
+ if _tmp
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save2
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save3 = self.pos
+ _tmp = begin; check_indent(s) ; end
+ self.pos = _save3
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_OlistItemBlock)
+ item = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; item.num = e; item ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_OlistItem unless _tmp
+ return _tmp
+ end
+
+ # NestedList = (NestedUlist | NestedOlist)
+ def _NestedList
+
+ _save = self.pos
+ while true # choice
+ _tmp = apply(:_NestedUlist)
+ break if _tmp
+ self.pos = _save
+ _tmp = apply(:_NestedOlist)
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_NestedList unless _tmp
+ return _tmp
+ end
+
+ # NestedUlist = Indent+:s Bullet Space+ &{ check_nested_indent(s) } { @list_stack.push(s) } UlistItemBlock:item (UlistItem | NestedList)*:items &{ s == @list_stack.pop } {ulist(self, position, items.unshift(item))}
+ def _NestedUlist
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_Indent)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_Indent)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ s = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Bullet)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _tmp = apply(:_Space)
+ if _tmp
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save2
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save3 = self.pos
+ _tmp = begin; check_nested_indent(s) ; end
+ self.pos = _save3
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; @list_stack.push(s) ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_UlistItemBlock)
+ item = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _ary = []
+ while true
+
+ _save5 = self.pos
+ while true # choice
+ _tmp = apply(:_UlistItem)
+ break if _tmp
+ self.pos = _save5
+ _tmp = apply(:_NestedList)
+ break if _tmp
+ self.pos = _save5
+ break
+ end # end choice
+
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ items = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save6 = self.pos
+ _tmp = begin; s == @list_stack.pop ; end
+ self.pos = _save6
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; ulist(self, position, items.unshift(item)); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_NestedUlist unless _tmp
+ return _tmp
+ end
+
+ # NestedOlist = Indent+:s Enumerator:e Space+ &{ check_nested_indent(s) } { @list_stack.push(s) } OlistItemBlock:item { item.num = e } (OlistItem | NestedList)*:items &{ s == @list_stack.pop } {olist(self, position, items.unshift(item))}
+ def _NestedOlist
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_Indent)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_Indent)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ s = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Enumerator)
+ e = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _tmp = apply(:_Space)
+ if _tmp
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save2
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save3 = self.pos
+ _tmp = begin; check_nested_indent(s) ; end
+ self.pos = _save3
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; @list_stack.push(s) ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_OlistItemBlock)
+ item = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; item.num = e ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _ary = []
+ while true
+
+ _save5 = self.pos
+ while true # choice
+ _tmp = apply(:_OlistItem)
+ break if _tmp
+ self.pos = _save5
+ _tmp = apply(:_NestedList)
+ break if _tmp
+ self.pos = _save5
+ break
+ end # end choice
+
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ items = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save6 = self.pos
+ _tmp = begin; s == @list_stack.pop ; end
+ self.pos = _save6
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; olist(self, position, items.unshift(item)); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_NestedOlist unless _tmp
+ return _tmp
+ end
+
+ # Dlist = (DlistElement | SinglelineComment)+:content {dlist(self, position, content)}
+ def _Dlist
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+
+ _save2 = self.pos
+ while true # choice
+ _tmp = apply(:_DlistElement)
+ break if _tmp
+ self.pos = _save2
+ _tmp = apply(:_SinglelineComment)
+ break if _tmp
+ self.pos = _save2
+ break
+ end # end choice
+
+ if _tmp
+ _ary << @result
+ while true
+
+ _save3 = self.pos
+ while true # choice
+ _tmp = apply(:_DlistElement)
+ break if _tmp
+ self.pos = _save3
+ _tmp = apply(:_SinglelineComment)
+ break if _tmp
+ self.pos = _save3
+ break
+ end # end choice
+
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ content = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; dlist(self, position, content); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_Dlist unless _tmp
+ return _tmp
+ end
+
+ # DlistElement = Indent* ":" Space+ SinglelineContent:text Newline DlistElementContent+:content {dlist_element(self, position, text, content)}
+ def _DlistElement
+
+ _save = self.pos
+ while true # sequence
+ while true
+ _tmp = apply(:_Indent)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = match_string(":")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _tmp = apply(:_Space)
+ if _tmp
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save2
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_SinglelineContent)
+ text = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_Newline)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save3 = self.pos
+ _ary = []
+ _tmp = apply(:_DlistElementContent)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_DlistElementContent)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save3
+ end
+ content = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; dlist_element(self, position, text, content); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_DlistElement unless _tmp
+ return _tmp
+ end
+
+ # DlistElementContent = (SinglelineComment:c { c } | Space+ SinglelineContent:c Newline { c })
+ def _DlistElementContent
+
+ _save = self.pos
+ while true # choice
+
+ _save1 = self.pos
+ while true # sequence
+ _tmp = apply(:_SinglelineComment)
+ c = @result
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save2 = self.pos
+ while true # sequence
+ _save3 = self.pos
+ _tmp = apply(:_Space)
+ if _tmp
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save3
+ end
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _tmp = apply(:_SinglelineContent)
+ c = @result
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _tmp = apply(:_Newline)
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save2
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_DlistElementContent unless _tmp
+ return _tmp
+ end
+
+ # SinglelineContent = Inline+:c {singleline_content(self, position, c)}
+ def _SinglelineContent
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_Inline)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_Inline)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; singleline_content(self, position, c); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_SinglelineContent unless _tmp
+ return _tmp
+ end
+
+ # Inline = (InlineElement | NonInlineElement)
+ def _Inline
+
+ _save = self.pos
+ while true # choice
+ _tmp = apply(:_InlineElement)
+ break if _tmp
+ self.pos = _save
+ _tmp = apply(:_NonInlineElement)
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_Inline unless _tmp
+ return _tmp
+ end
+
+ # NonInlineElement = !InlineElement < NonNewline > {text(self, position, text)}
+ def _NonInlineElement
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _tmp = apply(:_InlineElement)
+ _tmp = _tmp ? nil : true
+ self.pos = _save1
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _text_start = self.pos
+ _tmp = apply(:_NonNewline)
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; text(self, position, text); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_NonInlineElement unless _tmp
+ return _tmp
+ end
+
+ # InlineElement = (RawInlineElement:c { c } | !RawInlineElement "@<" InlineElementSymbol:symbol ">" "{" InlineElementContents?:contents "}" {inline_element(self, position, symbol,contents)} | !RawInlineElement "@<" ComplexInlineElementSymbol:symbol ">" "{" ComplexInlineElementContents?:contents "}" {complex_inline_element(self, position, symbol,contents)})
+ def _InlineElement
+
+ _save = self.pos
+ while true # choice
+
+ _save1 = self.pos
+ while true # sequence
+ _tmp = apply(:_RawInlineElement)
+ c = @result
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save2 = self.pos
+ while true # sequence
+ _save3 = self.pos
+ _tmp = apply(:_RawInlineElement)
+ _tmp = _tmp ? nil : true
+ self.pos = _save3
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _tmp = match_string("@<")
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _tmp = apply(:_InlineElementSymbol)
+ symbol = @result
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _tmp = match_string(">")
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _tmp = match_string("{")
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _save4 = self.pos
+ _tmp = apply(:_InlineElementContents)
+ @result = nil unless _tmp
+ unless _tmp
+ _tmp = true
+ self.pos = _save4
+ end
+ contents = @result
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _tmp = match_string("}")
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ @result = begin; inline_element(self, position, symbol,contents); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save2
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save5 = self.pos
+ while true # sequence
+ _save6 = self.pos
+ _tmp = apply(:_RawInlineElement)
+ _tmp = _tmp ? nil : true
+ self.pos = _save6
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = match_string("@<")
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = apply(:_ComplexInlineElementSymbol)
+ symbol = @result
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = match_string(">")
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = match_string("{")
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _save7 = self.pos
+ _tmp = apply(:_ComplexInlineElementContents)
+ @result = nil unless _tmp
+ unless _tmp
+ _tmp = true
+ self.pos = _save7
+ end
+ contents = @result
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _tmp = match_string("}")
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ @result = begin; complex_inline_element(self, position, symbol,contents); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save5
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_InlineElement unless _tmp
+ return _tmp
+ end
+
+ # RawInlineElement = "@{" RawBlockBuilderSelect?:builders RawInlineElementContent+:c "}" {raw(self, builders, position, c)}
+ def _RawInlineElement
+
+ _save = self.pos
+ while true # sequence
+ _tmp = match_string("@{")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save1 = self.pos
+ _tmp = apply(:_RawBlockBuilderSelect)
+ @result = nil unless _tmp
+ unless _tmp
+ _tmp = true
+ self.pos = _save1
+ end
+ builders = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _ary = []
+ _tmp = apply(:_RawInlineElementContent)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_RawInlineElementContent)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save2
+ end
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = match_string("}")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; raw(self, builders, position, c); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_RawInlineElement unless _tmp
+ return _tmp
+ end
+
+ # RawInlineElementContent = ("\\}" { "}" } | < /[^\r\n\}]/ > { text })
+ def _RawInlineElementContent
+
+ _save = self.pos
+ while true # choice
+
+ _save1 = self.pos
+ while true # sequence
+ _tmp = match_string("\\}")
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ @result = begin; "}" ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save2 = self.pos
+ while true # sequence
+ _text_start = self.pos
+ _tmp = scan(/\A(?-mix:[^\r\n\}])/)
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ @result = begin; text ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save2
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_RawInlineElementContent unless _tmp
+ return _tmp
+ end
+
+ # InlineElementSymbol = < AlphanumericAscii+ >:s &{ check_inline_element_symbol(text) } { text }
+ def _InlineElementSymbol
+
+ _save = self.pos
+ while true # sequence
+ _text_start = self.pos
+ _save1 = self.pos
+ _tmp = apply(:_AlphanumericAscii)
+ if _tmp
+ while true
+ _tmp = apply(:_AlphanumericAscii)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save1
+ end
+ if _tmp
+ text = get_text(_text_start)
+ end
+ s = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _tmp = begin; check_inline_element_symbol(text) ; end
+ self.pos = _save2
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; text ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_InlineElementSymbol unless _tmp
+ return _tmp
+ end
+
+ # InlineElementContents = !"}" InlineElementContentsSub:c { c }
+ def _InlineElementContents
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _tmp = match_string("}")
+ _tmp = _tmp ? nil : true
+ self.pos = _save1
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_InlineElementContentsSub)
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_InlineElementContents unless _tmp
+ return _tmp
+ end
+
+ # InlineElementContentsSub = !"}" Space* InlineElementContent:c1 Space* { [c1] }
+ def _InlineElementContentsSub
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _tmp = match_string("}")
+ _tmp = _tmp ? nil : true
+ self.pos = _save1
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_InlineElementContent)
+ c1 = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; [c1] ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_InlineElementContentsSub unless _tmp
+ return _tmp
+ end
+
+ # ComplexInlineElementSymbol = < AlphanumericAscii+ > &{ check_complex_inline_element_symbol(text) } { text }
+ def _ComplexInlineElementSymbol
+
+ _save = self.pos
+ while true # sequence
+ _text_start = self.pos
+ _save1 = self.pos
+ _tmp = apply(:_AlphanumericAscii)
+ if _tmp
+ while true
+ _tmp = apply(:_AlphanumericAscii)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save1
+ end
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save2 = self.pos
+ _tmp = begin; check_complex_inline_element_symbol(text) ; end
+ self.pos = _save2
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; text ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_ComplexInlineElementSymbol unless _tmp
+ return _tmp
+ end
+
+ # ComplexInlineElementContents = !"}" ComplexInlineElementContentsSub:c { c }
+ def _ComplexInlineElementContents
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _tmp = match_string("}")
+ _tmp = _tmp ? nil : true
+ self.pos = _save1
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = apply(:_ComplexInlineElementContentsSub)
+ c = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_ComplexInlineElementContents unless _tmp
+ return _tmp
+ end
+
+ # ComplexInlineElementContentsSub = !"}" (Space* InlineElementContent:c1 Space* "," ComplexInlineElementContentsSub:c2 { [c1]+c2 } | Space* InlineElementContent:c1 Space* { [c1] })
+ def _ComplexInlineElementContentsSub
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _tmp = match_string("}")
+ _tmp = _tmp ? nil : true
+ self.pos = _save1
+ unless _tmp
+ self.pos = _save
+ break
+ end
+
+ _save2 = self.pos
+ while true # choice
+
+ _save3 = self.pos
+ while true # sequence
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ _tmp = apply(:_InlineElementContent)
+ c1 = @result
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ _tmp = match_string(",")
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ _tmp = apply(:_ComplexInlineElementContentsSub)
+ c2 = @result
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ @result = begin; [c1]+c2 ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save3
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save2
+
+ _save6 = self.pos
+ while true # sequence
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save6
+ break
+ end
+ _tmp = apply(:_InlineElementContent)
+ c1 = @result
+ unless _tmp
+ self.pos = _save6
+ break
+ end
+ while true
+ _tmp = apply(:_Space)
+ break unless _tmp
+ end
+ _tmp = true
+ unless _tmp
+ self.pos = _save6
+ break
+ end
+ @result = begin; [c1] ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save6
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save2
+ break
+ end # end choice
+
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_ComplexInlineElementContentsSub unless _tmp
+ return _tmp
+ end
+
+ # InlineElementContent = InlineElementContentSub+:d { d }
+ def _InlineElementContent
+
+ _save = self.pos
+ while true # sequence
+ _save1 = self.pos
+ _ary = []
+ _tmp = apply(:_InlineElementContentSub)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_InlineElementContentSub)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ d = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; d ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_InlineElementContent unless _tmp
+ return _tmp
+ end
+
+ # InlineElementContentSub = (InlineElement:c { c } | !InlineElement QuotedInlineText:content {inline_element_content(self, position, content)} | !InlineElement InlineElementContentText+:content {inline_element_content(self, position, content)})
+ def _InlineElementContentSub
+
+ _save = self.pos
+ while true # choice
+
+ _save1 = self.pos
+ while true # sequence
+ _tmp = apply(:_InlineElement)
+ c = @result
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ @result = begin; c ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save2 = self.pos
+ while true # sequence
+ _save3 = self.pos
+ _tmp = apply(:_InlineElement)
+ _tmp = _tmp ? nil : true
+ self.pos = _save3
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ _tmp = apply(:_QuotedInlineText)
+ content = @result
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ @result = begin; inline_element_content(self, position, content); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save2
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save4 = self.pos
+ while true # sequence
+ _save5 = self.pos
+ _tmp = apply(:_InlineElement)
+ _tmp = _tmp ? nil : true
+ self.pos = _save5
+ unless _tmp
+ self.pos = _save4
+ break
+ end
+ _save6 = self.pos
+ _ary = []
+ _tmp = apply(:_InlineElementContentText)
+ if _tmp
+ _ary << @result
+ while true
+ _tmp = apply(:_InlineElementContentText)
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save6
+ end
+ content = @result
+ unless _tmp
+ self.pos = _save4
+ break
+ end
+ @result = begin; inline_element_content(self, position, content); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save4
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_InlineElementContentSub unless _tmp
+ return _tmp
+ end
+
+ # QuotedInlineText = "\"" ("\\\"" { "\"" } | "\\\\" { "\\" } | < /[^"\r\n\\]/ > { text })+:str "\"" {text(self, position, str.join(""))}
+ def _QuotedInlineText
+
+ _save = self.pos
+ while true # sequence
+ _tmp = match_string("\"")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _save1 = self.pos
+ _ary = []
+
+ _save2 = self.pos
+ while true # choice
+
+ _save3 = self.pos
+ while true # sequence
+ _tmp = match_string("\\\"")
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ @result = begin; "\"" ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save3
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save2
+
+ _save4 = self.pos
+ while true # sequence
+ _tmp = match_string("\\\\")
+ unless _tmp
+ self.pos = _save4
+ break
+ end
+ @result = begin; "\\" ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save4
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save2
+
+ _save5 = self.pos
+ while true # sequence
+ _text_start = self.pos
+ _tmp = scan(/\A(?-mix:[^"\r\n\\])/)
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ @result = begin; text ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save5
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save2
+ break
+ end # end choice
+
+ if _tmp
+ _ary << @result
+ while true
+
+ _save6 = self.pos
+ while true # choice
+
+ _save7 = self.pos
+ while true # sequence
+ _tmp = match_string("\\\"")
+ unless _tmp
+ self.pos = _save7
+ break
+ end
+ @result = begin; "\"" ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save7
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save6
+
+ _save8 = self.pos
+ while true # sequence
+ _tmp = match_string("\\\\")
+ unless _tmp
+ self.pos = _save8
+ break
+ end
+ @result = begin; "\\" ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save8
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save6
+
+ _save9 = self.pos
+ while true # sequence
+ _text_start = self.pos
+ _tmp = scan(/\A(?-mix:[^"\r\n\\])/)
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save9
+ break
+ end
+ @result = begin; text ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save9
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save6
+ break
+ end # end choice
+
+ _ary << @result if _tmp
+ break unless _tmp
+ end
+ _tmp = true
+ @result = _ary
+ else
+ self.pos = _save1
+ end
+ str = @result
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ _tmp = match_string("\"")
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; text(self, position, str.join("")); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_QuotedInlineText unless _tmp
+ return _tmp
+ end
+
+ # InlineElementContentText = ("\\}" {text(self, position, "}")} | "\\," {text(self, position, ",")} | "\\\\" {text(self, position, "\\" )} | "\\" {text(self, position, "\\" )} | !InlineElement < /[^\r\n\\},]/ > {text(self, position, text)})
+ def _InlineElementContentText
+
+ _save = self.pos
+ while true # choice
+
+ _save1 = self.pos
+ while true # sequence
+ _tmp = match_string("\\}")
+ unless _tmp
+ self.pos = _save1
+ break
+ end
+ @result = begin; text(self, position, "}"); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save1
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save2 = self.pos
+ while true # sequence
+ _tmp = match_string("\\,")
+ unless _tmp
+ self.pos = _save2
+ break
+ end
+ @result = begin; text(self, position, ","); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save2
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save3 = self.pos
+ while true # sequence
+ _tmp = match_string("\\\\")
+ unless _tmp
+ self.pos = _save3
+ break
+ end
+ @result = begin; text(self, position, "\\" ); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save3
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save4 = self.pos
+ while true # sequence
+ _tmp = match_string("\\")
+ unless _tmp
+ self.pos = _save4
+ break
+ end
+ @result = begin; text(self, position, "\\" ); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save4
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+
+ _save5 = self.pos
+ while true # sequence
+ _save6 = self.pos
+ _tmp = apply(:_InlineElement)
+ _tmp = _tmp ? nil : true
+ self.pos = _save6
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ _text_start = self.pos
+ _tmp = scan(/\A(?-mix:[^\r\n\\},])/)
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save5
+ break
+ end
+ @result = begin; text(self, position, text); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save5
+ end
+ break
+ end # end sequence
+
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_InlineElementContentText unless _tmp
+ return _tmp
+ end
+
+ # NonNewline = /[^\r\n]/
+ def _NonNewline
+ _tmp = scan(/\A(?-mix:[^\r\n])/)
+ set_failed_rule :_NonNewline unless _tmp
+ return _tmp
+ end
+
+ # Space = /[ \t]/
+ def _Space
+ _tmp = scan(/\A(?-mix:[ \t])/)
+ set_failed_rule :_Space unless _tmp
+ return _tmp
+ end
+
+ # Indent = " "
+ def _Indent
+ _tmp = match_string(" ")
+ set_failed_rule :_Indent unless _tmp
+ return _tmp
+ end
+
+ # EOL = (Newline | EOF)
+ def _EOL
+
+ _save = self.pos
+ while true # choice
+ _tmp = apply(:_Newline)
+ break if _tmp
+ self.pos = _save
+ _tmp = apply(:_EOF)
+ break if _tmp
+ self.pos = _save
+ break
+ end # end choice
+
+ set_failed_rule :_EOL unless _tmp
+ return _tmp
+ end
+
+ # EOF = !.
+ def _EOF
+ _save = self.pos
+ _tmp = get_byte
+ _tmp = _tmp ? nil : true
+ self.pos = _save
+ set_failed_rule :_EOF unless _tmp
+ return _tmp
+ end
+
+ # ElementName = < LowerAlphabetAscii+ > { text }
+ def _ElementName
+
+ _save = self.pos
+ while true # sequence
+ _text_start = self.pos
+ _save1 = self.pos
+ _tmp = apply(:_LowerAlphabetAscii)
+ if _tmp
+ while true
+ _tmp = apply(:_LowerAlphabetAscii)
+ break unless _tmp
+ end
+ _tmp = true
+ else
+ self.pos = _save1
+ end
+ if _tmp
+ text = get_text(_text_start)
+ end
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; text ; end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+
+ set_failed_rule :_ElementName unless _tmp
+ return _tmp
+ end
+
+ # AlphanumericAscii = /[A-Za-z0-9]/
+ def _AlphanumericAscii
+ _tmp = scan(/\A(?-mix:[A-Za-z0-9])/)
+ set_failed_rule :_AlphanumericAscii unless _tmp
+ return _tmp
+ end
+
+ # LowerAlphabetAscii = /[a-z]/
+ def _LowerAlphabetAscii
+ _tmp = scan(/\A(?-mix:[a-z])/)
+ set_failed_rule :_LowerAlphabetAscii unless _tmp
+ return _tmp
+ end
+
+ # Digit = /[0-9]/
+ def _Digit
+ _tmp = scan(/\A(?-mix:[0-9])/)
+ set_failed_rule :_Digit unless _tmp
+ return _tmp
+ end
+
+ # BOM = "uFEFF"
+ def _BOM
+ _tmp = match_string("uFEFF")
+ set_failed_rule :_BOM unless _tmp
+ return _tmp
+ end
+
+ # Newline = /\n|\r\n?|\p{Zl}|\p{Zp}/ {newline(self, position, "\n")}
+ def _Newline
+
+ _save = self.pos
+ while true # sequence
+ _tmp = scan(/\A(?-mix:\n|\r\n?|\p{Zl}|\p{Zp})/)
+ unless _tmp
+ self.pos = _save
+ break
+ end
+ @result = begin; newline(self, position, "\n"); end
+ _tmp = true
+ unless _tmp
+ self.pos = _save
+ end
+ break
+ end # end sequence
+ set_failed_rule :_Newline unless _tmp
+ return _tmp
end
-end # module ReVIEW
+ Rules = {}
+ Rules[:_root] = rule_info("root", "Start")
+ Rules[:_Start] = rule_info("Start", "&. { @list_stack = Array.new } Document:c { @strategy.ast = c }")
+ Rules[:_Document] = rule_info("Document", "BOM? Block*:c {document(self, position, c)}")
+ Rules[:_Block] = rule_info("Block", "BlankLine*:c { c } (SinglelineComment:c | Headline:c | BlockElement:c | Ulist:c | Olist:c | Dlist:c | Paragraph:c) { c }")
+ Rules[:_BlankLine] = rule_info("BlankLine", "Newline")
+ Rules[:_SinglelineComment] = rule_info("SinglelineComment", "\"\#@\" < NonNewline+ > EOL {singleline_comment(self, position, text)}")
+ Rules[:_Headline] = rule_info("Headline", "HeadlinePrefix:level BracketArg?:cmd BraceArg?:label Space* SinglelineContent?:caption EOL {headline(self, position, level, cmd, label, caption)}")
+ Rules[:_HeadlinePrefix] = rule_info("HeadlinePrefix", "< /={1,5}/ > { text.length }")
+ Rules[:_Paragraph] = rule_info("Paragraph", "ParagraphLine+:c {paragraph(self, position, c.flatten)}")
+ Rules[:_ParagraphLine] = rule_info("ParagraphLine", "!Headline !SinglelineComment !BlockElement !Ulist !Olist !Dlist SinglelineContent:c Newline { c }")
+ Rules[:_BlockElement] = rule_info("BlockElement", "(\"//raw[\" RawBlockBuilderSelect?:b RawBlockElementArg*:r1 \"]\" Space* EOL {raw(self, b, position, r1)} | !\"//raw\" \"//\" ElementName:symbol &{ syntax = syntax_descriptor(symbol); syntax && syntax.code_block? } BracketArg*:args \"{\" Space* Newline CodeBlockElementContents:contents \"//}\" Space* EOL {code_block_element(self, position, symbol, args, contents)} | !\"//raw\" \"//\" ElementName:symbol BracketArg*:args \"{\" Space* Newline BlockElementContents:contents \"//}\" Space* EOL {block_element(self, position, symbol, args, contents)} | !\"//raw\" \"//\" ElementName:symbol BracketArg*:args Space* EOL {block_element(self, position, symbol, args, nil)})")
+ Rules[:_RawBlockBuilderSelect] = rule_info("RawBlockBuilderSelect", "\"|\" Space* RawBlockBuilderSelectSub:c Space* \"|\" { c }")
+ Rules[:_RawBlockBuilderSelectSub] = rule_info("RawBlockBuilderSelectSub", "(< AlphanumericAscii+ >:c1 Space* \",\" Space* RawBlockBuilderSelectSub:c2 { [text] + c2 } | < AlphanumericAscii+ >:c1 { [text] })")
+ Rules[:_RawBlockElementArg] = rule_info("RawBlockElementArg", "!\"]\" (\"\\\\]\" { \"]\" } | \"\\\\n\" { \"\\n\" } | < NonNewline > { text })")
+ Rules[:_BracketArg] = rule_info("BracketArg", "\"[\" BracketArgInline*:content \"]\" {bracket_arg(self, position, content)}")
+ Rules[:_BracketArgInline] = rule_info("BracketArgInline", "(InlineElement:c { c } | \"\\\\]\" {text(self, position, \"]\")} | \"\\\\\\\\\" {text(self, position, \"\\\\\")} | < /[^\\r\\n\\]]/ > {text(self, position, text)})")
+ Rules[:_BraceArg] = rule_info("BraceArg", "\"{\" < /([^\\r\\n}\\\\]|\\\\[^\\r\\n])*/ > \"}\" { text }")
+ Rules[:_BlockElementContents] = rule_info("BlockElementContents", "BlockElementContent*:c { c }")
+ Rules[:_BlockElementContent] = rule_info("BlockElementContent", "(SinglelineComment:c { c } | BlockElement:c { c } | Ulist:c | Dlist:c | Olist:c | BlankLine:c { c } | BlockElementParagraph:c { c })")
+ Rules[:_BlockElementParagraph] = rule_info("BlockElementParagraph", "BlockElementParagraphLine+:c {paragraph(self, position, c.flatten)}")
+ Rules[:_BlockElementParagraphLine] = rule_info("BlockElementParagraphLine", "!\"//}\" !BlankLine !SinglelineComment !BlockElement !Ulist !Olist !Dlist SinglelineContent:c Newline { c }")
+ Rules[:_CodeBlockElementContents] = rule_info("CodeBlockElementContents", "CodeBlockElementContent+:c { c }")
+ Rules[:_CodeBlockElementContent] = rule_info("CodeBlockElementContent", "(SinglelineComment:c { c } | BlankLine:c { ::ReVIEW::TextNode.new(self, position, \"\\n\") } | !\"//}\" SinglelineContent:c Newline { [c, ::ReVIEW::TextNode.new(self, position, \"\\n\")] })")
+ Rules[:_Bullet] = rule_info("Bullet", "\"*\"")
+ Rules[:_Enumerator] = rule_info("Enumerator", "< /[0-9]+/ > { num = text } \".\" { num.to_i }")
+ Rules[:_Ulist] = rule_info("Ulist", "Indent+:s Bullet+:b Space+ { @list_stack.push(s) } UlistItemBlock:item { if b.size > 1 then item.level = b.size end } (UlistItem | UlistItemMore | NestedList)*:items &{ s == @list_stack.pop } {ulist(self, position, items.unshift(item))}")
+ Rules[:_Olist] = rule_info("Olist", "Indent+:s Enumerator:e Space+ { @list_stack.push(s) } OlistItemBlock:item { item.num = e } (OlistItem | NestedList)*:items &{ s == @list_stack.pop } {olist(self, position, items.unshift(item))}")
+ Rules[:_UlistItemBlock] = rule_info("UlistItemBlock", "ListItemFirstLine:c ListItemLine*:d {ulist_element(self, position, @list_stack.size, d.unshift(c))}")
+ Rules[:_OlistItemBlock] = rule_info("OlistItemBlock", "ListItemFirstLine:c ListItemLine*:d {olist_element(self, position, 0, d.unshift(c))}")
+ Rules[:_ListItemFirstLine] = rule_info("ListItemFirstLine", "SinglelineContent:c Newline { c }")
+ Rules[:_ListItemLine] = rule_info("ListItemLine", "Indent+:s !Bullet !Enumerator !Space SinglelineContent:c &{ check_indent(s) } Newline { c }")
+ Rules[:_UlistItemMore] = rule_info("UlistItemMore", "Indent+:s Bullet Bullet+:b Space+ &{ check_indent(s) } UlistItemBlock:item { item.level = b.size+1; item }")
+ Rules[:_UlistItem] = rule_info("UlistItem", "Indent+:s Bullet Space+ &{ check_indent(s) } UlistItemBlock:item { item }")
+ Rules[:_OlistItem] = rule_info("OlistItem", "Indent+:s Enumerator:e Space+ &{ check_indent(s) } OlistItemBlock:item { item.num = e; item }")
+ Rules[:_NestedList] = rule_info("NestedList", "(NestedUlist | NestedOlist)")
+ Rules[:_NestedUlist] = rule_info("NestedUlist", "Indent+:s Bullet Space+ &{ check_nested_indent(s) } { @list_stack.push(s) } UlistItemBlock:item (UlistItem | NestedList)*:items &{ s == @list_stack.pop } {ulist(self, position, items.unshift(item))}")
+ Rules[:_NestedOlist] = rule_info("NestedOlist", "Indent+:s Enumerator:e Space+ &{ check_nested_indent(s) } { @list_stack.push(s) } OlistItemBlock:item { item.num = e } (OlistItem | NestedList)*:items &{ s == @list_stack.pop } {olist(self, position, items.unshift(item))}")
+ Rules[:_Dlist] = rule_info("Dlist", "(DlistElement | SinglelineComment)+:content {dlist(self, position, content)}")
+ Rules[:_DlistElement] = rule_info("DlistElement", "Indent* \":\" Space+ SinglelineContent:text Newline DlistElementContent+:content {dlist_element(self, position, text, content)}")
+ Rules[:_DlistElementContent] = rule_info("DlistElementContent", "(SinglelineComment:c { c } | Space+ SinglelineContent:c Newline { c })")
+ Rules[:_SinglelineContent] = rule_info("SinglelineContent", "Inline+:c {singleline_content(self, position, c)}")
+ Rules[:_Inline] = rule_info("Inline", "(InlineElement | NonInlineElement)")
+ Rules[:_NonInlineElement] = rule_info("NonInlineElement", "!InlineElement < NonNewline > {text(self, position, text)}")
+ Rules[:_InlineElement] = rule_info("InlineElement", "(RawInlineElement:c { c } | !RawInlineElement \"@<\" InlineElementSymbol:symbol \">\" \"{\" InlineElementContents?:contents \"}\" {inline_element(self, position, symbol,contents)} | !RawInlineElement \"@<\" ComplexInlineElementSymbol:symbol \">\" \"{\" ComplexInlineElementContents?:contents \"}\" {complex_inline_element(self, position, symbol,contents)})")
+ Rules[:_RawInlineElement] = rule_info("RawInlineElement", "\"@{\" RawBlockBuilderSelect?:builders RawInlineElementContent+:c \"}\" {raw(self, builders, position, c)}")
+ Rules[:_RawInlineElementContent] = rule_info("RawInlineElementContent", "(\"\\\\}\" { \"}\" } | < /[^\\r\\n\\}]/ > { text })")
+ Rules[:_InlineElementSymbol] = rule_info("InlineElementSymbol", "< AlphanumericAscii+ >:s &{ check_inline_element_symbol(text) } { text }")
+ Rules[:_InlineElementContents] = rule_info("InlineElementContents", "!\"}\" InlineElementContentsSub:c { c }")
+ Rules[:_InlineElementContentsSub] = rule_info("InlineElementContentsSub", "!\"}\" Space* InlineElementContent:c1 Space* { [c1] }")
+ Rules[:_ComplexInlineElementSymbol] = rule_info("ComplexInlineElementSymbol", "< AlphanumericAscii+ > &{ check_complex_inline_element_symbol(text) } { text }")
+ Rules[:_ComplexInlineElementContents] = rule_info("ComplexInlineElementContents", "!\"}\" ComplexInlineElementContentsSub:c { c }")
+ Rules[:_ComplexInlineElementContentsSub] = rule_info("ComplexInlineElementContentsSub", "!\"}\" (Space* InlineElementContent:c1 Space* \",\" ComplexInlineElementContentsSub:c2 { [c1]+c2 } | Space* InlineElementContent:c1 Space* { [c1] })")
+ Rules[:_InlineElementContent] = rule_info("InlineElementContent", "InlineElementContentSub+:d { d }")
+ Rules[:_InlineElementContentSub] = rule_info("InlineElementContentSub", "(InlineElement:c { c } | !InlineElement QuotedInlineText:content {inline_element_content(self, position, content)} | !InlineElement InlineElementContentText+:content {inline_element_content(self, position, content)})")
+ Rules[:_QuotedInlineText] = rule_info("QuotedInlineText", "\"\\\"\" (\"\\\\\\\"\" { \"\\\"\" } | \"\\\\\\\\\" { \"\\\\\" } | < /[^\"\\r\\n\\\\]/ > { text })+:str \"\\\"\" {text(self, position, str.join(\"\"))}")
+ Rules[:_InlineElementContentText] = rule_info("InlineElementContentText", "(\"\\\\}\" {text(self, position, \"}\")} | \"\\\\,\" {text(self, position, \",\")} | \"\\\\\\\\\" {text(self, position, \"\\\\\" )} | \"\\\\\" {text(self, position, \"\\\\\" )} | !InlineElement < /[^\\r\\n\\\\},]/ > {text(self, position, text)})")
+ Rules[:_NonNewline] = rule_info("NonNewline", "/[^\\r\\n]/")
+ Rules[:_Space] = rule_info("Space", "/[ \\t]/")
+ Rules[:_Indent] = rule_info("Indent", "\" \"")
+ Rules[:_EOL] = rule_info("EOL", "(Newline | EOF)")
+ Rules[:_EOF] = rule_info("EOF", "!.")
+ Rules[:_ElementName] = rule_info("ElementName", "< LowerAlphabetAscii+ > { text }")
+ Rules[:_AlphanumericAscii] = rule_info("AlphanumericAscii", "/[A-Za-z0-9]/")
+ Rules[:_LowerAlphabetAscii] = rule_info("LowerAlphabetAscii", "/[a-z]/")
+ Rules[:_Digit] = rule_info("Digit", "/[0-9]/")
+ Rules[:_BOM] = rule_info("BOM", "\"uFEFF\"")
+ Rules[:_Newline] = rule_info("Newline", "/\\n|\\r\\n?|\\p{Zl}|\\p{Zp}/ {newline(self, position, \"\\n\")}")
+ # :startdoc:
+end
diff --git a/lib/review/extentions.rb b/lib/review/extentions.rb
index 5293a74b9..6815193c0 100644
--- a/lib/review/extentions.rb
+++ b/lib/review/extentions.rb
@@ -1,4 +1,5 @@
require 'review/extentions/object'
require 'review/extentions/string'
+require 'review/extentions/array'
require 'review/extentions/hash'
diff --git a/lib/review/extentions/array.rb b/lib/review/extentions/array.rb
new file mode 100644
index 000000000..446bae0a8
--- /dev/null
+++ b/lib/review/extentions/array.rb
@@ -0,0 +1,25 @@
+class Array
+
+ # for ReVIEW::Node
+ #
+ def to_doc
+ self.map(&:to_doc).join("")
+ end
+
+ # for ReVIEW::Node
+ #
+ def to_raw
+ self.map(&:to_raw).join("")
+ end
+
+ if [].map.kind_of?(Array)
+ # Ruby 1.8
+ def map(&block)
+ if !block_given?
+ return to_enum :map
+ else
+ collect(&block) ## XXX same as original
+ end
+ end
+ end
+end
diff --git a/lib/review/htmlbuilder.rb b/lib/review/htmlbuilder.rb
index 0ace2a7a3..91b885b1d 100644
--- a/lib/review/htmlbuilder.rb
+++ b/lib/review/htmlbuilder.rb
@@ -29,13 +29,6 @@ class HTMLBuilder < Builder
Compiler.defblock(:point, 0..1)
Compiler.defblock(:shoot, 0..1)
- def pre_paragraph
- ''
- end
- def post_paragraph
- '
'
- end
-
def extname
".#{@book.config["htmlext"]}"
end
@@ -89,7 +82,7 @@ def result
# default XHTML header/footer
@error_messages = error_messages
@warning_messages = warning_messages
- @title = strip_html(compile_inline(@chapter.title))
+ @title = strip_html(@chapter.title)
@body = @output.string
@language = @book.config['language']
@stylesheets = @book.config["stylesheet"]
@@ -157,122 +150,132 @@ def warning_messages
end
def headline(level, label, caption)
+ buf = ""
prefix, anchor = headline_prefix(level)
unless prefix.nil?
prefix = %Q[#{prefix} ]
end
- puts '' if level > 1
a_id = ""
unless anchor.nil?
a_id = %Q[ ]
end
if caption.empty?
- puts a_id unless label.nil?
+ buf << a_id+"\n" unless label.nil?
else
if label.nil?
- puts %Q[#{a_id}#{prefix}#{compile_inline(caption)} ]
+ buf << %Q[#{a_id}#{prefix}#{caption} \n]
else
- puts %Q[#{a_id}#{prefix}#{compile_inline(caption)} ]
+ buf << %Q[#{a_id}#{prefix}#{caption} \n]
end
end
+ buf
end
def nonum_begin(level, label, caption)
@nonum_counter += 1
- puts '' if level > 1
+ buf = ""
+ buf << "\n" if level > 1
unless caption.empty?
if label.nil?
id = normalize_id("#{@chapter.name}_nonum#{@nonum_counter}")
- puts %Q[#{compile_inline(caption)} ]
+ buf << %Q[#{caption} \n]
else
- puts %Q[#{compile_inline(caption)} ]
+ buf << %Q[#{caption} \n]
end
end
+ buf
end
def nonum_end(level)
end
def notoc_begin(level, label, caption)
+ buf = ""
@nonum_counter += 1
- puts '' if level > 1
+ buf << "\n" if level > 1
unless caption.empty?
if label.nil?
id = normalize_id("#{@chapter.name}_nonum#{@nonum_counter}")
- puts %Q[#{compile_inline(caption)} ]
+ buf << %Q[#{compile_inline(caption)} ]
else
- puts %Q[#{compile_inline(caption)} ]
+ buf << %Q[#{compile_inline(caption)} ]
end
end
+ buf
end
def notoc_end(level)
end
def nodisp_begin(level, label, caption)
+ buf = ""
@nonum_counter += 1
- puts '' if level > 1
+ buf << "\n" if level > 1
unless caption.empty?
if label.nil?
id = normalize_id("#{@chapter.name}_nonum#{@nonum_counter}")
- puts %Q[#{compile_inline(caption)} ]
+ buf << %Q[#{compile_inline(caption)} ]
else
- puts %Q[#{compile_inline(caption)} ]
+ buf << %Q[#{compile_inline(caption)} ]
end
end
+ buf
end
def nodisp_end(level)
end
def column_begin(level, label, caption)
- puts %Q[]
+ buf = %Q[
\n]
@column += 1
- puts '' if level > 1
+ buf << "\n" if level > 1
a_id = %Q[
]
if caption.empty?
- puts a_id unless label.nil?
+ buf << a_id + "\n" unless label.nil?
else
if label.nil?
- puts %Q[
#{a_id}#{compile_inline(caption)} ]
+ buf << %Q[
#{a_id}#{caption} \n]
else
- puts %Q[
#{a_id}#{compile_inline(caption)} ]
+ buf << %Q[
#{a_id}#{caption} \n]
end
end
-# headline(level, label, caption)
+ buf
end
def column_end(level)
- puts '
'
+ "
\n"
end
def xcolumn_begin(level, label, caption)
- puts %Q[]
- headline(level, label, caption)
+ buf << %Q[
\n]
+ buf << headline(level, label, caption)
+ buf
end
def xcolumn_end(level)
- puts '
'
+ "
\n"
end
def ref_begin(level, label, caption)
- print %Q[]
- headline(level, label, caption)
+ buf << %Q[
\n]
+ buf << headline(level, label, caption)
+ buf
end
def ref_end(level)
- puts '
'
+ "
\n"
end
def sup_begin(level, label, caption)
- print %Q[]
- headline(level, label, caption)
+ buf << %Q[
\n]
+ buf << headline(level, label, caption)
+ buf
end
def sup_end(level)
- puts '
'
+ "
\n"
end
def tsize(str)
@@ -280,13 +283,13 @@ def tsize(str)
end
def captionblock(type, lines, caption)
- puts %Q[]
+ buf = %Q[
\n]
unless caption.nil?
- puts %Q[
#{compile_inline(caption)}
]
+ buf << %Q[
#{caption}
\n]
end
- blocked_lines = split_paragraph(lines)
- puts blocked_lines.join("\n")
- puts '
'
+ buf << lines.join("")
+ buf << "
\n"
+ buf
end
def memo(lines, caption = nil)
@@ -338,12 +341,14 @@ def shoot(lines, caption = nil)
end
def box(lines, caption = nil)
- puts %Q[]
- puts %Q[
#{compile_inline(caption)}
] unless caption.nil?
- print %Q[
]
- lines.each {|line| puts detab(line) }
- puts ' '
- puts '
'
+ buf = ""
+ buf << %Q[\n]
+ buf << %Q[
#{caption}
\n] unless caption.nil?
+ buf << %Q[
]
+ lines.each {|line| buf << detab(line) << "\n" }
+ buf << " \n"
+ buf << "
\n"
+ buf
end
def note(lines, caption = nil)
@@ -351,94 +356,95 @@ def note(lines, caption = nil)
end
def ul_begin
- puts ''
+ "\n"
end
def ul_item(lines)
- puts "#{lines.join} "
+ "#{lines.map(&:to_s).join} \n"
end
def ul_item_begin(lines)
- print "#{lines.join}"
+ " #{lines.map(&:to_s).join}"
end
def ul_item_end
- puts " "
+ "\n"
end
def ul_end
- puts ' '
+ " \n"
end
def ol_begin
if @ol_num
- puts "" ## it's OK in HTML5, but not OK in XHTML1.1
+ num = @ol_num
@ol_num = nil
+ "\n" ## it's OK in HTML5, but not OK in XHTML1.1
else
- puts ''
+ "\n"
end
end
def ol_item(lines, num)
- puts "#{lines.join} "
+ "#{lines.map(&:to_s).join} \n"
end
def ol_end
- puts ' '
+ " \n"
end
def dl_begin
- puts ''
+ "\n"
end
def dt(line)
- puts "#{line} "
+ "#{line} \n"
end
def dd(lines)
- puts "#{lines.join} "
+ "#{lines.join} \n"
end
def dl_end
- puts ' '
+ " \n"
end
def paragraph(lines)
if @noindent.nil?
- puts "#{lines.join}
"
+ "#{lines.join}
\n"
else
- puts %Q[#{lines.join}
]
@noindent = nil
+ %Q[#{lines.join}
\n]
end
end
def parasep
- puts ' '
+ " \n"
end
def read(lines)
- blocked_lines = split_paragraph(lines)
- puts %Q[\n#{blocked_lines.join("\n")}\n
]
+ %Q[\n#{lines.join("")}\n
\n]
end
alias_method :lead, :read
def list(lines, id, caption, lang = nil)
- puts %Q[]
+ buf = %Q[
\n]
begin
- list_header id, caption, lang
+ buf << list_header(id, caption, lang)
rescue KeyError
error "no such list: #{id}"
end
- list_body id, lines, lang
- puts '
'
+ buf << list_body(id, lines, lang)
+ buf << "
\n"
+ buf
end
def list_header(id, caption, lang)
if get_chap.nil?
- puts %Q[#{I18n.t("list")}#{I18n.t("format_number_header_without_chapter", [@chapter.list(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}
]
+ %Q[#{I18n.t("list")}#{I18n.t("format_number_header_without_chapter", [@chapter.list(id).number])}#{I18n.t("caption_prefix")}#{caption}
\n]
else
- puts %Q[#{I18n.t("list")}#{I18n.t("format_number_header", [get_chap, @chapter.list(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}
]
+ %Q[#{I18n.t("list")}#{I18n.t("format_number_header", [get_chap, @chapter.list(id).number])}#{I18n.t("caption_prefix")}#{caption}
\n]
end
end
@@ -447,156 +453,167 @@ def list_body(id, lines, lang)
class_names = ["list"]
lexer = lang || File.extname(id).gsub(/\./, '')
class_names.push("language-#{lexer}") unless lexer.blank?
- print %Q[]
+ buf = %Q[]
body = lines.inject(''){|i, j| i + detab(j) + "\n"}
- puts highlight(:body => body, :lexer => lexer, :format => 'html')
- puts ' '
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html')
+ buf << " \n"
+ buf
end
def source(lines, caption = nil, lang = nil)
- puts %Q[]
- source_header caption
- source_body caption, lines, lang
- puts '
'
+ buf = %Q[\n]
+ buf << source_header(caption)
+ buf << source_body(caption, lines, lang)
+ buf << "
\n"
+ buf
end
def source_header(caption)
if caption.present?
- puts %Q[#{compile_inline(caption)}
]
+ %Q[#{caption}
\n]
end
end
def source_body(id, lines, lang)
id ||= ''
- print %Q[]
+ buf = %Q[]
body = lines.inject(''){|i, j| i + detab(j) + "\n"}
lexer = lang || File.extname(id).gsub(/\./, '')
- puts highlight(:body => body, :lexer => lexer, :format => 'html')
- puts ' '
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html')
+ buf << " \n"
+ buf
end
def listnum(lines, id, caption, lang = nil)
- puts %Q[]
+ buf = %Q[
\n]
begin
- list_header id, caption, lang
+ buf << list_header(id, caption, lang)
rescue KeyError
error "no such list: #{id}"
end
- listnum_body lines, lang
- puts '
'
+ buf << listnum_body(lines, lang)
+ buf << "
"
+ buf
end
def listnum_body(lines, lang)
+ buf = ""
if highlight?
body = lines.inject(''){|i, j| i + detab(j) + "\n"}
lexer = lang
- puts highlight(:body => body, :lexer => lexer, :format => 'html',
- :options => {:linenos => 'inline', :nowrap => false})
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html',
+ :options => {:linenos => 'inline', :nowrap => false})
else
class_names = ["list"]
class_names.push("language-#{lang}") unless lang.blank?
- print %Q[]
+ buf << %Q[]
lines.each_with_index do |line, i|
- puts detab((i+1).to_s.rjust(2) + ": " + line)
+ buf << detab((i+1).to_s.rjust(2) + ": " + line) << "\n"
end
- puts ' '
+ buf << ' ' << "\n"
end
+ buf
end
def emlist(lines, caption = nil, lang = nil)
- puts %Q[]
+ buf = %Q[
\n]
if caption.present?
- puts %Q(
#{compile_inline(caption)}
)
+ buf << %Q(
#{caption}
\n)
end
class_names = ["emlist"]
class_names.push("language-#{lang}") unless lang.blank?
- print %Q[
]
+ buf << %Q[]
body = lines.inject(''){|i, j| i + detab(j) + "\n"}
lexer = lang
- puts highlight(:body => body, :lexer => lexer, :format => 'html')
- puts ' '
- puts ' '
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html')
+ buf << "\n"
+ buf << "
\n"
+ buf
end
def emlistnum(lines, caption = nil, lang = nil)
- puts %Q[]
+ buf = %Q[
\n]
if caption.present?
- puts %Q(
#{compile_inline(caption)}
)
+ buf << %Q(
#{caption}
\n)
end
-
if highlight?
body = lines.inject(''){|i, j| i + detab(j) + "\n"}
lexer = lang
- puts highlight(:body => body, :lexer => lexer, :format => 'html',
- :options => {:linenos => 'inline', :nowrap => false})
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html',
+ :options => {:linenos => 'inline', :nowrap => false})
else
class_names = ["emlist"]
class_names.push("language-#{lang}") unless lang.blank?
- print %Q[
]
+ buf << %Q[]
lines.each_with_index do |line, i|
- puts detab((i+1).to_s.rjust(2) + ": " + line)
+ buf << detab((i+1).to_s.rjust(2) + ": " + line) << "\n"
end
- puts ' '
+ buf << ' ' << "\n"
end
- puts '
'
+ buf << '
' << "\n"
+ buf
end
def cmd(lines, caption = nil)
- puts %Q[]
+ buf = %Q[
\n]
if caption.present?
- puts %Q(
#{compile_inline(caption)}
)
+ buf << %Q(
#{caption}
\n)
end
- print %Q[
]
+ buf << %Q[]
body = lines.inject(''){|i, j| i + detab(j) + "\n"}
lexer = 'shell-session'
- puts highlight(:body => body, :lexer => lexer, :format => 'html')
- puts ' '
- puts ' '
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html')
+ buf << "\n"
+ buf << "
\n"
+ buf
end
def quotedlist(lines, css_class)
- print %Q[]
+ buf = %Q[\n]
lines.each do |line|
- puts detab(line)
+ buf << detab(line) << "\n"
end
- puts ' '
+ buf << " \n"
end
private :quotedlist
def quote(lines)
- blocked_lines = split_paragraph(lines)
- puts "#{blocked_lines.join("\n")} "
+ "#{lines.join("")} \n"
end
def doorquote(lines, ref)
- blocked_lines = split_paragraph(lines)
- puts %Q[]
- puts "#{blocked_lines.join("\n")}"
- puts %Q[#{ref}より
]
- puts %Q[ ]
+ buf = ""
+ buf << %Q[\n]
+ buf << "#{lines.join("")}\n"
+ buf << %Q[#{ref}より
\n]
+ buf << %Q[ \n]
+ buf
end
def talk(lines)
- puts %Q[]
- blocked_lines = split_paragraph(lines)
- puts "#{blocked_lines.join("\n")}"
- puts '
'
+ buf = ""
+ buf << %Q[\n]
+ buf << "#{lines.join("\n")}\n"
+ buf << "
\n"
+ buf
end
- def texequation(lines)
- puts %Q[]
+ def node_texequation(node)
+ buf = ""
+ buf << %Q[
\n]
if @book.config["mathml"]
require 'math_ml'
require 'math_ml/symbol/character_reference'
p = MathML::LaTeX::Parser.new(:symbol=>MathML::Symbol::CharacterReference)
- puts p.parse(unescape_html(lines.join("\n")), true)
+ buf << p.parse(node.to_raw, true).to_s << "\n"
else
- print '
'
- puts "#{lines.join("\n")}"
- puts ' '
+ buf << '
'
+ buf << lines.join("\n") << "\n"
+ buf << " \n"
end
- puts '
'
+ buf << "
\n"
+ buf
end
def handle_metric(str)
@@ -623,32 +640,35 @@ def result_metric(array)
def image_image(id, caption, metric)
metrics = parse_metric("html", metric)
- puts %Q[]
- puts %Q[
]
- image_header id, caption
- puts %Q[
]
+ buf = %Q[\n]
+ buf << %Q[
\n]
+ buf << image_header(id, caption)
+ buf << %Q[
\n]
+ buf
end
def image_dummy(id, caption, lines)
- puts %Q[]
- puts %Q[
]
+ buf = %Q[]
+ buf << %Q[
]
lines.each do |line|
- puts detab(line)
+ buf << detab(line) << "\n"
end
- puts %Q[ ]
- image_header id, caption
- puts %Q[
]
+ buf << %Q[ \n]
+ buf << image_header(id, caption)
+ buf << %Q[
\n]
warn "no such image: #{id}"
+ buf
end
def image_header(id, caption)
- puts %Q[]
+ buf = %Q[
\n]
if get_chap.nil?
- puts %Q[#{I18n.t("image")}#{I18n.t("format_number_header_without_chapter", [@chapter.image(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}]
+ buf << %Q[#{I18n.t("image")}#{I18n.t("format_number_header_without_chapter", [@chapter.image(id).number])}#{I18n.t("caption_prefix")}#{caption}\n]
else
- puts %Q[#{I18n.t("image")}#{I18n.t("format_number_header", [get_chap, @chapter.image(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}]
+ buf << %Q[#{I18n.t("image")}#{I18n.t("format_number_header", [get_chap, @chapter.image(id).number])}#{I18n.t("caption_prefix")}#{caption}\n]
end
- puts %Q[
]
+ buf << %Q[
\n]
+ buf
end
def table(lines, id = nil, caption = nil)
@@ -666,48 +686,49 @@ def table(lines, id = nil, caption = nil)
rows = adjust_n_cols(rows)
if id
- puts %Q[]
+ buf = %Q[
\n]
else
- puts %Q[
]
+ buf = %Q[
\n]
end
begin
- table_header id, caption unless caption.nil?
+ buf << table_header(id, caption) unless caption.nil?
rescue KeyError
error "no such table: #{id}"
end
- table_begin rows.first.size
+ buf << table_begin(rows.first.size)
return if rows.empty?
if sepidx
sepidx.times do
- tr rows.shift.map {|s| th(s) }
+ buf << tr(rows.shift.map {|s| th(s) })
end
rows.each do |cols|
- tr cols.map {|s| td(s) }
+ buf << tr(cols.map {|s| td(s) })
end
else
rows.each do |cols|
h, *cs = *cols
- tr [th(h)] + cs.map {|s| td(s) }
+ buf << tr([th(h)] + cs.map {|s| td(s) })
end
end
- table_end
- puts %Q[
]
+ buf << table_end
+ buf << %Q[
\n]
+ buf
end
def table_header(id, caption)
if get_chap.nil?
- puts %Q[
#{I18n.t("table")}#{I18n.t("format_number_header_without_chapter", [@chapter.table(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}
]
+ %Q[
#{I18n.t("table")}#{I18n.t("format_number_header_without_chapter", [@chapter.table(id).number])}#{I18n.t("caption_prefix")}#{caption}
\n]
else
- puts %Q[
#{I18n.t("table")}#{I18n.t("format_number_header", [get_chap, @chapter.table(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}
]
+ %Q[
#{I18n.t("table")}#{I18n.t("format_number_header", [get_chap, @chapter.table(id).number])}#{I18n.t("caption_prefix")}#{caption}
\n]
end
end
def table_begin(ncols)
- puts '
'
+ "\n"
end
def tr(rows)
- puts "#{rows.join} "
+ "#{rows.join} \n"
end
def th(str)
@@ -719,95 +740,98 @@ def td(str)
end
def table_end
- puts '
'
+ "
\n"
end
def imgtable(lines, id, caption = nil, metric = nil)
+ buf = ""
if !@chapter.image(id).bound?
warn "image not bound: #{id}"
- image_dummy id, caption, lines
- return
+ return image_dummy(id, caption, lines)
end
- puts %Q[
]
+ buf << %Q[
\n]
begin
- table_header id, caption unless caption.nil?
+ buf << table_header(id, caption) unless caption.nil?
rescue KeyError
error "no such table: #{id}"
end
- imgtable_image(id, caption, metric)
+ buf << imgtable_image(id, caption, metric)
- puts %Q[
]
+ buf << %Q[
\n]
+ buf
end
def imgtable_image(id, caption, metric)
metrics = parse_metric("html", metric)
- puts %Q[
]
+ %Q[
\n]
end
def comment(lines, comment = nil)
lines ||= []
lines.unshift comment unless comment.blank?
if @book.config["draft"]
- str = lines.join("
")
- puts %Q()
+ str = lines.map{|line| escape_html(line) }.join("
")
+ return %Q(\n)
else
str = lines.join("\n")
- puts %Q()
+ return %Q(\n)
end
end
def footnote(id, str)
if @book.config["epubversion"].to_i == 3
- puts %Q()
+ %Q(\n)
else
- puts %Q()
+ %Q(\n)
end
end
def indepimage(id, caption="", metric=nil)
metrics = parse_metric("html", metric)
caption = "" if caption.nil?
- puts %Q[
]
+ buf = %Q[
] + "\n"
begin
- puts %Q[
]
+ buf << %Q[
\n]
rescue
- puts %Q[
missing image: #{id} ]
+ buf << %Q[
missing image: #{id} \n]
end
unless caption.empty?
- puts %Q[
]
- puts %Q[#{I18n.t("numberless_image")}#{I18n.t("caption_prefix")}#{compile_inline(caption)}]
- puts %Q[
]
+ buf << %Q[
\n]
+ buf << %Q[#{I18n.t("numberless_image")}#{I18n.t("caption_prefix")}#{caption}\n]
+ buf << %Q[
\n]
end
- puts %Q[
]
+ buf << %Q[
\n]
+ buf
end
alias_method :numberlessimage, :indepimage
def hr
- puts "
"
+ "
\n"
end
def label(id)
- puts %Q(
)
+ %Q(
\n)
end
def linebreak
- puts "
"
+ "
\n"
end
def pagebreak
- puts %Q(
)
+ %Q(
\n)
end
def bpo(lines)
- puts "
"
+ buf = "\n"
lines.each do |line|
- puts detab(line)
+ buf << detab(line) + "\n"
end
- puts " "
+ buf << " \n"
+ buf
end
def noindent
@@ -815,7 +839,7 @@ def noindent
end
def inline_labelref(idref)
- %Q[
「#{I18n.t("label_marker")}#{escape_html(idref)}」 ]
+ %Q[
「#{I18n.t("label_marker")}#{idref}」 ]
end
alias_method :inline_ref, :inline_labelref
@@ -865,9 +889,9 @@ def inline_fn(id)
def compile_ruby(base, ruby)
if @book.htmlversion == 5
- %Q[
#{escape_html(base)}#{I18n.t("ruby_prefix")} #{escape_html(ruby)} #{I18n.t("ruby_postfix")} ]
+ %Q[
#{base}#{I18n.t("ruby_prefix")} #{ruby} #{I18n.t("ruby_postfix")} ]
else
- %Q[
#{escape_html(base)} #{I18n.t("ruby_prefix")} #{ruby} #{I18n.t("ruby_postfix")} ]
+ %Q[
#{base} #{I18n.t("ruby_prefix")} #{ruby} #{I18n.t("ruby_postfix")} ]
end
end
@@ -881,34 +905,34 @@ def compile_kw(word, alt)
end
def inline_i(str)
- %Q(
#{escape_html(str)} )
+ %Q(
#{str} )
end
def inline_b(str)
- %Q(
#{escape_html(str)} )
+ %Q(
#{str} )
end
def inline_ami(str)
- %Q(
#{escape_html(str)} )
+ %Q(
#{str} )
end
def inline_bou(str)
- %Q(
#{escape_html(str)} )
+ %Q(
#{str} )
end
def inline_tti(str)
if @book.htmlversion == 5
- %Q(
#{escape_html(str)}
)
+ %Q(
#{str}
)
else
- %Q(
#{escape_html(str)} )
+ %Q(
#{str} )
end
end
def inline_ttb(str)
if @book.htmlversion == 5
- %Q(
#{escape_html(str)}
)
+ %Q(
#{str}
)
else
- %Q(
#{escape_html(str)} )
+ %Q(
#{str} )
end
end
@@ -918,14 +942,14 @@ def inline_dtp(str)
def inline_code(str)
if @book.htmlversion == 5
- %Q(
#{escape_html(str)}
)
+ %Q(
#{str}
)
else
- %Q(
#{escape_html(str)} )
+ %Q(
#{str} )
end
end
def inline_idx(str)
- %Q(#{escape_html(str)})
+ %Q(#{str})
end
def inline_hidx(str)
@@ -943,7 +967,7 @@ def inline_m(str)
parser = MathML::LaTeX::Parser.new(:symbol => MathML::Symbol::CharacterReference)
%Q[
#{parser.parse(str, nil)} ]
else
- %Q[
#{escape_html(str)} ]
+ %Q[
#{str} ]
end
end
@@ -952,23 +976,24 @@ def text(str)
end
def bibpaper(lines, id, caption)
- puts %Q[
]
- bibpaper_header id, caption
+ buf = %Q[
\n]
+ buf << bibpaper_header(id, caption)
unless lines.empty?
- bibpaper_bibpaper id, caption, lines
+ buf << bibpaper_bibpaper(id, caption, lines)
end
- puts "
"
+ buf << "
" << "\n"
+ buf
end
def bibpaper_header(id, caption)
- print %Q(
)
- print "[#{@chapter.bibpaper(id).number}]"
- print %Q( )
- puts " #{compile_inline(caption)}"
+ buf = %Q(
)
+ buf << "[#{@chapter.bibpaper(id).number}]"
+ buf << %Q( )
+ buf << " #{caption}" << "\n"
end
def bibpaper_bibpaper(id, caption, lines)
- print split_paragraph(lines).join("")
+ lines.join("")
end
def inline_bib(id)
@@ -978,9 +1003,9 @@ def inline_bib(id)
def inline_hd_chap(chap, id)
n = chap.headline_index.number(id)
if chap.number and @book.config["secnolevel"] >= n.split('.').size
- str = I18n.t("chapter_quote", "#{n} #{compile_inline(chap.headline(id).caption)}")
+ str = I18n.t("chapter_quote", "#{n} #{chap.headline(id).caption}")
else
- str = I18n.t("chapter_quote", compile_inline(chap.headline(id).caption))
+ str = I18n.t("chapter_quote", chap.headline(id).caption)
end
if @book.config["chapterlink"]
anchor = "h"+n.gsub(/\./, "-")
@@ -1053,7 +1078,7 @@ def inline_img(id)
end
def inline_asis(str, tag)
- %Q(<#{tag}>#{escape_html(str)}#{tag}>)
+ %Q(<#{tag}>#{str}#{tag}>)
end
def inline_abbr(str)
@@ -1110,9 +1135,9 @@ def inline_sup(str)
def inline_tt(str)
if @book.htmlversion == 5
- %Q(
#{escape_html(str)}
)
+ %Q(
#{str}
)
else
- %Q(
#{escape_html(str)} )
+ %Q(
#{str} )
end
end
@@ -1125,11 +1150,11 @@ def inline_ins(str)
end
def inline_u(str)
- %Q(
#{escape_html(str)} )
+ %Q(
#{str} )
end
def inline_recipe(str)
- %Q(
「#{escape_html(str)}」 )
+ %Q(
「#{str}」 )
end
def inline_icon(id)
@@ -1146,7 +1171,7 @@ def inline_uchar(str)
def inline_comment(str)
if @book.config["draft"]
- %Q()
+ %Q()
else
%Q()
end
@@ -1169,18 +1194,20 @@ def nofunc_text(str)
def compile_href(url, label)
if @book.config["externallink"]
- %Q(
#{label.nil? ? escape_html(url) : escape_html(label)} )
+ %Q(
#{label.nil? ? url : label} )
else
- label.nil? ? escape_html(url) : I18n.t('external_link', [escape_html(label), escape_html(url)])
+ label.nil? ? url : I18n.t('external_link', [label, url])
end
end
def flushright(lines)
- puts split_paragraph(lines).join("\n").gsub("
", "
")
+ result = ""
+ result << lines.join("").gsub("
", "
")
+ result
end
def centering(lines)
- puts split_paragraph(lines).join("\n").gsub("
", "
")
+ lines.join("").gsub("
", "
")
end
def image_ext
diff --git a/lib/review/htmlutils.rb b/lib/review/htmlutils.rb
index 8aef9edf2..e4d0a77c8 100644
--- a/lib/review/htmlutils.rb
+++ b/lib/review/htmlutils.rb
@@ -77,7 +77,7 @@ def highlight(ops)
body
end
rescue LoadError
- body
+ body
end
end
diff --git a/lib/review/idgxmlbuilder.rb b/lib/review/idgxmlbuilder.rb
index 28b08f5bd..e5efbc470 100644
--- a/lib/review/idgxmlbuilder.rb
+++ b/lib/review/idgxmlbuilder.rb
@@ -23,7 +23,10 @@ class IDGXMLBuilder < Builder
[:ttbold, :hint, :maru, :keytop, :labelref, :ref, :pageref, :balloon].each {|e| Compiler.definline(e) }
Compiler.defsingle(:dtp, 1)
- Compiler.defblock(:insn, 0..1)
+ Compiler.defcodeblock(:insn, 1)
+ Compiler.defblock(:memo, 0..1)
+ Compiler.defblock(:tip, 0..1)
+ Compiler.defblock(:info, 0..1)
Compiler.defblock(:planning, 0..1)
Compiler.defblock(:best, 0..1)
Compiler.defblock(:security, 0..1)
@@ -36,14 +39,6 @@ class IDGXMLBuilder < Builder
Compiler.defblock(:expert, 0)
Compiler.defblock(:rawblock, 0)
- def pre_paragraph
- '
'
- end
-
- def post_paragraph
- '
'
- end
-
def extname
'.xml'
end
@@ -69,8 +64,14 @@ def builder_init_file
@tsize = nil
@texblockequation = 0
@texinlineequation = 0
- print %Q(\n)
- print %Q(<#{@rootelement} xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/">)
+
+ @output << %Q(\n)
+ @output << %Q(<#{@rootelement} xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/">)
+ if @book.config["nolf"].present?
+ @lf = ""
+ else
+ @lf = "\n"
+ end
@secttags = true unless @book.config["structuredxml"].nil?
end
private :builder_init_file
@@ -98,7 +99,7 @@ def result
def warn(msg)
if @no_error
@warns.push [@location.filename, @location.lineno, msg]
- puts "----WARNING: #{escape_html(msg)}----"
+ buf << "----WARNING: #{escape_html(msg)}----" << @lf
else
$stderr.puts "#{@location}: warning: #{msg}"
end
@@ -107,7 +108,7 @@ def warn(msg)
def error(msg)
if @no_error
@errors.push [@location.filename, @location.lineno, msg]
- puts "----ERROR: #{escape_html(msg)}----"
+ buf << "----ERROR: #{escape_html(msg)}----" << @lf
else
$stderr.puts "#{@location}: error: #{msg}"
end
@@ -138,63 +139,57 @@ def warning_messages
end
def headline(level, label, caption)
+ buf = ""
case level
when 1
unless @secttags.nil?
- print "" if @subsubsubsection > 0
- print "" if @subsubsection > 0
- print "" if @subsection > 0
- print "" if @section > 0
+ buf << "" if @subsubsubsection > 0
+ buf << "" if @subsubsection > 0
+ buf << "" if @subsection > 0
+ buf << "" if @section > 0
end
-
- print %Q(
) unless @secttags.nil?
-
+ buf << %Q() unless @secttags.nil?
@section = 0
@subsection = 0
@subsubsection = 0
@subsubsubsection = 0
when 2
unless @secttags.nil?
- print "" if @subsubsubsection > 0
- print "" if @subsubsection > 0
- print "" if @subsection > 0
- print "" if @section > 0
+ buf << "" if @subsubsubsection > 0
+ buf << "" if @subsubsection > 0
+ buf << "" if @subsection > 0
+ buf << "" if @section > 0
end
@section += 1
- print %Q() unless @secttags.nil?
-
+ buf << %Q() unless @secttags.nil?
@subsection = 0
@subsubsection = 0
@subsubsubsection = 0
when 3
unless @secttags.nil?
- print "" if @subsubsubsection > 0
- print "" if @subsubsection > 0
- print "" if @subsection > 0
+ buf << "" if @subsubsubsection > 0
+ buf << "" if @subsubsection > 0
+ buf << "" if @subsection > 0
end
-
@subsection += 1
- print %Q() unless @secttags.nil?
-
+ buf << %Q() unless @secttags.nil?
@subsubsection = 0
@subsubsubsection = 0
when 4
unless @secttags.nil?
- print "" if @subsubsubsection > 0
- print "" if @subsubsection > 0
+ buf << "" if @subsubsubsection > 0
+ buf << "" if @subsubsection > 0
end
-
@subsubsection += 1
- print %Q() unless @secttags.nil?
-
+ buf << %Q() unless @secttags.nil?
@subsubsubsection = 0
when 5
unless @secttags.nil?
- print "" if @subsubsubsection > 0
+ buf << "" if @subsubsubsection > 0
end
@subsubsubsection += 1
- print %Q() unless @secttags.nil?
+ buf << %Q() unless @secttags.nil?
else
raise "caption level too deep or unsupported: #{level}"
end
@@ -202,65 +197,68 @@ def headline(level, label, caption)
prefix, anchor = headline_prefix(level)
label = label.nil? ? "" : " id=\"#{label}\""
- toccaption = escape_html(compile_inline(caption.gsub(/@\{.+?\}/, '')).gsub(/<[^>]+>/, ''))
- puts %Q(#{prefix}#{compile_inline(caption)} )
+ toccaption = escape_html(caption.gsub(/@\{.+?\}/, '').gsub(/<[^>]+>/, ''))
+ buf << %Q(#{prefix}#{caption} ) << @lf
+
+ buf
end
def ul_begin
level = block_given? ? yield : ""
level = nil if level == 1
- puts ""
+ "" + @lf
end
def ul_item(lines)
- puts %Q(#{lines.join.chomp} )
+ %Q(#{lines.join.chomp} ) + @lf
end
def ul_item_begin(lines)
- print %Q(#{lines.join.chomp})
+ %Q( #{lines.join.chomp})
end
def ul_item_end
- puts " "
+ "" + @lf
end
def choice_single_begin
- puts ""
+ "" + @lf
end
def choice_multi_begin
- puts ""
+ "" + @lf
end
def choice_single_end
- puts " "
+ " " + @lf
end
def choice_multi_end
- puts " "
+ " " + @lf
end
def ul_end
level = block_given? ? yield : ""
level = nil if level == 1
- puts " "
+ " " + @lf
end
def ol_begin
- puts ''
if !@ol_num
@ol_num = 1
end
+ '' + @lf
end
def ol_item(lines, num)
- puts %Q(#{lines.join.chomp} )
+ buf = %Q(#{lines.join.chomp} ) + @lf
@ol_num += 1
+ buf
end
def ol_end
- puts ' '
@ol_num = nil
+ ' ' + @lf
end
def olnum(num)
@@ -268,36 +266,38 @@ def olnum(num)
end
def dl_begin
- puts ''
+ '' + @lf
end
def dt(line)
- puts "#{line} "
+ "#{line} " + @lf
end
def dd(lines)
- puts "#{lines.join.chomp} "
+ "#{lines.join.chomp} " + @lf
end
def dl_end
- puts ' '
+ ' ' + @lf
end
def paragraph(lines)
+ buf = ""
if @noindent.nil?
if lines[0] =~ /\A(\t+)/
- puts %Q(#{lines.join('').sub(/\A\t+/, "")}
)
+ buf << %Q(#{lines.join('').sub(/\A\t+/, "")}
) << @lf
else
- puts "#{lines.join}
"
+ buf << "#{lines.join}
" << @lf
end
else
- puts %Q(#{lines.join}
)
+ buf << %Q(#{lines.join}
) << @lf
@noindent = nil
end
+ buf
end
def read(lines)
- puts %Q[#{split_paragraph(lines).join} ]
+ %Q[#{lines.join} ] + @lf
end
alias_method :lead, :read
@@ -326,34 +326,40 @@ def inline_list(id)
end
def list_header(id, caption, lang)
- puts %Q[]
+ buf = ""
+ buf << %Q[] << @lf
if get_chap.nil?
- puts %Q[#{I18n.t("list")}#{I18n.t("format_number_without_chapter", [@chapter.list(id).number])}#{I18n.t("caption_prefix_idgxml")}#{compile_inline(caption)} ]
+ buf << %Q[#{I18n.t("list")}#{I18n.t("format_number_without_chapter", [@chapter.list(id).number])}#{I18n.t("caption_prefix_idgxml")}#{caption} ] << @lf
else
- puts %Q[#{I18n.t("list")}#{I18n.t("format_number", [get_chap, @chapter.list(id).number])}#{I18n.t("caption_prefix_idgxml")}#{compile_inline(caption)} ]
+ buf << %Q[#{I18n.t("list")}#{I18n.t("format_number", [get_chap, @chapter.list(id).number])}#{I18n.t("caption_prefix_idgxml")}#{caption} ] << @lf
end
+ buf
end
def codelines_body(lines)
+ buf = ""
no = 1
lines.each do |line|
unless @book.config["listinfo"].nil?
- print ""
+ buf << ""
end
- print detab(line)
- print "\n"
- print " " unless @book.config["listinfo"].nil?
+ buf << detab(line)
+ buf << "\n"
+ buf << " " unless @book.config["listinfo"].nil?
no += 1
end
+ buf
end
def list_body(id, lines, lang)
- print %Q()
- codelines_body(lines)
- puts " "
+ buf = ""
+ buf << %Q()
+ buf << codelines_body(lines)
+ buf << " " << @lf
+ buf
end
def emlist(lines, caption = nil, lang = nil)
@@ -363,27 +369,30 @@ def emlist(lines, caption = nil, lang = nil)
def emlistnum(lines, caption = nil, lang = nil)
_lines = []
lines.each_with_index do |line, i|
+ line.chomp! ## new parser don't remove LF in table (code block)
_lines << detab("" + (i + 1).to_s.rjust(2) + ": " + line)
end
quotedlist _lines, 'emlistnum', caption
end
def listnum_body(lines, lang)
- print %Q()
+ buf = ""
+ buf << %Q()
no = 1
lines.each_with_index do |line, i|
unless @book.config["listinfo"].nil?
- print ""
+ buf << ""
end
- print detab("" + (i + 1).to_s.rjust(2) + ": " + line)
- print "\n"
- print " " unless @book.config["listinfo"].nil?
+ buf << detab("" + (i + 1).to_s.rjust(2) + ": " + line)
+ buf << "\n"
+ buf << " " unless @book.config["listinfo"].nil?
no += 1
end
- puts " "
+ buf << " " << @lf
+ buf
end
def cmd(lines, caption = nil)
@@ -391,29 +400,30 @@ def cmd(lines, caption = nil)
end
def quotedlist(lines, css_class, caption)
- print %Q[]
- puts "#{compile_inline(caption)} " if caption.present?
- print %Q[]
+ buf = ""
+ buf << %Q[]
+ buf << "#{caption} " + @lf if caption.present?
+ buf << %Q[]
no = 1
lines.each do |line|
unless @book.config["listinfo"].nil?
- print ""
+ buf << ""
end
- print detab(line)
- print "\n"
- print " " unless @book.config["listinfo"].nil?
+ buf << detab(line)
+ buf << "\n"
+ buf << " " unless @book.config["listinfo"].nil?
no += 1
end
- puts '
'
+ buf << '
' << @lf
+ buf
end
private :quotedlist
def quote(lines)
- blocked_lines = split_paragraph(lines)
- puts "#{blocked_lines.join("")}
"
+ "#{lines.join("")}
" + @lf
end
def inline_table(id)
@@ -425,7 +435,8 @@ def inline_table(id)
end
end
- def inline_img(id)
+ def node_inline_img(node)
+ id = node[0].to_raw
chapter, id = extract_chapter_id(id)
if get_chap(chapter).nil?
"#{I18n.t("image")}#{I18n.t("format_number_without_chapter", [chapter.image(id).number])} "
@@ -434,10 +445,11 @@ def inline_img(id)
end
end
- def inline_imgref(id)
+ def node_inline_imgref(node)
+ id = node[0].to_raw
chapter, id = extract_chapter_id(id)
if chapter.image(id).caption.blank?
- inline_img(id)
+ node_inline_img(node)
else
if get_chap(chapter).nil?
"#{I18n.t("image")}#{I18n.t("format_number_without_chapter", [chapter.image(id).number])}#{I18n.t('image_quote', chapter.image(id).caption)} "
@@ -457,53 +469,59 @@ def result_metric(array)
end
def image_image(id, caption, metric=nil)
+ buf = ""
metrics = parse_metric("idgxml", metric)
- puts " "
- puts %Q[ ]
- image_header id, caption
- puts ""
+ buf << " " << @lf
+ buf << %Q[ ] << @lf
+ buf << image_header(id, caption)
+ buf << "" << @lf
+ buf
end
def image_dummy(id, caption, lines)
- puts " "
- print %Q[]
+ buf << " " << @lf
+ buf << %Q[]
lines.each do |line|
- print detab(line)
- print "\n"
+ buf << detab(line)
+ buf << "\n"
end
- print %Q[ ]
+ buf << %Q[ ]
image_header id, caption
- puts ""
+ buf << "" << @lf
warn "no such image: #{id}"
+ buf
end
def image_header(id, caption)
if get_chap.nil?
- puts %Q[#{I18n.t("image")}#{I18n.t("format_number_without_chapter", [@chapter.image(id).number])}#{I18n.t("caption_prefix_idgxml")}#{compile_inline(caption)} ]
+ %Q[#{I18n.t("image")}#{I18n.t("format_number_without_chapter", [@chapter.image(id).number])}#{I18n.t("caption_prefix_idgxml")}#{caption} ] + @lf
else
- puts %Q[#{I18n.t("image")}#{I18n.t("format_number", [get_chap, @chapter.image(id).number])}#{I18n.t("caption_prefix_idgxml")}#{compile_inline(caption)} ]
+ %Q[#{I18n.t("image")}#{I18n.t("format_number", [get_chap, @chapter.image(id).number])}#{I18n.t("caption_prefix_idgxml")}#{caption} ] + @lf
end
end
def texequation(lines)
+ buf = ""
@texblockequation += 1
- puts %Q[]
- puts ''
- puts "#{lines.join("\n")}"
- puts ' '
- puts ' '
+ buf << %Q[] << @lf
+ buf << '' << @lf
+ buf << "#{lines.join("\n")}" << @lf
+ buf << ' ' << @lf
+ buf << ' ' << @lf
end
def table(lines, id = nil, caption = nil)
+ buf = ""
tablewidth = nil
col = 0
if @book.config["tableopt"]
tablewidth = @book.config["tableopt"].split(",")[0].to_f / @book.config["pt_to_mm_unit"].to_f
end
- puts ""
+ buf << ""
rows = []
sepidx = nil
lines.each_with_index do |line, idx|
+ line.chomp! ## new parser don't remove LF in table (code block)
if /\A[\=\-]{12}/ =~ line
sepidx ||= idx
next
@@ -540,66 +558,71 @@ def table(lines, id = nil, caption = nil)
end
begin
- table_header id, caption unless caption.nil?
+ buf << table_header(id, caption) unless caption.nil?
rescue KeyError
error "no such table: #{id}"
end
return if rows.empty?
if tablewidth.nil?
- print ""
+ buf << " "
else
- print %Q[ ]
+ buf << %Q[ ]
end
if sepidx
sepidx.times do |y|
if tablewidth.nil?
- puts %Q[#{rows.shift} ]
+ buf << %Q[#{rows.shift} ] << @lf
else
i = 0
rows.shift.split(/\t/).each_with_index do |cell, x|
- print %Q[#{cell.sub("DUMMYCELLSPLITTER", "")} ]
+ buf << %Q[#{cell.sub("DUMMYCELLSPLITTER", "")} ]
i += 1
end
end
end
end
- trputs(tablewidth, rows, cellwidth, sepidx)
- puts "
"
+ buf << trputs(tablewidth, rows, cellwidth, sepidx)
+ buf << "
" << @lf
@tsize = nil
+ buf
end
def trputs(tablewidth, rows, cellwidth, sepidx)
+ buf = ""
sepidx = 0 if sepidx.nil?
if tablewidth.nil?
lastline = rows.pop
- rows.each {|row| puts %Q[#{row} ] }
- puts %Q[#{lastline} ] unless lastline.nil?
+ rows.each {|row| buf << %Q[#{row} ] }
+ buf << %Q[#{lastline} ] + @lf unless lastline.nil?
else
rows.each_with_index do |row, y|
i = 0
row.split(/\t/).each_with_index do |cell, x|
- print %Q[#{cell.sub("DUMMYCELLSPLITTER", "")} ]
+ buf << %Q[#{cell.sub("DUMMYCELLSPLITTER", "")} ]
i += 1
end
end
end
+ buf
end
def table_header(id, caption)
+ buf = ""
if get_chap.nil?
- puts %Q[#{I18n.t("table")}#{I18n.t("format_number_without_chapter", [@chapter.table(id).number])}#{I18n.t("caption_prefix_idgxml")}#{compile_inline(caption)} ]
+ buf << %Q[#{I18n.t("table")}#{I18n.t("format_number_without_chapter", [@chapter.table(id).number])}#{I18n.t("caption_prefix_idgxml")}#{caption} ] + @lf
else
- puts %Q[#{I18n.t("table")}#{I18n.t("format_number", [get_chap, @chapter.table(id).number])}#{I18n.t("caption_prefix_idgxml")}#{compile_inline(caption)} ]
+ buf << %Q[#{I18n.t("table")}#{I18n.t("format_number", [get_chap, @chapter.table(id).number])}#{I18n.t("caption_prefix_idgxml")}#{caption} ] + @lf
end
+ buf
end
def table_begin(ncols)
end
def tr(rows)
- puts %Q[#{rows.join("\t")} ]
+ %Q[#{rows.join("\t")} ] + @lf
end
def th(str)
@@ -611,7 +634,7 @@ def td(str)
end
def table_end
- print ""
+ ""
end
def imgtable(lines, id, caption = nil, metric = nil)
@@ -628,7 +651,7 @@ def imgtable(lines, id, caption = nil, metric = nil)
end
def comment(str)
- print %Q()
+ %Q()
end
def footnote(id, str)
@@ -636,7 +659,7 @@ def footnote(id, str)
end
def inline_fn(id)
- %Q[#{compile_inline(@chapter.footnote(id).content.strip)} ]
+ %Q[#{@chapter.footnote(id).content.strip} ]
end
def compile_ruby(base, ruby)
@@ -646,28 +669,30 @@ def compile_ruby(base, ruby)
def compile_kw(word, alt)
'' +
if alt
- then escape_html("#{word}(#{alt.strip})")
- else escape_html(word)
+ then
+ "#{word}(#{alt.strip})"
+ else
+ word
end +
' ' +
- %Q[ ] +
+ %Q[ ] +
if alt
- alt.split(/\s*,\s*/).collect! {|e| %Q[ ] }.join
+ alt.split(/\s*,\s*/).collect! {|e| %Q[ ] }.join
else
""
end
end
def compile_href(url, label)
- %Q[#{label.nil? ? escape_html(url) : escape_html(label)} ]
+ %Q[#{label.nil? ? url : label} ]
end
def inline_sup(str)
- %Q[#{escape_html(str)} ]
+ %Q[#{str} ]
end
def inline_sub(str)
- %Q[#{escape_html(str)} ]
+ %Q[#{str} ]
end
def inline_raw(str)
@@ -676,9 +701,9 @@ def inline_raw(str)
def inline_hint(str)
if @book.config["nolf"].nil?
- %Q[\n#{escape_html(str)} ]
+ %Q[\n#{str} ]
else
- %Q[#{escape_html(str)} ]
+ %Q[#{str} ]
end
end
@@ -703,41 +728,41 @@ def inline_maru(str)
end
def inline_idx(str)
- %Q(#{escape_html(str)} )
+ %Q(#{str} )
end
def inline_hidx(str)
- %Q( )
+ %Q( )
end
def inline_ami(str)
- %Q(#{escape_html(str)} )
+ %Q(#{str} )
end
def inline_i(str)
- %Q(#{escape_html(str)} )
+ %Q(#{str} )
end
def inline_b(str)
- %Q(#{escape_html(str)} )
+ %Q(#{str} )
end
def inline_tt(str)
- %Q(#{escape_html(str)} )
+ %Q(#{str} )
end
def inline_ttb(str)
- %Q(#{escape_html(str)} )
+ %Q(#{str} )
end
alias_method :inline_ttbold, :inline_ttb
def inline_tti(str)
- %Q(#{escape_html(str)} )
+ %Q(#{str} )
end
def inline_u(str)
- %Q(#{escape_html(str)} )
+ %Q(#{str} )
end
def inline_icon(id)
@@ -750,25 +775,25 @@ def inline_icon(id)
end
def inline_bou(str)
- %Q[#{escape_html(str)} ]
+ %Q[#{str} ]
end
def inline_keytop(str)
- %Q[#{escape_html(str)} ]
+ %Q[#{str} ]
end
def inline_labelref(idref)
- %Q[[「#{I18n.t("label_marker")}#{escape_html(idref)}」]] # FIXME:節名とタイトルも込みで要出力
+ %Q[[「#{I18n.t("label_marker")}#{idref}」]] # FIXME:節名とタイトルも込みで要出力
end
alias_method :inline_ref, :inline_labelref
def inline_pageref(idref)
- %Q[●● ] # ページ番号を参照
+ %Q[●● ] # ページ番号を参照
end
def inline_balloon(str)
- %Q[#{escape_html(str).gsub(/@maru\[(\d+)\]/) {|m| inline_maru($1)}} ]
+ %Q[#{str.gsub(/@maru\[(\d+)\]/) {|m| inline_maru($1)}} ]
end
def inline_uchar(str)
@@ -777,45 +802,48 @@ def inline_uchar(str)
def inline_m(str)
@texinlineequation += 1
- %Q[#{escape_html(str)} ]
+ %Q[#{str} ]
end
def noindent
@noindent = true
+ ""
end
def linebreak
# FIXME:pが閉じちゃってるので一度戻らないといけないが、難しい…。
- puts " "
+ " " + @lf
end
def pagebreak
- puts " "
+ " " + @lf
end
def nonum_begin(level, label, caption)
- puts %Q[#{compile_inline(caption)} ]
+ %Q[#{caption} ] + @lf
end
def nonum_end(level)
end
def circle_begin(level, label, caption)
- puts %Q[•#{compile_inline(caption)} ]
+ %Q[•#{caption} ] + @lf
end
def circle_end(level)
end
def common_column_begin(type, caption)
+ buf = ""
@column += 1
a_id = %Q[id="column-#{@column}"]
- print "<#{type}column #{a_id}>"
- puts %Q[#{compile_inline(caption)} ]
+ buf << "<#{type}column #{a_id}>"
+ buf << %Q[#{caption} ] << @lf
+ buf
end
def common_column_end(type)
- puts "#{type}column>"
+ "#{type}column>" + @lf
end
def column_begin(level, label, caption)
@@ -868,42 +896,43 @@ def insideout_end(level)
def ref_begin(level, label, caption)
if !label.nil?
- puts ""
+ "" + @lf
else
- puts ""
+ "" + @lf
end
end
def ref_end(level)
- puts " "
+ " " + @lf
end
def sup_begin(level, label, caption)
if !label.nil?
- puts ""
+ "" + @lf
else
- puts ""
+ "" + @lf
end
end
def sup_end(level)
- puts " "
+ " " + @lf
end
def flushright(lines)
- puts split_paragraph(lines).join.gsub("", "
")
+ lines.join("").gsub("
", "
") + @lf
end
def centering(lines)
- puts split_paragraph(lines).join.gsub("
", "
")
+ lines.join("").gsub("
", "
") + @lf
end
def captionblock(type, lines, caption, specialstyle = nil)
- print "<#{type}>"
+ buf = ""
+ buf << "<#{type}>"
style = specialstyle.nil? ? "#{type}-title" : specialstyle
- puts "
#{compile_inline(caption)} " unless caption.nil?
- blocked_lines = split_paragraph(lines)
- puts "#{blocked_lines.join}#{type}>"
+ buf << "#{caption} " + @lf unless caption.nil?
+ buf << "#{lines.join}#{type}>" << @lf
+ buf
end
def note(lines, caption = nil)
@@ -991,8 +1020,9 @@ def expert(lines)
end
def syntaxblock(type, lines, caption)
+ buf = ""
if caption.nil?
- puts %Q[<#{type}>]
+ buf << %Q[<#{type}>] << @lf
else
titleopentag = %Q[caption aid:pstyle="#{type}-title"]
titleclosetag = "caption"
@@ -1000,22 +1030,24 @@ def syntaxblock(type, lines, caption)
titleopentag = %Q[floattitle type="insn"]
titleclosetag = "floattitle"
end
- puts %Q[<#{type}><#{titleopentag}>#{compile_inline(caption)}#{titleclosetag}>]
+ buf << %Q[<#{type}><#{titleopentag}>#{caption}#{titleclosetag}>] << @lf
end
no = 1
lines.each do |line|
+ line.chomp!
unless @book.config["listinfo"].nil?
- print %Q[]
+ buf << %Q[]
end
- print detab(line)
- print "\n"
- print " " unless @book.config["listinfo"].nil?
+ buf << detab(line)
+ buf << "\n"
+ buf << " " unless @book.config["listinfo"].nil?
no += 1
end
- puts "#{type}>"
+ buf << "#{type}>" << @lf
+ buf
end
def insn(lines, caption = nil)
@@ -1027,38 +1059,41 @@ def box(lines, caption = nil)
end
def indepimage(id, caption=nil, metric=nil)
+ buf = ""
metrics = parse_metric("idgxml", metric)
- puts " "
+ buf << " " << @lf
begin
- puts %Q[ ]
+ buf << %Q[ ] << @lf
rescue
warn %Q[no such image: #{id}]
end
- puts %Q[#{compile_inline(caption)} ] if caption.present?
- puts ""
+ buf << %Q[#{caption} ] + @lf if caption.present?
+ buf << "" << @lf
+ buf
end
alias_method :numberlessimage, :indepimage
def label(id)
# FIXME
- print " "
+ " "
end
def tsize(str)
@tsize = str
+ nil
end
def dtp(str)
- print %Q()
+ %Q()
end
def hr
- print " "
+ " "
end
def bpo(lines)
- puts %Q[#{lines.join("\n")} ]
+ %Q[#{lines.join("\n")} ] + @lf
end
def inline_dtp(str)
@@ -1066,7 +1101,7 @@ def inline_dtp(str)
end
def inline_code(str)
- %Q[#{escape_html(str)} ]
+ %Q[#{str} ]
end
def inline_br(str)
@@ -1074,12 +1109,14 @@ def inline_br(str)
end
def rawblock(lines)
+ buf = ""
no = 1
lines.each do |l|
- print l.gsub("<", "<").gsub(">", ">").gsub(""", "\"").gsub("&", "&")
- print "\n" unless lines.length == no
+ buf << l.gsub("<", "<").gsub(">", ">").gsub(""", "\"").gsub("&", "&")
+ buf << "\n" unless lines.length == no
no += 1
end
+ buf
end
def text(str)
@@ -1132,31 +1169,39 @@ def inline_title(id)
end
def source_header(caption)
- puts %Q[]
- puts %Q[#{compile_inline(caption)} ]
+ buf = ""
+ buf << %Q[] << @lf
+ buf << %Q[#{caption} ] << @lf
+ buf
end
def source_body(lines, lang)
- puts %Q[]
- codelines_body(lines)
- puts %Q[ ]
+ buf = ""
+ buf << %Q[] << @lf
+ buf << codelines_body(lines)
+ buf << %Q[ ] << @lf
+ buf
end
def bibpaper(lines, id, caption)
- bibpaper_header id, caption
+ buf = ""
+ buf << bibpaper_header(id, caption)
unless lines.empty?
- bibpaper_bibpaper id, caption, lines
+ buf << bibpaper_bibpaper(id, caption, lines)
end
- puts %Q()
+ buf << %Q() << @lf
+ buf
end
def bibpaper_header(id, caption)
- puts %Q()
- puts "[#{@chapter.bibpaper(id).number}] #{compile_inline(caption)} "
+ buf = ""
+ buf << %Q() << @lf
+ buf << "[#{@chapter.bibpaper(id).number}] #{caption} " << @lf
+ buf
end
def bibpaper_bibpaper(id, caption, lines)
- print split_paragraph(lines).join("")
+ lines.join("")
end
def inline_bib(id)
@@ -1167,15 +1212,15 @@ def inline_hd_chap(chap, id)
if chap.number
n = chap.headline_index.number(id)
if @book.config["secnolevel"] >= n.split('.').size
- return I18n.t("chapter_quote", "#{n} #{compile_inline(chap.headline(id).caption)}")
+ return I18n.t("chapter_quote", "#{n} #{chap.headline(id).caption}")
end
end
- I18n.t("chapter_quote", compile_inline(chap.headline(id).caption))
+ I18n.t("chapter_quote", chap.headline(id).caption)
end
def inline_recipe(id)
# FIXME
- %Q([XXX]「#{escape_html(id)}」 p.XX )
+ %Q([XXX]「#{id}」 p.XX )
end
def nofunc_text(str)
diff --git a/lib/review/latexbuilder.rb b/lib/review/latexbuilder.rb
index 09b2db90b..1e8d9ceab 100644
--- a/lib/review/latexbuilder.rb
+++ b/lib/review/latexbuilder.rb
@@ -47,23 +47,10 @@ def blank
end
private :blank
- def print(*s)
- if @blank_needed
- @output.puts
- @blank_needed = false
- end
- super
- end
- private :print
-
- def puts(*s)
- if @blank_needed
- @output.puts
- @blank_needed = false
- end
- super
+ def blank_reset
+ @blank_needed = false
end
- private :puts
+ private :blank_reset
HEADLINE = {
1 => 'chapter',
@@ -75,6 +62,7 @@ def puts(*s)
}
def headline(level, label, caption)
+ buf = ""
_, anchor = headline_prefix(level)
headline_name = HEADLINE[level]
if @chapter.kind_of? ReVIEW::Book::Part
@@ -84,41 +72,40 @@ def headline(level, label, caption)
if level > @book.config["secnolevel"] || (@chapter.number.to_s.empty? && level > 1)
prefix = "*"
end
- blank unless @output.pos == 0
- puts macro(headline_name+prefix, compile_inline(caption))
+ buf << macro(headline_name+prefix, caption) << "\n"
if prefix == "*" && level <= @book.config["toclevel"].to_i
- puts "\\addcontentsline{toc}{#{headline_name}}{#{compile_inline(caption)}}"
+ buf << "\\addcontentsline{toc}{#{headline_name}}{#{caption}}\n"
end
if level == 1
- puts macro('label', chapter_label)
+ buf << macro('label', chapter_label) << "\n"
else
- puts macro('label', sec_label(anchor))
+ buf << macro('label', sec_label(anchor)) << "\n"
end
+ buf
rescue
error "unknown level: #{level}"
end
def nonum_begin(level, label, caption)
- blank unless @output.pos == 0
- puts macro(HEADLINE[level]+"*", compile_inline(caption))
- puts macro('addcontentsline', 'toc', HEADLINE[level], compile_inline(caption))
+ "\n" + macro(HEADLINE[level]+"*", caption) + "\n" +
+ macro('addcontentsline', 'toc', HEADLINE[level], caption)
end
def nonum_end(level)
end
def notoc_begin(level, label, caption)
- blank unless @output.pos == 0
- puts macro(HEADLINE[level]+"*", compile_inline(caption))
+ "\n" +
+ macro(HEADLINE[level]+"*", caption)
end
def notoc_end(level)
end
def nodisp_begin(level, label, caption)
- blank unless @output.pos == 0
- puts macro('clearpage') if @output.pos == 0
- puts macro('addcontentsline', 'toc', HEADLINE[level], compile_inline(caption))
+ buf = "\n"
+ buf << macro('clearpage') if @output.pos == 0
+ buf << macro('addcontentsline', 'toc', HEADLINE[level], caption)
# FIXME: headings
end
@@ -126,115 +113,124 @@ def nodisp_end(level)
end
def column_begin(level, label, caption)
+ buf = ""
blank
- puts "\\begin{reviewcolumn}\n"
+ if @blank_needed
+ buf << "\n"
+ blank_reset
+ end
+ buf << "\\begin{reviewcolumn}\n"
if label
- puts "\\hypertarget{#{column_label(label)}}{}"
+ buf << "\\hypertarget{#{column_label(label)}}{}\n"
else
- puts "\\hypertarget{#{column_label(caption)}}{}"
+ buf << "\\hypertarget{#{column_label(caption)}}{}\n"
end
- puts macro('reviewcolumnhead', nil, compile_inline(caption))
+ buf << macro('reviewcolumnhead', nil, caption) << "\n"
if level <= @book.config["toclevel"].to_i
- puts "\\addcontentsline{toc}{#{HEADLINE[level]}}{#{compile_inline(caption)}}"
+ buf << "\\addcontentsline{toc}{#{HEADLINE[level]}}{#{caption}}" << "\n"
end
+ buf
end
def column_end(level)
- puts "\\end{reviewcolumn}\n"
- blank
+ buf = ""
+ buf << "\\end{reviewcolumn}\n"
+ buf
end
def captionblock(type, lines, caption)
- puts "\\begin{reviewminicolumn}\n"
+ buf = ""
+ buf << "\\begin{reviewminicolumn}\n"
unless caption.nil?
- puts "\\reviewminicolumntitle{#{compile_inline(caption)}}\n"
+ buf << "\\reviewminicolumntitle{#{caption}}\n"
end
- blocked_lines = split_paragraph(lines)
- puts blocked_lines.join("\n\n")
+ if lines[0].start_with?("\n")
+ lines[0].sub!(/\A\n/, "")
+ end
+ buf << lines.join("")
- puts "\\end{reviewminicolumn}\n"
+ buf << "\\end{reviewminicolumn}\n"
+ buf
end
def box(lines, caption = nil)
- blank
+ buf = "\n"
if caption
- puts macro('reviewboxcaption', "#{compile_inline(caption)}")
+ buf << macro('reviewboxcaption', "#{caption}") << "\n"
end
- puts '\begin{reviewbox}'
+ buf << '\begin{reviewbox}' << "\n"
lines.each do |line|
- puts detab(line)
- end
- puts '\end{reviewbox}'
- blank
+ buf << detab(line) << "\n"
+ end<
+ buf << '\end{reviewbox}' << "\n"
end
def ul_begin
- blank
- puts '\begin{itemize}'
+ buf = "\n"
+ buf << '\begin{itemize}' << "\n"
+ buf
end
def ul_item(lines)
str = lines.join
str.sub!(/\A(\[)/){'\lbrack{}'}
- puts '\item ' + str
+ '\item ' + str + "\n"
end
def ul_end
- puts '\end{itemize}'
- blank
+ '\end{itemize}' + "\n"
end
def ol_begin
- blank
- puts '\begin{enumerate}'
+ buf = "\n"
+ buf << '\begin{enumerate}' << "\n"
if @ol_num
- puts "\\setcounter{enumi}{#{@ol_num - 1}}"
+ buf << "\\setcounter{enumi}{#{@ol_num - 1}}\n"
@ol_num = nil
end
+ buf
end
def ol_item(lines, num)
str = lines.join
str.sub!(/\A(\[)/){'\lbrack{}'}
- puts '\item ' + str
+ '\item ' + str + "\n"
end
def ol_end
- puts '\end{enumerate}'
- blank
+ '\end{enumerate}' + "\n"
end
def dl_begin
- blank
- puts '\begin{description}'
+ "\n" + '\begin{description}' + "\n"
end
def dt(str)
str.sub!(/\[/){'\lbrack{}'}
str.sub!(/\]/){'\rbrack{}'}
- puts '\item[' + str + '] \mbox{} \\\\'
+ '\item[' + str + '] \mbox{} \\\\' + "\n"
end
def dd(lines)
- puts lines.join
+ lines.join + "\n"
end
def dl_end
- puts '\end{description}'
- blank
+ '\end{description}' + "\n"
end
def paragraph(lines)
- blank
+ buf = "\n"
lines.each do |line|
- puts line
+ buf << line
end
- blank
+ buf << "\n"
+ buf
end
def parasep
- puts '\\parasep'
+ '\\parasep' + "\n"
end
def read(lines)
@@ -249,67 +245,78 @@ def highlight_listings?
private :highlight_listings?
def emlist(lines, caption = nil, lang = nil)
- blank
+ buf = "\n"
if highlight_listings?
- common_code_block_lst(nil, lines, 'reviewemlistlst', 'title', caption, lang)
+ buf << common_code_block_lst(nil, lines, 'reviewemlistlst', 'title', caption, lang)
else
- common_code_block(nil, lines, 'reviewemlist', caption, lang) do |line, idx|
+ buf << common_code_block(nil, lines, 'reviewemlist', caption, lang) do |line, idx|
detab(line) + "\n"
end
end
+ buf
end
def emlistnum(lines, caption = nil, lang = nil)
- blank
+ buf = "\n"
if highlight_listings?
- common_code_block_lst(nil, lines, 'reviewemlistnumlst', 'title', caption, lang)
+ buf << common_code_block_lst(nil, lines, 'reviewemlistnumlst', 'title', caption, lang)
else
- common_code_block(nil, lines, 'reviewemlist', caption, lang) do |line, idx|
+ buf << common_code_block(nil, lines, 'reviewemlist', caption, lang) do |line, idx|
detab((idx+1).to_s.rjust(2)+": " + line) + "\n"
end
end
+ buf
end
## override Builder#list
- def list(lines, id, caption, lang = nil)
+ def list(lines, id, caption = nil, lang = nil)
+ buf = ""
if highlight_listings?
- common_code_block_lst(id, lines, 'reviewlistlst', 'caption', caption, lang)
+ buf << common_code_block_lst(id, lines, 'reviewlistlst', 'caption', caption, lang)
else
- common_code_block(id, lines, 'reviewlist', caption, lang) do |line, idx|
+ buf << common_code_block(id, lines, 'reviewlist', caption, lang) do |line, idx|
detab(line) + "\n"
end
end
+ buf
end
+
## override Builder#listnum
- def listnum(lines, id, caption, lang = nil)
+ def listnum(lines, id, caption = nil, lang = nil)
+ buf = ""
if highlight_listings?
- common_code_block_lst(id, lines, 'reviewlistnumlst', 'caption', caption, lang)
+ buf << common_code_block_lst(id, lines, 'reviewlistnumlst', 'caption', caption, lang)
else
- common_code_block(id, lines, 'reviewlist', caption, lang) do |line, idx|
+ buf << common_code_block(id, lines, 'reviewlist', caption, lang) do |line, idx|
detab((idx+1).to_s.rjust(2)+": " + line) + "\n"
end
end
+ buf
end
def cmd(lines, caption = nil, lang = nil)
+ buf = ""
if highlight_listings?
- common_code_block_lst(nil, lines, 'reviewcmdlst', 'title', caption, lang)
+ buf << common_code_block_lst(nil, lines, 'reviewcmdlst', 'title', caption, lang)
else
- blank
- common_code_block(nil, lines, 'reviewcmd', caption, lang) do |line, idx|
+ buf << "\n"
+ buf << common_code_block(nil, lines, 'reviewcmd', caption, lang) do |line, idx|
detab(line) + "\n"
end
end
+ buf
end
def common_code_block(id, lines, command, caption, lang)
+ buf = ""
if caption
if command =~ /emlist/ || command =~ /cmd/
- puts macro(command + 'caption', "#{compile_inline(caption)}")
+ buf << macro(command + 'caption', "#{caption}") + "\n"
else
begin
- puts macro('reviewlistcaption', "#{I18n.t("list")}#{I18n.t("format_number_header", [@chapter.number, @chapter.list(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}")
+ buf << "\n"
+ buf << macro('reviewlistcaption', "#{I18n.t("list")}#{I18n.t("format_number_header", [@chapter.number, @chapter.list(id).number])}#{I18n.t("caption_prefix")}#{caption}") + "\n"
rescue KeyError
error "no such list: #{id}"
end
@@ -319,17 +326,18 @@ def common_code_block(id, lines, command, caption, lang)
lines.each_with_index do |line, idx|
body.concat(yield(line, idx))
end
- puts macro('begin' ,command)
- print body
- puts macro('end' ,command)
- blank
+ buf << macro('begin' ,command) + "\n"
+ buf << body
+ buf << macro('end' ,command) + "\n"
+ buf
end
def common_code_block_lst(id, lines, command, title, caption, lang)
- caption_str = compile_inline((caption || ""))
+ buf = ""
+ caption_str = (caption || "")
if title == "title" && caption_str == ""
caption_str = "\\relax" ## dummy charactor to remove lstname
- print "\\vspace{-1.5em}"
+ buf << "\\vspace{-1.5em}"
end
if @book.config["highlight"] && @book.config["highlight"]["lang"]
lexer = @book.config["highlight"]["lang"] # default setting
@@ -338,24 +346,36 @@ def common_code_block_lst(id, lines, command, title, caption, lang)
end
lexer = lang if lang.present?
body = lines.inject(''){|i, j| i + detab(unescape_latex(j)) + "\n"}
- puts "\\begin{"+command+"}["+title+"={"+caption_str+"},language={"+ lexer+"}]"
- print body
- puts "\\end{"+ command + "}"
- blank
+ buf << "\\begin{"+command+"}["+title+"={"+caption_str+"},language={"+ lexer+"}]" + "\n"
+ buf << body
+ buf << "\\end{"+ command + "}" + "\n"
+ buf
end
- def source(lines, caption, lang = nil)
+ def source(lines, caption = nil, lang = nil)
if highlight_listings?
common_code_block_lst(nil, lines, 'reviewlistlst', 'title', caption, lang)
else
- puts '\begin{reviewlist}'
- puts macro('reviewlistcaption', compile_inline(caption))
- lines.each do |line|
- puts detab(line)
- end
- puts '\end{reviewlist}'
- puts ""
+ buf = "\n"
+ buf << '\begin{reviewlist}' << "\n"
+ buf << source_header(caption)
+ buf << source_body(lines)
+ buf << '\end{reviewlist}' << "\n"
+ buf << "\n"
+ buf
+ end
+ end
+
+ def source_header(caption)
+ macro('reviewlistcaption', caption) + "\n"
+ end
+
+ def source_body(lines)
+ buf = ""
+ lines.each do |line|
+ buf << detab(line) << "\n"
end
+ buf
end
@@ -374,31 +394,34 @@ def result_metric(array)
end
def image_image(id, caption, metric)
+ buf = ""
metrics = parse_metric("latex", metric)
# image is always bound here
- puts '\begin{reviewimage}'
+ buf << '\begin{reviewimage}' << "\n"
if metrics.present?
- puts "\\includegraphics[#{metrics}]{#{@chapter.image(id).path}}"
+ buf << "\\includegraphics[#{metrics}]{#{@chapter.image(id).path}}\n"
else
- puts "\\includegraphics[width=\\maxwidth]{#{@chapter.image(id).path}}"
+ buf << "\\includegraphics[width=\\maxwidth]{#{@chapter.image(id).path}}\n"
end
if caption.present?
- puts macro('caption', compile_inline(caption))
+ buf << macro('caption', caption) << "\n"
end
- puts macro('label', image_label(id))
- puts '\end{reviewimage}'
+ buf << macro('label', image_label(id)) << "\n"
+ buf << '\end{reviewimage}' << "\n"
+ buf
end
def image_dummy(id, caption, lines)
- puts '\begin{reviewdummyimage}'
+ buf << '\begin{reviewdummyimage}' << "\n"
path = @chapter.image(id).path
- puts "--[[path = #{path} (#{existence(id)})]]--"
+ buf << "--[[path = #{path} (#{existence(id)})]]--\n"
lines.each do |line|
- puts detab(line.rstrip)
+ buf << detab(line.rstrip) << "\n"
end
- puts macro('label', image_label(id))
- puts compile_inline(caption)
- puts '\end{reviewdummyimage}'
+ buf << macro('label', image_label(id)) << "\n"
+ buf << caption << "\n"
+ buf << '\end{reviewdummyimage}' << "\n"
+ buf
end
def existence(id)
@@ -441,23 +464,34 @@ def column_label(id)
private :column_label
def indepimage(id, caption=nil, metric=nil)
+ buf = ""
metrics = parse_metric("latex", metric)
- puts '\begin{reviewimage}'
+ buf << '\begin{reviewimage}' << "\n"
if metrics.present?
- puts "\\includegraphics[#{metrics}]{#{@chapter.image(id).path}}"
+ buf << "\\includegraphics[#{metrics}]{#{@chapter.image(id).path}}\n"
else
- puts "\\includegraphics[width=\\maxwidth]{#{@chapter.image(id).path}}"
+ buf << "\\includegraphics[width=\\maxwidth]{#{@chapter.image(id).path}}\n"
end
if caption.present?
- puts macro('reviewindepimagecaption',
- %Q[#{I18n.t("numberless_image")}#{I18n.t("caption_prefix")}#{compile_inline(caption)}])
+ buf << macro('reviewindepimagecaption',
+ %Q[#{I18n.t("numberless_image")}#{I18n.t("caption_prefix")}#{caption}]) << "\n"
end
- puts '\end{reviewimage}'
+ buf << '\end{reviewimage}' << "\n"
+ buf
end
alias_method :numberlessimage, :indepimage
- def table(lines, id = nil, caption = nil)
+ def node_table(node)
+ id_node = node.args[0]
+ id = id_node ? id_node.to_raw : ""
+ caption_node = node.args[1]
+ caption = caption_node ? caption_node.to_doc : ""
+ lines = []
+ node.content.each do |line|
+ lines << line.to_doc
+ end
+ buf = ""
rows = []
sepidx = nil
lines.each_with_index do |line, idx|
@@ -472,49 +506,56 @@ def table(lines, id = nil, caption = nil)
rows = adjust_n_cols(rows)
begin
- table_header id, caption unless caption.nil?
+ buf << table_header(id, caption) unless caption.nil?
rescue KeyError
error "no such table: #{id}"
end
- return if rows.empty?
- table_begin rows.first.size
+ return buf if rows.empty?
+ buf << table_begin(rows.first.size)
if sepidx
sepidx.times do
- tr rows.shift.map {|s| th(s) }
+ buf << tr(rows.shift.map {|s| th(s) })
end
rows.each do |cols|
- tr cols.map {|s| td(s) }
+ buf << tr(cols.map {|s| td(s) })
end
else
rows.each do |cols|
h, *cs = *cols
- tr [th(h)] + cs.map {|s| td(s) }
+ buf << tr([th(h)] + cs.map {|s| td(s) })
end
end
- table_end
+ buf << table_end
+ buf
end
def table_header(id, caption)
+ buf = ""
if caption.present?
@table_caption = true
- puts '\begin{table}[h]'
- puts macro('reviewtablecaption', compile_inline(caption))
+ buf << '\begin{table}[h]' << "\n"
+ buf << macro('reviewtablecaption', caption) << "\n"
end
- puts macro('label', table_label(id))
+ if id.present?
+ buf << macro('label', table_label(id)) << "\n"
+ end
+ buf
end
def table_begin(ncols)
+ buf = ""
if @latex_tsize
- puts macro('begin', 'reviewtable', @latex_tsize)
+ buf << macro('begin', 'reviewtable', @latex_tsize) << "\n"
elsif @tsize
cellwidth = @tsize.split(/\s*,\s*/)
- puts macro('begin', 'reviewtable', '|'+cellwidth.collect{|i| "p{#{i}mm}"}.join('|')+'|')
+ buf << macro('begin', 'reviewtable', '|'+cellwidth.collect{|i| "p{#{i}mm}"}.join('|')+'|') << "\n"
else
- puts macro('begin', 'reviewtable', (['|'] * (ncols + 1)).join('l'))
+ buf << macro('begin', 'reviewtable', (['|'] * (ncols + 1)).join('l')) << "\n"
end
- puts '\hline'
+ buf << '\hline' << "\n"
@tsize = nil
@latex_tsize = nil
+ buf
end
def table_separator
@@ -540,53 +581,59 @@ def td(s)
end
def tr(rows)
- print rows.join(' & ')
- puts ' \\\\ \hline'
+ buf = ""
+ buf << rows.join(' & ')
+ buf << ' \\\\ \hline' << "\n"
+ buf
end
def table_end
- puts macro('end', 'reviewtable')
+ buf = ""
+ buf << macro('end', 'reviewtable') << "\n"
if @table_caption
- puts '\end{table}'
+ buf << '\end{table}' << "\n"
end
@table_caption = nil
- blank
+ buf
end
def imgtable(lines, id, caption = nil, metric = nil)
if !@chapter.image(id).bound?
warn "image not bound: #{id}"
- image_dummy id, caption, lines
- return
+ return image_dummy(id, caption, lines)
end
+ buf = ""
+
begin
if caption.present?
@table_caption = true
- puts '\begin{table}[h]'
- puts macro('reviewimgtablecaption', compile_inline(caption))
+ buf << '\begin{table}[h]' + "\n"
+ buf << macro('reviewimgtablecaption', caption) + "\n"
end
- puts macro('label', table_label(id))
+ buf << macro('label', table_label(id)) + "\n"
rescue ReVIEW::KeyError
error "no such table: #{id}"
end
- imgtable_image(id, caption, metric)
+ buf << imgtable_image(id, caption, metric)
- puts '\end{table}' if @table_caption
+ buf << '\end{table}' + "\n" if @table_caption
@table_caption = nil
- blank
+ buf
end
def imgtable_image(id, caption, metric)
metrics = parse_metric("latex", metric)
# image is always bound here
- puts '\begin{reviewimage}'
+ buf = ""
+ buf << '\begin{reviewimage}' + "\n"
if metrics.present?
- puts "\\includegraphics[#{metrics}]{#{@chapter.image(id).path}}"
+ buf << "\\includegraphics[#{metrics}]{#{@chapter.image(id).path}}" + "\n"
else
- puts "\\includegraphics[width=\\maxwidth]{#{@chapter.image(id).path}}"
+ buf << "\\includegraphics[width=\\maxwidth]{#{@chapter.image(id).path}}" + "\n"
end
- puts '\end{reviewimage}'
+ buf << '\end{reviewimage}' + "\n"
+ buf
end
def quote(lines)
@@ -604,63 +651,73 @@ def flushright(lines)
end
def texequation(lines)
- blank
- puts macro('begin','equation*')
+ buf = "\n"
+ buf << macro('begin','equation*') << "\n"
lines.each do |line|
- puts unescape_latex(line)
+ buf << unescape_latex(line) << "\n"
end
- puts macro('end', 'equation*')
- blank
+ buf << macro('end', 'equation*') << "\n"
+ buf << "\n"
+ buf
end
def latex_block(type, lines)
- blank
- puts macro('begin', type)
- blocked_lines = split_paragraph(lines)
- puts blocked_lines.join("\n\n")
- puts macro('end', type)
- blank
+ buf = "\n"
+ buf << macro('begin', type)
+ buf << lines.join("")
+ buf << macro('end', type) << "\n"
+ buf
end
private :latex_block
def direct(lines, fmt)
- return unless fmt == 'latex'
+ buf = ""
+ return buf unless fmt == 'latex'
lines.each do |line|
- puts line
+ buf << line << "\n"
end
+ buf
end
def comment(lines, comment = nil)
+ buf = ""
lines ||= []
lines.unshift comment unless comment.blank?
if @book.config["draft"]
str = lines.join("")
- puts macro('pdfcomment', escape(str))
+ buf << macro('pdfcomment', str) << "\n"
end
+ buf
end
def hr
- puts '\hrule'
+ '\hrule' + "\n"
end
def label(id)
- puts macro('label', id)
+ macro('label', id) + "\n"
+ end
+
+ def node_label(node)
+ id = node.args[0].to_raw
+ macro('label', id) + "\n"
end
def pagebreak
- puts '\pagebreak'
+ '\pagebreak' + "\n"
end
def linebreak
- puts '\\\\'
+ '\\\\' + "\n"
end
def noindent
- print '\noindent'
+ '\noindent'
end
- def inline_chapref(id)
- title = super
+ def node_inline_chapref(node)
+ id = node[0].to_raw
+ title = @book.chapter_index.display_string(id)
if @book.config["chapterlink"]
"\\hyperref[chap:#{id}]{#{title}}"
else
@@ -671,7 +728,8 @@ def inline_chapref(id)
nofunc_text("[UnknownChapter:#{id}]")
end
- def inline_chap(id)
+ def node_inline_chap(node)
+ id = node[0].to_raw
if @book.config["chapterlink"]
"\\hyperref[chap:#{id}]{#{@book.chapter_index.number(id)}}"
else
@@ -682,8 +740,9 @@ def inline_chap(id)
nofunc_text("[UnknownChapter:#{id}]")
end
- def inline_title(id)
- title = super
+ def node_inline_title(node)
+ id = node[0].to_raw
+ title = @book.chapter_index.title(id)
if @book.config["chapterlink"]
"\\hyperref[chap:#{id}]{#{title}}"
else
@@ -696,33 +755,37 @@ def inline_title(id)
# FIXME: use TeX native label/ref.
- def inline_list(id)
+ def node_inline_list(node)
+ id = node[0].to_raw
chapter, id = extract_chapter_id(id)
macro('reviewlistref', "#{chapter.number}.#{chapter.list(id).number}")
end
- def inline_table(id)
+ def node_inline_table(node)
+ id = node[0].to_raw
chapter, id = extract_chapter_id(id)
macro('reviewtableref', "#{chapter.number}.#{chapter.table(id).number}", table_label(id, chapter))
end
- def inline_img(id)
+ def node_inline_img(node)
+ id = node[0].to_raw
chapter, id = extract_chapter_id(id)
macro('reviewimageref', "#{chapter.number}.#{chapter.image(id).number}", image_label(id, chapter))
end
def footnote(id, content)
if @book.config["footnotetext"]
- puts macro("footnotetext[#{@chapter.footnote(id).number}]",
- compile_inline(content.strip))
+ macro("footnotetext[#{@chapter.footnote(id).number}]",
+ content.strip) + "\n"
end
end
- def inline_fn(id)
+ def node_inline_fn(node)
+ id = node[0].to_raw
if @book.config["footnotetext"]
macro("footnotemark[#{@chapter.footnote(id).number}]", "")
else
- macro('footnote', compile_inline(@chapter.footnote(id).content.strip))
+ macro('footnote', @chapter.footnote(id).content.strip)
end
end
@@ -733,12 +796,16 @@ def inline_bou(str)
end
def compile_ruby(base, ruby)
- macro('ruby', escape(base), escape(ruby))
+ macro('ruby', base, ruby)
end
# math
- def inline_m(str)
- " $#{str}$ "
+# def inline_m(str)
+# " $#{str}$ "
+# end
+
+ def node_inline_m(node)
+ " $#{node[0].to_raw}$ "
end
# hidden index
@@ -748,7 +815,7 @@ def inline_hi(str)
# index -> italic
def inline_i(str)
- macro('textit', escape(str))
+ macro('textit', str)
end
# index
@@ -756,14 +823,24 @@ def inline_idx(str)
escape(str) + index(str)
end
+ def node_inline_idx(nodelist)
+ content = nodelist[0].to_raw
+ escape(content) + index(content)
+ end
+
# hidden index??
def inline_hidx(str)
index(str)
end
+ def node_inline_hidx(nodelist)
+ content = nodelist[0].to_raw
+ index(content)
+ end
+
# bold
def inline_b(str)
- macro('textbf', escape(str))
+ macro('textbf', str)
end
# line break
@@ -778,7 +855,7 @@ def inline_dtp(str)
## @ is same as @
def inline_code(str)
- macro('texttt', escape(str))
+ macro('texttt', str)
end
def nofunc_text(str)
@@ -786,44 +863,46 @@ def nofunc_text(str)
end
def inline_tt(str)
- macro('texttt', escape(str))
+ macro('texttt', str)
end
def inline_del(str)
- macro('reviewstrike', escape(str))
+ macro('reviewstrike', str)
end
def inline_tti(str)
- macro('texttt', macro('textit', escape(str)))
+ macro('texttt', macro('textit', str))
end
def inline_ttb(str)
- macro('texttt', macro('textbf', escape(str)))
+ macro('texttt', macro('textbf', str))
end
- def inline_bib(id)
+ def node_inline_bib(node)
+ id = node[0].to_raw
macro('reviewbibref', "[#{@chapter.bibpaper(id).number}]", bib_label(id))
end
def inline_hd_chap(chap, id)
n = chap.headline_index.number(id)
if chap.number and @book.config["secnolevel"] >= n.split('.').size
- str = I18n.t("chapter_quote", "#{chap.headline_index.number(id)} #{compile_inline(chap.headline(id).caption)}")
+ str = I18n.t("chapter_quote", "#{chap.headline_index.number(id)} #{chap.headline(id).caption}")
else
- str = I18n.t("chapter_quote", compile_inline(chap.headline(id).caption))
+ str = I18n.t("chapter_quote", chap.headline(id).caption)
end
if @book.config["chapterlink"]
anchor = n.gsub(/\./, "-")
- macro('reviewsecref', str, sec_label(anchor))
+ macro('reviewsecref', escape(str), sec_label(anchor))
else
- str
+ escape(str)
end
end
- def inline_column_chap(chapter, id)
+ def node_inline_column(node)
+ id = node[0].to_raw
macro('reviewcolumnref',
- I18n.t("chapter_quote", compile_inline(chapter.column(id).caption)),
- column_label(id))
+ I18n.t("chapter_quote", compile_inline(@chapter.column(id).caption)),
+ column_label(id))
end
def inline_raw(str)
@@ -831,19 +910,19 @@ def inline_raw(str)
end
def inline_sub(str)
- macro('textsubscript', escape(str))
+ macro('textsubscript', str)
end
def inline_sup(str)
- macro('textsuperscript', escape(str))
+ macro('textsuperscript', str)
end
def inline_em(str)
- macro('reviewem', escape(str))
+ macro('reviewem', str)
end
def inline_strong(str)
- macro('reviewstrong', escape(str))
+ macro('reviewstrong', str)
end
def inline_u(str)
@@ -851,16 +930,17 @@ def inline_u(str)
end
def inline_ami(str)
- macro('reviewami', escape(str))
+ macro('reviewami', str)
end
- def inline_icon(id)
+ def node_inline_icon(node)
+ id = node[0].to_raw
macro('includegraphics', @chapter.image(id).path)
end
def inline_uchar(str)
# with otf package
- macro('UTF', escape(str))
+ macro('UTF', str)
end
def inline_comment(str)
@@ -871,50 +951,48 @@ def inline_comment(str)
end
end
+ def bibpaper(lines, id, caption)
+ buf = ""
+ buf << bibpaper_header(id, caption)
+ if lines.empty?
+ buf << "\n"
+ else
+ buf << "\n"
+ buf << bibpaper_bibpaper(id, caption, lines)
+ end
+ buf << "\n"
+ buf
+ end
+
def inline_tcy(str)
- macro('rensuji', escape(str))
+ macro('rensuji', str)
end
def bibpaper_header(id, caption)
- puts "[#{@chapter.bibpaper(id).number}] #{compile_inline(caption)}"
- puts macro('label', bib_label(id))
+ "[#{@chapter.bibpaper(id).number}] #{caption}\n" +
+ macro('label', bib_label(id))
end
def bibpaper_bibpaper(id, caption, lines)
- print split_paragraph(lines).join("")
- puts ""
+ lines.join("")
end
def index(str)
- str.sub!(/\(\)/, '')
- decl = ''
- if /@\z/ =~ str
- str.chop!
- decl = '|IndexDecl'
- end
- unless /[^ -~]/ =~ str
- if /\^/ =~ str
- macro('index', escape_index(str.gsub(/\^/, '')) + '@' + escape_index(text(str)) + decl)
- else
- '\index{' + escape_index(text(str)) + decl + '}'
- end
- else
- '\index{' + escape_index(@index_db[str]) + '@' + escape_index(text(str)) + '}'
- end
+ "\\index{" + str + "}"
end
def compile_kw(word, alt)
if alt
- macro('reviewkw', escape(word)) + "(#{escape(alt.strip)})"
+ macro('reviewkw', word) + "(#{alt.strip})"
else
- macro('reviewkw', escape(word))
+ macro('reviewkw', word)
end
end
def compile_href(url, label)
if /\A[a-z]+:/ =~ url
if label
- macro("href", escape_url(url), escape(label))
+ macro("href", escape_url(url), label)
else
macro("url", escape_url(url))
end
diff --git a/lib/review/location.rb b/lib/review/location.rb
new file mode 100644
index 000000000..662aa3df7
--- /dev/null
+++ b/lib/review/location.rb
@@ -0,0 +1,24 @@
+module ReVIEW
+ class Location
+ def initialize(filename, compiler)
+ @filename = filename
+ @f = compiler
+ end
+
+ attr_reader :filename
+
+ def lineno
+ @f.current_line
+ end
+
+ def string
+ begin
+ "#{@filename}:#{self.lineno}"
+ rescue
+ "#{@filename}:nil"
+ end
+ end
+
+ alias_method :to_s, :string
+ end
+end
diff --git a/lib/review/markdownbuilder.rb b/lib/review/markdownbuilder.rb
index 0be8399b7..fa258eb17 100644
--- a/lib/review/markdownbuilder.rb
+++ b/lib/review/markdownbuilder.rb
@@ -24,117 +24,152 @@ def builder_init_file
end
private :builder_init_file
- def puts(str)
+ def blank_reset
@blank_seen = false
- super
end
+# def puts(str)
+# @blank_seen = false
+# "#{str}\n"
+# end
+
def blank
- @output.puts unless @blank_seen
+ buf = ""
+ unless @blank_seen
+ buf = "\n"
+ end
@blank_seen = true
+ buf
end
def headline(level, label, caption)
- blank
+ buf = ""
+ buf << blank
prefix = "#" * level
- puts "#{prefix} #{caption}"
- blank
+ buf << "#{prefix} #{caption}\n"
+ blank_reset
+ buf << "\n"
+ buf
end
def quote(lines)
- blank
- puts split_paragraph(lines).map{|line| "> #{line}"}.join("\n> \n")
- blank
+ buf = ""
+ buf << blank
+ buf << lines.map{|line| line.chomp!;line.chomp!;"> #{line}"}.join("\n") << "\n"
+ blank_reset
+ buf << "\n"
+ buf
end
def paragraph(lines)
- puts lines.join
- puts "\n"
+ buf = lines.join << "\n"
+ blank_reset
+ buf << "\n"
+ buf
end
def list_header(id, caption, lang)
+ lang ||= ""
if get_chap.nil?
- print %Q[リスト#{@chapter.list(id).number} #{compile_inline(caption)}\n\n]
+ %Q[リスト#{@chapter.list(id).number} #{compile_inline(caption)}\n\n] + "```#{lang}\n"
else
- print %Q[リスト#{get_chap}.#{@chapter.list(id).number} #{compile_inline(caption)}\n\n]
+ %Q[リスト#{get_chap}.#{@chapter.list(id).number} #{compile_inline(caption)}\n\n] + "```#{lang}\n"
end
- lang ||= ""
- puts "```#{lang}"
end
def list_body(id, lines, lang)
+ buf = ""
lines.each do |line|
- puts detab(line)
+ buf << detab(line) << "\n"
end
- puts '```'
+ buf << '```' << "\n"
+ buf
end
def ul_begin
- blank if @ul_indent == 0
+ buf = ""
+ buf << blank if @ul_indent == 0
@ul_indent += 1
+ buf
end
def ul_item(lines)
- puts " " * (@ul_indent - 1) + "* " + "#{lines.join}"
+ blank_reset
+ " " * (@ul_indent - 1) + "* " + "#{lines.join}" + "\n"
end
def ul_item_begin(lines)
- puts " " * (@ul_indent - 1) + "* " + "#{lines.join}"
+ blank_reset
+ " " * (@ul_indent - 1) + "* " + "#{lines.join}" + "\n"
end
def ul_item_end
+ ""
end
def ul_end
+ buf = ""
@ul_indent -= 1
- blank if @ul_indent == 0
+ buf << blank if @ul_indent == 0
+ buf
end
def ol_begin
- blank
+ buf = ""
+ buf << blank
+ buf
end
def ol_item(lines, num)
- puts "#{num}. #{lines.join}"
+ buf = ""
+ buf << "#{num}. #{lines.join}" << "\n"
+ blank_reset
+ buf
end
def ol_end
- blank
+ buf = ""
+ buf << blank
+ buf
end
def dl_begin
- puts ''
+ "\n"
end
def dt(line)
- puts "#{line} "
+ "#{line} \n"
end
def dd(lines)
- puts "#{lines.join} "
+ "#{lines.join} \n"
end
def dl_end
- puts ' '
+ " \n"
end
def emlist(lines, caption = nil, lang = nil)
- blank
+ buf = ""
+ buf << blank
if caption
- puts caption
- print "\n"
+ buf << caption << "\n\n"
end
lang ||= ""
- puts "```#{lang}"
+ buf << "```#{lang}\n"
+ blank_reset
lines.each do |line|
- puts detab(line)
+ buf << detab(line) << "\n"
end
- puts "```"
- blank
+ buf << "```\n"
+ buf << blank
+ buf
end
def hr
- puts "----"
+ buf << "----\n"
+ blank_reset
+ buf
end
def compile_href(url, label)
@@ -168,45 +203,60 @@ def inline_tt(str)
def image_image(id, caption, metric)
- blank
- puts "![#{compile_inline(caption)}](#{@chapter.image(id).path.sub(/\A\.\//, "")})"
- blank
+ buf = ""
+ buf << blank
+ buf << "![#{compile_inline(caption)}](#{@chapter.image(id).path.sub(/\A\.\//, "")})" << "\n"
+ blank_reset
+ buf << blank
+ buf
end
def image_dummy(id, caption, lines)
- puts lines.join
+ buf = ""
+ buf << lines.join << "\n"
+ blank_reset
+ buf
end
def inline_img(id)
"#{I18n.t("image")}#{@chapter.image(id).number}"
rescue KeyError
error "unknown image: #{id}"
- nofunc_text("[UnknownImage:#{id}]")
+ "[UnknownImage:#{id}]"
end
def indepimage(id, caption="", metric=nil)
- blank
- puts "![#{compile_inline(caption)}](#{@chapter.image(id).path.sub(/\A\.\//, "")})"
- blank
+ buf = ""
+ buf << blank
+ buf << "![#{compile_inline(caption)}](#{@chapter.image(id).path.sub(/\A\.\//, "")})" << "\n"
+ blank_reset
+ buf << blank
+ buf
end
def pagebreak
- puts "{pagebreak}"
+ buf = ""
+ buf << "{pagebreak}" << "\n"
+ buf
end
def image_ext
"jpg"
end
- def cmd(lines)
- puts "```shell-session"
+ def cmd(lines, caption = nil)
+ buf = ""
+ buf << "```shell-session" << "\n"
+ blank_reset
lines.each do |line|
- puts detab(line)
+ buf << detab(line) << "\n"
end
- puts "```"
+ buf << "```" << "\n"
+ buf
end
def table(lines, id = nil, caption = nil)
+ buf = ""
rows = []
sepidx = nil
lines.each_with_index do |line, idx|
@@ -216,52 +266,58 @@ def table(lines, id = nil, caption = nil)
sepidx ||= idx
next
end
- rows.push line.strip.split(/\t+/).map {|s| s.sub(/\A\./, '') }
+ rows.push line.strip.split(/\t+/).map{|s| s.sub(/\A\./, '') }
end
rows = adjust_n_cols(rows)
begin
- table_header id, caption unless caption.nil?
+ buf << table_header(id, caption) unless caption.nil?
rescue KeyError
error "no such table: #{id}"
end
- table_begin rows.first.size
- return if rows.empty?
+ buf << table_begin(rows.first.size)
+ return buf if rows.empty?
if sepidx
sepidx.times do
- tr rows.shift.map {|s| th(s) }
+ buf << tr(rows.shift.map{|s| th(s) })
end
- table_border rows.first.size
+ buf << table_border(rows.first.size)
rows.each do |cols|
- tr cols.map {|s| td(s) }
+ buf << tr(cols.map{|s| td(s) })
end
else
rows.each do |cols|
h, *cs = *cols
- tr [th(h)] + cs.map {|s| td(s) }
+ tr([th(h)] + cs.map {|s| td(s) })
end
end
- table_end
+ buf << table_end
+ buf
end
def table_header(id, caption)
+ buf = ""
if get_chap.nil?
- puts %Q[#{I18n.t("table")}#{I18n.t("format_number_header_without_chapter", [@chapter.table(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}]
+ buf << %Q[#{I18n.t("table")}#{I18n.t("format_number_header_without_chapter", [@chapter.table(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}] << "\n"
else
- puts %Q[#{I18n.t("table")}#{I18n.t("format_number_header", [get_chap, @chapter.table(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}]
+ buf << %Q[#{I18n.t("table")}#{I18n.t("format_number_header", [get_chap, @chapter.table(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}] << "\n"
end
- blank
+ blank_reset
+ buf << blank
+ buf
end
def table_begin(ncols)
+ ""
end
def tr(rows)
- puts "|#{rows.join("|")}|"
+ "|#{rows.join("|")}|\n"
end
def table_border(ncols)
- puts (0..ncols).map{"|"}.join(":--")
+ blank_reset
+ (0..ncols).map{"|"}.join(":--") + "\n"
end
def th(str)
@@ -273,12 +329,17 @@ def td(str)
end
def table_end
- blank
+ buf = ""
+ buf << blank
+ buf
end
def footnote(id, str)
- puts "[^#{id}]: #{compile_inline(str)}"
- blank
+ buf = ""
+ buf << "[^#{id}]: #{compile_inline(str)}" << "\n"
+ blank_reset
+ buf << blank
+ buf
end
def inline_fn(id)
@@ -295,9 +356,9 @@ def nofunc_text(str)
def compile_ruby(base, ruby)
if @book.htmlversion == 5
- %Q[#{escape_html(base)}#{I18n.t("ruby_prefix")} #{escape_html(ruby)} #{I18n.t("ruby_postfix")} ]
+ %Q[#{base}#{I18n.t("ruby_prefix")} #{ruby} #{I18n.t("ruby_postfix")} ]
else
- %Q[#{escape_html(base)} #{I18n.t("ruby_prefix")} #{ruby} #{I18n.t("ruby_postfix")} ]
+ %Q[#{base} #{I18n.t("ruby_prefix")} #{ruby} #{I18n.t("ruby_postfix")} ]
end
end
diff --git a/lib/review/md2inaobuilder.rb b/lib/review/md2inaobuilder.rb
index 4dc290abf..6eec427fa 100644
--- a/lib/review/md2inaobuilder.rb
+++ b/lib/review/md2inaobuilder.rb
@@ -9,48 +9,54 @@ module ReVIEW
class MD2INAOBuilder < MARKDOWNBuilder
def paragraph(lines)
- puts " " + lines.join
- puts "\n"
+ ## XXX fix; do not use fullwidth space
+ buf = " " + lines.join << "\n"
+ blank_reset
+ buf << "\n"
+ buf
end
def list_header(id, caption, lang)
lang ||= ""
- puts "```#{lang}"
- print %Q[●リスト#{@chapter.list(id).number}::#{compile_inline(caption)}\n\n]
+ buf = "```#{lang}\n"
+ buf << %Q[●リスト#{@chapter.list(id).number}::#{compile_inline(caption)}\n\n]
+ buf
end
def cmd(lines)
# WEB+DB では使っていないらしいけど
- puts "!!! cmd"
+ buf = "!!! cmd\n"
lines.each do |line|
- puts detab(line)
+ buf << detab(line) + "\n"
end
- puts ""
+ buf << "\n"
+ buf
end
def dl_begin
- puts ''
+ "\n"
end
def dt(line)
- puts "#{line} "
+ "#{line} \n"
end
def dd(lines)
- puts "#{lines.join} "
+ "#{lines.join} \n"
end
def dl_end
- puts ' '
+ " \n"
end
def comment(lines, comment = nil)
lines ||= []
lines.unshift comment unless comment.blank?
str = lines.join("\n")
- puts ''
- puts str
- puts ' '
+ buf = '' + "\n"
+ buf << str + "\n"
+ buf << ' ' + "\n"
+ buf
end
def compile_ruby(base, ruby)
diff --git a/lib/review/node.rb b/lib/review/node.rb
new file mode 100644
index 000000000..2d9fe6dcd
--- /dev/null
+++ b/lib/review/node.rb
@@ -0,0 +1,288 @@
+require 'json'
+
+module ReVIEW
+ class Node
+ attr_accessor :content
+
+ def to_raw
+ to_s_by(:to_raw)
+ end
+
+ def to_doc
+ to_s_by(:to_doc)
+ end
+
+ def to_s_by(meth)
+ if content.kind_of? String
+ @content
+ elsif content.nil?
+ nil
+ elsif !content.kind_of? Array
+ @content.__send__(meth)
+ else
+ ##@content.map(&meth).join("")
+ @content.map{|o| o.__send__(meth)}.join("")
+ end
+ end
+
+ def to_json(*args)
+ if content.kind_of? String
+ val = '"'+@content.gsub(/\"/,'\\"').gsub(/\n/,'\\n')+'"'
+ elsif content.nil?
+ val = "null"
+ elsif !content.kind_of? Array
+ val = @content.to_json
+ else
+ val = "["+@content.map(&:to_json).join(",")+"]"
+ end
+ '{"ruleName":"' + self.class.to_s.sub(/ReVIEW::/,"").sub(/Node$/,"") + '",' +
+ "\"offset\":#{position.pos},\"line\":#{position.line},\"column\":#{position.col}," +
+ '"childNodes":' + val +
+ '}'
+ end
+
+ def inspect
+ self.to_json
+ end
+
+ end
+
+ class HeadlineNode < Node
+
+ def to_doc
+ content_str = super
+ cmd = @cmd ? @cmd.to_doc : nil
+ label = @label
+ @compiler.compile_headline(@level, cmd, label, content_str)
+ end
+
+ def to_json
+ '{"ruleName":"' + self.class.to_s.sub(/ReVIEW::/,"").sub(/Node$/,"") + '",' +
+ %Q|"cmd":"#{@cmd.to_json}",|+
+ %Q|"label":"#{@label.to_json}",|+
+ "\"offset\":#{position.pos},\"line\":#{position.line},\"column\":#{position.col}," +
+ '"childNodes":' + @content.to_json + '}'
+ end
+ end
+
+ class ParagraphNode < Node
+
+ def to_doc
+ #content = @content.map(&:to_doc)
+ content = super.split(/\n/)
+ @compiler.compile_paragraph(content)
+ end
+ end
+
+ class BlockElementNode < Node
+
+ def to_doc
+ # content_str = super
+ args = @args.map(&:to_doc)
+ if @content
+ content_lines = @content.map(&:to_doc)
+ else
+ content_lines = nil
+ end
+ @compiler.compile_command(@name, @args, content_lines, self)
+ end
+
+ def parse_args(*patterns)
+ patterns.map.with_index do |pattern, i|
+ if @args[i]
+ @args[i].__send__("to_#{pattern}")
+ else
+ nil
+ end
+ end
+ end
+ end
+
+ class CodeBlockElementNode < Node
+
+ def to_doc
+ # content_str = super
+ args = @args.map(&:to_doc)
+ if @content
+ content_lines = raw_lines
+ else
+ content_lines = nil
+ end
+ @compiler.compile_command(@name, @args, content_lines, self)
+ end
+
+ def parse_args(*patterns)
+ patterns.map.with_index do |pattern, i|
+ if @args[i]
+ @args[i].__send__("to_#{pattern}")
+ else
+ nil
+ end
+ end
+ end
+
+ def raw_lines
+ self.content.to_doc.split(/\n/)
+ end
+ end
+
+
+ class InlineElementNode < Node
+ def to_raw
+ content_str = super
+ "@<#{@symbol}>{#{content_str}}"
+ end
+
+ def to_doc
+ #content_str = super
+ @compiler.compile_inline(@symbol, @content)
+ end
+
+ def to_json
+ '{"ruleName":"' + self.class.to_s.sub(/ReVIEW::/,"").sub(/Node$/,"") + '",' +
+ %Q|"symbol":"#{@symbol}",| +
+ "\"offset\":#{position.pos},\"line\":#{position.line},\"column\":#{position.col}," +
+ (@concat ? '"childNodes":[' + @content.map(&:to_json).join(",") + ']' : '"childNodes":[]') + '}'
+ end
+ end
+
+ class ComplexInlineElementNode < Node
+ def to_raw
+ content_str = super
+ "@<#{@symbol}>{#{content_str}}"
+ end
+
+ def to_doc
+ #content_str = super
+ @compiler.compile_inline(@symbol, @content)
+ end
+
+ def to_json
+ '{"ruleName":"' + self.class.to_s.sub(/ReVIEW::/,"").sub(/Node$/,"") + '",' +
+ %Q|"symbol":"#{@symbol}",| +
+ "\"offset\":#{position.pos},\"line\":#{position.line},\"column\":#{position.col}," +
+ '"childNodes":[' + @content.map(&:to_json).join(",") + ']}'
+ end
+ end
+
+ class InlineElementContentNode < Node
+ end
+
+ class ComplexInlineElementContentNode < Node
+ end
+
+ class TextNode < Node
+
+ def to_raw
+ content_str = super
+ content_str.to_s
+ end
+
+ def to_doc
+ content_str = super
+ @compiler.compile_text(content_str)
+ end
+
+ def to_json(*args)
+ val = '"'+@content.gsub(/\"/,'\\"').gsub(/\n/,'\\n')+'"'
+ '{"ruleName":"' + self.class.to_s.sub(/ReVIEW::/,"").sub(/Node$/,"") + '",' +
+ "\"offset\":#{position.pos},\"line\":#{position.line},\"column\":#{position.col}," +
+ '"text":' + val + '}'
+ end
+ end
+
+ class NewLineNode < Node
+
+ def to_doc
+ ""
+ end
+ end
+
+ class RawNode < Node
+
+ def to_doc
+ @compiler.compile_raw(@builder, @content.join(""))
+ end
+ end
+
+ class BracketArgNode < Node
+ end
+
+ class BraceArgNode < Node
+ end
+
+ class SinglelineCommentNode < Node
+ def to_doc
+ ""
+ end
+ end
+
+ class SinglelineContentNode < Node
+ end
+
+ class UlistNode < Node
+ def to_doc
+ @compiler.compile_ulist(@content)
+ end
+ end
+
+ class UlistElementNode < Node
+ def level=(level)
+ @level = level
+ end
+
+ def to_doc
+ @content.map(&:to_doc).join("")
+ end
+
+ def concat(elem)
+ @content << elem
+ end
+ end
+
+ class OlistNode < Node
+ def to_doc
+ @compiler.compile_olist(@content)
+ end
+ end
+
+ class OlistElementNode < Node
+ def num=(num)
+ @num = num
+ end
+
+ def to_doc
+ @content.map(&:to_doc).join("")
+ end
+
+ def concat(elem)
+ @content << elem
+ end
+ end
+
+ class DlistNode < Node
+ def to_doc
+ @compiler.compile_dlist(@content)
+ end
+ end
+
+ class DlistElementNode < Node
+ def to_doc
+ @content.map(&:to_doc).join("")
+ end
+ end
+
+ class DocumentNode < Node
+ end
+
+ class ColumnNode < Node
+
+ def to_doc
+ level = @level
+ label = @label
+ caption = @caption ? @caption.to_doc : nil
+ @compiler.compile_column(level, label, caption, @content)
+ end
+ end
+
+end
diff --git a/lib/review/review.kpeg b/lib/review/review.kpeg
new file mode 100644
index 000000000..701825f01
--- /dev/null
+++ b/lib/review/review.kpeg
@@ -0,0 +1,756 @@
+%% name = ReVIEW::Compiler
+
+%% header {
+# coding: UTF-8
+
+}
+
+%% {
+ class Error; end
+ class Position
+ attr_accessor :pos, :line, :col
+ def initialize(compiler)
+ @pos = compiler.pos
+ @line = compiler.current_line
+ @col = compiler.current_column
+ end
+ end
+
+# rubocop:disable all
+require 'review/location'
+require 'review/extentions'
+require 'review/preprocessor'
+require 'review/exception'
+require 'review/node'
+ require 'lineinput'
+ # require 'review/compiler/literals_1_9'
+ # require 'review/compiler/literals_1_8'
+
+ ## redifine Compiler.new
+ def initialize(strategy)
+ @strategy = strategy
+ @current_column = nil
+ @chapter = nil
+ end
+
+ attr_accessor :strategy
+
+ def compile(chap)
+ @chapter = chap
+ do_compile
+ @strategy.result
+ end
+
+ def do_compile
+ @strategy.bind self, @chapter, ReVIEW::Location.new(@chapter.basename, self)
+ setup_parser(@chapter.content)
+ parse()
+ convert_ast
+ end
+
+ def convert_ast
+ ast = @strategy.ast
+ convert_column(ast)
+ if $DEBUG
+ File.open("review-dump.json","w") do |f|
+ f.write(ast.to_json)
+ end
+ end
+ @strategy.output << ast.to_doc
+ end
+
+ def flush_column(new_content)
+ if @current_column
+ new_content << @current_column
+ @current_column = nil
+ end
+ end
+
+ def convert_column(ast)
+ @column_stack = []
+ content = ast.content
+ new_content = []
+ @current_content = new_content
+ content.each do |elem|
+ if elem.kind_of?(ReVIEW::HeadlineNode) && elem.cmd && elem.cmd.to_doc == "column"
+ flush_column(new_content)
+ @current_content = []
+ @current_column = ReVIEW::ColumnNode.new(elem.compiler, elem.position, elem.level,
+ elem.label, elem.content, @current_content)
+ next
+ elsif elem.kind_of?(ReVIEW::HeadlineNode) && elem.cmd && elem.cmd.to_doc =~ %r|^/|
+ cmd_name = elem.cmd.to_doc[1..-1]
+ if cmd_name != "column"
+ raise ReVIEW::CompileError, "#{cmd_name} is not opened."
+ end
+ flush_column(new_content)
+ @current_content = new_content
+ next
+ elsif elem.kind_of?(ReVIEW::HeadlineNode) && @current_column && elem.level <= @current_column.level
+ flush_column(new_content)
+ @current_content = new_content
+ end
+ @current_content << elem
+ end
+ flush_column(new_content)
+ ast.content = new_content
+ ast
+ end
+
+ def compile_text(text)
+ @strategy.nofunc_text(text)
+ end
+
+ class SyntaxElement
+ def initialize(name, type, argc, esc, &block)
+ @name = name
+ @type = type
+ @argc_spec = argc
+ @esc_patterns = esc
+ @checker = block
+ end
+
+ attr_reader :name
+
+ def check_args(args)
+ unless @argc_spec === args.size
+ raise ReVIEW::CompileError, "wrong # of parameters (block command //#{@name}, expect #{@argc_spec} but #{args.size})"
+ end
+ @checker.call(*args) if @checker
+ end
+
+ def min_argc
+ case @argc_spec
+ when Range then @argc_spec.begin
+ when Integer then @argc_spec
+ else
+ raise TypeError, "argc_spec is not Range/Integer: #{inspect()}"
+ end
+ end
+
+ def parse_args(args)
+ if @esc_patterns
+ args.map.with_index do |pattern, i|
+ if @esc_patterns[i]
+ args[i].__send__("to_#{@esc_patterns[i]}")
+ else
+ args[i].to_doc
+ end
+ end
+ else
+ args.map(&:to_doc)
+ end
+ end
+
+ def block_required?
+ @type == :block or @type == :code_block
+ end
+
+ def block_allowed?
+ @type == :block or @type == :code_block or @type == :optional or @type == :optional_code_block
+ end
+
+ def code_block?
+ @type == :code_block or @type == :optional_code_block
+ end
+ end
+
+ SYNTAX = {}
+
+ def self.defblock(name, argc, optional = false, esc = nil, &block)
+ defsyntax(name, (optional ? :optional : :block), argc, esc, &block)
+ end
+
+ def self.defcodeblock(name, argc, optional = false, esc = nil, &block)
+ defsyntax(name, (optional ? :optional_code_block : :code_block), argc, esc, &block)
+ end
+
+ def self.defsingle(name, argc, esc = nil, &block)
+ defsyntax name, :line, argc, esc, &block
+ end
+
+ def self.defsyntax(name, type, argc, esc = nil, &block)
+ SYNTAX[name] = SyntaxElement.new(name, type, argc, esc, &block)
+ end
+
+ def syntax_defined?(name)
+ SYNTAX.key?(name.to_sym)
+ end
+
+ def syntax_descriptor(name)
+ SYNTAX[name.to_sym]
+ end
+
+ class InlineSyntaxElement
+ def initialize(name)
+ @name = name
+ end
+
+ attr_reader :name
+ end
+
+ INLINE = {}
+ COMPLEX_INLINE = {}
+
+ def self.definline(name)
+ INLINE[name] = InlineSyntaxElement.new(name)
+ end
+
+ def self.defcomplexinline(name)
+ COMPLEX_INLINE[name] = InlineSyntaxElement.new(name)
+ end
+
+ def inline_defined?(name)
+ INLINE.key?(name.to_sym) || COMPLEX_INLINE.key?(name.to_sym)
+ end
+
+ defblock :read, 0
+ defblock :lead, 0
+ defblock :quote, 0
+ defblock :bibpaper, 2..3, true, [:raw, :doc, :doc]
+ defblock :doorquote, 1, false, [:doc]
+ defblock :talk, 0
+ defblock :graph, 1..3, false, [:raw, :raw, :doc]
+
+ defcodeblock :emlist, 0..2, false, [:doc, :raw]
+ defcodeblock :cmd, 0..1, false, [:doc]
+ defcodeblock :source, 0..2, false, [:doc, :raw]
+ defcodeblock :list, 2..4, false, [:raw, :doc, :raw, :raw]
+ defcodeblock :listnum, 2..3, false, [:raw, :doc, :raw]
+ defcodeblock :emlistnum, 0..2, false, [:doc, :raw]
+ defcodeblock :texequation, 0, false
+ defcodeblock :table, 0..2, false, [:raw, :doc]
+ defcodeblock :imgtable, 0..2, false, [:raw, :doc]
+ defcodeblock :image, 2..3, true, [:raw,:doc,:raw]
+ defcodeblock :box, 0..1, false, [:doc]
+
+ defblock :address, 0
+ defblock :blockquote, 0
+ defblock :bpo, 0
+ defblock :flushright, 0
+ defblock :centering, 0
+ defblock :note, 0..1
+ defblock :memo, 0..1
+ defblock :info, 0..1
+ defblock :important, 0..1
+ defblock :caution, 0..1
+ defblock :notice, 0..1
+ defblock :warning, 0..1
+ defblock :tip, 0..1
+ defblock :comment, 0..1, true
+
+ defsingle :footnote, 2, [:raw, :doc]
+ defsingle :noindent, 0
+ defsingle :linebreak, 0
+ defsingle :pagebreak, 0
+ defsingle :indepimage, 1..3, [:raw, :doc, :raw]
+ defsingle :numberlessimage, 1..3, [:raw, :doc, :raw]
+ defsingle :hr, 0
+ defsingle :parasep, 0
+ defsingle :label, 1, [:raw]
+ defsingle :raw, 1, [:raw]
+ defsingle :tsize, 1, [:raw]
+ defsingle :include, 1, [:raw]
+ defsingle :olnum, 1, [:raw]
+
+ definline :chapref
+ definline :chap
+ definline :title
+ definline :img
+ definline :imgref
+ definline :icon
+ definline :list
+ definline :table
+ definline :fn
+ definline :bou
+ definline :ami
+ definline :b
+ definline :dtp
+ definline :code
+ definline :bib
+ definline :hd
+ definline :recipe
+ definline :column
+ definline :tcy
+
+ definline :abbr
+ definline :acronym
+ definline :cite
+ definline :dfn
+ definline :em
+ definline :kbd
+ definline :q
+ definline :samp
+ definline :strong
+ definline :var
+ definline :big
+ definline :small
+ definline :del
+ definline :ins
+ definline :sup
+ definline :sub
+ definline :tt
+ definline :i
+ definline :tti
+ definline :ttb
+ definline :u
+ definline :raw
+ definline :br
+ definline :m
+ definline :uchar
+ definline :idx
+ definline :hidx
+ definline :comment
+ definline :include
+ definline :tcy
+
+ defcomplexinline :kw
+ defcomplexinline :ruby
+ defcomplexinline :href
+
+ def compile_column(level, label, caption, content)
+ buf = ""
+ buf << @strategy.__send__("column_begin", level, label, caption)
+ buf << content.to_doc
+ buf << @strategy.__send__("column_end", level)
+ buf
+ end
+
+ def compile_command(name, args, lines, node)
+ syntax = syntax_descriptor(name)
+ if !syntax || (!@strategy.respond_to?(syntax.name) && !@strategy.respond_to?("node_#{syntax.name}"))
+ error "strategy does not support command: //#{name}"
+ compile_unknown_command args, lines
+ return
+ end
+ begin
+ syntax.check_args args
+ rescue ReVIEW::CompileError => err
+ error err.message
+ args = ['(NoArgument)'] * syntax.min_argc
+ end
+ if syntax.block_allowed?
+ compile_block(syntax, args, lines, node)
+ else
+ if lines
+ error "block is not allowed for command //#{syntax.name}; ignore"
+ end
+ compile_single(syntax, args, node)
+ end
+ end
+
+ def compile_headline(level, tag, label, caption)
+ buf = ""
+ @headline_indexs ||= [0] ## XXX
+ caption ||= ""
+ caption.strip!
+ index = level - 1
+ if @headline_indexs.size > (index + 1)
+ @headline_indexs = @headline_indexs[0..index]
+ end
+ @headline_indexs[index] = 0 if @headline_indexs[index].nil?
+ @headline_indexs[index] += 1
+ buf << @strategy.headline(level, label, caption)
+ buf
+ end
+
+ def comment(text)
+ @strategy.comment(text)
+ end
+
+ def compile_ulist(content)
+ buf0 = ""
+ level = 0
+ content.each do |element|
+ current_level = element.level
+ buf = element.to_doc
+ if level == current_level
+ buf0 << @strategy.ul_item_end
+ # body
+ buf0 << @strategy.ul_item_begin([buf])
+ elsif level < current_level # down
+ level_diff = current_level - level
+ level = current_level
+ (1..(level_diff - 1)).to_a.reverse_each do |i|
+ buf0 << @strategy.ul_begin{i}
+ buf0 << @strategy.ul_item_begin([])
+ end
+ buf0 << @strategy.ul_begin{level}
+ buf0 << @strategy.ul_item_begin([buf])
+ elsif level > current_level # up
+ level_diff = level - current_level
+ level = current_level
+ (1..level_diff).to_a.reverse_each do |i|
+ buf0 << @strategy.ul_item_end
+ buf0 << @strategy.ul_end{level + i}
+ end
+ buf0 << @strategy.ul_item_end
+ # body
+ buf0 <<@strategy.ul_item_begin([buf])
+ end
+ end
+
+ (1..level).to_a.reverse_each do |i|
+ buf0 << @strategy.ul_item_end
+ buf0 << @strategy.ul_end{i}
+ end
+ buf0
+ end
+
+ def compile_olist(content)
+ buf0 = ""
+ buf0 << @strategy.ol_begin
+ content.each do |element|
+ ## XXX 1st arg should be String, not Array
+ buf0 << @strategy.ol_item(element.to_doc.split(/\n/), element.num)
+ end
+ buf0 << @strategy.ol_end
+ buf0
+ end
+
+ def compile_dlist(content)
+ buf = ""
+ buf << @strategy.dl_begin
+ content.each do |element|
+ buf << @strategy.dt(element.text.to_doc)
+ buf << @strategy.dd(element.content.map{|s| s.to_doc})
+ end
+ buf << @strategy.dl_end
+ buf
+ end
+
+
+ def compile_unknown_command(args, lines)
+ @strategy.unknown_command(args, lines)
+ end
+
+ def compile_block(syntax, args, lines, node)
+ node_name = "node_#{syntax.name}".to_sym
+ if @strategy.respond_to?(node_name)
+ @strategy.__send__(node_name, node)
+ else
+ args_conv = syntax.parse_args(args)
+ @strategy.__send__(syntax.name, (lines || default_block(syntax)), *args_conv)
+ end
+ end
+
+ def default_block(syntax)
+ if syntax.block_required?
+ error "block is required for //#{syntax.name}; use empty block"
+ end
+ []
+ end
+
+ def compile_single(syntax, args, node)
+ node_name = "node_#{syntax.name}".to_sym
+ if @strategy.respond_to?(node_name)
+ @strategy.__send__(node_name, node)
+ else
+ args_conv = syntax.parse_args(args)
+ @strategy.__send__(syntax.name, *args_conv)
+ end
+ end
+
+
+ def compile_inline(op, args)
+ unless inline_defined?(op)
+ raise ReVIEW::CompileError, "no such inline op: #{op}"
+ end
+ if @strategy.respond_to?("node_inline_#{op}")
+ return @strategy.__send__("node_inline_#{op}", args)
+ end
+ unless @strategy.respond_to?("inline_#{op}")
+ raise "strategy does not support inline op: @<#{op}>"
+ end
+ if !args
+ @strategy.__send__("inline_#{op}", "")
+ else
+ @strategy.__send__("inline_#{op}", *(args.map(&:to_doc)))
+ end
+# rescue => err
+# error err.message
+ end
+
+ def compile_paragraph(buf)
+ @strategy.paragraph buf
+ end
+
+ def compile_raw(builders, content)
+ c = @strategy.class.to_s.gsub(/ReVIEW::/, '').gsub(/Builder/, '').downcase
+ if !builders || builders.include?(c)
+ content.gsub("\\n", "\n")
+ else
+ ""
+ end
+ end
+
+ def warn(msg)
+ @strategy.warn msg
+ end
+
+ def error(msg)
+ @strategy.error msg
+ end
+
+ def check_indent(s)
+ s.size >= @list_stack.last.size
+ end
+
+ def check_nested_indent(s)
+ s.size >= @list_stack.last.size + 2
+ end
+
+ def check_inline_element_symbol(name)
+ INLINE.key?(name.to_sym)
+ end
+
+ def check_complex_inline_element_symbol(name)
+ COMPLEX_INLINE.key?(name.to_sym)
+ end
+
+ def position
+ Position.new(self)
+ end
+
+
+}
+
+%% ast-location = ::ReVIEW
+%% headline = ast HeadlineNode(compiler, position, level, cmd, label, content)
+%% paragraph = ast ParagraphNode(compiler, position, content)
+%% block_element = ast BlockElementNode(compiler, position, name, args, content)
+%% code_block_element = ast CodeBlockElementNode(compiler, position, name, args, content)
+%% inline_element = ast InlineElementNode(compiler, position, symbol, content)
+%% inline_element_content = ast InlineElementContentNode(compiler, position, content)
+%% complex_inline_element = ast ComplexInlineElementNode(compiler, position, symbol, content)
+%% complex_inline_element_content = ast ComplexInlineElementContentNode(compiler, position, content)
+%% text = ast TextNode(compiler, position, content)
+%% raw = ast RawNode(compiler, builder, position, content)
+%% brace = ast BraceNode(compiler, position, content)
+%% singleline_content = ast SinglelineContentNode(compiler, position, content)
+%% singleline_comment = ast SinglelineCommentNode(compiler, position, content)
+%% ulist = ast UlistNode(compiler, position, content)
+%% ulist_element = ast UlistElementNode(compiler, position, level, content)
+%% olist = ast OlistNode(compiler, position, content)
+%% olist_element = ast OlistElementNode(compiler, position, num, content)
+%% dlist = ast DlistNode(compiler, position, content)
+%% dlist_element = ast DlistElementNode(compiler, position, text, content)
+%% bracket_arg = ast BracketArgNode(compiler, position, content)
+%% document = ast DocumentNode(compiler, position, content)
+%% column = ast ColumnNode(compiler, position, level, label, caption, content)
+%% newline = ast NewLineNode(compiler, position, content)
+
+# %% dummy
+
+root = Start
+
+Start = &. { @list_stack = Array.new } Document:c { @strategy.ast = c }
+
+## a Document is a set of Blocks
+Document = BOM? Block*:c ~document(self, position, c)
+
+## ignore leading blank lines
+Block = BlankLine*:c { c }
+ ( SinglelineComment:c
+ | Headline:c
+ | BlockElement:c
+ | Ulist:c
+ | Olist:c
+ | Dlist:c
+ | Paragraph:c
+ ) { c }
+
+BlankLine = Newline
+
+SinglelineComment = ("#@" < NonNewline+ > EOL) ~singleline_comment(self, position, text)
+
+Headline = HeadlinePrefix:level BracketArg?:cmd BraceArg?:label Space* SinglelineContent?:caption EOL ~headline(self, position, level, cmd, label, caption)
+
+HeadlinePrefix = < /={1,5}/ > { text.length }
+
+Paragraph = ParagraphLine+:c ~paragraph(self, position, c.flatten)
+
+ParagraphLine = !Headline !SinglelineComment !BlockElement !Ulist !Olist !Dlist SinglelineContent:c Newline { c }
+
+# There are 3 types of Block Element: raw Block, Code Block, and Normal Block
+BlockElement = ( "//raw[" RawBlockBuilderSelect?:b RawBlockElementArg*:r1 "]" Space* EOL
+ ~raw(self, b, position, r1)
+ | !"//raw" "//" ElementName:symbol &{ syntax = syntax_descriptor(symbol); syntax && syntax.code_block? } BracketArg*:args "{" Space* Newline CodeBlockElementContents:contents "//}" Space* EOL
+ ~code_block_element(self, position, symbol, args, contents)
+ | !"//raw" "//" ElementName:symbol BracketArg*:args "{" Space* Newline BlockElementContents:contents "//}" Space* EOL
+ ~block_element(self, position, symbol, args, contents)
+ | !"//raw" "//" ElementName:symbol BracketArg*:args Space* EOL ~block_element(self, position, symbol, args, nil)
+ )
+
+RawBlockBuilderSelect = "|" Space* RawBlockBuilderSelectSub:c Space* "|" { c }
+
+RawBlockBuilderSelectSub = ( < AlphanumericAscii+ >:c1 Space* "," Space* RawBlockBuilderSelectSub:c2
+ { [text] + c2 }
+ | < AlphanumericAscii+ >:c1
+ { [text] }
+ )
+
+RawBlockElementArg = !"]" ( "\\]" { "]" }
+ | "\\n" { "\n" }
+ | < NonNewline > { text }
+ )
+
+BracketArg = "[" BracketArgInline*:content "]" ~bracket_arg(self, position, content)
+
+## XXX '\' (excpet '\]' and '\\' ) => '\' is ???
+BracketArgInline = ( InlineElement:c { c }
+ | "\\]" ~text(self, position, "]")
+ | "\\\\" ~text(self, position, "\\")
+ | < /[^\r\n\]]/ > ~text(self, position, text)
+ )
+
+BraceArg = "{" < /([^\r\n}\\]|\\[^\r\n])*/ > "}" { text }
+
+## Standard BlockElement has nested blocks. Texts in content of block are parsed as Paragraph.
+BlockElementContents = BlockElementContent*:c { c }
+
+### Headline is prohibited.
+### Note: do not allow "//}" at front of Paragraph.
+BlockElementContent = ( SinglelineComment:c { c }
+ | BlockElement:c { c }
+ | Ulist:c
+ | Dlist:c
+ | Olist:c
+ | BlankLine:c { c }
+ | BlockElementParagraph:c { c }
+ )
+
+## it's like Paragraph, but it's in a block, so do not allow '//}\n'
+BlockElementParagraph = BlockElementParagraphLine+:c ~paragraph(self, position, c.flatten)
+BlockElementParagraphLine = !"//}" !BlankLine !SinglelineComment !BlockElement !Ulist !Olist !Dlist SinglelineContent:c Newline { c }
+
+## In CodeBlockElementContents, newline should no be ingored. So we use TextNode instead of NewLineNode.
+CodeBlockElementContents = CodeBlockElementContent+:c { c }
+CodeBlockElementContent = ( SinglelineComment:c { c }
+ | BlankLine:c { ::ReVIEW::TextNode.new(self, position, "\n") }
+ | !"//}" SinglelineContent:c Newline { [c, ::ReVIEW::TextNode.new(self, position, "\n")] }
+ )
+
+## Ulist and Olist
+
+Bullet = "*"
+Enumerator = < /[0-9]+/ > { num = text } "." { num.to_i }
+
+Ulist = Indent+:s Bullet+:b Space+ { @list_stack.push(s) } UlistItemBlock:item
+ { if b.size > 1 then item.level = b.size end }
+ (UlistItem | UlistItemMore | NestedList)*:items &{ s == @list_stack.pop }
+ ~ulist(self, position, items.unshift(item))
+
+Olist = Indent+:s Enumerator:e Space+ { @list_stack.push(s) } OlistItemBlock:item
+ { item.num = e }
+ (OlistItem | NestedList)*:items &{ s == @list_stack.pop }
+ ~olist(self, position, items.unshift(item))
+
+UlistItemBlock = ListItemFirstLine:c ListItemLine*:d ~ulist_element(self, position, @list_stack.size, d.unshift(c))
+OlistItemBlock = ListItemFirstLine:c ListItemLine*:d ~olist_element(self, position, 0, d.unshift(c))
+
+ListItemFirstLine = SinglelineContent:c Newline { c }
+ListItemLine = Indent+:s !Bullet !Enumerator !Space SinglelineContent:c &{ check_indent(s) } Newline { c }
+
+UlistItemMore = Indent+:s Bullet Bullet+:b Space+ &{ check_indent(s) } UlistItemBlock:item { item.level = b.size+1; item }
+
+UlistItem = Indent+:s Bullet Space+ &{ check_indent(s) } UlistItemBlock:item { item }
+OlistItem = Indent+:s Enumerator:e Space+ &{ check_indent(s) } OlistItemBlock:item { item.num = e; item }
+
+## NestedList is markdown-like indented syntax.
+## You can write nested Ulist and Olist with this syntax.
+
+NestedList = (NestedUlist | NestedOlist)
+
+NestedUlist = Indent+:s Bullet Space+ &{ check_nested_indent(s) } { @list_stack.push(s) } UlistItemBlock:item
+ (UlistItem | NestedList)*:items &{ s == @list_stack.pop }
+ ~ulist(self, position, items.unshift(item))
+NestedOlist = Indent+:s Enumerator:e Space+ &{ check_nested_indent(s) } { @list_stack.push(s) } OlistItemBlock:item
+ { item.num = e }
+ (OlistItem | NestedList)*:items &{ s == @list_stack.pop }
+ ~olist(self, position, items.unshift(item))
+
+# Dlist
+Dlist = (DlistElement | SinglelineComment)+:content ~dlist(self, position, content)
+
+DlistElement = Indent* ":" Space+ SinglelineContent:text Newline DlistElementContent+:content ~dlist_element(self, position, text, content)
+
+DlistElementContent = (SinglelineComment:c { c }
+ |Space+ SinglelineContent:c Newline { c }
+ )
+
+SinglelineContent = Inline+:c ~singleline_content(self, position, c)
+
+
+# Inline Element and Non Inline Element
+
+Inline = ( InlineElement | NonInlineElement)
+
+NonInlineElement = !InlineElement < NonNewline > ~text(self, position, text)
+
+InlineElement = ( RawInlineElement:c { c }
+ | !RawInlineElement "@<" InlineElementSymbol:symbol ">" "{" InlineElementContents?:contents "}" ~inline_element(self, position, symbol,contents)
+ | !RawInlineElement "@<" ComplexInlineElementSymbol:symbol ">" "{" ComplexInlineElementContents?:contents "}" ~complex_inline_element(self, position, symbol,contents)
+ )
+
+RawInlineElement = "@{" RawBlockBuilderSelect?:builders RawInlineElementContent+:c "}" ~raw(self, builders, position, c)
+
+RawInlineElementContent = ( "\\}" { "}" }
+ | < /[^\r\n\}]/ > { text }
+ )
+
+InlineElementSymbol = < AlphanumericAscii+ >:s &{ check_inline_element_symbol(text) } { text }
+
+InlineElementContents = !"}" InlineElementContentsSub:c { c }
+
+InlineElementContentsSub = !"}" Space* InlineElementContent:c1 Space* { [c1] }
+
+ComplexInlineElementSymbol = < AlphanumericAscii+ > &{ check_complex_inline_element_symbol(text) } { text }
+
+ComplexInlineElementContents = !"}" ComplexInlineElementContentsSub:c { c }
+
+ComplexInlineElementContentsSub = !"}" ( Space* InlineElementContent:c1 Space* "," ComplexInlineElementContentsSub:c2 { [c1]+c2 }
+ | Space* InlineElementContent:c1 Space* { [c1] }
+ )
+
+
+InlineElementContent = InlineElementContentSub+:d { d }
+
+InlineElementContentSub = ( InlineElement:c { c }
+ | !InlineElement QuotedInlineText:content ~inline_element_content(self, position, content)
+ | !InlineElement InlineElementContentText+:content ~inline_element_content(self, position, content)
+ )
+
+## Quoted Inline Text is "..."
+## In Quoted Inline Text, "\\" is "\", "\'" is "'", other characters are kept as is.
+QuotedInlineText = "\""
+ ( "\\\"" { "\"" }
+ | "\\\\" { "\\" }
+ | < /[^"\r\n\\]/ > { text }
+ )+:str "\"" ~text(self, position, str.join(""))
+
+## XXX '\' (excpet '\}' and '\,' and '\\' ) => '\' is OK?
+InlineElementContentText = ( "\\}" ~text(self, position, "}")
+ | "\\," ~text(self, position, ",")
+ | "\\\\" ~text(self, position, "\\" )
+ | "\\" ~text(self, position, "\\" )
+ | !InlineElement < /[^\r\n\\},]/> ~text(self, position, text)
+ )
+
+NonNewline = /[^\r\n]/
+
+Space = /[ \t]/
+
+Indent = " "
+
+EOL = (Newline|EOF)
+
+EOF = !.
+
+ElementName = < LowerAlphabetAscii+ > { text }
+
+AlphanumericAscii = /[A-Za-z0-9]/
+LowerAlphabetAscii = /[a-z]/
+Digit = /[0-9]/
+BOM = "\uFEFF"
+Newline = /\n|\r\n?|\p{Zl}|\p{Zp}/ ~newline(self, position, "\n")
diff --git a/lib/review/textutils.rb b/lib/review/textutils.rb
index 056902b69..e621d614c 100644
--- a/lib/review/textutils.rb
+++ b/lib/review/textutils.rb
@@ -12,27 +12,5 @@ def detab(str, ts = 8)
' ' * len
}
end
-
- def split_paragraph(lines)
- pre = pre_paragraph
- post = post_paragraph
-
- blocked_lines = [[]]
- lines.each {|element|
- if element == ""
- if blocked_lines.last != []
- blocked_lines << []
- end
- else
- blocked_lines.last << element
- end
- }
-
- if !pre.nil? and !post.nil?
- blocked_lines.map!{|i| [pre] + i + [post] }
- end
-
- blocked_lines.map{|l| l.join("")}
- end
end
end
diff --git a/lib/review/tocparser.rb b/lib/review/tocparser.rb
index 40421b88a..685533f36 100644
--- a/lib/review/tocparser.rb
+++ b/lib/review/tocparser.rb
@@ -108,9 +108,12 @@ def compile_label(line)
b = ReVIEW::TEXTBuilder.new
dummy_book = ReVIEW::Book::Base.load
dummy_chapter = ReVIEW::Book::Chapter.new(dummy_book, 1, '-', nil, StringIO.new)
- dummy_loc = Location.new("", StringIO.new)
- b.bind(ReVIEW::Compiler.new(b), dummy_chapter, dummy_loc)
- b.compile_inline(line)
+ c = ReVIEW::Compiler.new(b)
+ dummy_loc = Location.new("", c)
+ b.bind(c, dummy_chapter, dummy_loc)
+ c.setup_parser(line)
+ c.parse("Paragraph")
+ c.result.to_doc
end
def error!(filename, lineno, msg)
diff --git a/lib/review/topbuilder.rb b/lib/review/topbuilder.rb
index 7e66dd778..12ca99531 100644
--- a/lib/review/topbuilder.rb
+++ b/lib/review/topbuilder.rb
@@ -22,7 +22,10 @@ class TOPBuilder < Builder
}
Compiler.defsingle(:dtp, 1)
- Compiler.defblock(:insn, 1)
+ Compiler.defcodeblock(:insn, 1)
+ Compiler.defblock(:memo, 0..1)
+ Compiler.defblock(:tip, 0..1)
+ Compiler.defblock(:info, 0..1)
Compiler.defblock(:planning, 0..1)
Compiler.defblock(:best, 0..1)
Compiler.defblock(:securty, 0..1)
@@ -51,7 +54,6 @@ def builder_init_file
@subsection = 0
@subsubsection = 0
@subsubsubsection = 0
- @blank_seen = true
@titles = {
"emlist" => "インラインリスト",
@@ -99,28 +101,6 @@ def builder_init_file
end
private :builder_init_file
- def print(s)
- @blank_seen = false
- super
- end
- private :print
-
- def puts(s)
- @blank_seen = false
- super
- end
- private :puts
-
- def blank
- @output.puts unless @blank_seen
- @blank_seen = true
- end
- private :blank
-
- def result
- @output.string
- end
-
def warn(msg)
$stderr.puts "#{@location.filename}:#{@location.lineno}: warning: #{msg}"
end
@@ -134,8 +114,8 @@ def messages
end
def headline(level, label, caption)
+ buf = ""
prefix = ""
- blank
case level
when 1
if @chapter.number.to_s =~ /\A\d+\Z/
@@ -169,62 +149,67 @@ def headline(level, label, caption)
raise "caption level too deep or unsupported: #{level}"
end
prefix = "" if (level.to_i > @book.config["secnolevel"])
- puts "■H#{level}■#{prefix}#{compile_inline(caption)}"
+ buf << "■H#{level}■#{prefix}#{caption}\n"
+ buf
end
def ul_begin
- blank
+ "\n"
end
def ul_item(lines)
- puts "●\t#{lines.join}"
+ "●\t#{lines.join}\n"
end
def ul_end
- blank
+ "\n"
end
def ol_begin
- blank
@olitem = 0
+ "\n"
end
def ol_item(lines, num)
- puts "#{num}\t#{lines.join}"
+ "#{num}\t#{lines.join}\n"
end
def ol_end
- blank
@olitem = nil
+ "\n"
end
def dl_begin
- blank
+ "\n"
end
def dt(line)
- puts "★#{line}☆"
+ "★#{line}☆\n"
end
def dd(lines)
- split_paragraph(lines).each do |paragraph|
- puts "\t#{paragraph.gsub(/\n/, '')}"
+ buf = ""
+ lines.each do |paragraph|
+ buf << "\t#{paragraph.gsub(/\n/, '')}\n"
end
+ buf
end
def dl_end
- blank
+ "\n"
end
def paragraph(lines)
- puts lines.join
+ lines.join+"\n"
end
def read(lines)
- puts "◆→開始:#{@titles["lead"]}←◆"
- puts split_paragraph(lines).join("\n")
- puts "◆→終了:#{@titles["lead"]}←◆"
- blank
+ buf = ""
+ buf << "◆→開始:#{@titles["lead"]}←◆\n"
+ buf << lines.join("\n") << "\n"
+ buf << "◆→終了:#{@titles["lead"]}←◆\n"
+ buf << "\n"
+ buf
end
alias_method :lead, :read
@@ -236,44 +221,50 @@ def inline_list(id)
else
%Q[#{I18n.t("list")}#{I18n.t("format_number", [get_chap(chapter), @chapter.list(id).number])}]
end
-
end
def list_header(id, caption, lang)
- blank
- puts "◆→開始:#{@titles["list"]}←◆"
+ buf = ""
+ #buf << "\n"
+ buf << "◆→開始:#{@titles["list"]}←◆\n"
if get_chap.nil?
- puts %Q[#{I18n.t("list")}#{I18n.t("format_number_without_chapter", [@chapter.list(id).number])}#{I18n.t("caption_prefix_idgxml")}#{compile_inline(caption)}]
+ buf << %Q[#{I18n.t("list")}#{I18n.t("format_number_without_chapter", [@chapter.list(id).number])}#{I18n.t("caption_prefix_idgxml")}#{caption}] << "\n"
else
- puts %Q[#{I18n.t("list")}#{I18n.t("format_number", [get_chap, @chapter.list(id).number])}#{I18n.t("caption_prefix_idgxml")}#{compile_inline(caption)}]
+ buf << %Q[#{I18n.t("list")}#{I18n.t("format_number", [get_chap, @chapter.list(id).number])}#{I18n.t("caption_prefix_idgxml")}#{caption}] << "\n"
end
- blank
+ buf << "\n"
+ buf
end
def list_body(id, lines, lang)
+ buf = ""
lines.each do |line|
- puts detab(line)
+ buf << detab(line) << "\n"
end
- puts "◆→終了:#{@titles["list"]}←◆"
- blank
+ buf << "◆→終了:#{@titles["list"]}←◆\n"
+ buf << "\n"
+ buf
end
def base_block(type, lines, caption = nil)
- blank
- puts "◆→開始:#{@titles[type]}←◆"
- puts "■#{compile_inline(caption)}" unless caption.nil?
- puts lines.join("\n")
- puts "◆→終了:#{@titles[type]}←◆"
- blank
+ buf = ""
+ buf << "\n"
+ buf << "◆→開始:#{@titles[type]}←◆\n"
+ buf << "■#{caption}\n" unless caption.nil?
+ buf << lines.join("")
+ buf << "◆→終了:#{@titles[type]}←◆\n"
+ buf << "\n"
+ buf
end
def base_parablock(type, lines, caption = nil)
- blank
- puts "◆→開始:#{@titles[type]}←◆"
- puts "■#{compile_inline(caption)}" unless caption.nil?
- puts split_paragraph(lines).join("\n")
- puts "◆→終了:#{@titles[type]}←◆"
- blank
+ buf = ""
+ buf << "◆→開始:#{@titles[type]}←◆\n"
+ buf << "■#{caption}\n" unless caption.nil?
+ buf << lines.join("")
+ buf << "◆→終了:#{@titles[type]}←◆\n"
+ buf << "\n"
+ buf
end
def emlist(lines, caption = nil, lang = nil)
@@ -281,23 +272,26 @@ def emlist(lines, caption = nil, lang = nil)
end
def emlistnum(lines, caption = nil, lang = nil)
- blank
- puts "◆→開始:#{@titles["emlist"]}←◆"
- puts "■#{compile_inline(caption)}" unless caption.nil?
+ buf = ""
+ buf << "◆→開始:#{@titles["emlist"]}←◆\n"
+ buf << "■#{caption}\n" unless caption.nil?
_lines = []
lines.each_with_index do |line, i|
- puts (i + 1).to_s.rjust(2) + ": #{line}"
+ buf << (i + 1).to_s.rjust(2) + ": #{line}\n"
end
- puts "◆→終了:#{@titles["emlist"]}←◆"
- blank
+ buf << "◆→終了:#{@titles["emlist"]}←◆\n"
+ buf << "\n"
+ buf
end
def listnum_body(lines, lang)
+ buf = ""
lines.each_with_index do |line, i|
- puts (i + 1).to_s.rjust(2) + ": #{line}"
+ buf << (i + 1).to_s.rjust(2) + ": #{line}\n"
end
- puts "◆→終了:#{@titles["list"]}←◆"
- blank
+ buf << "◆→終了:#{@titles["list"]}←◆\n"
+ buf << "\n"
+ buf
end
def cmd(lines, caption = nil)
@@ -327,48 +321,57 @@ def inline_img(id)
end
def image(lines, id, caption, metric=nil)
- blank
- puts "◆→開始:#{@titles["image"]}←◆"
+ buf = ""
+ #buf << "\n"
+ buf << "◆→開始:#{@titles["image"]}←◆\n"
if get_chap.nil?
- puts "#{I18n.t("image")}#{I18n.t("format_number_without_chapter", [@chapter.image(id).number])}#{I18n.t("caption_prefix_idgxml")}#{compile_inline(caption)}"
+ buf << "#{I18n.t("image")}#{I18n.t("format_number_without_chapter", [@chapter.image(id).number])}#{I18n.t("caption_prefix_idgxml")}#{caption}\n"
else
- puts "#{I18n.t("image")}#{I18n.t("format_number", [get_chap, @chapter.image(id).number])}#{I18n.t("caption_prefix_idgxml")}#{compile_inline(caption)}"
+ buf << "#{I18n.t("image")}#{I18n.t("format_number", [get_chap, @chapter.image(id).number])}#{I18n.t("caption_prefix_idgxml")}#{caption}\n"
end
- blank
+ buf << "\n"
if @chapter.image(id).bound?
- puts "◆→#{@chapter.image(id).path}←◆"
+ buf << "◆→#{@chapter.image(id).path}←◆\n"
else
lines.each do |line|
- puts line
+ buf << line << "\n"
end
end
- puts "◆→終了:#{@titles["image"]}←◆"
- blank
+ buf << "◆→終了:#{@titles["image"]}←◆\n"
+ buf << "\n"
+ buf
end
def texequation(lines)
- puts "◆→開始:#{@titles["texequation"]}←◆"
- puts "#{lines.join("\n")}"
- puts "◆→終了:#{@titles["texequation"]}←◆"
- blank
+ buf = ""
+ buf << "◆→開始:#{@titles["texequation"]}←◆\n"
+ buf << "#{lines.join("\n")}\n"
+ buf << "◆→終了:#{@titles["texequation"]}←◆\n"
+ buf << "\n"
+ buf
end
def table_header(id, caption)
- blank
- puts "◆→開始:#{@titles["table"]}←◆"
+ buf = ""
+ buf << "\n"
+ buf << "◆→開始:#{@titles["table"]}←◆\n"
if get_chap.nil?
- puts "#{I18n.t("table")}#{I18n.t("format_number_without_chapter", [@chapter.table(id).number])}#{I18n.t("caption_prefix_idgxml")}#{compile_inline(caption)}"
+ buf << "#{I18n.t("table")}#{I18n.t("format_number_without_chapter", [@chapter.table(id).number])}#{I18n.t("caption_prefix_idgxml")}#{caption}\n"
else
- puts "#{I18n.t("table")}#{I18n.t("format_number", [get_chap, @chapter.table(id).number])}#{I18n.t("caption_prefix_idgxml")}#{compile_inline(caption)}"
+ buf << "#{I18n.t("table")}#{I18n.t("format_number", [get_chap, @chapter.table(id).number])}#{I18n.t("caption_prefix_idgxml")}#{caption}\n"
end
- blank
+ buf << "\n"
+ buf
end
def table_begin(ncols)
+ ""
end
def tr(rows)
- puts rows.join("\t")
+ buf = ""
+ buf << rows.join("\t") << "\n"
+ buf
end
def th(str)
@@ -380,19 +383,21 @@ def td(str)
end
def table_end
- puts "◆→終了:#{@titles["table"]}←◆"
- blank
+ buf = ""
+ buf << "◆→終了:#{@titles["table"]}←◆\n"
+ buf << "\n"
+ buf
end
def comment(lines, comment = nil)
lines ||= []
lines.unshift comment unless comment.blank?
str = lines.join("")
- puts "◆→DTP連絡:#{str}←◆"
+ "◆→DTP連絡:#{str}←◆\n"
end
def footnote(id, str)
- puts "【注#{@chapter.footnote(id).number}】#{compile_inline(str)}"
+ "【注#{@chapter.footnote(id).number}】#{str}\n"
end
def inline_fn(id)
@@ -526,25 +531,28 @@ def inline_hd_chap(chap, id)
end
def noindent
- puts "◆→DTP連絡:次の1行インデントなし←◆"
+ "◆→DTP連絡:次の1行インデントなし←◆\n"
end
def nonum_begin(level, label, caption)
- puts "■H#{level}■#{compile_inline(caption)}"
+ "■H#{level}■#{caption}\n"
end
def nonum_end(level)
end
def common_column_begin(type, caption)
- blank
- puts "◆→開始:#{@titles[type]}←◆"
- puts %Q[■#{compile_inline(caption)}]
+ buf = ""
+ buf << "◆→開始:#{@titles[type]}←◆\n"
+ buf << %Q[■#{caption}\n]
+ buf
end
def common_column_end(type)
- puts %Q[◆→終了:#{@titles[type]}←◆]
- blank
+ buf = ""
+ buf << %Q[◆→終了:#{@titles[type]}←◆\n]
+ buf << "\n"
+ buf
end
def column_begin(level, label, caption)
@@ -698,15 +706,17 @@ def warning(lines, caption = nil)
alias_method :box, :insn
def indepimage(id, caption=nil, metric=nil)
- blank
+ buf = ""
+ buf << "\n"
begin
- puts "◆→画像 #{@chapter.image(id).path.sub(/\A\.\//, "")} #{metric.join(" ")}←◆"
+ buf << "◆→画像 #{@chapter.image(id).path.sub(/\A\.\//, "")} #{metric.join(" ")}←◆\n"
rescue
warn "no such image: #{id}"
- puts "◆→画像 #{id}←◆"
+ buf << "◆→画像 #{id}←◆\n"
end
- puts "図 #{compile_inline(caption)}" if caption.present?
- blank
+ buf << "図 #{caption}\n" if caption.present?
+ buf << "\n"
+ buf
end
alias_method :numberlessimage, :indepimage
@@ -793,7 +803,7 @@ def inline_pageref(idref)
end
def circle_begin(level, label, caption)
- puts "・\t#{caption}"
+ "・\t#{caption}\n"
end
def circle_end(level)
diff --git a/lib/review/version.rb b/lib/review/version.rb
index 0d8b8d473..72a8651f7 100644
--- a/lib/review/version.rb
+++ b/lib/review/version.rb
@@ -1,3 +1,3 @@
module ReVIEW
- VERSION = "2.1.0"
+ VERSION = "0.3.0"
end
diff --git a/review.gemspec b/review.gemspec
index 5b03e182c..e9146c6aa 100644
--- a/review.gemspec
+++ b/review.gemspec
@@ -3,17 +3,17 @@ $:.push File.expand_path("../lib", __FILE__)
require "review/version"
Gem::Specification.new do |gem|
- gem.name = "review"
+ gem.name = "review-peg"
gem.version = ReVIEW::VERSION
gem.platform = Gem::Platform::RUBY
gem.license = "LGPL"
gem.authors = ["kmuto", "takahashim"]
gem.email = "kmuto@debian.org"
gem.homepage = "http://github.com/kmuto/review"
- gem.summary = "Re:VIEW: a easy-to-use digital publishing system"
- gem.description = "Re:VIEW is a digital publishing system for books and ebooks. It supports InDesign, EPUB and LaTeX."
+ gem.summary = "Re:VIEW peg: a easy-to-use digital publishing system (PEG version)"
+ gem.description = "Re:VIEW is a digital publishing system for books and ebooks. It supports InDesign, EPUB and LaTeX. This gem is experimental version with PEG grammar"
gem.required_rubygems_version = Gem::Requirement.new(">= 0") if gem.respond_to? :required_rubygems_version=
- gem.date = "2016-04-29"
+ gem.date = "2016-11-10"
gem.files = `git ls-files`.split("\n")
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -26,6 +26,7 @@ Gem::Specification.new do |gem|
gem.add_dependency("rubyzip")
gem.add_development_dependency("rake")
gem.add_development_dependency("test-unit")
+ gem.add_development_dependency("kpeg")
gem.add_development_dependency("pygments.rb")
gem.add_development_dependency("rubocop")
end
diff --git a/test/sample-book/src/Rakefile b/test/sample-book/src/Rakefile
index 14af6d1b1..778349e4a 100644
--- a/test/sample-book/src/Rakefile
+++ b/test/sample-book/src/Rakefile
@@ -5,17 +5,18 @@ BOOK = "book"
BOOK_PDF = BOOK+".pdf"
BOOK_EPUB = BOOK+".epub"
CONFIG_FILE = "config.yml"
+REVIEW_COMPILE = "review-compile-peg"
WEBROOT = "webroot"
def build(mode, chapter)
- sh "review-compile --target=#{mode} --footnotetext --stylesheet=style.css #{chapter} > tmp"
+ sh "#{REVIEW_COMPILE} --target=#{mode} --footnotetext --stylesheet=style.css #{chapter} > tmp"
mode_ext = {"html" => "html", "latex" => "tex",
"idgxml" => "xml"}
FileUtils.mv "tmp", chapter.gsub(/re\z/, mode_ext[mode])
end
def build_all(mode)
- sh "review-compile --target=#{mode} --footnotetext --stylesheet=style.css"
+ sh "#{REVIEW_COMPILE} --target=#{mode} --footnotetext --stylesheet=style.css"
end
task :default => :html_all
diff --git a/test/test_builder.rb b/test/test_builder.rb
index 13d29b87e..56a6b5d1e 100644
--- a/test/test_builder.rb
+++ b/test/test_builder.rb
@@ -44,16 +44,6 @@ def test_result
assert_equal '', b.result
end
- def test_print_and_puts
- b = Builder.new
- assert_raises(NoMethodError) do # XXX: OK?
- b.print ""
- end
- assert_raises(NoMethodError) do # XXX: OK?
- b.puts ""
- end
- end
-
def test_not_implemented_methods
ex = NoMethodError # XXX: OK?
[
@@ -70,26 +60,6 @@ def test_not_implemented_methods
end
end
- def test_compile_inline
- text = "abc"
- assert_equal [:text, text], @b.compile_inline(text)
- end
-
- def test_inline_ruby
- def @b.compile_ruby(base,ruby)
- [base,ruby]
- end
- str = @b.inline_ruby("foo,bar")
- assert_equal str, ["foo","bar"]
- str = @b.inline_ruby("foo\\,\\,,\\,bar,buz")
- assert_equal str, ["foo,,",",bar,buz"]
- end
-
- def test_compile_inline_backslash
- text = "abc\\d\\#a"
- assert_equal [:text, text], @b.compile_inline(text)
- end
-
class XBuilder < Builder
def list_header(id, caption)
end
diff --git a/test/test_catalog_converter_cmd.rb b/test/test_catalog_converter_cmd.rb
index ab240ad7d..ed65f91e7 100644
--- a/test/test_catalog_converter_cmd.rb
+++ b/test/test_catalog_converter_cmd.rb
@@ -4,7 +4,7 @@
require 'yaml'
require 'rbconfig'
-load File.expand_path('../bin/review-catalog-converter', File.dirname(__FILE__))
+load File.expand_path('../bin/review-catalog-converter-peg', File.dirname(__FILE__))
class CatalogConverterCmdTest < Test::Unit::TestCase
def test_parse_chaps
diff --git a/test/test_compiler.rb b/test/test_compiler.rb
index fd18b907c..7c84409f3 100644
--- a/test/test_compiler.rb
+++ b/test/test_compiler.rb
@@ -4,43 +4,90 @@
require 'review/compiler'
require 'review/book'
require 'review/latexbuilder'
+require 'review/htmlbuilder'
class CompilerTest < Test::Unit::TestCase
include ReVIEW
def setup
- @builder = LATEXBuilder.new()
- @c = Compiler.new(@builder)
+ @builder = HTMLBuilder.new()
+ @param = {
+ "secnolevel" => 2, # for IDGXMLBuilder, HTMLBuilder
+ "inencoding" => "UTF-8",
+ "outencoding" => "UTF-8",
+ "subdirmode" => nil,
+ "stylesheet" => nil, # for HTMLBuilder
+ }
+ @book = Book::Base.new(nil)
+ @book.config = @param
+ @compiler = ReVIEW::Compiler.new(@builder)
+ @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new)
+ location = Location.new(nil, nil)
+ @builder.bind(@compiler, @chapter, location)
+
+ def @compiler.compile_command(name, args, lines, node)
+ args
+ end
+
end
def test_parse_args
- args = @c.__send__(:parse_args, "[foo][bar]")
- assert_equal ["foo","bar"], args
+ args = compile_blockelem("//dummy[foo][bar]\n", false)
+ assert_equal ["foo","bar"], args.parse_args(:doc,:doc)
end
def test_parse_args_with_brace1
- args = @c.__send__(:parse_args, "[fo[\\][\\]o][bar]")
- assert_equal ["fo[][]o","bar"], args
+ args = compile_blockelem("//dummy[fo[\\][\\]o][bar]", false)
+ assert_equal ["fo[][]o","bar"], args.parse_args(:doc, :doc)
end
def test_parse_args_with_brace2
- args = @c.__send__(:parse_args, "[f\\]o\\]o][bar]")
- assert_equal ["f]o]o","bar"], args
+ args = compile_blockelem("//dummy[f\\]o\\]o][bar]", false)
+ assert_equal ["f]o]o","bar"], args.parse_args(:doc, :doc)
end
def test_parse_args_with_backslash
- args = @c.__send__(:parse_args, "[foo][bar\\buz]")
- assert_equal ["foo","bar\\buz"], args
+ args = compile_blockelem("//dummy[foo][bar\\buz]", false)
+ assert_equal ["foo","bar\\buz"], args.parse_args(:doc, :doc)
end
def test_parse_args_with_backslash2
- args = @c.__send__(:parse_args, "[foo][bar\\#\\[\\!]")
- assert_equal ["foo","bar\\#\\[\\!"], args
+ args = compile_blockelem("//dummy[foo][bar\\#\\[\\!]", false)
+ assert_equal ["foo","bar\\#\\[\\!"], args.parse_args(:doc, :doc)
end
def test_parse_args_with_backslash3
- args = @c.__send__(:parse_args, "[foo][bar\\\\buz]")
- assert_equal ["foo","bar\\buz"], args
+ args = compile_blockelem("//dummy[foo][bar\\\\buz]", false)
+ assert_equal ["foo","bar\\buz"], args.parse_args(:doc, :doc)
+ end
+
+ def test_compile_inline
+ def @compiler.inline_ruby(*args)
+ return args
+ end
+ args = compile_inline("@{abc}",false)
+ assert_equal "abc", args.content[0].content.to_doc
+ end
+
+ def test_inline_ruby
+# def @compiler.inline_ruby(*args)
+# return args
+# end
+ args = compile_inline("@{foo,bar}",false)
+ assert_equal "foo", args.content[0].content[0].to_doc
+ assert_equal "bar", args.content[0].content[1].to_doc
+ args = compile_inline("@{foo\\,\\,,\\,bar\\,buz}", false)
+ assert_equal "foo,,", args.content[0].content[0].to_doc
+ assert_equal ",bar,buz", args.content[0].content[1].to_doc
+ end
+
+ def test_compile_inline_backslash
+ def @compiler.inline_dummy(*args)
+ return args
+ end
+ Compiler.definline :dummy
+ args = compile_inline("@{abc\\d\\#a}", false)
+ assert_equal "abc\\d\\#a", args.content[0].content.to_doc
end
end
diff --git a/test/test_epubmaker_cmd.rb b/test/test_epubmaker_cmd.rb
index 32388f484..3e76d117c 100644
--- a/test/test_epubmaker_cmd.rb
+++ b/test/test_epubmaker_cmd.rb
@@ -6,7 +6,7 @@
require 'yaml'
require 'rbconfig'
-REVIEW_EPUBMAKER = File.expand_path('../bin/review-epubmaker', File.dirname(__FILE__))
+REVIEW_EPUBMAKER = File.expand_path('../bin/review-epubmaker-peg', File.dirname(__FILE__))
class EPUBMakerCmdTest < Test::Unit::TestCase
def setup
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 25b1ad82d..7feaa645f 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -1,6 +1,43 @@
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib/')
require 'test/unit'
+ def compile_document(str, force_to_s=true)
+ @compiler.setup_parser(str)
+ @compiler.parse("Document")
+ if force_to_s
+ @compiler.result.to_doc
+ else
+ @compiler.result
+ end
+ end
+
+ def compile_inline(str, force_to_s=true)
+ @compiler.setup_parser(str)
+ @compiler.parse("Paragraph")
+ if force_to_s
+## @compiler.result.map(&:to_doc).join
+ @compiler.result.to_doc
+ else
+ @compiler.result
+ end
+ end
+
+ def compile_blockelem(str, force_to_s=true)
+ @compiler.setup_parser(str)
+ @compiler.parse("BlockElement")
+ if force_to_s
+ @compiler.result.to_doc
+ else
+ @compiler.result
+ end
+ end
+
+ def compile_headline(str)
+ @compiler.setup_parser(str)
+ @compiler.parse("Headline")
+ @compiler.result.to_doc
+ end
+
def touch_file(path)
File.open(path, "w").close
path
@@ -16,10 +53,6 @@ def prepare_samplebook(srcdir)
YAML.load(File.open(srcdir + "/config.yml"))
end
-def compile_inline(text)
- @builder.compile_inline(text)
-end
-
def compile_block(text)
method_name = "compile_block_#{@builder.target_name}"
if !self.respond_to?(method_name, true)
diff --git a/test/test_htmlbuilder.rb b/test/test_htmlbuilder.rb
index 869bf19c8..d159a4bc6 100644
--- a/test/test_htmlbuilder.rb
+++ b/test/test_htmlbuilder.rb
@@ -55,7 +55,7 @@ def on_APPENDIX?
end
end
actual = compile_block("=={test} this is test.\n")
- assert_equal %Q|\nA.1 this is test. \n|, actual
+ assert_equal %Q|A.1 this is test. \n|, actual
end
def test_headline_postdef_roman
@@ -70,12 +70,8 @@ def on_APPENDIX?
end
end
- actual = compile_block("={test} this is test.\n")
- assert_equal %Q|付録I this is test. \n|, actual
-
actual = compile_block("=={test} this is test.\n")
- assert_equal %Q|\nI.1 this is test. \n|, actual
-
+ assert_equal %Q|I.1 this is test. \n|, actual
end
end
end
@@ -96,7 +92,7 @@ def on_APPENDIX?
assert_equal %Q|付録A this is test. \n|, actual
actual = compile_block("=={test} this is test.\n")
- assert_equal %Q|\nA.1 this is test. \n|, actual
+ assert_equal %Q|A.1 this is test. \n|, actual
end
end
end
@@ -119,18 +115,18 @@ def test_headline_level1_with_inlinetag
def test_headline_level2
actual = compile_block("=={test} this is test.\n")
- assert_equal %Q|\n1.1 this is test. \n|, actual
+ assert_equal %Q|1.1 this is test. \n|, actual
end
def test_headline_level3
actual = compile_block("==={test} this is test.\n")
- assert_equal %Q|\n this is test. \n|, actual
+ assert_equal %Q| this is test. \n|, actual
end
def test_headline_level3_with_secno
@book.config["secnolevel"] = 3
actual = compile_block("==={test} this is test.\n")
- assert_equal %Q|\n1.0.1 this is test. \n|, actual
+ assert_equal %Q|1.0.1 this is test. \n|, actual
end
def test_label
@@ -357,7 +353,7 @@ def @chapter.image(id)
def test_quote
actual = compile_block("//quote{\nfoo\nbar\n\nbuz\n//}\n")
- assert_equal %Q|foobar
\nbuz
\n|, actual
+ assert_equal %Q|foobar
\nbuz
\n \n|, actual
end
def test_memo
@@ -518,7 +514,7 @@ def @chapter.list(id)
@book.config["highlight"]["html"] = "pygments"
actual = compile_block("//list[samplelist][this is @{test}<&>_]{\ntest1\ntest1.5\n\ntest@{2}\n//}\n")
- assert_equal %Q|\n
リスト1.1: this is test <&>_
\n
test1\ntest1.5\n\ntest<i>2</i>\n \n
\n|, actual
+ assert_equal %Q|\n
リスト1.1: this is test <&>_
\n
test1\ntest1.5\n\ntest<i>2</i> \n
\n|, actual
end
def test_list_pygments_lang
@@ -539,7 +535,7 @@ def @chapter.list(id)
%Q|def foo (a1, a2= :test )\n| +
%Q| (1. .3 ). times{\| i\| a. include?(:foo )}\n| +
%Q| return true \n| +
- %Q|end \n| +
+ %Q|end | +
%Q| \n| +
%Q|
\n|, actual
end
@@ -558,7 +554,7 @@ def @chapter.list(id)
@book.config["highlight"]["html"] = "pygments"
actual = compile_block("//list[samplelist][this is @
{test}<&>_][]{\ndef foo(a1, a2=:test)\n (1..3).times{|i| a.include?(:foo)}\n return true\nend\n\n//}\n")
- assert_equal "\n
リスト1.1: this is test <&>_
\n
def foo(a1, a2=:test)\n (1..3).times{|i| a.include?(:foo)}\n return true\nend\n \n
\n", actual
+ assert_equal "\n
リスト1.1: this is test <&>_
\n
def foo(a1, a2=:test)\n (1..3).times{|i| a.include?(:foo)}\n return true\nend \n
\n", actual
end
def test_list_ext
@@ -595,7 +591,7 @@ def foo(a1, a2=:test)
EOS
- assert_equal expected, actual
+ assert_equal expected.chomp, actual
end
def test_listnum_pygments_lang
@@ -612,7 +608,7 @@ def @chapter.list(id)
@book.config["highlight"]["html"] = "pygments"
actual = compile_block("//listnum[samplelist][this is @{test}<&>_][ruby]{\ndef foo(a1, a2=:test)\n (1..3).times{|i| a.include?(:foo)}\n return true\nend\n\n//}\n")
- assert_equal "\n
リスト1.1: this is test <&>_
\n
1 def foo (a1, a2= :test )\n2 (1. .3 ). times{| i| a. include?(:foo )}\n3 return true \n4 end \n\n
\n", actual
+ assert_equal "\n
リスト1.1: this is test <&>_
\n
1 def foo (a1, a2= :test )\n2 (1. .3 ). times{| i| a. include?(:foo )}\n3 return true \n4 end \n ", actual
end
def test_listnum_pygments_lang_without_lang
@@ -630,7 +626,7 @@ def @chapter.list(id)
@book.config["highlight"]["lang"] = "ruby"
actual = compile_block("//listnum[samplelist][this is @{test}<&>_]{\ndef foo(a1, a2=:test)\n (1..3).times{|i| a.include?(:foo)}\n return true\nend\n\n//}\n")
- assert_equal "\n
リスト1.1: this is test <&>_
\n
1 def foo (a1, a2= :test )\n2 (1. .3 ). times{| i| a. include?(:foo )}\n3 return true \n4 end \n\n
\n", actual
+ assert_equal "\n
リスト1.1: this is test <&>_
\n
1 def foo (a1, a2= :test )\n2 (1. .3 ). times{| i| a. include?(:foo )}\n3 return true \n4 end \n ", actual
end
@@ -649,7 +645,7 @@ def test_emlist_pygments_lang
@book.config["highlight"] = {}
@book.config["highlight"]["html"] = "pygments"
actual = compile_block("//emlist[][sql]{\nSELECT COUNT(*) FROM tests WHERE tests.no > 10 AND test.name LIKE 'ABC%'\n//}\n")
- assert_equal "\n
SELECT COUNT (* ) FROM tests WHERE tests.no > 10 AND test.name LIKE 'ABC%' \n\n
\n", actual
+ assert_equal "\n
SELECT COUNT (* ) FROM tests WHERE tests.no > 10 AND test.name LIKE 'ABC%' \n
\n", actual
end
def test_emlist_caption
@@ -709,7 +705,7 @@ def test_cmd_pygments
@book.config["highlight"] = {}
@book.config["highlight"]["html"] = "pygments"
actual = compile_block("//cmd{\nlineA\nlineB\n//}\n")
- assert_equal "\n", actual
+ assert_equal "\n", actual
end
def test_cmd_caption
@@ -748,7 +744,7 @@ def @chapter.bibpaper(id)
end
actual = compile_block("//bibpaper[samplebib][sample bib @{bold}]{\na\nb\n//}\n")
- assert_equal %Q|\n
[1] sample bib
bold \n
ab
\n|, actual
+ assert_equal %Q|\n
[1] sample bib
bold \n
ab
\n
\n|, actual
end
def test_bibpaper_normalized
@@ -757,7 +753,7 @@ def @chapter.bibpaper(id)
end
actual = compile_block("//bibpaper[sample=bib][sample bib @{bold}]{\na\nb\n//}\n")
- assert_equal %Q|\n
[1] sample bib
bold \n
ab
\n|, actual
+ assert_equal %Q|\n
[1] sample bib
bold \n
ab
\n
\n|, actual
end
def test_bibpaper_with_anchor
@@ -766,7 +762,7 @@ def @chapter.bibpaper(id)
end
actual = compile_block("//bibpaper[samplebib][sample bib @{http://example.jp}]{\na\nb\n//}\n")
- assert_equal %Q|\n|, actual
+ assert_equal %Q|\n|, actual
end
def column_helper(review)
@@ -814,7 +810,6 @@ def test_column_2
test
inside column
-
next level
EOS
@@ -850,7 +845,6 @@ def test_column_ref
test
inside column
-
next level
this is コラム「test」.
EOS
@@ -1017,6 +1011,70 @@ def test_ul_nest5
assert_equal expected, actual
end
+ def test_ul_in_note
+ src =<<-EOS
+//note{
+
+aaaa
+bbb
+
+ * A
+ * B
+//}
+EOS
+
+ expected =<<-EOS
+
+EOS
+ actual = compile_block(src)
+ assert_equal expected, actual
+ end
+
+ def test_ul_in_note_and_emlist
+ src =<<-EOS
+//note{
+
+aaaa
+bbb
+
+//emlist{
+abc
+ddd
+ * A
+ * B
+//}
+
+ * A
+ * B
+//}
+EOS
+
+ expected =<<-EOS
+
+
aaaabbb
+
+
abc
+ddd
+ * A
+ * B
+
+
+
+
+EOS
+ actual = compile_block(src)
+ assert_equal expected, actual
+ end
+
def test_ol
src =<<-EOS
3. AAA
@@ -1107,6 +1165,24 @@ def test_inline_fn_with_tricky_id
assert_equal expected, actual
end
+
+ ## inline nesting tests
+ def test_href_nest
+ actual = compile_inline("@{http://github.com,@{G}itHub}")
+ assert_equal %Q|G itHub |, actual
+ end
+
+ def test_inline_tti_nest
+ actual = compile_inline("test @{aa@{inline test}bb} test2")
+ assert_equal %Q|test aainline test bb
test2|, actual
+ end
+
+ def test_inline_ttib_nest
+ actual = compile_inline("test @{aa@{inline @{te}st}bb} test2")
+ assert_equal %Q|test aainline te st bb
test2|, actual
+ end
+
+
def test_inline_hd
book = ReVIEW::Book::Base.load
book.catalog = ReVIEW::Catalog.new({"CHAPS"=>%w(ch1.re ch2.re)})
@@ -1118,7 +1194,9 @@ def test_inline_hd
builder = ReVIEW::HTMLBuilder.new
comp = ReVIEW::Compiler.new(builder)
builder.bind(comp, chap2, nil)
- hd = builder.inline_hd("ch1|test1-1")
+ comp.setup_parser("@{ch1|test1-1}")
+ comp.parse("Paragraph")
+ hd = comp.result.to_doc
assert_equal "「1.1 test1-1」", hd
end
@@ -1134,7 +1212,9 @@ def test_inline_hd_for_part
builder = ReVIEW::HTMLBuilder.new
comp = ReVIEW::Compiler.new(builder)
builder.bind(comp, chap2, nil)
- hd = builder.inline_hd("part1|part1-1")
+ comp.setup_parser("@{part1|part1-1}")
+ comp.parse("Paragraph")
+ hd = comp.result.to_doc
assert_equal "「1.1 part1-1」", hd
end
diff --git a/test/test_idgxmlbuilder.rb b/test/test_idgxmlbuilder.rb
index f2a3f0587..b65ee863b 100644
--- a/test/test_idgxmlbuilder.rb
+++ b/test/test_idgxmlbuilder.rb
@@ -1,8 +1,8 @@
# encoding: utf-8
require 'test_helper'
-require 'review/compiler'
require 'review/book'
+require 'review/compiler'
require 'review/idgxmlbuilder'
require 'review/i18n'
@@ -189,6 +189,18 @@ def test_quote
assert_equal %Q|foobar
buz
|, actual
end
+ ## XXX block content should be escaped.
+ def test_note
+ actual = compile_block("//note[this is @{test}<&>_]{\ntest1\ntest1.5\n\ntest@{2}\n//}\n")
+ assert_equal %Q|this is test <&>_ test1test1.5
test2
|, actual
+ end
+
+ ## XXX block content should be escaped.
+ def test_memo
+ actual = compile_block("//memo[this is @{test}<&>_]{\ntest1\ntest1.5\n\ntest@{2}\n//}\n")
+ assert_equal %Q|this is test <&>_ test1test1.5
test2
|, actual
+ end
+
def test_major_blocks
actual = compile_block("//note{\nA\n\nB\n//}\n//note[caption]{\nA\n//}")
expected = %Q(A
B
caption A
)
@@ -631,5 +643,4 @@ def test_block_raw4
expected = %Q(|idgxml <>!\"\n& )
assert_equal expected.chomp, actual
end
-
end
diff --git a/test/test_latexbuilder.rb b/test/test_latexbuilder.rb
index cea5adbb6..b5435c322 100644
--- a/test/test_latexbuilder.rb
+++ b/test/test_latexbuilder.rb
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
require 'test_helper'
-require 'review/compiler'
require 'review/book'
+require 'review/compiler'
require 'review/latexbuilder'
require 'review/i18n'
@@ -288,7 +288,7 @@ def test_emlistnum_caption
def test_list
actual = compile_block("//list[id1][cap1]{\nfoo\nbar\n\nbuz\n//}\n")
- assert_equal %Q|\\reviewlistcaption{リスト1.1: cap1}\n\\begin{reviewlist}\nfoo\nbar\n\nbuz\n\\end{reviewlist}\n|, actual
+ assert_equal %Q|\n\\reviewlistcaption{リスト1.1: cap1}\n\\begin{reviewlist}\nfoo\nbar\n\nbuz\n\\end{reviewlist}\n|, actual
end
def test_list_lst
@@ -308,7 +308,7 @@ def test_list_lst_with_lang
def test_listnum
actual = compile_block("//listnum[test1][ruby]{\nclass Foo\n def foo\n bar\n\n buz\n end\nend\n//}\n")
- assert_equal %Q|\\reviewlistcaption{リスト1.1: ruby}\n\\begin{reviewlist}\n 1: class Foo\n 2: def foo\n 3: bar\n 4: \n 5: buz\n 6: end\n 7: end\n\\end{reviewlist}\n|, actual
+ assert_equal %Q|\n\\reviewlistcaption{リスト1.1: ruby}\n\\begin{reviewlist}\n 1: class Foo\n 2: def foo\n 3: bar\n 4: \n 5: buz\n 6: end\n 7: end\n\\end{reviewlist}\n|, actual
end
def test_listnum_lst
@@ -340,7 +340,7 @@ def test_centering
def test_noindent
actual = compile_block("//noindent\nfoo\nbar\n\nfoo2\nbar2\n")
- assert_equal %Q|\\noindent\nfoo\nbar\n\nfoo2\nbar2\n|, actual
+ assert_equal %Q|\\noindent\nfoobar\n\nfoo2bar2\n|, actual
end
def test_image
@@ -411,6 +411,17 @@ def @chapter.image(id)
assert_equal %Q|\\begin{reviewimage}\n\\includegraphics[width=\\maxwidth]{./images/chap1-sampleimg.png}\n\\reviewindepimagecaption{図: sample photo}\n\\end{reviewimage}\n|, actual
end
+ def test_indepimage_esc
+ def @chapter.image(id)
+ item = Book::ImageIndex::Item.new("sampleimg",1)
+ item.instance_eval{@path="./images/chap1-sampleimg.png"}
+ item
+ end
+
+ actual = compile_block("//indepimage[sean_2_10][sample photo][]\n")
+ assert_equal %Q|\\begin{reviewimage}\n\\includegraphics[width=\\maxwidth]{./images/chap1-sampleimg.png}\n\\reviewindepimagecaption{図: sample photo}\n\\end{reviewimage}\n|, actual
+ end
+
def test_indepimage_without_caption
def @chapter.image(id)
item = Book::ImageIndex::Item.new("sampleimg",1)
@@ -544,7 +555,6 @@ def test_column_1
\\addcontentsline{toc}{subsection}{prev column}
inside prev column
-
\\end{reviewcolumn}
\\begin{reviewcolumn}
@@ -553,7 +563,6 @@ def test_column_1
\\addcontentsline{toc}{subsection}{test}
inside column
-
\\end{reviewcolumn}
EOS
@config["toclevel"] = 3
@@ -575,9 +584,7 @@ def test_column_2
\\reviewcolumnhead{}{test}
inside column
-
\\end{reviewcolumn}
-
\\subsection*{next level}
\\label{sec:1-0-1}
EOS
@@ -663,7 +670,6 @@ def test_ul_nest1
\\begin{itemize}
\\item AA
\\end{itemize}
-
\\end{itemize}
EOS
actual = compile_block(src)
@@ -686,13 +692,11 @@ def test_ul_nest3
\\begin{itemize}
\\item AA
\\end{itemize}
-
\\item BBB
\\begin{itemize}
\\item BB
\\end{itemize}
-
\\end{itemize}
EOS
actual = compile_block(src)
diff --git a/test/test_lineinput.rb b/test/test_lineinput.rb
index f8c209e5d..08167ce48 100644
--- a/test/test_lineinput.rb
+++ b/test/test_lineinput.rb
@@ -57,6 +57,7 @@ def test_ungets
assert_equal(-1, li.lineno) # XXX: OK?
end
+=begin
def test_peek
li = LineInput.new(StringIO.new)
assert_equal nil, li.peek
@@ -99,7 +100,7 @@ def test_gets_unless
assert_equal "abc\n", li.gets_unless(/^X/)
assert_equal nil, li.gets_unless(/^d/)
end
-
+=end
def test_each
content = "abc\ndef\nghi"
io = StringIO.new(content)
@@ -118,7 +119,7 @@ def test_while_match
assert_equal 2, li.lineno
assert_equal "ghi", li.gets
end
-
+=begin
def test_getlines_while
io = StringIO.new("abc\ndef\nghi")
li = LineInput.new(io)
@@ -128,7 +129,7 @@ def test_getlines_while
assert_equal 2, li.lineno
assert_equal "ghi", li.gets
end
-
+=end
def test_until_match
io = StringIO.new("abc\ndef\nghi")
li = LineInput.new(io)
@@ -137,7 +138,7 @@ def test_until_match
assert_equal 1, li.lineno
assert_equal "def\n", li.gets
end
-
+=begin
def test_getlines_until
io = StringIO.new("abc\ndef\nghi")
li = LineInput.new(io)
@@ -176,5 +177,6 @@ def test_until_terminator2
assert_equal ["abc\n", "def\n"], data
assert_equal 3, li.lineno
end
+=end
end
diff --git a/test/test_location.rb b/test/test_location.rb
index 6cd5911b4..0fcdcdf88 100644
--- a/test/test_location.rb
+++ b/test/test_location.rb
@@ -1,26 +1,30 @@
require 'test_helper'
+require 'review/location'
+require 'review/book'
+require 'review/textbuilder'
require 'review/compiler'
class LocationTest < Test::Unit::TestCase
def setup
+ @builder = ReVIEW::TEXTBuilder.new
+ dummy_book = ReVIEW::Book::Base.load
+ dummy_chapter = ReVIEW::Book::Chapter.new(dummy_book, 1, '-', nil, StringIO.new("a\nb\nc\n"))
+ @compiler = ReVIEW::Compiler.new(@builder)
+ @location = ReVIEW::Location.new("foo", @compiler)
+ @builder.bind(@compiler, dummy_chapter, @location)
+ @compiler.setup_parser(dummy_chapter.content)
end
def test_lineno
- f = StringIO.new("a\nb\nc\n")
- location = ReVIEW::Location.new("foo", f)
- assert_equal 0, location.lineno
- f.gets
- assert_equal 1, location.lineno
+ assert_equal 1, @location.lineno
end
def test_string
- location = ReVIEW::Location.new("foo", StringIO.new("a\nb\nc\n"))
- assert_equal "foo:0", location.string
+ assert_equal "foo:1", @location.string
end
def test_to_s
- location = ReVIEW::Location.new("foo", StringIO.new("a\nb\nc\n"))
- assert_equal "foo:0", "#{location}"
+ assert_equal "foo:1", "#{@location}"
end
def test_to_s_nil
diff --git a/test/test_markdownbuilder.rb b/test/test_markdownbuilder.rb
index ba06a2ebc..03d95718b 100644
--- a/test/test_markdownbuilder.rb
+++ b/test/test_markdownbuilder.rb
@@ -1,8 +1,8 @@
# encoding: utf-8
require 'test_helper'
-require 'review/compiler'
require 'review/book'
+require 'review/compiler'
require 'review/markdownbuilder'
require 'review/i18n'
@@ -10,6 +10,7 @@ class MARKDOWNBuilderTest < Test::Unit::TestCase
include ReVIEW
def setup
+ ReVIEW::I18n.setup
@builder = MARKDOWNBuilder.new()
@config = {
"secnolevel" => 2, # for IDGXMLBuilder, HTMLBuilder
@@ -140,9 +141,9 @@ def test_table
assert_equal "|testA|testB|\n|:--|:--|\n|contentA|contentB|\n\n", actual
end
- def test_ruby
- actual = compile_block("@{謳,うた}い文句")
- assert_equal "謳 ( うた ) い文句\n\n", actual
+ def test_inline_ruby
+ actual = compile_inline("@{謳,うた}い文句")
+ assert_equal "謳 ( うた ) い文句", actual
end
end
diff --git a/test/test_md2inaobuilder.rb b/test/test_md2inaobuilder.rb
index 1ee2b3cf5..1f72a292f 100644
--- a/test/test_md2inaobuilder.rb
+++ b/test/test_md2inaobuilder.rb
@@ -1,8 +1,8 @@
# encoding: utf-8
require 'test_helper'
-require 'review/compiler'
require 'review/book'
+require 'review/compiler'
require 'review/md2inaobuilder'
require 'review/i18n'
@@ -10,6 +10,7 @@ class MD2INAOBuilderTest < Test::Unit::TestCase
include ReVIEW
def setup
+ ReVIEW::I18n.setup
@builder = MD2INAOBuilder.new()
@config = {
"secnolevel" => 2, # for IDGXMLBuilder, HTMLBuilder
@@ -25,7 +26,7 @@ def setup
end
def test_paragraph
- actual = compile_block("Hello, world!")
+ actual = compile_block("Hello, world!\n")
assert_equal " Hello, world!\n\n", actual
end
@@ -59,16 +60,16 @@ def test_list
def test_comment
actual = compile_block("//comment{\nHello, world!\n//}\n")
- assert_equal "\nHello, world!\n \n", actual
+ assert_equal "\n Hello, world!\n\n\n \n", actual
end
def test_ruby_mono
- actual = compile_block("@{謳,うた}い文句")
+ actual = compile_block("@{謳,うた}い文句\n")
assert_equal " 謳(うた) い文句\n\n", actual
end
def test_ruby_group
- actual = compile_block("@{欠伸,あくび}が出る")
+ actual = compile_block("@{欠伸,あくび}が出る\n")
assert_equal " 欠伸(あくび) が出る\n\n", actual
end
diff --git a/test/test_pdfmaker.rb b/test/test_pdfmaker.rb
index 7aa86703a..9281457e8 100644
--- a/test/test_pdfmaker.rb
+++ b/test/test_pdfmaker.rb
@@ -34,6 +34,8 @@ def test_check_book_existed
assert !File.exist?(pdf_file)
end
end
+ ensure
+ $stderr = STDERR
end
def test_check_book_none
diff --git a/test/test_pdfmaker_cmd.rb b/test/test_pdfmaker_cmd.rb
index 27b58c3d7..9eb52954f 100644
--- a/test/test_pdfmaker_cmd.rb
+++ b/test/test_pdfmaker_cmd.rb
@@ -6,7 +6,7 @@
require 'yaml'
require 'rbconfig'
-REVIEW_PDFMAKER = File.expand_path('../bin/review-pdfmaker', File.dirname(__FILE__))
+REVIEW_PDFMAKER = File.expand_path('../bin/review-pdfmaker-peg', File.dirname(__FILE__))
class PDFMakerCmdTest < Test::Unit::TestCase
def setup
diff --git a/test/test_textutils.rb b/test/test_textutils.rb
index e8055e107..c34f1a17e 100644
--- a/test/test_textutils.rb
+++ b/test/test_textutils.rb
@@ -29,40 +29,4 @@ def test_detab_with_arg
detabed = detab("\tabc\tdef", 4)
assert_equal " abc def", detabed
end
-
- def test_split_paragraph_empty_nil
- ret = @tu_nil.split_paragraph([])
- assert_equal ret, [""]
- end
-
- def test_split_paragraph_empty_p
- ret = @tu_p.split_paragraph([])
- assert_equal ret, ["
"]
- end
-
- def test_split_paragraph_p
- ret = @tu_p.split_paragraph(["abc"])
- assert_equal ["abc
"], ret
- ret = @tu_p.split_paragraph(["abc","def"])
- assert_equal ["abcdef
"], ret
- ret = @tu_p.split_paragraph(["abc","","def"])
- assert_equal ["abc
","def
"], ret
- ret = @tu_p.split_paragraph(["abc","","","def"])
- assert_equal ["abc
","def
"], ret
- ret = @tu_p.split_paragraph(["abc","","","def","ghi"])
- assert_equal ["abc
","defghi
"], ret
- end
-
- def test_split_paragraph_nil
- ret = @tu_nil.split_paragraph(["abc"])
- assert_equal ["abc"], ret
- ret = @tu_nil.split_paragraph(["abc","def"])
- assert_equal ["abcdef"], ret
- ret = @tu_nil.split_paragraph(["abc","","def"])
- assert_equal ["abc","def"], ret
- ret = @tu_nil.split_paragraph(["abc","","","def"])
- assert_equal ["abc","def"], ret
- ret = @tu_nil.split_paragraph(["abc","","","def","ghi"])
- assert_equal ["abc","defghi"], ret
- end
end