class CodeRay::Encoders::HTML

Default: false
or :debug (via inspect).
Can be :info (show token kind on mouse-over), :info_long (with full path)
Include some information into the output using the title attribute.
=== :hint
Default: nil
in combination with :line_numbers.
Bolding is deactivated when :highlight_lines is set. It only makes sense
Can be any Enumerable, typically just an Array or Range, of numbers.
Highlights certain line numbers.
=== :highlight_lines
Default: 10
Make every n-th number appear bold.
=== :bold_every
Default: 1
Where to start with line number counting.
=== :line_number_start
Default: true, default prefix name: “line”
The prefix must consist only of letters, digits, and underscores.
or a prefix string that will be prepended to the anchor name.
Adds anchors and links to the line numbers. Can be false (off), true (on),
=== :line_number_anchors
Default: nil
Include line numbers in :table, :inline, or nil (no line numbers)
=== :line_numbers
Default: ‘CodeRay output’
The title of the HTML page (works only when :wrap is set to :page.)
=== :title
Default: nil
You can also use Encoders::Div and Encoders::Span.
Wrap in :page, :div, :span or nil.
=== :wrap
Default: :class
How to include the styles; can be :class or :style.
=== :css
Default: 8
Convert t characters to n spaces (a number.)
=== :tab_width
== Options
)
:css => :style
:line_numbers => :inline,
:wrap => nil,
puts CodeRay.scan(‘Some code’, :ruby).html(
puts CodeRay.scan(‘Some /code/’, :ruby).span #-> the same
#-> <span class=“CodeRay”><span class=“co”>Some</span> /code/</span>
puts CodeRay.scan(‘Some /code/’, :ruby).html(:wrap => :span)
puts CodeRay.scan(‘Some /code/’, :ruby).html #-> a HTML page
require ‘coderay’
== Usage
It provides save, fast XHTML generation and CSS support.
This is CodeRay’s most important highlighter:
= HTML Encoder

def self.token_path_to_hint hint, kinds

+hint+ may be :info, :info_long or :debug.

Generate a hint about the given +kinds+ in a +hint+ style.
def self.token_path_to_hint hint, kinds
  kinds = Array kinds
  title =
    case hint
    when :info
      kinds = kinds[1..-1] if TRANSPARENT_TOKEN_KINDS.include? kinds.first
      TOKEN_KIND_TO_INFO[kinds.first]
    when :info_long
      kinds.reverse.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/')
    when :debug
      kinds.inspect
    end
  title ? " title=\"#{title}\"" : ''
end

def begin_group kind

token groups, eg. strings
def begin_group kind
  @out << (@span_for_kind[@last_opened ? [kind, *@opened] : kind] || '<span>')
  @opened << kind
  @last_opened = kind if @set_last_opened
end

def begin_line kind

whole lines to be highlighted, eg. a deleted line in a diff
def begin_line kind
  if style = @span_for_kind[@last_opened ? [kind, *@opened] : kind]
    if style['class="']
      @out << style.sub('class="', 'class="line ')
    else
      @out << style.sub('>', ' class="line">')
    end
  else
    @out << '<span class="line">'
  end
  @opened << kind
  @last_opened = kind if @options[:css] == :style
end

def end_group kind

def end_group kind
  if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind)
    warn 'Malformed token stream: Trying to close a token (%p) ' \
      'that is not open. Open are: %p.' % [kind, @opened[1..-1]]
  end
  if @opened.pop
    @out << '</span>'
    @last_opened = @opened.last if @last_opened
  end
end

def end_line kind

def end_line kind
  if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind)
    warn 'Malformed token stream: Trying to close a line (%p) ' \
      'that is not open. Open are: %p.' % [kind, @opened[1..-1]]
  end
  if @opened.pop
    @out << '</span>'
    @last_opened = @opened.last if @last_opened
  end
end

def finish options

def finish options
  unless @opened.empty?
    warn '%d tokens still open: %p' % [@opened.size, @opened] if $CODERAY_DEBUG
    @out << '</span>' while @opened.pop
    @last_opened = nil
  end
  
  @out.extend Output
  @out.css = @css
  if options[:line_numbers]
    Numbering.number! @out, options[:line_numbers], options
  end
  @out.wrap! options[:wrap]
  @out.apply_title! options[:title]
  
  if defined?(@real_out) && @real_out
    @real_out << @out
    @out = @real_out
  end
  
  super
end

def setup options

def setup options
  super
  
  if options[:wrap] || options[:line_numbers]
    @real_out = @out
    @out = ''
  end
  
  @HTML_ESCAPE = HTML_ESCAPE.dup
  @HTML_ESCAPE["\t"] = ' ' * options[:tab_width]
  
  @opened = []
  @last_opened = nil
  @css = CSS.new options[:style]
  
  hint = options[:hint]
  if hint && ![:debug, :info, :info_long].include?(hint)
    raise ArgumentError, "Unknown value %p for :hint; \
      expected :info, :info_long, :debug, false, or nil." % hint
  end
  
  css_classes = TokenKinds
  case options[:css]
  when :class
    @span_for_kind = Hash.new do |h, k|
      if k.is_a? ::Symbol
        kind = k_dup = k
      else
        kind = k.first
        k_dup = k.dup
      end
      if kind != :space && (hint || css_class = css_classes[kind])
        title = HTML.token_path_to_hint hint, k if hint
        css_class ||= css_classes[kind]
        h[k_dup] = "<span#{title}#{" class=\"#{css_class}\"" if css_class}>"
      else
        h[k_dup] = nil
      end
    end
  when :style
    @span_for_kind = Hash.new do |h, k|
      kind = k.is_a?(Symbol) ? k : k.first
      h[k.is_a?(Symbol) ? k : k.dup] =
        if kind != :space && (hint || css_classes[kind])
          title = HTML.token_path_to_hint hint, k if hint
          style = @css.get_style Array(k).map { |c| css_classes[c] }
          "<span#{title}#{" style=\"#{style}\"" if style}>"
        end
    end
  else
    raise ArgumentError, "Unknown value %p for :css." % options[:css]
  end
  
  @set_last_opened = options[:hint] || options[:css] == :style
end

def text_token text, kind

def text_token text, kind
  if text =~ /#{HTML_ESCAPE_PATTERN}/o
    text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] }
  end
  if style = @span_for_kind[@last_opened ? [kind, *@opened] : kind]
    @out << style << text << '</span>'
  else
    @out << text
  end
end