root/livinglogic.python.www/site/Python_xmlns.py @ 699:375439711537

Revision 699:375439711537, 49.2 KB (checked in by Walter Doerwald <walter@…>, 6 years ago)

Update to use the new HTML5 sectioning elements.

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