class Asciidoctor::Converter::ManPageConverter

A built-in {Converter} implementation that generates the man page (troff) format.

The output follows the groff man page definition while also trying to be consistent with the output produced by the a2x tool from AsciiDoc Python.

See www.gnu.org/software/groff/manual/html_node/Man-usage.html#Man-usage

Constants

ESC
ESC_BS
ESC_FS
ET
EllipsisCharRefRx
EmDashCharRefRx
EscapedMacroRx
LF
LeadingPeriodRx
LiteralBackslashRx
MockBoundaryRx
TAB
WHITESPACE
WrappedIndentRx

Public Instance Methods

admonition(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 206
    def admonition node
      result = []
      result << %(.if n .sp
.RS 4
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
.B #{node.attr 'textlabel'}#{node.title? ? "\\fP: #{manify node.title}" : ''}
.ps -1
.br
#{resolve_content node}
.sp .5v
.RE)
      result.join LF
    end
audio(node, name = nil)
Alias for: skip_with_warning
colist(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 226
    def colist node
      result = []
      result << %(.sp
.B #{manify node.title}
.br) if node.title?
      result << '.TS
tab(:);
r lw(\n(.lu*75u/100u).'

      num = 0
      node.items.each do |item|
        result << %(\\fB(#{num += 1})\\fP\\h'-2n':T{)
        result << (manify item.text, :whitespace => :normalize)
        result << item.content if item.blocks?
        result << 'T}'
      end
      result << '.TE'
      result.join LF
    end
dlist(node) click to toggle source

TODO implement horizontal (if it makes sense)

# File lib/asciidoctor/converter/manpage.rb, line 247
    def dlist node
      result = []
      result << %(.sp
.B #{manify node.title}
.br) if node.title?
      counter = 0
      node.items.each do |terms, dd|
        counter += 1
        case node.style
        when 'qanda'
          result << %(.sp
#{counter}. #{manify [*terms].map {|dt| dt.text }.join ' '}
.RS 4)
        else
          result << %(.sp
#{manify [*terms].map {|dt| dt.text }.join(', '), :whitespace => :normalize}
.RS 4)
        end
        if dd
          result << (manify dd.text, :whitespace => :normalize) if dd.text?
          result << dd.content if dd.blocks?
        end
        result << '.RE'
      end
      result.join LF
    end
document(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 85
    def document node
      unless node.attr? 'mantitle'
        raise 'asciidoctor: ERROR: doctype must be set to manpage when using manpage backend'
      end
      mantitle = node.attr 'mantitle'
      manvolnum = node.attr 'manvolnum', '1'
      manname = node.attr 'manname', mantitle
      manmanual = node.attr 'manmanual'
      mansource = node.attr 'mansource'
      docdate = (node.attr? 'reproducible') ? nil : (node.attr 'docdate')
      # NOTE the first line enables the table (tbl) preprocessor, necessary for non-Linux systems
      result = [%('\\" t
.\\"     Title: #{mantitle}
.\\"    Author: #{(node.attr? 'authors') ? (node.attr 'authors') : '[see the "AUTHOR(S)" section]'}
.\\" Generator: Asciidoctor #{node.attr 'asciidoctor-version'})]
      result << %(.\\"      Date: #{docdate}) if docdate
      result << %(.\\"    Manual: #{manmanual ? (manmanual.tr_s WHITESPACE, ' ') : '\ \&'}
.\\"    Source: #{mansource ? (mansource.tr_s WHITESPACE, ' ') : '\ \&'}
.\\"  Language: English
.\\")
      # TODO add document-level setting to disable capitalization of manname
      result << %(.TH "#{manify manname.upcase}" "#{manvolnum}" "#{docdate}" "#{mansource ? (manify mansource) : '\ \&'}" "#{manmanual ? (manify manmanual) : '\ \&'}")
      # define portability settings
      # see http://bugs.debian.org/507673
      # see http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
      result << '.ie \n(.g .ds Aq \(aq'
      result << '.el       .ds Aq \''
      # set sentence_space_size to 0 to prevent extra space between sentences separated by a newline
      # the alternative is to add \& at the end of the line
      result << '.ss \n[.ss] 0'
      # disable hyphenation
      result << '.nh'
      # disable justification (adjust text to left margin only)
      result << '.ad l'
      # define URL macro for portability
      # see http://web.archive.org/web/20060102165607/http://people.debian.org/~branden/talks/wtfm/wtfm.pdf
      #
      # Usage
      #
      # .URL "http://www.debian.org" "Debian" "."
      #
      # * First argument: the URL
      # * Second argument: text to be hyperlinked
      # * Third (optional) argument: text that needs to immediately trail the hyperlink without intervening whitespace
      result << '.de URL
\\fI\\\\$2\\fP <\\\\$1>\\\\$3
..
.als MTO URL
.if \n[.g] \{\
.  mso www.tmac
.  am URL
.    ad l
.  .
.  am MTO
.    ad l
.  .'
      result << %(.  LINKSTYLE #{node.attr 'man-linkstyle', 'blue R < >'})
      result << '.\}'

      unless node.noheader
        if node.attr? 'manpurpose'
          mannames = node.attr 'mannames', [manname]
          result << %(.SH "#{(node.attr 'manname-title', 'NAME').upcase}"
#{mannames.map {|n| manify n }.join ', '} \\- #{manify node.attr('manpurpose'), :whitespace => :normalize})
        end
      end

      result << node.content

      # QUESTION should NOTES come after AUTHOR(S)?
      if node.footnotes? && !(node.attr? 'nofootnotes')
        result << '.SH "NOTES"'
        result.concat(node.footnotes.map {|fn| %(#{fn.index}. #{fn.text}) })
      end

      unless (authors = node.authors).empty?
        if authors.size > 1
          result << '.SH "AUTHORS"'
          authors.each do |author|
            result << %(.sp
#{author.name})
          end
        else
          result << %(.SH "AUTHOR"
.sp
#{authors[0].name})
        end
      end

      result.join LF
    end
embedded(node) click to toggle source

NOTE embedded doesn't really make sense in the manpage backend

# File lib/asciidoctor/converter/manpage.rb, line 178
def embedded node
  result = [node.content]

  if node.footnotes? && !(node.attr? 'nofootnotes')
    result << '.SH "NOTES"'
    result.concat(node.footnotes.map {|fn| %(#{fn.index}. #{fn.text}) })
  end

  # QUESTION should we add an AUTHOR(S) section?

  result.join LF
end
example(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 274
    def example node
      result = []
      result << %(.sp
.B #{manify node.captioned_title}
.br) if node.title?
      result << %(.RS 4
#{resolve_content node}
.RE)
      result.join LF
    end
floating_title(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 285
def floating_title node
  %(.SS "#{manify node.title}")
end
image(node, name = nil)
Alias for: skip_with_warning
inline_anchor(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 606
def inline_anchor node
  target = node.target
  case node.type
  when :link
    if target.start_with? 'mailto:'
      macro = 'MTO'
      target = target.slice 7, target.length
    else
      macro = 'URL'
    end
    if (text = node.text) == target
      text = ''
    else
      text = text.gsub '"', %[#{ESC_BS}(dq]
    end
    target = target.sub '@', %[#{ESC_BS}(at] if macro == 'MTO'
    %(#{ESC_BS}c#{LF}#{ESC_FS}#{macro} "#{target}" "#{text}" )
  when :xref
    refid = (node.attr 'refid') || target
    node.text || (node.document.catalog[:ids][refid] || %([#{refid}]))
  when :ref, :bibref
    # These are anchor points, which shouldn't be visible
    ''
  else
    logger.warn %(unknown anchor type: #{node.type.inspect})
    nil
  end
end
inline_break(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 635
def inline_break node
  %(#{node.text}#{LF}#{ESC_FS}br)
end
inline_button(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 639
def inline_button node
  %(#{ESC_BS}fB[#{ESC_BS}0#{node.text}#{ESC_BS}0]#{ESC_BS}fP)
end
inline_callout(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 643
def inline_callout node
  %(#{ESC_BS}fB(#{node.text})#{ESC_BS}fP)
end
inline_footnote(node) click to toggle source

TODO supposedly groff has footnotes, but we're in search of an example

# File lib/asciidoctor/converter/manpage.rb, line 648
def inline_footnote node
  if (index = node.attr 'index')
    %([#{index}])
  elsif node.type == :xref
    %([#{node.text}])
  end
end
inline_image(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 656
def inline_image node
  (node.attr? 'link') ? %([#{node.alt}] <#{node.attr 'link'}>) : %([#{node.alt}])
end
inline_indexterm(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 660
def inline_indexterm node
  node.type == :visible ? node.text : ''
end
inline_kbd(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 664
def inline_kbd node
  if (keys = node.attr 'keys').size == 1
    keys[0]
  else
    keys.join %(#{ESC_BS}0+#{ESC_BS}0)
  end
end
inline_menu(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 672
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
    %(#{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)
  end
end
inline_quoted(node) click to toggle source

NOTE use fake <BOUNDARY> element to prevent creating artificial word boundaries

# File lib/asciidoctor/converter/manpage.rb, line 686
def inline_quoted node
  case node.type
  when :emphasis
    %(#{ESC_BS}fI<BOUNDARY>#{node.text}</BOUNDARY>#{ESC_BS}fP)
  when :strong
    %(#{ESC_BS}fB<BOUNDARY>#{node.text}</BOUNDARY>#{ESC_BS}fP)
  when :monospaced
    %[#{ESC_BS}f(CR<BOUNDARY>#{node.text}</BOUNDARY>#{ESC_BS}fP]
  when :single
    %[#{ESC_BS}(oq<BOUNDARY>#{node.text}</BOUNDARY>#{ESC_BS}(cq]
  when :double
    %[#{ESC_BS}(lq<BOUNDARY>#{node.text}</BOUNDARY>#{ESC_BS}(rq]
  else
    node.text
  end
end
listing(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 291
    def listing node
      result = []
      result << %(.sp
.B #{manify node.captioned_title}
.br) if node.title?
      result << %(.sp
.if n .RS 4
.nf
#{manify node.content, :whitespace => :preserve}
.fi
.if n .RE)
      result.join LF
    end
literal(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 305
    def literal node
      result = []
      result << %(.sp
.B #{manify node.title}
.br) if node.title?
      result << %(.sp
.if n .RS 4
.nf
#{manify node.content, :whitespace => :preserve}
.fi
.if n .RE)
      result.join LF
    end
manify(str, opts = {}) click to toggle source

Converts HTML entity references back to their original form, escapes special man characters and strips trailing whitespace.

It's crucial that text only ever pass through manify once.

str - the String to convert opts - an Hash of options to control processing (default: {})

* :whitespace an enum that indicates how to handle whitespace; supported options are:
  :preserve - preserve spaces (only expanding tabs); :normalize - normalize whitespace
  (remove spaces around newlines); :collapse - collapse adjacent whitespace to a single
  space (default: :collapse)
* :append_newline a Boolean that indicates whether to append an endline to the result (default: false)
# File lib/asciidoctor/converter/manpage.rb, line 37
def manify str, opts = {}
  case opts.fetch :whitespace, :collapse
  when :preserve
    str = str.gsub TAB, ET
  when :normalize
    str = str.gsub WrappedIndentRx, LF
  else
    str = str.tr_s WHITESPACE, ' '
  end
  str = str.
    gsub(LiteralBackslashRx, '\&(rs'). # literal backslash (not a troff escape sequence)
    gsub(LeadingPeriodRx, '\\\&.'). # leading . is used in troff for macro call or other formatting; replace with \&.
    # drop orphaned \c escape lines, unescape troff macro, quote adjacent character, isolate macro line
    gsub(EscapedMacroRx) { (rest = $3.lstrip).empty? ? %(.#$1"#$2") : %(.#$1"#$2"#{LF}#{rest}) }.
    gsub('-', '\-').
    gsub('&lt;', '<').
    gsub('&gt;', '>').
    gsub('&#160;', '\~').     # non-breaking space
    gsub('&#169;', '\(co').   # copyright sign
    gsub('&#174;', '\(rg').   # registered sign
    gsub('&#8482;', '\(tm').  # trademark sign
    gsub('&#8201;', ' ').     # thin space
    gsub('&#8211;', '\(en').  # en dash
    gsub(EmDashCharRefRx, '\(em'). # em dash
    gsub('&#8216;', '\(oq').  # left single quotation mark
    gsub('&#8217;', '\(cq').  # right single quotation mark
    gsub('&#8220;', '\(lq').  # left double quotation mark
    gsub('&#8221;', '\(rq').  # right double quotation mark
    gsub(EllipsisCharRefRx, '...'). # horizontal ellipsis
    gsub('&#8592;', '\(<-').  # leftwards arrow
    gsub('&#8594;', '\(->').  # rightwards arrow
    gsub('&#8656;', '\(lA').  # leftwards double arrow
    gsub('&#8658;', '\(rA').  # rightwards double arrow
    gsub('&#8203;', '\:').    # zero width space
    gsub('&amp;','&').        # literal ampersand (NOTE must take place after any other replacement that includes &)
    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
olist(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 319
    def olist node
      result = []
      result << %(.sp
.B #{manify node.title}
.br) if node.title?

      node.items.each_with_index do |item, idx|
        result << %(.sp
.RS 4
.ie n \\{\\
\\h'-04' #{idx + 1}.\\h'+01'\\c
.\\}
.el \\{\\
.  sp -1
.  IP " #{idx + 1}." 4.2
.\\}
#{manify item.text, :whitespace => :normalize})
        result << item.content if item.blocks?
        result << '.RE'
      end
      result.join LF
    end
open(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 342
def open node
  case node.style
  when 'abstract', 'partintro'
    resolve_content node
  else
    node.content
  end
end
paragraph(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 354
    def paragraph node
      if node.title?
        %(.sp
.B #{manify node.title}
.br
#{manify node.content, :whitespace => :normalize})
      else
        %(.sp
#{manify node.content, :whitespace => :normalize})
      end
    end
quote(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 368
    def quote node
      result = []
      if node.title?
        result << %(.sp
.RS 3
.B #{manify node.title}
.br
.RE)
      end
      attribution_line = (node.attr? 'citetitle') ? %(#{node.attr 'citetitle'} ) : nil
      attribution_line = (node.attr? 'attribution') ? %[#{attribution_line}\\(em #{node.attr 'attribution'}] : nil
      result << %(.RS 3
.ll -.6i
#{resolve_content node}
.br
.RE
.ll)
      if attribution_line
        result << %(.RS 5
.ll -.10i
#{attribution_line}
.RE
.ll)
      end
      result.join LF
    end
resolve_content(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 703
def resolve_content node
  node.content_model == :compound ? node.content : %(.sp#{LF}#{manify node.content, :whitespace => :normalize})
end
section(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 191
    def section node
      result = []
      if node.level > 1
        macro = 'SS'
        # QUESTION why captioned title? why not when level == 1?
        stitle = node.captioned_title
      else
        macro = 'SH'
        stitle = node.title.upcase
      end
      result << %(.#{macro} "#{manify stitle}"
#{node.content})
      result.join LF
    end
sidebar(node, name = nil)
Alias for: skip_with_warning
skip_with_warning(node, name = nil) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 80
def skip_with_warning node, name = nil
  logger.warn %(converter missing for #{name || node.node_name} node in manpage backend)
  nil
end
Also aliased as: audio, image, sidebar
stem(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 397
    def stem node
      title_element = node.title? ? %(.sp
.B #{manify node.title}
.br) : ''
      open, close = BLOCK_MATH_DELIMITERS[node.style.to_sym]

      unless ((equation = node.content).start_with? open) && (equation.end_with? close)
        equation = %(#{open}#{equation}#{close})
      end

      %(#{title_element}#{equation})
    end
table(node) click to toggle source

FIXME: The reason this method is so complicated is because we are not receiving empty(marked) cells when there are colspans or rowspans. This method has to create a map of all cells and in the case of rowspans create empty cells as placeholders of the span. To fix this, asciidoctor needs to provide an API to tell the user if a given cell is being used as a colspan or rowspan.

# File lib/asciidoctor/converter/manpage.rb, line 416
    def table node
      result = []
      if node.title?
        result << %(.sp
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.B #{manify node.captioned_title}
)
      end
      result << '.TS
allbox tab(:);'
      row_header = []
      row_text = []
      row_index = 0
      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
          # c centered-adjusted
          # n numerical align
          # a alphabetic align
          # s spanned
          # ^ vertically spanned
          remaining_cells = row.size
          row.each_with_index do |cell, cell_index|
            remaining_cells -= 1
            row_header[row_index][cell_index] ||= []
            # 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').chr
            if tsec == :head
              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] << %(#{manify cell.text, :whitespace => :normalize}#{LF})
            elsif tsec == :body
              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 :literal
                cell_content = %(.nf#{LF}#{manify cell.text, :whitespace => :preserve}#{LF}.fi)
              when :verse
                cell_content = %(.nf#{LF}#{manify cell.text, :whitespace => :preserve}#{LF}.fi)
              else
                cell_content = manify cell.content.join, :whitespace => :normalize
              end
              row_text[row_index] << %(#{cell_content}#{LF})
            elsif tsec == :foot
              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] << %(#{manify cell.text, :whitespace => :normalize}#{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?
                  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?
                  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'
                end
              end
            end
            if remaining_cells >= 1
              row_text[row_index] << 'T}:'
            else
              row_text[row_index] << %(T}#{LF})
            end
          end
          row_index += 1
        end unless rows.empty?
      end

      #row_header.each do |row|
      #  result << LF
      #  row.each_with_index do |cell, i|
      #    result << (cell.join ' ')
      #    result << ' ' if row.size > i + 1
      #  end
      #end
      # FIXME temporary fix to get basic table to display
      result << LF
      result << ('lt ' * row_header[0].size).chop

      result << %(.#{LF})
      row_text.each do |row|
        result << row.join
      end
      result << %(.TE#{LF}.sp)
      result.join
    end
thematic_break(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 540
    def thematic_break node
      '.sp
.ce
\l\'\n(.lu*25u/100u\(ap\''
    end
ulist(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 548
    def ulist node
      result = []
      result << %(.sp
.B #{manify node.title}
.br) if node.title?
      node.items.map {|item|
        result << %[.sp
.RS 4
.ie n \\{\\
\\h'-04'\\(bu\\h'+03'\\c
.\\}
.el \\{\\
.  sp -1
.  IP \\(bu 2.3
.\\}
#{manify item.text, :whitespace => :normalize}]
        result << item.content if item.blocks?
        result << '.RE'
      }
      result.join LF
    end
verse(node) click to toggle source

FIXME git uses [verse] for the synopsis; detect this special case

# File lib/asciidoctor/converter/manpage.rb, line 571
    def verse node
      result = []
      if node.title?
        result << %(.sp
.B #{manify node.title}
.br)
      end
      attribution_line = (node.attr? 'citetitle') ? %(#{node.attr 'citetitle'} ) : nil
      attribution_line = (node.attr? 'attribution') ? %[#{attribution_line}\\(em #{node.attr 'attribution'}] : nil
      result << %(.sp
.nf
#{manify node.content, :whitespace => :preserve}
.fi
.br)
      if attribution_line
        result << %(.in +.5i
.ll -.5i
#{attribution_line}
.in
.ll)
      end
      result.join LF
    end
video(node) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 595
    def video node
      start_param = (node.attr? 'start', nil, false) ? %(&start=#{node.attr 'start'}) : ''
      end_param = (node.attr? 'end', nil, false) ? %(&end=#{node.attr 'end'}) : ''
      result = []
      result << %(.sp
.B #{manify node.title}
.br) if node.title?
      result << %(<#{node.media_uri(node.attr 'target')}#{start_param}#{end_param}> (video))
      result.join LF
    end
write_alternate_pages(mannames, manvolnum, target) click to toggle source
# File lib/asciidoctor/converter/manpage.rb, line 707
def write_alternate_pages mannames, manvolnum, target
  if mannames && mannames.size > 1
    mannames.shift
    manvolext = %(.#{manvolnum})
    dir, basename = ::File.split target
    mannames.each do |manname|
      ::IO.write ::File.join(dir, %(#{manname}#{manvolext})), %(.so #{basename})
    end
  end
end