author | Tero Marttila <terom@fixme.fi> |
Fri, 21 Jan 2011 04:44:30 +0200 | |
changeset 61 | ce1d012d02fe |
parent 60 | b364279347d9 |
permissions | -rw-r--r-- |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
1 |
""" |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
2 |
Generate XHTML output from python code. |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
3 |
|
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
4 |
>>> from html import tags |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
5 |
>>> unicode(tags.a(href="http://www.google.com")("Google <this>!")) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
6 |
u'<a href="http://www.google.com">\\n\\tGoogle <this>!\\n</a>' |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
7 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
8 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
9 |
import itertools as itertools |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
10 |
import types as types |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
11 |
from xml.sax import saxutils |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
12 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
13 |
class Renderable (object) : |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
14 |
""" |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
15 |
Structured data that's flattened into indented lines of text. |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
16 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
17 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
18 |
def flatten (self) : |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
19 |
""" |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
20 |
Flatten this object into a series of (identlevel, line) tuples. |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
21 |
""" |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
22 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
23 |
raise NotImplementedError() |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
24 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
25 |
def iter (self, indent='\t') : |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
26 |
""" |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
27 |
Yield a series of lines for this render. |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
28 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
29 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
30 |
for indent_level, line in self.flatten() : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
31 |
yield (indent * indent_level) + line |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
32 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
33 |
def unicode (self, newline=u'\n', **opts) : |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
34 |
""" |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
35 |
Render as a single unicode string. |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
36 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
37 |
No newline is returned at the end of the string. |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
38 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
39 |
>>> Tag.build('a', 'b').unicode(newline='X', indent='Y') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
40 |
u'<a>XYbX</a>' |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
41 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
42 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
43 |
return newline.join(self.iter(**opts)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
44 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
45 |
# required for print |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
46 |
def str (self, newline='\n', encoding='ascii', **opts) : |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
47 |
""" |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
48 |
Render as a single string. |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
49 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
50 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
51 |
# XXX: try and render as non-unicode, i.e. binary data in the tree? |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
52 |
return newline.join(line.encode(encoding) for line in self.iter(**opts)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
53 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
54 |
# formal interface using defaults |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
55 |
__iter__ = iter |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
56 |
__unicode__ = unicode |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
57 |
__str__ = str |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
58 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
59 |
class Text (Renderable) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
60 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
61 |
Plain un-structured/un-processed HTML text for output |
61 | 62 |
|
63 |
>>> Text('foo') |
|
64 |
Text(u'foo') |
|
65 |
>>> list(Text('<foo>')) |
|
66 |
[u'<foo>'] |
|
67 |
>>> list(tag('a', Text('<foo>'))) |
|
68 |
[u'<a>', u'\\t<foo>', u'</a>'] |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
69 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
70 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
71 |
def __init__ (self, text) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
72 |
self.text = unicode(text) |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
73 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
74 |
def flatten (self) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
75 |
yield (0, self.text) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
76 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
77 |
def __repr__ (self) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
78 |
return "Text(%r)" % (self.text, ) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
79 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
80 |
class Tag (Renderable) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
81 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
82 |
An immutable HTML tag structure, with the tag's name, attributes and contents. |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
83 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
84 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
85 |
# types of nested items to flatten |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
86 |
CONTAINER_TYPES = (types.TupleType, types.ListType, types.GeneratorType) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
87 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
88 |
# types of items to keep as-is |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
89 |
ITEM_TYPES = (Renderable, ) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
90 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
91 |
@classmethod |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
92 |
def process_contents (cls, *args) : |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
93 |
""" |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
94 |
Yield the HTML tag's contents from the given sequence of positional arguments as a series of flattened |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
95 |
items, eagerly converting them to unicode. |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
96 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
97 |
If no arguments are given, we don't have any children: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
98 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
99 |
>>> bool(list(Tag.process_contents())) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
100 |
False |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
101 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
102 |
Items that are None will be ignored: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
103 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
104 |
>>> list(Tag.process_contents(None)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
105 |
[] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
106 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
107 |
Various Python container types are recursively flattened: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
108 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
109 |
>>> list(Tag.process_contents([1, 2])) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
110 |
[u'1', u'2'] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
111 |
>>> list(Tag.process_contents([1], [2])) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
112 |
[u'1', u'2'] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
113 |
>>> list(Tag.process_contents([1, [2]])) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
114 |
[u'1', u'2'] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
115 |
>>> list(Tag.process_contents(n + 1 for n in xrange(2))) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
116 |
[u'1', u'2'] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
117 |
>>> list(Tag.process_contents((1, 2))) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
118 |
[u'1', u'2'] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
119 |
>>> list(Tag.process_contents((1), (2, ))) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
120 |
[u'1', u'2'] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
121 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
122 |
Our own HTML-aware objects are returned as-is: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
123 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
124 |
>>> list(Tag.process_contents(Tag.build('foo'))) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
125 |
[tag('foo')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
126 |
>>> list(Tag.process_contents(Text('bar'))) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
127 |
[Text(u'bar')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
128 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
129 |
All other objects are converted to unicode: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
130 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
131 |
>>> list(Tag.process_contents('foo', u'bar', 0.123, False)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
132 |
[u'foo', u'bar', u'0.123', u'False'] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
133 |
|
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
134 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
135 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
136 |
for arg in args : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
137 |
if arg is None : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
138 |
# skip null: None |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
139 |
continue |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
140 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
141 |
elif isinstance(arg, cls.CONTAINER_TYPES) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
142 |
# flatten nested container: tuple/list/generator |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
143 |
for node in arg : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
144 |
# recurse |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
145 |
for item in cls.process_contents(node) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
146 |
yield item |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
147 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
148 |
elif isinstance(arg, cls.ITEM_TYPES) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
149 |
# yield item: Renderable |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
150 |
yield arg |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
151 |
|
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
152 |
else : |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
153 |
# as unicode |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
154 |
yield unicode(arg) |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
155 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
156 |
@classmethod |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
157 |
def process_attrs (cls, **kwargs) : |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
158 |
""" |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
159 |
Yield the HTML tag attributes from the given set of keyword arguments as a series of (name, value) tuples. |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
160 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
161 |
Keyword-only options (`_key=value`) are filtered out: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
162 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
163 |
>>> dict(Tag.process_attrs(_opt=True)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
164 |
{} |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
165 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
166 |
Attributes with a value of None/False are filtered out: |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
167 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
168 |
>>> dict(Tag.process_attrs(foo=None, bar=False)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
169 |
{} |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
170 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
171 |
A value given as True is returned as the key's value: |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
172 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
173 |
>>> dict(Tag.process_attrs(quux=True)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
174 |
{'quux': u'quux'} |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
175 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
176 |
A (single) trailing underscore in the attribute name is removed: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
177 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
178 |
>>> dict(Tag.process_attrs(class_='foo')) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
179 |
{'class': u'foo'} |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
180 |
>>> dict(Tag.process_attrs(data__='foo')) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
181 |
{'data_': u'foo'} |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
182 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
183 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
184 |
for key, value in kwargs.iteritems() : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
185 |
# keyword arguments are always pure strings |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
186 |
assert type(key) is str |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
187 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
188 |
if value is None or value is False: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
189 |
# omit |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
190 |
continue |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
191 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
192 |
if key.startswith('_') : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
193 |
# option |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
194 |
continue |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
195 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
196 |
if key.endswith('_') : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
197 |
# strip underscore |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
198 |
key = key[:-1] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
199 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
200 |
if value is True : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
201 |
# flag attr |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
202 |
value = key |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
203 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
204 |
yield key, unicode(value) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
205 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
206 |
@classmethod |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
207 |
def process_opts (cls, **kwargs) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
208 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
209 |
Return a series of of the keyword-only _options, extracted from the given dict of keyword arguments, as |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
210 |
(k, v) tuples. |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
211 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
212 |
>>> Tag.process_opts(foo='bar', _bar=False) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
213 |
(('bar', False),) |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
214 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
215 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
216 |
return tuple((k.lstrip('_'), v) for k, v in kwargs.iteritems() if k.startswith('_')) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
217 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
218 |
@classmethod |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
219 |
def build (cls, _name, *args, **kwargs) : |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
220 |
""" |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
221 |
Factory function for constructing Tags by directly passing in contents/attributes/options as Python function |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
222 |
arguments/keyword arguments. |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
223 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
224 |
The first positional argument is the tag's name: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
225 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
226 |
>>> Tag.build('foo') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
227 |
tag('foo') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
228 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
229 |
Further positional arguments are the tag's contents: |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
230 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
231 |
>>> Tag.build('foo', 'quux', 'bar') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
232 |
tag('foo', u'quux', u'bar') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
233 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
234 |
All the rules used by process_contents() are available: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
235 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
236 |
>>> Tag.build('foo', [1, None], None, (n for n in xrange(2))) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
237 |
tag('foo', u'1', u'0', u'1') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
238 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
239 |
The special-case for a genexp as the only argument works: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
240 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
241 |
>>> f = lambda *args: Tag.build('foo', *args) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
242 |
>>> f('hi' for n in xrange(2)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
243 |
tag('foo', u'hi', u'hi') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
244 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
245 |
Attributes are passed as keyword arguments, with or without contents: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
246 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
247 |
>>> Tag.build('foo', id=1) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
248 |
tag('foo', id=u'1') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
249 |
>>> Tag.build('foo', 'quux', bar=5) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
250 |
tag('foo', u'quux', bar=u'5') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
251 |
>>> Tag.build('foo', class_='ten') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
252 |
tag('foo', class=u'ten') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
253 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
254 |
The attribute names don't conflict with positional argument names: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
255 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
256 |
>>> Tag.build('bar', name='foo') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
257 |
tag('bar', name=u'foo') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
258 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
259 |
Options are handled as the 'real' keyword arguments: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
260 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
261 |
>>> print Tag.build('foo', _selfclosing=False) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
262 |
<foo></foo> |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
263 |
>>> print Tag.build('foo', _foo='bar') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
264 |
Traceback (most recent call last): |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
265 |
... |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
266 |
TypeError: __init__() got an unexpected keyword argument 'foo' |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
267 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
268 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
269 |
# pre-process incoming user values |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
270 |
contents = list(cls.process_contents(*args)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
271 |
attrs = dict(cls.process_attrs(**kwargs)) |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
272 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
273 |
# XXX: use Python 2.6 keyword-only arguments instead? |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
274 |
options = dict(cls.process_opts(**kwargs)) |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
275 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
276 |
return cls(_name, contents, attrs, **options) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
277 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
278 |
def __init__ (self, name, contents, attrs, selfclosing=None, whitespace_sensitive=None) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
279 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
280 |
Initialize internal Tag state with the given tag identifier, flattened list of content items, dict of |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
281 |
attributes and dict of options. |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
282 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
283 |
selfclosing - set to False to render empty tags as <foo></foo> instead of <foo /> |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
284 |
(for XHTML -> HTML compatibility) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
285 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
286 |
whitespace_sensitive - do not indent tag content onto separate rows, render the full tag as a single |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
287 |
row |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
288 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
289 |
Use the build() factory function to build Tag objects using Python's function call argument semantics. |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
290 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
291 |
The tag name is used a pure string identifier: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
292 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
293 |
>>> Tag(u'foo', [], {}) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
294 |
tag('foo') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
295 |
>>> Tag(u'\\xE4', [], {}) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
296 |
Traceback (most recent call last): |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
297 |
... |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
298 |
UnicodeEncodeError: 'ascii' codec can't encode character u'\\xe4' in position 0: ordinal not in range(128) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
299 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
300 |
Contents have their order preserved: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
301 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
302 |
>>> Tag('foo', [1, 2], {}) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
303 |
tag('foo', 1, 2) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
304 |
>>> Tag('foo', [2, 1], {}) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
305 |
tag('foo', 2, 1) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
306 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
307 |
Attributes can be given: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
308 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
309 |
>>> Tag('foo', [], dict(foo='bar')) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
310 |
tag('foo', foo='bar') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
311 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
312 |
Options can be given: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
313 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
314 |
>>> print Tag('foo', [], {}, selfclosing=False) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
315 |
<foo></foo> |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
316 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
317 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
318 |
self.name = str(name) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
319 |
self.contents = contents |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
320 |
self.attrs = attrs |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
321 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
322 |
# options |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
323 |
self.selfclosing = selfclosing |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
324 |
self.whitespace_sensitive = whitespace_sensitive |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
325 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
326 |
def __call__ (self, *args, **kwargs) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
327 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
328 |
Return a new Tag as a copy of this tag, but with the given additional attributes/contents. |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
329 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
330 |
The same rules for function positional/keyword arguments apply as for build() |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
331 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
332 |
>>> Tag.build('foo')('bar') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
333 |
tag('foo', u'bar') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
334 |
>>> Tag.build('a', href='index.html')("Home") |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
335 |
tag('a', u'Home', href=u'index.html') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
336 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
337 |
New contents and attributes can be given freely, using the same rules as for Tag.build: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
338 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
339 |
>>> Tag.build('bar', None)(5, foo=None, class_='bar') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
340 |
tag('bar', u'5', class=u'bar') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
341 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
342 |
Tag contents accumulate in order: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
343 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
344 |
>>> Tag.build('a')('b', ['c'])('d') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
345 |
tag('a', u'b', u'c', u'd') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
346 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
347 |
Each Tag is immutable, so the called Tag isn't changed, but rather a copy is returned: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
348 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
349 |
>>> t1 = Tag.build('a'); t2 = t1('b'); t1 |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
350 |
tag('a') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
351 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
352 |
Attribute values are replaced: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
353 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
354 |
>>> Tag.build('foo', a=2)(a=3) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
355 |
tag('foo', a=u'3') |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
356 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
357 |
Options are also supported: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
358 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
359 |
>>> list(Tag.build('foo')(bar='quux', _selfclosing=False)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
360 |
[u'<foo bar="quux"></foo>'] |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
361 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
362 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
363 |
# accumulate contents |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
364 |
contents = self.contents + list(self.process_contents(*args)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
365 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
366 |
# merge attrs |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
367 |
attrs = dict(self.attrs) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
368 |
attrs.update(self.process_attrs(**kwargs)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
369 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
370 |
# options |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
371 |
opts = dict( |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
372 |
selfclosing = self.selfclosing, |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
373 |
whitespace_sensitive = self.whitespace_sensitive, |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
374 |
) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
375 |
opts.update(self.process_opts(**kwargs)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
376 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
377 |
# build updated tag |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
378 |
return Tag(self.name, contents, attrs, **opts) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
379 |
|
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
380 |
def render_attrs (self) : |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
381 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
382 |
Return the HTML attributes string |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
383 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
384 |
>>> Tag.build('x', foo=5, bar='<', quux=None).render_attrs() |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
385 |
u'foo="5" bar="<"' |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
386 |
>>> Tag.build('x', foo='a"b').render_attrs() |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
387 |
u'foo=\\'a"b\\'' |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
388 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
389 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
390 |
return " ".join( |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
391 |
( |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
392 |
u'%s=%s' % (name, saxutils.quoteattr(value)) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
393 |
) for name, value in self.attrs.iteritems() |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
394 |
) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
395 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
396 |
def flatten_items (self, indent=1) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
397 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
398 |
Flatten our content into a series of indented lines. |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
399 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
400 |
>>> list(Tag.build('tag', 5).flatten_items()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
401 |
[(1, u'5')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
402 |
>>> list(Tag.build('tag', 'line1', 'line2').flatten_items()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
403 |
[(1, u'line1'), (1, u'line2')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
404 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
405 |
Nested : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
406 |
>>> list(Tag.build('tag', 'a', Tag.build('b', 'bb'), 'c').flatten_items()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
407 |
[(1, u'a'), (1, u'<b>'), (2, u'bb'), (1, u'</b>'), (1, u'c')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
408 |
>>> list(Tag.build('tag', Tag.build('hr'), Tag.build('foo')('bar')).flatten_items()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
409 |
[(1, u'<hr />'), (1, u'<foo>'), (2, u'bar'), (1, u'</foo>')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
410 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
411 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
412 |
for item in self.contents : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
413 |
if isinstance(item, Renderable) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
414 |
# recursively flatten items |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
415 |
for line_indent, line in item.flatten() : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
416 |
# indented |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
417 |
yield indent + line_indent, line |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
418 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
419 |
else : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
420 |
# render HTML-escaped raw value |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
421 |
# escape raw values |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
422 |
yield indent, saxutils.escape(item) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
423 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
424 |
def flatten (self) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
425 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
426 |
Render the tag and all content as a flattened series of indented lines. |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
427 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
428 |
Empty tags collapse per default: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
429 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
430 |
>>> list(Tag.build('foo').flatten()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
431 |
[(0, u'<foo />')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
432 |
>>> list(Tag.build('bar', id=5).flatten()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
433 |
[(0, u'<bar id="5" />')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
434 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
435 |
Values are indented inside the start tag: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
436 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
437 |
>>> list(Tag.build('foo', 'bar', a=5).flatten()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
438 |
[(0, u'<foo a="5">'), (1, u'bar'), (0, u'</foo>')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
439 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
440 |
Nested tags are further indented: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
441 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
442 |
>>> list(Tag.build('1', '1.1', Tag.build('1.2', '1.2.1'), '1.3', a=5).flatten()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
443 |
[(0, u'<1 a="5">'), (1, u'1.1'), (1, u'<1.2>'), (2, u'1.2.1'), (1, u'</1.2>'), (1, u'1.3'), (0, u'</1>')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
444 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
445 |
Empty tags are rendered with a separate closing tag on the same line, if desired: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
446 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
447 |
>>> list(Tag.build('foo', _selfclosing=False).flatten()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
448 |
[(0, u'<foo></foo>')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
449 |
>>> list(Tag.build('foo', src='asdf', _selfclosing=False).flatten()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
450 |
[(0, u'<foo src="asdf"></foo>')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
451 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
452 |
Tags that are declared as whitespace-sensitive are collapsed onto the same line: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
453 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
454 |
>>> list(Tag.build('foo', _whitespace_sensitive=True).flatten()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
455 |
[(0, u'<foo />')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
456 |
>>> list(Tag.build('foo', _whitespace_sensitive=True, _selfclosing=False).flatten()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
457 |
[(0, u'<foo></foo>')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
458 |
>>> list(Tag.build('foo', 'bar', _whitespace_sensitive=True).flatten()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
459 |
[(0, u'<foo>bar</foo>')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
460 |
>>> list(Tag.build('foo', 'bar\\nasdf\\tx', _whitespace_sensitive=True).flatten()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
461 |
[(0, u'<foo>bar\\nasdf\\tx</foo>')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
462 |
>>> list(Tag.build('foo', 'bar', Tag.build('quux', 'asdf'), 'asdf', _whitespace_sensitive=True).flatten()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
463 |
[(0, u'<foo>bar<quux>asdf</quux>asdf</foo>')] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
464 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
465 |
Embedded HTML given as string values is escaped: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
466 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
467 |
>>> list(Tag.build('foo', '<asdf>')) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
468 |
[u'<foo>', u'\\t<asdf>', u'</foo>'] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
469 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
470 |
Embedded quotes in attribute values are esacaped: |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
471 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
472 |
>>> list(Tag.build('foo', style='ok;" onload="...')) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
473 |
[u'<foo style=\\'ok;" onload="...\\' />'] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
474 |
>>> list(Tag.build('foo', style='ok;\\'" onload=..."\\'')) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
475 |
[u'<foo style="ok;\\'" onload=..."\\'" />'] |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
476 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
477 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
478 |
# optional attr spec |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
479 |
if self.attrs : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
480 |
attrs = " " + self.render_attrs() |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
481 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
482 |
else : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
483 |
attrs = "" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
484 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
485 |
if not self.contents and self.selfclosing is False : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
486 |
# empty tag, but don't use the self-closing syntax.. |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
487 |
yield 0, u"<%s%s></%s>" % (self.name, attrs, self.name) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
488 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
489 |
elif not self.contents : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
490 |
# self-closing xml tag |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
491 |
# do note that this is invalid HTML, and the space before the / is relevant for parsing it as HTML |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
492 |
yield 0, u"<%s%s />" % (self.name, attrs) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
493 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
494 |
elif self.whitespace_sensitive : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
495 |
# join together each line for each child, discarding the indent |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
496 |
content = u''.join(line for indent, line in self.flatten_items()) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
497 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
498 |
# render full tag on a single line |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
499 |
yield 0, u"<%s%s>%s</%s>" % (self.name, attrs, content, self.name) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
500 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
501 |
else : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
502 |
# start tag |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
503 |
yield 0, u"<%s%s>" % (self.name, attrs) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
504 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
505 |
# contents, indented one level below the start tag |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
506 |
for indent, line in self.flatten_items(indent=1) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
507 |
yield indent, line |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
508 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
509 |
# close tag |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
510 |
yield 0, u"</%s>" % (self.name, ) |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
511 |
|
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
512 |
def __repr__ (self) : |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
513 |
return 'tag(%s)' % ', '.join( |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
514 |
[ |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
515 |
repr(self.name) |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
516 |
] + [ |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
517 |
repr(c) for c in self.contents |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
518 |
] + [ |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
519 |
'%s=%r' % (name, value) for name, value in self.attrs.iteritems() |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
520 |
] |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
521 |
) |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
522 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
523 |
# factory function for Tag |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
524 |
tag = Tag.build |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
525 |
|
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
526 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
527 |
class Document (Renderable) : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
528 |
""" |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
529 |
A full XHTML 1.0 document with optional XML header, doctype, html[@xmlns]. |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
530 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
531 |
>>> list(Document(tags.html('...'))) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
532 |
[u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">', u'<html xmlns="http://www.w3.org/1999/xhtml">', u'\\t...', u'</html>'] |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
533 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
534 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
535 |
def __init__ (self, root, |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
536 |
doctype='html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"', |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
537 |
html_xmlns='http://www.w3.org/1999/xhtml', |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
538 |
xml_version=None, xml_encoding=None, |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
539 |
) : |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
540 |
# add xmlns attr to root node |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
541 |
self.root = root(xmlns=html_xmlns) |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
542 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
543 |
# store |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
544 |
self.doctype = doctype |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
545 |
self.xml_declaration = {} |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
546 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
547 |
if xml_version : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
548 |
self.xml_declaration['version'] = xml_version |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
549 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
550 |
if xml_encoding : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
551 |
self.xml_declaration['encoding'] = xml_encoding |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
552 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
553 |
def flatten (self) : |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
554 |
""" |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
555 |
Return the header lines along with the normally formatted <html> tag |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
556 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
557 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
558 |
if self.xml_declaration : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
559 |
yield 0, u'<?xml %s ?>' % (' '.join('%s="%s"' % kv for kv in self.xml_declaration.iteritems())) |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
560 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
561 |
if self.doctype : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
562 |
yield 0, u'<!DOCTYPE %s>' % (self.doctype) |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
563 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
564 |
# <html> |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
565 |
for indent, line in self.root.flatten() : |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
566 |
yield indent, line |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
567 |
|
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
568 |
class TagFactory (object) : |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
569 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
570 |
Build Tags with names give as attribute names |
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
571 |
|
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
572 |
>>> list(TagFactory().a(href='#')('Yay')) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
573 |
[u'<a href="#">', u'\\tYay', u'</a>'] |
50
c3ae4c448248
html: add tags.raw pseudo-tag for raw HTML processing
Tero Marttila <terom@fixme.fi>
parents:
8
diff
changeset
|
574 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
575 |
>>> list(TagFactory().raw("><")) |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
576 |
[u'><'] |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
577 |
""" |
58
4f4150296cd3
controllers: tidy up PageHandler a little
Tero Marttila <terom@fixme.fi>
parents:
50
diff
changeset
|
578 |
|
4f4150296cd3
controllers: tidy up PageHandler a little
Tero Marttila <terom@fixme.fi>
parents:
50
diff
changeset
|
579 |
# full XHTML document |
4f4150296cd3
controllers: tidy up PageHandler a little
Tero Marttila <terom@fixme.fi>
parents:
50
diff
changeset
|
580 |
document = Document |
50
c3ae4c448248
html: add tags.raw pseudo-tag for raw HTML processing
Tero Marttila <terom@fixme.fi>
parents:
8
diff
changeset
|
581 |
|
c3ae4c448248
html: add tags.raw pseudo-tag for raw HTML processing
Tero Marttila <terom@fixme.fi>
parents:
8
diff
changeset
|
582 |
# raw HTML |
c3ae4c448248
html: add tags.raw pseudo-tag for raw HTML processing
Tero Marttila <terom@fixme.fi>
parents:
8
diff
changeset
|
583 |
raw = Text |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
584 |
|
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
585 |
def __getattr__ (self, name) : |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
586 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
587 |
Get a Tag object with the given name, but no contents |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
588 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
589 |
>>> TagFactory().a |
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
590 |
tag('a') |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
591 |
""" |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
592 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
593 |
return Tag(name, [], {}) |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
594 |
|
60
b364279347d9
html: refactor and update doctests
Tero Marttila <terom@fixme.fi>
parents:
58
diff
changeset
|
595 |
# static instance |
0
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
596 |
tags = TagFactory() |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
597 |
|
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
598 |
# testing |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
599 |
if __name__ == '__main__' : |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
600 |
import doctest |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
601 |
|
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
602 |
doctest.testmod() |
b28a1681e79b
Initial layout, with hello-world
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
603 |