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