From jholg at codespeak.net Tue Jul 1 10:44:38 2008 From: jholg at codespeak.net (jholg at codespeak.net) Date: Tue, 1 Jul 2008 10:44:38 +0200 (CEST) Subject: [Lxml-checkins] r56199 - lxml/trunk/src/lxml Message-ID: <20080701084438.C9A3C2D8007@codespeak.net> Author: jholg Date: Tue Jul 1 10:44:37 2008 New Revision: 56199 Modified: lxml/trunk/src/lxml/lxml.objectify.pyx Log: Call to etree.cleanup_namespaces() removed from objectify.deannotate(). Modified: lxml/trunk/src/lxml/lxml.objectify.pyx ============================================================================== --- lxml/trunk/src/lxml/lxml.objectify.pyx (original) +++ lxml/trunk/src/lxml/lxml.objectify.pyx Tue Jul 1 10:44:37 2008 @@ -1752,7 +1752,6 @@ cetree.delAttributeFromNsName( c_node, _XML_SCHEMA_INSTANCE_NS, "type") tree.END_FOR_EACH_ELEMENT_FROM(c_node) - etree.cleanup_namespaces(element) ################################################################################ From jholg at codespeak.net Tue Jul 1 17:47:17 2008 From: jholg at codespeak.net (jholg at codespeak.net) Date: Tue, 1 Jul 2008 17:47:17 +0200 (CEST) Subject: [Lxml-checkins] r56201 - in lxml/trunk/src/lxml: . tests Message-ID: <20080701154717.359552A0194@codespeak.net> Author: jholg Date: Tue Jul 1 17:47:15 2008 New Revision: 56201 Modified: lxml/trunk/src/lxml/lxml.objectify.pyx lxml/trunk/src/lxml/tests/test_objectify.py Log: Support for base_url argument in objectify module functions, with tests. 'base' attribute special-cased in ObjectifiedElement __setattr__ method. Modified: lxml/trunk/src/lxml/lxml.objectify.pyx ============================================================================== --- lxml/trunk/src/lxml/lxml.objectify.pyx (original) +++ lxml/trunk/src/lxml/lxml.objectify.pyx Tue Jul 1 17:47:15 2008 @@ -242,7 +242,10 @@ elif tag == u'tag': ElementBase.tag.__set__(self, value) return - + elif tag == u'base': + c_base = _cstr(value) + tree.xmlNodeSetBase(self._c_node, c_base) + return tag = _buildChildTag(self, tag) element = _lookupChild(self, tag) if element is None: @@ -1811,43 +1814,55 @@ cdef object _fromstring _fromstring = etree.fromstring -def fromstring(xml, parser=None): - u"""fromstring(xml, parser=None) +def fromstring(xml, parser=None, *, base_url=None): + u"""fromstring(xml, parser=None, base_url=None) Objectify specific version of the lxml.etree fromstring() function that uses the objectify parser. You can pass a different parser as second argument. + + The ``base_url`` keyword argument allows to set the original base URL of + the document to support relative Paths when looking up external entities + (DTD, XInclude, ...). """ if parser is None: parser = objectify_parser - return _fromstring(xml, parser) + return _fromstring(xml, parser, base_url=base_url) -def XML(xml, parser=None): - u"""XML(xml, parser=None) +def XML(xml, parser=None, *, base_url=None): + u"""XML(xml, parser=None, base_url=None) Objectify specific version of the lxml.etree XML() literal factory that uses the objectify parser. You can pass a different parser as second argument. + + The ``base_url`` keyword argument allows to set the original base URL of + the document to support relative Paths when looking up external entities + (DTD, XInclude, ...). """ if parser is None: parser = objectify_parser - return _fromstring(xml, parser) + return _fromstring(xml, parser, base_url=base_url) cdef object _parse _parse = etree.parse -def parse(f, parser=None): - u"""parse(f, parser=None) +def parse(f, parser=None, *, base_url=None): + u"""parse(f, parser=None, base_url=None) Parse a file or file-like object with the objectify parser. You can pass a different parser as second argument. + + The ``base_url`` keyword allows setting a URL for the document + when parsing from a file-like object. This is needed when looking + up external entities (DTD, XInclude, ...) with relative paths. """ if parser is None: parser = objectify_parser - return _parse(f, parser) + return _parse(f, parser, base_url=base_url) cdef object _DEFAULT_NSMAP _DEFAULT_NSMAP = { u"py" : PYTYPE_NAMESPACE, Modified: lxml/trunk/src/lxml/tests/test_objectify.py ============================================================================== --- lxml/trunk/src/lxml/tests/test_objectify.py (original) +++ lxml/trunk/src/lxml/tests/test_objectify.py Tue Jul 1 17:47:15 2008 @@ -2337,6 +2337,53 @@ self.assert_(isinstance(root.value[0], objectify.IntElement)) self.assert_(isinstance(root.value[1], objectify.FloatElement)) + def test_XML_base_url_docinfo(self): + root = objectify.XML(_bytes(""), base_url="http://no/such/url") + docinfo = root.getroottree().docinfo + self.assertEquals(docinfo.URL, "http://no/such/url") + + def test_XML_set_base_url_docinfo(self): + root = objectify.XML(_bytes(""), base_url="http://no/such/url") + docinfo = root.getroottree().docinfo + self.assertEquals(docinfo.URL, "http://no/such/url") + docinfo.URL = "https://secret/url" + self.assertEquals(docinfo.URL, "https://secret/url") + + def test_parse_stringio_base_url(self): + tree = objectify.parse(BytesIO(""), base_url="http://no/such/url") + docinfo = tree.docinfo + self.assertEquals(docinfo.URL, "http://no/such/url") + + def test_parse_base_url_docinfo(self): + tree = objectify.parse(fileInTestDir('include/test_xinclude.xml'), + base_url="http://no/such/url") + docinfo = tree.docinfo + self.assertEquals(docinfo.URL, "http://no/such/url") + + def test_xml_base(self): + root = objectify.XML(_bytes(""), base_url="http://no/such/url") + self.assertEquals(root.base, "http://no/such/url") + self.assertEquals( + root.get('{http://www.w3.org/XML/1998/namespace}base'), None) + root.base = "https://secret/url" + self.assertEquals(root.base, "https://secret/url") + self.assertEquals( + root.get('{http://www.w3.org/XML/1998/namespace}base'), + "https://secret/url") + + def test_xml_base_attribute(self): + root = objectify.XML(_bytes(""), base_url="http://no/such/url") + self.assertEquals(root.base, "http://no/such/url") + self.assertEquals( + root.get('{http://www.w3.org/XML/1998/namespace}base'), None) + root.set('{http://www.w3.org/XML/1998/namespace}base', + "https://secret/url") + self.assertEquals(root.base, "https://secret/url") + self.assertEquals( + root.get('{http://www.w3.org/XML/1998/namespace}base'), + "https://secret/url") + + def test_suite(): suite = unittest.TestSuite() suite.addTests([unittest.makeSuite(ObjectifyTestCase)]) From scoder at codespeak.net Wed Jul 2 08:21:33 2008 From: scoder at codespeak.net (scoder at codespeak.net) Date: Wed, 2 Jul 2008 08:21:33 +0200 (CEST) Subject: [Lxml-checkins] r56225 - in lxml/trunk: . src/lxml Message-ID: <20080702062133.1073369804A@codespeak.net> Author: scoder Date: Wed Jul 2 08:21:32 2008 New Revision: 56225 Modified: lxml/trunk/ (props changed) lxml/trunk/src/lxml/proxy.pxi Log: r4559 at delle: sbehnel | 2008-06-28 10:47:49 +0200 separate dict name fixing from namespace fixing when adapting trees => faster if not both required Modified: lxml/trunk/src/lxml/proxy.pxi ============================================================================== --- lxml/trunk/src/lxml/proxy.pxi (original) +++ lxml/trunk/src/lxml/proxy.pxi Wed Jul 2 08:21:32 2008 @@ -315,18 +315,10 @@ cdef xmlNs* c_nsdef cdef xmlNs* c_del_ns_list cdef cstd.size_t i - cdef tree.xmlDict* c_dict if not tree._isElementOrXInclude(c_element): return 0 - # we need to copy the names of tags and attributes iff the element - # is based on a different libxml2 tag name dictionary - if doc._c_doc.dict is not c_source_doc.dict: - c_dict = doc._c_doc.dict - else: - c_dict = NULL - c_start_node = c_element c_del_ns_list = NULL @@ -358,14 +350,6 @@ _appendToNsCache(&c_ns_cache, c_node.ns, c_ns) c_node.ns = c_ns - # 3) re-assign names from the target dict - if c_dict is not NULL: - c_name = tree.xmlDictLookup(c_dict, c_node.name, -1) - # c_name can be NULL on memory error, but we don't - # handle that here - if c_name is not NULL: - c_node.name = c_name - if c_node is c_element: # after the element, continue with its attributes c_node = c_element.properties @@ -414,6 +398,10 @@ break # all done c_element = c_node + # 3) fix the names in the tree in case we moved it to a different thread + if doc._c_doc.dict is not c_source_doc.dict: + fixThreadDictNames(c_start_node, doc._c_doc.dict) + # free now unused namespace declarations if c_del_ns_list is not NULL: tree.xmlFreeNsList(c_del_ns_list) @@ -425,3 +413,28 @@ cstd.free(c_ns_cache.old) return 0 + + +cdef void fixThreadDictNames(xmlNode* c_element, tree.xmlDict* c_dict) nogil: + # re-assign the names of tags and attributes + # + # this should only be called when the element is based on a + # different libxml2 tag name dictionary + cdef xmlNode* c_node + cdef char* c_name + if not tree._isElementOrXInclude(c_element): + return + + tree.BEGIN_FOR_EACH_ELEMENT_FROM(c_element, c_element, 1) + c_name = tree.xmlDictLookup(c_dict, c_element.name, -1) + # c_name can be NULL on memory error, but we don't handle that here + if c_name is not NULL: + c_element.name = c_name + if c_element.type == tree.XML_ELEMENT_NODE: + c_node = c_element.properties + while c_node is not NULL: + c_name = tree.xmlDictLookup(c_dict, c_node.name, -1) + if c_name is not NULL: + c_node.name = c_name + c_node = c_node.next + tree.END_FOR_EACH_ELEMENT_FROM(c_element) From scoder at codespeak.net Wed Jul 2 08:21:38 2008 From: scoder at codespeak.net (scoder at codespeak.net) Date: Wed, 2 Jul 2008 08:21:38 +0200 (CEST) Subject: [Lxml-checkins] r56226 - in lxml/trunk: . src/lxml Message-ID: <20080702062138.6B2AB698038@codespeak.net> Author: scoder Date: Wed Jul 2 08:21:37 2008 New Revision: 56226 Modified: lxml/trunk/ (props changed) lxml/trunk/CHANGES.txt lxml/trunk/src/lxml/xslt.pxi Log: r4560 at delle: sbehnel | 2008-06-28 10:51:55 +0200 faster thread adaptation in XSLT, doesn't require GIL Modified: lxml/trunk/CHANGES.txt ============================================================================== --- lxml/trunk/CHANGES.txt (original) +++ lxml/trunk/CHANGES.txt Wed Jul 2 08:21:37 2008 @@ -23,6 +23,8 @@ Other changes ------------- +* Speed-up when running XSLTs on documents from other threads + 2.0.7 (2008-06-20) ================== Modified: lxml/trunk/src/lxml/xslt.pxi ============================================================================== --- lxml/trunk/src/lxml/xslt.pxi (original) +++ lxml/trunk/src/lxml/xslt.pxi Wed Jul 2 08:21:37 2008 @@ -536,7 +536,8 @@ c_node = _findChildForwards(c_result, 0) if c_node is not NULL: __GLOBAL_PARSER_CONTEXT.initThreadDictRef(&c_result.dict) - moveNodeToDocument(result_doc, self._c_style.doc, c_node) + with nogil: + fixThreadDictNames(c_node, c_result.dict) return _xsltResultTreeFactory(result_doc, self, profile_doc) From scoder at codespeak.net Wed Jul 2 08:21:48 2008 From: scoder at codespeak.net (scoder at codespeak.net) Date: Wed, 2 Jul 2008 08:21:48 +0200 (CEST) Subject: [Lxml-checkins] r56227 - in lxml/trunk: . doc/html Message-ID: <20080702062148.84B2E69804A@codespeak.net> Author: scoder Date: Wed Jul 2 08:21:48 2008 New Revision: 56227 Modified: lxml/trunk/ (props changed) lxml/trunk/doc/html/style.css Log: r4564 at delle: sbehnel | 2008-07-02 08:18:38 +0200 smaller side menu Modified: lxml/trunk/doc/html/style.css ============================================================================== --- lxml/trunk/doc/html/style.css (original) +++ lxml/trunk/doc/html/style.css Wed Jul 2 08:21:48 2008 @@ -61,7 +61,7 @@ top: 0px; left: 0px; width: 24em; - font-size: 11px; + font-size: 10px; text-align: left; border-right: groove gray; border-bottom: groove gray; From scoder at codespeak.net Wed Jul 2 08:21:57 2008 From: scoder at codespeak.net (scoder at codespeak.net) Date: Wed, 2 Jul 2008 08:21:57 +0200 (CEST) Subject: [Lxml-checkins] r56228 - in lxml/trunk: . doc/s5 doc/s5/ui doc/s5/ui/default Message-ID: <20080702062157.512E9698038@codespeak.net> Author: scoder Date: Wed Jul 2 08:21:56 2008 New Revision: 56228 Added: lxml/trunk/doc/s5/ lxml/trunk/doc/s5/Makefile lxml/trunk/doc/s5/tagpython.png (contents, props changed) lxml/trunk/doc/s5/ui/ lxml/trunk/doc/s5/ui/default/ lxml/trunk/doc/s5/ui/default/blank.gif (contents, props changed) lxml/trunk/doc/s5/ui/default/bodybg.gif (contents, props changed) lxml/trunk/doc/s5/ui/default/framing.css lxml/trunk/doc/s5/ui/default/iepngfix.htc lxml/trunk/doc/s5/ui/default/lxml-logo64.png (contents, props changed) lxml/trunk/doc/s5/ui/default/opera.css lxml/trunk/doc/s5/ui/default/outline.css lxml/trunk/doc/s5/ui/default/pretty.css lxml/trunk/doc/s5/ui/default/print.css lxml/trunk/doc/s5/ui/default/s5-core.css lxml/trunk/doc/s5/ui/default/slides.css lxml/trunk/doc/s5/ui/default/slides.js lxml/trunk/doc/s5/ui/default/tagpython.png (contents, props changed) Modified: lxml/trunk/ (props changed) lxml/trunk/MANIFEST.in lxml/trunk/Makefile Log: r4565 at delle: sbehnel | 2008-07-02 08:19:19 +0200 s5 presentation theme for lxml Modified: lxml/trunk/MANIFEST.in ============================================================================== --- lxml/trunk/MANIFEST.in (original) +++ lxml/trunk/MANIFEST.in Wed Jul 2 08:21:56 2008 @@ -12,5 +12,7 @@ recursive-include samples *.xml recursive-include benchmark *.py recursive-include doc *.txt *.html *.css *.xml *.mgp pubkey.asc tagpython*.png +recursive-include doc/s5/ui *.gif *.htc *.png *.js +recursive-include doc/s5/ep2008 *.py *.png *.rng recursive-include fake_pyrex *.py include doc/mkhtml.py doc/rest2html.py Modified: lxml/trunk/Makefile ============================================================================== --- lxml/trunk/Makefile (original) +++ lxml/trunk/Makefile Wed Jul 2 08:21:56 2008 @@ -59,9 +59,12 @@ --name "lxml API" --url http://codespeak.net/lxml/ lxml/) \ || (echo "not generating epydoc API documentation") -html: inplace apihtml +html: inplace apihtml s5 PYTHONPATH=src $(PYTHON) doc/mkhtml.py doc/html . ${LXMLVERSION} +s5: inplace + $(MAKE) -C doc/s5 slides + apipdf: inplace rm -fr doc/pdf mkdir -p doc/pdf @@ -100,6 +103,7 @@ rm -rf build docclean: + $(MAKE) -C doc/s5 clean rm -f doc/html/*.html rm -fr doc/html/api rm -fr doc/pdf Added: lxml/trunk/doc/s5/Makefile ============================================================================== --- (empty file) +++ lxml/trunk/doc/s5/Makefile Wed Jul 2 08:21:56 2008 @@ -0,0 +1,10 @@ + +SLIDES=$(subst .txt,.html,$(wildcard *.txt)) + +slides: $(SLIDES) + +%.html: %.txt + rst2s5 --current-slide --language=en $< $@ + +clean: + rm -f *~ $(SLIDES) Added: lxml/trunk/doc/s5/tagpython.png ============================================================================== Binary file. No diff available. Added: lxml/trunk/doc/s5/ui/default/blank.gif ============================================================================== Binary file. No diff available. Added: lxml/trunk/doc/s5/ui/default/bodybg.gif ============================================================================== Binary file. No diff available. Added: lxml/trunk/doc/s5/ui/default/framing.css ============================================================================== --- (empty file) +++ lxml/trunk/doc/s5/ui/default/framing.css Wed Jul 2 08:21:56 2008 @@ -0,0 +1,23 @@ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#header {top: 0; height: 3em; z-index: 1;} +div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;} +.slide {top: 0; width: 92%; padding: 3.5em 4% 4%; z-index: 2; list-style: none;} +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ Added: lxml/trunk/doc/s5/ui/default/iepngfix.htc ============================================================================== --- (empty file) +++ lxml/trunk/doc/s5/ui/default/iepngfix.htc Wed Jul 2 08:21:56 2008 @@ -0,0 +1,42 @@ + + + + + \ No newline at end of file Added: lxml/trunk/doc/s5/ui/default/lxml-logo64.png ============================================================================== Binary file. No diff available. Added: lxml/trunk/doc/s5/ui/default/opera.css ============================================================================== --- (empty file) +++ lxml/trunk/doc/s5/ui/default/opera.css Wed Jul 2 08:21:56 2008 @@ -0,0 +1,7 @@ +/* DO NOT CHANGE THESE unless you really want to break Opera Show */ +.slide { + visibility: visible !important; + position: static !important; + page-break-before: always; +} +#slide0 {page-break-before: avoid;} Added: lxml/trunk/doc/s5/ui/default/outline.css ============================================================================== --- (empty file) +++ lxml/trunk/doc/s5/ui/default/outline.css Wed Jul 2 08:21:56 2008 @@ -0,0 +1,15 @@ +/* don't change this unless you want the layout stuff to show up in the outline view! */ + +.layout div, #footer *, #controlForm * {display: none;} +#footer, #controls, #controlForm, #navLinks, #toggle { + display: block; visibility: visible; margin: 0; padding: 0;} +#toggle {float: right; padding: 0.5em;} +html>body #toggle {position: fixed; top: 0; right: 0;} + +/* making the outline look pretty-ish */ + +#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;} +#slide0 h1 {padding-top: 1.5em;} +.slide h1 {margin: 1.5em 0 0; padding-top: 0.25em; + border-top: 1px solid #888; border-bottom: 1px solid #AAA;} +#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;} Added: lxml/trunk/doc/s5/ui/default/pretty.css ============================================================================== --- (empty file) +++ lxml/trunk/doc/s5/ui/default/pretty.css Wed Jul 2 08:21:56 2008 @@ -0,0 +1,160 @@ +/* Following are the presentation styles -- edit away! */ + +/* body {background: #FFF url(tagpython.png) 1em 1em no-repeat; color: #000; font-size: 2em;} */ +:link, :visited {text-decoration: none; color: #438e00;} +#controls :active {color: #8A8 !important;} +#controls :focus {outline: 1px dotted #227;} +h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;} +ul, pre {margin: 0; line-height: 1em;} +html, body {margin: 0; padding: 0;} + +blockquote, q {font-style: italic;} +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em; text-align: center; font-size: 1em;} +blockquote p {margin: 2em;} +blockquote p strong {font-size: 1.5em;} +blockquote i {font-style: normal;} +blockquote b {display: block; margin-top: 0.5em; font-weight: normal; font-size: smaller; font-style: normal;} +blockquote b i {font-style: italic;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide code {padding: 2px 0.25em; font-weight: bold; color: #533;} +.slide code.bad, code del {color: red;} +.slide code.old {color: silver;} +.slide .pre {padding: 0; margin: 0 0 0 0; color: #533; font-size: 80%;} +.slide pre {padding: 0; margin: 0.25em 0 0.5em 0.5em; color: #533; font-size: 90%;} +/* .slide pre {padding: 0; margin: 0 0 0 0; color: #533; font-size: 90%;} */ +.slide pre code {display: block;} +.slide div > ul {padding-left: 0; margin-left: 0; list-style: disc; } +.slide li {margin-top: 0.75em; margin-right: 0;} +.slide ul ul {line-height: 1; padding-left: 1em; margin-left: 2%; margin-right: 5%; list-style: disc; } +.slide ul ul li {margin: .4em; font-size: 85%; list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} + +div#header, div#footer {background: #438e00; color: #CDC; + font-family: Verdana, Helvetica, sans-serif; padding: 0;} +div#header {background: #438e00 url(lxml-logo64.png) 1ex 0.6ex no-repeat; + line-height: 1px;} +div#footer {font-size: 0.5em; font-weight: bold; padding: 0.6em 0;} +#footer h1, #footer h2 {display: block; padding: 0 1em;} +#footer h2 {font-style: italic;} +#footer a {color: #CDC;} + +div.long {font-size: 0.75em;} +.slide h1 {position: absolute; top: 0.4em; left: 87px; z-index: 1; + margin: 0; padding: 0.2em 0 0 25px; white-space: nowrap; + font: bold 150%/1em Helvetica, sans-serif; /* text-transform: capitalize; */ + color: #DED; background: #438e00;} +.slide h3 {font-size: 130%;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; + text-align: right; font: bold 0.7em Verdana, Helvetica, sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; + top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + background: #438e00; border: none; color: #DED; + cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; background: #EEE; color: #272;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #CDC; left: 90%; bottom: 2px;} + +#slide0 {padding-top: 3em; font-size: 90%;} +#slide0 h1 {position: static; margin: 1em 0 0; padding: 0; + font: bold 2em Helvetica, sans-serif; white-space: normal; + color: #000; background: transparent;} +#slide0 h2 {font: bold italic 1em Helvetica, sans-serif; margin: 1.25em;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.note {display: none;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +/* .external:after {content: " \274F"; font-size: smaller; color: #7B7;} */ + +/* .incremental, .incremental *, .incremental *:after {color: #DED; visibility: visible;} */ +.incremental, .incremental *, .incremental *:after {visibility: hidden;} +img.incremental {visibility: hidden;} +.slide .current {color: #B02;} + +.center {text-align: center; } +.right {text-align: right; } +.small {font-size: 60%; } +img.center {display: block; margin-left: auto; margin-right: auto; } + +.slide .syntax {padding: 2px 0.25em; font-weight: bold; color: #533; font-size:85%; } + +/* diagnostics + +li:after {content: " [" attr(class) "]"; color: #F88;} + */ + +/* Syntax highlighting */ + +/* .syntax { background: #f0f0f0; } */ +.syntax .c { color: #60a0b0; font-style: italic } /* Comment */ +.syntax .err { border: 1px solid #FF0000 } /* Error */ +.syntax .k { color: #007020; font-weight: bold } /* Keyword */ +.syntax .o { color: #666666 } /* Operator */ +.syntax .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */ +.syntax .cp { color: #007020 } /* Comment.Preproc */ +.syntax .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */ +.syntax .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */ +.syntax .gd { color: #A00000 } /* Generic.Deleted */ +.syntax .ge { font-style: italic } /* Generic.Emph */ +.syntax .gr { color: #FF0000 } /* Generic.Error */ +.syntax .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.syntax .gi { color: #00A000 } /* Generic.Inserted */ +.syntax .go { color: #404040 } /* Generic.Output */ +.syntax .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.syntax .gs { font-weight: bold } /* Generic.Strong */ +.syntax .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.syntax .gt { color: #0040D0 } /* Generic.Traceback */ +.syntax .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.syntax .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.syntax .kp { color: #007020 } /* Keyword.Pseudo */ +.syntax .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.syntax .kt { color: #902000 } /* Keyword.Type */ +.syntax .m { color: #40a070 } /* Literal.Number */ +.syntax .s { color: #4070a0 } /* Literal.String */ +.syntax .na { color: #4070a0 } /* Name.Attribute */ +.syntax .nb { color: #007020 } /* Name.Builtin */ +.syntax .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.syntax .no { color: #60add5 } /* Name.Constant */ +.syntax .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.syntax .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.syntax .ne { color: #007020 } /* Name.Exception */ +.syntax .nf { color: #06287e } /* Name.Function */ +.syntax .nl { color: #002070; font-weight: bold } /* Name.Label */ +.syntax .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.syntax .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.syntax .nv { color: #bb60d5 } /* Name.Variable */ +.syntax .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.syntax .w { color: #bbbbbb } /* Text.Whitespace */ +.syntax .mf { color: #40a070 } /* Literal.Number.Float */ +.syntax .mh { color: #40a070 } /* Literal.Number.Hex */ +.syntax .mi { color: #40a070 } /* Literal.Number.Integer */ +.syntax .mo { color: #40a070 } /* Literal.Number.Oct */ +.syntax .sb { color: #4070a0 } /* Literal.String.Backtick */ +.syntax .sc { color: #4070a0 } /* Literal.String.Char */ +.syntax .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.syntax .s2 { color: #4070a0 } /* Literal.String.Double */ +.syntax .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.syntax .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.syntax .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.syntax .sx { color: #c65d09 } /* Literal.String.Other */ +.syntax .sr { color: #235388 } /* Literal.String.Regex */ +.syntax .s1 { color: #4070a0 } /* Literal.String.Single */ +.syntax .ss { color: #517918 } /* Literal.String.Symbol */ +.syntax .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.syntax .vc { color: #bb60d5 } /* Name.Variable.Class */ +.syntax .vg { color: #bb60d5 } /* Name.Variable.Global */ +.syntax .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.syntax .il { color: #40a070 } /* Literal.Number.Integer.Long */ Added: lxml/trunk/doc/s5/ui/default/print.css ============================================================================== --- (empty file) +++ lxml/trunk/doc/s5/ui/default/print.css Wed Jul 2 08:21:56 2008 @@ -0,0 +1,24 @@ +/* The following rule is necessary to have all slides appear in print! DO NOT REMOVE IT! */ +.slide, ul {page-break-inside: avoid; visibility: visible !important;} +h1 {page-break-after: avoid;} + +body {font-size: 12pt; background: white;} +* {color: black;} + +#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;} +#slide0 h3 {margin: 0; padding: 0;} +#slide0 h4 {margin: 0 0 0.5em; padding: 0;} +#slide0 {margin-bottom: 3em;} + +h1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;} +.extra {background: transparent !important;} +div.extra, pre.extra, .example {font-size: 10pt; color: #333;} +ul.extra a {font-weight: bold;} +p.example {display: none;} + +#header {display: none;} +#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; font-style: italic;} +#footer h2, #controls {display: none;} + +/* The following rule keeps the layout stuff out of print. Remove at your own risk! */ +.layout, .layout * {display: none !important;} Added: lxml/trunk/doc/s5/ui/default/s5-core.css ============================================================================== --- (empty file) +++ lxml/trunk/doc/s5/ui/default/s5-core.css Wed Jul 2 08:21:56 2008 @@ -0,0 +1,9 @@ +/* Do not edit or override these styles! The system will likely break if you do. */ + +div#header, div#footer, div#controls, .slide {position: absolute;} +html>body div#header, html>body div#footer, + html>body div#controls, html>body .slide {position: fixed;} +.handout {display: none;} +.layout {display: block;} +.slide, .hideme, .incremental {visibility: hidden;} +#slide0 {visibility: visible;} Added: lxml/trunk/doc/s5/ui/default/slides.css ============================================================================== --- (empty file) +++ lxml/trunk/doc/s5/ui/default/slides.css Wed Jul 2 08:21:56 2008 @@ -0,0 +1,3 @@ + at import url(s5-core.css); /* required to make the slide show run at all */ + at import url(framing.css); /* sets basic placement and size of slide components */ + at import url(pretty.css); /* stuff that makes the slides look better than blah */ \ No newline at end of file Added: lxml/trunk/doc/s5/ui/default/slides.js ============================================================================== --- (empty file) +++ lxml/trunk/doc/s5/ui/default/slides.js Wed Jul 2 08:21:56 2008 @@ -0,0 +1,552 @@ +// S5 v1.1 slides.js -- released into the Public Domain +// +// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information +// about all the wonderful and talented contributors to this code! + +var undef; +var slideCSS = ''; +var snum = 0; +var smax = 1; +var incpos = 0; +var number = undef; +var s5mode = true; +var defaultView = 'slideshow'; +var controlVis = 'visible'; + +var isIE = navigator.appName == 'Microsoft Internet Explorer' ? 1 : 0; +var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0; +var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0; + +function hasClass(object, className) { + if (!object.className) return false; + return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1); +} + +function hasValue(object, value) { + if (!object) return false; + return (object.search('(^|\\s)' + value + '(\\s|$)') != -1); +} + +function removeClass(object,className) { + if (!object) return; + object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2); +} + +function addClass(object,className) { + if (!object || hasClass(object, className)) return; + if (object.className) { + object.className += ' '+className; + } else { + object.className = className; + } +} + +function GetElementsWithClassName(elementName,className) { + var allElements = document.getElementsByTagName(elementName); + var elemColl = new Array(); + for (var i = 0; i< allElements.length; i++) { + if (hasClass(allElements[i], className)) { + elemColl[elemColl.length] = allElements[i]; + } + } + return elemColl; +} + +function isParentOrSelf(element, id) { + if (element == null || element.nodeName=='BODY') return false; + else if (element.id == id) return true; + else return isParentOrSelf(element.parentNode, id); +} + +function nodeValue(node) { + var result = ""; + if (node.nodeType == 1) { + var children = node.childNodes; + for (var i = 0; i < children.length; ++i) { + result += nodeValue(children[i]); + } + } + else if (node.nodeType == 3) { + result = node.nodeValue; + } + return(result); +} + +function slideLabel() { + var slideColl = GetElementsWithClassName('*','slide'); + var list = document.getElementById('jumplist'); + smax = slideColl.length; + for (var n = 0; n < smax; n++) { + var obj = slideColl[n]; + + var did = 'slide' + n.toString(); + obj.setAttribute('id',did); + if (isOp) continue; + + var otext = ''; + var menu = obj.firstChild; + if (!menu) continue; // to cope with empty slides + while (menu && menu.nodeType == 3) { + menu = menu.nextSibling; + } + if (!menu) continue; // to cope with slides with only text nodes + + var menunodes = menu.childNodes; + for (var o = 0; o < menunodes.length; o++) { + otext += nodeValue(menunodes[o]); + } + list.options[list.length] = new Option(n + ' : ' + otext, n); + } +} + +function currentSlide() { + var cs; + if (document.getElementById) { + cs = document.getElementById('currentSlide'); + } else { + cs = document.currentSlide; + } + cs.innerHTML = '' + snum + '<\/span> ' + + '\/<\/span> ' + + '' + (smax-1) + '<\/span>'; + if (snum == 0) { + cs.style.visibility = 'hidden'; + } else { + cs.style.visibility = 'visible'; + } +} + +function go(step) { + if (document.getElementById('slideProj').disabled || step == 0) return; + var jl = document.getElementById('jumplist'); + var cid = 'slide' + snum; + var ce = document.getElementById(cid); + if (incrementals[snum].length > 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + removeClass(incrementals[snum][i], 'current'); + removeClass(incrementals[snum][i], 'incremental'); + } + } + if (step != 'j') { + snum += step; + lmax = smax - 1; + if (snum > lmax) snum = lmax; + if (snum < 0) snum = 0; + } else + snum = parseInt(jl.value); + var nid = 'slide' + snum; + var ne = document.getElementById(nid); + if (!ne) { + ne = document.getElementById('slide0'); + snum = 0; + } + if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;} + if (incrementals[snum].length > 0 && incpos == 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + if (hasClass(incrementals[snum][i], 'current')) + incpos = i + 1; + else + addClass(incrementals[snum][i], 'incremental'); + } + } + if (incrementals[snum].length > 0 && incpos > 0) + addClass(incrementals[snum][incpos - 1], 'current'); + ce.style.visibility = 'hidden'; + ne.style.visibility = 'visible'; + jl.selectedIndex = snum; + currentSlide(); + number = 0; +} + +function goTo(target) { + if (target >= smax || target == snum) return; + go(target - snum); +} + +function subgo(step) { + if (step > 0) { + removeClass(incrementals[snum][incpos - 1],'current'); + removeClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos],'current'); + incpos++; + } else { + incpos--; + removeClass(incrementals[snum][incpos],'current'); + addClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos - 1],'current'); + } +} + +function toggle() { + var slideColl = GetElementsWithClassName('*','slide'); + var slides = document.getElementById('slideProj'); + var outline = document.getElementById('outlineStyle'); + if (!slides.disabled) { + slides.disabled = true; + outline.disabled = false; + s5mode = false; + fontSize('1em'); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'visible'; + } + } else { + slides.disabled = false; + outline.disabled = true; + s5mode = true; + fontScale(); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'hidden'; + } + slideColl[snum].style.visibility = 'visible'; + } +} + +function showHide(action) { + var obj = GetElementsWithClassName('*','hideme')[0]; + switch (action) { + case 's': obj.style.visibility = 'visible'; break; + case 'h': obj.style.visibility = 'hidden'; break; + case 'k': + if (obj.style.visibility != 'visible') { + obj.style.visibility = 'visible'; + } else { + obj.style.visibility = 'hidden'; + } + break; + } +} + +// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/) +function keys(key) { + if (!key) { + key = event; + key.which = key.keyCode; + } + if (key.which == 84) { + toggle(); + return; + } + if (s5mode) { + switch (key.which) { + case 10: // return + case 13: // enter + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + if(number != undef) { + goTo(number); + break; + } + case 32: // spacebar + case 34: // page down + case 39: // rightkey + case 40: // downkey + if(number != undef) { + go(number); + } else if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + break; + case 33: // page up + case 37: // leftkey + case 38: // upkey + if(number != undef) { + go(-1 * number); + } else if (!incrementals[snum] || incpos <= 0) { + go(-1); + } else { + subgo(-1); + } + break; + case 36: // home + goTo(0); + break; + case 35: // end + goTo(smax-1); + break; + case 67: // c + showHide('k'); + break; + } + if (key.which < 48 || key.which > 57) { + number = undef; + } else { + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + number = (((number != undef) ? number : 0) * 10) + (key.which - 48); + } + } + return false; +} + +function clicker(e) { + number = undef; + var target; + if (window.event) { + target = window.event.srcElement; + e = window.event; + } else target = e.target; + if (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true; + if (!e.which || e.which == 1) { + if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + } +} + +function findSlide(hash) { + var target = null; + var slides = GetElementsWithClassName('*','slide'); + for (var i = 0; i < slides.length; i++) { + var targetSlide = slides[i]; + if ( (targetSlide.name && targetSlide.name == hash) + || (targetSlide.id && targetSlide.id == hash) ) { + target = targetSlide; + break; + } + } + while(target != null && target.nodeName != 'BODY') { + if (hasClass(target, 'slide')) { + return parseInt(target.id.slice(5)); + } + target = target.parentNode; + } + return null; +} + +function slideJump() { + if (window.location.hash == null) return; + var sregex = /^#slide(\d+)$/; + var matches = sregex.exec(window.location.hash); + var dest = null; + if (matches != null) { + dest = parseInt(matches[1]); + } else { + dest = findSlide(window.location.hash.slice(1)); + } + if (dest != null) + go(dest - snum); +} + +function fixLinks() { + var thisUri = window.location.href; + thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length); + var aelements = document.getElementsByTagName('A'); + for (var i = 0; i < aelements.length; i++) { + var a = aelements[i].href; + var slideID = a.match('\#slide[0-9]{1,2}'); + if ((slideID) && (slideID[0].slice(0,1) == '#')) { + var dest = findSlide(slideID[0].slice(1)); + if (dest != null) { + if (aelements[i].addEventListener) { + aelements[i].addEventListener("click", new Function("e", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "if (e.preventDefault) e.preventDefault();"), true); + } else if (aelements[i].attachEvent) { + aelements[i].attachEvent("onclick", new Function("", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "event.returnValue = false;")); + } + } + } + } +} + +function externalLinks() { + if (!document.getElementsByTagName) return; + var anchors = document.getElementsByTagName('a'); + for (var i=0; i' + + '