def highlight_source source, process_callouts, highlighter = nil
case (highlighter ||= @document.attributes['source-highlighter'])
when 'coderay'
unless (highlighter_loaded = defined? ::CodeRay) || @document.attributes['coderay-unavailable']
if (Helpers.require_library 'coderay', true, :warn).nil?
@document.set_attr 'coderay-unavailable', true
else
highlighter_loaded = true
end
end
when 'pygments'
unless (highlighter_loaded = defined? ::Pygments) || @document.attributes['pygments-unavailable']
if (Helpers.require_library 'pygments', 'pygments.rb', :warn).nil?
@document.set_attr 'pygments-unavailable', true
else
highlighter_loaded = true
end
end
else
highlighter_loaded = false
end
return sub_source source, process_callouts unless highlighter_loaded
lineno = 0
callout_on_last = false
if process_callouts
callout_marks = {}
last = -1
callout_rx = (attr? 'line-comment') ? /(?:#{::Regexp.escape(attr 'line-comment')} )?#{CalloutExtractRxt}/ : CalloutExtractRx
source = source.split(EOL).map {|line|
lineno = lineno + 1
line.gsub(callout_rx) {
m = $~
if m[1] == '\\'
m[0].sub('\\', '')
else
(callout_marks[lineno] ||= []) << m[3]
last = lineno
nil
end
}
} * EOL
callout_on_last = (last == lineno)
callout_marks = nil if callout_marks.empty?
else
callout_marks = nil
end
linenums_mode = nil
highlight_lines = nil
case highlighter
when 'coderay'
if (linenums_mode = (attr? 'linenums') ? (@document.attributes['coderay-linenums-mode'] || :table).to_sym : nil)
if attr? 'highlight', nil, false
highlight_lines = resolve_lines_to_highlight(attr 'highlight', nil, false)
end
end
result = ::CodeRay::Duo[attr('language', :text, false).to_sym, :html, {
:css => (@document.attributes['coderay-css'] || :class).to_sym,
:line_numbers => linenums_mode,
:line_number_anchors => false,
:highlight_lines => highlight_lines,
:bold_every => false}].highlight source
when 'pygments'
lexer = ::Pygments::Lexer[attr('language', nil, false)] || ::Pygments::Lexer['text']
opts = { :cssclass => 'pyhl', :classprefix => 'tok-', :nobackground => true }
unless (@document.attributes['pygments-css'] || 'class') == 'class'
opts[:noclasses] = true
opts[:style] = (@document.attributes['pygments-style'] || Stylesheets::DEFAULT_PYGMENTS_STYLE)
end
if attr? 'highlight', nil, false
unless (highlight_lines = resolve_lines_to_highlight(attr 'highlight', nil, false)).empty?
opts[:hl_lines] = highlight_lines * ' '
end
end
if attr? 'linenums'
if (opts[:linenos] = @document.attributes['pygments-linenums-mode'] || 'table') == 'table'
linenums_mode = :table
result = lexer.highlight(source, :options => opts).
sub(/<div class="pyhl">(.*)<\/div>/m, '\1').
gsub(/<pre[^>]*>(.*?)<\/pre>\s*/m, '\1')
else
result = lexer.highlight(source, :options => opts).
sub(/<div class="pyhl"><pre[^>]*>(.*?)<\/pre><\/div>/m, '\1')
end
else
opts[:nowrap] = true
result = lexer.highlight(source, :options => opts)
end
end
unless @passthroughs.empty?
result = result.gsub PASS_MATCH_HI, %(#{PASS_START}\\1#{PASS_END})
end
if process_callouts && callout_marks
lineno = 0
reached_code = linenums_mode != :table
result.split(EOL).map {|line|
unless reached_code
unless line.include?('<td class="code">')
next line
end
reached_code = true
end
lineno = lineno + 1
if (conums = callout_marks.delete(lineno))
tail = nil
if callout_on_last && callout_marks.empty?
if (pos = line.index '</pre>')
tail = line[pos..-1]
line = %(#{line[0...pos].chomp ' '} )
else
line = %(#{line.chomp ' '} )
end
end
if conums.size == 1
%(#{line}#{Inline.new(self, :callout, conums[0], :id => @document.callouts.read_next_id).convert }#{tail})
else
conums_markup = conums.map {|conum| Inline.new(self, :callout, conum, :id => @document.callouts.read_next_id).convert } * ' '
%(#{line}#{conums_markup}#{tail})
end
else
line
end
} * EOL
else
result
end
end