lib/asciidoctor/converter/manpage.rb in asciidoctor-1.5.5 vs lib/asciidoctor/converter/manpage.rb in asciidoctor-1.5.6
- old
+ new
@@ -8,11 +8,11 @@
class Converter::ManPageConverter < Converter::BuiltIn
LF = %(\n)
TAB = %(\t)
WHITESPACE = %(#{LF}#{TAB} )
ET = ' ' * 8
- ESC = %(\u001b) # troff leader marker
+ ESC = %(\u001b) # troff leader marker
ESC_BS = %(#{ESC}\\) # escaped backslash (indicates troff formatting sequence)
ESC_FS = %(#{ESC}.) # escaped full stop (indicates troff macro)
LiteralBackslashRx = /(?:\A|[^#{ESC}])\\/
LeadingPeriodRx = /^\./
@@ -58,10 +58,11 @@
gsub('⇒', '\(rA'). # rightwards double arrow
gsub('​', '\:'). # zero width space
gsub('\'', '\(aq'). # apostrophe-quote
gsub(MockBoundaryRx, ''). # mock boundary
gsub(ESC_BS, '\\'). # unescape troff backslash (NOTE update if more escapes are added)
+ gsub(ESC_FS, '.'). # unescape full stop in troff commands (NOTE must take place after gsub(LeadingPeriodRx))
rstrip # strip trailing space
opts[:append_newline] ? %(#{str}#{LF}) : str
end
def skip_with_warning node, name = nil
@@ -157,17 +158,14 @@
result * LF
end
def section node
- slevel = node.level
- # QUESTION should the check for slevel be done in section?
- slevel = 1 if slevel == 0 && node.special
result = []
- if slevel > 1
+ if node.level > 1
macro = 'SS'
- # QUESTION why captioned title? why not for slevel == 1?
+ # QUESTION why captioned title? why not when level == 1?
stitle = node.captioned_title
else
macro = 'SH'
stitle = node.title.upcase
end
@@ -185,34 +183,36 @@
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
-.B #{node.caption}#{node.title? ? "\\fP #{manify node.title}" : nil}
+.B #{node.attr 'textlabel'}#{node.title? ? "\\fP: #{manify node.title}" : nil}
.ps -1
.br
#{resolve_content node}
.sp .5v
.RE)
result * LF
end
- alias :audio :skip_with_warning
+ alias audio skip_with_warning
def colist node
result = []
result << %(.sp
.B #{manify node.title}
.br) if node.title?
result << '.TS
tab(:);
r lw(\n(.lu*75u/100u).'
- node.items.each_with_index do |item, index|
- result << %(\\fB(#{index + 1})\\fP\\h'-2n':T{
-#{manify item.text}
-T})
+ num = 0
+ node.items.each do |item|
+ result << %(\\fB(#{num += 1})\\fP\\h'-2n':T{)
+ result << (manify item.text)
+ result << item.content if item.blocks?
+ result << 'T}'
end
result << '.TE'
result * LF
end
@@ -224,15 +224,15 @@
node.items.each do |terms, dd|
counter += 1
case node.style
when 'qanda'
result << %(.sp
-#{counter}. #{manify([*terms].map {|dt| dt.text }.join ' ')}
+#{counter}. #{manify([*terms].map {|dt| dt.text } * ' ')}
.RS 4)
else
result << %(.sp
-#{manify([*terms].map {|dt| dt.text }.join ', ')}
+#{manify([*terms].map {|dt| dt.text } * ', ')}
.RS 4)
end
if dd
result << (manify dd.text) if dd.text?
result << dd.content if dd.blocks?
@@ -255,11 +255,11 @@
def floating_title node
%(.SS "#{manify node.title}")
end
- alias :image :skip_with_warning
+ alias image skip_with_warning
def listing node
result = []
result << %(.sp
.B #{manify node.captioned_title}
@@ -326,11 +326,11 @@
node.content
end
end
# TODO use Page Control https://www.gnu.org/software/groff/manual/html_node/Page-Control.html#Page-Control
- alias :page_break :skip
+ alias page_break skip
def paragraph node
if node.title?
%(.sp
.B #{manify node.title}
@@ -340,11 +340,11 @@
%(.sp
#{manify node.content})
end
end
- alias :preamble :content
+ alias preamble content
def quote node
result = []
if node.title?
result << %(.sp
@@ -371,11 +371,11 @@
.ll)
end
result * LF
end
- alias :sidebar :skip_with_warning
+ alias sidebar skip_with_warning
def stem node
title_element = node.title? ? %(.sp
.B #{manify node.title}
.br) : nil
@@ -400,19 +400,20 @@
result << %(.sp
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
-.B #{manify node.captioned_title})
+.B #{manify node.captioned_title}
+)
end
result << '.TS
allbox tab(:);'
row_header = []
row_text = []
row_index = 0
- [:head, :body, :foot].each do |tsec|
- node.rows[tsec].each do |row|
+ node.rows.by_section.each do |tsec, rows|
+ rows.each do |row|
row_header[row_index] ||= []
row_text[row_index] ||= []
# result << LF
# l left-adjusted
# r right-adjusted
@@ -428,63 +429,60 @@
# Add an empty cell if this is a rowspan cell
if row_header[row_index][cell_index] == ['^t']
row_text[row_index] << %(T{#{LF}.sp#{LF}T}:)
end
row_text[row_index] << %(T{#{LF}.sp#{LF})
- cell_halign = (cell.attr 'halign', 'left')[0..0]
+ cell_halign = (cell.attr 'halign', 'left').chr
if tsec == :head
- if row_header[row_index].empty? ||
- row_header[row_index][cell_index].empty?
+ if row_header[row_index].empty? || row_header[row_index][cell_index].empty?
row_header[row_index][cell_index] << %(#{cell_halign}tB)
else
row_header[row_index][cell_index + 1] ||= []
row_header[row_index][cell_index + 1] << %(#{cell_halign}tB)
end
- row_text[row_index] << %(#{cell.text}#{LF})
+ row_text[row_index] << %(#{manify cell.text}#{LF})
elsif tsec == :body
- if row_header[row_index].empty? ||
- row_header[row_index][cell_index].empty?
+ if row_header[row_index].empty? || row_header[row_index][cell_index].empty?
row_header[row_index][cell_index] << %(#{cell_halign}t)
else
row_header[row_index][cell_index + 1] ||= []
row_header[row_index][cell_index + 1] << %(#{cell_halign}t)
end
case cell.style
when :asciidoc
cell_content = cell.content
- when :verse, :literal
- cell_content = cell.text
+ when :literal
+ cell_content = %(.nf#{LF}#{manify cell.text}#{LF}.fi)
+ when :verse
+ cell_content = %(.nf#{LF}#{manify cell.text}#{LF}.fi)
else
- cell_content = cell.content.join
+ cell_content = manify cell.content.join
end
row_text[row_index] << %(#{cell_content}#{LF})
elsif tsec == :foot
- if row_header[row_index].empty? ||
- row_header[row_index][cell_index].empty?
+ if row_header[row_index].empty? || row_header[row_index][cell_index].empty?
row_header[row_index][cell_index] << %(#{cell_halign}tB)
else
row_header[row_index][cell_index + 1] ||= []
row_header[row_index][cell_index + 1] << %(#{cell_halign}tB)
end
- row_text[row_index] << %(#{cell.text}#{LF})
+ row_text[row_index] << %(#{manify cell.text}#{LF})
end
if cell.colspan && cell.colspan > 1
(cell.colspan - 1).times do |i|
- if row_header[row_index].empty? ||
- row_header[row_index][cell_index].empty?
+ if row_header[row_index].empty? || row_header[row_index][cell_index].empty?
row_header[row_index][cell_index + i] << 'st'
else
row_header[row_index][cell_index + 1 + i] ||= []
row_header[row_index][cell_index + 1 + i] << 'st'
end
end
end
if cell.rowspan && cell.rowspan > 1
(cell.rowspan - 1).times do |i|
row_header[row_index + 1 + i] ||= []
- if row_header[row_index + 1 + i].empty? ||
- row_header[row_index + 1 + i][cell_index].empty?
+ if row_header[row_index + 1 + i].empty? || row_header[row_index + 1 + i][cell_index].empty?
row_header[row_index + 1 + i][cell_index] ||= []
row_header[row_index + 1 + i][cell_index] << '^t'
else
row_header[row_index + 1 + i][cell_index + 1] ||= []
row_header[row_index + 1 + i][cell_index + 1] << '^t'
@@ -496,23 +494,23 @@
else
row_text[row_index] << %(T}#{LF})
end
end
row_index += 1
- end
+ end unless rows.empty?
end
#row_header.each do |row|
# result << LF
# row.each_with_index do |cell, i|
- # result << (cell.join ' ')
+ # result << (cell * ' ')
# result << ' ' if row.size > i + 1
# end
#end
# FIXME temporary fix to get basic table to display
result << LF
- result << row_header.first.map {|r| 'lt'}.join(' ')
+ result << row_header[0].map { 'lt' } * ' '
result << %(.#{LF})
row_text.each do |row|
result << row.join
end
@@ -524,11 +522,11 @@
'.sp
.ce
\l\'\n(.lu*25u/100u\(ap\''
end
- alias :toc :skip
+ alias toc skip
def ulist node
result = []
result << %(.sp
.B #{manify node.title}
@@ -576,12 +574,16 @@
end
def video node
start_param = (node.attr? 'start', nil, false) ? %(&start=#{node.attr 'start'}) : nil
end_param = (node.attr? 'end', nil, false) ? %(&end=#{node.attr 'end'}) : nil
- %(.sp
-#{manify node.captioned_title} (video) <#{node.media_uri(node.attr 'target')}#{start_param}#{end_param}>)
+ result = []
+ result << %(.sp
+.B #{manify node.title}
+.br) if node.title?
+ result << %(<#{node.media_uri(node.attr 'target')}#{start_param}#{end_param}> (video))
+ result * LF
end
def inline_anchor node
target = node.target
case node.type
@@ -598,22 +600,21 @@
macro = 'URL'
end
%(#{ESC_BS}c#{LF}#{ESC_FS}#{macro} "#{target}" "#{text}" )
when :xref
refid = (node.attr 'refid') || target
- node.text || (node.document.references[:ids][refid] || %([#{refid}]))
+ node.text || (node.document.catalog[:ids][refid] || %([#{refid}]))
when :ref, :bibref
- # These are anchor points, which shouldn't be visual
+ # These are anchor points, which shouldn't be visible
''
else
warn %(asciidoctor: WARNING: unknown anchor type: #{node.type.inspect})
end
end
def inline_break node
- %(#{node.text}
-.br)
+ %(#{node.text}#{LF}#{ESC_FS}br)
end
def inline_button node
%(#{ESC_BS}fB[#{ESC_BS}0#{node.text}#{ESC_BS}0]#{ESC_BS}fP)
end
@@ -630,31 +631,29 @@
%([#{node.text}])
end
end
def inline_image node
- # NOTE alt should always be set
- alt_text = (node.attr? 'alt') ? (node.attr 'alt') : node.target
- (node.attr? 'link') ? %([#{alt_text}] <#{node.attr 'link'}>) : %([#{alt_text}])
+ (node.attr? 'link') ? %([#{node.alt}] <#{node.attr 'link'}>) : %([#{node.alt}])
end
def inline_indexterm node
node.type == :visible ? node.text : ''
end
def inline_kbd node
if (keys = node.attr 'keys').size == 1
keys[0]
else
- keys.join %(#{ESC_BS}0+#{ESC_BS}0)
+ keys * %(#{ESC_BS}0+#{ESC_BS}0)
end
end
def inline_menu node
caret = %[#{ESC_BS}0#{ESC_BS}(fc#{ESC_BS}0]
menu = node.attr 'menu'
if !(submenus = node.attr 'submenus').empty?
- submenu_path = submenus.map {|item| %(#{ESC_BS}fI#{item}#{ESC_BS}fP) }.join caret
+ submenu_path = submenus.map {|item| %(#{ESC_BS}fI#{item}#{ESC_BS}fP) } * caret
%(#{ESC_BS}fI#{menu}#{ESC_BS}fP#{caret}#{submenu_path}#{caret}#{ESC_BS}fI#{node.attr 'menuitem'}#{ESC_BS}fP)
elsif (menuitem = node.attr 'menuitem')
%(#{ESC_BS}fI#{menu}#{caret}#{menuitem}#{ESC_BS}fP)
else
%(#{ESC_BS}fI#{menu}#{ESC_BS}fP)