root/livinglogic.python.www/site/Python_xmlns.py @ 587:1e1cb3bbd9d5

Revision 587:1e1cb3bbd9d5, 42.1 KB (checked in by Walter Doerwald <walter@…>, 11 years ago)

Remove xpit.

Line 
1# -*- coding: iso-8859-1 -*-
2
3
4from __future__ import with_statement
5
6import sys, types, inspect
7
8from ll import misc, url
9from ll.xist import xsc, sims, parsers
10from ll.xist.ns import html, chars, htmlspecials, specials, abbr, meta, doc, code, xml
11
12
13xmlns = "http://xmlns.livinglogic.de/Python"
14
15
16class Page(object):
17    """
18    A webpage in the sitemap tree.
19    This is an abstract class, that provides common
20    functionality for derived classes.
21    """
22
23    class keywords(misc.propclass):
24        def __get__(self):
25            keywords = list(self.localkeywords)
26            page = self
27            while page is not None:
28                for keyword in page.inheritablekeywords:
29                    if keyword not in keywords:
30                        keywords.append(keyword)
31                page = page.parent
32            return keywords
33
34    @misc.notimplemented
35    def getChildByIndex(self, index):
36        pass
37
38    @misc.notimplemented
39    def getChildByName(self, index):
40        pass
41
42    def getFirstSibling(self):
43        parent = self.parent
44        if parent is None:
45            return None
46        else:
47            return parent.getChildByIndex(0)
48
49    def getPrevSibling(self):
50        parent = self.parent
51        if parent is None:
52            return None
53        else:
54            sibling = None
55            for child in parent.getChildren():
56                if child is self:
57                    break
58                sibling = child
59            return sibling
60
61    def getNextSibling(self):
62        parent = self.parent
63        if parent is None:
64            return None
65        else:
66            sibling = None
67            for child in parent.getChildren():
68                if child is self:
69                    sibling = self
70                elif sibling is not None:
71                    return child
72                else:
73                    sibling = None
74            return None
75
76    def getLastSibling(self):
77        parent = self.parent
78        if parent is None:
79            return None
80        else:
81            return parent.getChildByIndex(-1)
82
83    @misc.notimplemented
84    def __len__(self):
85        pass
86
87    def getChildren(self):
88        children = []
89        index = 0
90        while True:
91            try:
92                children.append(self.getChildByIndex(index))
93            except IndexError:
94                break
95            index + 1
96        return children
97
98    def walk(self):
99        yield self
100        for child in self.getChildren():
101            for page in child.walk():
102                yield page
103
104    def __getitem__(self, index):
105        if isinstance(index, (int, long)):
106            return self.getChildByIndex(index)
107        elif isinstance(index, basestring):
108            if index=="":
109                index = []
110            else:
111                index = index.split("/")
112        if isinstance(index, (list, tuple)):
113            result = self
114            for i in index:
115                if isinstance(i, (int, long)):
116                    result = result.getChildByIndex(i)
117                elif isinstance(i, basestring):
118                    result = result.getChildByName(i)
119                else:
120                    raise TypeError("illegal index type %r" % type(i))
121            return result
122        else:
123            raise TypeError("wrong type %s for index (must be int, long, string, unicode or tuple)" % type(index))
124
125    def getPath(self):
126        path = []
127        page = self
128        while page is not None:
129            path.insert(0, page)
130            page = page.parent
131        return path
132
133    def getPathString(self):
134        return "/".join([ page.name for page in self.getPath() if page.parent])
135
136    def getRoot(self):
137        """
138        return the root page (i.e. the one without a parent)
139        """
140        parent = self
141        while 1:
142            testparent = parent.parent
143            if testparent is None:
144                return parent
145            parent = testparent
146
147    def __repr__(self):
148        return '<%s object path="%s" at 0x%x>' % (self.__class__.__name__, self.getPathString(), id(self))
149
150    def alternates(self):
151        return []
152
153
154class StaticPage(Page):
155    """
156    A webpage in the sitemap tree
157    """
158    def __init__(self, name, *children, **attrs):
159        self.parent = None
160        self.name = name
161        self.title = None
162        self.crumb = None
163        self.url = None
164        self.header = None
165        self.subheader = None
166        self.localkeywords = []
167        self.inheritablekeywords = []
168        self.linktitle = None
169        self.description = None
170        for (k, v) in attrs.items():
171            if k=="crumb":
172                self.crumb = v
173            elif k=="url":
174                self.url = v
175            elif k=="title":
176                self.title = v
177            elif k=="header":
178                self.header = v
179            elif k=="subheader":
180                self.subheader = v
181            elif k=="localkeywords":
182                self.localkeywords = v
183            elif k=="inheritablekeywords":
184                self.inheritablekeywords = v
185            elif k=="linktitle":
186                self.linktitle = v
187            elif k=="description":
188                self.description = u" ".join(v.strip().split())
189            else:
190                raise ValueError("unknown keyword %s" % k)
191        for child in children:
192            child.parent = self # this creates a cycle
193        self.__children = list(children)
194
195    def getChildByIndex(self, index):
196        return self.__children[index]
197
198    def getChildByName(self, index):
199        for child in self.__children:
200            if child.name == index:
201                return child
202        raise KeyError("unknown child %r in page %r" % (index, self.getPathString()))
203
204    def getChildren(self):
205        return self.__children
206
207    def __len__(self):
208        return len(self.__children)
209
210
211class XISTPage(StaticPage):
212    def alternates(self):
213        alternates = super(XISTPage, self).alternates()
214
215        url = self.url
216        pos = url.rfind(".")
217        if pos>=0:
218            txturl = url[:pos+1] + "txt"
219            xmlurl = url[:pos+1] + "htmlxsc"
220        else:
221            txturl = url + ".txt"
222            xmlurl = url + ".htmlxsc"
223
224        return [
225            html.a("Text", href=txturl, rel="alternate", type="text/plain", title="A plain text version of this page"),
226            html.a("XIST", href=xmlurl, rel="alternate", type="text/xml", title=("The ", abbr.xist(), " source of this page"))
227        ] + alternates
228
229
230class PythonSourcePage(XISTPage):
231    def alternates(self):
232        alternates = super(PythonSourcePage, self).alternates()
233        url = self.url
234        if url.endswith(".html"):
235            url = url[:-5] + "_module.py"
236        else:
237            url = url + "_module.py"
238        return alternates + [html.a("Python", href=url, rel="alternate", type="text/x-python", title="The Python module described in this page")]
239
240
241pages = XISTPage(u"python",
242    PythonSourcePage(u"xist",
243        XISTPage(u"examples",
244            crumb=u"Examples",
245            title=(abbr.xist(), u" examples · Python software · LivingLogic AG"),
246            header=(abbr.xist(), u" examples"),
247            subheader=(u"An introduction to ", abbr.xist(), u" by examples"),
248            url=u"root:xist/Examples.html",
249            localkeywords=[],
250            linktitle=u"XIST examples: Parsing/creating/modifying XML; Traversing XML trees"
251        ),
252        XISTPage(u"howto",
253            crumb=u"Howto",
254            title=(abbr.xist(), u" howto · Python software · LivingLogic AG"),
255            header=(abbr.xist(), u" howto"),
256            subheader=(u"A quick tour of ", abbr.xist()),
257            url=u"root:xist/Howto.html",
258            localkeywords=[],
259            linktitle=u"""
260            A quick tour of XIST: Explains parsing/generating XML files,
261            XML transformations via XIST classes and other basic concepts.
262            """
263        ),
264        XISTPage(u"searching",
265            crumb=u"Searching",
266            title=(u"Searching ", abbr.xist(), u" trees · Python software · LivingLogic AG"),
267            header=("Searching ", abbr.xist(), u" trees"),
268            subheader=("Searching, tree traversal, xfind and ", abbr.css(), " selectors"),
269            url=u"root:xist/Searching.html",
270            localkeywords=["searching", "traversal", "xfind", "css"],
271            linktitle=u"""
272            How to iterate through XIST trees
273            """
274        ),
275        XISTPage(u"transformation",
276            crumb=u"Transformation",
277            title=("Transforming ", abbr.xist(), u" trees · Python software · LivingLogic AG"),
278            header=("Transforming ", abbr.xist(), u" trees"),
279            subheader=("The ", doc.func("mapped"), " function, sorting, etc."),
280            url=u"root:xist/Transformation.html",
281            localkeywords=[],
282            linktitle=u"""
283            How to transform XIST trees
284            """
285        ),
286        XISTPage(u"advanced",
287            crumb=u"Advanced topics",
288            title=("Advanced ", abbr.xist(), u" · Python software · LivingLogic AG"),
289            header=("Advanced ", abbr.xist()),
290            subheader="Converter contexts, pool chaining, namespace extensions, conversion targets, validation",
291            url=u"root:xist/Advanced.html",
292            localkeywords=[],
293            linktitle=u"""
294            Advanced XIST features: pool chaining, converter contexts, validation
295            """
296        ),
297        XISTPage(u"misc",
298            crumb=u"Miscellaneous",
299            title=(abbr.xist(), u" miscellaneous · Python software · LivingLogic AG"),
300            header=(abbr.xist(), u" miscellaneous"),
301            subheader=(abbr.url(), u"s, pretty printing, image sizes, embedding Python code"),
302            url=u"root:xist/Misc.html",
303            localkeywords=[],
304            linktitle=u"""
305            Explains various odds and ends of XIST
306            """
307        ),
308        PythonSourcePage(u"xsc",
309            crumb=u"xsc",
310            title=(abbr.xist(), u".xsc · Python software · LivingLogic AG"),
311            header=(abbr.xist(), u".xsc"),
312            subheader=(abbr.xist(), u" core classes"),
313            url=u"root:xist/xsc/index.html",
314            linktitle=u"Module ll.xist.xsc: XIST core classes"
315        ),
316        PythonSourcePage(u"ns",
317            PythonSourcePage(u"html",
318                crumb=u"html",
319                title=(abbr.xist(), u".ns.html · Python software · LivingLogic AG"),
320                header=(abbr.xist(), u".ns.html"),
321                subheader=(u"Module implementing ", abbr.html(), u" 4.01 (with additions)"),
322                url=u"root:xist/ns/html/index.html",
323                linktitle=u"Module ll.xist.ns.html: HTML namespace",
324            ),
325            PythonSourcePage(u"xml",
326                crumb=u"xml",
327                title=(abbr.xist(), u".ns.xml · Python software · LivingLogic AG"),
328                header=(abbr.xist(), u".ns.xml"),
329                subheader=(u"Module for global attributes from the ", abbr.xml(), u" namespace"),
330                url=u"root:xist/ns/xml/index.html",
331                linktitle=u"Module ll.xist.ns.xml: Namespace implementing global XML attributes",
332            ),
333            PythonSourcePage(u"wml",
334                crumb=u"wml",
335                title=(abbr.xist(), u".ns.wml · Python software · LivingLogic AG"),
336                header=(abbr.xist(), u".ns.wml"),
337                subheader=(u"Module implementing ", abbr.wml(), u" 1.3"),
338                url=u"root:xist/ns/wml/index.html",
339                linktitle=u"Module ll.xist.ns.wml: WML 1.3 namespace",
340            ),
341            PythonSourcePage(u"ihtml",
342                crumb=u"ihtml",
343                title=(abbr.xist(), u".ns.ihtml · Python software · LivingLogic AG"),
344                header=(abbr.xist(), u".ns.ihtml"),
345                subheader=(u"Module module implementing i-mode compatible ", abbr.html()),
346                url=u"root:xist/ns/ihtml/index.html",
347                linktitle=u"Module ll.xist.ns.ihtml: Namespace implementing i-mode compatible HTML",
348            ),
349            PythonSourcePage(u"docbook",
350                crumb=u"docbook",
351                title=(abbr.xist(), u".ns.docbook · Python software · LivingLogic AG"),
352                header=(abbr.xist(), u".ns.docbook"),
353                subheader=u"Namespace module implementing DocBook 4.3",
354                url=u"root:xist/ns/docbook/index.html",
355                linktitle=u"Module ll.xist.ns.docbook: Namespace implementing DocBook 4.3",
356            ),
357            PythonSourcePage(u"svg",
358                crumb=u"svg",
359                title=(abbr.xist(), u".ns.svg · Python software · LivingLogic AG"),
360                header=(abbr.xist(), u".ns.svg"),
361                subheader=(u"Namespace module implementing ", abbr.svg(), u" 1.0"),
362                url=u"root:xist/ns/svg/index.html",
363                linktitle=u"Module ll.xist.ns.svg: Namespace implementing SVG 1.0",
364            ),
365            PythonSourcePage(u"abbr",
366                crumb=u"abbr",
367                title=(abbr.xist(), u".ns.abbr · Python software · LivingLogic AG"),
368                header=(abbr.xist(), u".ns.abbr"),
369                subheader=u"Namespace module containing many abbreviation entities",
370                url=u"root:xist/ns/abbr/index.html",
371                linktitle=u"Module ll.xist.ns.abbr: Namespace containing abbreviation entities",
372            ),
373            PythonSourcePage(u"code",
374                crumb=u"code",
375                title=(abbr.xist(), u".ns.code · Python software · LivingLogic AG"),
376                header=(abbr.xist(), u".ns.code"),
377                subheader=(u"Namespace module for embedding Python code in ", abbr.xml()),
378                url=u"root:xist/ns/code/index.html",
379                linktitle=u"Module ll.xist.ns.code: Namespace for embedding Python code in XML",
380            ),
381            PythonSourcePage(u"form",
382                crumb=u"form",
383                title=(abbr.xist(), u".ns.form · Python software · LivingLogic AG"),
384                header=(abbr.xist(), u".ns.form"),
385                subheader=u"Namespace module implementing form related elements",
386                url=u"root:xist/ns/form/index.html",
387                linktitle=u"Module ll.xist.ns.form: Namespace implementing form related elements",
388            ),
389            PythonSourcePage(u"php",
390                crumb=u"php",
391                title=(abbr.xist(), u".ns.php · Python software · LivingLogic AG"),
392                header=(abbr.xist(), u".ns.php"),
393                subheader=(u"Namespace module for PHP processing instructions"),
394                url=u"root:xist/ns/php/index.html",
395                linktitle=u"Module ll.xist.ns.php: Namespace for PHP processing instructions",
396            ),
397            PythonSourcePage(u"jsp",
398                crumb=u"jsp",
399                title=(abbr.xist(), u".ns.jsp · Python software · LivingLogic AG"),
400                header=(abbr.xist(), u".ns.jsp"),
401                subheader=(u"Namespace module for embedding ", abbr.jsp(), u" code as processing instructions"),
402                url=u"root:xist/ns/jsp/index.html",
403                linktitle=u"Module ll.xist.ns.jsp: Namespace for JSP code as processing instructions",
404            ),
405            PythonSourcePage(u"meta",
406                crumb=u"meta",
407                title=(abbr.xist(), u".ns.meta · Python software · LivingLogic AG"),
408                header=(abbr.xist(), u".ns.meta"),
409                subheader=u"Namespace module containing meta information elements",
410                url=u"root:xist/ns/meta/index.html",
411                linktitle=u"Module ll.xist.ns.meta: Namespace containing meta information elements",
412            ),
413            PythonSourcePage(u"ruby",
414                crumb=u"ruby",
415                title=(abbr.xist(), u".ns.ruby · Python software · LivingLogic AG"),
416                header=(abbr.xist(), u".ns.ruby"),
417                subheader=u"Namespace implementing the W3C ruby draft",
418                url=u"root:xist/ns/ruby/index.html",
419                linktitle=u"Module ll.xist.ns.ruby: Namespace implementing the W3C ruby draft",
420            ),
421            PythonSourcePage(u"specials",
422                crumb=u"specials",
423                title=(abbr.xist(), u".ns.specials · Python software · LivingLogic AG"),
424                header=(abbr.xist(), u".ns.specials"),
425                subheader=u"Common useful elements",
426                url=u"root:xist/ns/specials/index.html",
427                linktitle=u"Module ll.xist.ns.specials: Common useful elements",
428            ),
429            PythonSourcePage(u"htmlspecials",
430                crumb=u"htmlspecials",
431                title=(abbr.xist(), u".ns.htmlspecials · Python software · LivingLogic AG"),
432                header=(abbr.xist(), u".ns.htmlspecials"),
433                subheader=(u"Common useful elements for ", abbr.html(), u" generation"),
434                url=u"root:xist/ns/htmlspecials/index.html",
435                linktitle=u"Module ll.xist.ns.htmlspecials: Common useful elements for HTML generation",
436            ),
437            PythonSourcePage(u"doc",
438                crumb=u"doc",
439                title=(abbr.xist(), u".ns.doc · Python software · LivingLogic AG"),
440                header=(abbr.xist(), u".ns.doc"),
441                subheader=u"Namespace module for automated documentation generation",
442                url=u"root:xist/ns/doc/index.html",
443                linktitle=u"Module ll.xist.ns.doc: Namespace for automated documentation generation",
444            ),
445            PythonSourcePage(u"kid",
446                crumb=u"kid",
447                title=(abbr.xist(), u".ns.kid · Python software · LivingLogic AG"),
448                header=(abbr.xist(), u".ns.kid"),
449                subheader=u"Namespace module for Kid templates",
450                url=u"root:xist/ns/kid/index.html",
451                linktitle=u"Module ll.xist.ns.kid: Namespace for Kid templates",
452            ),
453            PythonSourcePage(u"detox",
454                crumb=u"detox",
455                title=(abbr.xist(), u".ns.detox · Python software · LivingLogic AG"),
456                header=(abbr.xist(), u".ns.detox"),
457                subheader=(abbr.xist(), u" based Python templating language"),
458                url=u"root:xist/ns/detox/index.html",
459                linktitle=u"Module ll.xist.ns.detox: Namespace for detox templates",
460            ),
461            PythonSourcePage(u"toxic",
462                crumb=u"toxic",
463                title=(abbr.xist(), u".ns.toxic · Python software · LivingLogic AG"),
464                header=(abbr.xist(), u".ns.toxic"),
465                subheader=(u"Generate Oracle functions from PL/SQL embedded in ", abbr.xml()),
466                url=u"root:xist/ns/toxic/index.html",
467                localkeywords=[u"Oracle", u"user defined function", u"PL/SQL", u"XML", u"HTML", u"processing instruction", u"PI", u"embed"],
468                linktitle=u"Embed PL/SQL in XIST XML",
469                description=u"""
470                toxic is an XIST namespace that can be used for generating Oracle
471                database functions that return XML strings. This is done by
472                embedding processing instructions containing PL/SQL code into XML
473                files and transforming those files with XIST.
474                """,
475            ),
476            PythonSourcePage(u"rng",
477                crumb=u"rng",
478                title=(abbr.xist(), u".ns.rng · Python software · LivingLogic AG"),
479                header=(abbr.xist(), u".ns.rng"),
480                subheader=u"Namespace module for Relax NG",
481                url=u"root:xist/ns/rng/index.html",
482                linktitle=u"Module ll.xist.ns.rng: Namespace for Relax NG",
483            ),
484            PythonSourcePage(u"rss091",
485                crumb=u"rss091",
486                title=(abbr.xist(), u".ns.rss091 · Python software · LivingLogic AG"),
487                header=(abbr.xist(), u".ns.rss091"),
488                subheader=u"Namespace module for RSS 0.91",
489                url=u"root:xist/ns/rss091/index.html",
490                linktitle=u"Module ll.xist.ns.rss091: Namespace for RSS 0.91",
491            ),
492            PythonSourcePage(u"rss20",
493                crumb=u"rss20",
494                title=(abbr.xist(), u".ns.rss20 · Python software · LivingLogic AG"),
495                header=(abbr.xist(), u".ns.rss20"),
496                subheader=u"Namespace module for RSS 2.0",
497                url=u"root:xist/ns/rss20/index.html",
498                linktitle=u"Module ll.xist.ns.rss20: Namespace for RSS 2.0",
499            ),
500            PythonSourcePage(u"atom",
501                crumb=u"atom",
502                title=(abbr.xist(), u".ns.atom · Python software · LivingLogic AG"),
503                header=(abbr.xist(), u".ns.atom"),
504                subheader=u"Namespace module for Atom 1.0",
505                url=u"root:xist/ns/atom/index.html",
506                linktitle=u"Module ll.xist.ns.atom: Namespace for Atom 1.0",
507            ),
508            PythonSourcePage(u"struts_html",
509                crumb=u"struts_html",
510                title=(abbr.xist(), u"ns.struts_html · Python software · LivingLogic AG"),
511                header=(abbr.xist(), u".ns.struts_html"),
512                subheader=(u"Mamespace module implementing the the Struts ", abbr.html(), u" tags"),
513                url=u"root:xist/ns/struts_html/index.html",
514                linktitle=u"Module ll.xist.ns.struts_html: Namespace for Jakarta Struts HTML tags",
515            ),
516            PythonSourcePage(u"struts_config",
517                crumb=u"struts_config",
518                title=(abbr.xist(), u".ns.struts_config · Python software · LivingLogic AG"),
519                header=(abbr.xist(), u".ns.struts_config"),
520                subheader=(u"Namespace module for Struts configuration files"),
521                url=u"root:xist/ns/struts_config/index.html",
522                linktitle=u"Module ll.xist.ns.struts_html: Namespace for Jakarta Struts configuration file tags",
523            ),
524            crumb=u"ns",
525            title=(abbr.xist(), u".ns"),
526            header=(abbr.xist(), u".ns"),
527            subheader=u"Subpackage containing namespace modules",
528            url=u"root:xist/ns/index.html",
529            linktitle=u"Package ll.xist.ns: Contains namespace modules",
530        ),
531        PythonSourcePage(u"parsers",
532            crumb=u"parsers",
533            title=(abbr.xist(), u".parsers · Python software · LivingLogic AG"),
534            header=(abbr.xist(), u".parsers"),
535            subheader=u"Module with classes for parsing files",
536            url=u"root:xist/parsers/index.html",
537            linktitle=u"Module ll.xist.parsers: Parsing XML",
538        ),
539        PythonSourcePage(u"converters",
540            crumb=u"converters",
541            title=(abbr.xist(), u".converters · Python software · LivingLogic AG"),
542            header=(abbr.xist(), u".converters"),
543            subheader=u"Module with the converter class",
544            url=u"root:xist/converters/index.html",
545            linktitle=u"Module ll.xist.converters: Configuring the XML transformation",
546        ),
547        PythonSourcePage(u"presenters",
548            crumb=u"presenters",
549            title=(abbr.xist(), u".presenters · Python software · LivingLogic AG"),
550            header=(abbr.xist(), u".presenters"),
551            subheader=u"Module with classes for printing trees",
552            url=u"root:xist/presenters/index.html",
553            linktitle=u"Module ll.xist.presenters: Screen output of XML trees",
554        ),
555        PythonSourcePage(u"publishers",
556            crumb=u"publishers",
557            title=(abbr.xist(), u".publishers · Python software · LivingLogic AG"),
558            header=(abbr.xist(), u".publishers"),
559            subheader=u"Module with classes for publishing trees",
560            url=u"root:xist/publishers/index.html",
561            linktitle=u"Module ll.xist.publishers: XML output",
562        ),
563        PythonSourcePage(u"sims",
564            crumb=u"sims",
565            title=(abbr.xist(), u".sims · Python software · LivingLogic AG"),
566            header=(abbr.xist(), u".sims"),
567            subheader=u"Simple schema validation",
568            url=u"root:xist/sims/index.html",
569            linktitle=u"Module ll.xist.sims: Simple schema validation",
570        ),
571        PythonSourcePage(u"xfind",
572            crumb=u"xfind",
573            title=(abbr.xist(), u".xfind · Python software · LivingLogic AG"),
574            header=(abbr.xist(), u".xfind"),
575            subheader=u"Tree iteration and filtering",
576            url=u"root:xist/xfind/index.html",
577            linktitle=u"Module ll.xist.xfind: Tree iteration and filtering",
578        ),
579        PythonSourcePage(u"css",
580            crumb=u"css",
581            title=(abbr.xist(), u".css · Python software · LivingLogic AG"),
582            header=(abbr.xist(), u".css"),
583            subheader=(abbr.css(), " related funtions"),
584            url=u"root:xist/css/index.html",
585            linktitle=u"Module ll.xist.css: CSS related functions",
586        ),
587        XISTPage(u"history",
588            XISTPage(u"old",
589                crumb=u"Old history",
590                title=u"Old history · Python software · LivingLogic AG",
591                header=u"Old history",
592                subheader=u"The history before distribution restructuring",
593                url=u"root:xist/OldHistory.html",
594                localkeywords=[u"history", u"changes", u"version"],
595                linktitle=(u"Old ChangeLog for modules merged into ", abbr.xist()),
596            ),
597            crumb=u"History",
598            title=(abbr.xist(), u" history · Python software · LivingLogic AG"),
599            header=(abbr.xist(), u" history"),
600            subheader=u"The development history",
601            url=u"root:xist/History.html",
602            localkeywords=[u"history", u"changes", u"version"],
603            linktitle=u"ChangeLog for XIST",
604        ),
605        XISTPage(u"installation",
606            crumb=u"Installation",
607            title=(abbr.xist(), u" requirements and installation · Python software · LivingLogic AG"),
608            header=(abbr.xist(), u" installation"),
609            subheader=u"Requirements, installation and configuration",
610            url=u"root:xist/Installation.html",
611            localkeywords=[u"installation", u"distutils"],
612            linktitle=u"How to install and configure XIST",
613        ),
614        XISTPage(u"migration",
615            XISTPage(u"old",
616                crumb=u"Old migration info",
617                title=u"Old migration info · Python software · LivingLogic AG",
618                header=u"Old migration info",
619                subheader=u"Migration infomation for old versions before distribution restructuring",
620                url=u"root:xist/OldMigration.html",
621                localkeywords=[u"history", u"changes", u"version"],
622                linktitle=u"Old migration info",
623            ),
624            crumb=u"Migration",
625            title=(abbr.xist(), u" migration guide · Python software · LivingLogic AG"),
626            header=(abbr.xist(), u" migration"),
627            subheader=(u"How to update your code to new versions of ", abbr.xist()),
628            url=u"root:xist/Migration.html",
629            localkeywords=[],
630            linktitle=u"How to update your code to new versions of XIST",
631        ),
632        XISTPage(u"mailinglists",
633            crumb=u"Mailing lists",
634            title=(abbr.xist(), u" mailing lists · Python software · LivingLogic AG"),
635            header=(abbr.xist(), u" mailing lists"),
636            subheader=u"How to subscribe to the mailing lists",
637            url=u"root:xist/Mailinglists.html",
638            localkeywords=[u"mailing list", u"list", u"posting", u"discussion", u"announcement"],
639            linktitle=u"How to subscribe to the XIST mailing lists",
640        ),
641        crumb="ll.xist",
642        title=(abbr.xist(), u" · Python software · LivingLogic AG"),
643        header=abbr.xist(),
644        subheader=(u"An extensible ", abbr.html(), u"/", abbr.xml(), u" generator"),
645        url=u"root:xist/index.html",
646        inheritablekeywords=[abbr.xist(), abbr.xml(), u"transformation", abbr.xsl(), u"hsc"],
647        linktitle=u"Package ll.xist: An extensible XML/HTML generator",
648        description=u"""
649        XIST is an extensible HTML/XML generator written in Python. XIST is also a
650        DOM parser (built on top of SAX2) with a very simple and pythonesque tree
651        API. Every XML element type corresponds to a Python class and these Python
652        classes provide a conversion method to transform the XML tree (e.g. into
653        HTML). XIST can be considered 'object oriented XSL'.
654        """,
655    ),
656    PythonSourcePage(u"ul4",
657        XISTPage(u"howto",
658            crumb=u"Howto",
659            title=u"ll.ul4c howto · Python software · LivingLogic AG",
660            header=u"ll.ul4c documentation",
661            subheader=u"How to use UL4",
662            url=u"root:ul4c/Howto.html",
663            localkeywords=[],
664            linktitle=u"How to use UL4",
665        ),
666        crumb=u"ll.ul4c",
667        title=u"ll.ul4c · Python software · LivingLogic AG",
668        header=u"ll.ul4c",
669        subheader=(u"Crossplatform templating language"),
670        url=u"root:ul4c/index.html",
671        linktitle=u"Module ll.ul4c: A templating language",
672        description=u"""
673        ll.ul4c provides a crossplatform templating language.
674        """,
675    ),
676    PythonSourcePage(u"url",
677        XISTPage(u"howto",
678            crumb=u"Howto",
679            title=u"ll.url howto · Python software · LivingLogic AG",
680            header=u"ll.url documentation",
681            subheader=u"Special features of URL",
682            url=u"root:url/Howto.html",
683            localkeywords=[],
684            linktitle=u"Special features of URL",
685        ),
686        crumb=u"ll.url",
687        title=u"ll.url · Python software · LivingLogic AG",
688        header=u"ll.url",
689        subheader=(u"Module implementing ", abbr.url(), u"s"),
690        url=u"root:url/index.html",
691        linktitle=u"Module ll.url: RFC 2396 compliant URLs",
692        description=u"""
693        ll.url is a Python module that provides classes for parsing and
694        constructing RFC 2396 compliant URLs.
695        """,
696    ),
697    PythonSourcePage(u"make",
698        crumb=u"ll.make",
699        title=u"ll.make · Python software · LivingLogic AG",
700        header=u"ll.make",
701        subheader=u"Object oriented make replacement",
702        url=u"root:make/index.html",
703        localkeywords=[u"make", u"build", u"dependencies", u"development", u"target"],
704        linktitle=u"Module ll.make: Object oriented make replacement",
705        description=u"""
706        ll.make is a Python module that provides an object oriented make replacement.
707        Like make it allows you to specify dependencies between files and actions
708        to be executed when files don't exist or are out of date with respect to
709        one of their sources. But unlike make you can do this in a object oriented
710        way and targets are not only limited to files, but you can implement
711        e.g. dependencies on database records.
712        """,
713    ),
714    PythonSourcePage(u"daemon",
715        crumb=u"ll.daemon",
716        title=u"ll.daemon · Python software · LivingLogic AG",
717        header=u"ll.daemon",
718        subheader=u"Forking daemon processes with Python",
719        url=u"root:daemon/index.html",
720        inheritablekeywords=[u"daemon", u"fork", u"process"],
721        linktitle=u"Module ll.daemon: Forking daemon processes",
722        description=u"""
723        ll.daemon is a Python module that can be used on UNIX to fork a daemon process.
724        """,
725    ),
726    PythonSourcePage(u"sisyphus",
727        crumb=u"ll.sisyphus",
728        title=u"ll.sisyphus · Python software · LivingLogic AG",
729        header=u"ll.sisyphus",
730        subheader=u"Writing cron jobs with Python",
731        url=u"root:sisyphus/index.html",
732        inheritablekeywords=[u"packages", u"Sisyphus", u"cron", u"job"],
733        linktitle=u"Module ll.sisyphus: Writing cron jobs with Python",
734        description=u"""
735        ll.sisyphus is a Python module that simplifies writing Python scripts
736        that run as cron jobs.
737        """,
738    ),
739    PythonSourcePage(u"color",
740        crumb=u"ll.color",
741        title=u"ll.color · Python software · LivingLogic AG",
742        header=u"ll.color",
743        subheader=u"RGB color values and color model conversion",
744        url=u"root:color/index.html",
745        localkeywords=[u"RGB", u"red", u"green", u"blue", u"HSV", u"HSB", u"HSL", u"HLS", u"hue", u"saturation", u"value", u"brightness", u"luminance"],
746        linktitle=u"Module ll.color: RGB color values and color model conversion",
747        description=u"""
748        ll.color is a Python module that provides classes and functions for handling
749        RGB color values. This includes the ability to convert between different
750        color models (RGB, HSV, HLS) as well as to and from CSS format, and several
751        functions for modifying and mixing colors.
752        """,
753    ),
754    PythonSourcePage(u"misc",
755        crumb=u"ll.misc",
756        title=u"ll.misc · Python software · LivingLogic AG",
757        header=u"ll.misc",
758        subheader=u"Miscellaneous utility functions and classes",
759        url=u"root:misc/index.html",
760        localkeywords=[u"utilities", u"decorator", u"property", u"module", u"namespace"],
761        linktitle=u"Module ll.misc: Misc utility functions and classes",
762        description=u"""
763        ll.misc provides serveral utility classes and functions.
764        """,
765    ),
766    PythonSourcePage(u"orasql",
767        XISTPage(u"history",
768            crumb=u"History",
769            title=u"ll.orasql history · Python software · LivingLogic AG",
770            header=u"ll.orasql history",
771            subheader=u"The development history",
772            url=u"root:orasql/History.html",
773            localkeywords=[u"packages", u"history", u"changes", u"version"],
774            linktitle=u"ChangeLog for ll-orasql",
775        ),
776        XISTPage(u"installation",
777            crumb=u"Installation",
778            title=u"ll.orasql installation · Python software · LivingLogic AG",
779            header=u"ll.orasql installation",
780            subheader=u"Requirements and installation",
781            url=u"root:orasql/Installation.html",
782            localkeywords=[u"installation", u"distutils"],
783            linktitle=u"How to install ll-orasql",
784        ),
785        crumb=u"ll.orasql",
786        title=u"ll.orasql · Python software · LivingLogic AG",
787        header=u"ll.orasql",
788        subheader=u"Utilities for working with cx_Oracle",
789        url=u"root:orasql/index.html",
790        localkeywords=[u"Oracle", u"cx_Oracle"],
791        linktitle=u"Module ll.orasql: Utilities for cx_Oracle",
792        description=u"""
793        ll.orasql is a Python module that provides utilities for working with cx_Oracle:
794        It allows calling Oracle procedures via keyword arguments and it wraps the
795        result of fetch calls in a custom dictionary.
796        """,
797    ),
798    PythonSourcePage(u"nightshade",
799        XISTPage(u"history",
800            crumb=u"History",
801            title=u"ll.nightshade history · Python software · LivingLogic AG",
802            header=u"ll.nightshade history",
803            subheader=u"The development history",
804            url=u"root:nightshade/History.html",
805            localkeywords=[u"packages", u"history", u"changes", u"version"],
806            linktitle=u"ChangeLog for ll-nightshade",
807        ),
808        XISTPage(u"installation",
809            crumb=u"Installation",
810            title=u"ll.nightshade installation · Python software · LivingLogic AG",
811            header=u"ll.nightshade installation",
812            subheader=u"Requirements and installation",
813            url=u"root:nightshade/Installation.html",
814            localkeywords=[u"installation", u"distutils"],
815            linktitle=u"How to install ll-nightshade",
816        ),
817        XISTPage(u"migration",
818            crumb=u"Migration",
819            title=(u"nightshade migration guide · Python software · LivingLogic AG"),
820            header=(u"nightshade migration"),
821            subheader=(u"How to update your code to new versions of nightshade"),
822            url=u"root:nightshade/Migration.html",
823            localkeywords=[],
824            linktitle=u"How to update your code to new versions of nightshade",
825        ),
826        crumb=u"ll.nightshade",
827        title=u"ll.nightshade · Python software · LivingLogic AG",
828        header=u"ll.nightshade",
829        subheader=u"Serving the output of Oracle functions/procedures with CherryPy",
830        url=u"root:nightshade/index.html",
831        localkeywords=[u"Oracle", u"cx_Oracle"],
832        linktitle=u"Module ll.nightshade: Serve the output of Oracle functions/procedures with CherryPy",
833        description=u"""
834        ll.orasql is a Python module that provides utilities for working with cx_Oracle:
835        It allows calling Oracle procedures via keyword arguments and it wraps the
836        result of fetch calls in a custom dictionary.
837        """,
838    ),
839    PythonSourcePage(u"aplora",
840        XISTPage(u"history",
841            crumb=u"History",
842            title=u"Aplora history · Python software · LivingLogic AG",
843            header=u"Aplora history",
844            subheader=u"The development history",
845            url=u"root:aplora/History.html",
846            localkeywords=[u"packages", u"history", u"changes", u"version"],
847            linktitle=u"ChangeLog for ll-aplora",
848        ),
849        XISTPage(u"installation",
850            crumb=u"Installation",
851            title=u"Aplora requirements, installation and configuration · Python software · LivingLogic AG",
852            header=u"Aplora installation",
853            subheader=u"Requirements, installation and configuration",
854            url=u"root:aplora/Installation.html",
855            localkeywords=[u"installation", u"distutils"],
856            linktitle=u"How to install ll-aplora",
857        ),
858        crumb=u"Aplora",
859        title=u"Aplora · Python software · LivingLogic AG",
860        header=u"Aplora",
861        subheader=(u"Logging Apache ", abbr.http(), u" requests to an Oracle database"),
862        url=u"root:aplora/index.html",
863        localkeywords=[u"make", u"build", u"dependencies", u"development", u"target"],
864        linktitle=u"Script ll.aplora: Logging Apache HTTP requests to an Oracle database",
865        description=u"""
866        ll-aplora is a script that can be used with Apaches piped logging facility
867        to log HTTP request to an Oracle database.
868        """,
869    ),
870    PythonSourcePage(u"pycoco",
871        XISTPage(u"history",
872            crumb=u"History",
873            title=u"Pycoco history · Python software · LivingLogic AG",
874            header=u"Pycoco history",
875            subheader=u"The development history",
876            url=u"root:pycoco/History.html",
877            localkeywords=[u"packages", u"history", u"changes", u"version"],
878            linktitle=u"ChangeLog for pycoco",
879        ),
880        XISTPage(u"installation",
881            crumb=u"Installation",
882            title=u"Pycoco requirements, installation and configuration · Python software · LivingLogic AG",
883            header=u"Pycoco installation",
884            subheader=u"Requirements, installation and configuration",
885            url=u"root:pycoco/Installation.html",
886            localkeywords=[u"installation", u"distutils"],
887            linktitle=u"How to install pycoco",
888        ),
889        crumb=u"Pycoco",
890        title=u"Pycoco · Python software · LivingLogic AG",
891        header=u"Pycoco",
892        subheader=(u"Python code coverage report"),
893        url=u"root:pycoco/index.html",
894        localkeywords=[u"test", u"Python", "code coverage"],
895        linktitle=u"Script pycoco: Python code coverage",
896        description=u"""
897        A script that can be used to generate code coverage info
898        for the Python source code.
899        """,
900    ),
901    XISTPage(u"download",
902        XISTPage(u"old",
903            crumb=u"Old download",
904            title=u"Old downloads · Python software · LivingLogic AG",
905            header=u"Old downloads",
906            subheader=u"Download old modules as separate distributions",
907            url=u"root:OldDownload.html",
908            localkeywords=[u"download", u"file", u"archive"],
909            linktitle=u"Links to older distributions",
910        ),
911        crumb=u"Download",
912        title=u"Download · Python software · LivingLogic AG",
913        header="Downloads",
914        subheader=u"All versions for download",
915        url=u"root:Download.html",
916        localkeywords=[u"download", u"file", u"archive"],
917        linktitle=u"Links to Windows and Linux, source and binary distributions",
918    ),
919    XISTPage(u"source",
920        crumb=u"Source code",
921        title=u"Source code · Python software · LivingLogic AG",
922        header=u"Source code",
923        subheader=(u"Access to the Mercurial repositories"),
924        url=u"root:Source.html",
925        localkeywords=[u"Mercurial", u"development", u"repository"],
926        linktitle=u"Access to the Mercurial repositories",
927        description=u"""
928        Provides a link to the Mercurial repositories for all
929        Open Source Python projects by LivingLogic.
930        """
931    ),
932    crumb=u"Python software",
933    title=u"Python software · LivingLogic AG",
934    header=u"Python packages",
935    subheader=u"Python packages and modules by LivingLogic",
936    url=u"root:index.html",
937    inheritablekeywords=[u"Living", u"Logic", u"LivingLogic", u"Bayreuth", u"Python"],
938    localkeywords=[u"packages", abbr.xist(), u"sisyphus", u"toxic", u"orasql"],
939    linktitle=u"Startpage with project list",
940    description=u"""
941    LivingLogic provides several Open Source Python packages:
942    XIST, ll-url, ll-make, ll-color, ll-sisyphus, ll-toxic, ll-xpit, ll-orasql
943    """
944)
945
946
947class pageref(xsc.Element):
948    xmlns = xmlns
949    model = sims.NoElements()
950    class Attrs(xsc.Element.Attrs):
951        class ref(xsc.TextAttr): pass
952
953    def convert(self, converter):
954        if "ref" in self.attrs:
955            page = pages[unicode(self.attrs.ref.convert(converter))]
956        else:
957            page = pages
958        e = html.a(self.content, href=page.url, title=page.linktitle)
959        return e.convert(converter)
960
961
962class download(xsc.Element):
963    xmlns = xmlns
964    model = sims.Empty()
965    class Attrs(xsc.Element.Attrs):
966        class version(xsc.TextAttr): pass
967        class date(xsc.TextAttr): pass
968
969    base = "ssh://root@ftp.livinglogic.de/~ftp/pub/livinglogic/"
970
971    def file(self, converter, u):
972        target = converter.target
973        name = u.file
974        if name.endswith(".tar.gz") or name.endswith(".tar.bz2") or name.endswith(".zip"):
975            type = "Source"
976        elif name.endswith(".egg"):
977            if "win32" in name:
978                type = "Windows egg"
979            elif "linux" in name:
980                type = "Linux egg"
981            else:
982                type = "Egg"
983            pos = name.rfind("py")
984            if pos >= 0:
985                version = name[pos+2:pos+5]
986                type += " (Python %s)" % version
987        elif name.endswith(".exe"):
988            type = "Windows installer"
989            pos = name.rfind("py")
990            if pos >= 0:
991                version = name[pos+2:-4]
992                type += " (Python %s)" % version
993        elif name.endswith(".src.rpm"):
994            type = "Source RPM"
995        elif name.endswith(".rpm"):
996            type = "Binary RPM"
997        else:
998            type = chars.nbsp()
999
1000        href = ("http://ftp.livinglogic.de/", u.relative(self.base))
1001        if target.xmlns == doc.xmlns:
1002            e = target.li(target.a(unicode(name), href=href), " (", type,")")
1003        else:
1004            e = html.tr(
1005                html.td(html.a(unicode(name), href=href, title=("Download ", href)), class_="file"),
1006                html.td(type, class_="type"),
1007                html.td(u.size(), class_="size"),
1008                class_="download"
1009            )
1010        return e
1011
1012    def convert(self, converter):
1013        version = str(self.attrs.version.convert(converter))
1014        name = converter[downloads].name
1015        u = url.URL("%s/%s/" % (self.base, name))
1016        files = u/u.files("*-%s[-.][twpz]*" % version)
1017        files = (self.file(converter, f) for f in files)
1018        target = converter.target
1019        if target.xmlns == doc.xmlns:
1020            e = target.section(
1021                target.h("Version ", self.attrs.version, " (released ", self.attrs.date, ")"),
1022                target.ul(files),
1023            )
1024        else:
1025            with xsc.build():
1026                with xsc.Frag() as e:
1027                    with html.tr():
1028                        with html.th(self.attrs.version, class_="version"):
1029                            if "date" in self.attrs:
1030                                xsc.add(" ", html.span("(released ", self.attrs.date, ")", class_="note"))
1031                        +html.th("Type", class_="type")
1032                        +html.th("Bytes", class_="size")
1033                    xsc.add(files)
1034        return e.convert(converter)
1035
1036
1037class downloads(xsc.Element):
1038    xmlns = xmlns
1039    model = sims.Elements(download)
1040    class Attrs(xsc.Element.Attrs):
1041        class name(xsc.TextAttr): pass
1042    class Context(xsc.Element.Context):
1043        pass
1044
1045    def convert(self, converter):
1046        converter[self].name = str(self.attrs.name.convert(converter))
1047        target = converter.target
1048        if target.xmlns == doc.xmlns:
1049            e = self.content
1050        else:
1051            e = html.div(
1052                htmlspecials.plaintable(
1053                    self.content,
1054                    class_="downloads",
1055                ),
1056                align="center"
1057            )
1058        return e.convert(converter)
1059
1060
1061class alldownloads(xsc.Element):
1062    xmlns = xmlns
1063    model = sims.Elements(downloads)
1064
1065    def convert(self, converter):
1066        e = html.div(self.content, class_="alldownloads")
1067        return e.convert(converter)
1068
1069
1070class page(xsc.Element):
1071    xmlns = xmlns
1072    model = sims.Elements(alldownloads, doc.block)
1073    class Attrs(xsc.Element.Attrs):
1074        class refresh(xsc.TextAttr): pass
1075        class path(xsc.TextAttr): pass
1076
1077    def _nodetype(self, path, activepath):
1078        if path[-1] is activepath[-1]:
1079            return "here"
1080        elif path[-1] in activepath:
1081            return "path"
1082        else:
1083            return "other"
1084
1085    def _node(self, path, activepath):
1086        type = self._nodetype(path, activepath)
1087        page = path[-1]
1088        if type == "here":
1089            e = html.div(page.crumb)
1090            children = True
1091        else:
1092            e = html.a(
1093                html.span(u"\u2713", class_=u"visited", title=u"You have already visited that page"),
1094                page.crumb,
1095                href=page.url,
1096                title=page.linktitle,
1097                class_=type,
1098            )
1099            children = (type == "path")
1100        if len(path) > 1:
1101            e = html.li(e, class_=type)
1102        else:
1103            e = xsc.Frag(e)
1104        if children:
1105            e.append(self._children(path, activepath))
1106        return e
1107
1108    def _children(self, path, activepath):
1109        return html.ul(self._node(path + [child], activepath) for child in path[-1].getChildren())
1110
1111    def _links(self, context):
1112        return self._node([pages], context.page.getPath())
1113
1114    def _crumbs(self, context):
1115        e = xsc.Frag()
1116        page = context.page
1117        while page is not None:
1118            if page is context.page:
1119                e.insert(0, html.span(page.crumb, class_=u"here"))
1120            else:
1121                e.insert(0, pageref(page.crumb, ref=page.getPathString()))
1122            e.insert(0, u"\xa0\u203a\xa0")
1123            page = page.parent
1124        e.insert(0, html.a(u"Home", href=u"http://www.livinglogic.de/", hreflang=u"de", title=u"The company homepage (in german)"))
1125        return e
1126
1127    def convert(self, converter):
1128        converter[doc.pyref].base = "root:"
1129        target = converter.target
1130        context = converter[self]
1131        context.path = unicode(self["path"].convert(converter))
1132        context.page = pages[context.path]
1133        if target.xmlns == doc.xmlns:
1134            return self.content.convert(converter)
1135        elif not target.xmlns == html.xmlns:
1136            raise ValueError("unknown conversion target %r" % target)
1137        else:
1138            with xsc.build():
1139                with xsc.Frag(xml.XML(), u"\n", target.DocTypeXHTML10transitional(), u"\n") as e:
1140                    with target.html(xml.Attrs(lang=u"en"), lang=u"en"):
1141                        with target.head():
1142                            +meta.contenttype()
1143                            +target.title(context.page.title)
1144                            if context.page.keywords:
1145                                +meta.keywords(xsc.Frag(*context.page.keywords).withsep(", "))
1146                            if context.page.description is not None:
1147                                +meta.description(context.page.description)
1148                            +meta.stylesheet(href="root:main_screen.css", media=u"screen, projection, tv")
1149                            +meta.stylesheet(href="root:main_print.css", media=u"print")
1150                            +meta.author(name=u"Walter Dörwald", email=u"walter.doerwald@livinglogic.de")
1151                            icbm = u"49.9550; 11.5909"
1152                            +html.meta(name=u"icbm", content=icbm)
1153                            +html.meta(name=u"geo.position", content=icbm)
1154                            +html.meta(name=u"geo.placename", content=u"Bayreuth, Germany, Europe")
1155                            +html.meta(name=u"geo.region", content=u"DE-BY")
1156                            +html.meta(name=u"DC.title", content=context.page.title)
1157                            +html.link(rel=u"icon", href=u"root:images/favicon.gif", type=u"image/gif")
1158                            top = context.page.getRoot()
1159                            if top is not None and top != context.page:
1160                                +html.link(rel="top", href=top.url)
1161                            parent = context.page.parent
1162                            if parent is not None:
1163                                +html.link(rel="up", href=parent.url)
1164                            firstsibling = context.page.getFirstSibling()
1165                            if firstsibling is not None and firstsibling != context.page:
1166                                +html.link(rel="first", title="First page in set", href=firstsibling.url)
1167                            prevsibling = context.page.getPrevSibling()
1168                            if prevsibling is not None and prevsibling != context.page:
1169                                +html.link(rel="prev", title="Previous page", href=prevsibling.url)
1170                            nextsibling = context.page.getNextSibling()
1171                            if nextsibling is not None and nextsibling != context.page:
1172                                +html.link(rel="next", title="Next page", href=nextsibling.url)
1173                            lastsibling = context.page.getLastSibling()
1174                            if lastsibling is not None and lastsibling != context.page:
1175                                +html.link(rel="last", title="Last page in set", href=lastsibling.url)
1176                            for link in context.page.alternates():
1177                                +html.link(link.attrs)
1178                            if "refresh" in self.attrs:
1179                                +html.meta(http_equiv="refresh", content=self.attrs.refresh)
1180
1181                        with target.body():
1182                            with htmlspecials.plaintable(width="100%", class_="body"):
1183                                with html.tr(valign="bottom", class_="header"):
1184                                    +html.td(htmlspecials.pixel(height=150), class_="header1", width="20%")
1185                                    with html.td(class_="header2", width="79%"):
1186                                        if context.page.header:
1187                                            +html.h1(context.page.header)
1188                                        if context.page.subheader:
1189                                            +html.h2(context.page.subheader)
1190                                with html.tr(class_="crumbs"):
1191                                    +html.td(htmlspecials.pixel(), class_="crumbs1")
1192                                    with html.td(class_="crumbs2"):
1193                                        with htmlspecials.plaintable(width="100%"):
1194                                            with html.tr(valign="middle"):
1195                                                +html.td(self._crumbs(context), class_="crumbs")
1196                                                +html.td(xsc.Frag(context.page.alternates()).withsep(u"\xa0\xb7\xa0"), align="right", class_="alternate")
1197                                with html.tr(valign="top", class_="content"):
1198                                    +html.td(htmlspecials.pixel(width=200), self._links(context), rowspan=2, class_="links"),
1199                                    +html.td(self.content, class_="content")
1200        return e.convert(converter)
Note: See TracBrowser for help on using the browser.