lib/asciidoctor/converter/manpage.rb in asciidoctor-2.0.15 vs lib/asciidoctor/converter/manpage.rb in asciidoctor-2.0.16

- old
+ new

@@ -21,11 +21,11 @@ LiteralBackslashRx = /\A\\|(#{ESC})?\\/ LeadingPeriodRx = /^\./ EscapedMacroRx = /^(?:#{ESC}\\c\n)?#{ESC}\.((?:URL|MTO) "#{CC_ANY}*?" "#{CC_ANY}*?" )( |[^\s]*)(#{CC_ANY}*?)(?: *#{ESC}\\c)?$/ MalformedEscapedMacroRx = /(#{ESC}\\c) (#{ESC}\.(?:URL|MTO) )/ - MockMacroRx = /<\/?(#{ESC}\\[^>]+)>/ + MockMacroRx = %r(</?(#{ESC}\\[^>]+)>) EmDashCharRefRx = /&#8212;(?:&#8203;)?/ EllipsisCharRefRx = /&#8230;(?:&#8203;)?/ WrappedIndentRx = /#{CG_BLANK}*#{LF}#{CG_BLANK}*/ XMLMarkupRx = /&#?[a-z\d]+;|</ PCDATAFilterRx = /(&#?[a-z\d]+;|<[^>]+>)|([^&<]+)/ @@ -417,20 +417,12 @@ 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 tsec == :body 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 @@ -441,11 +433,11 @@ 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 + else # tsec == :head || 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) @@ -585,12 +577,20 @@ end target = target.sub '@', %[#{ESC_BS}(at] if macro == 'MTO' %(#{ESC_BS}c#{LF}#{ESC_FS}#{macro} "#{target}" "#{text}" ) when :xref unless (text = node.text) - refid = node.attributes['refid'] - text = %([#{refid}]) unless AbstractNode === (ref = (@refs ||= node.document.catalog[:refs])[refid]) && (@resolving_xref ||= outer = true) && outer && (text = ref.xreftext node.attr 'xrefstyle', nil, true) + if AbstractNode === (ref = (@refs ||= node.document.catalog[:refs])[refid = node.attributes['refid']] || (refid.nil_or_empty? ? (top = get_root_document node) : nil)) + if (@resolving_xref ||= (outer = true)) && outer && (text = ref.xreftext node.attr 'xrefstyle', nil, true) + text = uppercase_pcdata text if ref.context === :section && ref.level < 2 && text == ref.title + else + text = top ? '[^top]' : %([#{refid}]) + end + @resolving_xref = nil if outer + else + text = %([#{refid}]) + end end text when :ref, :bibref # These are anchor points, which shouldn't be visible '' @@ -662,26 +662,25 @@ node.text end end def self.write_alternate_pages mannames, manvolnum, target - if mannames && mannames.size > 1 - mannames.shift - manvolext = %(.#{manvolnum}) - dir, basename = ::File.split target - mannames.each do |manname| - ::File.write ::File.join(dir, %(#{manname}#{manvolext})), %(.so #{basename}), mode: FILE_WRITE_MODE - end + return unless mannames && mannames.size > 1 + mannames.shift + manvolext = %(.#{manvolnum}) + dir, basename = ::File.split target + mannames.each do |manname| + ::File.write ::File.join(dir, %(#{manname}#{manvolext})), %(.so #{basename}), mode: FILE_WRITE_MODE end end private def append_footnotes result, node if node.footnotes? && !(node.attr? 'nofootnotes') result << '.SH "NOTES"' - node.footnotes.each_with_index do |fn, idx| + node.footnotes.each do |fn| result << %(.IP [#{fn.index}]) # NOTE restore newline in escaped macro that gets removed by normalize_text in substitutor if (text = fn.text).include? %(#{ESC}\\c #{ESC}.) text = (manify %(#{text.gsub MalformedEscapedMacroRx, %(\\1#{LF}\\2)} ), whitespace: :normalize).chomp ' ' else @@ -711,48 +710,58 @@ when :normalize str = str.gsub WrappedIndentRx, LF else str = str.tr_s WHITESPACE, ' ' end - str = str. - gsub(LiteralBackslashRx) { $1 ? $& : '\\(rs' }. # literal backslash (not a troff escape sequence) - gsub(EllipsisCharRefRx, '...'). # horizontal ellipsis - 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.rstrip}"#{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('&#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(MockMacroRx, '\1'). # 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 + str = str + .gsub(LiteralBackslashRx) { $1 ? $& : '\\(rs' } # literal backslash (not a troff escape sequence) + .gsub(EllipsisCharRefRx, '...') # horizontal ellipsis + .gsub(LeadingPeriodRx, '\\\&.') # leading . is used in troff for macro call or other formatting; replace with \&. + .gsub(EscapedMacroRx) do # drop orphaned \c escape lines, unescape troff macro, quote adjacent character, isolate macro line + (rest = $3.lstrip).empty? ? %(.#{$1}"#{$2}") : %(.#{$1}"#{$2.rstrip}"#{LF}#{rest}) + end + .gsub('-', '\-') + .gsub('&lt;', '<') + .gsub('&gt;', '>') + .gsub('&#43;', '+') # plus sign; alternately could use \c(pl + .gsub('&#160;', '\~') # non-breaking space + .gsub('&#169;', '\(co') # copyright sign + .gsub('&#174;', '\(rg') # registered sign + .gsub('&#8482;', '\(tm') # trademark sign + .gsub('&#176;', '\(de') # degree 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('&#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 / neutral single quote + .gsub(MockMacroRx, '\1') # 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 uppercase_pcdata string (XMLMarkupRx.match? string) ? string.gsub(PCDATAFilterRx) { $2 ? $2.upcase : $1 } : string.upcase end def enclose_content node node.content_model == :compound ? node.content : %(.sp#{LF}#{manify node.content, whitespace: :normalize}) + end + + def get_root_document node + while (node = node.document).nested? + node = node.parent_document + end + node end end end