Source Code Highlight Filter
============================

The AsciiDoc distribution includes a source code syntax highlight
filter (`source-highlight-filter.conf`). It uses
http://www.gnu.org/software/src-highlite/[GNU source-highlight] to
highlight HTML outputs; DocBook outputs are highlighted by toolchains
that have `programlisting` element highlight support, for example
'dblatex'.

TIP: If the source 'language' attribute has been set (using an
'AttributeEntry' or from the command-line) you don't have to specify
it in each source code block.


Examples
--------
Source code paragraphs
~~~~~~~~~~~~~~~~~~~~~~
The `source` paragraph style will highlight a paragraph of source
code. These three code paragraphs:

---------------------------------------------------------------------
[source,python]
if n < 0: print 'Hello World!'

:language: python

[source]
if n < 0: print 'Hello World!'

[source,ruby,numbered]
[true, false].cycle([0, 1, 2, 3, 4]) do |a, b|
    puts "#{a.inspect} => #{b.inspect}"
---------------------------------------------------------------------

Render this highlighted source code:

[source,python]
if n < 0: print 'Hello World!'

:language: python

[source]
if n < 0: print 'Hello World!'

[source,ruby,numbered]
[true, false].cycle([0, 1, 2, 3, 4]) do |a, b|
    puts "#{a.inspect} => #{b.inspect}"


Unnumbered source code listing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This source-highlight filtered block:

---------------------------------------------------------------------
 [source,python]
 ---------------------------------------------------------------------
 ''' A multi-line
     comment.'''
 def sub_word(mo):
     ''' Single line comment.'''
     word = mo.group('word')   # Inline comment
     if word in keywords[language]:
         return quote + word + quote
     else:
         return word
 ---------------------------------------------------------------------
---------------------------------------------------------------------

Renders this highlighted source code:

[source,python]
---------------------------------------------------------------------
''' A multi-line
    comment.'''
def sub_word(mo):
    ''' Single line comment.'''
    word = mo.group('word')     # Inline comment
    if word in keywords[language]:
        return quote + word + quote
    else:
        return word
---------------------------------------------------------------------

Numbered source code listing with callouts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This source-highlight filtered block:

---------------------------------------------------------------------
 [source,ruby,numbered]
 ---------------------------------------------------------------------
 #
 # Useful Ruby base class extensions.
 #

 class Array

   # Execute a block passing it corresponding items in
   # +self+ and +other_array+.
   # If self has less items than other_array it is repeated.

   def cycle(other_array)  # :yields: item, other_item
     other_array.each_with_index do |item, index|
       yield(self[index % self.length], item)
     end
   end

 end

 if $0 == __FILE__                                 \<1>
   # Array#cycle test
   # true => 0
   # false => 1
   # true => 2
   # false => 3
   # true => 4
   puts 'Array#cycle test'                         \<2>
   [true, false].cycle([0, 1, 2, 3, 4]) do |a, b|
     puts "#{a.inspect} => #{b.inspect}"
   end
 end
 ---------------------------------------------------------------------

 \<1> First callout.
 \<2> Second callout.

---------------------------------------------------------------------

Renders this highlighted source code:

[source,ruby,numbered]
---------------------------------------------------------------------
#
# Useful Ruby base class extensions.
#

class Array

  # Execute a block passing it corresponding items in
  # +self+ and +other_array+.
  # If self has less items than other_array it is repeated.

  def cycle(other_array)  # :yields: item, other_item
    other_array.each_with_index do |item, index|
      yield(self[index % self.length], item)
    end
  end

end

if $0 == __FILE__                                 <1>
  # Array#cycle test
  # true => 0
  # false => 1
  # true => 2
  # false => 3
  # true => 4
  puts 'Array#cycle test'                         <2>
  [true, false].cycle([0, 1, 2, 3, 4]) do |a, b|
    puts "#{a.inspect} => #{b.inspect}"
  end
end
---------------------------------------------------------------------

<1> First callout.
<2> Second callout.


Installation
------------
HTML
~~~~
If you want to syntax highlight AsciiDoc HTML outputs (`html4` and
`xhtml11` backends) you need to
install http://www.gnu.org/software/src-highlite/[GNU
source-highlight] (most distributions have this package).

DocBook
~~~~~~~
AsciiDoc encloses the source code in a DocBook 'programlisting'
element and leaves source code highlighting to the DocBook toolchain
(dblatex has a particularly nice programlisting highlighter). The
DocBook programlisting element is assigned two attributes:

. The 'language' attribute is set to the AsciiDoc 'language'
  attribute.
. The 'linenumbering' attribute is set to the AsciiDoc 'src_numbered'
  attribute ('numbered' or 'unnumbered').

Testing
~~~~~~~
Test the filter by converting the test file to HTML with AsciiDoc:

  $ asciidoc -v ./filters/source/source-highlight-filter-test.txt
  $ firefox ./filters/source/source-highlight-filter-test.html &
