Commits

Anonymous committed acb6c49

[svn] - Added option for the HTML formatter to write the CSS to an external file
in "full document" mode.

Comments (0)

Files changed (5)

 -----------
 (released Dec XX, 2006)
 
+- Added option for the HTML formatter to write the CSS to an external file
+  in "full document" mode.
+
 - Added RTF formatter.
 
 - Added Bash and Apache configuration lexers (thanks to Tim Hatch).
 
 - short cmdline options for common ``-O`` options
 
-- html formatter: full document, external css file?
-
 - improve guess_lexer heuristics (esp. for template langs)
 
 - more unit tests (pygmentize, all formatters)

docs/src/formatters.txt

     `nowrap` option.
 
     With the `full` option, a complete HTML 4 document is output, including
-    the style definitions inside a ``<style>`` tag.
+    the style definitions inside a ``<style>`` tag, or in a separate file if
+    the `cssfile` option is given.
 
     The `get_style_defs(arg='')` method of a `HtmlFormatter` returns a string
     containing CSS rules for the CSS classes used by the formatter. The
     `cssstyles`
         Inline CSS styles for the wrapping ``<div>`` tag (default: ``''``).
 
+    `cssfile`
+        If the `full` option is true and this option is given, it must be the
+        name of an external file. The stylesheet is then written to this file
+        instead of the HTML file. *New in Pygments 0.6.*
+
     `linenospecial`
         If set to a number n > 0, every nth line number is given the CSS
         class ``"special"`` (default: ``0``).
+
+    `nobackground`
+        If set to ``True``, the formatter won't output the background color
+        for the wrapping element (this automatically defaults to ``False``
+        when there is no wrapping element [eg: no argument for the
+        `get_syntax_defs` method given]) (default: ``False``). *New in
+        Pygments 0.6.*
     
     :Aliases: ``html``
     :Filename patterns: ``*.html``, ``*.htm``

pygments/__init__.py

     try:
         highlight(code, lexer, fmter, outfile)
     except Exception, err:
+        raise
         print >>sys.stderr, 'Error while highlighting:', err
         return 1
     return 0

pygments/formatters/html.py

     :copyright: 2006 by Georg Brandl, Armin Ronacher.
     :license: BSD, see LICENSE for more details.
 """
+import os
 import cStringIO
 
 from pygments.formatter import Formatter
 '''
 
 
+DOC_TEMPLATE_EXTERNALCSS = '''\
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">
+
+<html>
+<head>
+  <title>%(title)s</title>
+  <meta http-equiv="content-type" content="text/html; charset=%(encoding)s">
+  <link rel="stylesheet" href="%(cssfile)s">
+</head>
+<body>
+<h2>%(title)s</h2>
+
+%(code)s
+
+</body>
+</html>
+'''
+
+
+CSSFILE_TEMPLATE = '''\
+td.linenos { background-color: #f0f0f0; padding-right: 10px; }
+%(styledefs)s
+'''
+
+
 class HtmlFormatter(Formatter):
     """
     Output HTML <span> tags with appropriate classes.
         CSS class for the wrapping <div> (default: 'highlight').
     ``cssstyles``
         Inline CSS styles for the wrapping <div>. (default: '').
+    ``cssfile``
+        If the ``full`` option is ``True`` and this is not ``''``,
+        put the CSS in a separate file whose name is given by this option
+        (default: ''). New in 0.6.
     ``linenos``
         If set to ``True``, output line numbers (default: False).
     ``linenostart``
         If set to ``True`` the formatter won't output the background color
         for the overall element (this automatically defaults to ``False``
         when there is no overall element [eg: no argument for the
-        `get_syntax_defs` method given]) (default: ``False``)
+        `get_syntax_defs` method given]) (default: ``False``). New in 0.6.
     """
 
     def __init__(self, **options):
         self.classprefix = options.get('classprefix', '')
         self.cssclass = options.get('cssclass', 'highlight')
         self.cssstyles = options.get('cssstyles', '')
+        self.cssfile = options.get('cssfile', '')
         self.linenos = get_bool_opt(options, 'linenos', False)
         self.linenostart = abs(get_int_opt(options, 'linenostart', 1))
         self.linenostep = abs(get_int_opt(options, 'linenostep', 1))
         if self.nowrap:
             self._format_nowrap(tokensource, outfile)
             return
-
+        
         realoutfile = outfile
         lnos = self.linenos
         full = self.full
         if full:
             if not ret:
                 ret = div + outfile.getvalue() + '</div>\n'
-            realoutfile.write(DOC_TEMPLATE %
-                dict(title     = self.title,
-                     styledefs = self.get_style_defs('body'),
-                     encoding  = self.encoding,
-                     code      = ret))
+            if self.cssfile:
+                try:
+                    filename = realoutfile.name
+                    cssfilename = os.path.join(os.path.dirname(filename), self.cssfile)
+                except AttributeError:
+                    print >>sys.stderr, 'Note: Cannot determine output file name, ' \
+                          'using current directory as base for the CSS file name'
+                    cssfilename = self.cssfile
+                realoutfile.write(DOC_TEMPLATE_EXTERNALCSS %
+                                  dict(title     = self.title,
+                                       cssfile   = self.cssfile,
+                                       encoding  = self.encoding,
+                                       code      = ret))
+                try:
+                    cf = open(cssfilename, "w")
+                    cf.write(CSSFILE_TEMPLATE % dict(styledefs=self.get_style_defs('body')))
+                    cf.close()
+                except IOError, err:
+                    err.strerror = 'Error writing CSS file: ' + err.strerror
+                    raise
+            else:
+                realoutfile.write(DOC_TEMPLATE %
+                                  dict(title     = self.title,
+                                       styledefs = self.get_style_defs('body'),
+                                       encoding  = self.encoding,
+                                       code      = ret))
         elif lnos:
             realoutfile.write(ret + '</div>\n')
         else: