Mercurial > genshi > genshi-test
changeset 433:6d01e91f2a49
More API docs.
author | cmlenz |
---|---|
date | Thu, 22 Mar 2007 21:12:03 +0000 |
parents | 3879c9ad3472 |
children | e065d7906b68 |
files | genshi/builder.py genshi/input.py genshi/util.py |
diffstat | 3 files changed, 114 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/genshi/builder.py +++ b/genshi/builder.py @@ -70,7 +70,7 @@ from genshi.core import Attrs, Namespace, QName, Stream, START, END, TEXT -__all__ = ['Fragment', 'Element', 'tag'] +__all__ = ['Fragment', 'Element', 'ElementFactory', 'tag'] __docformat__ = 'restructuredtext en' @@ -81,12 +81,17 @@ __slots__ = ['children'] def __init__(self): + """Create a new fragment.""" self.children = [] def __add__(self, other): return Fragment()(self, other) def __call__(self, *args): + """Append any positional arguments as child nodes. + + :see: `append` + """ map(self.append, args) return self @@ -103,7 +108,11 @@ return unicode(self.generate()) def append(self, node): - """Append an element or string as child node.""" + """Append an element or string as child node. + + :param node: the node to append; can be an `Element`, `Fragment`, or a + `Stream`, or a Python string or number + """ if isinstance(node, (Stream, Element, basestring, int, float, long)): # For objects of a known/primitive type, we avoid the check for # whether it is iterable for better performance @@ -231,6 +240,11 @@ self.attrib = Attrs(_kwargs_to_attrs(attrib)) def __call__(self, *args, **kwargs): + """Append any positional arguments as child nodes, and keyword arguments + as attributes. + + :see: `Fragment.append` + """ self.attrib |= Attrs(_kwargs_to_attrs(kwargs)) Fragment.__call__(self, *args) return self @@ -295,15 +309,30 @@ self.namespace = namespace def __call__(self, *args): + """Create a fragment that has the given positional arguments as child + nodes. + + :return: the created `Fragment` + """ return Fragment()(*args) def __getitem__(self, namespace): - """Return a new factory that is bound to the specified namespace.""" + """Return a new factory that is bound to the specified namespace. + + :param namespace: the namespace URI or `Namespace` object + :return: an `ElementFactory` that produces elements bound to the given + namespace + """ return ElementFactory(namespace) def __getattr__(self, name): - """Create an `Element` with the given name.""" + """Create an `Element` with the given name. + + :param name: the tag name of the element to create + :return: an `Element` with the specified name + """ return Element(self.namespace and self.namespace[name] or name) tag = ElementFactory() +"""Global `ElementFactory` bound to the default namespace."""
--- a/genshi/input.py +++ b/genshi/input.py @@ -34,7 +34,11 @@ __docformat__ = 'restructuredtext en' def ET(element): - """Convert a given ElementTree element to a markup stream.""" + """Convert a given ElementTree element to a markup stream. + + :param element: an ElementTree element + :return: a markup stream + """ tag_name = QName(element.tag.lstrip('{')) attrs = Attrs([(QName(attr), value) for attr, value in element.items()]) @@ -51,9 +55,17 @@ class ParseError(Exception): """Exception raised when fatal syntax errors are found in the input being - parsed.""" + parsed. + """ def __init__(self, message, filename=None, lineno=-1, offset=-1): + """Exception initializer. + + :param message: the error message from the parser + :param filename: the path to the file that was parsed + :param lineno: the number of the line on which the error was encountered + :param offset: the column number where the error was encountered + """ self.msg = message if filename: message += ', in ' + os.path.basename(filename) @@ -128,6 +140,11 @@ self._queue = [] def parse(self): + """Generator that parses the XML source, yielding markup events. + + :return: a markup event stream + :raises ParseError: if the XML text is not well formed + """ def _generate(): try: bufsize = 4 * 1024 # 4K @@ -237,6 +254,23 @@ def XML(text): + """Parse the given XML source and return a markup stream. + + Unlike with `XMLParser`, the returned stream is reusable, meaning it can be + iterated over multiple times: + + >>> xml = XML('<doc><elem>Foo</elem><elem>Bar</elem></doc>') + >>> print xml + <doc><elem>Foo</elem><elem>Bar</elem></doc> + >>> print xml.select('elem') + <elem>Foo</elem><elem>Bar</elem> + >>> print xml.select('elem/text()') + FooBar + + :param text: the XML source + :return: the parsed XML event stream + :raises ParseError: if the XML text is not well-formed + """ return Stream(list(XMLParser(StringIO(text)))) @@ -277,6 +311,11 @@ self._open_tags = [] def parse(self): + """Generator that parses the HTML source, yielding markup events. + + :return: a markup event stream + :raises ParseError: if the HTML text is not well formed + """ def _generate(): try: bufsize = 4 * 1024 # 4K @@ -368,6 +407,24 @@ def HTML(text, encoding='utf-8'): + """Parse the given HTML source and return a markup stream. + + Unlike with `HTMLParser`, the returned stream is reusable, meaning it can be + iterated over multiple times: + + >>> html = HTML('<body><h1>Foo</h1></body>') + >>> print html + <body><h1>Foo</h1></body> + >>> print html.select('h1') + <h1>Foo</h1> + >>> print html.select('h1/text()') + Foo + + :param text: the HTML source + :return: the parsed XML event stream + :raises ParseError: if the HTML text is not well-formed, and error recovery + fails + """ return Stream(list(HTMLParser(StringIO(text), encoding=encoding))) def _coalesce(stream):
--- a/genshi/util.py +++ b/genshi/util.py @@ -139,7 +139,9 @@ def flatten(items): - """Flattens a potentially nested sequence into a flat list: + """Flattens a potentially nested sequence into a flat list. + + :param items: the sequence to flatten >>> flatten((1, 2)) [1, 2] @@ -159,6 +161,21 @@ def plaintext(text, keeplinebreaks=True): """Returns the text as a `unicode` string with all entities and tags removed. + + >>> plaintext('<b>1 < 2</b>') + u'1 < 2' + + The `keeplinebreaks` parameter can be set to ``False`` to replace any line + breaks by simple spaces: + + >>> plaintext('''<b>1 + ... < + ... 2</b>''', keeplinebreaks=False) + u'1 < 2' + + :param text: the text to convert to plain text + :param keeplinebreaks: whether line breaks in the text should be kept intact + :return: the text with tags and entities removed """ text = stripentities(striptags(text)) if not keeplinebreaks: @@ -208,7 +225,7 @@ _STRIPTAGS_RE = re.compile(r'<[^>]*?>') def striptags(text): - """Return a copy of the text with all XML/HTML tags removed. + """Return a copy of the text with any XML/HTML tags removed. >>> striptags('<span>Foo</span> bar') 'Foo bar' @@ -216,5 +233,8 @@ 'Foo' >>> striptags('Foo<br />') 'Foo' + + :param text: the string to remove tags from + :return: the text with tags removed """ return _STRIPTAGS_RE.sub('', text)