diff --git a/lib/review/builder.rb b/lib/review/builder.rb index d20040e6b..9227ce87b 100644 --- a/lib/review/builder.rb +++ b/lib/review/builder.rb @@ -1,4 +1,4 @@ -# Copyright (c) 2002-2018 Minero Aoki, Kenshi Muto +# Copyright (c) 2002-2019 Minero Aoki, Kenshi Muto # # This program is free software. # You can distribute or modify this program under the terms of @@ -225,8 +225,8 @@ def blankline puts '' end - def compile_inline(s) - @compiler.text(s) + def compile_inline(s, esc_array = nil) + @compiler.text(s, esc_array) end def inline_chapref(id) @@ -632,5 +632,9 @@ def escape(str) def unescape(str) str end + + def revert_escape(s, esc_array) + s.gsub("\x01") { esc_array.shift } + end end end # module ReVIEW diff --git a/lib/review/compiler.rb b/lib/review/compiler.rb index fb758d548..d6aca6830 100644 --- a/lib/review/compiler.rb +++ b/lib/review/compiler.rb @@ -1,4 +1,4 @@ -# Copyright (c) 2009-2018 Minero Aoki, Kenshi Muto +# Copyright (c) 2009-2019 Minero Aoki, Kenshi Muto # Copyright (c) 2002-2007 Minero Aoki # # This program is free software. @@ -445,7 +445,10 @@ def compile_paragraph(f) def read_command(f) line = f.gets name = line.slice(/[a-z]+/).to_sym - ignore_inline = (name == :embed) + ignore_inline = nil + if %i[embed list emlist source cmd listnum emlistnum].include?(name) + ignore_inline = true + end args = parse_args(line.sub(%r{\A//[a-z]+}, '').rstrip.chomp('{'), name) @strategy.doc_status[name] = true lines = block_open?(line) ? read_block(f, ignore_inline) : nil @@ -550,7 +553,7 @@ def revert_replace_fence(str) str.gsub("\x01", '@').gsub("\x02", '\\').gsub("\x03", '{').gsub("\x04", '}') end - def text(str) + def text(str, esc_array = nil) return '' if str.empty? words = replace_fence(str).split(/(@<\w+>\{(?:[^\}\\]|\\.)*?\})/, -1) words.each do |w| @@ -560,7 +563,12 @@ def text(str) end result = @strategy.nofunc_text(revert_replace_fence(words.shift)) until words.empty? - result << compile_inline(revert_replace_fence(words.shift.gsub(/\\\}/, '}').gsub(/\\\\/, '\\'))) + if esc_array + esc_array << compile_inline(revert_replace_fence(words.shift.gsub(/\\\}/, '}').gsub(/\\\\/, '\\'))) + result << "\x01" + else + result << compile_inline(revert_replace_fence(words.shift.gsub(/\\\}/, '}').gsub(/\\\\/, '\\'))) + end result << @strategy.nofunc_text(revert_replace_fence(words.shift)) end result diff --git a/lib/review/htmlbuilder.rb b/lib/review/htmlbuilder.rb index 4163aded4..d10cad71e 100644 --- a/lib/review/htmlbuilder.rb +++ b/lib/review/htmlbuilder.rb @@ -397,8 +397,10 @@ def list_body(_id, lines, lang) class_names.push("language-#{lexer}") unless lexer.blank? class_names.push('highlight') if highlight? print %Q(
)
-      body = lines.inject('') { |i, j| i + detab(j) + "\n" }
-      puts highlight(body: body, lexer: lexer, format: 'html')
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
+      body = lines.inject('') { |i, j| i + detab(j) }
+      puts revert_escape(highlight(body: body, lexer: lexer, format: 'html'), esc_array)
       puts '
' end @@ -417,9 +419,11 @@ def source_header(caption) def source_body(_id, lines, lang) print %Q(
)
-      body = lines.inject('') { |i, j| i + detab(j) + "\n" }
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
+      body = lines.inject('') { |i, j| i + detab(j) }
       lexer = lang
