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('&#8658;', '\(rA'). # rightwards double arrow gsub('&#8203;', '\:'). # 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)