Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
e052fb6b
Commit
e052fb6b
authored
Dec 11, 2005
by
Andreas Jung
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
you're time has come, no longer needed for Z3 ZPTs
parent
1c0af142
Changes
143
Show whitespace changes
Inline
Side-by-side
Showing
143 changed files
with
0 additions
and
9860 deletions
+0
-9860
lib/python/TAL/CHANGES.txt
lib/python/TAL/CHANGES.txt
+0
-11
lib/python/TAL/DummyEngine.py
lib/python/TAL/DummyEngine.py
+0
-258
lib/python/TAL/HISTORY.txt
lib/python/TAL/HISTORY.txt
+0
-72
lib/python/TAL/HTMLTALParser.py
lib/python/TAL/HTMLTALParser.py
+0
-315
lib/python/TAL/ITALES.py
lib/python/TAL/ITALES.py
+0
-156
lib/python/TAL/README.txt
lib/python/TAL/README.txt
+0
-97
lib/python/TAL/TALDefs.py
lib/python/TAL/TALDefs.py
+0
-191
lib/python/TAL/TALGenerator.py
lib/python/TAL/TALGenerator.py
+0
-892
lib/python/TAL/TALInterpreter.py
lib/python/TAL/TALInterpreter.py
+0
-843
lib/python/TAL/TALParser.py
lib/python/TAL/TALParser.py
+0
-143
lib/python/TAL/TranslationContext.py
lib/python/TAL/TranslationContext.py
+0
-41
lib/python/TAL/XMLParser.py
lib/python/TAL/XMLParser.py
+0
-88
lib/python/TAL/__init__.py
lib/python/TAL/__init__.py
+0
-14
lib/python/TAL/benchmark/dtml01.html
lib/python/TAL/benchmark/dtml01.html
+0
-1
lib/python/TAL/benchmark/dtml02.html
lib/python/TAL/benchmark/dtml02.html
+0
-100
lib/python/TAL/benchmark/dtml03.html
lib/python/TAL/benchmark/dtml03.html
+0
-8
lib/python/TAL/benchmark/dtml04.html
lib/python/TAL/benchmark/dtml04.html
+0
-6
lib/python/TAL/benchmark/dtml05.html
lib/python/TAL/benchmark/dtml05.html
+0
-10
lib/python/TAL/benchmark/dtml06.html
lib/python/TAL/benchmark/dtml06.html
+0
-14
lib/python/TAL/benchmark/dtml07.html
lib/python/TAL/benchmark/dtml07.html
+0
-73
lib/python/TAL/benchmark/dtml08.html
lib/python/TAL/benchmark/dtml08.html
+0
-73
lib/python/TAL/benchmark/dtml09.html
lib/python/TAL/benchmark/dtml09.html
+0
-10
lib/python/TAL/benchmark/dtml10.html
lib/python/TAL/benchmark/dtml10.html
+0
-102
lib/python/TAL/benchmark/dtml11.html
lib/python/TAL/benchmark/dtml11.html
+0
-103
lib/python/TAL/benchmark/dtml12.html
lib/python/TAL/benchmark/dtml12.html
+0
-12
lib/python/TAL/benchmark/tal01.html
lib/python/TAL/benchmark/tal01.html
+0
-1
lib/python/TAL/benchmark/tal02.html
lib/python/TAL/benchmark/tal02.html
+0
-100
lib/python/TAL/benchmark/tal03.html
lib/python/TAL/benchmark/tal03.html
+0
-8
lib/python/TAL/benchmark/tal04.html
lib/python/TAL/benchmark/tal04.html
+0
-6
lib/python/TAL/benchmark/tal05.html
lib/python/TAL/benchmark/tal05.html
+0
-10
lib/python/TAL/benchmark/tal06.html
lib/python/TAL/benchmark/tal06.html
+0
-14
lib/python/TAL/benchmark/tal07.html
lib/python/TAL/benchmark/tal07.html
+0
-73
lib/python/TAL/benchmark/tal08.html
lib/python/TAL/benchmark/tal08.html
+0
-73
lib/python/TAL/benchmark/tal09.html
lib/python/TAL/benchmark/tal09.html
+0
-10
lib/python/TAL/benchmark/tal10.html
lib/python/TAL/benchmark/tal10.html
+0
-102
lib/python/TAL/benchmark/tal11.html
lib/python/TAL/benchmark/tal11.html
+0
-103
lib/python/TAL/benchmark/tal12.html
lib/python/TAL/benchmark/tal12.html
+0
-12
lib/python/TAL/driver.py
lib/python/TAL/driver.py
+0
-198
lib/python/TAL/markbench.py
lib/python/TAL/markbench.py
+0
-137
lib/python/TAL/markupbase.py
lib/python/TAL/markupbase.py
+0
-312
lib/python/TAL/ndiff.py
lib/python/TAL/ndiff.py
+0
-634
lib/python/TAL/runtest.py
lib/python/TAL/runtest.py
+0
-151
lib/python/TAL/setpath.py
lib/python/TAL/setpath.py
+0
-29
lib/python/TAL/talgettext.py
lib/python/TAL/talgettext.py
+0
-318
lib/python/TAL/tests/__init__.py
lib/python/TAL/tests/__init__.py
+0
-1
lib/python/TAL/tests/input/test01.html
lib/python/TAL/tests/input/test01.html
+0
-56
lib/python/TAL/tests/input/test01.xml
lib/python/TAL/tests/input/test01.xml
+0
-57
lib/python/TAL/tests/input/test02.html
lib/python/TAL/tests/input/test02.html
+0
-118
lib/python/TAL/tests/input/test02.xml
lib/python/TAL/tests/input/test02.xml
+0
-119
lib/python/TAL/tests/input/test03.html
lib/python/TAL/tests/input/test03.html
+0
-9
lib/python/TAL/tests/input/test03.xml
lib/python/TAL/tests/input/test03.xml
+0
-10
lib/python/TAL/tests/input/test04.html
lib/python/TAL/tests/input/test04.html
+0
-26
lib/python/TAL/tests/input/test04.xml
lib/python/TAL/tests/input/test04.xml
+0
-27
lib/python/TAL/tests/input/test05.html
lib/python/TAL/tests/input/test05.html
+0
-9
lib/python/TAL/tests/input/test05.xml
lib/python/TAL/tests/input/test05.xml
+0
-10
lib/python/TAL/tests/input/test06.html
lib/python/TAL/tests/input/test06.html
+0
-6
lib/python/TAL/tests/input/test06.xml
lib/python/TAL/tests/input/test06.xml
+0
-7
lib/python/TAL/tests/input/test07.html
lib/python/TAL/tests/input/test07.html
+0
-11
lib/python/TAL/tests/input/test07.xml
lib/python/TAL/tests/input/test07.xml
+0
-12
lib/python/TAL/tests/input/test08.html
lib/python/TAL/tests/input/test08.html
+0
-44
lib/python/TAL/tests/input/test08.xml
lib/python/TAL/tests/input/test08.xml
+0
-45
lib/python/TAL/tests/input/test09.html
lib/python/TAL/tests/input/test09.html
+0
-30
lib/python/TAL/tests/input/test09.xml
lib/python/TAL/tests/input/test09.xml
+0
-30
lib/python/TAL/tests/input/test10.html
lib/python/TAL/tests/input/test10.html
+0
-48
lib/python/TAL/tests/input/test11.html
lib/python/TAL/tests/input/test11.html
+0
-14
lib/python/TAL/tests/input/test11.xml
lib/python/TAL/tests/input/test11.xml
+0
-14
lib/python/TAL/tests/input/test12.html
lib/python/TAL/tests/input/test12.html
+0
-29
lib/python/TAL/tests/input/test13.html
lib/python/TAL/tests/input/test13.html
+0
-7
lib/python/TAL/tests/input/test14.html
lib/python/TAL/tests/input/test14.html
+0
-10
lib/python/TAL/tests/input/test14.xml
lib/python/TAL/tests/input/test14.xml
+0
-15
lib/python/TAL/tests/input/test15.html
lib/python/TAL/tests/input/test15.html
+0
-26
lib/python/TAL/tests/input/test16.html
lib/python/TAL/tests/input/test16.html
+0
-4
lib/python/TAL/tests/input/test16.xml
lib/python/TAL/tests/input/test16.xml
+0
-7
lib/python/TAL/tests/input/test17.html
lib/python/TAL/tests/input/test17.html
+0
-6
lib/python/TAL/tests/input/test17.xml
lib/python/TAL/tests/input/test17.xml
+0
-10
lib/python/TAL/tests/input/test18.html
lib/python/TAL/tests/input/test18.html
+0
-16
lib/python/TAL/tests/input/test18.xml
lib/python/TAL/tests/input/test18.xml
+0
-20
lib/python/TAL/tests/input/test19.html
lib/python/TAL/tests/input/test19.html
+0
-22
lib/python/TAL/tests/input/test20.html
lib/python/TAL/tests/input/test20.html
+0
-1
lib/python/TAL/tests/input/test29.html
lib/python/TAL/tests/input/test29.html
+0
-4
lib/python/TAL/tests/input/test34.html
lib/python/TAL/tests/input/test34.html
+0
-11
lib/python/TAL/tests/input/test36.html
lib/python/TAL/tests/input/test36.html
+0
-6
lib/python/TAL/tests/input/test_failed_attr_translation.html
lib/python/TAL/tests/input/test_failed_attr_translation.html
+0
-2
lib/python/TAL/tests/input/test_metal1.html
lib/python/TAL/tests/input/test_metal1.html
+0
-61
lib/python/TAL/tests/input/test_metal2.html
lib/python/TAL/tests/input/test_metal2.html
+0
-7
lib/python/TAL/tests/input/test_metal3.html
lib/python/TAL/tests/input/test_metal3.html
+0
-1
lib/python/TAL/tests/input/test_metal4.html
lib/python/TAL/tests/input/test_metal4.html
+0
-4
lib/python/TAL/tests/input/test_metal5.html
lib/python/TAL/tests/input/test_metal5.html
+0
-4
lib/python/TAL/tests/input/test_metal6.html
lib/python/TAL/tests/input/test_metal6.html
+0
-5
lib/python/TAL/tests/input/test_metal7.html
lib/python/TAL/tests/input/test_metal7.html
+0
-4
lib/python/TAL/tests/output/test01.html
lib/python/TAL/tests/output/test01.html
+0
-68
lib/python/TAL/tests/output/test01.xml
lib/python/TAL/tests/output/test01.xml
+0
-65
lib/python/TAL/tests/output/test02.html
lib/python/TAL/tests/output/test02.html
+0
-118
lib/python/TAL/tests/output/test02.xml
lib/python/TAL/tests/output/test02.xml
+0
-119
lib/python/TAL/tests/output/test03.html
lib/python/TAL/tests/output/test03.html
+0
-9
lib/python/TAL/tests/output/test03.xml
lib/python/TAL/tests/output/test03.xml
+0
-10
lib/python/TAL/tests/output/test04.html
lib/python/TAL/tests/output/test04.html
+0
-38
lib/python/TAL/tests/output/test04.xml
lib/python/TAL/tests/output/test04.xml
+0
-39
lib/python/TAL/tests/output/test05.html
lib/python/TAL/tests/output/test05.html
+0
-9
lib/python/TAL/tests/output/test05.xml
lib/python/TAL/tests/output/test05.xml
+0
-10
lib/python/TAL/tests/output/test06.html
lib/python/TAL/tests/output/test06.html
+0
-7
lib/python/TAL/tests/output/test06.xml
lib/python/TAL/tests/output/test06.xml
+0
-8
lib/python/TAL/tests/output/test07.html
lib/python/TAL/tests/output/test07.html
+0
-11
lib/python/TAL/tests/output/test07.xml
lib/python/TAL/tests/output/test07.xml
+0
-12
lib/python/TAL/tests/output/test08.html
lib/python/TAL/tests/output/test08.html
+0
-47
lib/python/TAL/tests/output/test08.xml
lib/python/TAL/tests/output/test08.xml
+0
-48
lib/python/TAL/tests/output/test09.html
lib/python/TAL/tests/output/test09.html
+0
-30
lib/python/TAL/tests/output/test09.xml
lib/python/TAL/tests/output/test09.xml
+0
-30
lib/python/TAL/tests/output/test10.html
lib/python/TAL/tests/output/test10.html
+0
-51
lib/python/TAL/tests/output/test11.html
lib/python/TAL/tests/output/test11.html
+0
-5
lib/python/TAL/tests/output/test11.xml
lib/python/TAL/tests/output/test11.xml
+0
-5
lib/python/TAL/tests/output/test12.html
lib/python/TAL/tests/output/test12.html
+0
-29
lib/python/TAL/tests/output/test13.html
lib/python/TAL/tests/output/test13.html
+0
-7
lib/python/TAL/tests/output/test14.html
lib/python/TAL/tests/output/test14.html
+0
-13
lib/python/TAL/tests/output/test14.xml
lib/python/TAL/tests/output/test14.xml
+0
-18
lib/python/TAL/tests/output/test15.html
lib/python/TAL/tests/output/test15.html
+0
-29
lib/python/TAL/tests/output/test16.html
lib/python/TAL/tests/output/test16.html
+0
-3
lib/python/TAL/tests/output/test16.xml
lib/python/TAL/tests/output/test16.xml
+0
-6
lib/python/TAL/tests/output/test17.html
lib/python/TAL/tests/output/test17.html
+0
-6
lib/python/TAL/tests/output/test17.xml
lib/python/TAL/tests/output/test17.xml
+0
-9
lib/python/TAL/tests/output/test18.html
lib/python/TAL/tests/output/test18.html
+0
-16
lib/python/TAL/tests/output/test18.xml
lib/python/TAL/tests/output/test18.xml
+0
-19
lib/python/TAL/tests/output/test19.html
lib/python/TAL/tests/output/test19.html
+0
-14
lib/python/TAL/tests/output/test20.html
lib/python/TAL/tests/output/test20.html
+0
-1
lib/python/TAL/tests/output/test29.html
lib/python/TAL/tests/output/test29.html
+0
-1
lib/python/TAL/tests/output/test34.html
lib/python/TAL/tests/output/test34.html
+0
-7
lib/python/TAL/tests/output/test36.html
lib/python/TAL/tests/output/test36.html
+0
-2
lib/python/TAL/tests/output/test_failed_attr_translation.html
...python/TAL/tests/output/test_failed_attr_translation.html
+0
-1
lib/python/TAL/tests/output/test_metal1.html
lib/python/TAL/tests/output/test_metal1.html
+0
-79
lib/python/TAL/tests/output/test_metal2.html
lib/python/TAL/tests/output/test_metal2.html
+0
-11
lib/python/TAL/tests/output/test_metal3.html
lib/python/TAL/tests/output/test_metal3.html
+0
-1
lib/python/TAL/tests/output/test_metal4.html
lib/python/TAL/tests/output/test_metal4.html
+0
-4
lib/python/TAL/tests/output/test_metal5.html
lib/python/TAL/tests/output/test_metal5.html
+0
-4
lib/python/TAL/tests/output/test_metal6.html
lib/python/TAL/tests/output/test_metal6.html
+0
-5
lib/python/TAL/tests/output/test_metal7.html
lib/python/TAL/tests/output/test_metal7.html
+0
-6
lib/python/TAL/tests/run.py
lib/python/TAL/tests/run.py
+0
-30
lib/python/TAL/tests/test_files.py
lib/python/TAL/tests/test_files.py
+0
-71
lib/python/TAL/tests/test_htmltalparser.py
lib/python/TAL/tests/test_htmltalparser.py
+0
-927
lib/python/TAL/tests/test_sourcepos.py
lib/python/TAL/tests/test_sourcepos.py
+0
-81
lib/python/TAL/tests/test_talinterpreter.py
lib/python/TAL/tests/test_talinterpreter.py
+0
-437
lib/python/TAL/tests/test_xmlparser.py
lib/python/TAL/tests/test_xmlparser.py
+0
-254
lib/python/TAL/tests/utils.py
lib/python/TAL/tests/utils.py
+0
-64
lib/python/TAL/timer.py
lib/python/TAL/timer.py
+0
-57
No files found.
lib/python/TAL/CHANGES.txt
deleted
100644 → 0
View file @
1c0af142
TAL changes
This file contains change information for the current release.
Change information for previous versions can be found in the
file HISTORY.txt.
Version 1.5.0
Features Added
- Line and column numbers are added to more exceptions.
lib/python/TAL/DummyEngine.py
deleted
100644 → 0
View file @
1c0af142
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
Dummy TALES engine so that I can test out the TAL implementation.
"""
import
re
import
sys
from
TALDefs
import
NAME_RE
,
TALESError
,
ErrorInfo
from
ITALES
import
ITALESCompiler
,
ITALESEngine
from
DocumentTemplate.DT_Util
import
ustr
class
_Default
:
pass
Default
=
_Default
()
name_match
=
re
.
compile
(
r"(?s)(%s):(.*)\
Z
" % NAME_RE).match
class CompilerError(Exception):
pass
class DummyEngine:
position = None
source_file = None
__implements__ = ITALESCompiler, ITALESEngine
def __init__(self, macros=None):
if macros is None:
macros = {}
self.macros = macros
dict = {'nothing': None, 'default': Default}
self.locals = self.globals = dict
self.stack = [dict]
self.translationService = DummyTranslationService()
def getCompilerError(self):
return CompilerError
def getCompiler(self):
return self
def setSourceFile(self, source_file):
self.source_file = source_file
def setPosition(self, position):
self.position = position
def compile(self, expr):
return "
$
%
s
$
" % expr
def uncompile(self, expression):
assert (expression.startswith("
$
") and expression.endswith("
$
"),
expression)
return expression[1:-1]
def beginScope(self):
self.stack.append(self.locals)
def endScope(self):
assert len(self.stack) > 1, "
more
endScope
()
than
beginScope
()
calls
"
self.locals = self.stack.pop()
def setLocal(self, name, value):
if self.locals is self.stack[-1]:
# Unmerge this scope's locals from previous scope of first set
self.locals = self.locals.copy()
self.locals[name] = value
def setGlobal(self, name, value):
self.globals[name] = value
def evaluate(self, expression):
assert (expression.startswith("
$
") and expression.endswith("
$
"),
expression)
expression = expression[1:-1]
m = name_match(expression)
if m:
type, expr = m.group(1, 2)
else:
type = "
path
"
expr = expression
if type in ("
string
", "
str
"):
return expr
if type in ("
path
", "
var
", "
global
", "
local
"):
return self.evaluatePathOrVar(expr)
if type == "
not
":
return not self.evaluate(expr)
if type == "
exists
":
return self.locals.has_key(expr) or self.globals.has_key(expr)
if type == "
python
":
try:
return eval(expr, self.globals, self.locals)
except:
raise TALESError("
evaluation
error
in
%
s
" % `expr`)
if type == "
position
":
# Insert the current source file name, line number,
# and column offset.
if self.position:
lineno, offset = self.position
else:
lineno, offset = None, None
return '%s (%s,%s)' % (self.source_file, lineno, offset)
raise TALESError("
unrecognized
expression
:
" + `expression`)
def evaluatePathOrVar(self, expr):
expr = expr.strip()
if self.locals.has_key(expr):
return self.locals[expr]
elif self.globals.has_key(expr):
return self.globals[expr]
else:
raise TALESError("
unknown
variable
:
%
s
" % `expr`)
def evaluateValue(self, expr):
return self.evaluate(expr)
def evaluateBoolean(self, expr):
return self.evaluate(expr)
def evaluateText(self, expr):
text = self.evaluate(expr)
if text is not None and text is not Default:
text = ustr(text)
return text
def evaluateStructure(self, expr):
# XXX Should return None or a DOM tree
return self.evaluate(expr)
def evaluateSequence(self, expr):
# XXX Should return a sequence
return self.evaluate(expr)
def evaluateMacro(self, macroName):
assert (macroName.startswith("
$
") and macroName.endswith("
$
"),
macroName)
macroName = macroName[1:-1]
file, localName = self.findMacroFile(macroName)
if not file:
# Local macro
macro = self.macros[localName]
else:
# External macro
import driver
program, macros = driver.compilefile(file)
macro = macros.get(localName)
if not macro:
raise TALESError("
macro
%
s
not
found
in
file
%
s
" %
(localName, file))
return macro
def findMacroDocument(self, macroName):
file, localName = self.findMacroFile(macroName)
if not file:
return file, localName
import driver
doc = driver.parsefile(file)
return doc, localName
def findMacroFile(self, macroName):
if not macroName:
raise TALESError("
empty
macro
name
")
i = macroName.rfind('/')
if i < 0:
# No slash -- must be a locally defined macro
return None, macroName
else:
# Up to last slash is the filename
fileName = macroName[:i]
localName = macroName[i+1:]
return fileName, localName
def setRepeat(self, name, expr):
seq = self.evaluateSequence(expr)
return Iterator(name, seq, self)
def createErrorInfo(self, err, position):
return ErrorInfo(err, position)
def getDefault(self):
return Default
def translate(self, domain, msgid, mapping, default=None):
return self.translationService.translate(domain, msgid, mapping,
default=default)
class Iterator:
# This is not an implementation of a Python iterator. The next()
# method returns true or false to indicate whether another item is
# available; if there is another item, the iterator instance calls
# setLocal() on the evaluation engine passed to the constructor.
def __init__(self, name, seq, engine):
self.name = name
self.seq = seq
self.engine = engine
self.nextIndex = 0
def next(self):
i = self.nextIndex
try:
item = self.seq[i]
except IndexError:
return 0
self.nextIndex = i+1
self.engine.setLocal(self.name, item)
return 1
class DummyDomain:
def translate(self, msgid, mapping=None, context=None,
target_language=None, default=None):
# This is a fake translation service which simply uppercases non
# ${name} placeholder text in the message id.
#
# First, transform a string with ${name} placeholders into a list of
# substrings. Then upcase everything but the placeholders, then glue
# things back together.
# simulate an unknown msgid by returning None
text = msgid
if msgid == "
don
't translate me":
if default is not None:
text = default
else:
text = msgid.upper()
def repl(m, mapping=mapping):
return ustr(mapping[m.group(m.lastindex).lower()])
cre = re.compile(r'
\
$
(
?
:(
%
s
)
|
\
{(
%
s
)
\
})
' % (NAME_RE, NAME_RE))
return cre.sub(repl, text)
class DummyTranslationService:
def translate(self, domain, msgid, mapping=None, context=None,
target_language=None, default=None):
return self.getDomain(domain).translate(msgid, mapping, context,
target_language,
default=default)
def getDomain(self, domain):
return DummyDomain()
lib/python/TAL/HISTORY.txt
deleted
100644 → 0
View file @
1c0af142
TAL history
This file contains change information for previous versions.
Change information for the current release can be found
in the file CHANGES.txt.
Version 1.4.0
Features Added
- Added TAL statement: omit_tag="[<boolean expr>]" replaces
the statement tag with its contents if the boolean
expression is true or omitted.
- The TAL and METAL namespaces can be applied to tag names,
tags in these namespaces are removed from rendered output
(leaving the contents in place, as with omit_tag)
whenever attributes in these namespaces would be, and
tag attributes without explicit namespaces default to the
tag's namespace (per XML spec).
Version 1.3.3
Bugs Fixed
- tal:atributes was creating stray attributes in METAL
expansion, and there was no unit test for this behavior.
- tal:attributes parsing was not catching badly malformed
values, and used "print" instead of raising exceptions.
Version 1.3.2
Features Added
- Adopted Zope-style CHANGES.txt and HISTORY.txt
- Improved execution performance
- Added simple ZPT vs. TAL vs. DTML benchmarks, run by markbench.py
Version 1.3.0
Features Added
- New builtin variable 'attrs'.
Bug Fixed
- Nested macros were not working correctly.
Version 1.2.0
Features Added
- The 'if' path modifier can cancel any TAL action.
Bug Fixed
- tal:attributes inserted empty attributes into source.
Version 1.1.0
Features Added
- TAL does not try to parse replacement structural text.
- Changed tests to match TAL's omitted attributes.
Version 1.0.0
- Various minor bugs fixed
Version 1.0.0b1
- All functionality described in the Project Wiki is implemented
lib/python/TAL/HTMLTALParser.py
deleted
100644 → 0
View file @
1c0af142
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
Parse HTML and compile to TALInterpreter intermediate code.
"""
import
sys
from
TALGenerator
import
TALGenerator
from
HTMLParser
import
HTMLParser
,
HTMLParseError
from
TALDefs
import
\
ZOPE_METAL_NS
,
ZOPE_TAL_NS
,
ZOPE_I18N_NS
,
METALError
,
TALError
,
I18NError
BOOLEAN_HTML_ATTRS
=
[
# List of Boolean attributes in HTML that may be given in
# minimized form (e.g. <img ismap> rather than <img ismap="">)
# From http://www.w3.org/TR/xhtml1/#guidelines (C.10)
"compact"
,
"nowrap"
,
"ismap"
,
"declare"
,
"noshade"
,
"checked"
,
"disabled"
,
"readonly"
,
"multiple"
,
"selected"
,
"noresize"
,
"defer"
]
EMPTY_HTML_TAGS
=
[
# List of HTML tags with an empty content model; these are
# rendered in minimized form, e.g. <img />.
# From http://www.w3.org/TR/xhtml1/#dtds
"base"
,
"meta"
,
"link"
,
"hr"
,
"br"
,
"param"
,
"img"
,
"area"
,
"input"
,
"col"
,
"basefont"
,
"isindex"
,
"frame"
,
]
PARA_LEVEL_HTML_TAGS
=
[
# List of HTML elements that close open paragraph-level elements
# and are themselves paragraph-level.
"h1"
,
"h2"
,
"h3"
,
"h4"
,
"h5"
,
"h6"
,
"p"
,
]
BLOCK_CLOSING_TAG_MAP
=
{
"tr"
:
(
"tr"
,
"td"
,
"th"
),
"td"
:
(
"td"
,
"th"
),
"th"
:
(
"td"
,
"th"
),
"li"
:
(
"li"
,),
"dd"
:
(
"dd"
,
"dt"
),
"dt"
:
(
"dd"
,
"dt"
),
}
BLOCK_LEVEL_HTML_TAGS
=
[
# List of HTML tags that denote larger sections than paragraphs.
"blockquote"
,
"table"
,
"tr"
,
"th"
,
"td"
,
"thead"
,
"tfoot"
,
"tbody"
,
"noframe"
,
"ul"
,
"ol"
,
"li"
,
"dl"
,
"dt"
,
"dd"
,
"div"
,
]
TIGHTEN_IMPLICIT_CLOSE_TAGS
=
(
PARA_LEVEL_HTML_TAGS
+
BLOCK_CLOSING_TAG_MAP
.
keys
())
class
NestingError
(
HTMLParseError
):
"""Exception raised when elements aren't properly nested."""
def
__init__
(
self
,
tagstack
,
endtag
,
position
=
(
None
,
None
)):
self
.
endtag
=
endtag
if
tagstack
:
if
len
(
tagstack
)
==
1
:
msg
=
(
'Open tag <%s> does not match close tag </%s>'
%
(
tagstack
[
0
],
endtag
))
else
:
msg
=
(
'Open tags <%s> do not match close tag </%s>'
%
(
'>, <'
.
join
(
tagstack
),
endtag
))
else
:
msg
=
'No tags are open to match </%s>'
%
endtag
HTMLParseError
.
__init__
(
self
,
msg
,
position
)
class
EmptyTagError
(
NestingError
):
"""Exception raised when empty elements have an end tag."""
def
__init__
(
self
,
tag
,
position
=
(
None
,
None
)):
self
.
tag
=
tag
msg
=
'Close tag </%s> should be removed'
%
tag
HTMLParseError
.
__init__
(
self
,
msg
,
position
)
class
OpenTagError
(
NestingError
):
"""Exception raised when a tag is not allowed in another tag."""
def
__init__
(
self
,
tagstack
,
tag
,
position
=
(
None
,
None
)):
self
.
tag
=
tag
msg
=
'Tag <%s> is not allowed in <%s>'
%
(
tag
,
tagstack
[
-
1
])
HTMLParseError
.
__init__
(
self
,
msg
,
position
)
class
HTMLTALParser
(
HTMLParser
):
# External API
def
__init__
(
self
,
gen
=
None
):
HTMLParser
.
__init__
(
self
)
if
gen
is
None
:
gen
=
TALGenerator
(
xml
=
0
)
self
.
gen
=
gen
self
.
tagstack
=
[]
self
.
nsstack
=
[]
self
.
nsdict
=
{
'tal'
:
ZOPE_TAL_NS
,
'metal'
:
ZOPE_METAL_NS
,
'i18n'
:
ZOPE_I18N_NS
,
}
def
parseFile
(
self
,
file
):
f
=
open
(
file
)
data
=
f
.
read
()
f
.
close
()
try
:
self
.
parseString
(
data
)
except
TALError
,
e
:
e
.
setFile
(
file
)
raise
def
parseString
(
self
,
data
):
self
.
feed
(
data
)
self
.
close
()
while
self
.
tagstack
:
self
.
implied_endtag
(
self
.
tagstack
[
-
1
],
2
)
assert
self
.
nsstack
==
[],
self
.
nsstack
def
getCode
(
self
):
return
self
.
gen
.
getCode
()
def
getWarnings
(
self
):
return
()
# Overriding HTMLParser methods
def
handle_starttag
(
self
,
tag
,
attrs
):
self
.
close_para_tags
(
tag
)
self
.
scan_xmlns
(
attrs
)
tag
,
attrlist
,
taldict
,
metaldict
,
i18ndict
\
=
self
.
process_ns
(
tag
,
attrs
)
if
tag
in
EMPTY_HTML_TAGS
and
taldict
.
get
(
"content"
):
raise
TALError
(
"empty HTML tags cannot use tal:content: %s"
%
`tag`
,
self
.
getpos
())
self
.
tagstack
.
append
(
tag
)
self
.
gen
.
emitStartElement
(
tag
,
attrlist
,
taldict
,
metaldict
,
i18ndict
,
self
.
getpos
())
if
tag
in
EMPTY_HTML_TAGS
:
self
.
implied_endtag
(
tag
,
-
1
)
def
handle_startendtag
(
self
,
tag
,
attrs
):
self
.
close_para_tags
(
tag
)
self
.
scan_xmlns
(
attrs
)
tag
,
attrlist
,
taldict
,
metaldict
,
i18ndict
\
=
self
.
process_ns
(
tag
,
attrs
)
if
taldict
.
get
(
"content"
):
if
tag
in
EMPTY_HTML_TAGS
:
raise
TALError
(
"empty HTML tags cannot use tal:content: %s"
%
`tag`
,
self
.
getpos
())
self
.
gen
.
emitStartElement
(
tag
,
attrlist
,
taldict
,
metaldict
,
i18ndict
,
self
.
getpos
())
self
.
gen
.
emitEndElement
(
tag
,
implied
=-
1
)
else
:
self
.
gen
.
emitStartElement
(
tag
,
attrlist
,
taldict
,
metaldict
,
i18ndict
,
self
.
getpos
(),
isend
=
1
)
self
.
pop_xmlns
()
def
handle_endtag
(
self
,
tag
):
if
tag
in
EMPTY_HTML_TAGS
:
# </img> etc. in the source is an error
raise
EmptyTagError
(
tag
,
self
.
getpos
())
self
.
close_enclosed_tags
(
tag
)
self
.
gen
.
emitEndElement
(
tag
)
self
.
pop_xmlns
()
self
.
tagstack
.
pop
()
def
close_para_tags
(
self
,
tag
):
if
tag
in
EMPTY_HTML_TAGS
:
return
close_to
=
-
1
if
BLOCK_CLOSING_TAG_MAP
.
has_key
(
tag
):
blocks_to_close
=
BLOCK_CLOSING_TAG_MAP
[
tag
]
for
i
in
range
(
len
(
self
.
tagstack
)):
t
=
self
.
tagstack
[
i
]
if
t
in
blocks_to_close
:
if
close_to
==
-
1
:
close_to
=
i
elif
t
in
BLOCK_LEVEL_HTML_TAGS
:
close_to
=
-
1
elif
tag
in
PARA_LEVEL_HTML_TAGS
+
BLOCK_LEVEL_HTML_TAGS
:
i
=
len
(
self
.
tagstack
)
-
1
while
i
>=
0
:
closetag
=
self
.
tagstack
[
i
]
if
closetag
in
BLOCK_LEVEL_HTML_TAGS
:
break
if
closetag
in
PARA_LEVEL_HTML_TAGS
:
if
closetag
!=
"p"
:
raise
OpenTagError
(
self
.
tagstack
,
tag
,
self
.
getpos
())
close_to
=
i
i
=
i
-
1
if
close_to
>=
0
:
while
len
(
self
.
tagstack
)
>
close_to
:
self
.
implied_endtag
(
self
.
tagstack
[
-
1
],
1
)
def
close_enclosed_tags
(
self
,
tag
):
if
tag
not
in
self
.
tagstack
:
raise
NestingError
(
self
.
tagstack
,
tag
,
self
.
getpos
())
while
tag
!=
self
.
tagstack
[
-
1
]:
self
.
implied_endtag
(
self
.
tagstack
[
-
1
],
1
)
assert
self
.
tagstack
[
-
1
]
==
tag
def
implied_endtag
(
self
,
tag
,
implied
):
assert
tag
==
self
.
tagstack
[
-
1
]
assert
implied
in
(
-
1
,
1
,
2
)
isend
=
(
implied
<
0
)
if
tag
in
TIGHTEN_IMPLICIT_CLOSE_TAGS
:
# Pick out trailing whitespace from the program, and
# insert the close tag before the whitespace.
white
=
self
.
gen
.
unEmitWhitespace
()
else
:
white
=
None
self
.
gen
.
emitEndElement
(
tag
,
isend
=
isend
,
implied
=
implied
)
if
white
:
self
.
gen
.
emitRawText
(
white
)
self
.
tagstack
.
pop
()
self
.
pop_xmlns
()
def
handle_charref
(
self
,
name
):
self
.
gen
.
emitRawText
(
"&#%s;"
%
name
)
def
handle_entityref
(
self
,
name
):
self
.
gen
.
emitRawText
(
"&%s;"
%
name
)
def
handle_data
(
self
,
data
):
self
.
gen
.
emitRawText
(
data
)
def
handle_comment
(
self
,
data
):
self
.
gen
.
emitRawText
(
"<!--%s-->"
%
data
)
def
handle_decl
(
self
,
data
):
self
.
gen
.
emitRawText
(
"<!%s>"
%
data
)
def
handle_pi
(
self
,
data
):
self
.
gen
.
emitRawText
(
"<?%s>"
%
data
)
# Internal thingies
def
scan_xmlns
(
self
,
attrs
):
nsnew
=
{}
for
key
,
value
in
attrs
:
if
key
.
startswith
(
"xmlns:"
):
nsnew
[
key
[
6
:]]
=
value
if
nsnew
:
self
.
nsstack
.
append
(
self
.
nsdict
)
self
.
nsdict
=
self
.
nsdict
.
copy
()
self
.
nsdict
.
update
(
nsnew
)
else
:
self
.
nsstack
.
append
(
self
.
nsdict
)
def
pop_xmlns
(
self
):
self
.
nsdict
=
self
.
nsstack
.
pop
()
def
fixname
(
self
,
name
):
if
':'
in
name
:
prefix
,
suffix
=
name
.
split
(
':'
,
1
)
if
prefix
==
'xmlns'
:
nsuri
=
self
.
nsdict
.
get
(
suffix
)
if
nsuri
in
(
ZOPE_TAL_NS
,
ZOPE_METAL_NS
,
ZOPE_I18N_NS
):
return
name
,
name
,
prefix
else
:
nsuri
=
self
.
nsdict
.
get
(
prefix
)
if
nsuri
==
ZOPE_TAL_NS
:
return
name
,
suffix
,
'tal'
elif
nsuri
==
ZOPE_METAL_NS
:
return
name
,
suffix
,
'metal'
elif
nsuri
==
ZOPE_I18N_NS
:
return
name
,
suffix
,
'i18n'
return
name
,
name
,
0
def
process_ns
(
self
,
name
,
attrs
):
attrlist
=
[]
taldict
=
{}
metaldict
=
{}
i18ndict
=
{}
name
,
namebase
,
namens
=
self
.
fixname
(
name
)
for
item
in
attrs
:
key
,
value
=
item
key
,
keybase
,
keyns
=
self
.
fixname
(
key
)
ns
=
keyns
or
namens
# default to tag namespace
if
ns
and
ns
!=
'unknown'
:
item
=
(
key
,
value
,
ns
)
if
ns
==
'tal'
:
if
taldict
.
has_key
(
keybase
):
raise
TALError
(
"duplicate TAL attribute "
+
`keybase`
,
self
.
getpos
())
taldict
[
keybase
]
=
value
elif
ns
==
'metal'
:
if
metaldict
.
has_key
(
keybase
):
raise
METALError
(
"duplicate METAL attribute "
+
`keybase`
,
self
.
getpos
())
metaldict
[
keybase
]
=
value
elif
ns
==
'i18n'
:
if
i18ndict
.
has_key
(
keybase
):
raise
I18NError
(
"duplicate i18n attribute "
+
`keybase`
,
self
.
getpos
())
i18ndict
[
keybase
]
=
value
attrlist
.
append
(
item
)
if
namens
in
(
'metal'
,
'tal'
):
taldict
[
'tal tag'
]
=
namens
return
name
,
attrlist
,
taldict
,
metaldict
,
i18ndict
lib/python/TAL/ITALES.py
deleted
100644 → 0
View file @
1c0af142
"""Interface that a TALES engine provides to the METAL/TAL implementation."""
try
:
from
Interface
import
Interface
from
Interface.Attribute
import
Attribute
except
:
# Before 2.7
class
Interface
:
pass
def
Attribute
(
*
args
):
pass
class
ITALESCompiler
(
Interface
):
"""Compile-time interface provided by a TALES implementation.
The TAL compiler needs an instance of this interface to support
compilation of TALES expressions embedded in documents containing
TAL and METAL constructs.
"""
def
getCompilerError
():
"""Return the exception class raised for compilation errors.
"""
def
compile
(
expression
):
"""Return a compiled form of 'expression' for later evaluation.
'expression' is the source text of the expression.
The return value may be passed to the various evaluate*()
methods of the ITALESEngine interface. No compatibility is
required for the values of the compiled expression between
different ITALESEngine implementations.
"""
class
ITALESEngine
(
Interface
):
"""Render-time interface provided by a TALES implementation.
The TAL interpreter uses this interface to TALES to support
evaluation of the compiled expressions returned by
ITALESCompiler.compile().
"""
def
getCompiler
():
"""Return an object that supports ITALESCompiler."""
def
getDefault
():
"""Return the value of the 'default' TALES expression.
Checking a value for a match with 'default' should be done
using the 'is' operator in Python.
"""
def
setPosition
((
lineno
,
offset
)):
"""Inform the engine of the current position in the source file.
This is used to allow the evaluation engine to report
execution errors so that site developers can more easily
locate the offending expression.
"""
def
setSourceFile
(
filename
):
"""Inform the engine of the name of the current source file.
This is used to allow the evaluation engine to report
execution errors so that site developers can more easily
locate the offending expression.
"""
def
beginScope
():
"""Push a new scope onto the stack of open scopes.
"""
def
endScope
():
"""Pop one scope from the stack of open scopes.
"""
def
evaluate
(
compiled_expression
):
"""Evaluate an arbitrary expression.
No constraints are imposed on the return value.
"""
def
evaluateBoolean
(
compiled_expression
):
"""Evaluate an expression that must return a Boolean value.
"""
def
evaluateMacro
(
compiled_expression
):
"""Evaluate an expression that must return a macro program.
"""
def
evaluateStructure
(
compiled_expression
):
"""Evaluate an expression that must return a structured
document fragment.
The result of evaluating 'compiled_expression' must be a
string containing a parsable HTML or XML fragment. Any TAL
markup cnotained in the result string will be interpreted.
"""
def
evaluateText
(
compiled_expression
):
"""Evaluate an expression that must return text.
The returned text should be suitable for direct inclusion in
the output: any HTML or XML escaping or quoting is the
responsibility of the expression itself.
"""
def
evaluateValue
(
compiled_expression
):
"""Evaluate an arbitrary expression.
No constraints are imposed on the return value.
"""
def
createErrorInfo
(
exception
,
(
lineno
,
offset
)):
"""Returns an ITALESErrorInfo object.
The returned object is used to provide information about the
error condition for the on-error handler.
"""
def
setGlobal
(
name
,
value
):
"""Set a global variable.
The variable will be named 'name' and have the value 'value'.
"""
def
setLocal
(
name
,
value
):
"""Set a local variable in the current scope.
The variable will be named 'name' and have the value 'value'.
"""
def
setRepeat
(
name
,
compiled_expression
):
"""
"""
def
translate
(
domain
,
msgid
,
mapping
,
default
=
None
):
"""
See ITranslationService.translate()
"""
class
ITALESErrorInfo
(
Interface
):
type
=
Attribute
(
"type"
,
"The exception class."
)
value
=
Attribute
(
"value"
,
"The exception instance."
)
lineno
=
Attribute
(
"lineno"
,
"The line number the error occurred on in the source."
)
offset
=
Attribute
(
"offset"
,
"The character offset at which the error occurred."
)
lib/python/TAL/README.txt
deleted
100644 → 0
View file @
1c0af142
TAL - Template Attribute Language
---------------------------------
This is an implementation of TAL, the Zope Template Attribute
Language. For TAL, see the Zope Presentation Templates ZWiki:
http://dev.zope.org/Wikis/DevSite/Projects/ZPT/FrontPage
It is not a Zope product nor is it designed exclusively to run inside
of Zope, but if you have a Zope checkout that includes
Products/ParsedXML, its Expat parser will be used.
Prerequisites
-------------
You need:
- A recent checkout of Zope2; don't forget to run the wo_pcgi.py
script to compile everything. (See above -- this is now optional.)
- A recent checkout of the Zope2 product ParsedXML, accessible
throught <Zope2>/lib/python/Products/ParsedXML; don't forget to run
the setup.py script to compiles Expat. (Again, optional.)
- Python 1.5.2; the driver script refuses to work with other versions
unless you specify the -n option; this is done so that I don't
accidentally use Python 2.x features.
- Create a .path file containing proper module search path; it should
point the <Zope2>/lib/python directory that you want to use.
How To Play
-----------
(Don't forget to edit .path, see above!)
The script driver.py takes an XML file with TAL markup as argument and
writes the expanded version to standard output. The filename argument
defaults to tests/input/test01.xml.
Regression test
---------------
There are unit test suites in the 'tests' subdirectory; these can be
run with tests/run.py. This should print the testcase names plus
progress info, followed by a final line saying "OK". It requires that
../unittest.py exists.
There are a number of test files in the 'tests' subdirectory, named
tests/input/test<number>.xml and tests/input/test<number>.html. The
Python script ./runtest.py calls driver.main() for each test file, and
should print "<file> OK" for each one. These tests are also run as
part of the unit test suites, so tests/run.py is all you need.
What's Here
-----------
DummyEngine.py simple-minded TALES execution engine
TALInterpreter.py class to interpret intermediate code
TALGenerator.py class to generate intermediate code
XMLParser.py base class to parse XML, avoiding DOM
TALParser.py class to parse XML with TAL into intermediate code
HTMLTALParser.py class to parse HTML with TAL into intermediate code
HTMLParser.py HTML-parsing base class
driver.py script to demonstrate TAL expansion
timer.py script to time various processing phases
setpath.py hack to set sys.path and import ZODB
__init__.py empty file that makes this directory a package
runtest.py Python script to run file-comparison tests
ndiff.py helper for runtest.py to produce diffs
tests/ drectory with test files and output
tests/run.py Python script to run all tests
Author and License
------------------
This code is written by Guido van Rossum (project lead), Fred Drake,
and Tim Peters. It is owned by Digital Creations and can be
redistributed under the Zope Public License.
TO DO
-----
(See also http://www.zope.org/Members/jim/ZPTIssueTracker .)
- Need to remove leading whitespace and newline when omitting an
element (either through tal:replace with a value of nothing or
tal:condition with a false condition).
- Empty TAL/METAL attributes are ignored: tal:replace="" is ignored
rather than causing an error.
- HTMLTALParser.py and TALParser.py are silly names. Should be
HTMLTALCompiler.py and XMLTALCompiler.py (or maybe shortened,
without "TAL"?)
- Should we preserve case of tags and attribute names in HTML?
lib/python/TAL/TALDefs.py
deleted
100644 → 0
View file @
1c0af142
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
Common definitions used by TAL and METAL compilation an transformation.
"""
from
types
import
ListType
,
TupleType
from
ITALES
import
ITALESErrorInfo
TAL_VERSION
=
"1.5"
XML_NS
=
"http://www.w3.org/XML/1998/namespace"
# URI for XML namespace
XMLNS_NS
=
"http://www.w3.org/2000/xmlns/"
# URI for XML NS declarations
ZOPE_TAL_NS
=
"http://xml.zope.org/namespaces/tal"
ZOPE_METAL_NS
=
"http://xml.zope.org/namespaces/metal"
ZOPE_I18N_NS
=
"http://xml.zope.org/namespaces/i18n"
# This RE must exactly match the expression of the same name in the
# zope.i18n.simpletranslationservice module:
NAME_RE
=
"[a-zA-Z_][-a-zA-Z0-9_]*"
KNOWN_METAL_ATTRIBUTES
=
[
"define-macro"
,
"use-macro"
,
"define-slot"
,
"fill-slot"
,
"slot"
,
]
KNOWN_TAL_ATTRIBUTES
=
[
"define"
,
"condition"
,
"content"
,
"replace"
,
"repeat"
,
"attributes"
,
"on-error"
,
"omit-tag"
,
"tal tag"
,
]
KNOWN_I18N_ATTRIBUTES
=
[
"translate"
,
"domain"
,
"target"
,
"source"
,
"attributes"
,
"data"
,
"name"
,
]
class
TALError
(
Exception
):
def
__init__
(
self
,
msg
,
position
=
(
None
,
None
)):
assert
msg
!=
""
self
.
msg
=
msg
self
.
lineno
=
position
[
0
]
self
.
offset
=
position
[
1
]
self
.
filename
=
None
def
setFile
(
self
,
filename
):
self
.
filename
=
filename
def
__str__
(
self
):
result
=
self
.
msg
if
self
.
lineno
is
not
None
:
result
=
result
+
", at line %d"
%
self
.
lineno
if
self
.
offset
is
not
None
:
result
=
result
+
", column %d"
%
(
self
.
offset
+
1
)
if
self
.
filename
is
not
None
:
result
=
result
+
', in file %s'
%
self
.
filename
return
result
class
METALError
(
TALError
):
pass
class
TALESError
(
TALError
):
pass
class
I18NError
(
TALError
):
pass
class
ErrorInfo
:
__implements__
=
ITALESErrorInfo
def
__init__
(
self
,
err
,
position
=
(
None
,
None
)):
if
isinstance
(
err
,
Exception
):
self
.
type
=
err
.
__class__
self
.
value
=
err
else
:
self
.
type
=
err
self
.
value
=
None
self
.
lineno
=
position
[
0
]
self
.
offset
=
position
[
1
]
import
re
_attr_re
=
re
.
compile
(
r"\
s*([^
\s]+)\
s+([^
\s].*)\
Z
", re.S)
_subst_re = re.compile(r"
\
s
*
(
?
:(
text
|
structure
)
\
s
+
)
?
(.
*
)
\
Z
", re.S)
del re
def parseAttributeReplacements(arg, xml):
dict = {}
for part in splitParts(arg):
m = _attr_re.match(part)
if not m:
raise TALError("
Bad
syntax
in
attributes
:
" + `part`)
name, expr = m.group(1, 2)
if not xml:
name = name.lower()
if dict.has_key(name):
raise TALError("
Duplicate
attribute
name
in
attributes
:
" + `part`)
dict[name] = expr
return dict
def parseSubstitution(arg, position=(None, None)):
m = _subst_re.match(arg)
if not m:
raise TALError("
Bad
syntax
in
substitution
text
:
" + `arg`, position)
key, expr = m.group(1, 2)
if not key:
key = "
text
"
return key, expr
def splitParts(arg):
# Break in pieces at undoubled semicolons and
# change double semicolons to singles:
arg = arg.replace("
;;
", "
\
0
")
parts = arg.split(';')
parts = [p.replace("
\
0
", "
;
") for p in parts]
if len(parts) > 1 and not parts[-1].strip():
del parts[-1] # It ended in a semicolon
return parts
def isCurrentVersion(program):
version = getProgramVersion(program)
return version == TAL_VERSION
def getProgramMode(program):
version = getProgramVersion(program)
if (version == TAL_VERSION and isinstance(program[1], TupleType) and
len(program[1]) == 2):
opcode, mode = program[1]
if opcode == "
mode
":
return mode
return None
def getProgramVersion(program):
if (len(program) >= 2 and
isinstance(program[0], TupleType) and len(program[0]) == 2):
opcode, version = program[0]
if opcode == "
version
":
return version
return None
import re
_ent1_re = re.compile('&(?![A-Z#])', re.I)
_entch_re = re.compile('&([A-Z][A-Z0-9]*)(?![A-Z0-9;])', re.I)
_entn1_re = re.compile('&#(?![0-9X])', re.I)
_entnx_re = re.compile('&(#X[A-F0-9]*)(?![A-F0-9;])', re.I)
_entnd_re = re.compile('&(#[0-9][0-9]*)(?![0-9;])')
del re
def attrEscape(s):
"""Replace special characters '&<>' by character entities,
except when '&' already begins a syntactically valid entity."""
s = _ent1_re.sub('&', s)
s = _entch_re.sub(r'&
\
1
', s)
s = _entn1_re.sub('&#', s)
s = _entnx_re.sub(r'&
\
1
', s)
s = _entnd_re.sub(r'&
\
1
', s)
s = s.replace('<', '<')
s = s.replace('>', '>')
s = s.replace('"', '
&
quot
;
')
return s
lib/python/TAL/TALGenerator.py
deleted
100644 → 0
View file @
1c0af142
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
Code generator for TALInterpreter intermediate code.
"""
import
re
import
cgi
import
TALDefs
from
TALDefs
import
NAME_RE
,
TAL_VERSION
from
TALDefs
import
I18NError
,
METALError
,
TALError
from
TALDefs
import
parseSubstitution
from
TranslationContext
import
TranslationContext
,
DEFAULT_DOMAIN
I18N_REPLACE
=
1
I18N_CONTENT
=
2
I18N_EXPRESSION
=
3
_name_rx
=
re
.
compile
(
NAME_RE
)
class
TALGenerator
:
inMacroUse
=
0
inMacroDef
=
0
source_file
=
None
def
__init__
(
self
,
expressionCompiler
=
None
,
xml
=
1
,
source_file
=
None
):
if
not
expressionCompiler
:
from
DummyEngine
import
DummyEngine
expressionCompiler
=
DummyEngine
()
self
.
expressionCompiler
=
expressionCompiler
self
.
CompilerError
=
expressionCompiler
.
getCompilerError
()
# This holds the emitted opcodes representing the input
self
.
program
=
[]
# The program stack for when we need to do some sub-evaluation for an
# intermediate result. E.g. in an i18n:name tag for which the
# contents describe the ${name} value.
self
.
stack
=
[]
# Another stack of postponed actions. Elements on this stack are a
# dictionary; key/values contain useful information that
# emitEndElement needs to finish its calculations
self
.
todoStack
=
[]
self
.
macros
=
{}
self
.
slots
=
{}
self
.
slotStack
=
[]
self
.
xml
=
xml
self
.
emit
(
"version"
,
TAL_VERSION
)
self
.
emit
(
"mode"
,
xml
and
"xml"
or
"html"
)
if
source_file
is
not
None
:
self
.
source_file
=
source_file
self
.
emit
(
"setSourceFile"
,
source_file
)
self
.
i18nContext
=
TranslationContext
()
self
.
i18nLevel
=
0
def
getCode
(
self
):
assert
not
self
.
stack
assert
not
self
.
todoStack
return
self
.
optimize
(
self
.
program
),
self
.
macros
def
optimize
(
self
,
program
):
output
=
[]
collect
=
[]
cursor
=
0
if
self
.
xml
:
endsep
=
"/>"
else
:
endsep
=
" />"
for
cursor
in
xrange
(
len
(
program
)
+
1
):
try
:
item
=
program
[
cursor
]
except
IndexError
:
item
=
(
None
,
None
)
opcode
=
item
[
0
]
if
opcode
==
"rawtext"
:
collect
.
append
(
item
[
1
])
continue
if
opcode
==
"endTag"
:
collect
.
append
(
"</%s>"
%
item
[
1
])
continue
if
opcode
==
"startTag"
:
if
self
.
optimizeStartTag
(
collect
,
item
[
1
],
item
[
2
],
">"
):
continue
if
opcode
==
"startEndTag"
:
if
self
.
optimizeStartTag
(
collect
,
item
[
1
],
item
[
2
],
endsep
):
continue
if
opcode
in
(
"beginScope"
,
"endScope"
):
# Push *Scope instructions in front of any text instructions;
# this allows text instructions separated only by *Scope
# instructions to be joined together.
output
.
append
(
self
.
optimizeArgsList
(
item
))
continue
if
opcode
==
'noop'
:
# This is a spacer for end tags in the face of i18n:name
# attributes. We can't let the optimizer collect immediately
# following end tags into the same rawtextOffset.
opcode
=
None
pass
text
=
""
.
join
(
collect
)
if
text
:
i
=
text
.
rfind
(
"
\
n
"
)
if
i
>=
0
:
i
=
len
(
text
)
-
(
i
+
1
)
output
.
append
((
"rawtextColumn"
,
(
text
,
i
)))
else
:
output
.
append
((
"rawtextOffset"
,
(
text
,
len
(
text
))))
if
opcode
!=
None
:
output
.
append
(
self
.
optimizeArgsList
(
item
))
collect
=
[]
return
self
.
optimizeCommonTriple
(
output
)
def
optimizeArgsList
(
self
,
item
):
if
len
(
item
)
==
2
:
return
item
else
:
return
item
[
0
],
tuple
(
item
[
1
:])
# These codes are used to indicate what sort of special actions
# are needed for each special attribute. (Simple attributes don't
# get action codes.)
#
# The special actions (which are modal) are handled by
# TALInterpreter.attrAction() and .attrAction_tal().
#
# Each attribute is represented by a tuple:
#
# (name, value) -- a simple name/value pair, with
# no special processing
#
# (name, value, action, *extra) -- attribute with special
# processing needs, action is a
# code that indicates which
# branch to take, and *extra
# contains additional,
# action-specific information
# needed by the processing
#
def
optimizeStartTag
(
self
,
collect
,
name
,
attrlist
,
end
):
# return true if the tag can be converted to plain text
if
not
attrlist
:
collect
.
append
(
"<%s%s"
%
(
name
,
end
))
return
1
opt
=
1
new
=
[
"<"
+
name
]
for
i
in
range
(
len
(
attrlist
)):
item
=
attrlist
[
i
]
if
len
(
item
)
>
2
:
opt
=
0
name
,
value
,
action
=
item
[:
3
]
attrlist
[
i
]
=
(
name
,
value
,
action
)
+
item
[
3
:]
else
:
if
item
[
1
]
is
None
:
s
=
item
[
0
]
else
:
s
=
'%s="%s"'
%
(
item
[
0
],
TALDefs
.
attrEscape
(
item
[
1
]))
attrlist
[
i
]
=
item
[
0
],
s
new
.
append
(
" "
+
s
)
# if no non-optimizable attributes were found, convert to plain text
if
opt
:
new
.
append
(
end
)
collect
.
extend
(
new
)
return
opt
def
optimizeCommonTriple
(
self
,
program
):
if
len
(
program
)
<
3
:
return
program
output
=
program
[:
2
]
prev2
,
prev1
=
output
for
item
in
program
[
2
:]:
if
(
item
[
0
]
==
"beginScope"
and
prev1
[
0
]
==
"setPosition"
and
prev2
[
0
]
==
"rawtextColumn"
):
position
=
output
.
pop
()[
1
]
text
,
column
=
output
.
pop
()[
1
]
prev1
=
None
,
None
closeprev
=
0
if
output
and
output
[
-
1
][
0
]
==
"endScope"
:
closeprev
=
1
output
.
pop
()
item
=
(
"rawtextBeginScope"
,
(
text
,
column
,
position
,
closeprev
,
item
[
1
]))
output
.
append
(
item
)
prev2
=
prev1
prev1
=
item
return
output
def
todoPush
(
self
,
todo
):
self
.
todoStack
.
append
(
todo
)
def
todoPop
(
self
):
return
self
.
todoStack
.
pop
()
def
compileExpression
(
self
,
expr
):
try
:
return
self
.
expressionCompiler
.
compile
(
expr
)
except
self
.
CompilerError
,
err
:
raise
TALError
(
'%s in expression %s'
%
(
err
.
args
[
0
],
`expr`
),
self
.
position
)
def
pushProgram
(
self
):
self
.
stack
.
append
(
self
.
program
)
self
.
program
=
[]
def
popProgram
(
self
):
program
=
self
.
program
self
.
program
=
self
.
stack
.
pop
()
return
self
.
optimize
(
program
)
def
pushSlots
(
self
):
self
.
slotStack
.
append
(
self
.
slots
)
self
.
slots
=
{}
def
popSlots
(
self
):
slots
=
self
.
slots
self
.
slots
=
self
.
slotStack
.
pop
()
return
slots
def
emit
(
self
,
*
instruction
):
self
.
program
.
append
(
instruction
)
def
emitStartTag
(
self
,
name
,
attrlist
,
isend
=
0
):
if
isend
:
opcode
=
"startEndTag"
else
:
opcode
=
"startTag"
self
.
emit
(
opcode
,
name
,
attrlist
)
def
emitEndTag
(
self
,
name
):
if
self
.
xml
and
self
.
program
and
self
.
program
[
-
1
][
0
]
==
"startTag"
:
# Minimize empty element
self
.
program
[
-
1
]
=
(
"startEndTag"
,)
+
self
.
program
[
-
1
][
1
:]
else
:
self
.
emit
(
"endTag"
,
name
)
def
emitOptTag
(
self
,
name
,
optTag
,
isend
):
program
=
self
.
popProgram
()
#block
start
=
self
.
popProgram
()
#start tag
if
(
isend
or
not
program
)
and
self
.
xml
:
# Minimize empty element
start
[
-
1
]
=
(
"startEndTag"
,)
+
start
[
-
1
][
1
:]
isend
=
1
cexpr
=
optTag
[
0
]
if
cexpr
:
cexpr
=
self
.
compileExpression
(
optTag
[
0
])
self
.
emit
(
"optTag"
,
name
,
cexpr
,
optTag
[
1
],
isend
,
start
,
program
)
def
emitRawText
(
self
,
text
):
self
.
emit
(
"rawtext"
,
text
)
def
emitText
(
self
,
text
):
self
.
emitRawText
(
cgi
.
escape
(
text
))
def
emitDefines
(
self
,
defines
):
for
part
in
TALDefs
.
splitParts
(
defines
):
m
=
re
.
match
(
r"(?s)\
s*(?:(glo
bal|local)\
s+)?(%s)
\s+(.*)\
Z
" % NAME_RE, part)
if not m:
raise TALError("
invalid
define
syntax
:
" + `part`,
self.position)
scope, name, expr = m.group(1, 2, 3)
scope = scope or "
local
"
cexpr = self.compileExpression(expr)
if scope == "
local
":
self.emit("
setLocal
", name, cexpr)
else:
self.emit("
setGlobal
", name, cexpr)
def emitOnError(self, name, onError, TALtag, isend):
block = self.popProgram()
key, expr = parseSubstitution(onError)
cexpr = self.compileExpression(expr)
if key == "
text
":
self.emit("
insertText
", cexpr, [])
else:
assert key == "
structure
"
self.emit("
insertStructure
", cexpr, {}, [])
if TALtag:
self.emitOptTag(name, (None, 1), isend)
else:
self.emitEndTag(name)
handler = self.popProgram()
self.emit("
onError
", block, handler)
def emitCondition(self, expr):
cexpr = self.compileExpression(expr)
program = self.popProgram()
self.emit("
condition
", cexpr, program)
def emitRepeat(self, arg):
m = re.match("
(
?
s
)
\
s
*
(
%
s
)
\
s
+
(.
*
)
\
Z
" % NAME_RE, arg)
if not m:
raise TALError("
invalid
repeat
syntax
:
" + `arg`,
self.position)
name, expr = m.group(1, 2)
cexpr = self.compileExpression(expr)
program = self.popProgram()
self.emit("
loop
", name, cexpr, program)
def emitSubstitution(self, arg, attrDict={}):
key, expr = parseSubstitution(arg)
cexpr = self.compileExpression(expr)
program = self.popProgram()
if key == "
text
":
self.emit("
insertText
", cexpr, program)
else:
assert key == "
structure
"
self.emit("
insertStructure
", cexpr, attrDict, program)
def emitI18nVariable(self, stuff):
# Used for i18n:name attributes. arg is extra information describing
# how the contents of the variable should get filled in, and it will
# either be a 1-tuple or a 2-tuple. If arg[0] is None, then the
# i18n:name value is taken implicitly from the contents of the tag,
# e.g. "
I
live
in
<
span
i18n
:
name
=
"country"
>
the
USA
</
span
>
". In this
# case, arg[1] is the opcode sub-program describing the contents of
# the tag.
#
# When arg[0] is not None, it contains the tal expression used to
# calculate the contents of the variable, e.g.
# "
I
live
in
<
span
i18n
:
name
=
"country"
# tal:replace="here/countryOfOrigin" />"
varname
,
action
,
expression
=
stuff
m
=
_name_rx
.
match
(
varname
)
if
m
is
None
or
m
.
group
()
!=
varname
:
raise
TALError
(
"illegal i18n:name: %r"
%
varname
,
self
.
position
)
key
=
cexpr
=
None
program
=
self
.
popProgram
()
if
action
==
I18N_REPLACE
:
# This is a tag with an i18n:name and a tal:replace (implicit or
# explicit). Get rid of the first and last elements of the
# program, which are the start and end tag opcodes of the tag.
program
=
program
[
1
:
-
1
]
elif
action
==
I18N_CONTENT
:
# This is a tag with an i18n:name and a tal:content
# (explicit-only). Keep the first and last elements of the
# program, so we keep the start and end tag output.
pass
else
:
assert
action
==
I18N_EXPRESSION
key
,
expr
=
parseSubstitution
(
expression
)
cexpr
=
self
.
compileExpression
(
expr
)
self
.
emit
(
'i18nVariable'
,
varname
,
program
,
cexpr
,
int
(
key
==
"structure"
))
def
emitTranslation
(
self
,
msgid
,
i18ndata
):
program
=
self
.
popProgram
()
if
i18ndata
is
None
:
self
.
emit
(
'insertTranslation'
,
msgid
,
program
)
else
:
key
,
expr
=
parseSubstitution
(
i18ndata
)
cexpr
=
self
.
compileExpression
(
expr
)
assert
key
==
'text'
self
.
emit
(
'insertTranslation'
,
msgid
,
program
,
cexpr
)
def
emitDefineMacro
(
self
,
macroName
):
program
=
self
.
popProgram
()
macroName
=
macroName
.
strip
()
if
self
.
macros
.
has_key
(
macroName
):
raise
METALError
(
"duplicate macro definition: %s"
%
`macroName`
,
self
.
position
)
if
not
re
.
match
(
'%s$'
%
NAME_RE
,
macroName
):
raise
METALError
(
"invalid macro name: %s"
%
`macroName`
,
self
.
position
)
self
.
macros
[
macroName
]
=
program
self
.
inMacroDef
=
self
.
inMacroDef
-
1
self
.
emit
(
"defineMacro"
,
macroName
,
program
)
def
emitUseMacro
(
self
,
expr
):
cexpr
=
self
.
compileExpression
(
expr
)
program
=
self
.
popProgram
()
self
.
inMacroUse
=
0
self
.
emit
(
"useMacro"
,
expr
,
cexpr
,
self
.
popSlots
(),
program
)
def
emitDefineSlot
(
self
,
slotName
):
program
=
self
.
popProgram
()
slotName
=
slotName
.
strip
()
if
not
re
.
match
(
'%s$'
%
NAME_RE
,
slotName
):
raise
METALError
(
"invalid slot name: %s"
%
`slotName`
,
self
.
position
)
self
.
emit
(
"defineSlot"
,
slotName
,
program
)
def
emitFillSlot
(
self
,
slotName
):
program
=
self
.
popProgram
()
slotName
=
slotName
.
strip
()
if
self
.
slots
.
has_key
(
slotName
):
raise
METALError
(
"duplicate fill-slot name: %s"
%
`slotName`
,
self
.
position
)
if
not
re
.
match
(
'%s$'
%
NAME_RE
,
slotName
):
raise
METALError
(
"invalid slot name: %s"
%
`slotName`
,
self
.
position
)
self
.
slots
[
slotName
]
=
program
self
.
inMacroUse
=
1
self
.
emit
(
"fillSlot"
,
slotName
,
program
)
def
unEmitWhitespace
(
self
):
collect
=
[]
i
=
len
(
self
.
program
)
-
1
while
i
>=
0
:
item
=
self
.
program
[
i
]
if
item
[
0
]
!=
"rawtext"
:
break
text
=
item
[
1
]
if
not
re
.
match
(
r"\
A
\s*\
Z
", text):
break
collect.append(text)
i = i-1
del self.program[i+1:]
if i >= 0 and self.program[i][0] == "
rawtext
":
text = self.program[i][1]
m = re.search(r"
\
s
+
\
Z
", text)
if m:
self.program[i] = ("
rawtext
", text[:m.start()])
collect.append(m.group())
collect.reverse()
return "".join(collect)
def unEmitNewlineWhitespace(self):
collect = []
i = len(self.program)
while i > 0:
i = i-1
item = self.program[i]
if item[0] != "
rawtext
":
break
text = item[1]
if re.match(r"
\
A
[
\
t
]
*
\
Z
", text):
collect.append(text)
continue
m = re.match(r"
(
?
s
)
^
(.
*
)(
\
n
[
\
t
]
*
)
\
Z
", text)
if not m:
break
text, rest = m.group(1, 2)
collect.reverse()
rest = rest + "".join(collect)
del self.program[i:]
if text:
self.emit("
rawtext
", text)
return rest
return None
def replaceAttrs(self, attrlist, repldict):
# Each entry in attrlist starts like (name, value).
# Result is (name, value, action, expr, xlat) if there is a
# tal:attributes entry for that attribute. Additional attrs
# defined only by tal:attributes are added here.
#
# (name, value, action, expr, xlat)
if not repldict:
return attrlist
newlist = []
for item in attrlist:
key = item[0]
if repldict.has_key(key):
expr, xlat, msgid = repldict[key]
item = item[:2] + ("
replace
", expr, xlat, msgid)
del repldict[key]
newlist.append(item)
# Add dynamic-only attributes
for key, (expr, xlat, msgid) in repldict.items():
newlist.append((key, None, "
insert
", expr, xlat, msgid))
return newlist
def emitStartElement(self, name, attrlist, taldict, metaldict, i18ndict,
position=(None, None), isend=0):
if not taldict and not metaldict and not i18ndict:
# Handle the simple, common case
self.emitStartTag(name, attrlist, isend)
self.todoPush({})
if isend:
self.emitEndElement(name, isend)
return
self.position = position
for key, value in taldict.items():
if key not in TALDefs.KNOWN_TAL_ATTRIBUTES:
raise TALError("
bad
TAL
attribute
:
" + `key`, position)
if not (value or key == 'omit-tag'):
raise TALError("
missing
value
for
TAL
attribute
:
" +
`key`, position)
for key, value in metaldict.items():
if key not in TALDefs.KNOWN_METAL_ATTRIBUTES:
raise METALError("
bad
METAL
attribute
:
" + `key`,
position)
if not value:
raise TALError("
missing
value
for
METAL
attribute
:
" +
`key`, position)
for key, value in i18ndict.items():
if key not in TALDefs.KNOWN_I18N_ATTRIBUTES:
raise I18NError("
bad
i18n
attribute
:
" + `key`, position)
if not value and key in ("
attributes
", "
data
", "
id
"):
raise I18NError("
missing
value
for
i18n
attribute
:
" +
`key`, position)
todo = {}
defineMacro = metaldict.get("
define
-
macro
")
useMacro = metaldict.get("
use
-
macro
")
defineSlot = metaldict.get("
define
-
slot
")
fillSlot = metaldict.get("
fill
-
slot
")
define = taldict.get("
define
")
condition = taldict.get("
condition
")
repeat = taldict.get("
repeat
")
content = taldict.get("
content
")
replace = taldict.get("
replace
")
attrsubst = taldict.get("
attributes
")
onError = taldict.get("
on
-
error
")
omitTag = taldict.get("
omit
-
tag
")
TALtag = taldict.get("
tal
tag
")
i18nattrs = i18ndict.get("
attributes
")
# Preserve empty string if implicit msgids are used. We'll generate
# code with the msgid='' and calculate the right implicit msgid during
# interpretation phase.
msgid = i18ndict.get("
translate
")
varname = i18ndict.get('name')
i18ndata = i18ndict.get('data')
if varname and not self.i18nLevel:
raise I18NError(
"
i18n
:
name
can
only
occur
inside
a
translation
unit
",
position)
if i18ndata and not msgid:
raise I18NError("
i18n
:
data
must
be
accompanied
by
i18n
:
translate
",
position)
if len(metaldict) > 1 and (defineMacro or useMacro):
raise METALError("
define
-
macro
and
use
-
macro
cannot
be
used
"
"
together
or
with
define
-
slot
or
fill
-
slot
",
position)
if replace:
if content:
raise TALError(
"
tal
:
content
and
tal
:
replace
are
mutually
exclusive
",
position)
if msgid is not None:
raise I18NError(
"
i18n
:
translate
and
tal
:
replace
are
mutually
exclusive
",
position)
repeatWhitespace = None
if repeat:
# Hack to include preceding whitespace in the loop program
repeatWhitespace = self.unEmitNewlineWhitespace()
if position != (None, None):
# XXX at some point we should insist on a non-trivial position
self.emit("
setPosition
", position)
if self.inMacroUse:
if fillSlot:
self.pushProgram()
if self.source_file is not None:
self.emit("
setSourceFile
", self.source_file)
todo["
fillSlot
"] = fillSlot
self.inMacroUse = 0
else:
if fillSlot:
raise METALError("
fill
-
slot
must
be
within
a
use
-
macro
",
position)
if not self.inMacroUse:
if defineMacro:
self.pushProgram()
self.emit("
version
", TAL_VERSION)
self.emit("
mode
", self.xml and "
xml
" or "
html
")
if self.source_file is not None:
self.emit("
setSourceFile
", self.source_file)
todo["
defineMacro
"] = defineMacro
self.inMacroDef = self.inMacroDef + 1
if useMacro:
self.pushSlots()
self.pushProgram()
todo["
useMacro
"] = useMacro
self.inMacroUse = 1
if defineSlot:
if not self.inMacroDef:
raise METALError(
"
define
-
slot
must
be
within
a
define
-
macro
",
position)
self.pushProgram()
todo["
defineSlot
"] = defineSlot
if defineSlot or i18ndict:
domain = i18ndict.get("
domain
") or self.i18nContext.domain
source = i18ndict.get("
source
") or self.i18nContext.source
target = i18ndict.get("
target
") or self.i18nContext.target
if ( domain != DEFAULT_DOMAIN
or source is not None
or target is not None):
self.i18nContext = TranslationContext(self.i18nContext,
domain=domain,
source=source,
target=target)
self.emit("
beginI18nContext
",
{"
domain
": domain, "
source
": source,
"
target
": target})
todo["
i18ncontext
"] = 1
if taldict or i18ndict:
dict = {}
for item in attrlist:
key, value = item[:2]
dict[key] = value
self.emit("
beginScope
", dict)
todo["
scope
"] = 1
if onError:
self.pushProgram() # handler
if TALtag:
self.pushProgram() # start
self.emitStartTag(name, list(attrlist)) # Must copy attrlist!
if TALtag:
self.pushProgram() # start
self.pushProgram() # block
todo["
onError
"] = onError
if define:
self.emitDefines(define)
todo["
define
"] = define
if condition:
self.pushProgram()
todo["
condition
"] = condition
if repeat:
todo["
repeat
"] = repeat
self.pushProgram()
if repeatWhitespace:
self.emitText(repeatWhitespace)
if content:
if varname:
todo['i18nvar'] = (varname, I18N_CONTENT, None)
todo["
content
"] = content
self.pushProgram()
else:
todo["
content
"] = content
elif replace:
# tal:replace w/ i18n:name has slightly different semantics. What
# we're actually replacing then is the contents of the ${name}
# placeholder.
if varname:
todo['i18nvar'] = (varname, I18N_EXPRESSION, replace)
else:
todo["
replace
"] = replace
self.pushProgram()
# i18n:name w/o tal:replace uses the content as the interpolation
# dictionary values
elif varname:
todo['i18nvar'] = (varname, I18N_REPLACE, None)
self.pushProgram()
if msgid is not None:
self.i18nLevel += 1
todo['msgid'] = msgid
if i18ndata:
todo['i18ndata'] = i18ndata
optTag = omitTag is not None or TALtag
if optTag:
todo["
optional
tag
"] = omitTag, TALtag
self.pushProgram()
if attrsubst or i18nattrs:
if attrsubst:
repldict = TALDefs.parseAttributeReplacements(attrsubst,
self.xml)
else:
repldict = {}
if i18nattrs:
i18nattrs = _parseI18nAttributes(i18nattrs, attrlist, repldict,
self.position, self.xml,
self.source_file)
else:
i18nattrs = {}
# Convert repldict's name-->expr mapping to a
# name-->(compiled_expr, translate) mapping
for key, value in repldict.items():
if i18nattrs.get(key, None):
raise I18NError(
("
attribute
[
%
s
]
cannot
both
be
part
of
tal
:
attributes
" +
"
and
have
a
msgid
in
i18n
:
attributes
") % key,
position)
ce = self.compileExpression(value)
repldict[key] = ce, key in i18nattrs, i18nattrs.get(key)
for key in i18nattrs:
if not repldict.has_key(key):
repldict[key] = None, 1, i18nattrs.get(key)
else:
repldict = {}
if replace:
todo["
repldict
"] = repldict
repldict = {}
self.emitStartTag(name, self.replaceAttrs(attrlist, repldict), isend)
if optTag:
self.pushProgram()
if content and not varname:
self.pushProgram()
if msgid is not None:
self.pushProgram()
if content and varname:
self.pushProgram()
if todo and position != (None, None):
todo["
position
"] = position
self.todoPush(todo)
if isend:
self.emitEndElement(name, isend)
def emitEndElement(self, name, isend=0, implied=0):
todo = self.todoPop()
if not todo:
# Shortcut
if not isend:
self.emitEndTag(name)
return
self.position = position = todo.get("
position
", (None, None))
defineMacro = todo.get("
defineMacro
")
useMacro = todo.get("
useMacro
")
defineSlot = todo.get("
defineSlot
")
fillSlot = todo.get("
fillSlot
")
repeat = todo.get("
repeat
")
content = todo.get("
content
")
replace = todo.get("
replace
")
condition = todo.get("
condition
")
onError = todo.get("
onError
")
repldict = todo.get("
repldict
", {})
scope = todo.get("
scope
")
optTag = todo.get("
optional
tag
")
msgid = todo.get('msgid')
i18ncontext = todo.get("
i18ncontext
")
varname = todo.get('i18nvar')
i18ndata = todo.get('i18ndata')
if implied > 0:
if defineMacro or useMacro or defineSlot or fillSlot:
exc = METALError
what = "
METAL
"
else:
exc = TALError
what = "
TAL
"
raise exc("
%
s
attributes
on
<%
s
>
require
explicit
</%
s
>
" %
(what, name, name), position)
# If there's no tal:content or tal:replace in the tag with the
# i18n:name, tal:replace is the default.
if content:
self.emitSubstitution(content, {})
# If we're looking at an implicit msgid, emit the insertTranslation
# opcode now, so that the end tag doesn't become part of the implicit
# msgid. If we're looking at an explicit msgid, it's better to emit
# the opcode after the i18nVariable opcode so we can better handle
# tags with both of them in them (and in the latter case, the contents
# would be thrown away for msgid purposes).
#
# Still, we should emit insertTranslation opcode before i18nVariable
# in case tal:content, i18n:translate and i18n:name in the same tag
if msgid is not None:
if (not varname) or (
varname and (varname[1] == I18N_CONTENT)):
self.emitTranslation(msgid, i18ndata)
self.i18nLevel -= 1
if optTag:
self.emitOptTag(name, optTag, isend)
elif not isend:
# If we're processing the end tag for a tag that contained
# i18n:name, we need to make sure that optimize() won't collect
# immediately following end tags into the same rawtextOffset, so
# put a spacer here that the optimizer will recognize.
if varname:
self.emit('noop')
self.emitEndTag(name)
# If i18n:name appeared in the same tag as tal:replace then we're
# going to do the substitution a little bit differently. The results
# of the expression go into the i18n substitution dictionary.
if replace:
self.emitSubstitution(replace, repldict)
elif varname:
# o varname[0] is the variable name
# o varname[1] is either
# - I18N_REPLACE for implicit tal:replace
# - I18N_CONTENT for tal:content
# - I18N_EXPRESSION for explicit tal:replace
# o varname[2] will be None for the first two actions and the
# replacement tal expression for the third action. This
# can include a 'text' or 'structure' indicator.
assert (varname[1]
in [I18N_REPLACE, I18N_CONTENT, I18N_EXPRESSION])
self.emitI18nVariable(varname)
# Do not test for "
msgid
is
not
None
", i.e. we only want to test for
# explicit msgids here. See comment above.
if msgid is not None:
# in case tal:content, i18n:translate and i18n:name in the
# same tag insertTranslation opcode has already been
# emitted
if varname and (varname[1] <> I18N_CONTENT):
self.emitTranslation(msgid, i18ndata)
if repeat:
self.emitRepeat(repeat)
if condition:
self.emitCondition(condition)
if onError:
self.emitOnError(name, onError, optTag and optTag[1], isend)
if scope:
self.emit("
endScope
")
if i18ncontext:
self.emit("
endI18nContext
")
assert self.i18nContext.parent is not None
self.i18nContext = self.i18nContext.parent
if defineSlot:
self.emitDefineSlot(defineSlot)
if fillSlot:
self.emitFillSlot(fillSlot)
if useMacro:
self.emitUseMacro(useMacro)
if defineMacro:
self.emitDefineMacro(defineMacro)
def _parseI18nAttributes(i18nattrs, attrlist, repldict, position,
xml, source_file):
def addAttribute(dic, attr, msgid, position, xml):
if not xml:
attr = attr.lower()
if attr in dic:
raise TALError(
"
attribute
may
only
be
specified
once
in
i18n
:
attributes
:
"
+ attr,
position)
dic[attr] = msgid
d = {}
if ';' in i18nattrs:
i18nattrlist = i18nattrs.split(';')
i18nattrlist = [attr.strip().split()
for attr in i18nattrlist if attr.strip()]
for parts in i18nattrlist:
if len(parts) > 2:
raise TALError("
illegal
i18n
:
attributes
specification
:
%
r"
% parts, position)
if len(parts) == 2:
attr, msgid = parts
else:
# len(parts) == 1
attr = parts[0]
msgid = None
addAttribute(d, attr, msgid, position, xml)
else:
i18nattrlist = i18nattrs.split()
if len(i18nattrlist) == 1:
addAttribute(d, i18nattrlist[0], None, position, xml)
elif len(i18nattrlist) == 2:
staticattrs = [attr[0] for attr in attrlist if len(attr) == 2]
if (not i18nattrlist[1] in staticattrs) and (
not i18nattrlist[1] in repldict):
attr, msgid = i18nattrlist
addAttribute(d, attr, msgid, position, xml)
else:
import warnings
warnings.warn(I18N_ATTRIBUTES_WARNING
% (source_file, str(position), i18nattrs)
, DeprecationWarning)
msgid = None
for attr in i18nattrlist:
addAttribute(d, attr, msgid, position, xml)
else:
import warnings
warnings.warn(I18N_ATTRIBUTES_WARNING
% (source_file, str(position), i18nattrs)
, DeprecationWarning)
msgid = None
for attr in i18nattrlist:
addAttribute(d, attr, msgid, position, xml)
return d
I18N_ATTRIBUTES_WARNING = (
'Space separated attributes in i18n:attributes'
' are deprecated (i18n:attributes="
value
title
"). Please use'
' semicolon to separate attributes'
' (i18n:attributes="
value
;
title
").'
'
\
n
File %s at row, column %s
\
n
Attributes %s')
def test():
t = TALGenerator()
t.pushProgram()
t.emit("
bar
")
p = t.popProgram()
t.emit("
foo
", p)
if __name__ == "
__main__
":
test()
lib/python/TAL/TALInterpreter.py
deleted
100644 → 0
View file @
1c0af142
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Interpreter for a pre-compiled TAL program.
$Id$
"""
import
cgi
import
sys
import
re
# Do not use cStringIO here! It's not unicode aware. :(
from
StringIO
import
StringIO
from
DocumentTemplate.DT_Util
import
ustr
from
ZODB.POSException
import
ConflictError
# BBB 2005/10/10 -- MessageIDs are to be removed for Zope 3.3
import
zope.deprecation
zope
.
deprecation
.
__show__
.
off
()
from
zope.i18nmessageid
import
Message
,
MessageID
zope
.
deprecation
.
__show__
.
on
()
from
TALDefs
import
attrEscape
,
TAL_VERSION
,
METALError
from
TALDefs
import
isCurrentVersion
from
TALDefs
import
getProgramVersion
,
getProgramMode
from
TALGenerator
import
TALGenerator
from
TranslationContext
import
TranslationContext
# This will become (MessageID, Message) when we use Zope 3.1 as a base:
I18nMessageTypes
=
Message
,
MessageID
# TODO: In Python 2.4 we can use frozenset() instead of dict.fromkeys()
BOOLEAN_HTML_ATTRS
=
dict
.
fromkeys
([
# List of Boolean attributes in HTML that should be rendered in
# minimized form (e.g. <img ismap> rather than <img ismap="">)
# From http://www.w3.org/TR/xhtml1/#guidelines (C.10)
# TODO: The problem with this is that this is not valid XML and
# can't be parsed back!
"compact"
,
"nowrap"
,
"ismap"
,
"declare"
,
"noshade"
,
"checked"
,
"disabled"
,
"readonly"
,
"multiple"
,
"selected"
,
"noresize"
,
"defer"
])
_nulljoin
=
''
.
join
_spacejoin
=
' '
.
join
def
normalize
(
text
):
# Now we need to normalize the whitespace in implicit message ids and
# implicit $name substitution values by stripping leading and trailing
# whitespace, and folding all internal whitespace to a single space.
return
_spacejoin
(
text
.
split
())
NAME_RE
=
r"[a-zA-Z][a-zA-Z0-9_]*"
_interp_regex
=
re
.
compile
(
r'(?<!\
$)(
\$(?:%(n)s|{%(n)s}))'
%
({
'n'
:
NAME_RE
}))
_get_var_regex
=
re
.
compile
(
r'%(n)s'
%
({
'n'
:
NAME_RE
}))
def
interpolate
(
text
,
mapping
):
"""Interpolate ${keyword} substitutions.
This is called when no translation is provided by the translation
service.
"""
if
not
mapping
:
return
text
# Find all the spots we want to substitute.
to_replace
=
_interp_regex
.
findall
(
text
)
# Now substitute with the variables in mapping.
for
string
in
to_replace
:
var
=
_get_var_regex
.
findall
(
string
)[
0
]
if
mapping
.
has_key
(
var
):
# Call ustr because we may have an integer for instance.
subst
=
ustr
(
mapping
[
var
])
try
:
text
=
text
.
replace
(
string
,
subst
)
except
UnicodeError
:
# subst contains high-bit chars...
# As we have no way of knowing the correct encoding,
# substitue something instead of raising an exception.
subst
=
`subst`
[
1
:
-
1
]
text
=
text
.
replace
(
string
,
subst
)
return
text
class
AltTALGenerator
(
TALGenerator
):
def
__init__
(
self
,
repldict
,
expressionCompiler
=
None
,
xml
=
0
):
self
.
repldict
=
repldict
self
.
enabled
=
1
TALGenerator
.
__init__
(
self
,
expressionCompiler
,
xml
)
def
enable
(
self
,
enabled
):
self
.
enabled
=
enabled
def
emit
(
self
,
*
args
):
if
self
.
enabled
:
TALGenerator
.
emit
(
self
,
*
args
)
def
emitStartElement
(
self
,
name
,
attrlist
,
taldict
,
metaldict
,
i18ndict
,
position
=
(
None
,
None
),
isend
=
0
):
metaldict
=
{}
taldict
=
{}
i18ndict
=
{}
if
self
.
enabled
and
self
.
repldict
:
taldict
[
"attributes"
]
=
"x x"
TALGenerator
.
emitStartElement
(
self
,
name
,
attrlist
,
taldict
,
metaldict
,
i18ndict
,
position
,
isend
)
def
replaceAttrs
(
self
,
attrlist
,
repldict
):
if
self
.
enabled
and
self
.
repldict
:
repldict
=
self
.
repldict
self
.
repldict
=
None
return
TALGenerator
.
replaceAttrs
(
self
,
attrlist
,
repldict
)
class
TALInterpreter
:
"""TAL interpreter.
"""
def
__init__
(
self
,
program
,
macros
,
engine
,
stream
=
None
,
debug
=
0
,
wrap
=
60
,
metal
=
1
,
tal
=
1
,
showtal
=-
1
,
strictinsert
=
1
,
stackLimit
=
100
,
i18nInterpolate
=
1
):
"""Create a TAL interpreter.
Optional arguments:
stream -- output stream (defaults to sys.stdout).
debug -- enable debugging output to sys.stderr (off by default).
wrap -- try to wrap attributes on opening tags to this number of
column (default: 60).
metal -- enable METAL macro processing (on by default).
tal -- enable TAL processing (on by default).
showtal -- do not strip away TAL directives. A special value of
-1 (which is the default setting) enables showtal when TAL
processing is disabled, and disables showtal when TAL processing is
enabled. Note that you must use 0, 1, or -1; true boolean values
are not supported (TODO: why?).
strictinsert -- enable TAL processing and stricter HTML/XML
checking on text produced by structure inserts (on by default).
Note that Zope turns this value off by default.
stackLimit -- set macro nesting limit (default: 100).
i18nInterpolate -- enable i18n translations (default: on).
"""
self
.
program
=
program
self
.
macros
=
macros
self
.
engine
=
engine
# Execution engine (aka context)
self
.
Default
=
engine
.
getDefault
()
self
.
_currentTag
=
""
self
.
_stream_stack
=
[
stream
or
sys
.
stdout
]
self
.
popStream
()
self
.
debug
=
debug
self
.
wrap
=
wrap
self
.
metal
=
metal
self
.
tal
=
tal
if
tal
:
self
.
dispatch
=
self
.
bytecode_handlers_tal
else
:
self
.
dispatch
=
self
.
bytecode_handlers
assert
showtal
in
(
-
1
,
0
,
1
)
if
showtal
==
-
1
:
showtal
=
(
not
tal
)
self
.
showtal
=
showtal
self
.
strictinsert
=
strictinsert
self
.
stackLimit
=
stackLimit
self
.
html
=
0
self
.
endsep
=
"/>"
self
.
endlen
=
len
(
self
.
endsep
)
self
.
macroStack
=
[]
self
.
position
=
None
,
None
# (lineno, offset)
self
.
col
=
0
self
.
level
=
0
self
.
scopeLevel
=
0
self
.
sourceFile
=
None
self
.
i18nStack
=
[]
self
.
i18nInterpolate
=
i18nInterpolate
self
.
i18nContext
=
TranslationContext
()
def
StringIO
(
self
):
# Third-party products wishing to provide a full Unicode-aware
# StringIO can do so by monkey-patching this method.
return
FasterStringIO
()
def
saveState
(
self
):
return
(
self
.
position
,
self
.
col
,
self
.
stream
,
self
.
_stream_stack
,
self
.
scopeLevel
,
self
.
level
,
self
.
i18nContext
)
def
restoreState
(
self
,
state
):
(
self
.
position
,
self
.
col
,
self
.
stream
,
self
.
_stream_stack
,
scopeLevel
,
level
,
i18n
)
=
state
self
.
_stream_write
=
self
.
stream
.
write
assert
self
.
level
==
level
while
self
.
scopeLevel
>
scopeLevel
:
self
.
engine
.
endScope
()
self
.
scopeLevel
=
self
.
scopeLevel
-
1
self
.
engine
.
setPosition
(
self
.
position
)
self
.
i18nContext
=
i18n
def
restoreOutputState
(
self
,
state
):
(
dummy
,
self
.
col
,
self
.
stream
,
self
.
_stream_stack
,
scopeLevel
,
level
,
i18n
)
=
state
self
.
_stream_write
=
self
.
stream
.
write
assert
self
.
level
==
level
assert
self
.
scopeLevel
==
scopeLevel
def
pushMacro
(
self
,
macroName
,
slots
,
entering
=
1
):
if
len
(
self
.
macroStack
)
>=
self
.
stackLimit
:
raise
METALError
(
"macro nesting limit (%d) exceeded "
"by %s"
%
(
self
.
stackLimit
,
`macroName`
))
self
.
macroStack
.
append
([
macroName
,
slots
,
entering
,
self
.
i18nContext
])
def
popMacro
(
self
):
return
self
.
macroStack
.
pop
()
def
__call__
(
self
):
assert
self
.
level
==
0
assert
self
.
scopeLevel
==
0
assert
self
.
i18nContext
.
parent
is
None
self
.
interpret
(
self
.
program
)
assert
self
.
level
==
0
assert
self
.
scopeLevel
==
0
assert
self
.
i18nContext
.
parent
is
None
if
self
.
col
>
0
:
self
.
_stream_write
(
"
\
n
"
)
self
.
col
=
0
def
pushStream
(
self
,
newstream
):
self
.
_stream_stack
.
append
(
self
.
stream
)
self
.
stream
=
newstream
self
.
_stream_write
=
self
.
stream
.
write
def
popStream
(
self
):
self
.
stream
=
self
.
_stream_stack
.
pop
()
self
.
_stream_write
=
self
.
stream
.
write
def
stream_write
(
self
,
s
,
len
=
len
):
self
.
_stream_write
(
s
)
i
=
s
.
rfind
(
'
\
n
'
)
if
i
<
0
:
self
.
col
=
self
.
col
+
len
(
s
)
else
:
self
.
col
=
len
(
s
)
-
(
i
+
1
)
bytecode_handlers
=
{}
def
interpret
(
self
,
program
):
oldlevel
=
self
.
level
self
.
level
=
oldlevel
+
1
handlers
=
self
.
dispatch
try
:
if
self
.
debug
:
for
(
opcode
,
args
)
in
program
:
s
=
"%sdo_%s(%s)
\
n
"
%
(
" "
*
self
.
level
,
opcode
,
repr
(
args
))
if
len
(
s
)
>
80
:
s
=
s
[:
76
]
+
"...
\
n
"
sys
.
stderr
.
write
(
s
)
handlers
[
opcode
](
self
,
args
)
else
:
for
(
opcode
,
args
)
in
program
:
handlers
[
opcode
](
self
,
args
)
finally
:
self
.
level
=
oldlevel
def
do_version
(
self
,
version
):
assert
version
==
TAL_VERSION
bytecode_handlers
[
"version"
]
=
do_version
def
do_mode
(
self
,
mode
):
assert
mode
in
(
"html"
,
"xml"
)
self
.
html
=
(
mode
==
"html"
)
if
self
.
html
:
self
.
endsep
=
" />"
else
:
self
.
endsep
=
"/>"
self
.
endlen
=
len
(
self
.
endsep
)
bytecode_handlers
[
"mode"
]
=
do_mode
def
do_setSourceFile
(
self
,
source_file
):
self
.
sourceFile
=
source_file
self
.
engine
.
setSourceFile
(
source_file
)
bytecode_handlers
[
"setSourceFile"
]
=
do_setSourceFile
def
do_setPosition
(
self
,
position
):
self
.
position
=
position
self
.
engine
.
setPosition
(
position
)
bytecode_handlers
[
"setPosition"
]
=
do_setPosition
def
do_startEndTag
(
self
,
stuff
):
self
.
do_startTag
(
stuff
,
self
.
endsep
,
self
.
endlen
)
bytecode_handlers
[
"startEndTag"
]
=
do_startEndTag
def
do_startTag
(
self
,
(
name
,
attrList
),
end
=
">"
,
endlen
=
1
,
_len
=
len
):
# The bytecode generator does not cause calls to this method
# for start tags with no attributes; those are optimized down
# to rawtext events. Hence, there is no special "fast path"
# for that case.
self
.
_currentTag
=
name
L
=
[
"<"
,
name
]
append
=
L
.
append
col
=
self
.
col
+
_len
(
name
)
+
1
wrap
=
self
.
wrap
align
=
col
+
1
if
align
>=
wrap
/
2
:
align
=
4
# Avoid a narrow column far to the right
attrAction
=
self
.
dispatch
[
"<attrAction>"
]
try
:
for
item
in
attrList
:
if
_len
(
item
)
==
2
:
name
,
s
=
item
else
:
# item[2] is the 'action' field:
if
item
[
2
]
in
(
'metal'
,
'tal'
,
'xmlns'
,
'i18n'
):
if
not
self
.
showtal
:
continue
ok
,
name
,
s
=
self
.
attrAction
(
item
)
else
:
ok
,
name
,
s
=
attrAction
(
self
,
item
)
if
not
ok
:
continue
slen
=
_len
(
s
)
if
(
wrap
and
col
>=
align
and
col
+
1
+
slen
>
wrap
):
append
(
"
\
n
"
)
append
(
" "
*
align
)
col
=
align
+
slen
else
:
append
(
" "
)
col
=
col
+
1
+
slen
append
(
s
)
append
(
end
)
col
=
col
+
endlen
finally
:
self
.
_stream_write
(
_nulljoin
(
L
))
self
.
col
=
col
bytecode_handlers
[
"startTag"
]
=
do_startTag
def
attrAction
(
self
,
item
):
name
,
value
,
action
=
item
[:
3
]
if
action
==
'insert'
:
return
0
,
name
,
value
macs
=
self
.
macroStack
if
action
==
'metal'
and
self
.
metal
and
macs
:
if
len
(
macs
)
>
1
or
not
macs
[
-
1
][
2
]:
# Drop all METAL attributes at a use-depth above one.
return
0
,
name
,
value
# Clear 'entering' flag
macs
[
-
1
][
2
]
=
0
# Convert or drop depth-one METAL attributes.
i
=
name
.
rfind
(
":"
)
+
1
prefix
,
suffix
=
name
[:
i
],
name
[
i
:]
if
suffix
==
"define-macro"
:
# Convert define-macro as we enter depth one.
name
=
prefix
+
"use-macro"
value
=
macs
[
-
1
][
0
]
# Macro name
elif
suffix
==
"define-slot"
:
name
=
prefix
+
"fill-slot"
elif
suffix
==
"fill-slot"
:
pass
else
:
return
0
,
name
,
value
if
value
is
None
:
value
=
name
else
:
value
=
'%s="%s"'
%
(
name
,
attrEscape
(
value
))
return
1
,
name
,
value
def
attrAction_tal
(
self
,
item
):
name
,
value
,
action
=
item
[:
3
]
ok
=
1
expr
,
xlat
,
msgid
=
item
[
3
:]
if
self
.
html
and
name
.
lower
()
in
BOOLEAN_HTML_ATTRS
:
evalue
=
self
.
engine
.
evaluateBoolean
(
item
[
3
])
if
evalue
is
self
.
Default
:
if
action
==
'insert'
:
# Cancelled insert
ok
=
0
elif
evalue
:
value
=
None
else
:
ok
=
0
elif
expr
is
not
None
:
evalue
=
self
.
engine
.
evaluateText
(
item
[
3
])
if
evalue
is
self
.
Default
:
if
action
==
'insert'
:
# Cancelled insert
ok
=
0
else
:
if
evalue
is
None
:
ok
=
0
value
=
evalue
else
:
evalue
=
None
if
ok
:
if
xlat
:
translated
=
self
.
translate
(
msgid
or
value
,
value
,
{})
if
translated
is
not
None
:
value
=
translated
if
value
is
None
:
value
=
name
elif
evalue
is
self
.
Default
:
value
=
attrEscape
(
value
)
else
:
value
=
cgi
.
escape
(
value
,
quote
=
1
)
value
=
'%s="%s"'
%
(
name
,
value
)
return
ok
,
name
,
value
bytecode_handlers
[
"<attrAction>"
]
=
attrAction
def
no_tag
(
self
,
start
,
program
):
state
=
self
.
saveState
()
self
.
stream
=
stream
=
self
.
StringIO
()
self
.
_stream_write
=
stream
.
write
self
.
interpret
(
start
)
self
.
restoreOutputState
(
state
)
self
.
interpret
(
program
)
def
do_optTag
(
self
,
(
name
,
cexpr
,
tag_ns
,
isend
,
start
,
program
),
omit
=
0
):
if
tag_ns
and
not
self
.
showtal
:
return
self
.
no_tag
(
start
,
program
)
self
.
interpret
(
start
)
if
not
isend
:
self
.
interpret
(
program
)
s
=
'</%s>'
%
name
self
.
_stream_write
(
s
)
self
.
col
=
self
.
col
+
len
(
s
)
def
do_optTag_tal
(
self
,
stuff
):
cexpr
=
stuff
[
1
]
if
cexpr
is
not
None
and
(
cexpr
==
''
or
self
.
engine
.
evaluateBoolean
(
cexpr
)):
self
.
no_tag
(
stuff
[
-
2
],
stuff
[
-
1
])
else
:
self
.
do_optTag
(
stuff
)
bytecode_handlers
[
"optTag"
]
=
do_optTag
def
do_rawtextBeginScope
(
self
,
(
s
,
col
,
position
,
closeprev
,
dict
)):
self
.
_stream_write
(
s
)
self
.
col
=
col
self
.
do_setPosition
(
position
)
if
closeprev
:
engine
=
self
.
engine
engine
.
endScope
()
engine
.
beginScope
()
else
:
self
.
engine
.
beginScope
()
self
.
scopeLevel
=
self
.
scopeLevel
+
1
def
do_rawtextBeginScope_tal
(
self
,
(
s
,
col
,
position
,
closeprev
,
dict
)):
self
.
_stream_write
(
s
)
self
.
col
=
col
engine
=
self
.
engine
self
.
position
=
position
engine
.
setPosition
(
position
)
if
closeprev
:
engine
.
endScope
()
engine
.
beginScope
()
else
:
engine
.
beginScope
()
self
.
scopeLevel
=
self
.
scopeLevel
+
1
engine
.
setLocal
(
"attrs"
,
dict
)
bytecode_handlers
[
"rawtextBeginScope"
]
=
do_rawtextBeginScope
def
do_beginScope
(
self
,
dict
):
self
.
engine
.
beginScope
()
self
.
scopeLevel
=
self
.
scopeLevel
+
1
def
do_beginScope_tal
(
self
,
dict
):
engine
=
self
.
engine
engine
.
beginScope
()
engine
.
setLocal
(
"attrs"
,
dict
)
self
.
scopeLevel
=
self
.
scopeLevel
+
1
bytecode_handlers
[
"beginScope"
]
=
do_beginScope
def
do_endScope
(
self
,
notused
=
None
):
self
.
engine
.
endScope
()
self
.
scopeLevel
=
self
.
scopeLevel
-
1
bytecode_handlers
[
"endScope"
]
=
do_endScope
def
do_setLocal
(
self
,
notused
):
pass
def
do_setLocal_tal
(
self
,
(
name
,
expr
)):
self
.
engine
.
setLocal
(
name
,
self
.
engine
.
evaluateValue
(
expr
))
bytecode_handlers
[
"setLocal"
]
=
do_setLocal
def
do_setGlobal_tal
(
self
,
(
name
,
expr
)):
self
.
engine
.
setGlobal
(
name
,
self
.
engine
.
evaluateValue
(
expr
))
bytecode_handlers
[
"setGlobal"
]
=
do_setLocal
def
do_beginI18nContext
(
self
,
settings
):
get
=
settings
.
get
self
.
i18nContext
=
TranslationContext
(
self
.
i18nContext
,
domain
=
get
(
"domain"
),
source
=
get
(
"source"
),
target
=
get
(
"target"
))
bytecode_handlers
[
"beginI18nContext"
]
=
do_beginI18nContext
def
do_endI18nContext
(
self
,
notused
=
None
):
self
.
i18nContext
=
self
.
i18nContext
.
parent
assert
self
.
i18nContext
is
not
None
bytecode_handlers
[
"endI18nContext"
]
=
do_endI18nContext
def
do_insertText
(
self
,
stuff
):
self
.
interpret
(
stuff
[
1
])
def
do_insertText_tal
(
self
,
stuff
):
text
=
self
.
engine
.
evaluateText
(
stuff
[
0
])
if
text
is
None
:
return
if
text
is
self
.
Default
:
self
.
interpret
(
stuff
[
1
])
return
if
isinstance
(
text
,
I18nMessageTypes
):
# Translate this now.
text
=
self
.
engine
.
translate
(
text
.
domain
,
text
,
text
.
mapping
,
default
=
text
.
default
)
s
=
cgi
.
escape
(
text
)
self
.
_stream_write
(
s
)
i
=
s
.
rfind
(
'
\
n
'
)
if
i
<
0
:
self
.
col
=
self
.
col
+
len
(
s
)
else
:
self
.
col
=
len
(
s
)
-
(
i
+
1
)
bytecode_handlers
[
"insertText"
]
=
do_insertText
def
do_i18nVariable
(
self
,
stuff
):
varname
,
program
,
expression
,
structure
=
stuff
if
expression
is
None
:
# The value is implicitly the contents of this tag, so we have to
# evaluate the mini-program to get the value of the variable.
state
=
self
.
saveState
()
try
:
tmpstream
=
self
.
StringIO
()
self
.
pushStream
(
tmpstream
)
try
:
self
.
interpret
(
program
)
finally
:
self
.
popStream
()
if
self
.
html
and
self
.
_currentTag
==
"pre"
:
value
=
tmpstream
.
getvalue
()
else
:
value
=
normalize
(
tmpstream
.
getvalue
())
finally
:
self
.
restoreState
(
state
)
else
:
# Evaluate the value to be associated with the variable in the
# i18n interpolation dictionary.
if
structure
:
value
=
self
.
engine
.
evaluateStructure
(
expression
)
else
:
value
=
self
.
engine
.
evaluate
(
expression
)
# evaluate() does not do any I18n, so we do it here.
if
isinstance
(
value
,
I18nMessageTypes
):
# Translate this now.
# XXX
value
=
self
.
engine
.
translate
(
value
.
domain
,
value
,
value
.
mapping
,
value
.
default
)
if
not
structure
:
value
=
cgi
.
escape
(
ustr
(
value
))
# Either the i18n:name tag is nested inside an i18n:translate in which
# case the last item on the stack has the i18n dictionary and string
# representation, or the i18n:name and i18n:translate attributes are
# in the same tag, in which case the i18nStack will be empty. In that
# case we can just output the ${name} to the stream
i18ndict
,
srepr
=
self
.
i18nStack
[
-
1
]
i18ndict
[
varname
]
=
value
placeholder
=
'${%s}'
%
varname
srepr
.
append
(
placeholder
)
self
.
_stream_write
(
placeholder
)
bytecode_handlers
[
'i18nVariable'
]
=
do_i18nVariable
def
do_insertTranslation
(
self
,
stuff
):
i18ndict
=
{}
srepr
=
[]
obj
=
None
self
.
i18nStack
.
append
((
i18ndict
,
srepr
))
msgid
=
stuff
[
0
]
# We need to evaluate the content of the tag because that will give us
# several useful pieces of information. First, the contents will
# include an implicit message id, if no explicit one was given.
# Second, it will evaluate any i18nVariable definitions in the body of
# the translation (necessary for $varname substitutions).
#
# Use a temporary stream to capture the interpretation of the
# subnodes, which should /not/ go to the output stream.
currentTag
=
self
.
_currentTag
tmpstream
=
self
.
StringIO
()
self
.
pushStream
(
tmpstream
)
try
:
self
.
interpret
(
stuff
[
1
])
finally
:
self
.
popStream
()
# We only care about the evaluated contents if we need an implicit
# message id. All other useful information will be in the i18ndict on
# the top of the i18nStack.
default
=
tmpstream
.
getvalue
()
if
not
msgid
:
if
self
.
html
and
currentTag
==
"pre"
:
msgid
=
default
else
:
msgid
=
normalize
(
default
)
self
.
i18nStack
.
pop
()
# See if there is was an i18n:data for msgid
if
len
(
stuff
)
>
2
:
obj
=
self
.
engine
.
evaluate
(
stuff
[
2
])
xlated_msgid
=
self
.
translate
(
msgid
,
default
,
i18ndict
,
obj
)
# TODO: I can't decide whether we want to cgi escape the translated
# string or not. OTOH not doing this could introduce a cross-site
# scripting vector by allowing translators to sneak JavaScript into
# translations. OTOH, for implicit interpolation values, we don't
# want to escape stuff like ${name} <= "<b>Timmy</b>".
assert
xlated_msgid
is
not
None
self
.
_stream_write
(
xlated_msgid
)
bytecode_handlers
[
'insertTranslation'
]
=
do_insertTranslation
def
do_insertStructure
(
self
,
stuff
):
self
.
interpret
(
stuff
[
2
])
def
do_insertStructure_tal
(
self
,
(
expr
,
repldict
,
block
)):
structure
=
self
.
engine
.
evaluateStructure
(
expr
)
if
structure
is
None
:
return
if
structure
is
self
.
Default
:
self
.
interpret
(
block
)
return
text
=
ustr
(
structure
)
if
not
(
repldict
or
self
.
strictinsert
):
# Take a shortcut, no error checking
self
.
stream_write
(
text
)
return
if
self
.
html
:
self
.
insertHTMLStructure
(
text
,
repldict
)
else
:
self
.
insertXMLStructure
(
text
,
repldict
)
bytecode_handlers
[
"insertStructure"
]
=
do_insertStructure
def
insertHTMLStructure
(
self
,
text
,
repldict
):
from
HTMLTALParser
import
HTMLTALParser
gen
=
AltTALGenerator
(
repldict
,
self
.
engine
.
getCompiler
(),
0
)
p
=
HTMLTALParser
(
gen
)
# Raises an exception if text is invalid
p
.
parseString
(
text
)
program
,
macros
=
p
.
getCode
()
self
.
interpret
(
program
)
def
insertXMLStructure
(
self
,
text
,
repldict
):
from
TALParser
import
TALParser
gen
=
AltTALGenerator
(
repldict
,
self
.
engine
.
getCompiler
(),
0
)
p
=
TALParser
(
gen
)
gen
.
enable
(
0
)
p
.
parseFragment
(
'<!DOCTYPE foo PUBLIC "foo" "bar"><foo>'
)
gen
.
enable
(
1
)
p
.
parseFragment
(
text
)
# Raises an exception if text is invalid
gen
.
enable
(
0
)
p
.
parseFragment
(
'</foo>'
,
1
)
program
,
macros
=
gen
.
getCode
()
self
.
interpret
(
program
)
def
do_loop
(
self
,
(
name
,
expr
,
block
)):
self
.
interpret
(
block
)
def
do_loop_tal
(
self
,
(
name
,
expr
,
block
)):
iterator
=
self
.
engine
.
setRepeat
(
name
,
expr
)
while
iterator
.
next
():
self
.
interpret
(
block
)
bytecode_handlers
[
"loop"
]
=
do_loop
def
translate
(
self
,
msgid
,
default
,
i18ndict
,
obj
=
None
):
if
obj
:
i18ndict
.
update
(
obj
)
if
not
self
.
i18nInterpolate
:
return
msgid
# TODO: We need to pass in one of context or target_language
return
self
.
engine
.
translate
(
self
.
i18nContext
.
domain
,
msgid
,
i18ndict
,
default
=
default
)
def
do_rawtextColumn
(
self
,
(
s
,
col
)):
self
.
_stream_write
(
s
)
self
.
col
=
col
bytecode_handlers
[
"rawtextColumn"
]
=
do_rawtextColumn
def
do_rawtextOffset
(
self
,
(
s
,
offset
)):
self
.
_stream_write
(
s
)
self
.
col
=
self
.
col
+
offset
bytecode_handlers
[
"rawtextOffset"
]
=
do_rawtextOffset
def
do_condition
(
self
,
(
condition
,
block
)):
if
not
self
.
tal
or
self
.
engine
.
evaluateBoolean
(
condition
):
self
.
interpret
(
block
)
bytecode_handlers
[
"condition"
]
=
do_condition
def
do_defineMacro
(
self
,
(
macroName
,
macro
)):
macs
=
self
.
macroStack
if
len
(
macs
)
==
1
:
entering
=
macs
[
-
1
][
2
]
if
not
entering
:
macs
.
append
(
None
)
self
.
interpret
(
macro
)
assert
macs
[
-
1
]
is
None
macs
.
pop
()
return
self
.
interpret
(
macro
)
bytecode_handlers
[
"defineMacro"
]
=
do_defineMacro
def
do_useMacro
(
self
,
(
macroName
,
macroExpr
,
compiledSlots
,
block
)):
if
not
self
.
metal
:
self
.
interpret
(
block
)
return
macro
=
self
.
engine
.
evaluateMacro
(
macroExpr
)
if
macro
is
self
.
Default
:
macro
=
block
else
:
if
not
isCurrentVersion
(
macro
):
raise
METALError
(
"macro %s has incompatible version %s"
%
(
`macroName`
,
`getProgramVersion(macro)`
),
self
.
position
)
mode
=
getProgramMode
(
macro
)
if
mode
!=
(
self
.
html
and
"html"
or
"xml"
):
raise
METALError
(
"macro %s has incompatible mode %s"
%
(
`macroName`
,
`mode`
),
self
.
position
)
self
.
pushMacro
(
macroName
,
compiledSlots
)
prev_source
=
self
.
sourceFile
self
.
interpret
(
macro
)
if
self
.
sourceFile
!=
prev_source
:
self
.
engine
.
setSourceFile
(
prev_source
)
self
.
sourceFile
=
prev_source
self
.
popMacro
()
bytecode_handlers
[
"useMacro"
]
=
do_useMacro
def
do_fillSlot
(
self
,
(
slotName
,
block
)):
# This is only executed if the enclosing 'use-macro' evaluates
# to 'default'.
self
.
interpret
(
block
)
bytecode_handlers
[
"fillSlot"
]
=
do_fillSlot
def
do_defineSlot
(
self
,
(
slotName
,
block
)):
if
not
self
.
metal
:
self
.
interpret
(
block
)
return
macs
=
self
.
macroStack
if
macs
and
macs
[
-
1
]
is
not
None
:
macroName
,
slots
=
self
.
popMacro
()[:
2
]
slot
=
slots
.
get
(
slotName
)
if
slot
is
not
None
:
prev_source
=
self
.
sourceFile
self
.
interpret
(
slot
)
if
self
.
sourceFile
!=
prev_source
:
self
.
engine
.
setSourceFile
(
prev_source
)
self
.
sourceFile
=
prev_source
self
.
pushMacro
(
macroName
,
slots
,
entering
=
0
)
return
self
.
pushMacro
(
macroName
,
slots
)
# Falling out of the 'if' allows the macro to be interpreted.
self
.
interpret
(
block
)
bytecode_handlers
[
"defineSlot"
]
=
do_defineSlot
def
do_onError
(
self
,
(
block
,
handler
)):
self
.
interpret
(
block
)
def
do_onError_tal
(
self
,
(
block
,
handler
)):
state
=
self
.
saveState
()
self
.
stream
=
stream
=
self
.
StringIO
()
self
.
_stream_write
=
stream
.
write
try
:
self
.
interpret
(
block
)
except
ConflictError
:
raise
except
:
exc
=
sys
.
exc_info
()[
1
]
self
.
restoreState
(
state
)
engine
=
self
.
engine
engine
.
beginScope
()
error
=
engine
.
createErrorInfo
(
exc
,
self
.
position
)
engine
.
setLocal
(
'error'
,
error
)
try
:
self
.
interpret
(
handler
)
finally
:
engine
.
endScope
()
else
:
self
.
restoreOutputState
(
state
)
self
.
stream_write
(
stream
.
getvalue
())
bytecode_handlers
[
"onError"
]
=
do_onError
bytecode_handlers_tal
=
bytecode_handlers
.
copy
()
bytecode_handlers_tal
[
"rawtextBeginScope"
]
=
do_rawtextBeginScope_tal
bytecode_handlers_tal
[
"beginScope"
]
=
do_beginScope_tal
bytecode_handlers_tal
[
"setLocal"
]
=
do_setLocal_tal
bytecode_handlers_tal
[
"setGlobal"
]
=
do_setGlobal_tal
bytecode_handlers_tal
[
"insertStructure"
]
=
do_insertStructure_tal
bytecode_handlers_tal
[
"insertText"
]
=
do_insertText_tal
bytecode_handlers_tal
[
"loop"
]
=
do_loop_tal
bytecode_handlers_tal
[
"onError"
]
=
do_onError_tal
bytecode_handlers_tal
[
"<attrAction>"
]
=
attrAction_tal
bytecode_handlers_tal
[
"optTag"
]
=
do_optTag_tal
class
FasterStringIO
(
StringIO
):
"""Append-only version of StringIO.
This let's us have a much faster write() method.
"""
def
close
(
self
):
if
not
self
.
closed
:
self
.
write
=
_write_ValueError
StringIO
.
close
(
self
)
def
seek
(
self
,
pos
,
mode
=
0
):
raise
RuntimeError
(
"FasterStringIO.seek() not allowed"
)
def
write
(
self
,
s
):
#assert self.pos == self.len
self
.
buflist
.
append
(
s
)
self
.
len
=
self
.
pos
=
self
.
pos
+
len
(
s
)
def
_write_ValueError
(
s
):
raise
ValueError
,
"I/O operation on closed file"
lib/python/TAL/TALParser.py
deleted
100644 → 0
View file @
1c0af142
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
Parse XML and compile to TALInterpreter intermediate code.
"""
from
XMLParser
import
XMLParser
from
TALDefs
import
XML_NS
,
ZOPE_I18N_NS
,
ZOPE_METAL_NS
,
ZOPE_TAL_NS
from
TALGenerator
import
TALGenerator
class
TALParser
(
XMLParser
):
ordered_attributes
=
1
def
__init__
(
self
,
gen
=
None
):
# Override
XMLParser
.
__init__
(
self
)
if
gen
is
None
:
gen
=
TALGenerator
()
self
.
gen
=
gen
self
.
nsStack
=
[]
self
.
nsDict
=
{
XML_NS
:
'xml'
}
self
.
nsNew
=
[]
def
getCode
(
self
):
return
self
.
gen
.
getCode
()
def
getWarnings
(
self
):
return
()
def
StartNamespaceDeclHandler
(
self
,
prefix
,
uri
):
self
.
nsStack
.
append
(
self
.
nsDict
.
copy
())
self
.
nsDict
[
uri
]
=
prefix
self
.
nsNew
.
append
((
prefix
,
uri
))
def
EndNamespaceDeclHandler
(
self
,
prefix
):
self
.
nsDict
=
self
.
nsStack
.
pop
()
def
StartElementHandler
(
self
,
name
,
attrs
):
if
self
.
ordered_attributes
:
# attrs is a list of alternating names and values
attrlist
=
[]
for
i
in
range
(
0
,
len
(
attrs
),
2
):
key
=
attrs
[
i
]
value
=
attrs
[
i
+
1
]
attrlist
.
append
((
key
,
value
))
else
:
# attrs is a dict of {name: value}
attrlist
=
attrs
.
items
()
attrlist
.
sort
()
# For definiteness
name
,
attrlist
,
taldict
,
metaldict
,
i18ndict
\
=
self
.
process_ns
(
name
,
attrlist
)
attrlist
=
self
.
xmlnsattrs
()
+
attrlist
self
.
gen
.
emitStartElement
(
name
,
attrlist
,
taldict
,
metaldict
,
i18ndict
)
def
process_ns
(
self
,
name
,
attrlist
):
taldict
=
{}
metaldict
=
{}
i18ndict
=
{}
fixedattrlist
=
[]
name
,
namebase
,
namens
=
self
.
fixname
(
name
)
for
key
,
value
in
attrlist
:
key
,
keybase
,
keyns
=
self
.
fixname
(
key
)
ns
=
keyns
or
namens
# default to tag namespace
item
=
key
,
value
if
ns
==
'metal'
:
metaldict
[
keybase
]
=
value
item
=
item
+
(
"metal"
,)
elif
ns
==
'tal'
:
taldict
[
keybase
]
=
value
item
=
item
+
(
"tal"
,)
elif
ns
==
'i18n'
:
i18ndict
[
keybase
]
=
value
item
=
item
+
(
'i18n'
,)
fixedattrlist
.
append
(
item
)
if
namens
in
(
'metal'
,
'tal'
,
'i18n'
):
taldict
[
'tal tag'
]
=
namens
return
name
,
fixedattrlist
,
taldict
,
metaldict
,
i18ndict
def
xmlnsattrs
(
self
):
newlist
=
[]
for
prefix
,
uri
in
self
.
nsNew
:
if
prefix
:
key
=
"xmlns:"
+
prefix
else
:
key
=
"xmlns"
if
uri
in
(
ZOPE_METAL_NS
,
ZOPE_TAL_NS
,
ZOPE_I18N_NS
):
item
=
(
key
,
uri
,
"xmlns"
)
else
:
item
=
(
key
,
uri
)
newlist
.
append
(
item
)
self
.
nsNew
=
[]
return
newlist
def
fixname
(
self
,
name
):
if
' '
in
name
:
uri
,
name
=
name
.
split
(
' '
)
prefix
=
self
.
nsDict
[
uri
]
prefixed
=
name
if
prefix
:
prefixed
=
"%s:%s"
%
(
prefix
,
name
)
ns
=
'x'
if
uri
==
ZOPE_TAL_NS
:
ns
=
'tal'
elif
uri
==
ZOPE_METAL_NS
:
ns
=
'metal'
elif
uri
==
ZOPE_I18N_NS
:
ns
=
'i18n'
return
(
prefixed
,
name
,
ns
)
return
(
name
,
name
,
None
)
def
EndElementHandler
(
self
,
name
):
name
=
self
.
fixname
(
name
)[
0
]
self
.
gen
.
emitEndElement
(
name
)
def
DefaultHandler
(
self
,
text
):
self
.
gen
.
emitRawText
(
text
)
def
test
():
import
sys
p
=
TALParser
()
file
=
"tests/input/test01.xml"
if
sys
.
argv
[
1
:]:
file
=
sys
.
argv
[
1
]
p
.
parseFile
(
file
)
program
,
macros
=
p
.
getCode
()
from
TALInterpreter
import
TALInterpreter
from
DummyEngine
import
DummyEngine
engine
=
DummyEngine
(
macros
)
TALInterpreter
(
program
,
macros
,
engine
,
sys
.
stdout
,
wrap
=
0
)()
if
__name__
==
"__main__"
:
test
()
lib/python/TAL/TranslationContext.py
deleted
100644 → 0
View file @
1c0af142
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Translation context object for the TALInterpreter's I18N support.
The translation context provides a container for the information
needed to perform translation of a marked string from a page template.
$Id$
"""
DEFAULT_DOMAIN
=
"default"
class
TranslationContext
:
"""Information about the I18N settings of a TAL processor."""
def
__init__
(
self
,
parent
=
None
,
domain
=
None
,
target
=
None
,
source
=
None
):
if
parent
:
if
not
domain
:
domain
=
parent
.
domain
if
not
target
:
target
=
parent
.
target
if
not
source
:
source
=
parent
.
source
elif
domain
is
None
:
domain
=
DEFAULT_DOMAIN
self
.
parent
=
parent
self
.
domain
=
domain
self
.
target
=
target
self
.
source
=
source
lib/python/TAL/XMLParser.py
deleted
100644 → 0
View file @
1c0af142
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
Generic expat-based XML parser base class.
"""
import
xml.parsers.expat
import
zLOG
XMLParseError
=
xml
.
parsers
.
expat
.
ExpatError
class
XMLParser
:
ordered_attributes
=
0
handler_names
=
[
"StartElementHandler"
,
"EndElementHandler"
,
"ProcessingInstructionHandler"
,
"CharacterDataHandler"
,
"UnparsedEntityDeclHandler"
,
"NotationDeclHandler"
,
"StartNamespaceDeclHandler"
,
"EndNamespaceDeclHandler"
,
"CommentHandler"
,
"StartCdataSectionHandler"
,
"EndCdataSectionHandler"
,
"DefaultHandler"
,
"DefaultHandlerExpand"
,
"NotStandaloneHandler"
,
"ExternalEntityRefHandler"
,
"XmlDeclHandler"
,
"StartDoctypeDeclHandler"
,
"EndDoctypeDeclHandler"
,
"ElementDeclHandler"
,
"AttlistDeclHandler"
]
def
__init__
(
self
,
encoding
=
None
):
self
.
parser
=
p
=
self
.
createParser
()
if
self
.
ordered_attributes
:
try
:
self
.
parser
.
ordered_attributes
=
self
.
ordered_attributes
except
AttributeError
:
zLOG
.
LOG
(
"TAL.XMLParser"
,
zLOG
.
INFO
,
"Can't set ordered_attributes"
)
self
.
ordered_attributes
=
0
for
name
in
self
.
handler_names
:
method
=
getattr
(
self
,
name
,
None
)
if
method
is
not
None
:
try
:
setattr
(
p
,
name
,
method
)
except
AttributeError
:
zLOG
.
LOG
(
"TAL.XMLParser"
,
zLOG
.
PROBLEM
,
"Can't set expat handler %s"
%
name
)
def
createParser
(
self
,
encoding
=
None
):
return
xml
.
parsers
.
expat
.
ParserCreate
(
encoding
,
' '
)
def
parseFile
(
self
,
filename
):
self
.
parseStream
(
open
(
filename
))
def
parseString
(
self
,
s
):
self
.
parser
.
Parse
(
s
,
1
)
def
parseURL
(
self
,
url
):
import
urllib
self
.
parseStream
(
urllib
.
urlopen
(
url
))
def
parseStream
(
self
,
stream
):
self
.
parser
.
ParseFile
(
stream
)
def
parseFragment
(
self
,
s
,
end
=
0
):
self
.
parser
.
Parse
(
s
,
end
)
lib/python/TAL/__init__.py
deleted
100644 → 0
View file @
1c0af142
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
""" Template Attribute Language package """
lib/python/TAL/benchmark/dtml01.html
deleted
100644 → 0
View file @
1c0af142
baseline
lib/python/TAL/benchmark/dtml02.html
deleted
100644 → 0
View file @
1c0af142
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
lib/python/TAL/benchmark/dtml03.html
deleted
100644 → 0
View file @
1c0af142
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
lib/python/TAL/benchmark/dtml04.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
r8
>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
</dtml-in>
lib/python/TAL/benchmark/dtml05.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
r8
>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
</dtml-in>
lib/python/TAL/benchmark/dtml06.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
r2
>
<dtml-in
r2
>
<dtml-in
r2
>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
</dtml-in>
</dtml-in>
</dtml-in>
lib/python/TAL/benchmark/dtml07.html
deleted
100644 → 0
View file @
1c0af142
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
lib/python/TAL/benchmark/dtml08.html
deleted
100644 → 0
View file @
1c0af142
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
lib/python/TAL/benchmark/dtml09.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
r64
>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
<td
bgcolor=
"white"
>
&dtml-x1;
</td>
<td
bgcolor=
"white"
>
&dtml-x2;
</td>
<td
bgcolor=
"white"
>
&dtml-x3;
</td>
<td
bgcolor=
"white"
>
&dtml-x4;
</td>
<td
bgcolor=
"white"
>
&dtml-x5;
</td>
<td
bgcolor=
"white"
>
&dtml-x6;
</td>
<td
bgcolor=
"white"
>
&dtml-x7;
</td>
</dtml-in>
lib/python/TAL/benchmark/dtml10.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
r64
>
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
</dtml-in>
lib/python/TAL/benchmark/dtml11.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
r64
>
<td
bgcolor=
"white"
>
&dtml-x0;
</td>
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
</dtml-in>
lib/python/TAL/benchmark/dtml12.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
r8
>
<dtml-let
y0=
x0
y1=
x1
y2=
x2
y3=
x3
y4=
x4
y5=
x5
y6=
x6
y7=
x7
>
<td
bgcolor=
"white"
>
&dtml-y0;
</td>
<td
bgcolor=
"white"
>
&dtml-y1;
</td>
<td
bgcolor=
"white"
>
&dtml-y2;
</td>
<td
bgcolor=
"white"
>
&dtml-y3;
</td>
<td
bgcolor=
"white"
>
&dtml-y4;
</td>
<td
bgcolor=
"white"
>
&dtml-y5;
</td>
<td
bgcolor=
"white"
>
&dtml-y6;
</td>
<td
bgcolor=
"white"
>
&dtml-y7;
</td>
</dtml-let>
</dtml-in>
lib/python/TAL/benchmark/tal01.html
deleted
100644 → 0
View file @
1c0af142
baseline
lib/python/TAL/benchmark/tal02.html
deleted
100644 → 0
View file @
1c0af142
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
lib/python/TAL/benchmark/tal03.html
deleted
100644 → 0
View file @
1c0af142
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
<td
bgcolor=
"white"
tal:content=
"x4"
></td>
<td
bgcolor=
"white"
tal:content=
"x5"
></td>
<td
bgcolor=
"white"
tal:content=
"x6"
></td>
<td
bgcolor=
"white"
tal:content=
"x7"
></td>
lib/python/TAL/benchmark/tal04.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
tal:repeat=
"r r8"
>
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
</dtml-in>
lib/python/TAL/benchmark/tal05.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
tal:repeat=
"r r8"
>
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
<td
bgcolor=
"white"
tal:content=
"x4"
></td>
<td
bgcolor=
"white"
tal:content=
"x5"
></td>
<td
bgcolor=
"white"
tal:content=
"x6"
></td>
<td
bgcolor=
"white"
tal:content=
"x7"
></td>
</dtml-in>
lib/python/TAL/benchmark/tal06.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
tal:repeat=
"r r2"
>
<dtml-in
tal:repeat=
"r r2"
>
<dtml-in
tal:repeat=
"r r2"
>
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
<td
bgcolor=
"white"
tal:content=
"x4"
></td>
<td
bgcolor=
"white"
tal:content=
"x5"
></td>
<td
bgcolor=
"white"
tal:content=
"x6"
></td>
<td
bgcolor=
"white"
tal:content=
"x7"
></td>
</dtml-in>
</dtml-in>
</dtml-in>
lib/python/TAL/benchmark/tal07.html
deleted
100644 → 0
View file @
1c0af142
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
<td
bgcolor=
"white"
tal:content=
"x4"
></td>
<td
bgcolor=
"white"
tal:content=
"x5"
></td>
<td
bgcolor=
"white"
tal:content=
"x6"
></td>
<td
bgcolor=
"white"
tal:content=
"x7"
></td>
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
<td
bgcolor=
"white"
tal:content=
"x4"
></td>
<td
bgcolor=
"white"
tal:content=
"x5"
></td>
<td
bgcolor=
"white"
tal:content=
"x6"
></td>
<td
bgcolor=
"white"
tal:content=
"x7"
></td>
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
<td
bgcolor=
"white"
tal:content=
"x4"
></td>
<td
bgcolor=
"white"
tal:content=
"x5"
></td>
<td
bgcolor=
"white"
tal:content=
"x6"
></td>
<td
bgcolor=
"white"
tal:content=
"x7"
></td>
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
<td
bgcolor=
"white"
tal:content=
"x4"
></td>
<td
bgcolor=
"white"
tal:content=
"x5"
></td>
<td
bgcolor=
"white"
tal:content=
"x6"
></td>
<td
bgcolor=
"white"
tal:content=
"x7"
></td>
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
<td
bgcolor=
"white"
tal:content=
"x4"
></td>
<td
bgcolor=
"white"
tal:content=
"x5"
></td>
<td
bgcolor=
"white"
tal:content=
"x6"
></td>
<td
bgcolor=
"white"
tal:content=
"x7"
></td>
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
<td
bgcolor=
"white"
tal:content=
"x4"
></td>
<td
bgcolor=
"white"
tal:content=
"x5"
></td>
<td
bgcolor=
"white"
tal:content=
"x6"
></td>
<td
bgcolor=
"white"
tal:content=
"x7"
></td>
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
<td
bgcolor=
"white"
tal:content=
"x4"
></td>
<td
bgcolor=
"white"
tal:content=
"x5"
></td>
<td
bgcolor=
"white"
tal:content=
"x6"
></td>
<td
bgcolor=
"white"
tal:content=
"x7"
></td>
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
<td
bgcolor=
"white"
tal:content=
"x4"
></td>
<td
bgcolor=
"white"
tal:content=
"x5"
></td>
<td
bgcolor=
"white"
tal:content=
"x6"
></td>
<td
bgcolor=
"white"
tal:content=
"x7"
></td>
lib/python/TAL/benchmark/tal08.html
deleted
100644 → 0
View file @
1c0af142
<td
bgcolor=
"white"
><span
tal:replace=
"x0"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x1"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x2"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x3"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x4"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x5"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x6"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x7"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x0"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x1"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x2"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x3"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x4"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x5"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x6"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x7"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x0"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x1"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x2"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x3"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x4"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x5"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x6"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x7"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x0"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x1"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x2"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x3"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x4"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x5"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x6"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x7"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x0"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x1"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x2"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x3"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x4"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x5"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x6"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x7"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x0"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x1"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x2"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x3"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x4"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x5"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x6"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x7"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x0"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x1"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x2"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x3"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x4"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x5"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x6"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x7"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x0"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x1"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x2"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x3"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x4"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x5"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x6"
></span></td>
<td
bgcolor=
"white"
><span
tal:replace=
"x7"
></span></td>
lib/python/TAL/benchmark/tal09.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
tal:repeat=
"r r64"
>
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
<td
bgcolor=
"white"
tal:content=
"x1"
></td>
<td
bgcolor=
"white"
tal:content=
"x2"
></td>
<td
bgcolor=
"white"
tal:content=
"x3"
></td>
<td
bgcolor=
"white"
tal:content=
"x4"
></td>
<td
bgcolor=
"white"
tal:content=
"x5"
></td>
<td
bgcolor=
"white"
tal:content=
"x6"
></td>
<td
bgcolor=
"white"
tal:content=
"x7"
></td>
</dtml-in>
lib/python/TAL/benchmark/tal10.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
tal:repeat=
"r r64"
>
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
</dtml-in>
lib/python/TAL/benchmark/tal11.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
tal:repeat=
"r r64"
>
<td
bgcolor=
"white"
tal:content=
"x0"
></td>
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
A large chunk of text to be repeated.
</dtml-in>
lib/python/TAL/benchmark/tal12.html
deleted
100644 → 0
View file @
1c0af142
<dtml-in
tal:repeat=
"r r8"
>
<span
tal:define=
"y0 x0;y1 x1;y2 x2;y3 x3;y4 x4;y5 x5;y6 x6;y7 x7"
>
<td
bgcolor=
"white"
tal:content=
"y0"
></td>
<td
bgcolor=
"white"
tal:content=
"y1"
></td>
<td
bgcolor=
"white"
tal:content=
"y2"
></td>
<td
bgcolor=
"white"
tal:content=
"y3"
></td>
<td
bgcolor=
"white"
tal:content=
"y4"
></td>
<td
bgcolor=
"white"
tal:content=
"y5"
></td>
<td
bgcolor=
"white"
tal:content=
"y6"
></td>
<td
bgcolor=
"white"
tal:content=
"y7"
></td>
</span>
</dtml-in>
lib/python/TAL/driver.py
deleted
100755 → 0
View file @
1c0af142
#!/usr/bin/env python
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
Driver program to test METAL and TAL implementation.
Usage: driver.py [options] [file]
Options:
-h / --help
Print this message and exit.
-H / --html
-x / --xml
Explicitly choose HTML or XML input. The default is to automatically
select based on the file extension. These options are mutually
exclusive.
-l
Lenient structure insertion.
-m
Macro expansion only
-s
Print intermediate opcodes only
-t
Leave TAL/METAL attributes in output
-i
Leave I18N substitution strings un-interpolated.
"""
import
os
import
sys
import
getopt
if
__name__
==
"__main__"
:
import
setpath
# Local hack to tweak sys.path etc.
# Import local classes
import
TALDefs
from
DummyEngine
import
DummyEngine
from
DummyEngine
import
DummyTranslationService
FILE
=
"tests/input/test01.xml"
class
TestTranslations
(
DummyTranslationService
):
def
translate
(
self
,
domain
,
msgid
,
mapping
=
None
,
context
=
None
,
target_language
=
None
,
default
=
None
):
if
msgid
==
'timefmt'
:
return
'%(minutes)s minutes after %(hours)s %(ampm)s'
%
mapping
elif
msgid
==
'jobnum'
:
return
'%(jobnum)s is the JOB NUMBER'
%
mapping
elif
msgid
==
'verify'
:
s
=
'Your contact email address is recorded as %(email)s'
return
s
%
mapping
elif
msgid
==
'mailto:${request/submitter}'
:
return
'mailto:bperson@dom.ain'
elif
msgid
==
'origin'
:
return
'%(name)s was born in %(country)s'
%
mapping
return
DummyTranslationService
.
translate
(
self
,
domain
,
msgid
,
mapping
,
context
,
target_language
,
default
=
default
)
class
TestEngine
(
DummyEngine
):
def
__init__
(
self
,
macros
=
None
):
DummyEngine
.
__init__
(
self
,
macros
)
self
.
translationService
=
TestTranslations
()
def
evaluatePathOrVar
(
self
,
expr
):
if
expr
==
'here/currentTime'
:
return
{
'hours'
:
6
,
'minutes'
:
59
,
'ampm'
:
'PM'
,
}
elif
expr
==
'context/@@object_name'
:
return
'7'
elif
expr
==
'request/submitter'
:
return
'aperson@dom.ain'
return
DummyEngine
.
evaluatePathOrVar
(
self
,
expr
)
# This is a disgusting hack so that we can use engines that actually know
# something about certain object paths. TimeEngine knows about
# here/currentTime.
ENGINES
=
{
'test23.html'
:
TestEngine
,
'test24.html'
:
TestEngine
,
'test26.html'
:
TestEngine
,
'test27.html'
:
TestEngine
,
'test28.html'
:
TestEngine
,
'test29.html'
:
TestEngine
,
'test30.html'
:
TestEngine
,
'test31.html'
:
TestEngine
,
'test32.html'
:
TestEngine
,
}
def
usage
(
code
,
msg
=
''
):
# Python 2.1 required
print
>>
sys
.
stderr
,
__doc__
if
msg
:
print
>>
sys
.
stderr
,
msg
sys
.
exit
(
code
)
def
main
():
macros
=
0
mode
=
None
showcode
=
0
showtal
=
-
1
strictinsert
=
1
i18nInterpolate
=
1
try
:
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
"hHxlmsti"
,
[
'help'
,
'html'
,
'xml'
])
except
getopt
.
error
,
msg
:
usage
(
2
,
msg
)
for
opt
,
arg
in
opts
:
if
opt
in
(
'-h'
,
'--help'
):
usage
(
0
)
if
opt
in
(
'-H'
,
'--html'
):
if
mode
==
'xml'
:
usage
(
1
,
'--html and --xml are mutually exclusive'
)
mode
=
"html"
if
opt
==
'-l'
:
strictinsert
=
0
if
opt
==
'-m'
:
macros
=
1
if
opt
==
'-n'
:
versionTest
=
0
if
opt
in
(
'-x'
,
'--xml'
):
if
mode
==
'html'
:
usage
(
1
,
'--html and --xml are mutually exclusive'
)
mode
=
"xml"
if
opt
==
'-s'
:
showcode
=
1
if
opt
==
'-t'
:
showtal
=
1
if
opt
==
'-i'
:
i18nInterpolate
=
0
if
args
:
file
=
args
[
0
]
else
:
file
=
FILE
it
=
compilefile
(
file
,
mode
)
if
showcode
:
showit
(
it
)
else
:
# See if we need a special engine for this test
engine
=
None
engineClass
=
ENGINES
.
get
(
os
.
path
.
basename
(
file
))
if
engineClass
is
not
None
:
engine
=
engineClass
(
macros
)
interpretit
(
it
,
engine
=
engine
,
tal
=
(
not
macros
),
showtal
=
showtal
,
strictinsert
=
strictinsert
,
i18nInterpolate
=
i18nInterpolate
)
def
interpretit
(
it
,
engine
=
None
,
stream
=
None
,
tal
=
1
,
showtal
=-
1
,
strictinsert
=
1
,
i18nInterpolate
=
1
):
from
TALInterpreter
import
TALInterpreter
program
,
macros
=
it
assert
TALDefs
.
isCurrentVersion
(
program
)
if
engine
is
None
:
engine
=
DummyEngine
(
macros
)
TALInterpreter
(
program
,
macros
,
engine
,
stream
,
wrap
=
0
,
tal
=
tal
,
showtal
=
showtal
,
strictinsert
=
strictinsert
,
i18nInterpolate
=
i18nInterpolate
)()
def
compilefile
(
file
,
mode
=
None
):
assert
mode
in
(
"html"
,
"xml"
,
None
)
if
mode
is
None
:
ext
=
os
.
path
.
splitext
(
file
)[
1
]
if
ext
.
lower
()
in
(
".html"
,
".htm"
):
mode
=
"html"
else
:
mode
=
"xml"
if
mode
==
"html"
:
from
HTMLTALParser
import
HTMLTALParser
p
=
HTMLTALParser
()
else
:
from
TALParser
import
TALParser
p
=
TALParser
()
p
.
parseFile
(
file
)
return
p
.
getCode
()
def
showit
(
it
):
from
pprint
import
pprint
pprint
(
it
)
if
__name__
==
"__main__"
:
main
()
lib/python/TAL/markbench.py
deleted
100755 → 0
View file @
1c0af142
#! /usr/bin/env python
# This software is subject to the provisions of the Zope Public License,
# Version 1.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
'''Run benchmarks of TAL vs. DTML'''
try
:
import
warnings
except
ImportError
:
pass
else
:
warnings
.
filterwarnings
(
"ignore"
,
category
=
DeprecationWarning
)
import
os
os
.
environ
[
'NO_SECURITY'
]
=
'true'
import
sys
,
time
if
__name__
==
"__main__"
:
import
setpath
from
DocumentTemplate.DT_HTML
import
HTMLFile
from
HTMLTALParser
import
HTMLTALParser
from
TALInterpreter
import
TALInterpreter
from
DummyEngine
import
DummyEngine
from
cStringIO
import
StringIO
def
time_apply
(
f
,
args
,
kwargs
,
count
):
for
i
in
range
(
4
):
f
(
*
args
,
**
kwargs
)
r
=
[
None
]
*
count
t0
=
time
.
clock
()
for
i
in
r
:
pass
t1
=
time
.
clock
()
for
i
in
r
:
f
(
*
args
,
**
kwargs
)
t
=
time
.
clock
()
-
t1
-
(
t1
-
t0
)
return
t
/
count
def
time_zpt
(
fn
,
count
):
from
Products.PageTemplates.PageTemplate
import
PageTemplate
pt
=
PageTemplate
()
pt
.
write
(
open
(
fn
).
read
())
return
time_apply
(
pt
.
pt_render
,
(),
{
'extra_context'
:
data
},
count
)
def
time_tal
(
fn
,
count
):
p
=
HTMLTALParser
()
p
.
parseFile
(
fn
)
program
,
macros
=
p
.
getCode
()
engine
=
DummyEngine
(
macros
)
engine
.
globals
=
data
tal
=
TALInterpreter
(
program
,
macros
,
engine
,
StringIO
(),
wrap
=
0
,
tal
=
1
,
strictinsert
=
0
)
return
time_apply
(
tal
,
(),
{},
count
)
def
time_dtml
(
fn
,
count
):
html
=
HTMLFile
(
fn
)
return
time_apply
(
html
,
(),
data
,
count
)
def
profile_zpt
(
fn
,
count
,
profiler
):
from
Products.PageTemplates.PageTemplate
import
PageTemplate
pt
=
PageTemplate
()
pt
.
write
(
open
(
fn
).
read
())
for
i
in
range
(
4
):
pt
.
pt_render
(
extra_context
=
data
)
r
=
[
None
]
*
count
for
i
in
r
:
profiler
.
runcall
(
pt
.
pt_render
,
0
,
data
)
def
profile_tal
(
fn
,
count
,
profiler
):
p
=
HTMLTALParser
()
p
.
parseFile
(
fn
)
program
,
macros
=
p
.
getCode
()
engine
=
DummyEngine
(
macros
)
engine
.
globals
=
data
tal
=
TALInterpreter
(
program
,
macros
,
engine
,
StringIO
(),
wrap
=
0
,
tal
=
1
,
strictinsert
=
0
)
for
i
in
range
(
4
):
tal
()
r
=
[
None
]
*
count
for
i
in
r
:
profiler
.
runcall
(
tal
)
tal_fn
=
'benchmark/tal%.2d.html'
dtml_fn
=
'benchmark/dtml%.2d.html'
def
compare
(
n
,
count
,
profiler
=
None
):
t1
=
int
(
time_zpt
(
tal_fn
%
n
,
count
)
*
1000
+
0.5
)
t2
=
int
(
time_tal
(
tal_fn
%
n
,
count
)
*
1000
+
0.5
)
t3
=
int
(
time_dtml
(
dtml_fn
%
n
,
count
)
*
1000
+
0.5
)
print
'%.2d: %10s %10s %10s'
%
(
n
,
t1
,
t2
,
t3
)
if
profiler
:
profile_tal
(
tal_fn
%
n
,
count
,
profiler
)
def
main
(
count
,
profiler
=
None
):
n
=
1
print
'##: %10s %10s %10s'
%
(
'ZPT'
,
'TAL'
,
'DTML'
)
while
os
.
path
.
isfile
(
tal_fn
%
n
)
and
os
.
path
.
isfile
(
dtml_fn
%
n
):
compare
(
n
,
count
,
profiler
)
n
=
n
+
1
data
=
{
'x'
:
'X'
,
'r2'
:
range
(
2
),
'r8'
:
range
(
8
),
'r64'
:
range
(
64
)}
for
i
in
range
(
10
):
data
[
'x%s'
%
i
]
=
'X%s'
%
i
if
__name__
==
"__main__"
:
filename
=
"markbench.prof"
profiler
=
None
if
len
(
sys
.
argv
)
>
1
and
sys
.
argv
[
1
]
==
"-p"
:
import
profile
profiler
=
profile
.
Profile
()
del
sys
.
argv
[
1
]
if
len
(
sys
.
argv
)
>
1
:
for
arg
in
sys
.
argv
[
1
:]:
compare
(
int
(
arg
),
25
,
profiler
)
else
:
main
(
25
,
profiler
)
if
profiler
is
not
None
:
profiler
.
dump_stats
(
filename
)
import
pstats
p
=
pstats
.
Stats
(
filename
)
p
.
strip_dirs
()
p
.
sort_stats
(
'time'
,
'calls'
)
try
:
p
.
print_stats
(
20
)
except
IOError
,
e
:
if
e
.
errno
!=
errno
.
EPIPE
:
raise
lib/python/TAL/markupbase.py
deleted
100644 → 0
View file @
1c0af142
"""Shared support for scanning document type declarations in HTML and XHTML."""
import
re
,
string
_declname_match
=
re
.
compile
(
r'[a-zA-Z][-_.a-zA-Z0-9]*\
s*
').match
_declstringlit_match = re.compile(r'
(
\
'[^
\
'
]*
\
'
|"[^"]*")
\
s*
'
).match
del re
class ParserBase:
"""Parser base class which provides some common support methods used
by the SGML/HTML and XHTML parsers."""
def reset(self):
self.lineno = 1
self.offset = 0
def getpos(self):
"""Return current line number and offset."""
return self.lineno, self.offset
def error(self, message):
"""Return an error, showing current line number and offset.
Concrete subclasses *must* override this method.
"""
raise NotImplementedError
# Internal -- update line number and offset. This should be
# called for each piece of data exactly once, in order -- in other
# words the concatenation of all the input strings to this
# function should be exactly the entire input.
def updatepos(self, i, j):
if i >= j:
return j
rawdata = self.rawdata
nlines = rawdata.count("
\
n
", i, j)
if nlines:
self.lineno = self.lineno + nlines
pos = rawdata.rindex("
\
n
", i, j) # Should not fail
self.offset = j-(pos+1)
else:
self.offset = self.offset + j-i
return j
_decl_otherchars = ''
# Internal -- parse declaration (for use by subclasses).
def parse_declaration(self, i):
# This is some sort of declaration; in "HTML as
# deployed," this should only be the document type
# declaration ("<!DOCTYPE html...>").
rawdata = self.rawdata
import sys
j = i + 2
assert rawdata[i:j] == "<!", "unexpected call to parse_declaration"
if rawdata[j:j+1] in ("-", ""):
# Start of comment followed by buffer boundary,
# or just a buffer boundary.
return -1
# in practice, this should look like: ((name|stringlit) S*)+ '
>
'
n = len(rawdata)
decltype, j = self._scan_name(j, i)
if j < 0:
return j
if decltype == "doctype":
self._decl_otherchars = ''
while j < n:
c = rawdata[j]
if c == ">":
# end of declaration syntax
data = rawdata[i+2:j]
if decltype == "doctype":
self.handle_decl(data)
else:
self.unknown_decl(data)
return j + 1
if c in "
\
"
'":
m = _declstringlit_match(rawdata, j)
if not m:
return -1 # incomplete
j = m.end()
elif c in "
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
":
name, j = self._scan_name(j, i)
elif c in self._decl_otherchars:
j = j + 1
elif c == "
[
":
if decltype == "
doctype
":
j = self._parse_doctype_subset(j + 1, i)
else:
self.error("
unexpected
'['
char
in
declaration
")
else:
self.error(
"
unexpected
%
s
char
in
declaration
" % `rawdata[j]`)
if j < 0:
return j
return -1 # incomplete
# Internal -- scan past the internal subset in a <!DOCTYPE declaration,
# returning the index just past any whitespace following the trailing ']'.
def _parse_doctype_subset(self, i, declstartpos):
rawdata = self.rawdata
n = len(rawdata)
j = i
while j < n:
c = rawdata[j]
if c == "
<
":
s = rawdata[j:j+2]
if s == "
<
":
# end of buffer; incomplete
return -1
if s != "
<
!
":
self.updatepos(declstartpos, j + 1)
self.error("
unexpected
char
in
internal
subset
(
in
%
s
)
"
% `s`)
if (j + 2) == n:
# end of buffer; incomplete
return -1
if (j + 4) > n:
# end of buffer; incomplete
return -1
if rawdata[j:j+4] == "
<
!
--
":
j = self.parse_comment(j, report=0)
if j < 0:
return j
continue
name, j = self._scan_name(j + 2, declstartpos)
if j == -1:
return -1
if name not in ("
attlist
", "
element
", "
entity
", "
notation
"):
self.updatepos(declstartpos, j + 2)
self.error(
"
unknown
declaration
%
s
in
internal
subset
" % `name`)
# handle the individual names
meth = getattr(self, "
_parse_doctype_
" + name)
j = meth(j, declstartpos)
if j < 0:
return j
elif c == "
%
":
# parameter entity reference
if (j + 1) == n:
# end of buffer; incomplete
return -1
s, j = self._scan_name(j + 1, declstartpos)
if j < 0:
return j
if rawdata[j] == "
;
":
j = j + 1
elif c == "
]
":
j = j + 1
while j < n and rawdata[j] in string.whitespace:
j = j + 1
if j < n:
if rawdata[j] == "
>
":
return j
self.updatepos(declstartpos, j)
self.error("
unexpected
char
after
internal
subset
")
else:
return -1
elif c in string.whitespace:
j = j + 1
else:
self.updatepos(declstartpos, j)
self.error("
unexpected
char
%
s
in
internal
subset
" % `c`)
# end of buffer reached
return -1
# Internal -- scan past <!ELEMENT declarations
def _parse_doctype_element(self, i, declstartpos):
rawdata = self.rawdata
n = len(rawdata)
name, j = self._scan_name(i, declstartpos)
if j == -1:
return -1
# style content model; just skip until '>'
if '>' in rawdata[j:]:
return rawdata.find("
>
", j) + 1
return -1
# Internal -- scan past <!ATTLIST declarations
def _parse_doctype_attlist(self, i, declstartpos):
rawdata = self.rawdata
name, j = self._scan_name(i, declstartpos)
c = rawdata[j:j+1]
if c == "":
return -1
if c == "
>
":
return j + 1
while 1:
# scan a series of attribute descriptions; simplified:
# name type [value] [#constraint]
name, j = self._scan_name(j, declstartpos)
if j < 0:
return j
c = rawdata[j:j+1]
if c == "":
return -1
if c == "
(
":
# an enumerated type; look for ')'
if "
)
" in rawdata[j:]:
j = rawdata.find("
)
", j) + 1
else:
return -1
while rawdata[j:j+1].isspace():
j = j + 1
if not rawdata[j:]:
# end of buffer, incomplete
return -1
else:
name, j = self._scan_name(j, declstartpos)
c = rawdata[j:j+1]
if not c:
return -1
if c in "'
\
"
":
m = _declstringlit_match(rawdata, j)
if m:
j = m.end()
else:
return -1
c = rawdata[j:j+1]
if not c:
return -1
if c == "#":
if rawdata[j:] == "#":
# end of buffer
return -1
name, j = self._scan_name(j + 1, declstartpos)
if j < 0:
return j
c = rawdata[j:j+1]
if not c:
return -1
if c == '
>
':
# all done
return j + 1
# Internal -- scan past <!NOTATION declarations
def _parse_doctype_notation(self, i, declstartpos):
name, j = self._scan_name(i, declstartpos)
if j < 0:
return j
rawdata = self.rawdata
while 1:
c = rawdata[j:j+1]
if not c:
# end of buffer; incomplete
return -1
if c == '
>
':
return j + 1
if c in "'
\
""
:
m
=
_declstringlit_match
(
rawdata
,
j
)
if
not
m
:
return
-
1
j
=
m
.
end
()
else
:
name
,
j
=
self
.
_scan_name
(
j
,
declstartpos
)
if
j
<
0
:
return
j
# Internal -- scan past <!ENTITY declarations
def
_parse_doctype_entity
(
self
,
i
,
declstartpos
):
rawdata
=
self
.
rawdata
if
rawdata
[
i
:
i
+
1
]
==
"%"
:
j
=
i
+
1
while
1
:
c
=
rawdata
[
j
:
j
+
1
]
if
not
c
:
return
-
1
if
c
in
string
.
whitespace
:
j
=
j
+
1
else
:
break
else
:
j
=
i
name
,
j
=
self
.
_scan_name
(
j
,
declstartpos
)
if
j
<
0
:
return
j
while
1
:
c
=
self
.
rawdata
[
j
:
j
+
1
]
if
not
c
:
return
-
1
if
c
in
"'
\
"
"
:
m
=
_declstringlit_match
(
rawdata
,
j
)
if
m
:
j
=
m
.
end
()
else
:
return
-
1
# incomplete
elif
c
==
">"
:
return
j
+
1
else
:
name
,
j
=
self
.
_scan_name
(
j
,
declstartpos
)
if
j
<
0
:
return
j
# Internal -- scan a name token and the new position and the token, or
# return -1 if we've reached the end of the buffer.
def
_scan_name
(
self
,
i
,
declstartpos
):
rawdata
=
self
.
rawdata
n
=
len
(
rawdata
)
if
i
==
n
:
return
None
,
-
1
m
=
_declname_match
(
rawdata
,
i
)
if
m
:
s
=
m
.
group
()
name
=
s
.
strip
()
if
(
i
+
len
(
s
))
==
n
:
return
None
,
-
1
# end of buffer
return
name
.
lower
(),
m
.
end
()
else
:
self
.
updatepos
(
declstartpos
,
i
)
self
.
error
(
"expected name token"
)
lib/python/TAL/ndiff.py
deleted
100644 → 0
View file @
1c0af142
#! /usr/bin/env python
# Module ndiff version 1.6.0
# Released to the public domain 08-Dec-2000,
# by Tim Peters (tim.one@home.com).
# Provided as-is; use at your own risk; no warranty; no promises; enjoy!
"""ndiff [-q] file1 file2
or
ndiff (-r1 | -r2) < ndiff_output > file1_or_file2
Print a human-friendly file difference report to stdout. Both inter-
and intra-line differences are noted. In the second form, recreate file1
(-r1) or file2 (-r2) on stdout, from an ndiff report on stdin.
In the first form, if -q ("quiet") is not specified, the first two lines
of output are
-: file1
+: file2
Each remaining line begins with a two-letter code:
"- " line unique to file1
"+ " line unique to file2
" " line common to both files
"? " line not present in either input file
Lines beginning with "? " attempt to guide the eye to intraline
differences, and were not present in either input file. These lines can be
confusing if the source files contain tab characters.
The first file can be recovered by retaining only lines that begin with
" " or "- ", and deleting those 2-character prefixes; use ndiff with -r1.
The second file can be recovered similarly, but by retaining only " " and
"+ " lines; use ndiff with -r2; or, on Unix, the second file can be
recovered by piping the output through
sed -n '/^[+ ] /s/^..//p'
See module comments for details and programmatic interface.
"""
__version__
=
1
,
5
,
0
# SequenceMatcher tries to compute a "human-friendly diff" between
# two sequences (chiefly picturing a file as a sequence of lines,
# and a line as a sequence of characters, here). Unlike e.g. UNIX(tm)
# diff, the fundamental notion is the longest *contiguous* & junk-free
# matching subsequence. That's what catches peoples' eyes. The
# Windows(tm) windiff has another interesting notion, pairing up elements
# that appear uniquely in each sequence. That, and the method here,
# appear to yield more intuitive difference reports than does diff. This
# method appears to be the least vulnerable to synching up on blocks
# of "junk lines", though (like blank lines in ordinary text files,
# or maybe "<P>" lines in HTML files). That may be because this is
# the only method of the 3 that has a *concept* of "junk" <wink>.
#
# Note that ndiff makes no claim to produce a *minimal* diff. To the
# contrary, minimal diffs are often counter-intuitive, because they
# synch up anywhere possible, sometimes accidental matches 100 pages
# apart. Restricting synch points to contiguous matches preserves some
# notion of locality, at the occasional cost of producing a longer diff.
#
# With respect to junk, an earlier version of ndiff simply refused to
# *start* a match with a junk element. The result was cases like this:
# before: private Thread currentThread;
# after: private volatile Thread currentThread;
# If you consider whitespace to be junk, the longest contiguous match
# not starting with junk is "e Thread currentThread". So ndiff reported
# that "e volatil" was inserted between the 't' and the 'e' in "private".
# While an accurate view, to people that's absurd. The current version
# looks for matching blocks that are entirely junk-free, then extends the
# longest one of those as far as possible but only with matching junk.
# So now "currentThread" is matched, then extended to suck up the
# preceding blank; then "private" is matched, and extended to suck up the
# following blank; then "Thread" is matched; and finally ndiff reports
# that "volatile " was inserted before "Thread". The only quibble
# remaining is that perhaps it was really the case that " volatile"
# was inserted after "private". I can live with that <wink>.
#
# NOTE on junk: the module-level names
# IS_LINE_JUNK
# IS_CHARACTER_JUNK
# can be set to any functions you like. The first one should accept
# a single string argument, and return true iff the string is junk.
# The default is whether the regexp r"\s*#?\s*$" matches (i.e., a
# line without visible characters, except for at most one splat).
# The second should accept a string of length 1 etc. The default is
# whether the character is a blank or tab (note: bad idea to include
# newline in this!).
#
# After setting those, you can call fcompare(f1name, f2name) with the
# names of the files you want to compare. The difference report
# is sent to stdout. Or you can call main(args), passing what would
# have been in sys.argv[1:] had the cmd-line form been used.
TRACE
=
0
# define what "junk" means
import
re
def
IS_LINE_JUNK
(
line
,
pat
=
re
.
compile
(
r"\
s*#?
\s*$"
).
match
):
return
pat
(
line
)
is
not
None
def
IS_CHARACTER_JUNK
(
ch
,
ws
=
"
\
t
"
):
return
ch
in
ws
del
re
class
SequenceMatcher
:
def
__init__
(
self
,
isjunk
=
None
,
a
=
''
,
b
=
''
):
# Members:
# a
# first sequence
# b
# second sequence; differences are computed as "what do
# we need to do to 'a' to change it into 'b'?"
# b2j
# for x in b, b2j[x] is a list of the indices (into b)
# at which x appears; junk elements do not appear
# b2jhas
# b2j.has_key
# fullbcount
# for x in b, fullbcount[x] == the number of times x
# appears in b; only materialized if really needed (used
# only for computing quick_ratio())
# matching_blocks
# a list of (i, j, k) triples, where a[i:i+k] == b[j:j+k];
# ascending & non-overlapping in i and in j; terminated by
# a dummy (len(a), len(b), 0) sentinel
# opcodes
# a list of (tag, i1, i2, j1, j2) tuples, where tag is
# one of
# 'replace' a[i1:i2] should be replaced by b[j1:j2]
# 'delete' a[i1:i2] should be deleted
# 'insert' b[j1:j2] should be inserted
# 'equal' a[i1:i2] == b[j1:j2]
# isjunk
# a user-supplied function taking a sequence element and
# returning true iff the element is "junk" -- this has
# subtle but helpful effects on the algorithm, which I'll
# get around to writing up someday <0.9 wink>.
# DON'T USE! Only __chain_b uses this. Use isbjunk.
# isbjunk
# for x in b, isbjunk(x) == isjunk(x) but much faster;
# it's really the has_key method of a hidden dict.
# DOES NOT WORK for x in a!
self
.
isjunk
=
isjunk
self
.
a
=
self
.
b
=
None
self
.
set_seqs
(
a
,
b
)
def
set_seqs
(
self
,
a
,
b
):
self
.
set_seq1
(
a
)
self
.
set_seq2
(
b
)
def
set_seq1
(
self
,
a
):
if
a
is
self
.
a
:
return
self
.
a
=
a
self
.
matching_blocks
=
self
.
opcodes
=
None
def
set_seq2
(
self
,
b
):
if
b
is
self
.
b
:
return
self
.
b
=
b
self
.
matching_blocks
=
self
.
opcodes
=
None
self
.
fullbcount
=
None
self
.
__chain_b
()
# For each element x in b, set b2j[x] to a list of the indices in
# b where x appears; the indices are in increasing order; note that
# the number of times x appears in b is len(b2j[x]) ...
# when self.isjunk is defined, junk elements don't show up in this
# map at all, which stops the central find_longest_match method
# from starting any matching block at a junk element ...
# also creates the fast isbjunk function ...
# note that this is only called when b changes; so for cross-product
# kinds of matches, it's best to call set_seq2 once, then set_seq1
# repeatedly
def
__chain_b
(
self
):
# Because isjunk is a user-defined (not C) function, and we test
# for junk a LOT, it's important to minimize the number of calls.
# Before the tricks described here, __chain_b was by far the most
# time-consuming routine in the whole module! If anyone sees
# Jim Roskind, thank him again for profile.py -- I never would
# have guessed that.
# The first trick is to build b2j ignoring the possibility
# of junk. I.e., we don't call isjunk at all yet. Throwing
# out the junk later is much cheaper than building b2j "right"
# from the start.
b
=
self
.
b
self
.
b2j
=
b2j
=
{}
self
.
b2jhas
=
b2jhas
=
b2j
.
has_key
for
i
in
xrange
(
len
(
b
)):
elt
=
b
[
i
]
if
b2jhas
(
elt
):
b2j
[
elt
].
append
(
i
)
else
:
b2j
[
elt
]
=
[
i
]
# Now b2j.keys() contains elements uniquely, and especially when
# the sequence is a string, that's usually a good deal smaller
# than len(string). The difference is the number of isjunk calls
# saved.
isjunk
,
junkdict
=
self
.
isjunk
,
{}
if
isjunk
:
for
elt
in
b2j
.
keys
():
if
isjunk
(
elt
):
junkdict
[
elt
]
=
1
# value irrelevant; it's a set
del
b2j
[
elt
]
# Now for x in b, isjunk(x) == junkdict.has_key(x), but the
# latter is much faster. Note too that while there may be a
# lot of junk in the sequence, the number of *unique* junk
# elements is probably small. So the memory burden of keeping
# this dict alive is likely trivial compared to the size of b2j.
self
.
isbjunk
=
junkdict
.
has_key
def
find_longest_match
(
self
,
alo
,
ahi
,
blo
,
bhi
):
"""Find longest matching block in a[alo:ahi] and b[blo:bhi].
If isjunk is not defined:
Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
alo <= i <= i+k <= ahi
blo <= j <= j+k <= bhi
and for all (i',j',k') meeting those conditions,
k >= k'
i <= i'
and if i == i', j <= j'
In other words, of all maximal matching blocks, return one
that starts earliest in a, and of all those maximal matching
blocks that start earliest in a, return the one that starts
earliest in b.
If isjunk is defined, first the longest matching block is
determined as above, but with the additional restriction that
no junk element appears in the block. Then that block is
extended as far as possible by matching (only) junk elements on
both sides. So the resulting block never matches on junk except
as identical junk happens to be adjacent to an "interesting"
match.
If no blocks match, return (alo, blo, 0).
"""
# CAUTION: stripping common prefix or suffix would be incorrect.
# E.g.,
# ab
# acab
# Longest matching block is "ab", but if common prefix is
# stripped, it's "a" (tied with "b"). UNIX(tm) diff does so
# strip, so ends up claiming that ab is changed to acab by
# inserting "ca" in the middle. That's minimal but unintuitive:
# "it's obvious" that someone inserted "ac" at the front.
# Windiff ends up at the same place as diff, but by pairing up
# the unique 'b's and then matching the first two 'a's.
a
,
b
,
b2j
,
isbjunk
=
self
.
a
,
self
.
b
,
self
.
b2j
,
self
.
isbjunk
besti
,
bestj
,
bestsize
=
alo
,
blo
,
0
# find longest junk-free match
# during an iteration of the loop, j2len[j] = length of longest
# junk-free match ending with a[i-1] and b[j]
j2len
=
{}
nothing
=
[]
for
i
in
xrange
(
alo
,
ahi
):
# look at all instances of a[i] in b; note that because
# b2j has no junk keys, the loop is skipped if a[i] is junk
j2lenget
=
j2len
.
get
newj2len
=
{}
for
j
in
b2j
.
get
(
a
[
i
],
nothing
):
# a[i] matches b[j]
if
j
<
blo
:
continue
if
j
>=
bhi
:
break
k
=
newj2len
[
j
]
=
j2lenget
(
j
-
1
,
0
)
+
1
if
k
>
bestsize
:
besti
,
bestj
,
bestsize
=
i
-
k
+
1
,
j
-
k
+
1
,
k
j2len
=
newj2len
# Now that we have a wholly interesting match (albeit possibly
# empty!), we may as well suck up the matching junk on each
# side of it too. Can't think of a good reason not to, and it
# saves post-processing the (possibly considerable) expense of
# figuring out what to do with it. In the case of an empty
# interesting match, this is clearly the right thing to do,
# because no other kind of match is possible in the regions.
while
besti
>
alo
and
bestj
>
blo
and
\
isbjunk
(
b
[
bestj
-
1
])
and
\
a
[
besti
-
1
]
==
b
[
bestj
-
1
]:
besti
,
bestj
,
bestsize
=
besti
-
1
,
bestj
-
1
,
bestsize
+
1
while
besti
+
bestsize
<
ahi
and
bestj
+
bestsize
<
bhi
and
\
isbjunk
(
b
[
bestj
+
bestsize
])
and
\
a
[
besti
+
bestsize
]
==
b
[
bestj
+
bestsize
]:
bestsize
=
bestsize
+
1
if
TRACE
:
print
"get_matching_blocks"
,
alo
,
ahi
,
blo
,
bhi
print
" returns"
,
besti
,
bestj
,
bestsize
return
besti
,
bestj
,
bestsize
def
get_matching_blocks
(
self
):
if
self
.
matching_blocks
is
not
None
:
return
self
.
matching_blocks
self
.
matching_blocks
=
[]
la
,
lb
=
len
(
self
.
a
),
len
(
self
.
b
)
self
.
__helper
(
0
,
la
,
0
,
lb
,
self
.
matching_blocks
)
self
.
matching_blocks
.
append
(
(
la
,
lb
,
0
)
)
if
TRACE
:
print
'*** matching blocks'
,
self
.
matching_blocks
return
self
.
matching_blocks
# builds list of matching blocks covering a[alo:ahi] and
# b[blo:bhi], appending them in increasing order to answer
def
__helper
(
self
,
alo
,
ahi
,
blo
,
bhi
,
answer
):
i
,
j
,
k
=
x
=
self
.
find_longest_match
(
alo
,
ahi
,
blo
,
bhi
)
# a[alo:i] vs b[blo:j] unknown
# a[i:i+k] same as b[j:j+k]
# a[i+k:ahi] vs b[j+k:bhi] unknown
if
k
:
if
alo
<
i
and
blo
<
j
:
self
.
__helper
(
alo
,
i
,
blo
,
j
,
answer
)
answer
.
append
(
x
)
if
i
+
k
<
ahi
and
j
+
k
<
bhi
:
self
.
__helper
(
i
+
k
,
ahi
,
j
+
k
,
bhi
,
answer
)
def
ratio
(
self
):
"""Return a measure of the sequences' similarity (float in [0,1]).
Where T is the total number of elements in both sequences, and
M is the number of matches, this is 2*M / T.
Note that this is 1 if the sequences are identical, and 0 if
they have nothing in common.
"""
matches
=
reduce
(
lambda
sum
,
triple
:
sum
+
triple
[
-
1
],
self
.
get_matching_blocks
(),
0
)
return
2.0
*
matches
/
(
len
(
self
.
a
)
+
len
(
self
.
b
))
def
quick_ratio
(
self
):
"""Return an upper bound on ratio() relatively quickly."""
# viewing a and b as multisets, set matches to the cardinality
# of their intersection; this counts the number of matches
# without regard to order, so is clearly an upper bound
if
self
.
fullbcount
is
None
:
self
.
fullbcount
=
fullbcount
=
{}
for
elt
in
self
.
b
:
fullbcount
[
elt
]
=
fullbcount
.
get
(
elt
,
0
)
+
1
fullbcount
=
self
.
fullbcount
# avail[x] is the number of times x appears in 'b' less the
# number of times we've seen it in 'a' so far ... kinda
avail
=
{}
availhas
,
matches
=
avail
.
has_key
,
0
for
elt
in
self
.
a
:
if
availhas
(
elt
):
numb
=
avail
[
elt
]
else
:
numb
=
fullbcount
.
get
(
elt
,
0
)
avail
[
elt
]
=
numb
-
1
if
numb
>
0
:
matches
=
matches
+
1
return
2.0
*
matches
/
(
len
(
self
.
a
)
+
len
(
self
.
b
))
def
real_quick_ratio
(
self
):
"""Return an upper bound on ratio() very quickly"""
la
,
lb
=
len
(
self
.
a
),
len
(
self
.
b
)
# can't have more matches than the number of elements in the
# shorter sequence
return
2.0
*
min
(
la
,
lb
)
/
(
la
+
lb
)
def
get_opcodes
(
self
):
if
self
.
opcodes
is
not
None
:
return
self
.
opcodes
i
=
j
=
0
self
.
opcodes
=
answer
=
[]
for
ai
,
bj
,
size
in
self
.
get_matching_blocks
():
# invariant: we've pumped out correct diffs to change
# a[:i] into b[:j], and the next matching block is
# a[ai:ai+size] == b[bj:bj+size]. So we need to pump
# out a diff to change a[i:ai] into b[j:bj], pump out
# the matching block, and move (i,j) beyond the match
tag
=
''
if
i
<
ai
and
j
<
bj
:
tag
=
'replace'
elif
i
<
ai
:
tag
=
'delete'
elif
j
<
bj
:
tag
=
'insert'
if
tag
:
answer
.
append
(
(
tag
,
i
,
ai
,
j
,
bj
)
)
i
,
j
=
ai
+
size
,
bj
+
size
# the list of matching blocks is terminated by a
# sentinel with size 0
if
size
:
answer
.
append
(
(
'equal'
,
ai
,
i
,
bj
,
j
)
)
return
answer
# meant for dumping lines
def
dump
(
tag
,
x
,
lo
,
hi
):
for
i
in
xrange
(
lo
,
hi
):
print
tag
,
x
[
i
],
def
plain_replace
(
a
,
alo
,
ahi
,
b
,
blo
,
bhi
):
assert
alo
<
ahi
and
blo
<
bhi
# dump the shorter block first -- reduces the burden on short-term
# memory if the blocks are of very different sizes
if
bhi
-
blo
<
ahi
-
alo
:
dump
(
'+'
,
b
,
blo
,
bhi
)
dump
(
'-'
,
a
,
alo
,
ahi
)
else
:
dump
(
'-'
,
a
,
alo
,
ahi
)
dump
(
'+'
,
b
,
blo
,
bhi
)
# When replacing one block of lines with another, this guy searches
# the blocks for *similar* lines; the best-matching pair (if any) is
# used as a synch point, and intraline difference marking is done on
# the similar pair. Lots of work, but often worth it.
def
fancy_replace
(
a
,
alo
,
ahi
,
b
,
blo
,
bhi
):
if
TRACE
:
print
'*** fancy_replace'
,
alo
,
ahi
,
blo
,
bhi
dump
(
'>'
,
a
,
alo
,
ahi
)
dump
(
'<'
,
b
,
blo
,
bhi
)
# don't synch up unless the lines have a similarity score of at
# least cutoff; best_ratio tracks the best score seen so far
best_ratio
,
cutoff
=
0.74
,
0.75
cruncher
=
SequenceMatcher
(
IS_CHARACTER_JUNK
)
eqi
,
eqj
=
None
,
None
# 1st indices of equal lines (if any)
# search for the pair that matches best without being identical
# (identical lines must be junk lines, & we don't want to synch up
# on junk -- unless we have to)
for
j
in
xrange
(
blo
,
bhi
):
bj
=
b
[
j
]
cruncher
.
set_seq2
(
bj
)
for
i
in
xrange
(
alo
,
ahi
):
ai
=
a
[
i
]
if
ai
==
bj
:
if
eqi
is
None
:
eqi
,
eqj
=
i
,
j
continue
cruncher
.
set_seq1
(
ai
)
# computing similarity is expensive, so use the quick
# upper bounds first -- have seen this speed up messy
# compares by a factor of 3.
# note that ratio() is only expensive to compute the first
# time it's called on a sequence pair; the expensive part
# of the computation is cached by cruncher
if
cruncher
.
real_quick_ratio
()
>
best_ratio
and
\
cruncher
.
quick_ratio
()
>
best_ratio
and
\
cruncher
.
ratio
()
>
best_ratio
:
best_ratio
,
best_i
,
best_j
=
cruncher
.
ratio
(),
i
,
j
if
best_ratio
<
cutoff
:
# no non-identical "pretty close" pair
if
eqi
is
None
:
# no identical pair either -- treat it as a straight replace
plain_replace
(
a
,
alo
,
ahi
,
b
,
blo
,
bhi
)
return
# no close pair, but an identical pair -- synch up on that
best_i
,
best_j
,
best_ratio
=
eqi
,
eqj
,
1.0
else
:
# there's a close pair, so forget the identical pair (if any)
eqi
=
None
# a[best_i] very similar to b[best_j]; eqi is None iff they're not
# identical
if
TRACE
:
print
'*** best_ratio'
,
best_ratio
,
best_i
,
best_j
dump
(
'>'
,
a
,
best_i
,
best_i
+
1
)
dump
(
'<'
,
b
,
best_j
,
best_j
+
1
)
# pump out diffs from before the synch point
fancy_helper
(
a
,
alo
,
best_i
,
b
,
blo
,
best_j
)
# do intraline marking on the synch pair
aelt
,
belt
=
a
[
best_i
],
b
[
best_j
]
if
eqi
is
None
:
# pump out a '-', '?', '+', '?' quad for the synched lines
atags
=
btags
=
""
cruncher
.
set_seqs
(
aelt
,
belt
)
for
tag
,
ai1
,
ai2
,
bj1
,
bj2
in
cruncher
.
get_opcodes
():
la
,
lb
=
ai2
-
ai1
,
bj2
-
bj1
if
tag
==
'replace'
:
atags
=
atags
+
'^'
*
la
btags
=
btags
+
'^'
*
lb
elif
tag
==
'delete'
:
atags
=
atags
+
'-'
*
la
elif
tag
==
'insert'
:
btags
=
btags
+
'+'
*
lb
elif
tag
==
'equal'
:
atags
=
atags
+
' '
*
la
btags
=
btags
+
' '
*
lb
else
:
raise
ValueError
,
'unknown tag '
+
`tag`
printq
(
aelt
,
belt
,
atags
,
btags
)
else
:
# the synch pair is identical
print
' '
,
aelt
,
# pump out diffs from after the synch point
fancy_helper
(
a
,
best_i
+
1
,
ahi
,
b
,
best_j
+
1
,
bhi
)
def
fancy_helper
(
a
,
alo
,
ahi
,
b
,
blo
,
bhi
):
if
alo
<
ahi
:
if
blo
<
bhi
:
fancy_replace
(
a
,
alo
,
ahi
,
b
,
blo
,
bhi
)
else
:
dump
(
'-'
,
a
,
alo
,
ahi
)
elif
blo
<
bhi
:
dump
(
'+'
,
b
,
blo
,
bhi
)
# Crap to deal with leading tabs in "?" output. Can hurt, but will
# probably help most of the time.
def
printq
(
aline
,
bline
,
atags
,
btags
):
common
=
min
(
count_leading
(
aline
,
"
\
t
"
),
count_leading
(
bline
,
"
\
t
"
))
common
=
min
(
common
,
count_leading
(
atags
[:
common
],
" "
))
print
"-"
,
aline
,
if
count_leading
(
atags
,
" "
)
<
len
(
atags
):
print
"?"
,
"
\
t
"
*
common
+
atags
[
common
:]
print
"+"
,
bline
,
if
count_leading
(
btags
,
" "
)
<
len
(
btags
):
print
"?"
,
"
\
t
"
*
common
+
btags
[
common
:]
def
count_leading
(
line
,
ch
):
i
,
n
=
0
,
len
(
line
)
while
i
<
n
and
line
[
i
]
==
ch
:
i
=
i
+
1
return
i
def
fail
(
msg
):
import
sys
out
=
sys
.
stderr
.
write
out
(
msg
+
"
\
n
\
n
"
)
out
(
__doc__
)
return
0
# open a file & return the file object; gripe and return 0 if it
# couldn't be opened
def
fopen
(
fname
):
try
:
return
open
(
fname
,
'r'
)
except
IOError
,
detail
:
return
fail
(
"couldn't open "
+
fname
+
": "
+
str
(
detail
))
# open two files & spray the diff to stdout; return false iff a problem
def
fcompare
(
f1name
,
f2name
):
f1
=
fopen
(
f1name
)
f2
=
fopen
(
f2name
)
if
not
f1
or
not
f2
:
return
0
a
=
f1
.
readlines
();
f1
.
close
()
b
=
f2
.
readlines
();
f2
.
close
()
cruncher
=
SequenceMatcher
(
IS_LINE_JUNK
,
a
,
b
)
for
tag
,
alo
,
ahi
,
blo
,
bhi
in
cruncher
.
get_opcodes
():
if
tag
==
'replace'
:
fancy_replace
(
a
,
alo
,
ahi
,
b
,
blo
,
bhi
)
elif
tag
==
'delete'
:
dump
(
'-'
,
a
,
alo
,
ahi
)
elif
tag
==
'insert'
:
dump
(
'+'
,
b
,
blo
,
bhi
)
elif
tag
==
'equal'
:
dump
(
' '
,
a
,
alo
,
ahi
)
else
:
raise
ValueError
,
'unknown tag '
+
`tag`
return
1
# crack args (sys.argv[1:] is normal) & compare;
# return false iff a problem
def
main
(
args
):
import
getopt
try
:
opts
,
args
=
getopt
.
getopt
(
args
,
"qr:"
)
except
getopt
.
error
,
detail
:
return
fail
(
str
(
detail
))
noisy
=
1
qseen
=
rseen
=
0
for
opt
,
val
in
opts
:
if
opt
==
"-q"
:
qseen
=
1
noisy
=
0
elif
opt
==
"-r"
:
rseen
=
1
whichfile
=
val
if
qseen
and
rseen
:
return
fail
(
"can't specify both -q and -r"
)
if
rseen
:
if
args
:
return
fail
(
"no args allowed with -r option"
)
if
whichfile
in
"12"
:
restore
(
whichfile
)
return
1
return
fail
(
"-r value must be 1 or 2"
)
if
len
(
args
)
!=
2
:
return
fail
(
"need 2 filename args"
)
f1name
,
f2name
=
args
if
noisy
:
print
'-:'
,
f1name
print
'+:'
,
f2name
return
fcompare
(
f1name
,
f2name
)
def
restore
(
which
):
import
sys
tag
=
{
"1"
:
"- "
,
"2"
:
"+ "
}[
which
]
prefixes
=
(
" "
,
tag
)
for
line
in
sys
.
stdin
.
readlines
():
if
line
[:
2
]
in
prefixes
:
print
line
[
2
:],
if
__name__
==
'__main__'
:
import
sys
args
=
sys
.
argv
[
1
:]
if
"-profile"
in
args
:
import
profile
,
pstats
args
.
remove
(
"-profile"
)
statf
=
"ndiff.pro"
profile
.
run
(
"main(args)"
,
statf
)
stats
=
pstats
.
Stats
(
statf
)
stats
.
strip_dirs
().
sort_stats
(
'time'
).
print_stats
()
else
:
main
(
args
)
lib/python/TAL/runtest.py
deleted
100755 → 0
View file @
1c0af142
#! /usr/bin/env python
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
Driver program to run METAL and TAL regression tests.
"""
import
sys
import
os
from
cStringIO
import
StringIO
import
glob
import
traceback
if
__name__
==
"__main__"
:
import
setpath
# Local hack to tweak sys.path etc.
import
driver
import
tests.utils
def
showdiff
(
a
,
b
):
import
ndiff
cruncher
=
ndiff
.
SequenceMatcher
(
ndiff
.
IS_LINE_JUNK
,
a
,
b
)
for
tag
,
alo
,
ahi
,
blo
,
bhi
in
cruncher
.
get_opcodes
():
if
tag
==
"equal"
:
continue
print
nicerange
(
alo
,
ahi
)
+
tag
[
0
]
+
nicerange
(
blo
,
bhi
)
ndiff
.
dump
(
'<'
,
a
,
alo
,
ahi
)
if
a
and
b
:
print
'---'
ndiff
.
dump
(
'>'
,
b
,
blo
,
bhi
)
def
nicerange
(
lo
,
hi
):
if
hi
<=
lo
+
1
:
return
str
(
lo
+
1
)
else
:
return
"%d,%d"
%
(
lo
+
1
,
hi
)
def
main
():
opts
=
[]
args
=
sys
.
argv
[
1
:]
quiet
=
0
unittesting
=
0
if
args
and
args
[
0
]
==
"-q"
:
quiet
=
1
del
args
[
0
]
if
args
and
args
[
0
]
==
"-Q"
:
unittesting
=
1
del
args
[
0
]
while
args
and
args
[
0
].
startswith
(
'-'
):
opts
.
append
(
args
[
0
])
del
args
[
0
]
if
not
args
:
prefix
=
os
.
path
.
join
(
"tests"
,
"input"
,
"test*."
)
if
tests
.
utils
.
skipxml
:
xmlargs
=
[]
else
:
xmlargs
=
glob
.
glob
(
prefix
+
"xml"
)
xmlargs
.
sort
()
htmlargs
=
glob
.
glob
(
prefix
+
"html"
)
htmlargs
.
sort
()
args
=
xmlargs
+
htmlargs
if
not
args
:
sys
.
stderr
.
write
(
"No tests found -- please supply filenames
\
n
"
)
sys
.
exit
(
1
)
errors
=
0
for
arg
in
args
:
locopts
=
[]
if
arg
.
find
(
"metal"
)
>=
0
and
"-m"
not
in
opts
:
locopts
.
append
(
"-m"
)
if
not
unittesting
:
print
arg
,
sys
.
stdout
.
flush
()
if
tests
.
utils
.
skipxml
and
arg
.
endswith
(
".xml"
):
print
"SKIPPED (XML parser not available)"
continue
save
=
sys
.
stdout
,
sys
.
argv
try
:
try
:
sys
.
stdout
=
stdout
=
StringIO
()
sys
.
argv
=
[
""
]
+
opts
+
locopts
+
[
arg
]
driver
.
main
()
finally
:
sys
.
stdout
,
sys
.
argv
=
save
except
SystemExit
:
raise
except
:
errors
=
1
if
quiet
:
print
sys
.
exc_type
sys
.
stdout
.
flush
()
else
:
if
unittesting
:
print
else
:
print
"Failed:"
sys
.
stdout
.
flush
()
traceback
.
print_exc
()
continue
head
,
tail
=
os
.
path
.
split
(
arg
)
outfile
=
os
.
path
.
join
(
head
.
replace
(
"input"
,
"output"
),
tail
)
try
:
f
=
open
(
outfile
)
except
IOError
:
expected
=
None
print
"(missing file %s)"
%
outfile
,
else
:
expected
=
f
.
readlines
()
f
.
close
()
stdout
.
seek
(
0
)
if
hasattr
(
stdout
,
"readlines"
):
actual
=
stdout
.
readlines
()
else
:
actual
=
readlines
(
stdout
)
if
actual
==
expected
:
if
not
unittesting
:
print
"OK"
else
:
if
unittesting
:
print
else
:
print
"not OK"
errors
=
1
if
not
quiet
and
expected
is
not
None
:
showdiff
(
expected
,
actual
)
if
errors
:
sys
.
exit
(
1
)
def
readlines
(
f
):
L
=
[]
while
1
:
line
=
f
.
readline
()
if
not
line
:
break
L
.
append
(
line
)
return
L
if
__name__
==
"__main__"
:
main
()
lib/python/TAL/setpath.py
deleted
100644 → 0
View file @
1c0af142
# This software is subject to the provisions of the Zope Public License,
# Version 1.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
"""
Read a module search path from .path.
"""
import
os
import
sys
dir
=
os
.
path
.
dirname
(
__file__
)
path
=
os
.
path
.
join
(
dir
,
".path"
)
try
:
f
=
open
(
path
)
except
IOError
:
raise
IOError
,
"Please edit .path to point to <Zope2/lib/python>"
else
:
for
line
in
f
.
readlines
():
line
=
line
.
strip
()
if
line
and
line
[
0
]
!=
'#'
:
for
dir
in
line
.
split
(
os
.
pathsep
):
dir
=
os
.
path
.
expanduser
(
os
.
path
.
expandvars
(
dir
))
if
dir
not
in
sys
.
path
:
sys
.
path
.
append
(
dir
)
import
ZODB
# Must import this first to initialize Persistence properly
lib/python/TAL/talgettext.py
deleted
100755 → 0
View file @
1c0af142
#!/usr/bin/env python
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Program to extract internationalization markup from Page Templates.
Once you have marked up a Page Template file with i18n: namespace tags, use
this program to extract GNU gettext .po file entries.
Usage: talgettext.py [options] files
Options:
-h / --help
Print this message and exit.
-o / --output <file>
Output the translation .po file to <file>.
-u / --update <file>
Update the existing translation <file> with any new translation strings
found.
"""
import
sys
import
time
import
getopt
import
traceback
from
TAL.HTMLTALParser
import
HTMLTALParser
from
TAL.TALInterpreter
import
TALInterpreter
from
TAL.DummyEngine
import
DummyEngine
from
ITALES
import
ITALESEngine
from
TAL.TALDefs
import
TALESError
__version__
=
'$Revision: 1.1.2.1 $'
pot_header
=
'''
\
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION
\
\
n"
"POT-Creation-Date: %(time)s
\
\
n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
\
\
n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>
\
\
n"
"Language-Team: LANGUAGE <LL@li.org>
\
\
n"
"MIME-Version: 1.0
\
\
n"
"Content-Type: text/plain; charset=CHARSET
\
\
n"
"Content-Transfer-Encoding: ENCODING
\
\
n"
"Generated-By: talgettext.py %(version)s
\
\
n"
'''
NLSTR
=
'"
\
n
"'
try
:
True
except
NameError
:
True
=
1
False
=
0
def
usage
(
code
,
msg
=
''
):
# Python 2.1 required
print
>>
sys
.
stderr
,
__doc__
if
msg
:
print
>>
sys
.
stderr
,
msg
sys
.
exit
(
code
)
class
POTALInterpreter
(
TALInterpreter
):
def
translate
(
self
,
msgid
,
default
,
i18ndict
=
None
,
obj
=
None
):
# XXX is this right?
if
i18ndict
is
None
:
i18ndict
=
{}
if
obj
:
i18ndict
.
update
(
obj
)
# XXX Mmmh, it seems that sometimes the msgid is None; is that really
# possible?
if
msgid
is
None
:
return
None
# XXX We need to pass in one of context or target_language
return
self
.
engine
.
translate
(
msgid
,
self
.
i18nContext
.
domain
,
i18ndict
,
position
=
self
.
position
,
default
=
default
)
class
POEngine
(
DummyEngine
):
__implements__
=
ITALESEngine
def
__init__
(
self
,
macros
=
None
):
self
.
catalog
=
{}
DummyEngine
.
__init__
(
self
,
macros
)
def
evaluate
(
*
args
):
return
''
# who cares
def
evaluatePathOrVar
(
*
args
):
return
''
# who cares
def
evaluateSequence
(
self
,
expr
):
return
(
0
,)
# dummy
def
evaluateBoolean
(
self
,
expr
):
return
True
# dummy
def
translate
(
self
,
msgid
,
domain
=
None
,
mapping
=
None
,
default
=
None
,
# XXX position is not part of the ITALESEngine
# interface
position
=
None
):
if
domain
not
in
self
.
catalog
:
self
.
catalog
[
domain
]
=
{}
domain
=
self
.
catalog
[
domain
]
# ---------------------------------------------
# only non-empty msgids are added to dictionary
# (changed by heinrichbernd - 2004/09/07)
# ---------------------------------------------
if
msgid
:
if
msgid
not
in
domain
:
domain
[
msgid
]
=
[]
domain
[
msgid
].
append
((
self
.
file
,
position
))
return
'x'
class
UpdatePOEngine
(
POEngine
):
"""A slightly-less braindead POEngine which supports loading an existing
.po file first."""
def
__init__
(
self
,
macros
=
None
,
filename
=
None
):
POEngine
.
__init__
(
self
,
macros
)
self
.
_filename
=
filename
self
.
_loadFile
()
self
.
base
=
self
.
catalog
self
.
catalog
=
{}
def
__add
(
self
,
id
,
s
,
fuzzy
):
"Add a non-fuzzy translation to the dictionary."
if
not
fuzzy
and
str
:
# check for multi-line values and munge them appropriately
if
'
\
n
'
in
s
:
lines
=
s
.
rstrip
().
split
(
'
\
n
'
)
s
=
NLSTR
.
join
(
lines
)
self
.
catalog
[
id
]
=
s
def
_loadFile
(
self
):
# shamelessly cribbed from Python's Tools/i18n/msgfmt.py
# 25-Mar-2003 Nathan R. Yergler (nathan@zope.org)
# 14-Apr-2003 Hacked by Barry Warsaw (barry@zope.com)
ID
=
1
STR
=
2
try
:
lines
=
open
(
self
.
_filename
).
readlines
()
except
IOError
,
msg
:
print
>>
sys
.
stderr
,
msg
sys
.
exit
(
1
)
section
=
None
fuzzy
=
False
# Parse the catalog
lno
=
0
for
l
in
lines
:
lno
+=
True
# If we get a comment line after a msgstr, this is a new entry
if
l
[
0
]
==
'#'
and
section
==
STR
:
self
.
__add
(
msgid
,
msgstr
,
fuzzy
)
section
=
None
fuzzy
=
False
# Record a fuzzy mark
if
l
[:
2
]
==
'#,'
and
l
.
find
(
'fuzzy'
):
fuzzy
=
True
# Skip comments
if
l
[
0
]
==
'#'
:
continue
# Now we are in a msgid section, output previous section
if
l
.
startswith
(
'msgid'
):
if
section
==
STR
:
self
.
__add
(
msgid
,
msgstr
,
fuzzy
)
section
=
ID
l
=
l
[
5
:]
msgid
=
msgstr
=
''
# Now we are in a msgstr section
elif
l
.
startswith
(
'msgstr'
):
section
=
STR
l
=
l
[
6
:]
# Skip empty lines
if
not
l
.
strip
():
continue
# XXX: Does this always follow Python escape semantics?
l
=
eval
(
l
)
if
section
==
ID
:
msgid
+=
l
elif
section
==
STR
:
msgstr
+=
'%s
\
n
'
%
l
else
:
print
>>
sys
.
stderr
,
'Syntax error on %s:%d'
%
(
infile
,
lno
),
\
'before:'
print
>>
sys
.
stderr
,
l
sys
.
exit
(
1
)
# Add last entry
if
section
==
STR
:
self
.
__add
(
msgid
,
msgstr
,
fuzzy
)
def
evaluate
(
self
,
expression
):
try
:
return
POEngine
.
evaluate
(
self
,
expression
)
except
TALESError
:
pass
def
evaluatePathOrVar
(
self
,
expr
):
return
'who cares'
def
translate
(
self
,
msgid
,
domain
=
None
,
mapping
=
None
,
default
=
None
,
position
=
None
):
if
msgid
not
in
self
.
base
:
POEngine
.
translate
(
self
,
msgid
,
domain
,
mapping
,
default
,
position
)
return
'x'
def
main
():
try
:
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
'ho:u:'
,
[
'help'
,
'output='
,
'update='
])
except
getopt
.
error
,
msg
:
usage
(
1
,
msg
)
outfile
=
None
engine
=
None
update_mode
=
False
for
opt
,
arg
in
opts
:
if
opt
in
(
'-h'
,
'--help'
):
usage
(
0
)
elif
opt
in
(
'-o'
,
'--output'
):
outfile
=
arg
elif
opt
in
(
'-u'
,
'--update'
):
update_mode
=
True
if
outfile
is
None
:
outfile
=
arg
engine
=
UpdatePOEngine
(
filename
=
arg
)
if
not
args
:
print
'nothing to do'
return
# We don't care about the rendered output of the .pt file
class
Devnull
:
def
write
(
self
,
s
):
pass
# check if we've already instantiated an engine;
# if not, use the stupidest one available
if
not
engine
:
engine
=
POEngine
()
# process each file specified
for
filename
in
args
:
try
:
engine
.
file
=
filename
p
=
HTMLTALParser
()
p
.
parseFile
(
filename
)
program
,
macros
=
p
.
getCode
()
POTALInterpreter
(
program
,
macros
,
engine
,
stream
=
Devnull
(),
metal
=
False
)()
except
:
# Hee hee, I love bare excepts!
print
'There was an error processing'
,
filename
traceback
.
print_exc
()
# Now output the keys in the engine. Write them to a file if --output or
# --update was specified; otherwise use standard out.
if
(
outfile
is
None
):
outfile
=
sys
.
stdout
else
:
outfile
=
file
(
outfile
,
update_mode
and
"a"
or
"w"
)
catalog
=
{}
for
domain
in
engine
.
catalog
.
keys
():
catalog
.
update
(
engine
.
catalog
[
domain
])
messages
=
catalog
.
copy
()
try
:
messages
.
update
(
engine
.
base
)
except
AttributeError
:
pass
if
''
not
in
messages
:
print
>>
outfile
,
pot_header
%
{
'time'
:
time
.
ctime
(),
'version'
:
__version__
}
msgids
=
catalog
.
keys
()
# XXX: You should not sort by msgid, but by filename and position. (SR)
msgids
.
sort
()
for
msgid
in
msgids
:
positions
=
catalog
[
msgid
]
for
filename
,
position
in
positions
:
outfile
.
write
(
'#: %s:%s
\
n
'
%
(
filename
,
position
[
0
]))
outfile
.
write
(
'msgid "%s"
\
n
'
%
msgid
)
outfile
.
write
(
'msgstr ""
\
n
'
)
outfile
.
write
(
'
\
n
'
)
if
__name__
==
'__main__'
:
main
()
lib/python/TAL/tests/__init__.py
deleted
100644 → 0
View file @
1c0af142
"""Empty file to make this directory a Python package."""
lib/python/TAL/tests/input/test01.html
deleted
100644 → 0
View file @
1c0af142
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"DTD/xhtml1-transitional.dtd">
<html>
<head>
dadada
</head>
<body
xmlns:z=
"http://xml.zope.org/namespaces/tal"
z:define=
"foo python:1"
>
<h1
z:condition=
"python:0"
>
This title is not displayed
</h1>
<h1
z:condition=
"python:1"
z:content=
"str:This
Is
The
Replaced
Title"
>
Title
</h1>
<!-- test entity references -->
&HarryPotter;
<!-- examples adapted from TemplateAttributeLanguageSyntax -->
<span
z:content=
"str:here/id"
/>
<p
z:define=
"x str:template/title; global five python:2+3;"
z:content=
"text var:five"
/>
<p
z:repeat=
"car python:['honda', 'subaru', 'acura']"
>
<span
z:replace=
"var:car"
/>
</p>
<p
xml:foo=
"bar"
>
foo bar
</p>
<!-- more examples -->
<ul>
<span
z:repeat=
"car python:['honda', 'subaru', 'acura']"
>
<li
z:content=
"var:car"
>
Car Name
</li>
</span>
</ul>
<!-- test attribute expansion -->
<a
href=
"foo"
z:attributes=
"href python:'http://python.org' "
>
python
</a>
<a
z:attributes=
"href python:'http://python.org' "
>
python
</a>
<!-- test insert/replace structure -->
<span
z:content=
"structure python:None"
/>
<span
z:replace=
"structure python:None"
/>
<span
z:define=
"global x str:<h3>Header Level 3</h3>"
/>
<span
z:define=
"global x python:'&' + 'nbsp;;' + x"
/>
<span
z:replace=
"structure x"
/>
<span
z:content=
"structure x"
/>
</body>
</html>
lib/python/TAL/tests/input/test01.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"DTD/xhtml1-transitional.dtd">
<html>
<head>
dadada
</head>
<body
xmlns:z=
"http://xml.zope.org/namespaces/tal"
z:define=
"foo python:1"
>
<h1
z:condition=
"python:0"
>
This title is not displayed
</h1>
<h1
z:condition=
"python:1"
z:content=
"str:This
Is
The
Replaced
Title"
>
Title
</h1>
<!-- test entity references -->
&HarryPotter;
<!-- examples adapted from TemplateAttributeLanguageSyntax -->
<span
z:content=
"str:here/id"
/>
<p
z:define=
"x str:template/title; global five python:2+3;"
z:content=
"text var:five"
/>
<p
z:repeat=
"car python:['honda', 'subaru', 'acura']"
>
<span
z:replace=
"var:car"
/>
</p>
<p
xml:foo=
"bar"
>
foo bar
</p>
<!-- more examples -->
<ul>
<span
z:repeat=
"car python:['honda', 'subaru', 'acura']"
>
<li
z:content=
"var:car"
>
Car Name
</li>
</span>
</ul>
<!-- test attribute expansion -->
<a
href=
"foo"
z:attributes=
"href python:'http://python.org' "
>
python
</a>
<a
z:attributes=
"href python:'http://python.org' "
>
python
</a>
<!-- test insert/replace structure -->
<span
z:content=
"structure python:None"
/>
<span
z:replace=
"structure python:None"
/>
<span
z:define=
"global x str:<h3>Header Level 3</h3>"
/>
<span
z:define=
"global x python:'&' + 'nbsp;;' + x"
/>
<span
z:replace=
"structure x"
/>
<span
z:content=
"structure x"
/>
</body>
</html>
lib/python/TAL/tests/input/test02.html
deleted
100644 → 0
View file @
1c0af142
<biztalk
_1
xmlns=
"urn:schemas-biztalk-org:biztalk:biztalk_1"
>
<foo:header
xmlns:foo=
"whomping-willow"
plain=
"guido"
quote=
'"'
apostrophe=
"'"
both=
""'"
lt=
"<"
gt=
">"
amp=
"&"
foo=
""
>
<manifest>
<document>
<name>
sample1
</name>
<description>
a simple invoice
</description>
</document>
</manifest>
</foo:header>
<body>
<!-- sample1.xml is an example of a simple invoice for a small restaurant supplies order -->
<Invoice
xmlns=
"urn:http://schemas.biztalk.org/united_rest_com/yw7sg15x.xml"
>
<Header>
<InvoiceNumber>
01786
</InvoiceNumber>
<InvoiceDate>
2000-03-17
</InvoiceDate>
<!-- March 17th, 2000 -->
<OrderNo>
55377
</OrderNo>
<OrderDate>
2000-03-15
</OrderDate>
<!-- March 15th, 2000 -->
<CustomerPO>
GJ03405
</CustomerPO>
<ShipMethod>
DAVE 1
</ShipMethod>
<ShipDate>
2000-03-17
</ShipDate>
<!-- March 17th, 2000 -->
<CustomerID>
K5211(34)
</CustomerID>
<SalesPersonCode>
23
</SalesPersonCode>
<TaxID>
23
</TaxID>
</Header>
<InvoiceTo>
<Name>
SHIPWRIGHT RESTAURANTS LIMITED
</Name>
<AddressLine>
125 NORTH SERVICE ROAD W
</AddressLine>
<AddressLine>
WESTLAKE ACCESS
</AddressLine>
<City>
NORTH BAY
</City>
<PostCode>
L8B1O5
</PostCode>
<State>
ONTARIO
</State>
<Country>
CANADA
</Country>
</InvoiceTo>
<ShipTo>
<Name/>
<AddressLine>
ATTN: PAULINE DEGRASSI
</AddressLine>
<City/>
<PostCode/>
<State/>
<Country/>
</ShipTo>
<DetailLines>
<DetailLine>
<QuantityShipped>
1
</QuantityShipped>
<UnitOfMeasure>
CS
</UnitOfMeasure>
<PartNumber>
DM 5309
</PartNumber>
<PartDescription>
#1013 12 OZ.MUNICH STEIN
</PartDescription>
<UnitPrice>
37.72
</UnitPrice>
<LineTotal>
37.72
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
6
</QuantityShipped>
<UnitOfMeasure>
DZ
</UnitOfMeasure>
<PartNumber>
ON 6420
</PartNumber>
<PartDescription>
PROVINCIAL DINNER FORK
</PartDescription>
<UnitPrice>
17.98
</UnitPrice>
<LineTotal>
107.88
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
72
</QuantityShipped>
<UnitOfMeasure>
EA
</UnitOfMeasure>
<PartNumber>
JR20643
</PartNumber>
<PartDescription>
PLASTIC HANDLED STEAK KNIFE
</PartDescription>
<UnitPrice>
.81
</UnitPrice>
<LineTotal>
58.32
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
6
</QuantityShipped>
<UnitOfMeasure>
DZ
</UnitOfMeasure>
<PartNumber>
ON 6410
</PartNumber>
<PartDescription>
PROVINCIAL TEASPOONS
</PartDescription>
<UnitPrice>
12.16
</UnitPrice>
<LineTotal>
72.96
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
0
</QuantityShipped>
<UnitOfMeasure>
DZ
</UnitOfMeasure>
<PartNumber>
ON 6411
</PartNumber>
<PartDescription>
PROVINCIAL RD BOWL SPOON
</PartDescription>
<QuantityBackOrdered>
6
</QuantityBackOrdered>
<UnitPrice>
17.98
</UnitPrice>
<LineTotal>
0.00
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
1
</QuantityShipped>
<UnitOfMeasure>
EA
</UnitOfMeasure>
<PartNumber>
DO 3218
</PartNumber>
<PartDescription>
34 OZ DUAL DIAL SCALE AM3218
</PartDescription>
<UnitPrice>
70.00
</UnitPrice>
<DiscountPercentage>
5.0
</DiscountPercentage>
<LineTotal>
66.50
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
1
</QuantityShipped>
<UnitOfMeasure>
CS
</UnitOfMeasure>
<PartNumber>
DM 195
</PartNumber>
<PartDescription>
20 OZ.BEER PUB GLASS
</PartDescription>
<UnitPrice>
55.90
</UnitPrice>
<LineTotal>
55.90
</LineTotal>
</DetailLine>
</DetailLines>
<Totals>
<SubTotal>
399.28
</SubTotal>
<DiscountTotal>
3.50
</DiscountTotal>
<FreightTotal>
23.75
</FreightTotal>
<GSTTotal>
29.61
</GSTTotal>
<ProvTaxTotal>
33.84
</ProvTaxTotal>
<OtherTotal>
33.84
</OtherTotal>
<InvoiceTotal>
486.48
</InvoiceTotal>
</Totals>
</Invoice>
</body>
</biztalk
_1
>
lib/python/TAL/tests/input/test02.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<biztalk_1
xmlns=
"urn:schemas-biztalk-org:biztalk:biztalk_1"
>
<foo:header
xmlns:foo=
"whomping-willow"
plain=
"guido"
quote=
'"'
apostrophe=
"'"
both=
""'"
lt=
"<"
gt=
">"
amp=
"&"
foo=
""
>
<manifest>
<document>
<name>
sample1
</name>
<description>
a simple invoice
</description>
</document>
</manifest>
</foo:header>
<body>
<!-- sample1.xml is an example of a simple invoice for a small restaurant supplies order -->
<Invoice
xmlns=
"urn:http://schemas.biztalk.org/united_rest_com/yw7sg15x.xml"
>
<Header>
<InvoiceNumber>
01786
</InvoiceNumber>
<InvoiceDate>
2000-03-17
</InvoiceDate>
<!-- March 17th, 2000 -->
<OrderNo>
55377
</OrderNo>
<OrderDate>
2000-03-15
</OrderDate>
<!-- March 15th, 2000 -->
<CustomerPO>
GJ03405
</CustomerPO>
<ShipMethod>
DAVE 1
</ShipMethod>
<ShipDate>
2000-03-17
</ShipDate>
<!-- March 17th, 2000 -->
<CustomerID>
K5211(34)
</CustomerID>
<SalesPersonCode>
23
</SalesPersonCode>
<TaxID>
23
</TaxID>
</Header>
<InvoiceTo>
<Name>
SHIPWRIGHT RESTAURANTS LIMITED
</Name>
<AddressLine>
125 NORTH SERVICE ROAD W
</AddressLine>
<AddressLine>
WESTLAKE ACCESS
</AddressLine>
<City>
NORTH BAY
</City>
<PostCode>
L8B1O5
</PostCode>
<State>
ONTARIO
</State>
<Country>
CANADA
</Country>
</InvoiceTo>
<ShipTo>
<Name/>
<AddressLine>
ATTN: PAULINE DEGRASSI
</AddressLine>
<City/>
<PostCode/>
<State/>
<Country/>
</ShipTo>
<DetailLines>
<DetailLine>
<QuantityShipped>
1
</QuantityShipped>
<UnitOfMeasure>
CS
</UnitOfMeasure>
<PartNumber>
DM 5309
</PartNumber>
<PartDescription>
#1013 12 OZ.MUNICH STEIN
</PartDescription>
<UnitPrice>
37.72
</UnitPrice>
<LineTotal>
37.72
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
6
</QuantityShipped>
<UnitOfMeasure>
DZ
</UnitOfMeasure>
<PartNumber>
ON 6420
</PartNumber>
<PartDescription>
PROVINCIAL DINNER FORK
</PartDescription>
<UnitPrice>
17.98
</UnitPrice>
<LineTotal>
107.88
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
72
</QuantityShipped>
<UnitOfMeasure>
EA
</UnitOfMeasure>
<PartNumber>
JR20643
</PartNumber>
<PartDescription>
PLASTIC HANDLED STEAK KNIFE
</PartDescription>
<UnitPrice>
.81
</UnitPrice>
<LineTotal>
58.32
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
6
</QuantityShipped>
<UnitOfMeasure>
DZ
</UnitOfMeasure>
<PartNumber>
ON 6410
</PartNumber>
<PartDescription>
PROVINCIAL TEASPOONS
</PartDescription>
<UnitPrice>
12.16
</UnitPrice>
<LineTotal>
72.96
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
0
</QuantityShipped>
<UnitOfMeasure>
DZ
</UnitOfMeasure>
<PartNumber>
ON 6411
</PartNumber>
<PartDescription>
PROVINCIAL RD BOWL SPOON
</PartDescription>
<QuantityBackOrdered>
6
</QuantityBackOrdered>
<UnitPrice>
17.98
</UnitPrice>
<LineTotal>
0.00
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
1
</QuantityShipped>
<UnitOfMeasure>
EA
</UnitOfMeasure>
<PartNumber>
DO 3218
</PartNumber>
<PartDescription>
34 OZ DUAL DIAL SCALE AM3218
</PartDescription>
<UnitPrice>
70.00
</UnitPrice>
<DiscountPercentage>
5.0
</DiscountPercentage>
<LineTotal>
66.50
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
1
</QuantityShipped>
<UnitOfMeasure>
CS
</UnitOfMeasure>
<PartNumber>
DM 195
</PartNumber>
<PartDescription>
20 OZ.BEER PUB GLASS
</PartDescription>
<UnitPrice>
55.90
</UnitPrice>
<LineTotal>
55.90
</LineTotal>
</DetailLine>
</DetailLines>
<Totals>
<SubTotal>
399.28
</SubTotal>
<DiscountTotal>
3.50
</DiscountTotal>
<FreightTotal>
23.75
</FreightTotal>
<GSTTotal>
29.61
</GSTTotal>
<ProvTaxTotal>
33.84
</ProvTaxTotal>
<OtherTotal>
33.84
</OtherTotal>
<InvoiceTotal>
486.48
</InvoiceTotal>
</Totals>
</Invoice>
</body>
</biztalk_1>
lib/python/TAL/tests/input/test03.html
deleted
100644 → 0
View file @
1c0af142
<p
xmlns:z=
"http://xml.zope.org/namespaces/tal"
>
<span
z:define=
"local x str:hello brave new world"
>
<span
z:content=
"text local:x"
>
outer variable x, first appearance
</span>
<span
z:define=
"local x str:goodbye cruel world"
>
<span
z:content=
"text local:x"
>
inner variable x
</span>
</span>
<span
z:content=
"text local:x"
>
outer variable x, second appearance
</span>
</span>
</p>
lib/python/TAL/tests/input/test03.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<p
xmlns:z=
"http://xml.zope.org/namespaces/tal"
>
<span
z:define=
"local x str:hello brave new world"
>
<span
z:content=
"text local:x"
>
outer variable x, first appearance
</span>
<span
z:define=
"local x str:goodbye cruel world"
>
<span
z:content=
"text local:x"
>
inner variable x
</span>
</span>
<span
z:content=
"text local:x"
>
outer variable x, second appearance
</span>
</span>
</p>
lib/python/TAL/tests/input/test04.html
deleted
100644 → 0
View file @
1c0af142
<html>
<body
xmlns:m=
"http://xml.zope.org/namespaces/metal"
xmlns:z=
"http://xml.zope.org/namespaces/tal"
m:define-macro=
"body"
z:define=
"global count python:0"
>
<ul
m:define-macro=
"whoops"
>
<li
z:repeat=
"item python:range(count)"
>
<span
z:replace=
"item"
>
1
</span>
<span
z:replace=
"global:message"
/>
</li>
</ul>
<span
z:define=
"global count python:2; global message str:hello world"
/>
<p
m:use-macro=
"whoops"
>
use-macro
<span
m:fill-slot=
"whoops"
>
fill-slot
</span>
</p>
<span
z:define=
"global message str:goodbye cruel world"
/>
<p
m:use-macro=
"whoops"
>
use-macro
</p>
<p
m:define-slot=
"whoops"
>
define-slot
</p>
</body>
</html>
lib/python/TAL/tests/input/test04.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<html>
<body
xmlns:m=
"http://xml.zope.org/namespaces/metal"
xmlns:z=
"http://xml.zope.org/namespaces/tal"
m:define-macro=
"body"
z:define=
"global count python:0"
>
<ul
m:define-macro=
"whoops"
>
<li
z:repeat=
"item python:range(count)"
>
<span
z:replace=
"item"
>
1
</span>
<span
z:replace=
"global:message"
/>
</li>
</ul>
<span
z:define=
"global count python:2; global message str:hello world"
/>
<p
m:use-macro=
"whoops"
>
use-macro
<span
m:fill-slot=
"whoops"
>
fill-slot
</span>
</p>
<span
z:define=
"global message str:goodbye cruel world"
/>
<p
m:use-macro=
"whoops"
>
use-macro
</p>
<p
m:define-slot=
"whoops"
>
define-slot
</p>
</body>
</html>
lib/python/TAL/tests/input/test05.html
deleted
100644 → 0
View file @
1c0af142
<html>
<body
xmlns:m=
"http://xml.zope.org/namespaces/metal"
m:define-macro=
"body"
>
<h1>
This is the body of test5
</h1>
</body>
</html>
lib/python/TAL/tests/input/test05.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<html>
<body
xmlns:m=
"http://xml.zope.org/namespaces/metal"
m:define-macro=
"body"
>
<h1>
This is the body of test5
</h1>
</body>
</html>
lib/python/TAL/tests/input/test06.html
deleted
100644 → 0
View file @
1c0af142
<html>
<body
xmlns:m=
"http://xml.zope.org/namespaces/metal"
m:use-macro=
"tests/input/test05.html/body"
>
dummy body in test6
</body>
</html>
lib/python/TAL/tests/input/test06.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<html>
<body
xmlns:m=
"http://xml.zope.org/namespaces/metal"
m:use-macro=
"tests/input/test05.xml/body"
>
dummy body in test6
</body>
</html>
lib/python/TAL/tests/input/test07.html
deleted
100644 → 0
View file @
1c0af142
<table
xmlns:m=
"http://xml.zope.org/namespaces/metal"
m:define-macro=
"myTable"
>
<!-- macro definition with slots -->
<tr>
<td>
Top Left
</td>
<td>
Top Right
</td>
</tr>
<tr>
<td>
Bottom left
</td>
<td><span
m:define-slot=
"bottomRight"
>
Bottom Right
</span></td>
</tr>
</table>
lib/python/TAL/tests/input/test07.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<table
xmlns:m=
"http://xml.zope.org/namespaces/metal"
m:define-macro=
"myTable"
>
<!-- macro definition with slots -->
<tr>
<td>
Top Left
</td>
<td>
Top Right
</td>
</tr>
<tr>
<td>
Bottom left
</td>
<td><span
m:define-slot=
"bottomRight"
>
Bottom Right
</span></td>
</tr>
</table>
lib/python/TAL/tests/input/test08.html
deleted
100644 → 0
View file @
1c0af142
<table
xmlns:m=
"http://xml.zope.org/namespaces/metal"
m:use-macro=
"tests/input/test07.html/myTable"
>
<!-- macro use with slots -->
<tr>
<td>
<span
m:fill-slot=
"bottomRight"
>
<h1>
Some headline
</h1>
<p>
This is the real contents of the bottom right slot.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
</span>
</td>
</tr>
</table>
lib/python/TAL/tests/input/test08.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<table
xmlns:m=
"http://xml.zope.org/namespaces/metal"
m:use-macro=
"tests/input/test07.xml/myTable"
>
<!-- macro use with slots -->
<tr>
<td>
<span
m:fill-slot=
"bottomRight"
>
<h1>
Some headline
</h1>
<p>
This is the real contents of the bottom right slot.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
</span>
</td>
</tr>
</table>
lib/python/TAL/tests/input/test09.html
deleted
100644 → 0
View file @
1c0af142
<html>
<body>
<p>
Just a bunch of text.
<p>
more text...
<ul>
<li>
first item
<li>
second item
<ol>
<li>
second list, first item
<li>
second list, second item
<dl
compact
>
<dt>
term 1
<dt>
term 2
<dd>
definition
</dl>
</ol>
<li>
Now let's have a paragraph...
<p>
My Paragraph
</li>
<li>
And a table in a list item:
<table>
</table>
</ul>
</body>
</html>
lib/python/TAL/tests/input/test09.xml
deleted
100644 → 0
View file @
1c0af142
<html>
<body>
<p>
Just a bunch of text.
</p>
<p>
more text...
</p>
<ul>
<li>
first item
</li>
<li>
second item
<ol>
<li>
second list, first item
</li>
<li>
second list, second item
<dl
compact=
""
>
<dt>
term 1
</dt>
<dt>
term 2
</dt>
<dd>
definition
</dd>
</dl></li>
</ol></li>
<li>
Now let's have a paragraph...
<p>
My Paragraph
</p>
</li>
<li>
And a table in a list item:
<table>
</table></li>
</ul>
</body>
</html>
lib/python/TAL/tests/input/test10.html
deleted
100644 → 0
View file @
1c0af142
<html><body>
<table
xmlns:m=
"http://xml.zope.org/namespaces/metal"
m:use-macro=
"tests/input/test07.html/myTable"
>
<!-- macro use with slots -->
<tr>
<td>
<span
m:fill-slot=
"bottomRight"
>
<h1>
Some headline
</h1>
<p>
This is the real contents of the bottom right slot.
</p>
<hr>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<br><br>
</span>
</td>
</tr>
</table>
</body></html>
lib/python/TAL/tests/input/test11.html
deleted
100644 → 0
View file @
1c0af142
<html
xmlns:tal=
"http://xml.zope.org/namespaces/tal"
>
<p
tal:replace=
"structure string:<a>bar</a>"
tal:attributes=
"href string:http://www.python.org"
>
dummy text
</p>
<p
tal:define=
"x python:1"
tal:on-error=
"string:bad boy!"
>
<span
tal:define=
"x python:2"
>
<span
tal:define=
"x python:3"
>
<span
tal:content=
"python:1/0"
/>
</span>
</span>
</p>
<p
tal:on-error=
"string:x undefined"
>
<span
tal:content=
"x"
/>
</p>
</html>
lib/python/TAL/tests/input/test11.xml
deleted
100644 → 0
View file @
1c0af142
<html
xmlns:tal=
"http://xml.zope.org/namespaces/tal"
>
<p
tal:replace=
"structure string:<a>bar</a>"
tal:attributes=
"href string:http://www.python.org"
>
dummy text
</p>
<p
tal:define=
"x python:1"
tal:on-error=
"string:bad boy!"
>
<span
tal:define=
"x python:2"
>
<span
tal:define=
"x python:3"
>
<span
tal:content=
"python:1/0"
/>
</span>
</span>
</p>
<p
tal:on-error=
"string:x undefined"
>
<span
tal:content=
"x"
/>
</p>
</html>
lib/python/TAL/tests/input/test12.html
deleted
100644 → 0
View file @
1c0af142
<span
tal:define=
"global true python:1; global false python:0"
/>
<img
ismap
>
<img
ismap=
ismap
>
<img
ismap=
"ismap"
>
<img
ismap=
"foo"
>
<img
ismap
tal:attributes=
"ismap true"
>
<img
ismap
tal:attributes=
"ismap false"
>
<img
ismap
tal:attributes=
"ismap nothing"
>
<img
ismap
tal:attributes=
"ismap default"
>
<img
ismap=
"foo"
tal:attributes=
"ismap true"
>
<img
ismap=
"foo"
tal:attributes=
"ismap false"
>
<img
ismap=
"foo"
tal:attributes=
"ismap nothing"
>
<img
ismap=
"foo"
tal:attributes=
"ismap default"
>
<img
tal:attributes=
"ismap true"
>
<img
tal:attributes=
"ismap false"
>
<img
tal:attributes=
"ismap nothing"
>
<img
tal:attributes=
"ismap default"
>
<span
tal:define=
"global x string:x.gif"
/>
<img
src=
"foo"
>
<img
src=
"foo"
tal:attributes=
"src x"
>
<img
src=
"foo"
tal:attributes=
"src nothing"
>
<img
src=
"foo"
tal:attributes=
"src default"
>
<img
tal:attributes=
"src default"
>
lib/python/TAL/tests/input/test13.html
deleted
100644 → 0
View file @
1c0af142
Here's a stray greater than: >
<script>
<!--
no
comment
-->
<
notag
>
&
noentity
;
</script>
lib/python/TAL/tests/input/test14.html
deleted
100644 → 0
View file @
1c0af142
<table>
<tr>
<td
tal:repeat=
"x python:['car', 'bike', 'broomstick']"
tal:content=
"x"
>
</td>
</tr>
</table>
<p>
<span
tal:repeat=
"x python:['Harry', 'Ron', 'Hermione']"
tal:replace=
"x"
/>
</p>
lib/python/TAL/tests/input/test14.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<html
xmlns:tal=
"http://xml.zope.org/namespaces/tal"
>
<table>
<tr>
<td
tal:repeat=
"x python:['car', 'bike', 'broomstick']"
tal:content=
"x"
>
</td>
</tr>
</table>
<p>
<span
tal:repeat=
"x python:['Harry', 'Ron', 'Hermione']"
tal:replace=
"x"
/>
</p>
</html>
lib/python/TAL/tests/input/test15.html
deleted
100644 → 0
View file @
1c0af142
<span
metal:define-macro=
"INNER"
>
<span
metal:define-slot=
"INNERSLOT"
>
INNERSLOT
</span>
</span>
<xxx
metal:use-macro=
"INNER"
>
<xxx
metal:fill-slot=
"INNERSLOT"
>
inner-argument
</xxx>
</xxx>
<div
metal:define-macro=
"OUTER"
>
<div
metal:use-macro=
"INNER"
>
<xxx
metal:define-slot=
"OUTERSLOT"
metal:fill-slot=
"INNERSLOT"
>
OUTERSLOT
</xxx>
</div>
</div>
<div
metal:use-macro=
"OUTER"
>
<span>
<xxx>
<div
metal:fill-slot=
"OUTERSLOT"
>
outer-argument
</div>
</xxx>
</span>
</div>
<div
metal:use-macro=
"OUTER"
>
</div>
lib/python/TAL/tests/input/test16.html
deleted
100644 → 0
View file @
1c0af142
<a
href=
"valid/link.html"
tal:attributes=
"href python:'/base/' + attrs['href']"
>
blah, blah
</a>
<input
tal:attributes=
"value string:a "laser""
/>
lib/python/TAL/tests/input/test16.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0"?>
<body
xmlns:tal=
"http://xml.zope.org/namespaces/tal"
>
<ImG
href=
"foo"
Alt=
"bar"
tal:attributes=
"Href string:about:foo;alT string:baz"
/>
</body>
lib/python/TAL/tests/input/test17.html
deleted
100644 → 0
View file @
1c0af142
<tal:block
tal:content=
"string:Yes"
>
No
</tal:block>
<tal:block
content=
"string:Yes"
>
No
</tal:block>
<tal:block>
Yes
</tal:block>
<metal:block
tal:content=
"string:Yes"
>
No
</metal:block>
<metal:block>
Yes
</metal:block>
lib/python/TAL/tests/input/test17.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0"?>
<body
xmlns:z=
"http://xml.zope.org/namespaces/tal"
xmlns:z2=
"http://xml.zope.org/namespaces/metal"
>
<z:block
z:content=
"string:Yes"
>
No
</z:block>
<z:block
content=
"string:Yes"
>
No
</z:block>
<z:block>
Yes
</z:block>
<z2:block
z:content=
"string:Yes"
>
No
</z2:block>
<z2:block>
Yes
</z2:block>
</body>
lib/python/TAL/tests/input/test18.html
deleted
100644 → 0
View file @
1c0af142
<p
tal:omit-tag=
""
>
Content
</p>
<p
tal:omit-tag=
""
></p>
<img
tal:omit-tag=
""
>
<p
tal:omit-tag=
"string:Yes"
>
Content
</p>
<p
tal:omit-tag=
"string:Yes"
></p>
<img
tal:omit-tag=
"string:Yes"
>
<p
tal:omit-tag=
"nothing"
>
Content
</p>
<p
tal:omit-tag=
"nothing"
></p>
<img
tal:omit-tag=
"nothing"
>
<p
tal:define=
"txt string:Yes"
tal:omit-tag=
""
tal:content=
"txt"
>
No
</p>
<p
tal:define=
"txt string:Yes"
tal:omit-tag=
""
tal:replace=
"txt"
>
No
</p>
<p
tal:omit-tag=
""
tal:content=
"default"
>
Yes
</p>
<p
tal:omit-tag=
""
tal:replace=
"default"
>
Yes
</p>
lib/python/TAL/tests/input/test18.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0"?>
<body
xmlns:tal=
"http://xml.zope.org/namespaces/tal"
xmlns:metal=
"http://xml.zope.org/namespaces/metal"
>
<p
tal:omit-tag=
""
>
Content
</p>
<p
tal:omit-tag=
""
></p>
<img
tal:omit-tag=
""
/>
<p
tal:omit-tag=
"string:Yes"
>
Content
</p>
<p
tal:omit-tag=
"string:Yes"
></p>
<img
tal:omit-tag=
"string:Yes"
/>
<p
tal:omit-tag=
"nothing"
>
Content
</p>
<p
tal:omit-tag=
"nothing"
></p>
<img
tal:omit-tag=
"nothing"
/>
<p
tal:define=
"txt string:Yes"
tal:omit-tag=
""
tal:content=
"txt"
>
No
</p>
<p
tal:define=
"txt string:Yes"
tal:omit-tag=
""
tal:replace=
"txt"
>
No
</p>
<p
tal:omit-tag=
""
tal:content=
"default"
>
Yes
</p>
<p
tal:omit-tag=
""
tal:replace=
"default"
>
Yes
</p>
</body>
lib/python/TAL/tests/input/test19.html
deleted
100644 → 0
View file @
1c0af142
<input
name=
"Delete"
tal:attributes=
"name string:delete_button"
i18n:attributes=
"name"
>
<input
name=
"Delete"
i18n:attributes=
"name message-id"
>
<input
i18n:attributes=
" name message-id;
attr input-attr "
>
<input
name=
"Delete"
i18n:attributes=
"name message-id;"
>
<input
name=
"Delete"
title=
"titletext"
i18n:attributes=
"name; title"
>
<input
name=
"Delete"
tal:attributes=
"title string:titletaltext"
i18n:attributes=
"name; title"
>
<input
name=
"Delete"
tal:attributes=
"title string:titletaltext"
i18n:attributes=
"name message-id"
>
lib/python/TAL/tests/input/test20.html
deleted
100644 → 0
View file @
1c0af142
<input
name=
"Delete"
i18n:attributes=
"name"
>
lib/python/TAL/tests/input/test29.html
deleted
100644 → 0
View file @
1c0af142
<div
i18n:translate=
""
>
At the tone the time will be
<span
i18n:data=
"here/currentTime"
i18n:translate=
"timefmt"
i18n:name=
"time"
>
2:32 pm
</span>
... beep!
</div>
lib/python/TAL/tests/input/test34.html
deleted
100644 → 0
View file @
1c0af142
<span
i18n:translate=
"don't translate me"
>
stuff
<span
tal:replace=
"string:foobar"
i18n:name=
"longname"
/>
more stuff
</span>
<span
i18n:translate=
""
>
stuff
<span
tal:replace=
"string:foobar"
i18n:name=
"longname"
/>
more stuff
</span>
lib/python/TAL/tests/input/test36.html
deleted
100644 → 0
View file @
1c0af142
<span
tal:replace=
"string:<foo>"
/>
<span
i18n:translate=
""
>
<span
tal:replace=
"string:<foo>"
i18n:name=
"name1"
/>
<span
tal:replace=
"structure string:<bar />"
i18n:name=
"name2"
/>
<span
i18n:name=
"name3"
><b>
some
</b>
<i>
text
</i></span>
</span>
lib/python/TAL/tests/input/test_failed_attr_translation.html
deleted
100644 → 0
View file @
1c0af142
<input
value=
"don't translate me"
i18n:attributes=
"value"
>
lib/python/TAL/tests/input/test_metal1.html
deleted
100644 → 0
View file @
1c0af142
<span
metal:define-macro=
"OUTER"
>
AAA
<span
metal:define-macro=
"INNER"
>
INNER
</span>
BBB
</span>
<xxx
metal:use-macro=
"OUTER"
>
</xxx>
<xxx
metal:use-macro=
"INNER"
>
</xxx>
<span
metal:define-macro=
"OUTER2"
>
AAA
<xxx
metal:define-slot=
"OUTERSLOT"
>
<span
metal:define-macro=
"INNER2"
>
INNER
</span>
</xxx>
BBB
</span>
<xxx
metal:use-macro=
"OUTER2"
>
</xxx>
<xxx
metal:use-macro=
"INNER2"
>
</xxx>
<xxx
metal:use-macro=
"OUTER2"
>
<yyy
metal:fill-slot=
"OUTERSLOT"
>
OUTERSLOT
</yyy>
</xxx>
<span
metal:define-macro=
"OUTER3"
>
AAA
<xxx
metal:define-slot=
"OUTERSLOT"
>
<span
metal:define-macro=
"INNER3"
>
INNER
<xxx
metal:define-slot=
"INNERSLOT"
>
INNERSLOT
</xxx>
</span>
</xxx>
BBB
</span>
<xxx
metal:use-macro=
"OUTER3"
>
</xxx>
<xxx
metal:use-macro=
"OUTER3"
>
<yyy
metal:fill-slot=
"OUTERSLOT"
>
OUTERSLOT
</yyy>
</xxx>
<xxx
metal:use-macro=
"INNER3"
>
</xxx>
<xxx
metal:use-macro=
"INNER3"
>
<yyy
metal:fill-slot=
"INNERSLOT"
>
INNERSLOT
</yyy>
</xxx>
<xxx
metal:use-macro=
"INNER3"
>
<yyy
metal:fill-slot=
"INNERSLOT"
>
<zzz
metal:define-macro=
"INSLOT"
>
INSLOT
</zzz>
</yyy>
</xxx>
<xxx
metal:use-macro=
"INSLOT"
></xxx>
lib/python/TAL/tests/input/test_metal2.html
deleted
100644 → 0
View file @
1c0af142
<div
metal:define-macro=
"OUTER"
>
OUTER
<span
metal:define-macro=
"INNER"
>
INNER
</span>
OUTER
</div>
<div
metal:use-macro=
"OUTER"
/>
lib/python/TAL/tests/input/test_metal3.html
deleted
100644 → 0
View file @
1c0af142
<span
tal:attributes=
"class string:foo"
>
Should not get attr in metal
</span>
lib/python/TAL/tests/input/test_metal4.html
deleted
100755 → 0
View file @
1c0af142
<!-- the outer element *must* be tal:something or metal:something -->
<metal:block
define-macro=
"page"
i18n:domain=
"zope"
>
<title
metal:define-slot=
"title"
>
Z3 UI
</title>
</metal:block>
lib/python/TAL/tests/input/test_metal5.html
deleted
100755 → 0
View file @
1c0af142
<!-- the outer element *must* include tal:omit-tag='' -->
<x
tal:omit-tag=
""
metal:define-macro=
"page"
i18n:domain=
"zope"
>
<title
metal:define-slot=
"title"
>
Z3 UI
</title>
</x>
lib/python/TAL/tests/input/test_metal6.html
deleted
100755 → 0
View file @
1c0af142
<metal:block
define-macro=
"page"
>
<html
i18:domain=
"zope"
>
<metal:block
define-slot=
"title"
>
Z3 UI
</metal:block>
</html>
</metal:block>
lib/python/TAL/tests/input/test_metal7.html
deleted
100755 → 0
View file @
1c0af142
<html
metal:define-macro=
"page"
i18n:domain=
"zope"
>
<x
metal:define-slot=
"title"
/>
</html>
<html
metal:use-macro=
"page"
/>
\ No newline at end of file
lib/python/TAL/tests/output/test01.html
deleted
100644 → 0
View file @
1c0af142
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"DTD/xhtml1-transitional.dtd">
<html>
<head>
dadada
</head>
<body>
<h1>
This
Is
The
Replaced
Title
</h1>
<!-- test entity references -->
&HarryPotter;
<!-- examples adapted from TemplateAttributeLanguageSyntax -->
<span>
here/id
</span>
<p>
5
</p>
<p>
honda
</p>
<p>
subaru
</p>
<p>
acura
</p>
<p
xml:foo=
"bar"
>
foo bar
</p>
<!-- more examples -->
<ul>
<span>
<li>
honda
</li>
</span>
<span>
<li>
subaru
</li>
</span>
<span>
<li>
acura
</li>
</span>
</ul>
<!-- test attribute expansion -->
<a
href=
"http://python.org"
>
python
</a>
<a
href=
"http://python.org"
>
python
</a>
<!-- test insert/replace structure -->
<span></span>
<span
/>
<span
/>
<h3>
Header Level 3
</h3>
<span>
<h3>
Header Level 3
</h3></span>
</body>
</html>
lib/python/TAL/tests/output/test01.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"DTD/xhtml1-transitional.dtd">
<html>
<head>
dadada
</head>
<body>
<h1>
This Is The Replaced Title
</h1>
<!-- test entity references -->
&HarryPotter;
<!-- examples adapted from TemplateAttributeLanguageSyntax -->
<span>
here/id
</span>
<p>
5
</p>
<p>
honda
</p>
<p>
subaru
</p>
<p>
acura
</p>
<p
xml:foo=
"bar"
>
foo bar
</p>
<!-- more examples -->
<ul>
<span>
<li>
honda
</li>
</span>
<span>
<li>
subaru
</li>
</span>
<span>
<li>
acura
</li>
</span>
</ul>
<!-- test attribute expansion -->
<a
href=
"http://python.org"
>
python
</a>
<a
href=
"http://python.org"
>
python
</a>
<!-- test insert/replace structure -->
<span></span>
<span/>
<span/>
<h3>
Header Level 3
</h3>
<span>
<h3>
Header Level 3
</h3></span>
</body>
</html>
lib/python/TAL/tests/output/test02.html
deleted
100644 → 0
View file @
1c0af142
<biztalk
_1
xmlns=
"urn:schemas-biztalk-org:biztalk:biztalk_1"
>
<foo:header
xmlns:foo=
"whomping-willow"
plain=
"guido"
quote=
"""
apostrophe=
"'"
both=
""'"
lt=
"<"
gt=
">"
amp=
"&"
foo=
""
>
<manifest>
<document>
<name>
sample1
</name>
<description>
a simple invoice
</description>
</document>
</manifest>
</foo:header>
<body>
<!-- sample1.xml is an example of a simple invoice for a small restaurant supplies order -->
<invoice
xmlns=
"urn:http://schemas.biztalk.org/united_rest_com/yw7sg15x.xml"
>
<header>
<invoicenumber>
01786
</invoicenumber>
<invoicedate>
2000-03-17
</invoicedate>
<!-- March 17th, 2000 -->
<orderno>
55377
</orderno>
<orderdate>
2000-03-15
</orderdate>
<!-- March 15th, 2000 -->
<customerpo>
GJ03405
</customerpo>
<shipmethod>
DAVE 1
</shipmethod>
<shipdate>
2000-03-17
</shipdate>
<!-- March 17th, 2000 -->
<customerid>
K5211(34)
</customerid>
<salespersoncode>
23
</salespersoncode>
<taxid>
23
</taxid>
</header>
<invoiceto>
<name>
SHIPWRIGHT RESTAURANTS LIMITED
</name>
<addressline>
125 NORTH SERVICE ROAD W
</addressline>
<addressline>
WESTLAKE ACCESS
</addressline>
<city>
NORTH BAY
</city>
<postcode>
L8B1O5
</postcode>
<state>
ONTARIO
</state>
<country>
CANADA
</country>
</invoiceto>
<shipto>
<name
/>
<addressline>
ATTN: PAULINE DEGRASSI
</addressline>
<city
/>
<postcode
/>
<state
/>
<country
/>
</shipto>
<detaillines>
<detailline>
<quantityshipped>
1
</quantityshipped>
<unitofmeasure>
CS
</unitofmeasure>
<partnumber>
DM 5309
</partnumber>
<partdescription>
#1013 12 OZ.MUNICH STEIN
</partdescription>
<unitprice>
37.72
</unitprice>
<linetotal>
37.72
</linetotal>
</detailline>
<detailline>
<quantityshipped>
6
</quantityshipped>
<unitofmeasure>
DZ
</unitofmeasure>
<partnumber>
ON 6420
</partnumber>
<partdescription>
PROVINCIAL DINNER FORK
</partdescription>
<unitprice>
17.98
</unitprice>
<linetotal>
107.88
</linetotal>
</detailline>
<detailline>
<quantityshipped>
72
</quantityshipped>
<unitofmeasure>
EA
</unitofmeasure>
<partnumber>
JR20643
</partnumber>
<partdescription>
PLASTIC HANDLED STEAK KNIFE
</partdescription>
<unitprice>
.81
</unitprice>
<linetotal>
58.32
</linetotal>
</detailline>
<detailline>
<quantityshipped>
6
</quantityshipped>
<unitofmeasure>
DZ
</unitofmeasure>
<partnumber>
ON 6410
</partnumber>
<partdescription>
PROVINCIAL TEASPOONS
</partdescription>
<unitprice>
12.16
</unitprice>
<linetotal>
72.96
</linetotal>
</detailline>
<detailline>
<quantityshipped>
0
</quantityshipped>
<unitofmeasure>
DZ
</unitofmeasure>
<partnumber>
ON 6411
</partnumber>
<partdescription>
PROVINCIAL RD BOWL SPOON
</partdescription>
<quantitybackordered>
6
</quantitybackordered>
<unitprice>
17.98
</unitprice>
<linetotal>
0.00
</linetotal>
</detailline>
<detailline>
<quantityshipped>
1
</quantityshipped>
<unitofmeasure>
EA
</unitofmeasure>
<partnumber>
DO 3218
</partnumber>
<partdescription>
34 OZ DUAL DIAL SCALE AM3218
</partdescription>
<unitprice>
70.00
</unitprice>
<discountpercentage>
5.0
</discountpercentage>
<linetotal>
66.50
</linetotal>
</detailline>
<detailline>
<quantityshipped>
1
</quantityshipped>
<unitofmeasure>
CS
</unitofmeasure>
<partnumber>
DM 195
</partnumber>
<partdescription>
20 OZ.BEER PUB GLASS
</partdescription>
<unitprice>
55.90
</unitprice>
<linetotal>
55.90
</linetotal>
</detailline>
</detaillines>
<totals>
<subtotal>
399.28
</subtotal>
<discounttotal>
3.50
</discounttotal>
<freighttotal>
23.75
</freighttotal>
<gsttotal>
29.61
</gsttotal>
<provtaxtotal>
33.84
</provtaxtotal>
<othertotal>
33.84
</othertotal>
<invoicetotal>
486.48
</invoicetotal>
</totals>
</invoice>
</body>
</biztalk
_1
>
lib/python/TAL/tests/output/test02.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<biztalk_1
xmlns=
"urn:schemas-biztalk-org:biztalk:biztalk_1"
>
<foo:header
xmlns:foo=
"whomping-willow"
plain=
"guido"
quote=
"""
apostrophe=
"'"
both=
""'"
lt=
"<"
gt=
">"
amp=
"&"
foo=
""
>
<manifest>
<document>
<name>
sample1
</name>
<description>
a simple invoice
</description>
</document>
</manifest>
</foo:header>
<body>
<!-- sample1.xml is an example of a simple invoice for a small restaurant supplies order -->
<Invoice
xmlns=
"urn:http://schemas.biztalk.org/united_rest_com/yw7sg15x.xml"
>
<Header>
<InvoiceNumber>
01786
</InvoiceNumber>
<InvoiceDate>
2000-03-17
</InvoiceDate>
<!-- March 17th, 2000 -->
<OrderNo>
55377
</OrderNo>
<OrderDate>
2000-03-15
</OrderDate>
<!-- March 15th, 2000 -->
<CustomerPO>
GJ03405
</CustomerPO>
<ShipMethod>
DAVE 1
</ShipMethod>
<ShipDate>
2000-03-17
</ShipDate>
<!-- March 17th, 2000 -->
<CustomerID>
K5211(34)
</CustomerID>
<SalesPersonCode>
23
</SalesPersonCode>
<TaxID>
23
</TaxID>
</Header>
<InvoiceTo>
<Name>
SHIPWRIGHT RESTAURANTS LIMITED
</Name>
<AddressLine>
125 NORTH SERVICE ROAD W
</AddressLine>
<AddressLine>
WESTLAKE ACCESS
</AddressLine>
<City>
NORTH BAY
</City>
<PostCode>
L8B1O5
</PostCode>
<State>
ONTARIO
</State>
<Country>
CANADA
</Country>
</InvoiceTo>
<ShipTo>
<Name/>
<AddressLine>
ATTN: PAULINE DEGRASSI
</AddressLine>
<City/>
<PostCode/>
<State/>
<Country/>
</ShipTo>
<DetailLines>
<DetailLine>
<QuantityShipped>
1
</QuantityShipped>
<UnitOfMeasure>
CS
</UnitOfMeasure>
<PartNumber>
DM 5309
</PartNumber>
<PartDescription>
#1013 12 OZ.MUNICH STEIN
</PartDescription>
<UnitPrice>
37.72
</UnitPrice>
<LineTotal>
37.72
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
6
</QuantityShipped>
<UnitOfMeasure>
DZ
</UnitOfMeasure>
<PartNumber>
ON 6420
</PartNumber>
<PartDescription>
PROVINCIAL DINNER FORK
</PartDescription>
<UnitPrice>
17.98
</UnitPrice>
<LineTotal>
107.88
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
72
</QuantityShipped>
<UnitOfMeasure>
EA
</UnitOfMeasure>
<PartNumber>
JR20643
</PartNumber>
<PartDescription>
PLASTIC HANDLED STEAK KNIFE
</PartDescription>
<UnitPrice>
.81
</UnitPrice>
<LineTotal>
58.32
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
6
</QuantityShipped>
<UnitOfMeasure>
DZ
</UnitOfMeasure>
<PartNumber>
ON 6410
</PartNumber>
<PartDescription>
PROVINCIAL TEASPOONS
</PartDescription>
<UnitPrice>
12.16
</UnitPrice>
<LineTotal>
72.96
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
0
</QuantityShipped>
<UnitOfMeasure>
DZ
</UnitOfMeasure>
<PartNumber>
ON 6411
</PartNumber>
<PartDescription>
PROVINCIAL RD BOWL SPOON
</PartDescription>
<QuantityBackOrdered>
6
</QuantityBackOrdered>
<UnitPrice>
17.98
</UnitPrice>
<LineTotal>
0.00
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
1
</QuantityShipped>
<UnitOfMeasure>
EA
</UnitOfMeasure>
<PartNumber>
DO 3218
</PartNumber>
<PartDescription>
34 OZ DUAL DIAL SCALE AM3218
</PartDescription>
<UnitPrice>
70.00
</UnitPrice>
<DiscountPercentage>
5.0
</DiscountPercentage>
<LineTotal>
66.50
</LineTotal>
</DetailLine>
<DetailLine>
<QuantityShipped>
1
</QuantityShipped>
<UnitOfMeasure>
CS
</UnitOfMeasure>
<PartNumber>
DM 195
</PartNumber>
<PartDescription>
20 OZ.BEER PUB GLASS
</PartDescription>
<UnitPrice>
55.90
</UnitPrice>
<LineTotal>
55.90
</LineTotal>
</DetailLine>
</DetailLines>
<Totals>
<SubTotal>
399.28
</SubTotal>
<DiscountTotal>
3.50
</DiscountTotal>
<FreightTotal>
23.75
</FreightTotal>
<GSTTotal>
29.61
</GSTTotal>
<ProvTaxTotal>
33.84
</ProvTaxTotal>
<OtherTotal>
33.84
</OtherTotal>
<InvoiceTotal>
486.48
</InvoiceTotal>
</Totals>
</Invoice>
</body>
</biztalk_1>
lib/python/TAL/tests/output/test03.html
deleted
100644 → 0
View file @
1c0af142
<p>
<span>
<span>
hello brave new world
</span>
<span>
<span>
goodbye cruel world
</span>
</span>
<span>
hello brave new world
</span>
</span>
</p>
lib/python/TAL/tests/output/test03.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<p>
<span>
<span>
hello brave new world
</span>
<span>
<span>
goodbye cruel world
</span>
</span>
<span>
hello brave new world
</span>
</span>
</p>
lib/python/TAL/tests/output/test04.html
deleted
100644 → 0
View file @
1c0af142
<html>
<body>
<ul>
</ul>
<span
/>
<ul>
<li>
0
hello world
</li>
<li>
1
hello world
</li>
</ul>
<span
/>
<ul>
<li>
0
goodbye cruel world
</li>
<li>
1
goodbye cruel world
</li>
</ul>
<p>
define-slot
</p>
</body>
</html>
lib/python/TAL/tests/output/test04.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<html>
<body>
<ul>
</ul>
<span/>
<ul>
<li>
0
hello world
</li>
<li>
1
hello world
</li>
</ul>
<span/>
<ul>
<li>
0
goodbye cruel world
</li>
<li>
1
goodbye cruel world
</li>
</ul>
<p>
define-slot
</p>
</body>
</html>
lib/python/TAL/tests/output/test05.html
deleted
100644 → 0
View file @
1c0af142
<html>
<body>
<h1>
This is the body of test5
</h1>
</body>
</html>
lib/python/TAL/tests/output/test05.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<html>
<body>
<h1>
This is the body of test5
</h1>
</body>
</html>
lib/python/TAL/tests/output/test06.html
deleted
100644 → 0
View file @
1c0af142
<html>
<body>
<h1>
This is the body of test5
</h1>
</body>
</html>
lib/python/TAL/tests/output/test06.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<html>
<body>
<h1>
This is the body of test5
</h1>
</body>
</html>
lib/python/TAL/tests/output/test07.html
deleted
100644 → 0
View file @
1c0af142
<table>
<!-- macro definition with slots -->
<tr>
<td>
Top Left
</td>
<td>
Top Right
</td>
</tr>
<tr>
<td>
Bottom left
</td>
<td><span>
Bottom Right
</span></td>
</tr>
</table>
lib/python/TAL/tests/output/test07.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<table>
<!-- macro definition with slots -->
<tr>
<td>
Top Left
</td>
<td>
Top Right
</td>
</tr>
<tr>
<td>
Bottom left
</td>
<td><span>
Bottom Right
</span></td>
</tr>
</table>
lib/python/TAL/tests/output/test08.html
deleted
100644 → 0
View file @
1c0af142
<table>
<!-- macro definition with slots -->
<tr>
<td>
Top Left
</td>
<td>
Top Right
</td>
</tr>
<tr>
<td>
Bottom left
</td>
<td><span>
<h1>
Some headline
</h1>
<p>
This is the real contents of the bottom right slot.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
</span></td>
</tr>
</table>
lib/python/TAL/tests/output/test08.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<table>
<!-- macro definition with slots -->
<tr>
<td>
Top Left
</td>
<td>
Top Right
</td>
</tr>
<tr>
<td>
Bottom left
</td>
<td><span>
<h1>
Some headline
</h1>
<p>
This is the real contents of the bottom right slot.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
</span></td>
</tr>
</table>
lib/python/TAL/tests/output/test09.html
deleted
100644 → 0
View file @
1c0af142
<html>
<body>
<p>
Just a bunch of text.
</p>
<p>
more text...
</p>
<ul>
<li>
first item
</li>
<li>
second item
<ol>
<li>
second list, first item
</li>
<li>
second list, second item
<dl
compact
>
<dt>
term 1
</dt>
<dt>
term 2
</dt>
<dd>
definition
</dd>
</dl></li>
</ol></li>
<li>
Now let's have a paragraph...
<p>
My Paragraph
</p>
</li>
<li>
And a table in a list item:
<table>
</table></li>
</ul>
</body>
</html>
lib/python/TAL/tests/output/test09.xml
deleted
100644 → 0
View file @
1c0af142
<html>
<body>
<p>
Just a bunch of text.
</p>
<p>
more text...
</p>
<ul>
<li>
first item
</li>
<li>
second item
<ol>
<li>
second list, first item
</li>
<li>
second list, second item
<dl
compact=
""
>
<dt>
term 1
</dt>
<dt>
term 2
</dt>
<dd>
definition
</dd>
</dl></li>
</ol></li>
<li>
Now let's have a paragraph...
<p>
My Paragraph
</p>
</li>
<li>
And a table in a list item:
<table>
</table></li>
</ul>
</body>
</html>
lib/python/TAL/tests/output/test10.html
deleted
100644 → 0
View file @
1c0af142
<html><body>
<table>
<!-- macro definition with slots -->
<tr>
<td>
Top Left
</td>
<td>
Top Right
</td>
</tr>
<tr>
<td>
Bottom left
</td>
<td><span>
<h1>
Some headline
</h1>
<p>
This is the real contents of the bottom right slot.
</p>
<hr>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<p>
It is supposed to contain a lot of text. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab.
Blabber, blabber, blah. Baah, baah, barb.
</p>
<br><br>
</span></td>
</tr>
</table>
</body></html>
lib/python/TAL/tests/output/test11.html
deleted
100644 → 0
View file @
1c0af142
<html>
<a
href=
"http://www.python.org"
>
bar
</a>
<p>
bad boy!
</p>
<p>
x undefined
</p>
</html>
lib/python/TAL/tests/output/test11.xml
deleted
100644 → 0
View file @
1c0af142
<html>
<a
href=
"http://www.python.org"
>
bar
</a>
<p>
bad boy!
</p>
<p>
x undefined
</p>
</html>
lib/python/TAL/tests/output/test12.html
deleted
100644 → 0
View file @
1c0af142
<span
/>
<img
ismap
>
<img
ismap=
"ismap"
>
<img
ismap=
"ismap"
>
<img
ismap=
"foo"
>
<img
ismap=
"ismap"
>
<img>
<img>
<img
ismap=
"ismap"
>
<img
ismap=
"ismap"
>
<img>
<img>
<img
ismap=
"foo"
>
<img
ismap=
"ismap"
>
<img>
<img>
<img>
<span
/>
<img
src=
"foo"
>
<img
src=
"x.gif"
>
<img>
<img
src=
"foo"
>
<img>
lib/python/TAL/tests/output/test13.html
deleted
100644 → 0
View file @
1c0af142
Here's a stray greater than: >
<script>
<!--
no
comment
-->
<
notag
>
&
noentity
;
</script>
lib/python/TAL/tests/output/test14.html
deleted
100644 → 0
View file @
1c0af142
<table>
<tr>
<td>
car
</td>
<td>
bike
</td>
<td>
broomstick
</td>
</tr>
</table>
<p>
Harry
Ron
Hermione
</p>
lib/python/TAL/tests/output/test14.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0" ?>
<html>
<table>
<tr>
<td>
car
</td>
<td>
bike
</td>
<td>
broomstick
</td>
</tr>
</table>
<p>
Harry
Ron
Hermione
</p>
</html>
lib/python/TAL/tests/output/test15.html
deleted
100644 → 0
View file @
1c0af142
<span>
<span>
INNERSLOT
</span>
</span>
<span>
<xxx>
inner-argument
</xxx>
</span>
<div>
<span>
<xxx>
OUTERSLOT
</xxx>
</span>
</div>
<div>
<span>
<div>
outer-argument
</div>
</span>
</div>
<div>
<span>
<xxx>
OUTERSLOT
</xxx>
</span>
</div>
lib/python/TAL/tests/output/test16.html
deleted
100644 → 0
View file @
1c0af142
<a
href=
"/base/valid/link.html"
>
blah, blah
</a>
<input
value=
"a "laser""
/>
lib/python/TAL/tests/output/test16.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0"?>
<body>
<ImG
href=
"foo"
Alt=
"bar"
alT=
"baz"
Href=
"about:foo"
/>
</body>
lib/python/TAL/tests/output/test17.html
deleted
100644 → 0
View file @
1c0af142
Yes
Yes
Yes
Yes
Yes
lib/python/TAL/tests/output/test17.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0"?>
<body>
Yes
Yes
Yes
Yes
Yes
</body>
lib/python/TAL/tests/output/test18.html
deleted
100644 → 0
View file @
1c0af142
Content
Content
<p>
Content
</p>
<p></p>
<img>
Yes
Yes
Yes
Yes
lib/python/TAL/tests/output/test18.xml
deleted
100644 → 0
View file @
1c0af142
<?xml version="1.0"?>
<body>
Content
Content
<p>
Content
</p>
<p/>
<img/>
Yes
Yes
Yes
Yes
</body>
lib/python/TAL/tests/output/test19.html
deleted
100644 → 0
View file @
1c0af142
<input
name=
"DELETE_BUTTON"
>
<input
name=
"MESSAGE-ID"
>
<input
name=
"MESSAGE-ID"
attr=
"INPUT-ATTR"
>
<input
name=
"MESSAGE-ID"
>
<input
name=
"DELETE"
title=
"TITLETEXT"
>
<input
name=
"DELETE"
title=
"TITLETALTEXT"
>
<input
name=
"MESSAGE-ID"
title=
"titletaltext"
>
lib/python/TAL/tests/output/test20.html
deleted
100644 → 0
View file @
1c0af142
<input
name=
"DELETE"
>
lib/python/TAL/tests/output/test29.html
deleted
100644 → 0
View file @
1c0af142
<div>
AT THE TONE THE TIME WILL BE 59 MINUTES AFTER 6 PM... BEEP!
</div>
lib/python/TAL/tests/output/test34.html
deleted
100644 → 0
View file @
1c0af142
<span>
stuff
foobar
more stuff
</span>
<span>
STUFF foobar MORE STUFF
</span>
lib/python/TAL/tests/output/test36.html
deleted
100644 → 0
View file @
1c0af142
<
foo
>
<span>
<
foo
>
<bar
/>
<b>
some
</b>
<i>
text
</i></span>
lib/python/TAL/tests/output/test_failed_attr_translation.html
deleted
100644 → 0
View file @
1c0af142
<input
value=
"don't translate me"
>
lib/python/TAL/tests/output/test_metal1.html
deleted
100644 → 0
View file @
1c0af142
<span
metal:define-macro=
"OUTER"
>
AAA
<span
metal:define-macro=
"INNER"
>
INNER
</span>
BBB
</span>
<span
metal:use-macro=
"OUTER"
>
AAA
<span>
INNER
</span>
BBB
</span>
<span
metal:use-macro=
"INNER"
>
INNER
</span>
<span
metal:define-macro=
"OUTER2"
>
AAA
<xxx
metal:define-slot=
"OUTERSLOT"
>
<span
metal:define-macro=
"INNER2"
>
INNER
</span>
</xxx>
BBB
</span>
<span
metal:use-macro=
"OUTER2"
>
AAA
<xxx
metal:fill-slot=
"OUTERSLOT"
>
<span>
INNER
</span>
</xxx>
BBB
</span>
<span
metal:use-macro=
"INNER2"
>
INNER
</span>
<span
metal:use-macro=
"OUTER2"
>
AAA
<yyy
metal:fill-slot=
"OUTERSLOT"
>
OUTERSLOT
</yyy>
BBB
</span>
<span
metal:define-macro=
"OUTER3"
>
AAA
<xxx
metal:define-slot=
"OUTERSLOT"
>
<span
metal:define-macro=
"INNER3"
>
INNER
<xxx
metal:define-slot=
"INNERSLOT"
>
INNERSLOT
</xxx>
</span>
</xxx>
BBB
</span>
<span
metal:use-macro=
"OUTER3"
>
AAA
<xxx
metal:fill-slot=
"OUTERSLOT"
>
<span>
INNER
<xxx>
INNERSLOT
</xxx>
</span>
</xxx>
BBB
</span>
<span
metal:use-macro=
"OUTER3"
>
AAA
<yyy
metal:fill-slot=
"OUTERSLOT"
>
OUTERSLOT
</yyy>
BBB
</span>
<span
metal:use-macro=
"INNER3"
>
INNER
<xxx
metal:fill-slot=
"INNERSLOT"
>
INNERSLOT
</xxx>
</span>
<span
metal:use-macro=
"INNER3"
>
INNER
<yyy
metal:fill-slot=
"INNERSLOT"
>
INNERSLOT
</yyy>
</span>
<span
metal:use-macro=
"INNER3"
>
INNER
<yyy
metal:fill-slot=
"INNERSLOT"
>
<zzz
metal:define-macro=
"INSLOT"
>
INSLOT
</zzz>
</yyy>
</span>
<zzz
metal:use-macro=
"INSLOT"
>
INSLOT
</zzz>
lib/python/TAL/tests/output/test_metal2.html
deleted
100644 → 0
View file @
1c0af142
<div
metal:define-macro=
"OUTER"
>
OUTER
<span
metal:define-macro=
"INNER"
>
INNER
</span>
OUTER
</div>
<div
metal:use-macro=
"OUTER"
>
OUTER
<span>
INNER
</span>
OUTER
</div>
lib/python/TAL/tests/output/test_metal3.html
deleted
100644 → 0
View file @
1c0af142
<span
tal:attributes=
"class string:foo"
>
Should not get attr in metal
</span>
lib/python/TAL/tests/output/test_metal4.html
deleted
100755 → 0
View file @
1c0af142
<!-- the outer element *must* be tal:something or metal:something -->
<metal:block
define-macro=
"page"
i18n:domain=
"zope"
>
<title
metal:define-slot=
"title"
>
Z3 UI
</title>
</metal:block>
lib/python/TAL/tests/output/test_metal5.html
deleted
100755 → 0
View file @
1c0af142
<!-- the outer element *must* include tal:omit-tag='' -->
<x
tal:omit-tag=
""
metal:define-macro=
"page"
i18n:domain=
"zope"
>
<title
metal:define-slot=
"title"
>
Z3 UI
</title>
</x>
lib/python/TAL/tests/output/test_metal6.html
deleted
100755 → 0
View file @
1c0af142
<metal:block
define-macro=
"page"
>
<html
i18:domain=
"zope"
>
<metal:block
define-slot=
"title"
>
Z3 UI
</metal:block>
</html>
</metal:block>
lib/python/TAL/tests/output/test_metal7.html
deleted
100755 → 0
View file @
1c0af142
<html
metal:define-macro=
"page"
i18n:domain=
"zope"
>
<x
metal:define-slot=
"title"
/>
</html>
<html
metal:use-macro=
"page"
i18n:domain=
"zope"
>
<x
metal:fill-slot=
"title"
/>
</html>
lib/python/TAL/tests/run.py
deleted
100755 → 0
View file @
1c0af142
#! /usr/bin/env python1.5
"""Run all tests."""
import
sys
import
utils
import
unittest
import
test_htmlparser
import
test_htmltalparser
import
test_talinterpreter
import
test_files
import
test_sourcepos
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
test_htmlparser
.
test_suite
())
suite
.
addTest
(
test_htmltalparser
.
test_suite
())
if
not
utils
.
skipxml
:
import
test_xmlparser
suite
.
addTest
(
test_xmlparser
.
test_suite
())
suite
.
addTest
(
test_talinterpreter
.
test_suite
())
suite
.
addTest
(
test_files
.
test_suite
())
suite
.
addTest
(
test_sourcepos
.
test_suite
())
return
suite
def
main
():
return
utils
.
run_suite
(
test_suite
())
if
__name__
==
"__main__"
:
errs
=
main
()
sys
.
exit
(
errs
and
1
or
0
)
lib/python/TAL/tests/test_files.py
deleted
100755 → 0
View file @
1c0af142
#! /usr/bin/env python1.5
"""Tests that run driver.py over input files comparing to output files."""
import
os
import
sys
import
glob
from
TAL.tests
import
utils
import
unittest
from
TAL
import
runtest
class
FileTestCase
(
unittest
.
TestCase
):
def
__init__
(
self
,
file
,
dir
):
self
.
__file
=
file
self
.
__dir
=
dir
unittest
.
TestCase
.
__init__
(
self
)
def
shortDescription
(
self
):
return
os
.
path
.
join
(
"..."
,
"TAL"
,
"tests"
,
"input"
,
os
.
path
.
basename
(
self
.
__file
))
def
runTest
(
self
):
basename
=
os
.
path
.
basename
(
self
.
__file
)
#sys.stdout.write(basename + " ")
sys
.
stdout
.
flush
()
if
basename
[:
10
]
==
'test_metal'
:
sys
.
argv
=
[
""
,
"-Q"
,
"-m"
,
self
.
__file
]
else
:
sys
.
argv
=
[
""
,
"-Q"
,
self
.
__file
]
pwd
=
os
.
getcwd
()
try
:
try
:
os
.
chdir
(
self
.
__dir
)
runtest
.
main
()
finally
:
os
.
chdir
(
pwd
)
except
SystemExit
,
what
:
if
what
.
code
:
self
.
fail
(
"output for %s didn't match"
%
self
.
__file
)
try
:
script
=
__file__
except
NameError
:
script
=
sys
.
argv
[
0
]
def
test_suite
():
suite
=
unittest
.
TestSuite
()
dir
=
os
.
path
.
dirname
(
script
)
dir
=
os
.
path
.
abspath
(
dir
)
parentdir
=
os
.
path
.
dirname
(
dir
)
prefix
=
os
.
path
.
join
(
dir
,
"input"
,
"test*."
)
if
utils
.
skipxml
:
xmlargs
=
[]
else
:
xmlargs
=
glob
.
glob
(
prefix
+
"xml"
)
xmlargs
.
sort
()
htmlargs
=
glob
.
glob
(
prefix
+
"html"
)
htmlargs
.
sort
()
args
=
xmlargs
+
htmlargs
if
not
args
:
sys
.
stderr
.
write
(
"Warning: no test input files found!!!
\
n
"
)
for
arg
in
args
:
case
=
FileTestCase
(
arg
,
parentdir
)
suite
.
addTest
(
case
)
return
suite
if
__name__
==
"__main__"
:
errs
=
utils
.
run_suite
(
test_suite
())
sys
.
exit
(
errs
and
1
or
0
)
lib/python/TAL/tests/test_htmltalparser.py
deleted
100755 → 0
View file @
1c0af142
#! /usr/bin/env python
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests for the HTMLTALParser code generator."""
import
pprint
import
sys
from
TAL.tests
import
utils
import
unittest
from
TAL
import
HTMLTALParser
from
TAL.TALDefs
import
TAL_VERSION
,
TALError
,
METALError
class
TestCaseBase
(
unittest
.
TestCase
):
prologue
=
""
epilogue
=
""
initial_program
=
[(
'version'
,
TAL_VERSION
),
(
'mode'
,
'html'
)]
final_program
=
[]
def
_merge
(
self
,
p1
,
p2
):
if
p1
and
p2
:
op1
,
args1
=
p1
[
-
1
]
op2
,
args2
=
p2
[
0
]
if
op1
.
startswith
(
'rawtext'
)
and
op2
.
startswith
(
'rawtext'
):
return
(
p1
[:
-
1
]
+
[
rawtext
(
args1
[
0
]
+
args2
[
0
])]
+
p2
[
1
:])
return
p1
+
p2
def
_run_check
(
self
,
source
,
program
,
macros
=
{}):
parser
=
HTMLTALParser
.
HTMLTALParser
()
parser
.
parseString
(
self
.
prologue
+
source
+
self
.
epilogue
)
got_program
,
got_macros
=
parser
.
getCode
()
program
=
self
.
_merge
(
self
.
initial_program
,
program
)
program
=
self
.
_merge
(
program
,
self
.
final_program
)
self
.
assert_
(
got_program
==
program
,
"Program:
\
n
"
+
pprint
.
pformat
(
got_program
)
+
"
\
n
Expected:
\
n
"
+
pprint
.
pformat
(
program
))
self
.
assert_
(
got_macros
==
macros
,
"Macros:
\
n
"
+
pprint
.
pformat
(
got_macros
)
+
"
\
n
Expected:
\
n
"
+
pprint
.
pformat
(
macros
))
def
_get_check
(
self
,
source
,
program
=
[],
macros
=
{}):
parser
=
HTMLTALParser
.
HTMLTALParser
()
parser
.
parseString
(
source
)
got_program
,
got_macros
=
parser
.
getCode
()
pprint
.
pprint
(
got_program
)
pprint
.
pprint
(
got_macros
)
def
_should_error
(
self
,
source
,
exc
=
TALError
):
def
parse
(
self
=
self
,
source
=
source
):
parser
=
HTMLTALParser
.
HTMLTALParser
()
parser
.
parseString
(
self
.
prologue
+
source
+
self
.
epilogue
)
self
.
assertRaises
(
exc
,
parse
)
def
rawtext
(
s
):
"""Compile raw text to the appropriate instruction."""
if
"
\
n
"
in
s
:
return
(
"rawtextColumn"
,
(
s
,
len
(
s
)
-
(
s
.
rfind
(
"
\
n
"
)
+
1
)))
else
:
return
(
"rawtextOffset"
,
(
s
,
len
(
s
)))
class
HTMLTALParserTestCases
(
TestCaseBase
):
def
check_code_simple_identity
(
self
):
self
.
_run_check
(
"""<html a='b' b="c" c=d><title>My Title</html>"""
,
[
rawtext
(
'<html a="b" b="c" c="d">'
'<title>My Title</title></html>'
),
])
def
check_code_implied_list_closings
(
self
):
self
.
_run_check
(
"""<ul><li><p><p><li></ul>"""
,
[
rawtext
(
'<ul><li><p></p><p></p></li><li></li></ul>'
),
])
self
.
_run_check
(
"""<dl><dt><dt><dd><dd><ol><li><li></ol></dl>"""
,
[
rawtext
(
'<dl><dt></dt><dt></dt><dd></dd>'
'<dd><ol><li></li><li></li></ol></dd></dl>'
),
])
def
check_code_implied_table_closings
(
self
):
self
.
_run_check
(
"""<p>text <table><tr><th>head
\
t
<tr><td>cell
\
t
"""
"""<table><tr><td>cell
\
n
\
t
\
n
<tr>"""
,
[
rawtext
(
'<p>text</p> <table><tr><th>head</th>'
'</tr>
\
t
<tr><td>cell
\
t
<table><tr><td>cell</td>'
'</tr>
\
n
\
t
\
n
<tr></tr></table></td></tr></table>'
),
])
self
.
_run_check
(
"""<table><tr><td>cell """
"""<table><tr><td>cell </table></table>"""
,
[
rawtext
(
'<table><tr><td>cell <table><tr><td>cell</td></tr>'
' </table></td></tr></table>'
),
])
def
check_code_bad_nesting
(
self
):
def
check
(
self
=
self
):
self
.
_run_check
(
"<a><b></a></b>"
,
[])
self
.
assertRaises
(
HTMLTALParser
.
NestingError
,
check
)
def
check_code_attr_syntax
(
self
):
output
=
[
rawtext
(
'<a b="v" c="v" d="v" e></a>'
),
]
self
.
_run_check
(
"""<a b='v' c="v" d=v e>"""
,
output
)
self
.
_run_check
(
"""<a b = 'v' c = "v" d = v e>"""
,
output
)
self
.
_run_check
(
"""<a
\
n
b
\
n
=
\
n
'v'
\
n
c
\
n
=
\
n
"v"
\
n
d
\
n
=
\
n
v
\
n
e>"""
,
output
)
self
.
_run_check
(
"""<a
\
t
b
\
t
=
\
t
'v'
\
t
c
\
t
=
\
t
"v"
\
t
d
\
t
=
\
t
v
\
t
e>"""
,
output
)
def
check_code_attr_values
(
self
):
self
.
_run_check
(
"""<a b='xxx
\
n
\
t
xxx' c="yyy
\
t
\
n
yyy" d='
\
t
xyz
\
n
'>"""
,
[
rawtext
(
'<a b="xxx
\
n
\
t
xxx" c="yyy
\
t
\
n
yyy" d="
\
t
xyz
\
n
"></a>'
)])
self
.
_run_check
(
"""<a b='' c="">"""
,
[
rawtext
(
'<a b="" c=""></a>'
),
])
def
check_code_attr_entity_replacement
(
self
):
# we expect entities *not* to be replaced by HTLMParser!
self
.
_run_check
(
"""<a b='&><"''>"""
,
[
rawtext
(
'<a b="&><"
\
'
"></a>'
),
])
self
.
_run_check
(
"""<a b='
\
"
'>"""
,
[
rawtext
(
'<a b="""></a>'
),
])
self
.
_run_check
(
"""<a b='&'>"""
,
[
rawtext
(
'<a b="&"></a>'
),
])
self
.
_run_check
(
"""<a b='<'>"""
,
[
rawtext
(
'<a b="<"></a>'
),
])
def
check_code_attr_funky_names
(
self
):
self
.
_run_check
(
"""<a a.b='v' c:d=v e-f=v>"""
,
[
rawtext
(
'<a a.b="v" c:d="v" e-f="v"></a>'
),
])
def
check_code_pcdata_entityref
(
self
):
self
.
_run_check
(
""" """
,
[
rawtext
(
' '
),
])
def
check_code_short_endtags
(
self
):
self
.
_run_check
(
"""<html><img/></html>"""
,
[
rawtext
(
'<html><img /></html>'
),
])
class
METALGeneratorTestCases
(
TestCaseBase
):
def
check_null
(
self
):
self
.
_run_check
(
""
,
[])
def
check_define_macro
(
self
):
macro
=
self
.
initial_program
+
[
(
'startTag'
,
(
'p'
,
[(
'metal:define-macro'
,
'M'
,
'metal'
)])),
rawtext
(
'booh</p>'
),
]
program
=
[
(
'setPosition'
,
(
1
,
0
)),
(
'defineMacro'
,
(
'M'
,
macro
)),
]
macros
=
{
'M'
:
macro
}
self
.
_run_check
(
'<p metal:define-macro="M">booh</p>'
,
program
,
macros
)
def
check_use_macro
(
self
):
self
.
_run_check
(
'<p metal:use-macro="M">booh</p>'
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'useMacro'
,
(
'M'
,
'$M$'
,
{},
[(
'startTag'
,
(
'p'
,
[(
'metal:use-macro'
,
'M'
,
'metal'
)])),
rawtext
(
'booh</p>'
)])),
])
def
check_define_slot
(
self
):
macro
=
self
.
initial_program
+
[
(
'startTag'
,
(
'p'
,
[(
'metal:define-macro'
,
'M'
,
'metal'
)])),
rawtext
(
'foo'
),
(
'setPosition'
,
(
1
,
29
)),
(
'defineSlot'
,
(
'S'
,
[(
'startTag'
,
(
'span'
,
[(
'metal:define-slot'
,
'S'
,
'metal'
)])),
rawtext
(
'spam</span>'
)])),
rawtext
(
'bar</p>'
),
]
program
=
[(
'setPosition'
,
(
1
,
0
)),
(
'defineMacro'
,
(
'M'
,
macro
))]
macros
=
{
'M'
:
macro
}
self
.
_run_check
(
'<p metal:define-macro="M">foo'
'<span metal:define-slot="S">spam</span>bar</p>'
,
program
,
macros
)
def
check_fill_slot
(
self
):
self
.
_run_check
(
'<p metal:use-macro="M">foo'
'<span metal:fill-slot="S">spam</span>bar</p>'
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'useMacro'
,
(
'M'
,
'$M$'
,
{
'S'
:
[(
'startTag'
,
(
'span'
,
[(
'metal:fill-slot'
,
'S'
,
'metal'
)])),
rawtext
(
'spam</span>'
)]},
[(
'startTag'
,
(
'p'
,
[(
'metal:use-macro'
,
'M'
,
'metal'
)])),
rawtext
(
'foo'
),
(
'setPosition'
,
(
1
,
26
)),
(
'fillSlot'
,
(
'S'
,
[(
'startTag'
,
(
'span'
,
[(
'metal:fill-slot'
,
'S'
,
'metal'
)])),
rawtext
(
'spam</span>'
)])),
rawtext
(
'bar</p>'
)])),
])
class
TALGeneratorTestCases
(
TestCaseBase
):
def
check_null
(
self
):
self
.
_run_check
(
""
,
[])
def
check_define_1
(
self
):
self
.
_run_check
(
"<p tal:define='xyzzy string:spam'></p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:define'
:
'xyzzy string:spam'
}),
(
'setLocal'
,
(
'xyzzy'
,
'$string:spam$'
)),
(
'startTag'
,
(
'p'
,
[(
'tal:define'
,
'xyzzy string:spam'
,
'tal'
)])),
(
'endScope'
,
()),
rawtext
(
'</p>'
),
])
def
check_define_2
(
self
):
self
.
_run_check
(
"<p tal:define='local xyzzy string:spam'></p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:define'
:
'local xyzzy string:spam'
}),
(
'setLocal'
,
(
'xyzzy'
,
'$string:spam$'
)),
(
'startTag'
,
(
'p'
,
[(
'tal:define'
,
'local xyzzy string:spam'
,
'tal'
)])),
(
'endScope'
,
()),
rawtext
(
'</p>'
),
])
def
check_define_3
(
self
):
self
.
_run_check
(
"<p tal:define='global xyzzy string:spam'></p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:define'
:
'global xyzzy string:spam'
}),
(
'setGlobal'
,
(
'xyzzy'
,
'$string:spam$'
)),
(
'startTag'
,
(
'p'
,
[(
'tal:define'
,
'global xyzzy string:spam'
,
'tal'
)])),
(
'endScope'
,
()),
rawtext
(
'</p>'
),
])
def
check_define_4
(
self
):
self
.
_run_check
(
"<p tal:define='x string:spam; y x'></p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:define'
:
'x string:spam; y x'
}),
(
'setLocal'
,
(
'x'
,
'$string:spam$'
)),
(
'setLocal'
,
(
'y'
,
'$x$'
)),
(
'startTag'
,
(
'p'
,
[(
'tal:define'
,
'x string:spam; y x'
,
'tal'
)])),
(
'endScope'
,
()),
rawtext
(
'</p>'
),
])
def
check_define_5
(
self
):
self
.
_run_check
(
"<p tal:define='x string:;;;;; y x'></p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:define'
:
'x string:;;;;; y x'
}),
(
'setLocal'
,
(
'x'
,
'$string:;;$'
)),
(
'setLocal'
,
(
'y'
,
'$x$'
)),
(
'startTag'
,
(
'p'
,
[(
'tal:define'
,
'x string:;;;;; y x'
,
'tal'
)])),
(
'endScope'
,
()),
rawtext
(
'</p>'
),
])
def
check_define_6
(
self
):
self
.
_run_check
(
"<p tal:define='x string:spam; global y x; local z y'></p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:define'
:
'x string:spam; global y x; local z y'
}),
(
'setLocal'
,
(
'x'
,
'$string:spam$'
)),
(
'setGlobal'
,
(
'y'
,
'$x$'
)),
(
'setLocal'
,
(
'z'
,
'$y$'
)),
(
'startTag'
,
(
'p'
,
[(
'tal:define'
,
'x string:spam; global y x; local z y'
,
'tal'
)])),
(
'endScope'
,
()),
rawtext
(
'</p>'
),
])
def
check_condition
(
self
):
self
.
_run_check
(
"<p><span tal:condition='python:1'><b>foo</b></span></p>"
,
[
rawtext
(
'<p>'
),
(
'setPosition'
,
(
1
,
3
)),
(
'beginScope'
,
{
'tal:condition'
:
'python:1'
}),
(
'condition'
,
(
'$python:1$'
,
[(
'startTag'
,
(
'span'
,
[(
'tal:condition'
,
'python:1'
,
'tal'
)])),
rawtext
(
'<b>foo</b></span>'
)])),
(
'endScope'
,
()),
rawtext
(
'</p>'
),
])
def
check_content_1
(
self
):
self
.
_run_check
(
"<p tal:content='string:foo'>bar</p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:content'
:
'string:foo'
}),
(
'startTag'
,
(
'p'
,
[(
'tal:content'
,
'string:foo'
,
'tal'
)])),
(
'insertText'
,
(
'$string:foo$'
,
[
rawtext
(
'bar'
)])),
(
'endScope'
,
()),
rawtext
(
'</p>'
),
])
def
check_content_2
(
self
):
self
.
_run_check
(
"<p tal:content='text string:foo'>bar</p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:content'
:
'text string:foo'
}),
(
'startTag'
,
(
'p'
,
[(
'tal:content'
,
'text string:foo'
,
'tal'
)])),
(
'insertText'
,
(
'$string:foo$'
,
[
rawtext
(
'bar'
)])),
(
'endScope'
,
()),
rawtext
(
'</p>'
),
])
def
check_content_3
(
self
):
self
.
_run_check
(
"<p tal:content='structure string:<br>'>bar</p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:content'
:
'structure string:<br>'
}),
(
'startTag'
,
(
'p'
,
[(
'tal:content'
,
'structure string:<br>'
,
'tal'
)])),
(
'insertStructure'
,
(
'$string:<br>$'
,
{},
[
rawtext
(
'bar'
)])),
(
'endScope'
,
()),
rawtext
(
'</p>'
),
])
def
check_replace_1
(
self
):
self
.
_run_check
(
"<p tal:replace='string:foo'>bar</p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:replace'
:
'string:foo'
}),
(
'insertText'
,
(
'$string:foo$'
,
[(
'startTag'
,
(
'p'
,
[(
'tal:replace'
,
'string:foo'
,
'tal'
)])),
rawtext
(
'bar</p>'
)])),
(
'endScope'
,
()),
])
def
check_replace_2
(
self
):
self
.
_run_check
(
"<p tal:replace='text string:foo'>bar</p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:replace'
:
'text string:foo'
}),
(
'insertText'
,
(
'$string:foo$'
,
[(
'startTag'
,
(
'p'
,
[(
'tal:replace'
,
'text string:foo'
,
'tal'
)])),
rawtext
(
'bar</p>'
)])),
(
'endScope'
,
()),
])
def
check_replace_3
(
self
):
self
.
_run_check
(
"<p tal:replace='structure string:<br>'>bar</p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:replace'
:
'structure string:<br>'
}),
(
'insertStructure'
,
(
'$string:<br>$'
,
{},
[(
'startTag'
,
(
'p'
,
[(
'tal:replace'
,
'structure string:<br>'
,
'tal'
)])),
rawtext
(
'bar</p>'
)])),
(
'endScope'
,
()),
])
def
check_repeat
(
self
):
self
.
_run_check
(
"<p tal:repeat='x python:(1,2,3)'>"
"<span tal:replace='x'>dummy</span></p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:repeat'
:
'x python:(1,2,3)'
}),
(
'loop'
,
(
'x'
,
'$python:(1,2,3)$'
,
[(
'startTag'
,
(
'p'
,
[(
'tal:repeat'
,
'x python:(1,2,3)'
,
'tal'
)])),
(
'setPosition'
,
(
1
,
33
)),
(
'beginScope'
,
{
'tal:replace'
:
'x'
}),
(
'insertText'
,
(
'$x$'
,
[(
'startTag'
,
(
'span'
,
[(
'tal:replace'
,
'x'
,
'tal'
)])),
rawtext
(
'dummy</span>'
)])),
(
'endScope'
,
()),
rawtext
(
'</p>'
)])),
(
'endScope'
,
()),
])
def
check_attributes_1
(
self
):
self
.
_run_check
(
"<a href='foo' name='bar' tal:attributes="
"'href string:http://www.zope.org; x string:y'>"
"link</a>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:attributes'
:
'href string:http://www.zope.org; x string:y'
,
'name'
:
'bar'
,
'href'
:
'foo'
}),
(
'startTag'
,
(
'a'
,
[(
'href'
,
'foo'
,
'replace'
,
'$string:http://www.zope.org$'
,
0
,
None
),
(
'name'
,
'name="bar"'
),
(
'tal:attributes'
,
'href string:http://www.zope.org; x string:y'
,
'tal'
),
(
'x'
,
None
,
'insert'
,
'$string:y$'
,
0
,
None
)])),
(
'endScope'
,
()),
rawtext
(
'link</a>'
),
])
def
check_attributes_2
(
self
):
self
.
_run_check
(
"<p tal:replace='structure string:<img>' "
"tal:attributes='src string:foo.png'>duh</p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:attributes'
:
'src string:foo.png'
,
'tal:replace'
:
'structure string:<img>'
}),
(
'insertStructure'
,
(
'$string:<img>$'
,
{
'src'
:
(
'$string:foo.png$'
,
0
,
None
)},
[(
'startTag'
,
(
'p'
,
[(
'tal:replace'
,
'structure string:<img>'
,
'tal'
),
(
'tal:attributes'
,
'src string:foo.png'
,
'tal'
)])),
rawtext
(
'duh</p>'
)])),
(
'endScope'
,
()),
])
def
check_on_error_1
(
self
):
self
.
_run_check
(
"<p tal:on-error='string:error' "
"tal:content='notHere'>okay</p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:content'
:
'notHere'
,
'tal:on-error'
:
'string:error'
}),
(
'onError'
,
([(
'startTag'
,
(
'p'
,
[(
'tal:on-error'
,
'string:error'
,
'tal'
),
(
'tal:content'
,
'notHere'
,
'tal'
)])),
(
'insertText'
,
(
'$notHere$'
,
[
rawtext
(
'okay'
)])),
rawtext
(
'</p>'
)],
[(
'startTag'
,
(
'p'
,
[(
'tal:on-error'
,
'string:error'
,
'tal'
),
(
'tal:content'
,
'notHere'
,
'tal'
)])),
(
'insertText'
,
(
'$string:error$'
,
[])),
rawtext
(
'</p>'
)])),
(
'endScope'
,
()),
])
def
check_on_error_2
(
self
):
self
.
_run_check
(
"<p tal:on-error='string:error' "
"tal:replace='notHere'>okay</p>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'tal:replace'
:
'notHere'
,
'tal:on-error'
:
'string:error'
}),
(
'onError'
,
([(
'insertText'
,
(
'$notHere$'
,
[(
'startTag'
,
(
'p'
,
[(
'tal:on-error'
,
'string:error'
,
'tal'
),
(
'tal:replace'
,
'notHere'
,
'tal'
)])),
rawtext
(
'okay</p>'
)]))],
[(
'startTag'
,
(
'p'
,
[(
'tal:on-error'
,
'string:error'
,
'tal'
),
(
'tal:replace'
,
'notHere'
,
'tal'
)])),
(
'insertText'
,
(
'$string:error$'
,
[])),
rawtext
(
'</p>'
)])),
(
'endScope'
,
()),
])
def
check_dup_attr
(
self
):
self
.
_should_error
(
"<img tal:condition='x' tal:condition='x'>"
)
self
.
_should_error
(
"<img metal:define-macro='x' "
"metal:define-macro='x'>"
,
METALError
)
def
check_tal_errors
(
self
):
self
.
_should_error
(
"<p tal:define='x' />"
)
self
.
_should_error
(
"<p tal:repeat='x' />"
)
self
.
_should_error
(
"<p tal:foobar='x' />"
)
self
.
_should_error
(
"<p tal:replace='x' tal:content='x' />"
)
self
.
_should_error
(
"<p tal:replace='x'>"
)
for
tag
in
HTMLTALParser
.
EMPTY_HTML_TAGS
:
self
.
_should_error
(
"<%s tal:content='string:foo'>"
%
tag
)
def
check_metal_errors
(
self
):
exc
=
METALError
self
.
_should_error
(
2
*
"<p metal:define-macro='x'>xxx</p>"
,
exc
)
self
.
_should_error
(
"<html metal:use-macro='x'>"
+
2
*
"<p metal:fill-slot='y' />"
+
"</html>"
,
exc
)
self
.
_should_error
(
"<p metal:foobar='x' />"
,
exc
)
self
.
_should_error
(
"<p metal:define-macro='x'>"
,
exc
)
#
# I18N test cases
#
def
check_i18n_attributes
(
self
):
self
.
_run_check
(
"<img alt='foo' i18n:attributes='alt'>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'alt'
:
'foo'
,
'i18n:attributes'
:
'alt'
}),
(
'startTag'
,
(
'img'
,
[(
'alt'
,
'foo'
,
'replace'
,
None
,
1
,
None
),
(
'i18n:attributes'
,
'alt'
,
'i18n'
)])),
(
'endScope'
,
()),
])
self
.
_run_check
(
"<img alt='foo' i18n:attributes='alt foo ; bar'>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'alt'
:
'foo'
,
'i18n:attributes'
:
'alt foo ; bar'
}),
(
'startTag'
,
(
'img'
,
[(
'alt'
,
'foo'
,
'replace'
,
None
,
1
,
'foo'
),
(
'i18n:attributes'
,
'alt foo ; bar'
,
'i18n'
),
(
'bar'
,
None
,
'insert'
,
None
,
1
,
None
)])),
(
'endScope'
,
()),
])
self
.
_should_error
(
'''<input name="Delete"
tal:attributes="name string:delete_button"
i18n:attributes="name message-id">'''
)
def
test_i18n_name_bad_name
(
self
):
self
.
_should_error
(
"<span i18n:name='not a valid name' />"
)
self
.
_should_error
(
"<span i18n:name='-bad-name' />"
)
def
test_i18n_attributes_repeated_attr
(
self
):
self
.
_should_error
(
"<a i18n:attributes='href; href' />"
)
self
.
_should_error
(
"<a i18n:attributes='href; HREF' />"
)
def
check_i18n_translate
(
self
):
# input/test19.html
self
.
_run_check
(
'''
\
<span i18n:translate="">Replace this</span>
<span i18n:translate="msgid">This is a
translated string</span>
<span i18n:translate="">And another
translated string</span>
'''
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'i18n:translate'
:
''
}),
(
'startTag'
,
(
'span'
,
[(
'i18n:translate'
,
''
,
'i18n'
)])),
(
'insertTranslation'
,
(
''
,
[(
'rawtextOffset'
,
(
'Replace this'
,
12
))])),
(
'rawtextBeginScope'
,
(
'</span>
\
n
'
,
0
,
(
2
,
0
),
1
,
{
'i18n:translate'
:
'msgid'
})),
(
'startTag'
,
(
'span'
,
[(
'i18n:translate'
,
'msgid'
,
'i18n'
)])),
(
'insertTranslation'
,
(
'msgid'
,
[(
'rawtextColumn'
,
(
'This is a
\
n
translated string'
,
17
))])),
(
'rawtextBeginScope'
,
(
'</span>
\
n
'
,
0
,
(
4
,
0
),
1
,
{
'i18n:translate'
:
''
})),
(
'startTag'
,
(
'span'
,
[(
'i18n:translate'
,
''
,
'i18n'
)])),
(
'insertTranslation'
,
(
''
,
[(
'rawtextColumn'
,
(
'And another
\
n
translated string'
,
17
))])),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'</span>
\
n
'
,
0
))])
def
check_i18n_translate_with_nested_tal
(
self
):
self
.
_run_check
(
'''
\
<span i18n:translate="">replaceable <p tal:replace="str:here">content</p></span>
'''
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'i18n:translate'
:
''
}),
(
'startTag'
,
(
'span'
,
[(
'i18n:translate'
,
''
,
'i18n'
)])),
(
'insertTranslation'
,
(
''
,
[(
'rawtextOffset'
,
(
'replaceable '
,
12
)),
(
'setPosition'
,
(
1
,
36
)),
(
'beginScope'
,
{
'tal:replace'
:
'str:here'
}),
(
'insertText'
,
(
'$str:here$'
,
[(
'startTag'
,
(
'p'
,
[(
'tal:replace'
,
'str:here'
,
'tal'
)])),
(
'rawtextOffset'
,
(
'content</p>'
,
11
))])),
(
'endScope'
,
())])),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'</span>
\
n
'
,
0
))
])
def
check_i18n_name
(
self
):
# input/test21.html
self
.
_run_check
(
'''
\
<span i18n:translate="">
<span tal:replace="str:Lomax" i18n:name="name" /> was born in
<span tal:replace="str:Antarctica" i18n:name="country" />.
</span>
'''
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'i18n:translate'
:
''
}),
(
'startTag'
,
(
'span'
,
[(
'i18n:translate'
,
''
,
'i18n'
)])),
(
'insertTranslation'
,
(
''
,
[(
'rawtextBeginScope'
,
(
'
\
n
'
,
2
,
(
2
,
2
),
0
,
{
'i18n:name'
:
'name'
,
'tal:replace'
:
'str:Lomax'
})),
(
'i18nVariable'
,
(
'name'
,
[(
'startEndTag'
,
(
'span'
,
[(
'tal:replace'
,
'str:Lomax'
,
'tal'
),
(
'i18n:name'
,
'name'
,
'i18n'
)]))],
'$str:Lomax$'
,
0
)),
(
'rawtextBeginScope'
,
(
' was born in
\
n
'
,
2
,
(
3
,
2
),
1
,
{
'i18n:name'
:
'country'
,
'tal:replace'
:
'str:Antarctica'
})),
(
'i18nVariable'
,
(
'country'
,
[(
'startEndTag'
,
(
'span'
,
[(
'tal:replace'
,
'str:Antarctica'
,
'tal'
),
(
'i18n:name'
,
'country'
,
'i18n'
)]))],
'$str:Antarctica$'
,
0
)),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'.
\
n
'
,
0
))])),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'</span>
\
n
'
,
0
))
])
def
test_i18n_name_with_content
(
self
):
self
.
_run_check
(
'<div i18n:translate="">This is text for '
'<span i18n:translate="" tal:content="bar" i18n:name="bar_name"/>.'
'</div>'
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'i18n:translate'
:
''
}),
(
'startTag'
,
(
'div'
,
[(
'i18n:translate'
,
''
,
'i18n'
)])),
(
'insertTranslation'
,
(
''
,
[(
'rawtextOffset'
,
(
'This is text for '
,
17
)),
(
'setPosition'
,
(
1
,
40
)),
(
'beginScope'
,
{
'tal:content'
:
'bar'
,
'i18n:name'
:
'bar_name'
,
'i18n:translate'
:
''
}),
(
'i18nVariable'
,
(
'bar_name'
,
[(
'startTag'
,
(
'span'
,
[(
'i18n:translate'
,
''
,
'i18n'
),
(
'tal:content'
,
'bar'
,
'tal'
),
(
'i18n:name'
,
'bar_name'
,
'i18n'
)])),
(
'insertTranslation'
,
(
''
,
[(
'insertText'
,
(
'$bar$'
,
[]))])),
(
'rawtextOffset'
,
(
'</span>'
,
7
))],
None
,
0
)),
(
'endScope'
,
()),
(
'rawtextOffset'
,
(
'.'
,
1
))])),
(
'endScope'
,
()),
(
'rawtextOffset'
,
(
'</div>'
,
6
))
])
def
check_i18n_name_implicit_value
(
self
):
# input/test22.html
self
.
_run_check
(
'''
\
<span i18n:translate="">
<span i18n:name="name"><b>Jim</b></span> was born in
<span i18n:name="country">the USA</span>.
</span>
'''
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'i18n:translate'
:
''
}),
(
'startTag'
,
(
'span'
,
[(
'i18n:translate'
,
''
,
'i18n'
)])),
(
'insertTranslation'
,
(
''
,
[(
'rawtextBeginScope'
,
(
'
\
n
'
,
2
,
(
2
,
2
),
0
,
{
'i18n:name'
:
'name'
})),
(
'i18nVariable'
,
(
'name'
,
[(
'rawtextOffset'
,
(
'<b>Jim</b>'
,
10
))],
None
,
0
)),
(
'rawtextBeginScope'
,
(
' was born in
\
n
'
,
2
,
(
3
,
2
),
1
,
{
'i18n:name'
:
'country'
})),
(
'i18nVariable'
,
(
'country'
,
[(
'rawtextOffset'
,
(
'the USA'
,
7
))],
None
,
0
)),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'.
\
n
'
,
0
))])),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'</span>
\
n
'
,
0
))
])
def
check_i18n_context_domain
(
self
):
self
.
_run_check
(
"<span i18n:domain='mydomain'/>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginI18nContext'
,
{
'domain'
:
'mydomain'
,
'source'
:
None
,
'target'
:
None
}),
(
'beginScope'
,
{
'i18n:domain'
:
'mydomain'
}),
(
'startEndTag'
,
(
'span'
,
[(
'i18n:domain'
,
'mydomain'
,
'i18n'
)])),
(
'endScope'
,
()),
(
'endI18nContext'
,
()),
])
def
check_i18n_context_source
(
self
):
self
.
_run_check
(
"<span i18n:source='en'/>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginI18nContext'
,
{
'source'
:
'en'
,
'domain'
:
'default'
,
'target'
:
None
}),
(
'beginScope'
,
{
'i18n:source'
:
'en'
}),
(
'startEndTag'
,
(
'span'
,
[(
'i18n:source'
,
'en'
,
'i18n'
)])),
(
'endScope'
,
()),
(
'endI18nContext'
,
()),
])
def
check_i18n_context_source_target
(
self
):
self
.
_run_check
(
"<span i18n:source='en' i18n:target='ru'/>"
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginI18nContext'
,
{
'source'
:
'en'
,
'target'
:
'ru'
,
'domain'
:
'default'
}),
(
'beginScope'
,
{
'i18n:source'
:
'en'
,
'i18n:target'
:
'ru'
}),
(
'startEndTag'
,
(
'span'
,
[(
'i18n:source'
,
'en'
,
'i18n'
),
(
'i18n:target'
,
'ru'
,
'i18n'
)])),
(
'endScope'
,
()),
(
'endI18nContext'
,
()),
])
def
check_i18n_context_in_define_slot
(
self
):
text
=
(
"<div metal:use-macro='M' i18n:domain='mydomain'>"
"<div metal:fill-slot='S'>spam</div>"
"</div>"
)
self
.
_run_check
(
text
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'useMacro'
,
(
'M'
,
'$M$'
,
{
'S'
:
[(
'startTag'
,
(
'div'
,
[(
'metal:fill-slot'
,
'S'
,
'metal'
)])),
rawtext
(
'spam</div>'
)]},
[(
'beginI18nContext'
,
{
'domain'
:
'mydomain'
,
'source'
:
None
,
'target'
:
None
}),
(
'beginScope'
,
{
'i18n:domain'
:
'mydomain'
,
'metal:use-macro'
:
'M'
}),
(
'startTag'
,
(
'div'
,
[(
'metal:use-macro'
,
'M'
,
'metal'
),
(
'i18n:domain'
,
'mydomain'
,
'i18n'
)])),
(
'setPosition'
,
(
1
,
48
)),
(
'fillSlot'
,
(
'S'
,
[(
'startTag'
,
(
'div'
,
[(
'metal:fill-slot'
,
'S'
,
'metal'
)])),
rawtext
(
'spam</div>'
)])),
(
'endScope'
,
()),
rawtext
(
'</div>'
),
(
'endI18nContext'
,
())])),
])
def
check_i18n_data
(
self
):
# input/test23.html
self
.
_run_check
(
'''
\
<span i18n:data="here/currentTime"
i18n:translate="timefmt">2:32 pm</span>
'''
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'i18n:translate'
:
'timefmt'
,
'i18n:data'
:
'here/currentTime'
}),
(
'startTag'
,
(
'span'
,
[(
'i18n:data'
,
'here/currentTime'
,
'i18n'
),
(
'i18n:translate'
,
'timefmt'
,
'i18n'
)])),
(
'insertTranslation'
,
(
'timefmt'
,
[(
'rawtextOffset'
,
(
'2:32 pm'
,
7
))],
'$here/currentTime$'
)),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'</span>
\
n
'
,
0
))
])
def
check_i18n_data_with_name
(
self
):
# input/test29.html
self
.
_run_check
(
'''
\
<div i18n:translate="">At the tone the time will be
<span i18n:data="here/currentTime"
i18n:translate="timefmt"
i18n:name="time">2:32 pm</span>... beep!</div>
'''
,
[(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'i18n:translate'
:
''
}),
(
'startTag'
,
(
'div'
,
[(
'i18n:translate'
,
''
,
'i18n'
)])),
(
'insertTranslation'
,
(
''
,
[(
'rawtextBeginScope'
,
(
'At the tone the time will be
\
n
'
,
0
,
(
2
,
0
),
0
,
{
'i18n:data'
:
'here/currentTime'
,
'i18n:name'
:
'time'
,
'i18n:translate'
:
'timefmt'
})),
(
'insertTranslation'
,
(
'timefmt'
,
[(
'startTag'
,
(
'span'
,
[(
'i18n:data'
,
'here/currentTime'
,
'i18n'
),
(
'i18n:translate'
,
'timefmt'
,
'i18n'
),
(
'i18n:name'
,
'time'
,
'i18n'
)])),
(
'i18nVariable'
,
(
'time'
,
[],
None
,
0
))],
'$here/currentTime$'
)),
(
'endScope'
,
()),
(
'rawtextOffset'
,
(
'... beep!'
,
9
))])),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'</div>
\
n
'
,
0
))]
)
def
check_i18n_explicit_msgid_with_name
(
self
):
# input/test26.html
self
.
_run_check
(
'''
\
<span i18n:translate="jobnum">
Job #<span tal:replace="context/@@object_name"
i18n:name="jobnum">NN</span></span>
'''
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'i18n:translate'
:
'jobnum'
}),
(
'startTag'
,
(
'span'
,
[(
'i18n:translate'
,
'jobnum'
,
'i18n'
)])),
(
'insertTranslation'
,
(
'jobnum'
,
[(
'rawtextBeginScope'
,
(
'
\
n
Job #'
,
9
,
(
2
,
9
),
0
,
{
'i18n:name'
:
'jobnum'
,
'tal:replace'
:
'context/@@object_name'
})),
(
'i18nVariable'
,
(
'jobnum'
,
[(
'startTag'
,
(
'span'
,
[(
'tal:replace'
,
'context/@@object_name'
,
'tal'
),
(
'i18n:name'
,
'jobnum'
,
'i18n'
)])),
(
'rawtextOffset'
,
(
'NN'
,
2
)),
(
'rawtextOffset'
,
(
'</span>'
,
7
))],
'$context/@@object_name$'
,
0
)),
(
'endScope'
,
())])),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'</span>
\
n
'
,
0
))
])
def
check_i18n_name_around_tal_content
(
self
):
# input/test28.html
self
.
_run_check
(
'''
\
<p i18n:translate="verify">Your contact email address is recorded as
<span i18n:name="email">
<a href="mailto:user@example.com"
tal:content="request/submitter">user@host.com</a></span>
</p>
'''
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'i18n:translate'
:
'verify'
}),
(
'startTag'
,
(
'p'
,
[(
'i18n:translate'
,
'verify'
,
'i18n'
)])),
(
'insertTranslation'
,
(
'verify'
,
[(
'rawtextBeginScope'
,
(
'Your contact email address is recorded as
\
n
'
,
4
,
(
2
,
4
),
0
,
{
'i18n:name'
:
'email'
})),
(
'i18nVariable'
,
(
'email'
,
[(
'rawtextBeginScope'
,
(
'
\
n
'
,
4
,
(
3
,
4
),
0
,
{
'href'
:
'mailto:user@example.com'
,
'tal:content'
:
'request/submitter'
})),
(
'startTag'
,
(
'a'
,
[(
'href'
,
'href="mailto:user@example.com"'
),
(
'tal:content'
,
'request/submitter'
,
'tal'
)])),
(
'insertText'
,
(
'$request/submitter$'
,
[(
'rawtextOffset'
,
(
'user@host.com'
,
13
))])),
(
'endScope'
,
()),
(
'rawtextOffset'
,
(
'</a>'
,
4
))],
None
,
0
)),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'
\
n
'
,
0
))])),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'</p>
\
n
'
,
0
))
])
def
check_i18n_name_with_tal_content
(
self
):
# input/test27.html
self
.
_run_check
(
'''
\
<p i18n:translate="verify">Your contact email address is recorded as
<a href="mailto:user@example.com"
tal:content="request/submitter"
i18n:name="email">user@host.com</a>
</p>
'''
,
[
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'i18n:translate'
:
'verify'
}),
(
'startTag'
,
(
'p'
,
[(
'i18n:translate'
,
'verify'
,
'i18n'
)])),
(
'insertTranslation'
,
(
'verify'
,
[(
'rawtextBeginScope'
,
(
'Your contact email address is recorded as
\
n
'
,
4
,
(
2
,
4
),
0
,
{
'href'
:
'mailto:user@example.com'
,
'i18n:name'
:
'email'
,
'tal:content'
:
'request/submitter'
})),
(
'i18nVariable'
,
(
'email'
,
[(
'startTag'
,
(
'a'
,
[(
'href'
,
'href="mailto:user@example.com"'
),
(
'tal:content'
,
'request/submitter'
,
'tal'
),
(
'i18n:name'
,
'email'
,
'i18n'
)])),
(
'insertText'
,
(
'$request/submitter$'
,
[(
'rawtextOffset'
,
(
'user@host.com'
,
13
))])),
(
'rawtextOffset'
,
(
'</a>'
,
4
))],
None
,
0
)),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'
\
n
'
,
0
))])),
(
'endScope'
,
()),
(
'rawtextColumn'
,
(
'</p>
\
n
'
,
0
))
])
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
HTMLTALParserTestCases
,
"check_"
))
suite
.
addTest
(
unittest
.
makeSuite
(
METALGeneratorTestCases
,
"check_"
))
suite
.
addTest
(
unittest
.
makeSuite
(
TALGeneratorTestCases
,
"check_"
))
return
suite
if
__name__
==
"__main__"
:
errs
=
utils
.
run_suite
(
test_suite
())
sys
.
exit
(
errs
and
1
or
0
)
lib/python/TAL/tests/test_sourcepos.py
deleted
100644 → 0
View file @
1c0af142
#! /usr/bin/env python
"""Tests for TALInterpreter."""
import
sys
import
unittest
from
StringIO
import
StringIO
from
TAL.HTMLTALParser
import
HTMLTALParser
from
TAL.TALInterpreter
import
TALInterpreter
from
TAL.TALGenerator
import
TALGenerator
from
TAL.DummyEngine
import
DummyEngine
page1
=
'''<html metal:use-macro="main"><body>
<div metal:fill-slot="body">
page1=<span tal:replace="position:" />
</div>
</body></html>'''
main_template
=
'''<html metal:define-macro="main"><body>
main_template=<span tal:replace="position:" />
<div metal:define-slot="body" />
main_template=<span tal:replace="position:" />
<div metal:use-macro="foot" />
main_template=<span tal:replace="position:" />
</body></html>'''
footer
=
'''<div metal:define-macro="foot">
footer=<span tal:replace="position:" />
</div>'''
expected
=
'''<html><body>
main_template=main_template (2,14)
<div>
page1=page1 (3,6)
</div>
main_template=main_template (4,14)
<div>
footer=footer (2,7)
</div>
main_template=main_template (6,14)
</body></html>'''
class
Tests
(
unittest
.
TestCase
):
def
parse
(
self
,
eng
,
s
,
fn
):
gen
=
TALGenerator
(
expressionCompiler
=
eng
,
xml
=
0
,
source_file
=
fn
)
parser
=
HTMLTALParser
(
gen
)
parser
.
parseString
(
s
)
program
,
macros
=
parser
.
getCode
()
return
program
,
macros
def
testSourcePositions
(
self
):
"""Ensure source file and position are set correctly by TAL"""
macros
=
{}
eng
=
DummyEngine
(
macros
)
page1_program
,
page1_macros
=
self
.
parse
(
eng
,
page1
,
'page1'
)
main_template_program
,
main_template_macros
=
self
.
parse
(
eng
,
main_template
,
'main_template'
)
footer_program
,
footer_macros
=
self
.
parse
(
eng
,
footer
,
'footer'
)
macros
[
'main'
]
=
main_template_macros
[
'main'
]
macros
[
'foot'
]
=
footer_macros
[
'foot'
]
stream
=
StringIO
()
interp
=
TALInterpreter
(
page1_program
,
macros
,
eng
,
stream
)
interp
()
self
.
assertEqual
(
stream
.
getvalue
().
strip
(),
expected
.
strip
(),
stream
.
getvalue
())
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
Tests
))
return
suite
if
__name__
==
"__main__"
:
unittest
.
main
()
lib/python/TAL/tests/test_talinterpreter.py
deleted
100644 → 0
View file @
1c0af142
# -*- coding: ISO-8859-1 -*-
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests for TALInterpreter.
$Id$
"""
import
sys
import
unittest
from
StringIO
import
StringIO
from
TAL.TALDefs
import
METALError
,
I18NError
from
TAL.HTMLTALParser
import
HTMLTALParser
from
TAL.TALParser
import
TALParser
from
TAL.TALInterpreter
import
TALInterpreter
from
TAL.DummyEngine
import
DummyEngine
,
DummyTranslationService
from
TAL.TALInterpreter
import
interpolate
from
TAL.tests
import
utils
from
zope.i18nmessageid
import
Message
class
TestCaseBase
(
unittest
.
TestCase
):
def
_compile
(
self
,
source
):
parser
=
HTMLTALParser
()
parser
.
parseString
(
source
)
program
,
macros
=
parser
.
getCode
()
return
program
,
macros
class
MacroErrorsTestCase
(
TestCaseBase
):
def
setUp
(
self
):
dummy
,
macros
=
self
.
_compile
(
'<p metal:define-macro="M">Booh</p>'
)
self
.
macro
=
macros
[
'M'
]
self
.
engine
=
DummyEngine
(
macros
)
program
,
dummy
=
self
.
_compile
(
'<p metal:use-macro="M">Bah</p>'
)
self
.
interpreter
=
TALInterpreter
(
program
,
{},
self
.
engine
)
def
tearDown
(
self
):
try
:
self
.
interpreter
()
except
METALError
:
pass
else
:
self
.
fail
(
"Expected METALError"
)
def
test_mode_error
(
self
):
self
.
macro
[
1
]
=
(
"mode"
,
"duh"
)
def
test_version_error
(
self
):
self
.
macro
[
0
]
=
(
"version"
,
"duh"
)
class
I18NCornerTestCase
(
TestCaseBase
):
def
setUp
(
self
):
self
.
engine
=
DummyEngine
()
self
.
engine
.
setLocal
(
'foo'
,
Message
(
'FoOvAlUe'
,
'default'
))
self
.
engine
.
setLocal
(
'bar'
,
'BaRvAlUe'
)
self
.
engine
.
setLocal
(
'raw'
,
'
\
t
RaW
\
n
'
)
self
.
engine
.
setLocal
(
'noxlt'
,
Message
(
"don't translate me"
))
def
_check
(
self
,
program
,
expected
):
result
=
StringIO
()
self
.
interpreter
=
TALInterpreter
(
program
,
{},
self
.
engine
,
stream
=
result
)
self
.
interpreter
()
self
.
assertEqual
(
expected
,
result
.
getvalue
())
def
test_simple_messageid_translate
(
self
):
# This test is mainly here to make sure our DummyEngine works
# correctly.
program
,
macros
=
self
.
_compile
(
'<span tal:content="foo"/>'
)
self
.
_check
(
program
,
'<span>FOOVALUE</span>
\
n
'
)
program
,
macros
=
self
.
_compile
(
'<span tal:replace="foo"/>'
)
self
.
_check
(
program
,
'FOOVALUE
\
n
'
)
def
test_replace_with_messageid_and_i18nname
(
self
):
program
,
macros
=
self
.
_compile
(
'<div i18n:translate="" >'
'<span tal:replace="foo" i18n:name="foo_name"/>'
'</div>'
)
self
.
_check
(
program
,
'<div>FOOVALUE</div>
\
n
'
)
def
test_pythonexpr_replace_with_messageid_and_i18nname
(
self
):
program
,
macros
=
self
.
_compile
(
'<div i18n:translate="" >'
'<span tal:replace="python: foo" i18n:name="foo_name"/>'
'</div>'
)
self
.
_check
(
program
,
'<div>FOOVALUE</div>
\
n
'
)
def
test_structure_replace_with_messageid_and_i18nname
(
self
):
program
,
macros
=
self
.
_compile
(
'<div i18n:translate="" >'
'<span tal:replace="structure foo" i18n:name="foo_name"/>'
'</div>'
)
self
.
_check
(
program
,
'<div>FOOVALUE</div>
\
n
'
)
def
test_complex_replace_with_messageid_and_i18nname
(
self
):
program
,
macros
=
self
.
_compile
(
'<div i18n:translate="" >'
'<em i18n:name="foo_name">'
'<span tal:replace="foo"/>'
'</em>'
'</div>'
)
self
.
_check
(
program
,
'<div>FOOVALUE</div>
\
n
'
)
def
test_content_with_messageid_and_i18nname
(
self
):
program
,
macros
=
self
.
_compile
(
'<div i18n:translate="" >'
'<span tal:content="foo" i18n:name="foo_name"/>'
'</div>'
)
self
.
_check
(
program
,
'<div><span>FOOVALUE</span></div>
\
n
'
)
def
test_content_with_messageid_and_i18nname_and_i18ntranslate
(
self
):
# Let's tell the user this is incredibly silly!
self
.
assertRaises
(
I18NError
,
self
.
_compile
,
'<span i18n:translate="" tal:content="foo" i18n:name="foo_name"/>'
)
def
test_content_with_plaintext_and_i18nname_and_i18ntranslate
(
self
):
# Let's tell the user this is incredibly silly!
self
.
assertRaises
(
I18NError
,
self
.
_compile
,
'<span i18n:translate="" i18n:name="color_name">green</span>'
)
def
test_translate_static_text_as_dynamic
(
self
):
program
,
macros
=
self
.
_compile
(
'<div i18n:translate="">This is text for '
'<span i18n:translate="" tal:content="bar" i18n:name="bar_name"/>.'
'</div>'
)
self
.
_check
(
program
,
'<div>THIS IS TEXT FOR <span>BARVALUE</span>.</div>
\
n
'
)
def
test_translate_static_text_as_dynamic_from_bytecode
(
self
):
program
=
[(
'version'
,
'1.5'
),
(
'mode'
,
'html'
),
(
'setPosition'
,
(
1
,
0
)),
(
'beginScope'
,
{
'i18n:translate'
:
''
}),
(
'startTag'
,
(
'div'
,
[(
'i18n:translate'
,
''
,
'i18n'
)])),
(
'insertTranslation'
,
(
''
,
[(
'rawtextOffset'
,
(
'This is text for '
,
17
)),
(
'setPosition'
,
(
1
,
40
)),
(
'beginScope'
,
{
'tal:content'
:
'bar'
,
'i18n:name'
:
'bar_name'
,
'i18n:translate'
:
''
}),
(
'i18nVariable'
,
(
'bar_name'
,
[(
'startTag'
,
(
'span'
,
[(
'i18n:translate'
,
''
,
'i18n'
),
(
'tal:content'
,
'bar'
,
'tal'
),
(
'i18n:name'
,
'bar_name'
,
'i18n'
)])),
(
'insertTranslation'
,
(
''
,
[(
'insertText'
,
(
'$bar$'
,
[]))])),
(
'rawtextOffset'
,
(
'</span>'
,
7
))],
None
,
0
)),
(
'endScope'
,
()),
(
'rawtextOffset'
,
(
'.'
,
1
))])),
(
'endScope'
,
()),
(
'rawtextOffset'
,
(
'</div>'
,
6
))
]
self
.
_check
(
program
,
'<div>THIS IS TEXT FOR <span>BARVALUE</span>.</div>
\
n
'
)
def
_getCollectingTranslationDomain
(
self
):
class
CollectingTranslationService
(
DummyTranslationService
):
data
=
[]
def
translate
(
self
,
domain
,
msgid
,
mapping
=
None
,
context
=
None
,
target_language
=
None
,
default
=
None
):
self
.
data
.
append
((
msgid
,
mapping
))
return
DummyTranslationService
.
translate
(
self
,
domain
,
msgid
,
mapping
,
context
,
target_language
,
default
)
xlatsvc
=
CollectingTranslationService
()
self
.
engine
.
translationService
=
xlatsvc
return
xlatsvc
def
test_for_correct_msgids
(
self
):
xlatdmn
=
self
.
_getCollectingTranslationDomain
()
result
=
StringIO
()
program
,
macros
=
self
.
_compile
(
'<div i18n:translate="">This is text for '
'<span i18n:translate="" tal:content="bar" '
'i18n:name="bar_name"/>.</div>'
)
self
.
interpreter
=
TALInterpreter
(
program
,
{},
self
.
engine
,
stream
=
result
)
self
.
interpreter
()
msgids
=
list
(
xlatdmn
.
data
)
msgids
.
sort
()
self
.
assertEqual
(
2
,
len
(
msgids
))
self
.
assertEqual
(
'BaRvAlUe'
,
msgids
[
0
][
0
])
self
.
assertEqual
(
'This is text for ${bar_name}.'
,
msgids
[
1
][
0
])
self
.
assertEqual
({
'bar_name'
:
'<span>BARVALUE</span>'
},
msgids
[
1
][
1
])
self
.
assertEqual
(
'<div>THIS IS TEXT FOR <span>BARVALUE</span>.</div>
\
n
'
,
result
.
getvalue
())
def
test_for_raw_msgids
(
self
):
# Test for Issue 314: i18n:translate removes line breaks from
# <pre>...</pre> contents
# HTML mode
xlatdmn
=
self
.
_getCollectingTranslationDomain
()
result
=
StringIO
()
program
,
macros
=
self
.
_compile
(
'<div i18n:translate=""> This is text
\
n
'
'
\
t
for
\
n
div. </div>'
'<pre i18n:translate=""> This is text
\
n
'
' <b>
\
t
for</b>
\
n
pre. </pre>'
)
self
.
interpreter
=
TALInterpreter
(
program
,
{},
self
.
engine
,
stream
=
result
)
self
.
interpreter
()
msgids
=
list
(
xlatdmn
.
data
)
msgids
.
sort
()
self
.
assertEqual
(
2
,
len
(
msgids
))
self
.
assertEqual
(
' This is text
\
n
<b>
\
t
for</b>
\
n
pre. '
,
msgids
[
0
][
0
])
self
.
assertEqual
(
'This is text for div.'
,
msgids
[
1
][
0
])
self
.
assertEqual
(
'<div>THIS IS TEXT FOR DIV.</div>'
'<pre> THIS IS TEXT
\
n
<B>
\
t
FOR</B>
\
n
PRE. </pre>
\
n
'
,
result
.
getvalue
())
# XML mode
xlatdmn
=
self
.
_getCollectingTranslationDomain
()
result
=
StringIO
()
parser
=
TALParser
()
parser
.
parseString
(
'<?xml version="1.0"?>
\
n
'
'<pre xmlns:i18n="http://xml.zope.org/namespaces/i18n"'
' i18n:translate=""> This is text
\
n
'
' <b>
\
t
for</b>
\
n
barvalue. </pre>'
)
program
,
macros
=
parser
.
getCode
()
self
.
interpreter
=
TALInterpreter
(
program
,
{},
self
.
engine
,
stream
=
result
)
self
.
interpreter
()
msgids
=
list
(
xlatdmn
.
data
)
msgids
.
sort
()
self
.
assertEqual
(
1
,
len
(
msgids
))
self
.
assertEqual
(
'This is text <b> for</b> barvalue.'
,
msgids
[
0
][
0
])
self
.
assertEqual
(
'<?xml version="1.0"?>
\
n
'
'<pre>THIS IS TEXT <B> FOR</B> BARVALUE.</pre>
\
n
'
,
result
.
getvalue
())
def
test_raw_msgids_and_i18ntranslate_i18nname
(
self
):
xlatdmn
=
self
.
_getCollectingTranslationDomain
()
result
=
StringIO
()
program
,
macros
=
self
.
_compile
(
'<div i18n:translate=""> This is text
\
n
\
t
for
\
n
'
'<pre tal:content="raw" i18n:name="raw"'
' i18n:translate=""></pre>.</div>'
)
self
.
interpreter
=
TALInterpreter
(
program
,
{},
self
.
engine
,
stream
=
result
)
self
.
interpreter
()
msgids
=
list
(
xlatdmn
.
data
)
msgids
.
sort
()
self
.
assertEqual
(
2
,
len
(
msgids
))
self
.
assertEqual
(
'
\
t
RaW
\
n
'
,
msgids
[
0
][
0
])
self
.
assertEqual
(
'This is text for ${raw}.'
,
msgids
[
1
][
0
])
self
.
assertEqual
({
'raw'
:
'<pre>
\
t
RAW
\
n
</pre>'
},
msgids
[
1
][
1
])
self
.
assertEqual
(
u'<div>THIS IS TEXT FOR <pre>
\
t
RAW
\
n
</pre>.</div>
\
n
'
,
result
.
getvalue
())
def
test_for_handling_unicode_vars
(
self
):
# Make sure that non-ASCII Unicode is substituted correctly.
# http://collector.zope.org/Zope3-dev/264
program
,
macros
=
self
.
_compile
(
"<div i18n:translate='' tal:define='bar python:unichr(0xC0)'>"
"Foo <span tal:replace='bar' i18n:name='bar' /></div>"
)
self
.
_check
(
program
,
u"<div>FOO
\
u00C0
</div>
\
n
"
)
def
test_for_untranslated_messageid_simple
(
self
):
program
,
macros
=
self
.
_compile
(
'<span tal:content="noxlt"/>'
)
self
.
_check
(
program
,
"<span>don't translate me</span>
\
n
"
)
def
test_for_untranslated_messageid_i18nname
(
self
):
program
,
macros
=
self
.
_compile
(
'<div i18n:translate="" >'
'<span tal:replace="python: noxlt" i18n:name="foo_name"/>'
'</div>'
)
self
.
_check
(
program
,
"<div>don't translate me</div>
\
n
"
)
class
I18NErrorsTestCase
(
TestCaseBase
):
def
_check
(
self
,
src
,
msg
):
try
:
self
.
_compile
(
src
)
except
I18NError
:
pass
else
:
self
.
fail
(
msg
)
def
test_id_with_replace
(
self
):
self
.
_check
(
'<p i18n:id="foo" tal:replace="string:splat"></p>'
,
"expected i18n:id with tal:replace to be denied"
)
def
test_missing_values
(
self
):
self
.
_check
(
'<p i18n:attributes=""></p>'
,
"missing i18n:attributes value not caught"
)
self
.
_check
(
'<p i18n:data=""></p>'
,
"missing i18n:data value not caught"
)
self
.
_check
(
'<p i18n:id=""></p>'
,
"missing i18n:id value not caught"
)
def
test_id_with_attributes
(
self
):
self
.
_check
(
'''<input name="Delete"
tal:attributes="name string:delete_button"
i18n:attributes="name message-id">'''
,
"expected attribute being both part of tal:attributes"
+
" and having a msgid in i18n:attributes to be denied"
)
class
OutputPresentationTestCase
(
TestCaseBase
):
def
test_attribute_wrapping
(
self
):
# To make sure the attribute-wrapping code is invoked, we have to
# include at least one TAL/METAL attribute to avoid having the start
# tag optimized into a rawtext instruction.
INPUT
=
r"""
<html this='element' has='a' lot='of' attributes=', so' the='output'
needs='to' be='line' wrapped='.' tal:define='foo nothing'>
</html>"""
EXPECTED
=
r'''
<html this="element" has="a" lot="of"
attributes=", so" the="output" needs="to"
be="line" wrapped=".">
</html>'''
"
\
n
"
self
.
compare
(
INPUT
,
EXPECTED
)
def
test_unicode_content
(
self
):
INPUT
=
"""<p tal:content="python:u'dj-vu'">para</p>"""
EXPECTED
=
u"""<p>dj-vu</p>"""
"
\
n
"
self
.
compare
(
INPUT
,
EXPECTED
)
def
test_unicode_structure
(
self
):
INPUT
=
"""<p tal:replace="structure python:u'dj-vu'">para</p>"""
EXPECTED
=
u"""dj-vu"""
"
\
n
"
self
.
compare
(
INPUT
,
EXPECTED
)
def
test_i18n_replace_number
(
self
):
INPUT
=
"""
<p i18n:translate="foo ${bar}">
<span tal:replace="python:123" i18n:name="bar">para</span>
</p>"""
EXPECTED
=
u"""
<p>FOO 123</p>"""
"
\
n
"
self
.
compare
(
INPUT
,
EXPECTED
)
def
test_entities
(
self
):
INPUT
=
(
'<img tal:define="foo nothing" '
'alt="&a;  
 &a - &; �a; <>" />'
)
EXPECTED
=
(
'<img alt="&a;  
 '
'&a &#45 &; &#0a; <>" />
\
n
'
)
self
.
compare
(
INPUT
,
EXPECTED
)
def
compare
(
self
,
INPUT
,
EXPECTED
):
program
,
macros
=
self
.
_compile
(
INPUT
)
sio
=
StringIO
()
interp
=
TALInterpreter
(
program
,
{},
DummyEngine
(),
sio
,
wrap
=
60
)
interp
()
self
.
assertEqual
(
sio
.
getvalue
(),
EXPECTED
)
class
InterpolateTestCase
(
TestCaseBase
):
def
test_syntax_ok
(
self
):
text
=
"foo ${bar_0MAN} $baz_zz bee"
mapping
=
{
'bar_0MAN'
:
'fish'
,
'baz_zz'
:
'moo'
}
expected
=
"foo fish moo bee"
self
.
assertEqual
(
interpolate
(
text
,
mapping
),
expected
)
def
test_syntax_bad
(
self
):
text
=
"foo $_bar_man} $ ${baz bee"
mapping
=
{
'_bar_man'
:
'fish'
,
'baz'
:
'moo'
}
expected
=
text
self
.
assertEqual
(
interpolate
(
text
,
mapping
),
expected
)
def
test_missing
(
self
):
text
=
"foo ${bar} ${baz}"
mapping
=
{
'bar'
:
'fish'
}
expected
=
"foo fish ${baz}"
self
.
assertEqual
(
interpolate
(
text
,
mapping
),
expected
)
def
test_redundant
(
self
):
text
=
"foo ${bar}"
mapping
=
{
'bar'
:
'fish'
,
'baz'
:
'moo'
}
expected
=
"foo fish"
self
.
assertEqual
(
interpolate
(
text
,
mapping
),
expected
)
def
test_numeric
(
self
):
text
=
"foo ${bar}"
mapping
=
{
'bar'
:
123
}
expected
=
"foo 123"
self
.
assertEqual
(
interpolate
(
text
,
mapping
),
expected
)
def
test_unicode
(
self
):
text
=
u"foo ${bar}"
mapping
=
{
u'bar'
:
u'baz'
}
expected
=
u"foo baz"
self
.
assertEqual
(
interpolate
(
text
,
mapping
),
expected
)
def
test_unicode_mixed_unknown_encoding
(
self
):
# This test assumes that sys.getdefaultencoding is ascii...
text
=
u"foo ${bar}"
mapping
=
{
u'bar'
:
'd
\
xe9
j
\
xe0
'
}
expected
=
u"foo d
\
\
xe9j
\
\
xe0"
self
.
assertEqual
(
interpolate
(
text
,
mapping
),
expected
)
def
test_suite
():
suite
=
unittest
.
makeSuite
(
I18NErrorsTestCase
)
suite
.
addTest
(
unittest
.
makeSuite
(
MacroErrorsTestCase
))
suite
.
addTest
(
unittest
.
makeSuite
(
OutputPresentationTestCase
))
suite
.
addTest
(
unittest
.
makeSuite
(
I18NCornerTestCase
))
suite
.
addTest
(
unittest
.
makeSuite
(
InterpolateTestCase
))
return
suite
if
__name__
==
"__main__"
:
errs
=
utils
.
run_suite
(
test_suite
())
sys
.
exit
(
errs
and
1
or
0
)
lib/python/TAL/tests/test_xmlparser.py
deleted
100755 → 0
View file @
1c0af142
#! /usr/bin/env python1.5
"""Tests for XMLParser.py."""
import
string
import
sys
from
TAL.tests
import
utils
import
unittest
from
TAL
import
XMLParser
class
EventCollector
(
XMLParser
.
XMLParser
):
def
__init__
(
self
):
self
.
events
=
[]
self
.
append
=
self
.
events
.
append
XMLParser
.
XMLParser
.
__init__
(
self
)
self
.
parser
.
ordered_attributes
=
1
def
get_events
(
self
):
# Normalize the list of events so that buffer artefacts don't
# separate runs of contiguous characters.
L
=
[]
prevtype
=
None
for
event
in
self
.
events
:
type
=
event
[
0
]
if
type
==
prevtype
==
"data"
:
L
[
-
1
]
=
(
"data"
,
L
[
-
1
][
1
]
+
event
[
1
])
else
:
L
.
append
(
event
)
prevtype
=
type
self
.
events
=
L
return
L
# structure markup
def
StartElementHandler
(
self
,
tag
,
attrs
):
self
.
append
((
"starttag"
,
tag
,
attrs
))
def
EndElementHandler
(
self
,
tag
):
self
.
append
((
"endtag"
,
tag
))
# all other markup
def
CommentHandler
(
self
,
data
):
self
.
append
((
"comment"
,
data
))
def
handle_charref
(
self
,
data
):
self
.
append
((
"charref"
,
data
))
def
CharacterDataHandler
(
self
,
data
):
self
.
append
((
"data"
,
data
))
def
StartDoctypeDeclHandler
(
self
,
rootelem
,
publicId
,
systemId
,
subset
):
self
.
append
((
"doctype"
,
rootelem
,
systemId
,
publicId
,
subset
))
def
XmlDeclHandler
(
self
,
version
,
encoding
,
standalone
):
self
.
append
((
"decl"
,
version
,
encoding
,
standalone
))
def
ExternalEntityRefHandler
(
self
,
data
):
self
.
append
((
"entityref"
,
data
))
def
ProcessingInstructionHandler
(
self
,
target
,
data
):
self
.
append
((
"pi"
,
target
,
data
))
class
EventCollectorExtra
(
EventCollector
):
def
handle_starttag
(
self
,
tag
,
attrs
):
EventCollector
.
handle_starttag
(
self
,
tag
,
attrs
)
self
.
append
((
"starttag_text"
,
self
.
get_starttag_text
()))
class
SegmentedFile
:
def
__init__
(
self
,
parts
):
self
.
parts
=
list
(
parts
)
def
read
(
self
,
bytes
):
if
self
.
parts
:
s
=
self
.
parts
.
pop
(
0
)
else
:
s
=
''
return
s
class
XMLParserTestCase
(
unittest
.
TestCase
):
def
_run_check
(
self
,
source
,
events
,
collector
=
EventCollector
):
parser
=
collector
()
if
isinstance
(
source
,
type
([])):
parser
.
parseStream
(
SegmentedFile
(
source
))
else
:
parser
.
parseString
(
source
)
if
utils
.
oldexpat
:
while
events
[
0
][
0
]
in
(
'decl'
,
'doctype'
):
del
events
[
0
]
self
.
assertEquals
(
parser
.
get_events
(),
events
)
def
_run_check_extra
(
self
,
source
,
events
):
self
.
_run_check
(
source
,
events
,
EventCollectorExtra
)
def
_parse_error
(
self
,
source
):
def
parse
(
source
=
source
):
parser
=
XMLParser
.
XMLParser
()
parser
.
parseString
(
source
)
self
.
assertRaises
(
XMLParser
.
XMLParseError
,
parse
)
def
check_processing_instruction_plus
(
self
):
self
.
_run_check
(
"<?processing instruction?><a/>"
,
[
(
"pi"
,
"processing"
,
"instruction"
),
(
"starttag"
,
"a"
,
[]),
(
"endtag"
,
"a"
),
])
def
_check_simple_html
(
self
):
self
.
_run_check
(
"""
\
<?xml version='1.0' encoding='iso-8859-1'?>
<!DOCTYPE html PUBLIC 'foo' 'bar'>
<html>&entity; 
<!--comment1a
-></foo><bar><<?pi?></foo<bar
comment1b-->
<img src='Bar' ismap=''/>sample
text
<!--comment2a- -comment2b-->
</html>
"""
,
[
(
"decl"
,
"1.0"
,
"iso-8859-1"
,
-
1
),
(
"doctype"
,
"html"
,
"foo"
,
"bar"
,
0
),
(
"starttag"
,
"html"
,
[]),
# ("entityref", "entity"),
(
"data"
,
"
\
n
"
),
(
"comment"
,
"comment1a
\
n
-></foo><bar><<?pi?></foo<bar
\
n
comment1b"
),
(
"data"
,
"
\
n
"
),
(
"starttag"
,
"img"
,
[
"src"
,
"Bar"
,
"ismap"
,
""
]),
(
"endtag"
,
"img"
),
(
"data"
,
"sample
\
n
text
\
n
"
),
(
"comment"
,
"comment2a- -comment2b"
),
(
"data"
,
"
\
n
"
),
(
"endtag"
,
"html"
),
])
def
check_bad_nesting
(
self
):
try
:
self
.
_run_check
(
"<a><b></a></b>"
,
[
(
"starttag"
,
"a"
,
[]),
(
"starttag"
,
"b"
,
[]),
(
"endtag"
,
"a"
),
(
"endtag"
,
"b"
),
])
except
:
e
=
sys
.
exc_info
()[
1
]
self
.
assert_
(
e
.
lineno
==
1
,
"did not receive correct position information"
)
else
:
self
.
fail
(
"expected parse error: bad nesting"
)
def
check_attr_syntax
(
self
):
output
=
[
(
"starttag"
,
"a"
,
[
"b"
,
"v"
,
"c"
,
"v"
]),
(
"endtag"
,
"a"
),
]
self
.
_run_check
(
"""<a b='v' c="v"/>"""
,
output
)
self
.
_run_check
(
"""<a b = 'v' c = "v"/>"""
,
output
)
self
.
_run_check
(
"""<a
\
n
b
\
n
=
\
n
'v'
\
n
c
\
n
=
\
n
"v"
\
n
/>"""
,
output
)
self
.
_run_check
(
"""<a
\
t
b
\
t
=
\
t
'v'
\
t
c
\
t
=
\
t
"v"
\
t
/>"""
,
output
)
def
check_attr_values
(
self
):
self
.
_run_check
(
"""<a b='xxx
\
n
\
t
xxx' c="yyy
\
t
\
n
yyy" d='
\
t
xyz
\
n
'/>"""
,
[(
"starttag"
,
"a"
,
[
"b"
,
"xxx xxx"
,
"c"
,
"yyy yyy"
,
"d"
,
" xyz "
]),
(
"endtag"
,
"a"
),
])
self
.
_run_check
(
"""<a b='' c="" d=''/>"""
,
[
(
"starttag"
,
"a"
,
[
"b"
,
""
,
"c"
,
""
,
"d"
,
""
]),
(
"endtag"
,
"a"
),
])
def
check_attr_entity_replacement
(
self
):
self
.
_run_check
(
"""<a b='&><"''/>"""
,
[
(
"starttag"
,
"a"
,
[
"b"
,
"&><
\
"
'"
]),
(
"endtag"
,
"a"
),
])
def
check_attr_funky_names
(
self
):
self
.
_run_check
(
"""<a a.b='v' e-f='v'/>"""
,
[
(
"starttag"
,
"a"
,
[
"a.b"
,
"v"
,
"e-f"
,
"v"
]),
(
"endtag"
,
"a"
),
])
def
check_starttag_end_boundary
(
self
):
self
.
_run_check
(
"""<a b='<'/>"""
,
[
(
"starttag"
,
"a"
,
[
"b"
,
"<"
]),
(
"endtag"
,
"a"
),
])
self
.
_run_check
(
"""<a b='>'/>"""
,
[
(
"starttag"
,
"a"
,
[
"b"
,
">"
]),
(
"endtag"
,
"a"
),
])
def
check_buffer_artefacts
(
self
):
output
=
[(
"starttag"
,
"a"
,
[
"b"
,
"<"
]),
(
"endtag"
,
"a"
)]
self
.
_run_check
([
"<a b='<'/>"
],
output
)
self
.
_run_check
([
"<a "
,
"b='<'/>"
],
output
)
self
.
_run_check
([
"<a b"
,
"='<'/>"
],
output
)
self
.
_run_check
([
"<a b="
,
"'<'/>"
],
output
)
self
.
_run_check
([
"<a b='<"
,
"'/>"
],
output
)
self
.
_run_check
([
"<a b='<'"
,
"/>"
],
output
)
output
=
[(
"starttag"
,
"a"
,
[
"b"
,
">"
]),
(
"endtag"
,
"a"
)]
self
.
_run_check
([
"<a b='>'/>"
],
output
)
self
.
_run_check
([
"<a "
,
"b='>'/>"
],
output
)
self
.
_run_check
([
"<a b"
,
"='>'/>"
],
output
)
self
.
_run_check
([
"<a b="
,
"'>'/>"
],
output
)
self
.
_run_check
([
"<a b='>"
,
"'/>"
],
output
)
self
.
_run_check
([
"<a b='>'"
,
"/>"
],
output
)
def
check_starttag_junk_chars
(
self
):
self
.
_parse_error
(
"<"
)
self
.
_parse_error
(
"<>"
)
self
.
_parse_error
(
"</>"
)
self
.
_parse_error
(
"</$>"
)
self
.
_parse_error
(
"</"
)
self
.
_parse_error
(
"</a"
)
self
.
_parse_error
(
"</a"
)
self
.
_parse_error
(
"<a<a>"
)
self
.
_parse_error
(
"</a<a>"
)
self
.
_parse_error
(
"<$"
)
self
.
_parse_error
(
"<$>"
)
self
.
_parse_error
(
"<!"
)
self
.
_parse_error
(
"<a $>"
)
self
.
_parse_error
(
"<a"
)
self
.
_parse_error
(
"<a foo='bar'"
)
self
.
_parse_error
(
"<a foo='bar"
)
self
.
_parse_error
(
"<a foo='>'"
)
self
.
_parse_error
(
"<a foo='>"
)
def
check_declaration_junk_chars
(
self
):
self
.
_parse_error
(
"<!DOCTYPE foo $ >"
)
# Support for the Zope regression test framework:
def
test_suite
(
skipxml
=
utils
.
skipxml
):
suite
=
unittest
.
TestSuite
()
if
not
skipxml
:
suite
.
addTest
(
unittest
.
makeSuite
(
XMLParserTestCase
,
"check_"
))
return
suite
if
__name__
==
"__main__"
:
errs
=
utils
.
run_suite
(
test_suite
(
skipxml
=
0
))
sys
.
exit
(
errs
and
1
or
0
)
lib/python/TAL/tests/utils.py
deleted
100644 → 0
View file @
1c0af142
"""Helper functions for the test suite."""
import
os
import
sys
mydir
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
__file__
))
codedir
=
os
.
path
.
dirname
(
os
.
path
.
dirname
(
mydir
))
if
codedir
not
in
sys
.
path
:
sys
.
path
.
append
(
codedir
)
import
unittest
import
xml.parsers.expat
# Set skipxml to true if an XML parser could not be found.
# (But Python always includes one now.)
skipxml
=
False
# Set oldexpat if the StartDoctypeDeclHandler and XmlDeclHandler are
# not supported. The tests need to know whether the events reported
# by those handlers should be expected, but need to make sure the
# right thing is returned if they are.
#
oldexpat
=
False
p
=
xml
.
parsers
.
expat
.
ParserCreate
()
#
# Can't use hasattr() since pyexpat supports the handler
# attributes in a broken way.
try
:
p
.
StartDoctypeDeclHandler
=
None
except
AttributeError
:
oldexpat
=
True
def
run_suite
(
suite
,
outf
=
None
,
errf
=
None
):
if
outf
is
None
:
outf
=
sys
.
stdout
runner
=
unittest
.
TextTestRunner
(
outf
)
result
=
runner
.
run
(
suite
)
## print "\n\n"
## if result.errors:
## print "Errors (unexpected exceptions):"
## map(print_error, result.errors)
## print
## if result.failures:
## print "Failures (assertion failures):"
## map(print_error, result.failures)
## print
newerrs
=
len
(
result
.
errors
)
+
len
(
result
.
failures
)
if
newerrs
:
print
"'Errors' indicate exceptions other than AssertionError."
print
"'Failures' indicate AssertionError"
if
errf
is
None
:
errf
=
sys
.
stderr
errf
.
write
(
"%d errors, %d failures
\
n
"
%
(
len
(
result
.
errors
),
len
(
result
.
failures
)))
return
newerrs
def
print_error
(
info
):
testcase
,
(
type
,
e
,
tb
)
=
info
lib/python/TAL/timer.py
deleted
100755 → 0
View file @
1c0af142
#! /usr/bin/env python
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
Helper program to time compilation and interpretation
"""
import
sys
import
time
import
getopt
from
cPickle
import
dumps
,
loads
from
cStringIO
import
StringIO
from
driver
import
FILE
,
compilefile
,
interpretit
def
main
():
count
=
10
try
:
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
"n:"
)
except
getopt
.
error
,
msg
:
print
msg
sys
.
exit
(
2
)
for
o
,
a
in
opts
:
if
o
==
"-n"
:
count
=
int
(
a
)
if
not
args
:
args
=
[
FILE
]
for
file
in
args
:
print
file
dummyfile
=
StringIO
()
it
=
timefunc
(
count
,
compilefile
,
file
)
timefunc
(
count
,
interpretit
,
it
,
None
,
dummyfile
)
def
timefunc
(
count
,
func
,
*
args
):
sys
.
stderr
.
write
(
"%-14s: "
%
func
.
__name__
)
sys
.
stderr
.
flush
()
t0
=
time
.
clock
()
for
i
in
range
(
count
):
result
=
func
(
*
args
)
t1
=
time
.
clock
()
sys
.
stderr
.
write
(
"%6.3f secs for %d calls, i.e. %4.0f msecs per call
\
n
"
%
((
t1
-
t0
),
count
,
1000
*
(
t1
-
t0
)
/
count
))
return
result
if
__name__
==
"__main__"
:
main
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment