# HG changeset patch # User cmlenz # Date 1155767551 0 # Node ID 7b1f07496bf761a07d9697ec2b8baa68154d3564 # Parent d19e8a2c549e38ec09ee87996d7d88d2ee1f3f3f Various docstring additions and other cosmetic changes. diff --git a/markup/core.py b/markup/core.py --- a/markup/core.py +++ b/markup/core.py @@ -216,7 +216,7 @@ return default def remove(self, name): - """Removes the attribute with the specified name. + """Remove the attribute with the specified name. If no such attribute is found, this method does nothing. """ @@ -226,7 +226,7 @@ break def set(self, name, value): - """Sets the specified attribute to the given value. + """Set the specified attribute to the given value. If an attribute with the specified name is already in the list, the value of the existing entry is updated. Otherwise, a new attribute is @@ -240,6 +240,11 @@ self.append((QName(name), value)) def totuple(self): + """Return the attributes as a markup event. + + The returned event is a TEXT event, the data is the value of all + attributes joined together. + """ return TEXT, u''.join([x[1] for x in self]), (None, -1, -1) diff --git a/markup/path.py b/markup/path.py --- a/markup/path.py +++ b/markup/path.py @@ -431,6 +431,7 @@ # Node tests class PrincipalTypeTest(object): + """Node test that matches any event with the given principal type.""" __slots__ = ['principal_type'] def __init__(self, principal_type): self.principal_type = principal_type @@ -444,6 +445,9 @@ return '*' class LocalNameTest(object): + """Node test that matches any event with the given prinipal type and + local name. + """ __slots__ = ['principal_type', 'name'] def __init__(self, principal_type, name): self.principal_type = principal_type @@ -458,6 +462,7 @@ return self.name class CommentNodeTest(object): + """Node test that matches any comment events.""" __slots__ = [] def __call__(self, kind, data, pos): return kind is COMMENT and (kind, data, pos) @@ -465,6 +470,7 @@ return 'comment()' class NodeTest(object): + """Node test that matches any node.""" __slots__ = [] def __call__(self, kind, data, pos): if kind is START: @@ -474,6 +480,7 @@ return 'node()' class ProcessingInstructionNodeTest(object): + """Node test that matches any processing instruction event.""" __slots__ = ['target'] def __init__(self, target=None): self.target = target @@ -487,6 +494,7 @@ return 'processing-instruction(%s)' % arg class TextNodeTest(object): + """Node test that matches any text event.""" __slots__ = [] def __call__(self, kind, data, pos): return kind is TEXT and (kind, data, pos) @@ -503,6 +511,9 @@ """Base class for function nodes in XPath expressions.""" class BooleanFunction(Function): + """The `boolean` function, which converts its argument to a boolean + value. + """ __slots__ = ['expr'] def __init__(self, expr): self.expr = expr @@ -515,6 +526,9 @@ return 'boolean(%r)' % self.expr class CeilingFunction(Function): + """The `ceiling` function, which returns the nearest lower integer number + for the given number. + """ __slots__ = ['number'] def __init__(self, number): self.number = number @@ -527,6 +541,9 @@ return 'ceiling(%r)' % self.number class ConcatFunction(Function): + """The `concat` function, which concatenates (joins) the variable number of + strings it gets as arguments. + """ __slots__ = ['exprs'] def __init__(self, *exprs): self.exprs = exprs @@ -539,10 +556,13 @@ strings.append(item) return u''.join(strings) def __repr__(self): - return 'concat(%s)' % [repr(expr for expr in self.expr)] + return 'concat(%s)' % [repr(expr for expr in self.exprs)] class ContainsFunction(Function): - __slots__ = ['string1' ,'string2'] + """The `contains` function, which returns whether a string contains a given + substring. + """ + __slots__ = ['string1', 'string2'] def __init__(self, string1, string2): self.string1 = string1 self.string2 = string2 @@ -558,6 +578,7 @@ return 'contains(%r, %r)' % (self.string1, self.string2) class FalseFunction(Function): + """The `false` function, which always returns the boolean `false` value.""" __slots__ = [] def __call__(self, kind, data, pos): return False @@ -565,6 +586,9 @@ return 'false()' class FloorFunction(Function): + """The `ceiling` function, which returns the nearest higher integer number + for the given number. + """ __slots__ = ['number'] def __init__(self, number): self.number = number @@ -577,6 +601,9 @@ return 'floor(%r)' % self.number class LocalNameFunction(Function): + """The `local-name` function, which returns the local name of the current + element. + """ __slots__ = [] def __call__(self, kind, data, pos): if kind is START: @@ -585,6 +612,9 @@ return 'local-name()' class NameFunction(Function): + """The `name` function, which returns the qualified name of the current + element. + """ __slots__ = [] def __call__(self, kind, data, pos): if kind is START: @@ -593,6 +623,9 @@ return 'name()' class NamespaceUriFunction(Function): + """The `namespace-uri` function, which returns the namespace URI of the + current element. + """ __slots__ = [] def __call__(self, kind, data, pos): if kind is START: @@ -601,6 +634,9 @@ return 'namespace-uri()' class NotFunction(Function): + """The `not` function, which returns the negated boolean value of its + argument. + """ __slots__ = ['expr'] def __init__(self, expr): self.expr = expr @@ -610,6 +646,10 @@ return 'not(%s)' % self.expr class NormalizeSpaceFunction(Function): + """The `normalize-space` function, which removes leading and trailing + whitespace in the given string, and replaces multiple adjacent whitespace + characters inside the string with a single space. + """ __slots__ = ['expr'] _normalize = re.compile(r'\s{2,}').sub def __init__(self, expr): @@ -623,6 +663,7 @@ return 'normalize-space(%s)' % repr(self.expr) class NumberFunction(Function): + """The `number` function that converts its argument to a number.""" __slots__ = ['expr'] def __init__(self, expr): self.expr = expr @@ -635,6 +676,9 @@ return 'number(%r)' % self.expr class StartsWithFunction(Function): + """The `starts-with` function that returns whether one string starts with + a given substring. + """ __slots__ = ['string1', 'string2'] def __init__(self, string1, string2): self.string1 = string2 @@ -651,6 +695,9 @@ return 'starts-with(%r, %r)' % (self.string1, self.string2) class StringLengthFunction(Function): + """The `string-length` function that returns the length of the given + string. + """ __slots__ = ['expr'] def __init__(self, expr): self.expr = expr @@ -663,6 +710,9 @@ return 'string-length(%r)' % self.expr class SubstringFunction(Function): + """The `substring` function that returns the part of a string that starts + at the given offset, and optionally limited to the given length. + """ __slots__ = ['string', 'start', 'length'] def __init__(self, string, start, length=None): self.string = string @@ -689,6 +739,9 @@ return 'substring(%r, %r)' % (self.string, self.start) class SubstringAfterFunction(Function): + """The `substring-after` function that returns the part of a string that + is found after the given substring. + """ __slots__ = ['string1', 'string2'] def __init__(self, string1, string2): self.string1 = string1 @@ -708,6 +761,9 @@ return 'substring-after(%r, %r)' % (self.string1, self.string2) class SubstringBeforeFunction(Function): + """The `substring-before` function that returns the part of a string that + is found before the given substring. + """ __slots__ = ['string1', 'string2'] def __init__(self, string1, string2): self.string1 = string1 @@ -727,6 +783,9 @@ return 'substring-after(%r, %r)' % (self.string1, self.string2) class TranslateFunction(Function): + """The `translate` function that translates a set of characters in a + string to target set of characters. + """ __slots__ = ['string', 'fromchars', 'tochars'] def __init__(self, string, fromchars, tochars): self.string = string @@ -750,6 +809,7 @@ self.tochars) class TrueFunction(Function): + """The `true` function, which always returns the boolean `true` value.""" __slots__ = [] def __call__(self, kind, data, pos): return True @@ -775,6 +835,7 @@ """Abstract base class for literal nodes.""" class StringLiteral(Literal): + """A string literal node.""" __slots__ = ['text'] def __init__(self, text): self.text = text @@ -784,6 +845,7 @@ return '"%s"' % self.text class NumberLiteral(Literal): + """A number literal node.""" __slots__ = ['number'] def __init__(self, number): self.number = number @@ -795,70 +857,74 @@ # Operators class AndOperator(object): - __slots__ = ['lval', 'rval'] - def __init__(self, lval, rval): - self.lval = lval - self.rval = rval - def __call__(self, kind, data, pos): - lv = self.lval(kind, data, pos) - if type(lv) is tuple: - lv = lv[1] - if not lv: - return False - rv = self.rval(kind, data, pos) - if type(rv) is tuple: - rv = rv[1] - return bool(rv) - def __repr__(self): - return '%s and %s' % (self.lval, self.rval) - -class EqualsOperator(object): + """The boolean operator `and`.""" __slots__ = ['lval', 'rval'] def __init__(self, lval, rval): self.lval = lval self.rval = rval def __call__(self, kind, data, pos): - lv = self.lval(kind, data, pos) - if type(lv) is tuple: - lv = lv[1] - rv = self.rval(kind, data, pos) - if type(rv) is tuple: - rv = rv[1] - return lv == rv + lval = self.lval(kind, data, pos) + if type(lval) is tuple: + lval = lval[1] + if not lval: + return False + rval = self.rval(kind, data, pos) + if type(rval) is tuple: + rval = rval[1] + return bool(rval) def __repr__(self): - return '%s=%s' % (self.lval, self.rval) + return '%s and %s' % (self.lval, self.rval) -class NotEqualsOperator(object): +class EqualsOperator(object): + """The equality operator `=`.""" __slots__ = ['lval', 'rval'] def __init__(self, lval, rval): self.lval = lval self.rval = rval def __call__(self, kind, data, pos): - lv = self.lval(kind, data, pos) - if type(lv) is tuple: - lv = lv[1] - rv = self.rval(kind, data, pos) - if type(rv) is tuple: - rv = rv[1] - return lv != rv + lval = self.lval(kind, data, pos) + if type(lval) is tuple: + lval = lval[1] + rval = self.rval(kind, data, pos) + if type(rval) is tuple: + rval = rval[1] + return lval == rval def __repr__(self): - return '%s!=%s' % (self.lval, self.rval) + return '%s=%s' % (self.lval, self.rval) -class OrOperator(object): +class NotEqualsOperator(object): + """The equality operator `!=`.""" __slots__ = ['lval', 'rval'] def __init__(self, lval, rval): self.lval = lval self.rval = rval def __call__(self, kind, data, pos): - lv = self.lval(kind, data, pos) - if type(lv) is tuple: - lv = lv[1] - if lv: + lval = self.lval(kind, data, pos) + if type(lval) is tuple: + lval = lval[1] + rval = self.rval(kind, data, pos) + if type(rval) is tuple: + rval = rval[1] + return lval != rval + def __repr__(self): + return '%s!=%s' % (self.lval, self.rval) + +class OrOperator(object): + """The boolean operator `or`.""" + __slots__ = ['lval', 'rval'] + def __init__(self, lval, rval): + self.lval = lval + self.rval = rval + def __call__(self, kind, data, pos): + lval = self.lval(kind, data, pos) + if type(lval) is tuple: + lval = lval[1] + if lval: return True - rv = self.rval(kind, data, pos) - if type(rv) is tuple: - rv = rv[1] - return bool(rv) + rval = self.rval(kind, data, pos) + if type(rval) is tuple: + rval = rval[1] + return bool(rval) def __repr__(self): return '%s or %s' % (self.lval, self.rval) diff --git a/markup/plugin.py b/markup/plugin.py --- a/markup/plugin.py +++ b/markup/plugin.py @@ -18,20 +18,22 @@ from pkg_resources import resource_filename -from markup import Stream, QName +from markup.core import Attributes, Stream, QName from markup.template import Context, Template, TemplateLoader -def ET(element): +def et_to_stream(element): + """Converts the given ElementTree element to a markup stream.""" tag_name = element.tag if tag_name.startswith('{'): tag_name = tag_name[1:] tag_name = QName(tag_name) + attrib = Attributes(element.items()) - yield (Stream.START, (tag_name, element.items()), (None, -1, -1)) + yield (Stream.START, (tag_name, attrib), (None, -1, -1)) if element.text: yield Stream.TEXT, element.text, (None, -1, -1) for child in element.getchildren(): - for item in ET(child): + for item in et_to_stream(child): yield item yield Stream.END, tag_name, (None, -1, -1) if element.tail: @@ -69,7 +71,7 @@ if not isinstance(template, Template): template = self.load_template(template) - data = {'ET': ET} + data = {'ET': et_to_stream} if self.get_extra_vars: data.update(self.get_extra_vars()) data.update(info) diff --git a/markup/template.py b/markup/template.py --- a/markup/template.py +++ b/markup/template.py @@ -166,6 +166,7 @@ def _apply_directives(stream, ctxt, directives): + """Apply the given directives to the stream.""" if directives: stream = directives[0](iter(stream), ctxt, directives[1:]) return stream