diff --git a/wiki/README.txt b/wiki/README.txt index 08c0539..4313bc8 100644 --- a/wiki/README.txt +++ b/wiki/README.txt @@ -26,33 +26,11 @@ We format the content of the start page using the restructured text format. The parser for restructured text and a corresponding HTML writer are the default plugins used, so we can already render the page as HTML. - >>> tree = startPage.parse() - >>> print startPage.render() + visiting document + visiting paragraph + visiting strong + visiting #text
Welcome to the Demo Wiki
-A Very Basic Wiki Format -======================== - -(this is probably obsolete, will be replaced by corresponding WikiPage -parsing and rendering functionality) - -We first set up a format (a utility) and create a format instance -from it. The instance needs a wiki page as its context - to simplify -things during testing we just use a bare object. - - >>> from cybertools.wiki.base.format import BasicFormat - >>> format = BasicFormat() - >>> page = object() - >>> instance = format.getInstance(page) - -Now we enter some simple text and request the format instance to -unmarshall it, i.e. to convert it from the editable to the internal -representation. - - >>> input = ('This is text with a [[Wiki Link]].\n\n' - ... 'It also contains a second line.') - - >>> instance.unmarshall(input) - 'This is text with a [[${l0000001}]].\n\nIt also contains a second line.' diff --git a/wiki/base/config.py b/wiki/base/config.py index a168778..4a67026 100644 --- a/wiki/base/config.py +++ b/wiki/base/config.py @@ -53,4 +53,4 @@ class WikiConfiguration(BaseConfiguration): writer = 'docutils.html' parser = 'docutils.rstx' - + processor = 'standard' diff --git a/wiki/base/format.py b/wiki/base/format.py deleted file mode 100644 index 8a4b220..0000000 --- a/wiki/base/format.py +++ /dev/null @@ -1,81 +0,0 @@ -# -# Copyright (c) 2008 Helmut Merz helmutm@cy55.de -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -""" -Basic Wiki formatting. - -$Id$ -""" - -import re -from zope.interface import implements - -from cybertools.wiki.base.link import Link, LinkManager -from cybertools.wiki.interfaces import IFormat, IFormatInstance - - -class FormatInstance(object): - - #implements(IFormatInstance) - - parent = None - - def __init__(self, context): - self.context = context - - def unmarshall(self, text): - return self.parent.linkRegexp.sub(self.processLink, text) - - def processLink(self, match): - ref, label = match.group(1).split(' ', 1) - link = Link(self.context, ref) - link.original = match.group(0) - link.label = label - self.parent.manager.registerLink(link) - return self.parent.linkFormat % (self.parent.internalFormat % link.identifier) - - def marshall(self, text): - return text - - def display(self, text): - return text - - -class BasicFormat(object): - - #implements(IFormat) - - name = 'basic' - instanceFactory = FormatInstance - - internalRegexp = re.compile(r'!\\\$([_A-Z0-9a-z]+)|{(.+)}') - internalFormat = '${%s}' - linkRegexp = re.compile(r'\[\[(.+)\]\]') - linkFormat = '[[%s]]' - - repository = None - - def __init__(self, manager=None): - if manager is None: - manager = LinkManager() - self.manager = manager - - def getInstance(self, context): - instance = self.instanceFactory(context) - instance.parent = self - return instance diff --git a/wiki/base/link.py b/wiki/base/link.py index 91bddc0..d0c3f1e 100644 --- a/wiki/base/link.py +++ b/wiki/base/link.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2008 Helmut Merz helmutm@cy55.de +# Copyright (c) 2009 Helmut Merz helmutm@cy55.de # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -22,7 +22,6 @@ Basic (sample) implementations for links and link management $Id$ """ -import re from zope.interface import implements from cybertools.wiki.interfaces import ILink, ILinkManager diff --git a/wiki/base/process.py b/wiki/base/process.py new file mode 100644 index 0000000..dcd2655 --- /dev/null +++ b/wiki/base/process.py @@ -0,0 +1,54 @@ +# +# Copyright (c) 2009 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Tree processor implementation + +$Id$ +""" + +from zope.interface import implements +from zope.component import adapts + +from cybertools.wiki.interfaces import ITreeProcessor, IWikiPage + + +class TreeProcessor(object): + """ The standard tree processor walking the tree and processing + the tree's nodes. + """ + + implements(ITreeProcessor) + adapts(IWikiPage) + + tree = None + + def __init__(self, context): + self.context = context + + def process(self): + self.tree.walk(Visitor(self.tree)) + + +class Visitor(object): + + def __init__(self, document): + self.document = document + + def dispatch_visit(self, node): + print 'visiting', node.tagname diff --git a/wiki/base/wiki.py b/wiki/base/wiki.py index 23711e6..79bc4f6 100644 --- a/wiki/base/wiki.py +++ b/wiki/base/wiki.py @@ -27,7 +27,7 @@ from zope.interface import implements from cybertools.wiki.interfaces import IWikiConfiguration from cybertools.wiki.interfaces import IWikiManager, IWiki, IWikiPage -from cybertools.wiki.interfaces import IParser, IWriter +from cybertools.wiki.interfaces import IParser, IWriter, ITreeProcessor from cybertools.wiki.base.config import BaseConfiguration @@ -88,18 +88,34 @@ class WikiPage(BaseConfiguration): self.title = title or name def render(self): - return self.write(self.parse()) + source = self.preprocess(self.text) + tree = self.parse(source) + self.process(tree) + result = self.write(tree) + return self.postprocess(result) - def parse(self): + def parse(self, source): parserName = self.getConfig('parser') parser = component.getUtility(IParser, name=parserName) - return parser.parse(self.text) + return parser.parse(source) def write(self, tree): writerName = self.getConfig('writer') writer = component.getUtility(IWriter, name=writerName) return writer.write(tree) + def preprocess(self, source): + return source + + def process(self, tree): + processor = component.getAdapter(self, ITreeProcessor, + name=self.getConfig('processor')) + processor.tree = tree + processor.process() + + def postprocess(self, result): + return result + # configuration def getParent(self): diff --git a/wiki/interfaces.py b/wiki/interfaces.py index 3d7cc1e..2506142 100644 --- a/wiki/interfaces.py +++ b/wiki/interfaces.py @@ -92,17 +92,30 @@ class IWikiPage(Interface): text = Attribute('The page content in input text format.') def render(): - """ Convert the text of the page to presentation format. + """ Convert the source text of the page to presentation format. """ - def parse(): - """ Convert the text of the page to a document tree. + def parse(source): + """ Convert the source text of the page to a document tree. """ def write(tree): """ Convert the document tree given to presentation format. """ + def preprocess(source): + """ Modify the source text of the page before parsing it and return it. + """ + + def process(tree): + """ Scan the tree, changing it if necessary and collecting + interesting information about the nodes, e.g. about links. + """ + + def postprocess(result): + """ Modify the output of the write process and return it. + """ + # wiki plugins @@ -123,6 +136,18 @@ class IWriter(Interface): """ +class ITreeProcessor(Interface): + """ Processes a document tree. + """ + + context = Attribute('The wiki page from which the tree was generated.') + tree = Attribute('The tree to be processed.') + + def process(): + """ Do what is necessary. + """ + + # wiki elements class ILinkManager(Interface): @@ -152,36 +177,3 @@ class ILink(Interface): source = Attribute('Link source.') target = Attribute('Link target.') - -class IFormat(Interface): - """Identifies links in texts and transforms text correspondingly. - """ - - manager = Attribute('The Wiki manager this format is associated with.') - - -class IFormatInstance(Interface): - - def unmarshall(text): - """Analyse the text given extracting all links and registering them - with the link manager; return text with all links transformed to - an internal link naming format. - - This is typically used for preprocessing the text after editing. - """ - - def marshall(text): - """Scan text for all links (i.e. substrings corresponding to the - internal link naming format) and replace them with their external - format. - - This is typically used for preparing a text for editing. - """ - - def display(text): - """Scan text for all links (i.e. substrings corresponding to the - internal link naming format) and replace them with their display - format. - - The result will then be used for rendering by the text format. - """ diff --git a/wiki/tests.py b/wiki/tests.py index 45fad68..3702124 100755 --- a/wiki/tests.py +++ b/wiki/tests.py @@ -11,6 +11,7 @@ from zope.testing.doctestunit import DocFileSuite from zope import component from cybertools.wiki.base.config import WikiConfiguration +from cybertools.wiki.base.process import TreeProcessor from cybertools.wiki.dcu.html import Writer as DocutilsHTMLWriter from cybertools.wiki.dcu.rstx import Parser as DocutilsRstxParser @@ -26,6 +27,7 @@ def setUp(testCase): component.provideUtility(WikiConfiguration()) component.provideUtility(DocutilsHTMLWriter(), name='docutils.html') component.provideUtility(DocutilsRstxParser(), name='docutils.rstx') + component.provideAdapter(TreeProcessor, name='standard') def test_suite():