# HG changeset patch
# User cmlenz
# Date 1152018576 0
# Node ID 01981cbc757517fcd4436a4955408e8d0a9d2660
# Parent 60f1a556690ef1cba6aa09ebb4f5052e00c345e7
Fix a number of escaping problems:
* `Markup` instances were get escaped
* Expressions in text nodes no longer escape quotes (#9)
diff --git a/markup/core.py b/markup/core.py
--- a/markup/core.py
+++ b/markup/core.py
@@ -238,8 +238,8 @@
def __repr__(self):
return '<%s "%s">' % (self.__class__.__name__, self)
- def join(self, seq):
- return Markup(unicode(self).join([escape(item, quotes=False)
+ def join(self, seq, escape_quotes=True):
+ return Markup(unicode(self).join([escape(item, quotes=escape_quotes)
for item in seq]))
def stripentities(self, keepxmlentities=False):
diff --git a/markup/filters.py b/markup/filters.py
--- a/markup/filters.py
+++ b/markup/filters.py
@@ -118,7 +118,7 @@
if kind is Stream.TEXT:
textbuf.append(data)
elif prev_kind is Stream.TEXT:
- text = Markup('').join(textbuf)
+ text = Markup('').join(textbuf, escape_quotes=False)
text = self._TRAILING_SPACE.sub('', text)
text = self._LINE_COLLAPSE.sub('\n', text)
yield Stream.TEXT, Markup(text), pos
@@ -128,7 +128,9 @@
yield kind, data, pos
if textbuf:
- text = self._LINE_COLLAPSE.sub('\n', ''.join(textbuf))
+ text = Markup('').join(textbuf, escape_quotes=False)
+ text = self._TRAILING_SPACE.sub('', text)
+ text = self._LINE_COLLAPSE.sub('\n', text)
yield Stream.TEXT, Markup(text), pos
diff --git a/markup/template.py b/markup/template.py
--- a/markup/template.py
+++ b/markup/template.py
@@ -157,9 +157,10 @@
class Directive(object):
"""Abstract base class for template directives.
- A directive is basically a callable that takes two parameters: `ctxt` is
- the template data context, and `stream` is an iterable over the events that
- the directive applies to.
+ A directive is basically a callable that takes three positional arguments:
+ `ctxt` is the template data context, `stream` is an iterable over the
+ events that the directive applies to, and `directives` is is a list of
+ other directives on the same stream that need to be applied.
Directives can be "anonymous" or "registered". Registered directives can be
applied by the template author using an XML attribute with the
@@ -470,7 +471,7 @@
"""
__slots__ = []
- def __call__(self, stream, ctxt, directives=None):
+ def __call__(self, stream, ctxt, directives):
kind, data, pos = stream.next()
yield Template.EXPR, self.expr, pos
@@ -507,7 +508,7 @@
"""
__slots__ = []
- def __call__(self, stream, ctxt, directives=None):
+ def __call__(self, stream, ctxt, directives):
if self.expr:
strip = self.expr.evaluate(ctxt)
else:
@@ -580,7 +581,7 @@
See the documentation of `py:choose` for usage.
"""
- def __call__(self, stream, ctxt, directives=None):
+ def __call__(self, stream, ctxt, directives):
choose = ctxt['_choose']
if choose.matched:
return []
@@ -602,7 +603,7 @@
See the documentation of `py:choose` for usage.
"""
- def __call__(self, stream, ctxt, directives=None):
+ def __call__(self, stream, ctxt, directives):
choose = ctxt['_choose']
if choose.matched:
return []
@@ -809,7 +810,7 @@
# succeeds, and the string will be chopped up into individual
# characters
if isinstance(result, basestring):
- yield Stream.TEXT, unicode(result), pos
+ yield Stream.TEXT, result, pos
else:
# Test if the expression evaluated to an iterable, in which
# case we yield the individual items
diff --git a/markup/tests/template.py b/markup/tests/template.py
--- a/markup/tests/template.py
+++ b/markup/tests/template.py
@@ -15,7 +15,7 @@
import unittest
import sys
-from markup.core import Stream
+from markup.core import Markup, Stream
from markup.template import BadDirectiveError, Context, Template, \
TemplateSyntaxError
@@ -35,6 +35,30 @@