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 = /—(?:​)?/
EllipsisCharRefRx = /…(?:​)?/
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('<', '<').
- gsub('>', '>').
- gsub(' ', '\~'). # non-breaking space
- gsub('©', '\(co'). # copyright sign
- gsub('®', '\(rg'). # registered sign
- gsub('™', '\(tm'). # trademark sign
- gsub(' ', ' '). # thin space
- gsub('–', '\(en'). # en dash
- gsub(EmDashCharRefRx, '\(em'). # em dash
- gsub('‘', '\(oq'). # left single quotation mark
- gsub('’', '\(cq'). # right single quotation mark
- gsub('“', '\(lq'). # left double quotation mark
- gsub('”', '\(rq'). # right double quotation mark
- gsub('←', '\(<-'). # leftwards arrow
- gsub('→', '\(->'). # rightwards arrow
- gsub('⇐', '\(lA'). # leftwards double arrow
- gsub('⇒', '\(rA'). # rightwards double arrow
- gsub('​', '\:'). # zero width space
- gsub('&', '&'). # 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('<', '<')
+ .gsub('>', '>')
+ .gsub('+', '+') # plus sign; alternately could use \c(pl
+ .gsub(' ', '\~') # non-breaking space
+ .gsub('©', '\(co') # copyright sign
+ .gsub('®', '\(rg') # registered sign
+ .gsub('™', '\(tm') # trademark sign
+ .gsub('°', '\(de') # degree sign
+ .gsub(' ', ' ') # thin space
+ .gsub('–', '\(en') # en dash
+ .gsub(EmDashCharRefRx, '\(em') # em dash
+ .gsub('‘', '\(oq') # left single quotation mark
+ .gsub('’', '\(cq') # right single quotation mark
+ .gsub('“', '\(lq') # left double quotation mark
+ .gsub('”', '\(rq') # right double quotation mark
+ .gsub('←', '\(<-') # leftwards arrow
+ .gsub('→', '\(->') # rightwards arrow
+ .gsub('⇐', '\(lA') # leftwards double arrow
+ .gsub('⇒', '\(rA') # rightwards double arrow
+ .gsub('​', '\:') # zero width space
+ .gsub('&', '&') # 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