changeset 434:5692bc32ba5f trunk

* Better method to propogate the full path to the template file on parse errors. Supersedes r513. * More API docs and doctests.
author cmlenz
date Thu, 22 Mar 2007 21:54:16 +0000
parents bc430fd7c54d
children be39660919a5
files genshi/core.py genshi/input.py genshi/template/base.py genshi/template/markup.py
diffstat 4 files changed, 64 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/genshi/core.py
+++ b/genshi/core.py
@@ -219,7 +219,7 @@
 class Attrs(tuple):
     """Immutable sequence type that stores the attributes of an element.
     
-    Ordering of the attributes is preserved, while accessing by name is also
+    Ordering of the attributes is preserved, while access by name is also
     supported.
     
     >>> attrs = Attrs([('href', '#'), ('title', 'Foo')])
@@ -316,6 +316,9 @@
         
         The returned event is a `TEXT` event, the data is the value of all
         attributes joined together.
+        
+        >>> Attrs([('href', '#'), ('title', 'Foo')]).totuple()
+        ('TEXT', u'#Foo', (None, -1, -1))
         """
         return TEXT, u''.join([x[1] for x in self]), (None, -1, -1)
 
@@ -352,6 +355,19 @@
         return '<%s %r>' % (self.__class__.__name__, unicode(self))
 
     def join(self, seq, escape_quotes=True):
+        """Return a `Markup` object which is the concatenation of the strings
+        in the given sequence, where this `Markup` object is the separator
+        between the joined elements.
+        
+        Any element in the sequence that is not a `Markup` instance is
+        automatically escaped.
+        
+        :param seq: the sequence of strings to join
+        :param escape_quotes: whether double quote characters in the elements
+                              should be escaped
+        :return: the joined `Markup` object
+        :see: `escape`
+        """
         return Markup(unicode(self).join([escape(item, quotes=escape_quotes)
                                           for item in seq]))
 
@@ -359,9 +375,21 @@
         """Create a Markup instance from a string and escape special characters
         it may contain (<, >, & and \").
         
+        >>> escape('"1 < 2"')
+        <Markup u'&#34;1 &lt; 2&#34;'>
+        
         If the `quotes` parameter is set to `False`, the \" character is left
         as is. Escaping quotes is generally only required for strings that are
         to be used in attribute values.
+        
+        >>> escape('"1 < 2"', quotes=False)
+        <Markup u'"1 &lt; 2"'>
+        
+        :param text: the text to escape
+        :param quotes: if ``True``, double quote characters are escaped in
+                       addition to the other special characters
+        :return: the escaped `Markup` string
+        :see: `genshi.core.escape`
         """
         if not text:
             return cls()
@@ -376,7 +404,13 @@
     escape = classmethod(escape)
 
     def unescape(self):
-        """Reverse-escapes &, <, > and \" and returns a `unicode` object."""
+        """Reverse-escapes &, <, >, and \" and returns a `unicode` object.
+        
+        >>> Markup('1 &lt; 2').unescape()
+        u'1 < 2'
+        
+        :see: `genshi.core.unescape`
+        """
         if not self:
             return u''
         return unicode(self).replace('&#34;', '"') \
@@ -389,20 +423,37 @@
         replaced by the equivalent UTF-8 characters.
         
         If the `keepxmlentities` parameter is provided and evaluates to `True`,
-        the core XML entities (&amp;, &apos;, &gt;, &lt; and &quot;) are not
-        stripped.
+        the core XML entities (``&amp;``, ``&apos;``, ``&gt;``, ``&lt;`` and
+        ``&quot;``) are not stripped.
+        
+        :see: `genshi.util.stripentities`
         """
         return Markup(stripentities(self, keepxmlentities=keepxmlentities))
 
     def striptags(self):
-        """Return a copy of the text with all XML/HTML tags removed."""
+        """Return a copy of the text with all XML/HTML tags removed.
+        
+        :see: `genshi.util.striptags`
+        """
         return Markup(striptags(self))
 
 
 escape = Markup.escape
 
 def unescape(text):
-    """Reverse-escapes &, <, > and \" and returns a `unicode` object."""
+    """Reverse-escapes &, <, >, and \" and returns a `unicode` object.
+    
+    >>> unescape(Markup('1 &lt; 2'))
+    u'1 < 2'
+    
+    If the provided `text` object is not a `Markup` instance, the text is
+    returned as-is.
+    
+    >>> unescape('1 &lt; 2')
+    '1 &lt; 2'
+    
+    :param text: the text to unescape
+    """
     if not isinstance(text, Markup):
         return text
     return text.unescape()
--- a/genshi/input.py
+++ b/genshi/input.py
@@ -23,7 +23,6 @@
     from sets import ImmutableSet as frozenset
 import HTMLParser as html
 import htmlentitydefs
-import os
 from StringIO import StringIO
 
 from genshi.core import Attrs, QName, Stream, stripentities
@@ -68,7 +67,7 @@
         """
         self.msg = message
         if filename:
-            message += ', in ' + os.path.basename(filename)
+            message += ', in ' + filename
         Exception.__init__(self, message)
         self.filename = filename or '<string>'
         self.lineno = lineno
--- a/genshi/template/base.py
+++ b/genshi/template/base.py
@@ -23,6 +23,7 @@
 from StringIO import StringIO
 
 from genshi.core import Attrs, Stream, StreamEventKind, START, TEXT, _ensure
+from genshi.input import ParseError
 
 __all__ = ['Context', 'Template', 'TemplateError', 'TemplateRuntimeError',
            'TemplateSyntaxError', 'BadDirectiveError']
@@ -235,7 +236,10 @@
             source = StringIO(source)
         else:
             source = source
-        self.stream = list(self._prepare(self._parse(source, encoding)))
+        try:
+            self.stream = list(self._prepare(self._parse(source, encoding)))
+        except ParseError, e:
+            raise TemplateSyntaxError(e.msg, self.filepath, e.lineno, e.offset)
         self.filters = [self._flatten, self._eval]
 
     def __repr__(self):
--- a/genshi/template/markup.py
+++ b/genshi/template/markup.py
@@ -87,7 +87,7 @@
         include_href = None
 
         if not isinstance(source, Stream):
-            source = XMLParser(source, filename=self.filepath,
+            source = XMLParser(source, filename=self.filename,
                                encoding=encoding)
 
         for kind, data, pos in source:
Copyright (C) 2012-2017 Edgewall Software