-      puts highlight(body: body, lexer: lexer, format: 'html')
+      puts revert_escape(highlight(body: body, lexer: lexer, format: 'html'), esc_array)
       puts '
' end @@ -435,19 +439,21 @@ def listnum(lines, id, caption, lang = nil) end def listnum_body(lines, lang) - body = lines.inject('') { |i, j| i + detab(j) + "\n" } + esc_array = [] + lines.map! { |l| compile_inline(l, esc_array) } + body = lines.inject('') { |i, j| i + detab(j) } lexer = lang first_line_number = line_num hs = highlight(body: body, lexer: lexer, format: 'html', linenum: true, options: { linenostart: first_line_number }) if highlight? - puts hs + puts revert_escape(hs, esc_array) else class_names = ['list'] class_names.push("language-#{lang}") unless lang.blank? print %Q(
)
-        hs.split("\n").each_with_index do |line, i|
+        revert_escape(hs, esc_array).split("\n").each_with_index do |line, i|
           puts detab((i + first_line_number).to_s.rjust(2) + ': ' + line)
         end
         puts '
' @@ -463,9 +469,11 @@ def emlist(lines, caption = nil, lang = nil) class_names.push("language-#{lang}") unless lang.blank? class_names.push('highlight') if highlight? print %Q(
)
-      body = lines.inject('') { |i, j| i + detab(j) + "\n" }
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
+      body = lines.inject('') { |i, j| i + detab(j) }
       lexer = lang
-      puts highlight(body: body, lexer: lexer, format: 'html')
+      puts revert_escape(highlight(body: body, lexer: lexer, format: 'html'), esc_array)
       puts '
' puts '' end @@ -476,19 +484,21 @@ def emlistnum(lines, caption = nil, lang = nil) puts %Q(

#{compile_inline(caption)}

) end - body = lines.inject('') { |i, j| i + detab(j) + "\n" } + esc_array = [] + lines.map! { |l| compile_inline(l, esc_array) } + body = lines.inject('') { |i, j| i + detab(j) } lexer = lang first_line_number = line_num hs = highlight(body: body, lexer: lexer, format: 'html', linenum: true, options: { linenostart: first_line_number }) if highlight? - puts hs + puts revert_escape(hs, esc_array) else class_names = ['emlist'] class_names.push("language-#{lang}") unless lang.blank? class_names.push('highlight') if highlight? print %Q(
)
-        hs.split("\n").each_with_index do |line, i|
+        revert_escape(hs, esc_array).split("\n").each_with_index do |line, i|
           puts detab((i + first_line_number).to_s.rjust(2) + ': ' + line)
         end
         puts '
' @@ -503,9 +513,11 @@ def cmd(lines, caption = nil) puts %Q(

#{compile_inline(caption)}

) end print %Q(
)
-      body = lines.inject('') { |i, j| i + detab(j) + "\n" }
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
+      body = lines.inject('') { |i, j| i + detab(j) }
       lexer = 'shell-session'
-      puts highlight(body: body, lexer: lexer, format: 'html')
+      puts revert_escape(highlight(body: body, lexer: lexer, format: 'html'), esc_array)
       puts '
' puts '' end @@ -1219,6 +1231,12 @@ def olnum(num) @ol_num = num.to_i end + def revert_escape(s, esc_array) + s.gsub("\x01", "\x01"). + gsub("\x01", "\x01"). + gsub("\x01") { esc_array.shift } + end + def defer_math_image(str, path, key) # for Re:VIEW >3 File.open(File.join(File.dirname(path), '__IMGMATH_BODY__.tex'), 'a+') do |f| diff --git a/lib/review/idgxmlbuilder.rb b/lib/review/idgxmlbuilder.rb index d9db97599..a51c6315b 100644 --- a/lib/review/idgxmlbuilder.rb +++ b/lib/review/idgxmlbuilder.rb @@ -1,4 +1,4 @@ -# Copyright (c) 2008-2018 Minero Aoki, Kenshi Muto +# Copyright (c) 2008-2019 Minero Aoki, Kenshi Muto # 2002-2007 Minero Aoki # # This program is free software. @@ -279,6 +279,8 @@ def list_header(id, caption, _lang) def codelines_body(lines) no = 1 + esc_array = [] + lines.map! { |l| compile_inline(l, esc_array) } lines.each do |line| if @book.config['listinfo'] print %Q(' end - print detab(line) - print "\n" + print revert_escape(detab(line), esc_array) print '' if @book.config['listinfo'] no += 1 end @@ -304,18 +305,34 @@ def emlist(lines, caption = nil, _lang = nil) end def emlistnum(lines, caption = nil, _lang = nil) - lines2 = [] + print %Q() + puts "#{compile_inline(caption)}" if caption.present? + print '
'
+      no = 1
       first_line_num = line_num
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
       lines.each_with_index do |line, i|
