[Checkins] SVN: zwiki/trunk/s `code-block` directive support added by:

Darryl Cousins darryl at darrylcousins.net.nz
Fri Aug 24 08:17:41 EDT 2007


Log message for revision 79228:
  `code-block` directive support added by:
  
  * including Pygments in setup.py
  * registration of the directive in file
  * pygments_code_block_directive.py
  * addition of pygments_default.css to the `wiki` skin
  
  TODO: fix browser test for the directive
  

Changed:
  U   zwiki/trunk/setup.py
  U   zwiki/trunk/src/zwiki/CHANGES.txt
  U   zwiki/trunk/src/zwiki/__init__.py
  U   zwiki/trunk/src/zwiki/browser/browser.txt
  U   zwiki/trunk/src/zwiki/browser/skin/configure.zcml
  A   zwiki/trunk/src/zwiki/browser/skin/pygments-default.css
  U   zwiki/trunk/src/zwiki/browser/skin/template.pt
  A   zwiki/trunk/src/zwiki/pygments_code_block_directive.py

-=-
Modified: zwiki/trunk/setup.py
===================================================================
--- zwiki/trunk/setup.py	2007-08-24 12:02:43 UTC (rev 79227)
+++ zwiki/trunk/setup.py	2007-08-24 12:17:40 UTC (rev 79228)
@@ -50,6 +50,7 @@
                           'zope.app.zptpage',
                           'zope.app.skins',
                           'zope.app.renderer',
