work in progress: process document tree
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@3143 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
		
							parent
							
								
									fdb814fed7
								
							
						
					
					
						commit
						1d4363f23c
					
				
					 8 changed files with 110 additions and 150 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
  <p><strong>Welcome to the Demo Wiki</strong></p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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.'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,4 +53,4 @@ class WikiConfiguration(BaseConfiguration):
 | 
			
		|||
 | 
			
		||||
    writer = 'docutils.html'
 | 
			
		||||
    parser = 'docutils.rstx'
 | 
			
		||||
 | 
			
		||||
    processor = 'standard'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										54
									
								
								wiki/base/process.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								wiki/base/process.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
        """
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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():
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue