From 5742a7850bc59d4e9e5a47a06c90b2321c389c63 Mon Sep 17 00:00:00 2001 From: gbrandl Date: Wed, 14 Feb 2007 20:16:23 +0100 Subject: [svn] Add a first version of the Moin parser. --- TODO | 16 ++------ external/moin-parser.py | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/test_cmdline.py | 10 ++++- 3 files changed, 114 insertions(+), 14 deletions(-) create mode 100644 external/moin-parser.py diff --git a/TODO b/TODO index 496e7f48..c1d6396a 100644 --- a/TODO +++ b/TODO @@ -1,16 +1,8 @@ Todo ==== -for 0.7 -------- - -- a MoinMoin parser - -- more unit tests (test pygmentize, test all formatters comprehensively) - - -new lexers ----------- +suggested new lexers +-------------------- * Haskell * Lisp @@ -33,8 +25,8 @@ for 0.8 -- 1.0 backtrack to death... * add support for function name highlighting to C++ lexer -- add folding? would require more language-aware parsers... - - allow "overlay" token types to highlight specials: nth line, a word etc. - pygmentize option presets, more sophisticated method to output styles? + +- add folding? would require more language-aware parsers... diff --git a/external/moin-parser.py b/external/moin-parser.py new file mode 100644 index 00000000..5d00be83 --- /dev/null +++ b/external/moin-parser.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +""" + The Pygments MoinMoin Parser + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This is a MoinMoin parser plugin that renders source code + to HTML via Pygments. + + To use it, put it in the data/plugin/parser subdirectory of + your Moin instance, and give it the name that the parser directive + should have. For example, if you name the file ``code.py``, you + can get a highlighted Python code sample with this Wiki markup:: + + {{{ + #!code python + [...] + }}} + + Additionally, if you set ATTACHMENTS below to True, Pygments will + also be called for all attachments for whose filenames there is no other + parser registered. + + You are responsible for including CSS rules that will map the Pygments + CSS classes to colors. You can output a stylesheet file with `pygmentize`, + put it into the `htdocs` directory of your Moin instance and then include + it in the `stylesheets` configuration option in the Moin config, e.g.:: + + stylesheets = [('screen', '/htdocs/pygments.css')] + + If you do not want to do that and are willing to accept slightly larger + HTML output, you can set the INLINESTYLES option below to True. + + :copyright: 2007 by Georg Brandl. + :license: BSD, see LICENSE for more details. +""" + +# Options +# ~~~~~~~ + +# Set to True if you want to highlight attachments, in addition to +# {{{ }}} blocks. +ATTACHMENTS = True + +# Set to False if you don't want to have line numbers in the output. +LINENOS = True + +# Set to True if you want inline CSS styles instead of classes +INLINESTYLES = False + + +import sys + +from pygments import highlight +from pygments.util import ObjectNotFound +from pygments.lexers import get_lexer_by_name, get_lexer_for_filename, TextLexer +from pygments.formatters import HtmlFormatter + +formatter = HtmlFormatter(linenos=LINENOS, noclasses=INLINESTYLES) +textlexer = TextLexer() + + +class Parser: + """ + MoinMoin Pygments parser. + """ + if ATTACHMENTS: + extensions = '*' + else: + extensions = [] + + Dependencies = [] + + def __init__(self, raw, request, **kw): + self.raw = raw + self.req = request + if "format_args" in kw: + # called from a {{{ }}} block + try: + self.lexer = get_lexer_by_name(kw['format_args'].strip()) + except ObjectNotFound: + self.lexer = textlexer + return + if "filename" in kw: + # called for an attachment + filename = kw['filename'] + else: + # called for an attachment by an older moin + # HACK: find out the filename by peeking into the execution + # frame which might not always work + try: + frame = sys._getframe(1) + filename = frame.f_locals['filename'] + except: + filename = 'x.txt' + try: + self.lexer = get_lexer_for_filename(filename) + except ObjectNotFound: + self.lexer = textlexer + + def format(self, formatter): + self.req.write( + formatter.rawHTML(highlight(self.raw, self.lexer, formatter))) diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index 89048db9..d38628e2 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -44,7 +44,7 @@ class CmdLineTest(unittest.TestCase): def test_O_opt(self): filename = os.path.join(testdir, testfile) - c, o, e = run_cmdline("-Ofull=1,linenos=true", "-fhtml", filename) + c, o, e = run_cmdline("-Ofull=1,linenos=true,foo=bar", "-fhtml", filename) self.assertEquals(c, 0) self.assert_("