lib/review/latexbuilder.rb in review-2.4.0 vs lib/review/latexbuilder.rb in review-2.5.0
- old
+ new
@@ -1,8 +1,8 @@
# Copyright (c) 2002-2007 Minero Aoki
# 2008-2009 Minero Aoki, Kenshi Muto
-# 2010-2017 Minero Aoki, Kenshi Muto, TAKAHASHI Masayoshi
+# 2010-2018 Minero Aoki, Kenshi Muto, TAKAHASHI Masayoshi
#
# 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.
# For details of the GNU LGPL, see the file "COPYING".
@@ -15,11 +15,13 @@
module ReVIEW
class LATEXBuilder < Builder
include LaTeXUtils
include TextUtils
- %i[dtp hd_chap].each { |e| Compiler.definline(e) }
+ %i[dtp hd_chap].each do |e|
+ Compiler.definline(e)
+ end
Compiler.defsingle(:latextsize, 1)
def extname
'.tex'
@@ -32,21 +34,24 @@
@tsize = nil
@table_caption = nil
@ol_num = nil
@first_line_num = nil
@sec_counter = SecCounter.new(5, @chapter)
+ @foottext = {}
setup_index
initialize_metachars(@book.config['texcommand'])
end
private :builder_init_file
def setup_index
@index_db = {}
@index_mecab = nil
return true unless @book.config['pdfmaker']['makeindex']
- @index_db = load_idxdb(@book.config['pdfmaker']['makeindex_dic']) if @book.config['pdfmaker']['makeindex_dic']
+ if @book.config['pdfmaker']['makeindex_dic']
+ @index_db = load_idxdb(@book.config['pdfmaker']['makeindex_dic'])
+ end
return true unless @book.config['pdfmaker']['makeindex_mecab']
begin
require 'MeCab'
require 'nkf'
@index_mecab = MeCab::Tagger.new(@book.config['pdfmaker']['makeindex_mecab_opts'])
@@ -97,19 +102,24 @@
}.freeze
def headline(level, label, caption)
_, anchor = headline_prefix(level)
headline_name = HEADLINE[level]
- headline_name = 'part' if @chapter.is_a? ReVIEW::Book::Part
- prefix = if level > @book.config['secnolevel'] || (@chapter.number.to_s.empty? && level > 1)
- '*'
- else
- ''
- end
+ if @chapter.is_a? ReVIEW::Book::Part
+ headline_name = 'part'
+ end
+ prefix = ''
+ if level > @book.config['secnolevel'] || (@chapter.number.to_s.empty? && level > 1)
+ prefix = '*'
+ end
blank unless @output.pos == 0
+ @doc_status[:caption] = true
puts macro(headline_name + prefix, compile_inline(caption))
- puts "\\addcontentsline{toc}{#{headline_name}}{#{compile_inline(caption)}}" if prefix == '*' && level <= @book.config['toclevel'].to_i
+ @doc_status[:caption] = nil
+ if prefix == '*' && level <= @book.config['toclevel'].to_i
+ puts "\\addcontentsline{toc}{#{headline_name}}{#{compile_inline(caption)}}"
+ end
if level == 1
puts macro('label', chapter_label)
else
puts macro('label', sec_label(anchor))
puts macro('label', label) if label
@@ -118,20 +128,24 @@
error "unknown level: #{level}"
end
def nonum_begin(level, _label, caption)
blank unless @output.pos == 0
+ @doc_status[:caption] = true
puts macro(HEADLINE[level] + '*', compile_inline(caption))
+ @doc_status[:caption] = nil
puts macro('addcontentsline', 'toc', HEADLINE[level], compile_inline(caption))
end
def nonum_end(level)
end
def notoc_begin(level, _label, caption)
blank unless @output.pos == 0
+ @doc_status[:caption] = true
puts macro(HEADLINE[level] + '*', compile_inline(caption))
+ @doc_status[:caption] = nil
end
def notoc_end(level)
end
@@ -145,40 +159,50 @@
def nodisp_end(level)
end
def column_begin(level, label, caption)
blank
+ @doc_status[:column] = true
puts "\\begin{reviewcolumn}\n"
if label
puts "\\hypertarget{#{column_label(label)}}{}"
else
puts "\\hypertarget{#{column_label(caption)}}{}"
end
+ @doc_status[:caption] = true
puts macro('reviewcolumnhead', nil, compile_inline(caption))
- puts "\\addcontentsline{toc}{#{HEADLINE[level]}}{#{compile_inline(caption)}}" if level <= @book.config['toclevel'].to_i
+ @doc_status[:caption] = nil
+ if level <= @book.config['toclevel'].to_i
+ puts "\\addcontentsline{toc}{#{HEADLINE[level]}}{#{compile_inline(caption)}}"
+ end
end
def column_end(_level)
puts "\\end{reviewcolumn}\n"
blank
+ @doc_status[:column] = nil
end
def captionblock(_type, lines, caption)
puts "\\begin{reviewminicolumn}\n"
- puts "\\reviewminicolumntitle{#{compile_inline(caption)}}\n" if caption
+ @doc_status[:caption] = true
+ puts "\\reviewminicolumntitle{#{compile_inline(caption)}}\n" if caption.present?
+ @doc_status[:caption] = nil
blocked_lines = split_paragraph(lines)
puts blocked_lines.join("\n\n")
puts "\\end{reviewminicolumn}\n"
end
def box(lines, caption = nil)
blank
- puts macro('reviewboxcaption', compile_inline(caption)) if caption
+ puts macro('reviewboxcaption', compile_inline(caption)) if caption.present?
puts '\begin{reviewbox}'
- lines.each { |line| puts detab(line) }
+ lines.each do |line|
+ puts detab(line)
+ end
puts '\end{reviewbox}'
blank
end
def ul_begin
@@ -236,11 +260,13 @@
blank
end
def paragraph(lines)
blank
- lines.each { |line| puts line }
+ lines.each do |line|
+ puts line
+ end
blank
end
def parasep
puts '\\parasep'
@@ -303,11 +329,12 @@
common_code_block(nil, lines, 'reviewcmd', caption, lang) { |line, _idx| detab(line) + "\n" }
end
end
def common_code_block(id, lines, command, caption, _lang)
- if caption
+ @doc_status[:caption] = true
+ if caption.present?
if command =~ /emlist/ || command =~ /cmd/ || command =~ /source/
puts macro(command + 'caption', compile_inline(caption))
else
begin
if get_chap.nil?
@@ -318,20 +345,25 @@
rescue KeyError
error "no such list: #{id}"
end
end
end
+ @doc_status[:caption] = nil
body = ''
- lines.each_with_index { |line, idx| body.concat(yield(line, idx)) }
+ lines.each_with_index do |line, idx|
+ body.concat(yield(line, idx))
+ end
puts macro('begin', command)
print body
puts macro('end', command)
blank
end
def common_code_block_lst(_id, lines, command, title, caption, lang, first_line_num: 1)
- print '\vspace{-1.5em}' if title == 'title' && caption.blank?
+ if title == 'title' && caption.blank?
+ print '\vspace{-1.5em}'
+ end
body = lines.inject('') { |i, j| i + detab(unescape_latex(j)) + "\n" }
args = make_code_block_args(title, caption, lang, first_line_num: first_line_num)
puts %Q(\\begin{#{command}}[#{args}])
print body
puts %Q(\\end{#{command}})
@@ -348,11 +380,13 @@
else
''
end
lexer = lang if lang.present?
args = %Q(#{title}={#{caption_str}},language={#{lexer}})
- args += ",firstnumber=#{first_line_num}" if first_line_num != 1
+ if first_line_num != 1
+ args += ",firstnumber=#{first_line_num}"
+ end
args
end
def source(lines, caption = nil, lang = nil)
if highlight_listings?
@@ -377,29 +411,35 @@
end
def image_image(id, caption, metric)
metrics = parse_metric('latex', metric)
# image is always bound here
- puts '\begin{reviewimage}'
+ puts "\\begin{reviewimage}%%#{id}"
if metrics.present?
puts "\\includegraphics[#{metrics}]{#{@chapter.image(id).path}}"
else
puts "\\includegraphics[width=\\maxwidth]{#{@chapter.image(id).path}}"
end
+ @doc_status[:caption] = true
puts macro('caption', compile_inline(caption)) if caption.present?
+ @doc_status[:caption] = nil
puts macro('label', image_label(id))
puts '\end{reviewimage}'
end
def image_dummy(id, caption, lines)
warn "image not bound: #{id}"
puts '\begin{reviewdummyimage}'
# path = @chapter.image(id).path
puts "--[[path = #{id} (#{existence(id)})]]--"
- lines.each { |line| puts detab(line.rstrip) }
+ lines.each do |line|
+ puts detab(line.rstrip)
+ end
puts macro('label', image_label(id))
- puts compile_inline(caption)
+ @doc_status[:caption] = true
+ puts macro('caption', compile_inline(caption)) if caption.present?
+ @doc_status[:caption] = nil
puts '\end{reviewdummyimage}'
end
def existence(id)
@chapter.image(id).bound? ? 'exist' : 'not exist'
@@ -442,24 +482,28 @@
def indepimage(lines, id, caption = nil, metric = nil)
metrics = parse_metric('latex', metric)
if @chapter.image(id).path
- puts '\begin{reviewimage}'
+ puts "\\begin{reviewimage}%%#{id}"
if metrics.present?
puts "\\includegraphics[#{metrics}]{#{@chapter.image(id).path}}"
else
puts "\\includegraphics[width=\\maxwidth]{#{@chapter.image(id).path}}"
end
else
warn "image not bound: #{id}"
puts '\begin{reviewdummyimage}'
puts "--[[path = #{id} (#{existence(id)})]]--"
- lines.each { |line| puts detab(line.rstrip) }
+ lines.each do |line|
+ puts detab(line.rstrip)
+ end
end
+ @doc_status[:caption] = true
puts macro('reviewindepimagecaption', %Q(#{I18n.t('numberless_image')}#{I18n.t('caption_prefix')}#{compile_inline(caption)})) if caption.present?
+ @doc_status[:caption] = nil
if @chapter.image(id).path
puts '\end{reviewimage}'
else
puts '\end{reviewdummyimage}'
@@ -481,19 +525,23 @@
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?
+ table_header id, caption if caption.present?
rescue KeyError
error "no such table: #{id}"
end
return if rows.empty?
table_begin rows.first.size
if sepidx
- sepidx.times { tr(rows.shift.map { |s| th(s) }) }
- rows.each { |cols| tr(cols.map { |s| td(s) }) }
+ sepidx.times do
+ tr(rows.shift.map { |s| th(s) })
+ end
+ rows.each do |cols|
+ tr(cols.map { |s| td(s) })
+ end
else
rows.each do |cols|
h, *cs = *cols
tr([th(h)] + cs.map { |s| td(s) })
end
@@ -503,18 +551,22 @@
def table_header(id, caption)
if id.nil?
if caption.present?
@table_caption = true
- puts '\begin{table}[h]'
+ @doc_status[:caption] = true
+ puts "\\begin{table}[h]%%#{id}"
puts macro('reviewtablecaption*', compile_inline(caption))
+ @doc_status[:caption] = nil
end
else
if caption.present?
@table_caption = true
- puts '\begin{table}[h]'
+ @doc_status[:caption] = true
+ puts "\\begin{table}[h]%%#{id}"
puts macro('reviewtablecaption', compile_inline(caption))
+ @doc_status[:caption] = nil
end
puts macro('label', table_label(id))
end
end
@@ -540,11 +592,11 @@
# puts '\hline'
end
def th(s)
## use shortstack for @<br>
- if /\\\\/i =~ s
+ if /\\\\/ =~ s
macro('reviewth', macro('shortstack[l]', s))
else
macro('reviewth', s)
end
end
@@ -582,12 +634,14 @@
end
begin
if caption.present?
@table_caption = true
- puts '\begin{table}[h]'
+ @doc_status[:caption] = true
+ puts "\\begin{table}[h]%%#{id}"
puts macro('reviewimgtablecaption', compile_inline(caption))
+ @doc_status[:caption] = nil
end
puts macro('label', table_label(id))
rescue ReVIEW::KeyError
error "no such table: #{id}"
end
@@ -599,11 +653,11 @@
end
def imgtable_image(id, _caption, metric)
metrics = parse_metric('latex', metric)
# image is always bound here
- puts '\begin{reviewimage}'
+ puts "\\begin{reviewimage}%%#{id}"
if metrics.present?
puts "\\includegraphics[#{metrics}]{#{@chapter.image(id).path}}"
else
puts "\\includegraphics[width=\\maxwidth]{#{@chapter.image(id).path}}"
end
@@ -625,11 +679,13 @@
end
def texequation(lines)
blank
puts macro('begin', 'equation*')
- lines.each { |line| puts unescape_latex(line) }
+ lines.each do |line|
+ puts unescape_latex(line)
+ end
puts macro('end', 'equation*')
blank
end
def latex_block(type, lines)
@@ -642,16 +698,20 @@
end
private :latex_block
def direct(lines, fmt)
return unless fmt == 'latex'
- lines.each { |line| puts line }
+ lines.each do |line|
+ puts line
+ end
end
def comment(lines, comment = nil)
lines ||= []
- lines.unshift comment unless comment.blank?
+ unless comment.blank?
+ lines.unshift comment
+ end
return true unless @book.config['draft']
str = lines.join('\par ')
puts macro('pdfcomment', escape(str))
end
@@ -665,12 +725,12 @@
def pagebreak
puts '\pagebreak'
end
- def linebreak
- puts '\\\\'
+ def blankline
+ puts '\vspace*{\baselineskip}'
end
def noindent
print '\noindent'
end
@@ -720,40 +780,53 @@
if get_chap(chapter).nil?
macro('reviewlistref', I18n.t('format_number_without_chapter', [chapter.list(id).number]))
else
macro('reviewlistref', I18n.t('format_number', [get_chap(chapter), chapter.list(id).number]))
end
+ rescue KeyError
+ error "unknown list: #{id}"
end
def inline_table(id)
chapter, id = extract_chapter_id(id)
if get_chap(chapter).nil?
macro('reviewtableref', I18n.t('format_number_without_chapter', [chapter.table(id).number]), table_label(id, chapter))
else
macro('reviewtableref', I18n.t('format_number', [get_chap(chapter), chapter.table(id).number]), table_label(id, chapter))
end
+ rescue KeyError
+ error "unknown table: #{id}"
end
def inline_img(id)
chapter, id = extract_chapter_id(id)
if get_chap(chapter).nil?
macro('reviewimageref', I18n.t('format_number_without_chapter', [chapter.image(id).number]), image_label(id, chapter))
else
macro('reviewimageref', I18n.t('format_number', [get_chap(chapter), chapter.image(id).number]), image_label(id, chapter))
end
+ rescue KeyError
+ error "unknown image: #{id}"
end
def footnote(id, content)
- puts macro("footnotetext[#{@chapter.footnote(id).number}]", compile_inline(content.strip)) if @book.config['footnotetext']
+ if @book.config['footnotetext'] || @foottext[id]
+ puts macro("footnotetext[#{@chapter.footnote(id).number}]", compile_inline(content.strip))
+ end
end
def inline_fn(id)
if @book.config['footnotetext']
macro("footnotemark[#{@chapter.footnote(id).number}]", '')
+ elsif @doc_status[:caption] || @doc_status[:table] || @doc_status[:column]
+ @foottext[id] = @chapter.footnote(id).number
+ macro('protect\\footnotemark', '')
else
macro('footnote', compile_inline(@chapter.footnote(id).content.strip))
end
+ rescue KeyError
+ error "unknown footnote: #{id}"
end
BOUTEN = '・'.freeze
def inline_bou(str)
@@ -850,9 +923,11 @@
def inline_column_chap(chapter, id)
macro('reviewcolumnref',
I18n.t('chapter_quote', compile_inline(chapter.column(id).caption)),
column_label(id, chapter))
+ rescue KeyError
+ error "unknown column: #{id}"
end
def inline_raw(str)
super(str)
end