+                          'Pygments',
                           ],
       extras_require = dict(test=['zope.app.testing',
                                   'zope.testbrowser',

Modified: zwiki/trunk/src/zwiki/CHANGES.txt
===================================================================
--- zwiki/trunk/src/zwiki/CHANGES.txt	2007-08-24 12:02:43 UTC (rev 79227)
+++ zwiki/trunk/src/zwiki/CHANGES.txt	2007-08-24 12:17:40 UTC (rev 79228)
@@ -1,5 +1,15 @@
 CHANGES
 
+  2007-08-24: darrylcousins
+
+    - `code-block` directive support added by:
+    
+     * including Pygments in setup.py
+     * registration of the directive in file pygments_code_block_directive.py
+     * addition of pygments_default.css to the `wiki` skin
+
+    - TODO: fix browser test for the directive
+
   Version 0.2.5
 
     - Added translations.

Modified: zwiki/trunk/src/zwiki/__init__.py
===================================================================
--- zwiki/trunk/src/zwiki/__init__.py	2007-08-24 12:02:43 UTC (rev 79227)
+++ zwiki/trunk/src/zwiki/__init__.py	2007-08-24 12:17:40 UTC (rev 79228)
@@ -15,3 +15,11 @@
 
 $Id$
 """
+
+# registers code-block directive using pygments.
+import pygments_code_block_directive
+
+# this registration will probably be unecessary when docutils itself
+# supports the code-block directive.
+
+# a stylesheet has been included in the `wiki` skin.

Modified: zwiki/trunk/src/zwiki/browser/browser.txt
===================================================================
--- zwiki/trunk/src/zwiki/browser/browser.txt	2007-08-24 12:02:43 UTC (rev 79227)
+++ zwiki/trunk/src/zwiki/browser/browser.txt	2007-08-24 12:17:40 UTC (rev 79228)
@@ -54,3 +54,24 @@
   ...
         Cyrillic text: Тест
   ...
+  
+Code-block directive
+--------------------
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+  >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+  >>> browser.handleErrors = False
+  >>> browser.open("http://localhost/wiki/FrontPage/@@edit.html")
+  >>> browser.getControl(name='field.type').displayValue = ['ReStructured Text (ReST)']
+  >>> browser.getControl(name='field.source').value = " \
+  ... \n\n..code-block:: python\
+  ... \n\n\tclass Test(object):\
+  ... \n\t\tdef test(self):\
+  ... \n\t\t\ta=3\
+  ... \n\n\n"
+  >>> browser.getControl('Change').click()
+  >>> browser.open("http://localhost/wiki/FrontPage/@@edit.html")
+
+This isn't working right now in the test. But doesn't cause errors. ;-)
+

Modified: zwiki/trunk/src/zwiki/browser/skin/configure.zcml
===================================================================
--- zwiki/trunk/src/zwiki/browser/skin/configure.zcml	2007-08-24 12:02:43 UTC (rev 79227)
+++ zwiki/trunk/src/zwiki/browser/skin/configure.zcml	2007-08-24 12:17:40 UTC (rev 79228)
@@ -20,6 +20,9 @@
 <browser:resource
     name="wiki.css" file="wiki.css" layer="wiki" />
 
+<browser:resource
+    name="pygments-default.css" file="pygments-default.css" layer="wiki" />
+
 <browser:page
     for="*"
     name="skin_macros"

Added: zwiki/trunk/src/zwiki/browser/skin/pygments-default.css
===================================================================
--- zwiki/trunk/src/zwiki/browser/skin/pygments-default.css	                        (rev 0)
+++ zwiki/trunk/src/zwiki/browser/skin/pygments-default.css	2007-08-24 12:17:40 UTC (rev 79228)
@@ -0,0 +1,96 @@
+/* Stylesheet for pygments enhanced reStructured Text */
+/* ================================================== */
+
+/* :Author:    Guenter Milde */
+/* :Copyright: 2007 G. Milde */
+/*             This stylesheet is released under the GPL v. 2 or later */
+
+/* This stylesheet provides syntax highlight for documents generated with a */
+/* pygments_ enhanced reStructured Text -> html converter. */
+
+/* Import the default docutils style sheet */
+/* --------------------------------------- */
+/* :: */
+
+/* @import url("/stylesheets/html4css1.css");  */
+/* Disabled, for Zwiki comes with it's own styles. */
+
+/* Indent the code block */
+/* --------------------- */
+
+/* Content copied from the `html4css1.css` rule for literal blocks. */
+/* Selector adapted to the output of Pygments_. :: */
+
+div.highlight {
+  margin-left: 2em ;
+  margin-right: 2em ;
+  background-color: #eeeeee
+  }
+
+
+/* Colour code blocks */
+/* ------------------ */
+
+/* Pygments_ has an option to generate stylesheets for html and latex. */
+/* The following code is generated with the command */
+/* `pygmentize -S default -f html > pygments-default.css`:: */
+
+.c { color: #008800; font-style: italic } /* Comment */
+.err { border: 1px solid #FF0000 } /* Error */
+.k { color: #AA22FF; font-weight: bold } /* Keyword */
+.o { color: #666666 } /* Operator */
+.cm { color: #008800; font-style: italic } /* Comment.Multiline */
+.cp { color: #008800 } /* Comment.Preproc */
+.c1 { color: #008800; font-style: italic } /* Comment.Single */
+.gd { color: #A00000 } /* Generic.Deleted */
+.ge { font-style: italic } /* Generic.Emph */
+.gr { color: #FF0000 } /* Generic.Error */
+.gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.gi { color: #00A000 } /* Generic.Inserted */
+.go { color: #808080 } /* Generic.Output */
+.gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.gs { font-weight: bold } /* Generic.Strong */
+.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.gt { color: #0040D0 } /* Generic.Traceback */
+.kc { color: #AA22FF; font-weight: bold } /* Keyword.Constant */
+.kd { color: #AA22FF; font-weight: bold } /* Keyword.Declaration */
+.kp { color: #AA22FF } /* Keyword.Pseudo */
+.kr { color: #AA22FF; font-weight: bold } /* Keyword.Reserved */
+.kt { color: #AA22FF; font-weight: bold } /* Keyword.Type */
+.m { color: #666666 } /* Literal.Number */
+.s { color: #BB4444 } /* Literal.String */
+.na { color: #BB4444 } /* Name.Attribute */
+.nb { color: #AA22FF } /* Name.Builtin */
+.nc { color: #0000FF } /* Name.Class */
+.no { color: #880000 } /* Name.Constant */
+.nd { color: #AA22FF } /* Name.Decorator */
+.ni { color: #999999; font-weight: bold } /* Name.Entity */
+.ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.nf { color: #00A000 } /* Name.Function */
+.nl { color: #A0A000 } /* Name.Label */
+.nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.nt { color: #008000; font-weight: bold } /* Name.Tag */
+.nv { color: #B8860B } /* Name.Variable */
+.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.mf { color: #666666 } /* Literal.Number.Float */
+.mh { color: #666666 } /* Literal.Number.Hex */
+.mi { color: #666666 } /* Literal.Number.Integer */
+.mo { color: #666666 } /* Literal.Number.Oct */
+.sb { color: #BB4444 } /* Literal.String.Backtick */
+.sc { color: #BB4444 } /* Literal.String.Char */
+.sd { color: #BB4444; font-style: italic } /* Literal.String.Doc */
+.s2 { color: #BB4444 } /* Literal.String.Double */
+.se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.sh { color: #BB4444 } /* Literal.String.Heredoc */
+.si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.sx { color: #008000 } /* Literal.String.Other */
+.sr { color: #BB6688 } /* Literal.String.Regex */
+.s1 { color: #BB4444 } /* Literal.String.Single */
+.ss { color: #B8860B } /* Literal.String.Symbol */
+.bp { color: #AA22FF } /* Name.Builtin.Pseudo */
+.vc { color: #B8860B } /* Name.Variable.Class */
+.vg { color: #B8860B } /* Name.Variable.Global */
+.vi { color: #B8860B } /* Name.Variable.Instance */
+.il { color: #666666 } /* Literal.Number.Integer.Long */
+
+/* .. _pygments:  http://pygments.org/ */

Modified: zwiki/trunk/src/zwiki/browser/skin/template.pt
===================================================================
--- zwiki/trunk/src/zwiki/browser/skin/template.pt	2007-08-24 12:02:43 UTC (rev 79227)
+++ zwiki/trunk/src/zwiki/browser/skin/template.pt	2007-08-24 12:17:40 UTC (rev 79228)
@@ -16,6 +16,11 @@
       @import url(wiki.css);
     </style>
         
+    <style type="text/css" media="all"
+       tal:content="string: @import url(${context/++resource++pygments-default.css});">
+      @import url(pygments-default.css);
+    </style>
+        
     <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 
     <link rel="icon" type="image/png"

Added: zwiki/trunk/src/zwiki/pygments_code_block_directive.py
===================================================================
--- zwiki/trunk/src/zwiki/pygments_code_block_directive.py	                        (rev 0)
+++ zwiki/trunk/src/zwiki/pygments_code_block_directive.py	2007-08-24 12:17:40 UTC (rev 79228)
@@ -0,0 +1,177 @@
+#!/usr/bin/python
+
+# :Author: a Pygments author|contributor; Felix Wiemann; Guenter Milde
+# :Date: $Date: 2007-06-13 22:20:42 +1200 (Wed, 13 Jun 2007) $
+# :Copyright: This module has been placed in the public domain.
+# 
+# This is a merge of `Using Pygments in ReST documents`_ from the pygments_
+# documentation, and a `proof of concept`_ by Felix Wiemann.
+# 
+# ========== ===========================================================
+# 2007-06-01 Removed redundancy from class values.
+# 2007-06-04 Merge of successive tokens of same type
+#            (code taken from pygments.formatters.others).
+# 2007-06-05 Separate docutils formatter script
+#            Use pygments' CSS class names (like the html formatter)
+#            allowing the use of pygments-produced style sheets.
+# 2007-06-07 Merge in the formatting of the parsed tokens
+#            (misnamed as docutils_formatter) as class DocutilsInterface
+# 2007-06-08 Failsave implementation (fallback to a standard literal block 
+#            if pygments not found)
+# ========== ===========================================================
+# 
+# ::
+
+"""Define and register a code-block directive using pygments
+"""
+
+# Requirements
+# ------------
+# ::
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+try:
+    import pygments
+    from pygments.lexers import get_lexer_by_name
+    from pygments.formatters.html import _get_ttype_class
+except ImportError:
+    pass
+
+
+# Customisation
+# -------------
+# 
+# Do not insert inline nodes for the following tokens.
+# (You could add e.g. Token.Punctuation like ``['', 'p']``.) ::
+
+unstyled_tokens = ['']
+
+# DocutilsInterface
+# -----------------
+# 
+# This interface class combines code from
+# pygments.formatters.html and pygments.formatters.others.
+# 
+# It does not require anything of docutils and could also become a part of
+# pygments::
+
+class DocutilsInterface(object):
+    """Parse `code` string and yield "classified" tokens.
+    
+    Arguments
+    
+      code     -- string of source code to parse
+      language -- formal language the code is written in.
+    
+    Merge subsequent tokens of the same token-type. 
+    
+    Yields the tokens as ``(ttype_class, value)`` tuples, 
+    where ttype_class is taken from pygments.token.STANDARD_TYPES and 
+    corresponds to the class argument used in pygments html output.
+
+    """
+
+    def __init__(self, code, language):
+        self.code = code
+        self.language = language
+        
+    def lex(self):
+        # Get lexer for language (use text as fallback)
+        try:
+            lexer = get_lexer_by_name(self.language)
+        except ValueError:
+            # info: "no pygments lexer for %s, using 'text'"%self.language
+            lexer = get_lexer_by_name('text')
+        return pygments.lex(self.code, lexer)
+        
+            
+    def join(self, tokens):
+        """join subsequent tokens of same token-type
+        """
+        tokens = iter(tokens)
+        (lasttype, lastval) = tokens.next()
+        for ttype, value in tokens:
+            if ttype is lasttype:
+                lastval += value
+            else:
+                yield(lasttype, lastval)
+                (lasttype, lastval) = (ttype, value)
+        yield(lasttype, lastval)
+
+    def __iter__(self):
+        """parse code string and yield "clasified" tokens
+        """
+        try:
+            tokens = self.lex()
+        except IOError:
+            print "INFO: Pygments lexer not found, using fallback"
+            # TODO: write message to INFO 
+            yield ('', self.code)
+            return
+
+        for ttype, value in self.join(tokens):
+            yield (_get_ttype_class(ttype), value)
+
+
+
+# code_block_directive
+# --------------------
+# ::
+
+def code_block_directive(name, arguments, options, content, lineno,
+                       content_offset, block_text, state, state_machine):
+    """parse and classify content of a code_block
+    """
+    language = arguments[0]
+    # create a literal block element and set class argument
+    code_block = nodes.literal_block(classes=["code-block", language])
+    
+    # parse content with pygments and add to code_block element
+    for cls, value in DocutilsInterface(u'\n'.join(content), language):
+        if cls in unstyled_tokens:
+            # insert as Text to decrease the verbosity of the output.
+            code_block += nodes.Text(value, value)
+        else:
+            code_block += nodes.inline(value, value, classes=[cls])
+
+    return [code_block]
+
+
+# Register Directive
+# ------------------
+# ::
+
+code_block_directive.arguments = (1, 0, 1)
+code_block_directive.content = 1
+directives.register_directive('code-block', code_block_directive)
+
+# .. _doctutils: http://docutils.sf.net/
+# .. _pygments: http://pygments.org/
+# .. _Using Pygments in ReST documents: http://pygments.org/docs/rstdirective/
+# .. _proof of concept:
+#      http://article.gmane.org/gmane.text.docutils.user/3689
+# 
+# Test output
+# -----------
+# 
+# If called from the command line, call the docutils publisher to render the
+# input::
+
+if __name__ == '__main__':
+    from docutils.core import publish_cmdline, default_description
+    description = "code-block directive test output" + default_description
+    try:
+        import locale
+        locale.setlocale(locale.LC_ALL, '')
+    except:
+        pass
+    # Uncomment the desired output format:
+    publish_cmdline(writer_name='pseudoxml', description=description)
+    # publish_cmdline(writer_name='xml', description=description)
+    # publish_cmdline(writer_name='html', description=description)
+    # publish_cmdline(writer_name='latex', description=description)
+    # publish_cmdline(writer_name='newlatex2e', description=description)
+    
+
+


Property changes on: zwiki/trunk/src/zwiki/pygments_code_block_directive.py
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + Id



More information about the Checkins mailing list