-        lines2 << detab(%Q() + (i + first_line_num).to_s.rjust(2) + ': ' + line)
+        if @book.config['listinfo']
+          print %Q('
+        end
+        print revert_escape(detab(%Q() + (i + first_line_num).to_s.rjust(2) + ': ' + line), esc_array)
+
+        print '' if @book.config['listinfo']
+        no += 1
       end
-      quotedlist lines2, 'emlistnum', caption
+      puts '
' end def listnum_body(lines, _lang) print '
'
       no = 1
       first_line_num = line_num
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
       lines.each_with_index do |line, i|
         if @book.config['listinfo']
           print %Q('
         end
-        print detab(%Q() + (i + first_line_num).to_s.rjust(2) + ': ' + line)
-        print "\n"
+        print revert_escape(detab(%Q() + (i + first_line_num).to_s.rjust(2) + ': ' + line), esc_array)
+
         print '' if @book.config['listinfo']
         no += 1
       end
@@ -340,6 +357,8 @@ def quotedlist(lines, css_class, caption)
       puts "#{compile_inline(caption)}" if caption.present?
       print '
'
       no = 1
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
       lines.each do |line|
         if @book.config['listinfo']
           print %Q('
         end
-        print detab(line)
-        print "\n"
+        print revert_escape(detab(line), esc_array)
         print '' if @book.config['listinfo']
         no += 1
       end
diff --git a/lib/review/latexbuilder.rb b/lib/review/latexbuilder.rb
index ca6989d5a..61e34da04 100644
--- a/lib/review/latexbuilder.rb
+++ b/lib/review/latexbuilder.rb
@@ -334,7 +334,7 @@ def emlist(lines, caption = nil, lang = nil)
       if highlight_listings?
         common_code_block_lst(nil, lines, 'reviewemlistlst', 'title', caption, lang)
       else
-        common_code_block(nil, lines, 'reviewemlist', caption, lang) { |line, _idx| detab(line) + "\n" }
+        common_code_block(nil, lines, 'reviewemlist', caption, lang) { |line, _idx| detab(line) }
       end
     end
 
@@ -344,7 +344,7 @@ def emlistnum(lines, caption = nil, lang = nil)
       if highlight_listings?
         common_code_block_lst(nil, lines, 'reviewemlistnumlst', 'title', caption, lang, first_line_num: first_line_num)
       else
-        common_code_block(nil, lines, 'reviewemlist', caption, lang) { |line, idx| detab((idx + first_line_num).to_s.rjust(2) + ': ' + line) + "\n" }
+        common_code_block(nil, lines, 'reviewemlist', caption, lang) { |line, idx| detab((idx + first_line_num).to_s.rjust(2) + ': ' + line) }
       end
     end
 
@@ -353,7 +353,7 @@ def list(lines, id, caption, lang = nil)
       if highlight_listings?
         common_code_block_lst(id, lines, 'reviewlistlst', 'caption', caption, lang)
       else
-        common_code_block(id, lines, 'reviewlist', caption, lang) { |line, _idx| detab(line) + "\n" }
+        common_code_block(id, lines, 'reviewlist', caption, lang) { |line, _idx| detab(line) }
       end
     end
 
@@ -363,7 +363,7 @@ def listnum(lines, id, caption, lang = nil)
       if highlight_listings?
         common_code_block_lst(id, lines, 'reviewlistnumlst', 'caption', caption, lang, first_line_num: first_line_num)
       else
-        common_code_block(id, lines, 'reviewlist', caption, lang) { |line, idx| detab((idx + first_line_num).to_s.rjust(2) + ': ' + line) + "\n" }
+        common_code_block(id, lines, 'reviewlist', caption, lang) { |line, idx| detab((idx + first_line_num).to_s.rjust(2) + ': ' + line) }
       end
     end
 
@@ -372,7 +372,7 @@ def cmd(lines, caption = nil, lang = nil)
         common_code_block_lst(nil, lines, 'reviewcmdlst', 'title', caption, lang)
       else
         blank
-        common_code_block(nil, lines, 'reviewcmd', caption, lang) { |line, _idx| detab(line) + "\n" }
+        common_code_block(nil, lines, 'reviewcmd', caption, lang) { |line, _idx| detab(line) }
       end
     end
 
@@ -398,11 +398,15 @@ def common_code_block(id, lines, command, caption, _lang)
       end
       @doc_status[:caption] = nil
       body = ''
+
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
+
       lines.each_with_index do |line, idx|
         body.concat(yield(line, idx))
       end
       puts macro('begin', command)
-      print body
+      print revert_escape(body, esc_array)
       puts macro('end', command)
       unless @book.config.check_version('2', exception: false)
         puts '\\end{reviewlistblock}'
@@ -414,10 +418,12 @@ def common_code_block_lst(_id, lines, command, title, caption, lang, first_line_
       if title == 'title' && caption.blank? && @book.config.check_version('2', exception: false)
         print '\vspace{-1.5em}'
       end
-      body = lines.inject('') { |i, j| i + detab(unescape(j)) + "\n" }
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
+      body = lines.inject('') { |i, j| i + detab(unescape(j)) }
       args = make_code_block_args(title, caption, lang, first_line_num: first_line_num)
       puts %Q(\\begin{#{command}}[#{args}])
-      print body
+      print revert_escape(body, esc_array)
       puts %Q(\\end{#{command}})
       blank
     end
@@ -449,7 +455,7 @@ def source(lines, caption = nil, lang = nil)
       if highlight_listings?
         common_code_block_lst(nil, lines, 'reviewsourcelst', 'title', caption, lang)
       else
-        common_code_block(nil, lines, 'reviewsource', caption, lang) { |line, _idx| detab(line) + "\n" }
+        common_code_block(nil, lines, 'reviewsource', caption, lang) { |line, _idx| detab(line) }
       end
     end
 
diff --git a/lib/review/markdownbuilder.rb b/lib/review/markdownbuilder.rb
index 82ad70c24..185fd5c14 100644
--- a/lib/review/markdownbuilder.rb
+++ b/lib/review/markdownbuilder.rb
@@ -1,3 +1,5 @@
+# Copyright (c) 2013-2019 Masanori Kado, Masayoshi Takahashi, 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.
@@ -74,8 +76,10 @@ def list_header(id, caption, lang)
     end
 
     def list_body(_id, lines, _lang)
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
       lines.each do |line|
-        puts detab(line)
+        puts revert_escape(detab(line), esc_array)
       end
       puts '```'
     end
@@ -126,6 +130,8 @@ def dl_end
     end
 
     def emlist(lines, caption = nil, lang = nil)
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
       blank
       if caption
         puts caption
@@ -134,7 +140,7 @@ def emlist(lines, caption = nil, lang = nil)
       lang ||= ''
       puts "```#{lang}"
       lines.each do |line|
-        puts detab(line)
+        puts revert_escape(detab(line), esc_array)
       end
       puts '```'
       blank
@@ -230,9 +236,11 @@ def image_ext
     end
 
     def cmd(lines)
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
       puts '```shell-session'
       lines.each do |line|
-        puts detab(line)
+        puts revert_escape(detab(line), esc_array)
       end
       puts '```'
     end
diff --git a/lib/review/plaintextbuilder.rb b/lib/review/plaintextbuilder.rb
index 677f7e4dc..18fb5cd9e 100644
--- a/lib/review/plaintextbuilder.rb
+++ b/lib/review/plaintextbuilder.rb
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Kenshi Muto
+# Copyright (c) 2018-2019 Kenshi Muto
 #
 # This program is free software.
 # You can distribute or modify this program under the terms of
@@ -148,16 +148,20 @@ def list_header(id, caption, _lang)
     end
 
     def list_body(_id, lines, _lang)
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
       lines.each do |line|
-        puts detab(line)
+        puts revert_escape(detab(line), esc_array)
       end
       blank
     end
 
     def base_block(_type, lines, caption = nil)
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
       blank
       puts compile_inline(caption) if caption.present?
-      puts lines.join("\n")
+      puts revert_escape(lines.join, esc_array)
       blank
     end
 
diff --git a/lib/review/topbuilder.rb b/lib/review/topbuilder.rb
index d7f243f58..1c17581f2 100644
--- a/lib/review/topbuilder.rb
+++ b/lib/review/topbuilder.rb
@@ -1,4 +1,4 @@
-# Copyright (c) 2008-2018 Minero Aoki, Kenshi Muto
+# Copyright (c) 2008-2019 Minero Aoki, Kenshi Muto
 #               2002-2006 Minero Aoki
 #
 # This program is free software.
@@ -103,18 +103,22 @@ def list_header(id, caption, _lang)
     end
 
     def list_body(_id, lines, _lang)
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
       lines.each do |line|
-        puts detab(line)
+        puts revert_escape(detab(line), esc_array)
       end
       puts "◆→終了:#{@titles['list']}←◆"
       blank
     end
 
     def base_block(type, lines, caption = nil)
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
       blank
       puts "◆→開始:#{@titles[type]}←◆"
       puts "■#{compile_inline(caption)}" if caption.present?
-      puts lines.join("\n")
+      puts revert_escape(lines.join, esc_array)
       puts "◆→終了:#{@titles[type]}←◆"
       blank
     end
@@ -132,16 +136,20 @@ def emlistnum(lines, caption = nil, _lang = nil)
       blank
       puts "◆→開始:#{@titles['emlist']}←◆"
       puts "■#{compile_inline(caption)}" if caption.present?
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
       lines.each_with_index do |line, i|
-        puts((i + 1).to_s.rjust(2) + ": #{line}")
+        puts((i + 1).to_s.rjust(2) + ": #{revert_escape(line, esc_array)}")
       end
       puts "◆→終了:#{@titles['emlist']}←◆"
       blank
     end
 
     def listnum_body(lines, _lang)
+      esc_array = []
+      lines.map! { |l| compile_inline(l, esc_array) }
       lines.each_with_index do |line, i|
-        puts((i + 1).to_s.rjust(2) + ": #{line}")
+        puts((i + 1).to_s.rjust(2) + ": #{revert_escape(line, esc_array)}")
       end
       puts "◆→終了:#{@titles['list']}←◆"
       blank
diff --git a/test/test_builder.rb b/test/test_builder.rb
index 9dce36acd..145bebcad 100644
--- a/test/test_builder.rb
+++ b/test/test_builder.rb
@@ -4,7 +4,7 @@
 require 'review/book'
 
 class MockCompiler
-  def text(s)
+  def text(s, _array = nil)
     [:text, s]
   end
 end
diff --git a/test/test_htmlbuilder.rb b/test/test_htmlbuilder.rb
index aa7e91ea0..48b3fa097 100644
--- a/test/test_htmlbuilder.rb
+++ b/test/test_htmlbuilder.rb
@@ -630,7 +630,7 @@ def @chapter.list(_id)
 
test1
 test1.5
 
-test<i>2</i>
+test2
 
EOS @@ -706,7 +706,7 @@ def @chapter.list(_id) @book.config['highlight']['html'] = 'rouge' 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\ntest2\n
\n
\n), actual end def test_list_rouge_lang