.. -*- rst-mode -*-

Syntax highlight with the ``listings.sty`` LaTeX package
========================================================

Convert this file with::

  ./rst2latex2e_listings.py --stylesheet=listings-options.sty test.txt test.tex


A test snippet in Python::

  """
  LaTeX2e document tree Writer 
  supporting the `lstlisting` environment for literal blocks
  """
  
  __docformat__ = 'reStructuredText'
  
  
  import docutils
  from docutils import frontend, nodes, utils, writers, languages
  
  from docutils.writers import latex2e

Noch ein Zwischenabsatz, der ein wenig lnger ist und daher eigentlich
umgebrochen werden mte. Was soll das eigentlich bedeuten?

::

    class LaTeXTranslator(latex2e.LaTeXTranslator):
        """
        This LaTeX writer has been customized to use the `lstlisting` 
        environment for literal blocks.
        """
        
        # Arguments, override in the wrapper script
        
        # Package loading and settings.
        # TODO: set in style-sheet.
        literal_block_package = "\n".join(
        [
         # default is lstlistings of the listings package
         r"\usepackage{listings}",
         # settings can be appended, e.g. 
         #     no special string spaces:
         r"\lstset{showstringspaces=false}",
         # ... line numbers:
         # r"\lstset{numbers=left, numberstyle=\tiny, stepnumber=2, numbersep=5pt}",
         # ... frames around listings:
         # r"\lstset{frame=single}
         # ... and the default language of the code blocks
         r"\lstset{language=Python}",  # our favourite
         # r"\lstset language={}",  # no syntax highlight
         # pre-load the language
         r"\lstloadlanguages{Python}" #  comma separated list of languages
        ]) + "\n"
        
        # argument to the ``\begin{}`` ``\end{}`` pair
        literal_block_environment = "lstlisting"
        # TODO: make this a command line option
        
        def __init__(self, document):
            # ae package is outdated and aeguill is exotic (in texlive)
            #
            # if self.font_encoding == '':
            #     fontenc_header = "\n".join([
            #                                 r"\usepackage{mathptmx}",
            #                                 r"\usepackage[scaled=0.92]{helvet}",
            #                                 r"\usepackage{courier}"
            #                                ])
            # TODO: how to insert this into the header?
            
            latex2e.LaTeXTranslator.__init__(self, document)
            self.head_prefix.append(self.literal_block_package)
        
        def visit_doctest_block(self, node):
            self.visit_literal_block(node)
    
        def depart_doctest_block(self, node):
            self.depart_literal_block(node)
    
        def visit_literal_block(self, node):
            """
            Render a literal-block.
    
            Literal-blocks doctree elements are used for "::"-prefixed 
            indented blocks of text, where the inline markup is not recognized,
            but are also the product of the parsed-literal directive,
            where the markup is respected.
            """
            # In both cases, we want to use a typewriter/monospaced typeface.
            # For "real" literal-blocks, we can use \verbatim, while for all
            # the others we must use the `alltt` environment.
            #
            # We can distinguish between the two kinds by the number of
            # siblings that compose this node: if it is composed by a
            # single element, it's surely either a real one or a
            # parsed-literal that does not contain any markup.
            #
            if (len(node) == 1) and isinstance(node[0], nodes.Text):
                # in case of a parsed-literal containing just a "**bold**" word:
                self.verbatim = 1
                self.body.append('\\begin{quote}\n\\begin{%s}\n' 
                                 % self.literal_block_environment)
                self.context.append('\n\\end{%s}\n\\end{quote}\n' 
                                    % self.literal_block_environment)
            else:
                self.literal_block = 1
                self.insert_none_breaking_blanks = 1
                if self.active_table.is_open():
                    # no quote inside tables, to avoid vertical space between
                    # table border and literal block.
                    # BUG: fails if normal text preceeds the literal block.
                    self.body.append('\n')
                    self.context.append('\n')
                else:
                    self.body.append('\\begin{quote}\n')
                    self.context.append('\\end{quote}\n')
                # TODO: use alltt environment
                self.body.append('{\\ttfamily \\raggedright \\noindent\n')
                # * obey..: is from julien and never worked for me (grubert).
                #   self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n')
    
    
        def depart_literal_block(self, node):
            self.verbatim = 0
            self.insert_none_breaking_blanks = 0
            self.literal_block = 0
            self.body.append(self.context.pop())


And a doctest

>>> print "hallo"
hallo

Ende.       
