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(
' + 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 '
' 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> +test2EOS @@ -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\n), actual + assert_equal %Q(リスト1.1: this is test<&>_
\ntest1\ntest1.5\n\ntest<i>2</i>\n\n\n\n), actual end def test_list_rouge_langリスト1.1: this is test<&>_
\ntest1\ntest1.5\n\ntest2\n\n