From e06f58a6c6695a385455dc9b9b0826bd0a740aba Mon Sep 17 00:00:00 2001 From: "W. Martin Borgert" Date: Sat, 25 Jul 2015 15:36:45 +0200 Subject: [PATCH] python-odf (1.3.1+dfsg-1) unstable; urgency=medium * New upstream version, which allowed to remove all previous patches. * Set HTML_TIMESTAMP = NO (Closes: #777635). * Added patch which (Closes: #783789). * Remove doc/ in source, because of uglified JS. * Updated watch file. # imported from the archive --- .gitignore | 2 + APACHE-LICENSE-2.0.txt | 202 + ChangeLog | 24 + GPL-LICENSE-2.txt | 339 + MANIFEST.in | 5 + README.md | 93 + api-for-odfpy.odt | Bin 0 -> 75143 bytes config.dox | 2312 ++ contrib/ODFFile/Makefile | 6 + contrib/ODFFile/ODFFile.py | 213 + contrib/ODFFile/README.txt | 3 + contrib/ODFFile/__init__.py | 45 + contrib/ODFFile/dtml/odfEdit.dtml | 149 + contrib/ODFFile/dtml/odffileAdd.dtml | 69 + contrib/ODFFile/help/ODFFile.stx | 5 + .../openofficeorg-oasis-presentation.gif | Bin 0 -> 1067 bytes .../openofficeorg-oasis-spreadsheet.gif | Bin 0 -> 1065 bytes .../images/openofficeorg-oasis-text.gif | Bin 0 -> 1065 bytes contrib/ODFFile/refresh.txt | 0 contrib/ODFFile/version.txt | 1 + contrib/gutenberg/Makefile | 14 + contrib/gutenberg/gbtext2odt.1 | 76 + contrib/gutenberg/gbtext2odt.docbook | 159 + contrib/gutenberg/gbtext2odt.py | 269 + contrib/html2odt/Makefile | 8 + contrib/html2odt/emptycontent.py | 48 + contrib/html2odt/html2odt.py | 495 + contrib/html2odt/htmlstyles.py | 114 + contrib/html2odt/shtml2odt.py | 619 + contrib/odf2epub/Makefile | 15 + contrib/odf2epub/odf2epub | 350 + contrib/odf2epub/odf2epub.1 | 72 + contrib/odf2epub/odf2epub.docbook | 92 + contrib/odf2gbzip/Makefile | 15 + contrib/odf2gbzip/odf2gbzip | 64 + contrib/odf2gbzip/odf2gbzip.1 | 35 + contrib/odf2gbzip/odf2gbzip.docbook | 38 + contrib/odf2war/Makefile | 15 + contrib/odf2war/odf2war | 61 + contrib/odf2war/odf2war.1 | 217 + contrib/odf2war/odf2war.docbook | 51 + contrib/odfsign/Makefile | 14 + contrib/odfsign/odfsign | 92 + contrib/odfsign/odfsign.1 | 217 + contrib/odfsign/odfsign.docbook | 50 + contrib/odfsign/testdocs/ClimateChange2.odt | Bin 0 -> 57571 bytes contrib/odfsign/testdocs/ClimateChange3.odt | Bin 0 -> 73828 bytes contrib/odftohtmlplugin/0.10/setup.py | 32 + contrib/odscell/Makefile | 14 + contrib/odscell/odscell | 184 + contrib/odscell/odscell.1 | 98 + contrib/odscell/odscell.docbook | 117 + contrib/odt2tracwiki/Makefile | 15 + contrib/odt2tracwiki/odt2tracwiki.1 | 57 + contrib/odt2tracwiki/odt2tracwiki.docbook | 46 + contrib/odt2tracwiki/odt2tracwiki.py | 28 + contrib/odt2zwiki/Makefile | 15 + contrib/odt2zwiki/odf2zwikimoin.1 | 51 + contrib/odt2zwiki/odf2zwikimoin.docbook | 33 + contrib/odt2zwiki/odf2zwikimoin.py | 46 + contrib/odt2zwiki/odt2moinmoin.py | 533 + contrib/sqlite2ods/README | 4 + contrib/sqlite2ods/sqlite2ods.py | 77 + contrib/syntaxhighlight/Makefile | 14 + contrib/syntaxhighlight/syntaxhighlight.1 | 220 + .../syntaxhighlight/syntaxhighlight.docbook | 72 + contrib/syntaxhighlight/syntaxhighlight.py | 508 + contrib/tracplugins/0.10/README | 7 + .../tracplugins/0.10/odfpreview/__init__.py | 20 + .../tracplugins/0.10/odfpreview/odfpreview.py | 85 + .../tracplugins/0.10/odftohtml/__init__.py | 20 + .../tracplugins/0.10/odftohtml/odftohtml.py | 41 + contrib/tracplugins/0.10/setup.py | 33 + contrib/xliff/README | 14 + contrib/xliff/global.xlf | 423 + contrib/xliff/xliff2table.py | 87 + contrib/xliff/xliff_parser.py | 169 + csv2ods/Makefile | 22 + csv2ods/csv2ods | 229 + csv2ods/csv2ods.1 | 270 + csv2ods/csv2ods.docbook | 162 + debian/changelog | 85 + debian/compat | 1 + debian/control | 79 + debian/copyright | 105 + debian/patches/fix_chinese_ods.patch | 19 + debian/patches/no_html_timestamp.patch | 19 + debian/patches/series | 2 + debian/python-odf-doc.install | 3 + debian/python-odf-tools.install | 2 + debian/python-odf.install | 1 + debian/python3-odf.install | 1 + debian/rules | 45 + debian/source/format | 1 + debian/source/include-binaries | 3 + debian/watch | 3 + examples/barchart.py | 148 + examples/countrystatistics.ods | Bin 0 -> 14794 bytes examples/datatable.py | 94 + examples/easylists.py | 122 + examples/europeanflag-as-odg.py | 138 + examples/europeanflag-as-odt.py | 124 + examples/helloworld.py | 29 + examples/list-as-odt.py | 53 + examples/loadsave.py | 30 + examples/manualpagebreak.py | 38 + examples/ods-currency.py | 81 + examples/ods2odt.py | 76 + examples/passwd-as-ods.py | 64 + examples/passwd-as-odt.py | 63 + examples/photoalbum.py | 167 + examples/subobject.py | 169 + examples/text-with-masterpage.py | 34 + grammar/Makefile | 33 + grammar/OpenDocument-dsig-schema-v1.2-cd1.rng | 76 + .../OpenDocument-manifest-schema-v1.0-os.rng | 111 + grammar/OpenDocument-manifest-schema-v1.1.rng | 111 + .../OpenDocument-manifest-schema-v1.2-cd1.rng | 209 + grammar/OpenDocument-metadata-v1.2-cd04.owl | 84 + ...OpenDocument-package-metadata-v1.2-cd1.owl | 83 + grammar/OpenDocument-schema-v1.0-os.rng | 17672 ++++++++++++++ grammar/OpenDocument-schema-v1.1.rng | 17894 ++++++++++++++ grammar/OpenDocument-schema-v1.2-cd04.rng | 20263 ++++++++++++++++ .../OpenDocument-strict-schema-v1.0-os.rng | 61 + grammar/OpenDocument-strict-schema-v1.1.rng | 61 + grammar/gen_allowed_attrs.py | 114 + grammar/gen_allowed_children.py | 164 + grammar/gen_allows_text.py | 129 + grammar/gen_required_attrs.py | 118 + grammar/simplification.xsl | 1037 + grammar/test_grammar.py | 101 + mailodf/Makefile | 21 + mailodf/mailodf | 95 + mailodf/mailodf.1 | 232 + mailodf/mailodf.docbook | 62 + manual/buildmanual.py | 162 + manual/htmlmanual.py | 177 + odf/__init__.py | 19 + odf/anim.py | 61 + odf/attrconverters.py | 1612 ++ odf/chart.py | 96 + odf/config.py | 39 + odf/dc.py | 72 + odf/dr3d.py | 45 + odf/draw.py | 188 + odf/easyliststyle.py | 104 + odf/element.py | 541 + odf/elementtypes.py | 325 + odf/form.py | 115 + odf/grammar.py | 9194 +++++++ odf/load.py | 115 + odf/manifest.py | 44 + odf/math.py | 30 + odf/meta.py | 67 + odf/namespaces.py | 107 + odf/number.py | 104 + odf/odf2moinmoin.py | 579 + odf/odf2xhtml.py | 1617 ++ odf/odfmanifest.py | 120 + odf/office.py | 107 + odf/opendocument.py | 1011 + odf/presentation.py | 86 + odf/script.py | 30 + odf/style.py | 154 + odf/svg.py | 56 + odf/table.py | 321 + odf/teletype.py | 137 + odf/text.py | 573 + odf/thumbnail.py | 80 + odf/userfield.py | 180 + odf/xforms.py | 34 + odf2mht/Makefile | 20 + odf2mht/odf2mht | 72 + odf2mht/odf2mht.1 | 239 + odf2mht/odf2mht.docbook | 67 + odf2xhtml/Makefile | 24 + odf2xhtml/odf2xhtml | 59 + odf2xhtml/odf2xhtml.1 | 221 + odf2xhtml/odf2xhtml.docbook | 63 + odf2xml/Makefile | 20 + odf2xml/odf2xml | 81 + odf2xml/odf2xml.1 | 231 + odf2xml/odf2xml.docbook | 82 + odfimgimport/Makefile | 22 + odfimgimport/odfimgimport | 190 + odfimgimport/odfimgimport.1 | 227 + odfimgimport/odfimgimport.docbook | 84 + odfimgimport/textWithImages.odt | Bin 0 -> 10139 bytes odflint/Makefile | 19 + odflint/odflint | 216 + odflint/odflint.1 | 217 + odflint/odflint.docbook | 52 + odfmeta/Makefile | 20 + odfmeta/odfmeta | 266 + odfmeta/odfmeta.1 | 277 + odfmeta/odfmeta.docbook | 192 + odfoutline/Makefile | 20 + odfoutline/odfoutline | 144 + odfoutline/odfoutline.1 | 213 + odfoutline/odfoutline.docbook | 45 + odfuserfield/Makefile | 39 + odfuserfield/odfuserfield | 101 + odfuserfield/odfuserfield.1 | 267 + odfuserfield/odfuserfield.docbook | 144 + samples/Bluff Crag.odt | Bin 0 -> 2179532 bytes samples/Electra.odt | Bin 0 -> 54147 bytes samples/spreadsheet-with-macro.ods | Bin 0 -> 34426 bytes setup.py | 112 + tests/Makefile | 10 + tests/elementparser.py | 98 + tests/examples/cols.odp | Bin 0 -> 18037 bytes tests/examples/definitionlists.odt | Bin 0 -> 7824 bytes tests/examples/emb_spreadsheet.odp | Bin 0 -> 16403 bytes tests/examples/headerfooter.odt | Bin 0 -> 7177 bytes tests/examples/images.odt | Bin 0 -> 16975 bytes tests/examples/imageslabels.odt | Bin 0 -> 17655 bytes tests/examples/no_userfields.odt | Bin 0 -> 19228 bytes tests/examples/ol.odp | Bin 0 -> 14940 bytes tests/examples/parastyles.odt | Bin 0 -> 7250 bytes tests/examples/pythagoras-kspread.ods | Bin 0 -> 5037 bytes tests/examples/pythagoras.ods | Bin 0 -> 6837 bytes tests/examples/serious_poem.odt | Bin 0 -> 8539 bytes tests/examples/simplelist.odt | Bin 0 -> 6928 bytes tests/examples/simplestyles.odt | Bin 0 -> 7277 bytes tests/examples/simpletable.odt | Bin 0 -> 7055 bytes tests/examples/twolevellist.odt | Bin 0 -> 7183 bytes tests/examples/userfields.odt | Bin 0 -> 19410 bytes tests/examples/userfields_ooo3.odt | Bin 0 -> 38420 bytes tests/runtests | 6 + tests/testchart.py | 50 + tests/testconverters.py | 72 + tests/testdatastyles.py | 140 + tests/testdrawelement.py | 60 + tests/testeasyliststyle.py | 148 + tests/testform.py | 90 + tests/testlengths.py | 191 + tests/testload.py | 172 + tests/testmasterstyles.py | 141 + tests/testmoinmoin.py | 124 + tests/testpresentations.py | 80 + tests/teststyleref.py | 90 + tests/teststyles.py | 102 + tests/testsubobjects.py | 109 + tests/testtext.py | 72 + tests/testtypes.py | 50 + tests/testunicode.py | 75 + tests/testuserfields.py | 196 + tests/testwhitespace.py | 68 + tests/testwrite.py | 54 + tests/testxhtml.py | 256 + tests/testxmlgen.py | 134 + xml2odf/Makefile | 22 + xml2odf/definitionlists.xml | 2 + xml2odf/xml2odf | 241 + xml2odf/xml2odf.1 | 235 + xml2odf/xml2odf.docbook | 93 + 256 files changed, 96473 insertions(+) create mode 100644 .gitignore create mode 100644 APACHE-LICENSE-2.0.txt create mode 100644 ChangeLog create mode 100644 GPL-LICENSE-2.txt create mode 100644 MANIFEST.in create mode 100644 README.md create mode 100644 api-for-odfpy.odt create mode 100644 config.dox create mode 100644 contrib/ODFFile/Makefile create mode 100644 contrib/ODFFile/ODFFile.py create mode 100644 contrib/ODFFile/README.txt create mode 100644 contrib/ODFFile/__init__.py create mode 100644 contrib/ODFFile/dtml/odfEdit.dtml create mode 100644 contrib/ODFFile/dtml/odffileAdd.dtml create mode 100644 contrib/ODFFile/help/ODFFile.stx create mode 100644 contrib/ODFFile/images/openofficeorg-oasis-presentation.gif create mode 100644 contrib/ODFFile/images/openofficeorg-oasis-spreadsheet.gif create mode 100644 contrib/ODFFile/images/openofficeorg-oasis-text.gif create mode 100644 contrib/ODFFile/refresh.txt create mode 100644 contrib/ODFFile/version.txt create mode 100644 contrib/gutenberg/Makefile create mode 100644 contrib/gutenberg/gbtext2odt.1 create mode 100644 contrib/gutenberg/gbtext2odt.docbook create mode 100755 contrib/gutenberg/gbtext2odt.py create mode 100644 contrib/html2odt/Makefile create mode 100644 contrib/html2odt/emptycontent.py create mode 100644 contrib/html2odt/html2odt.py create mode 100644 contrib/html2odt/htmlstyles.py create mode 100644 contrib/html2odt/shtml2odt.py create mode 100644 contrib/odf2epub/Makefile create mode 100755 contrib/odf2epub/odf2epub create mode 100644 contrib/odf2epub/odf2epub.1 create mode 100644 contrib/odf2epub/odf2epub.docbook create mode 100644 contrib/odf2gbzip/Makefile create mode 100755 contrib/odf2gbzip/odf2gbzip create mode 100644 contrib/odf2gbzip/odf2gbzip.1 create mode 100644 contrib/odf2gbzip/odf2gbzip.docbook create mode 100644 contrib/odf2war/Makefile create mode 100755 contrib/odf2war/odf2war create mode 100644 contrib/odf2war/odf2war.1 create mode 100644 contrib/odf2war/odf2war.docbook create mode 100644 contrib/odfsign/Makefile create mode 100755 contrib/odfsign/odfsign create mode 100644 contrib/odfsign/odfsign.1 create mode 100644 contrib/odfsign/odfsign.docbook create mode 100644 contrib/odfsign/testdocs/ClimateChange2.odt create mode 100644 contrib/odfsign/testdocs/ClimateChange3.odt create mode 100644 contrib/odftohtmlplugin/0.10/setup.py create mode 100644 contrib/odscell/Makefile create mode 100755 contrib/odscell/odscell create mode 100644 contrib/odscell/odscell.1 create mode 100644 contrib/odscell/odscell.docbook create mode 100644 contrib/odt2tracwiki/Makefile create mode 100644 contrib/odt2tracwiki/odt2tracwiki.1 create mode 100644 contrib/odt2tracwiki/odt2tracwiki.docbook create mode 100644 contrib/odt2tracwiki/odt2tracwiki.py create mode 100644 contrib/odt2zwiki/Makefile create mode 100644 contrib/odt2zwiki/odf2zwikimoin.1 create mode 100644 contrib/odt2zwiki/odf2zwikimoin.docbook create mode 100644 contrib/odt2zwiki/odf2zwikimoin.py create mode 100644 contrib/odt2zwiki/odt2moinmoin.py create mode 100644 contrib/sqlite2ods/README create mode 100644 contrib/sqlite2ods/sqlite2ods.py create mode 100644 contrib/syntaxhighlight/Makefile create mode 100644 contrib/syntaxhighlight/syntaxhighlight.1 create mode 100644 contrib/syntaxhighlight/syntaxhighlight.docbook create mode 100644 contrib/syntaxhighlight/syntaxhighlight.py create mode 100644 contrib/tracplugins/0.10/README create mode 100644 contrib/tracplugins/0.10/odfpreview/__init__.py create mode 100644 contrib/tracplugins/0.10/odfpreview/odfpreview.py create mode 100644 contrib/tracplugins/0.10/odftohtml/__init__.py create mode 100644 contrib/tracplugins/0.10/odftohtml/odftohtml.py create mode 100644 contrib/tracplugins/0.10/setup.py create mode 100644 contrib/xliff/README create mode 100644 contrib/xliff/global.xlf create mode 100644 contrib/xliff/xliff2table.py create mode 100644 contrib/xliff/xliff_parser.py create mode 100644 csv2ods/Makefile create mode 100755 csv2ods/csv2ods create mode 100644 csv2ods/csv2ods.1 create mode 100644 csv2ods/csv2ods.docbook create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/patches/fix_chinese_ods.patch create mode 100644 debian/patches/no_html_timestamp.patch create mode 100644 debian/patches/series create mode 100644 debian/python-odf-doc.install create mode 100644 debian/python-odf-tools.install create mode 100644 debian/python-odf.install create mode 100644 debian/python3-odf.install create mode 100755 debian/rules create mode 100644 debian/source/format create mode 100644 debian/source/include-binaries create mode 100644 debian/watch create mode 100644 examples/barchart.py create mode 100644 examples/countrystatistics.ods create mode 100644 examples/datatable.py create mode 100644 examples/easylists.py create mode 100644 examples/europeanflag-as-odg.py create mode 100644 examples/europeanflag-as-odt.py create mode 100644 examples/helloworld.py create mode 100644 examples/list-as-odt.py create mode 100644 examples/loadsave.py create mode 100644 examples/manualpagebreak.py create mode 100644 examples/ods-currency.py create mode 100644 examples/ods2odt.py create mode 100644 examples/passwd-as-ods.py create mode 100644 examples/passwd-as-odt.py create mode 100644 examples/photoalbum.py create mode 100644 examples/subobject.py create mode 100644 examples/text-with-masterpage.py create mode 100644 grammar/Makefile create mode 100644 grammar/OpenDocument-dsig-schema-v1.2-cd1.rng create mode 100644 grammar/OpenDocument-manifest-schema-v1.0-os.rng create mode 100644 grammar/OpenDocument-manifest-schema-v1.1.rng create mode 100644 grammar/OpenDocument-manifest-schema-v1.2-cd1.rng create mode 100644 grammar/OpenDocument-metadata-v1.2-cd04.owl create mode 100644 grammar/OpenDocument-package-metadata-v1.2-cd1.owl create mode 100644 grammar/OpenDocument-schema-v1.0-os.rng create mode 100644 grammar/OpenDocument-schema-v1.1.rng create mode 100644 grammar/OpenDocument-schema-v1.2-cd04.rng create mode 100644 grammar/OpenDocument-strict-schema-v1.0-os.rng create mode 100644 grammar/OpenDocument-strict-schema-v1.1.rng create mode 100755 grammar/gen_allowed_attrs.py create mode 100755 grammar/gen_allowed_children.py create mode 100755 grammar/gen_allows_text.py create mode 100755 grammar/gen_required_attrs.py create mode 100644 grammar/simplification.xsl create mode 100644 grammar/test_grammar.py create mode 100644 mailodf/Makefile create mode 100755 mailodf/mailodf create mode 100644 mailodf/mailodf.1 create mode 100644 mailodf/mailodf.docbook create mode 100644 manual/buildmanual.py create mode 100644 manual/htmlmanual.py create mode 100644 odf/__init__.py create mode 100644 odf/anim.py create mode 100644 odf/attrconverters.py create mode 100644 odf/chart.py create mode 100644 odf/config.py create mode 100644 odf/dc.py create mode 100644 odf/dr3d.py create mode 100644 odf/draw.py create mode 100644 odf/easyliststyle.py create mode 100644 odf/element.py create mode 100644 odf/elementtypes.py create mode 100644 odf/form.py create mode 100644 odf/grammar.py create mode 100644 odf/load.py create mode 100644 odf/manifest.py create mode 100644 odf/math.py create mode 100644 odf/meta.py create mode 100644 odf/namespaces.py create mode 100644 odf/number.py create mode 100644 odf/odf2moinmoin.py create mode 100644 odf/odf2xhtml.py create mode 100644 odf/odfmanifest.py create mode 100644 odf/office.py create mode 100644 odf/opendocument.py create mode 100644 odf/presentation.py create mode 100644 odf/script.py create mode 100644 odf/style.py create mode 100644 odf/svg.py create mode 100644 odf/table.py create mode 100644 odf/teletype.py create mode 100644 odf/text.py create mode 100644 odf/thumbnail.py create mode 100644 odf/userfield.py create mode 100644 odf/xforms.py create mode 100644 odf2mht/Makefile create mode 100755 odf2mht/odf2mht create mode 100644 odf2mht/odf2mht.1 create mode 100644 odf2mht/odf2mht.docbook create mode 100644 odf2xhtml/Makefile create mode 100755 odf2xhtml/odf2xhtml create mode 100644 odf2xhtml/odf2xhtml.1 create mode 100644 odf2xhtml/odf2xhtml.docbook create mode 100644 odf2xml/Makefile create mode 100755 odf2xml/odf2xml create mode 100644 odf2xml/odf2xml.1 create mode 100644 odf2xml/odf2xml.docbook create mode 100644 odfimgimport/Makefile create mode 100755 odfimgimport/odfimgimport create mode 100644 odfimgimport/odfimgimport.1 create mode 100644 odfimgimport/odfimgimport.docbook create mode 100644 odfimgimport/textWithImages.odt create mode 100644 odflint/Makefile create mode 100755 odflint/odflint create mode 100644 odflint/odflint.1 create mode 100644 odflint/odflint.docbook create mode 100644 odfmeta/Makefile create mode 100755 odfmeta/odfmeta create mode 100644 odfmeta/odfmeta.1 create mode 100644 odfmeta/odfmeta.docbook create mode 100644 odfoutline/Makefile create mode 100755 odfoutline/odfoutline create mode 100644 odfoutline/odfoutline.1 create mode 100644 odfoutline/odfoutline.docbook create mode 100644 odfuserfield/Makefile create mode 100755 odfuserfield/odfuserfield create mode 100644 odfuserfield/odfuserfield.1 create mode 100644 odfuserfield/odfuserfield.docbook create mode 100644 samples/Bluff Crag.odt create mode 100644 samples/Electra.odt create mode 100644 samples/spreadsheet-with-macro.ods create mode 100644 setup.py create mode 100644 tests/Makefile create mode 100644 tests/elementparser.py create mode 100644 tests/examples/cols.odp create mode 100644 tests/examples/definitionlists.odt create mode 100644 tests/examples/emb_spreadsheet.odp create mode 100644 tests/examples/headerfooter.odt create mode 100644 tests/examples/images.odt create mode 100644 tests/examples/imageslabels.odt create mode 100644 tests/examples/no_userfields.odt create mode 100644 tests/examples/ol.odp create mode 100644 tests/examples/parastyles.odt create mode 100644 tests/examples/pythagoras-kspread.ods create mode 100644 tests/examples/pythagoras.ods create mode 100644 tests/examples/serious_poem.odt create mode 100644 tests/examples/simplelist.odt create mode 100644 tests/examples/simplestyles.odt create mode 100644 tests/examples/simpletable.odt create mode 100644 tests/examples/twolevellist.odt create mode 100644 tests/examples/userfields.odt create mode 100644 tests/examples/userfields_ooo3.odt create mode 100755 tests/runtests create mode 100644 tests/testchart.py create mode 100644 tests/testconverters.py create mode 100644 tests/testdatastyles.py create mode 100644 tests/testdrawelement.py create mode 100644 tests/testeasyliststyle.py create mode 100644 tests/testform.py create mode 100644 tests/testlengths.py create mode 100644 tests/testload.py create mode 100644 tests/testmasterstyles.py create mode 100644 tests/testmoinmoin.py create mode 100644 tests/testpresentations.py create mode 100644 tests/teststyleref.py create mode 100644 tests/teststyles.py create mode 100644 tests/testsubobjects.py create mode 100644 tests/testtext.py create mode 100644 tests/testtypes.py create mode 100644 tests/testunicode.py create mode 100644 tests/testuserfields.py create mode 100644 tests/testwhitespace.py create mode 100644 tests/testwrite.py create mode 100644 tests/testxhtml.py create mode 100644 tests/testxmlgen.py create mode 100644 xml2odf/Makefile create mode 100644 xml2odf/definitionlists.xml create mode 100755 xml2odf/xml2odf create mode 100644 xml2odf/xml2odf.1 create mode 100644 xml2odf/xml2odf.docbook diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eeaf92c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +.pyc diff --git a/APACHE-LICENSE-2.0.txt b/APACHE-LICENSE-2.0.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/APACHE-LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..26f5335 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,24 @@ +1.3 + A new edition of odfpy to support Python3. + + This version has been reworked by Georges Khaznadar , + to add Python3 support. + +1.2 + Support ODF 1.2 + +past 0.9 + Made sure userfield.py works with OpenOffice.org 3.x files. +0.9 + Updated to ODF version 1.1 +0.8 + Added the ability to load a document. +0.7 + Refactored command-line tool odfuserfied into odf.userfield as a + library and adapted odfuserfied to use this library. + +0.6.1 + TODO: collect changes from svn check-in messages + +0.6 + Implemented subobjects. diff --git a/GPL-LICENSE-2.txt b/GPL-LICENSE-2.txt new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/GPL-LICENSE-2.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..b30ce7d --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,5 @@ +include *.txt api-for-odfpy.odt +recursive-include * *.1 *.docbook Makefile +recursive-include tests *.txt *.py runtests *.odt *.ods *.odp +recursive-include examples *.txt *.py +recursive-include contrib *.txt *.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..50c2fee --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# ODFPY + +This is a collection of utility programs written in Python to manipulate +OpenDocument 1.2 files. + +How to proceed: Each application has its own directory. In there, look +at the manual pages. The Python-based tools need the odf library. Just +make a symbolic link like this: ln -s ../odf odf +... or type: make + +For your own use of the odf library, see api-for-odfpy.odt + +## INSTALLATION + +First you get the package. + + $ git clone https://github.com/eea/odfpy.git + +Then you can build and install the library for Python2 and Python3: + +``` +$ python setup.py build +$ python3 setup.py build +$ su +# python setup.py install +# python3 setup.py install +``` +The library is incompatible with PyXML. + +## ISSUES + +If you run the tests with python3, you will probably see one error. +It is probably a flaw in the command assertRaises of Python3: the +right exception is raised, but it is not correctly identified by +Python3's assertRaises. + +## REDISTRIBUTION LICENSE + +This project, with the exception of the OpenDocument schemas, are +Copyright (C) 2006-2014, Daniel Carrera, Alex Hudson, Søren Roug, +Thomas Zander, Roman Fordinal, Michael Howitz and Georges Khaznadar. + +It is distributed under both GNU General Public License v.2 or (at +your option) any later version or APACHE License v.2. +See GPL-LICENSE-2.txt and APACHE-LICENSE-2.0.txt. + +The OpenDocument RelaxNG Schemas are Copyright © OASIS Open 2005. See +the schema files for their copyright notice. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +## TODO / IDEAS + +* html2odf + Alex Hudson has been contracted to produce a command-line html2odf + converter. It should include support for images, tables, CSS, etc. + He will provide a C# version first, and later a C version. + +* odf2pdf + A valuable tool, but one that is hard to do. PDF is an immensely + popular format, but it's tricky to make PDFs. With an odf2pdf tool + available, many developers would use ODF purely for the purpose of + generating a PDF later. The latest idea is to hire KOffice + developers and get them to trim down KOffice into a converter. + +* pdf2odf + This conversion is less likely to produce good results, but it + might be worth a shot. Poppler is a pdf library that can convert + PDF into XML. Maybe we can convert that XML to ODF. + http://webcvs.freedesktop.org/poppler/poppler/ + +* odfclean + A command-line program that removes unused automatic styles, + metadata and track-changes. Some companies might like to send all + out-going files through odfclean to remove any information they + don't want others to see. + +* odf2xliff + Create XLIFF extraction and merge application. XLIFF is a OASIS file + for translations. You extract the text strings, send them to the translator + and then import them. It allows you to work on the document in the + meantime and only retranslate the changed parts. + +* odfdiff + A program that can generate a diff between two ODF files. Useful for + SVN commit messages. This is very difficult to do. But see: + http://www.manageability.org/blog/stuff/open-source-xml-diff-in-java/view + http://freshmeat.net/projects/xmldiff/ + +* odfsign + Sign and verify the signature(s) of an ODF document. diff --git a/api-for-odfpy.odt b/api-for-odfpy.odt new file mode 100644 index 0000000000000000000000000000000000000000..7f4b21cf3dcaedb2db1a742317b1000d6e606f25 GIT binary patch literal 75143 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 literal 0 HcmV?d00001 diff --git a/config.dox b/config.dox new file mode 100644 index 0000000..bf460ff --- /dev/null +++ b/config.dox @@ -0,0 +1,2312 @@ +# Doxyfile 1.8.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = ODFPY + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = 1.2.0 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is included in +# the documentation. The maximum height of the logo should not exceed 55 pixels +# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo +# to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a +# new page for each member. If set to NO, the documentation of a member will be +# part of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = YES + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO these classes will be included in the various overviews. This option has +# no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the +# todo list. This list is created by putting \todo commands in the +# documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the +# test list. This list is created by putting \test commands in the +# documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES the list +# will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = "true" + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. Do not use file names with spaces, bibtex cannot handle them. See +# also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO doxygen will only warn about wrong or incomplete parameter +# documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. +# Note: If this tag is empty the current directory is searched. + +INPUT = odf + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank the +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, +# *.qsf, *.as and *.js. + +FILE_PATTERNS = *.py + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = /usr/bin/doxypy + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER ) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = YES + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 8 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- +# defined cascading style sheet that is included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefor more robust against future updates. +# Doxygen will copy the style sheet file to the output directory. For an example +# see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the stylesheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated ( +# YES) or that it should be included in the master .chm file ( NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated ( +# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = YES + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = YES + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /
""" + name = self.find_attr(attrs,'id') + if name is None: + self.sectnum = self.sectnum + 1 + name = "Sect%d" % self.sectnum + self.write_odt(u'' % name) + + def e_html_section(self, tag): + """ Outputs block tag such as

and

""" + self.write_odt(u'') + + def s_html_block(self, tag, attrs): + """ Outputs block tag such as

and

""" + self.write_odt(u'') + + def e_html_block(self, tag): + """ Outputs block tag such as

and

""" + self.write_odt(u'') +# +# HANDLE STARTTAG +# + def handle_starttag(self, tag, attrs): + self.pstack.append( (self.processelem, self.processcont) ) + tagobj = TagObject(tag, attrs, self.last_data_pos()) + self.tagstack.append(tagobj) + + method = self.elements.get(tag, (None, None))[0] + if self.processelem and method: + method(tag, attrs) +# +# HANDLE END +# + def handle_endtag(self, tag): + """ + """ + tagobj = self.tagstack.pop() + method = self.elements.get(tag, (None, None))[1] + if self.processelem and method: + method(tag) + self.processelem, self.processcont = self.pstack.pop() + + +# +# Data operations +# + def handle_data(self, data): + if self.processelem and self.processcont: + self.write_odt(escape(data)) + + def write_odt(self, data): + """ Collect the data to show on the webpage """ + if type(data) == StringType: + data = unicode(data, self.encoding) + self.__data.append(data) + + def last_data_pos(self): + return len(self.__data) + + def find_attr(self, attrs, key): + """ Run through the attibutes to find a specific one + return None if not found + """ + for attr in attrs: + if attr[0] == key: + return attr[1] + return None + +# +# Tagstack operations +# + def find_tag(self, tag): + """ Run down the stack to find the last entry with the same tag name + Not Tested + """ + for tagitem in range(len(self.tagstack), 0, -1): + if tagitem.tag == tag: + return tagitem + return None + + def handle_charref(self, name): + """ Handle character reference for UNICODE + """ + if name[0] in ('x', 'X'): + try: + n = int(name[1:],16) + except ValueError: + return + else: + try: + n = int(name) + except ValueError: + return + if not 0 <= n <= 65535: + return + self.handle_data(unichr(n)) + + def handle_entityref(self, name): + """Handle entity references. + """ + table = htmlentitydefs.name2codepoint + if name in table: + self.handle_data(unichr(table[name])) + else: + return + + def handle_attr(self, attrval): + """ Scan attribute values for entities and resolve them + Simply calls handle_data + """ + i = 0 + n = len(attrval) + while i < n: + match = ampersand.search(attrval, i) # + if match: + j = match.start() + else: + j = n + if i < j: self.handle_data(attrval[i:j]) + i = j + if i == n: break + startswith = attrval.startswith + if startswith('&#', i): + match = charref.match(attrval, i) + if match: + name = match.group()[2:-1] + self.handle_charref(name) + k = match.end() + if not startswith(';', k-1): + k = k - 1 + i = k + continue + else: + break + elif startswith('&', i): + match = entityref.match(attrval, i) + if match: + name = match.group(1) + self.handle_entityref(name) + k = match.end() + if not startswith(';', k-1): + k = k - 1 + i = k + continue + match = incomplete.match(attrval, i) + if match: + # match.group() will contain at least 2 chars + if match.group() == attrval[i:]: + self.error("EOF in middle of entity or char ref") + # incomplete + break + elif (i + 1) < n: + # not the end of the buffer, and can't be confused + # with some other construct + self.handle_data("&") + i = i + 1 + else: + break + else: + assert 0, "interesting.search() lied" + # end while + if i < n: + self.handle_data(attrval[i:n]) + i = n + +if __name__ == "__main__": + import sys + result = checkurl(sys.argv[1]) + sys.stdout.write('\n'.join(emptycontent.chead)) + sys.stdout.write(result.encode('utf-8')) + sys.stdout.write('\n'.join(emptycontent.cfoot)) + sys.stdout.write('\n') + + diff --git a/contrib/html2odt/htmlstyles.py b/contrib/html2odt/htmlstyles.py new file mode 100644 index 0000000..1cec24e --- /dev/null +++ b/contrib/html2odt/htmlstyles.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2007 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from odf.style import Style, ParagraphProperties, TextProperties + +def addStandardStyles(doc): + style = Style(name="Standard", family="paragraph", attributes={'class':"text"}) + doc.styles.addElement(style) + + style = Style(name="Text_20_body", displayname="Text body", family="paragraph", parentstylename="Standard", attributes={'class':"text"}) + p = ParagraphProperties(margintop="0cm", marginbottom="0.212cm") + style.addElement(p) + doc.styles.addElement(style) + + style = Style(name="List_20_Contents", displayname="List Contents", family="paragraph", parentstylename="Standard", attributes={'class':"html"}) + p = ParagraphProperties(marginleft="1cm", marginright="0cm", textindent="0cm", autotextindent="false") + style.addElement(p) + doc.styles.addElement(style) + + + style = Style(name="List_20_Heading", displayname="List Heading", family="paragraph", parentstylename="Standard", + nextstylename="List_20_Contents", attributes={'class':"html"}) + p = ParagraphProperties(marginleft="0cm", marginright="0cm", textindent="0cm", autotextindent="false") + style.addElement(p) + doc.styles.addElement(style) + + style = Style(name="Text_20_body_20_indent", displayname="Text body indent", family="paragraph", parentstylename="Text_20_body", attributes={'class':"text"}) + p = ParagraphProperties(marginleft="0.499cm", marginright="0cm", textindent="0cm", autotextindent="false") + style.addElement(p) + doc.styles.addElement(style) + + style = Style(name="Heading", family="paragraph", parentstylename="Standard", nextstylename="Text_20_body", attributes={'class':"text"}) + p = ParagraphProperties(margintop="0.423cm", marginbottom="0.212cm", keepwithnext="always") + style.addElement(p) + p = TextProperties(fontname="Nimbus Sans L", fontsize="14pt", fontnameasian="DejaVu LGC Sans", fontsizeasian="14pt", fontnamecomplex="DejaVu LGC Sans", fontsizecomplex="14pt") + style.addElement(p) + doc.styles.addElement(style) + + style = Style(name="Heading_20_1", displayname="Heading 1", family="paragraph", parentstylename="Heading", nextstylename="Text_20_body", attributes={'class':"text"}, defaultoutlinelevel=1) + p = TextProperties(fontsize="115%", fontweight="bold", fontsizeasian="115%", fontweightasian="bold", fontsizecomplex="115%", fontweightcomplex="bold") + style.addElement(p) + doc.styles.addElement(style) + + style = Style(name="Heading_20_2", displayname="Heading 2", family="paragraph", parentstylename="Heading", nextstylename="Text_20_body", attributes={'class':"text"}, defaultoutlinelevel=2) + p = TextProperties(fontsize="14pt", fontstyle="italic", fontweight="bold", fontsizeasian="14pt", fontstyleasian="italic", fontweightasian="bold", fontsizecomplex="14pt", fontstylecomplex="italic", fontweightcomplex="bold") + style.addElement(p) + doc.styles.addElement(style) + + style = Style(name="Heading_20_3", displayname="Heading 3", family="paragraph", parentstylename="Heading", nextstylename="Text_20_body", attributes={'class':"text"}, defaultoutlinelevel=3) + p = TextProperties(fontsize="14pt", fontweight="bold", fontsizeasian="14pt", fontweightasian="bold", fontsizecomplex="14pt", fontweightcomplex="bold") + style.addElement(p) + doc.styles.addElement(style) + + style = Style(name="List", family="paragraph", parentstylename="Text_20_body", attributes={'class':"list"}) + doc.styles.addElement(style) + + style = Style(name="Caption", family="paragraph", parentstylename="Standard", attributes={'class':"extra"}) + p = ParagraphProperties(margintop="0.212cm", marginbottom="0.212cm", numberlines="false", linenumber="0") + style.addElement(p) + p = TextProperties(fontsize="12pt", fontstyle="italic", fontsizeasian="12pt", fontstyleasian="italic", fontsizecomplex="12pt", fontstylecomplex="italic") + style.addElement(p) + doc.styles.addElement(style) + + style = Style(name="Index", family="paragraph", parentstylename="Standard", attributes={'class':"index"}) + p = ParagraphProperties(numberlines="false", linenumber=0) + doc.styles.addElement(style) + + style = Style(name="Source_20_Text", displayname="Source Text", family="text") + p = TextProperties(fontname="Courier", fontnameasian="Courier", fontnamecomplex="Courier") + style.addElement(p) + doc.styles.addElement(style) + + style = Style(name="Variable", family="text") + p = TextProperties(fontstyle="italic", fontstyleasian="italic", fontstylecomplex="italic") + style.addElement(p) + doc.styles.addElement(style) + + style = Style(name="Emphasis", family="text") + p = TextProperties(fontstyle="italic", fontstyleasian="italic", fontstylecomplex="italic") + style.addElement(p) + doc.styles.addElement(style) + + style = Style(name="Strong_20_Emphasis", displayname="Strong Emphasis", family="text") + p = TextProperties(fontweight="bold", fontweightasian="bold", fontweightcomplex="bold") + style.addElement(p) + doc.styles.addElement(style) + +# Automatic styles + style = Style(name="Bold", displayname="Bold", family="text") + p = TextProperties(fontweight="bold", fontweightasian="bold", fontweightcomplex="bold") + style.addElement(p) + doc.automaticstyles.addElement(style) + + style = Style(name="Italic", family="text") + p = TextProperties(fontstyle="italic", fontstyleasian="italic", fontstylecomplex="italic") + style.addElement(p) + doc.automaticstyles.addElement(style) + diff --git a/contrib/html2odt/shtml2odt.py b/contrib/html2odt/shtml2odt.py new file mode 100644 index 0000000..d71fbfc --- /dev/null +++ b/contrib/html2odt/shtml2odt.py @@ -0,0 +1,619 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2008-2009 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +# +import string, sys, re, getopt +import urllib2, htmlentitydefs, urlparse +from urllib import quote_plus +from HTMLParser import HTMLParser +from cgi import escape,parse_header +from types import StringType + +from odf.opendocument import OpenDocumentText, load +from odf import dc, text, table +import htmlstyles + + +def converturl(url, document=None): + """ grab and convert url + """ + url = string.strip(url) +# if url.lower()[:5] != "http:": +# raise IOError, "Only http is accepted" + + _proxies = {} + proxy_support = urllib2.ProxyHandler(_proxies) + opener = urllib2.build_opener(proxy_support, urllib2.HTTPHandler) + + urllib2.install_opener(opener) + + req = urllib2.Request(url) + req.add_header("User-agent", "HTML2ODT: Convert HTML to OpenDocument") + conn = urllib2.urlopen(req) + + if not conn: + raise IOError, "Failure in open" + data = conn.read() + headers = conn.info() + conn.close() + + encoding = 'iso8859-1' #Standard HTML + if headers.has_key('content-type'): + (ct, parms) = parse_header(headers['content-type']) + if parms.has_key('charset'): + encoding = parms['charset'] + + mhp = HTML2ODTParser(document, encoding, url) + mhp.feed(data) + return mhp + +entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]') +charref = re.compile('&#(?:[0-9]+|[xX][0-9a-fA-F]+)[^0-9a-fA-F]') +incomplete = re.compile('&[a-zA-Z#]') +ampersand = re.compile('&') + +def listget(list, key, default=None): + for l in list: + if l[0] == key: + default = l[1] + return default + +class TagObject: + + def __init__(self, tag, attrs, output_loc): + self.tag = tag + self.attrs = attrs + self.output_loc = output_loc + +class HTML2ODTParser(HTMLParser): + + def __init__(self, document, encoding, baseurl): + HTMLParser.__init__(self) + self.doc = document + self.curr = self.doc.text + if self.doc.getStyleByName("Standard") is None: + style = Style(name="Standard", family="paragraph", attributes={'class':"text"}) + self.doc.styles.addElement(style) + + if self.doc.getStyleByName("Text_20_body") is None: + style = Style(name="Text_20_body", displayname="Text body", family="paragraph", + parentstylename="Standard", attributes={'class':"text"}) + p = ParagraphProperties(margintop="0cm", marginbottom="0.212cm") + style.addElement(p) + self.doc.styles.addElement(style) + + if self.doc.getStyleByName("Heading") is None: + style = Style(name="Heading", family="paragraph", parentstylename="Standard", + nextstylename="Text_20_body", attributes={'class':"text"}) + p = ParagraphProperties(margintop="0.423cm", marginbottom="0.212cm", keepwithnext="always") + style.addElement(p) + p = TextProperties(fontname="Nimbus Sans L", fontsize="14pt", + fontnameasian="DejaVu LGC Sans", fontsizeasian="14pt", + fontnamecomplex="DejaVu LGC Sans", fontsizecomplex="14pt") + style.addElement(p) + self.doc.styles.addElement(style) + + self.encoding = encoding + (scheme, host, path, params, fragment) = urlparse.urlsplit(baseurl) + lastslash = path.rfind('/') + if lastslash > -1: + path = path[:lastslash] + self.baseurl = urlparse.urlunsplit((scheme, host, path,'','')) + self.basehost = urlparse.urlunsplit((scheme, host, '','','')) + self.sectnum = 0 + self.tagstack = [] + self.pstack = [] + self.processelem = True + self.processcont = True + self.__data = [] + self.elements = { + 'a': (self.s_html_a, self.close_tag), + 'base': ( self.output_base, None), + 'b': ( self.s_html_fontstyle, self.close_tag), + 'big': ( self.s_html_fontstyle, self.close_tag), + 'br': ( self.output_br, None), + 'col': ( self.s_html_col, None), + 'dd': ( self.s_html_dd, self.close_tag), + 'dt': ( self.s_html_dt, None), + 'div': ( self.s_html_section, self.e_html_section), + 'em': ( self.s_html_emphasis, self.close_tag), + 'h1': ( self.s_html_headline, self.close_tag), + 'h2': ( self.s_html_headline, self.close_tag), + 'h3': ( self.s_html_headline, self.close_tag), + 'h4': ( self.s_html_headline, self.close_tag), + 'h5': ( self.s_html_headline, self.close_tag), + 'h6': ( self.s_html_headline, self.close_tag), + 'head': ( self.s_ignorexml, None), + 'i': ( self.s_html_fontstyle, self.close_tag), + 'img': ( self.output_img, None), + 'li': ( self.s_html_li, self.e_html_li), + 'meta': ( self.meta_encoding, None), + 'ol': ( self.output_ol, self.e_html_list), + 'p': ( self.s_html_block, self.e_html_block), + 's': ( self.s_html_fontstyle, self.close_tag), + 'small':( self.s_html_fontstyle, self.close_tag), + 'span': ( self.s_html_span, self.close_tag), + 'strike':( self.s_html_fontstyle, self.close_tag), + 'strong':( self.s_html_emphasis, self.close_tag), + 'table':( self.s_html_table, self.e_html_table), + 'td': ( self.s_html_td, self.close_tag), + 'th': ( self.s_html_td, self.close_tag), + 'title':( self.s_html_title, self.e_html_title), + 'tr': ( self.s_html_tr, self.close_tag), + 'tt': ( self.s_html_fontstyle, self.close_tag), + 'u': ( self.s_html_fontstyle, self.close_tag), + 'ul': ( self.output_ul, self.e_html_list), + 'var': ( self.s_html_emphasis, self.close_tag), + } + + def result(self): + """ Return a string + String must be in UNICODE + """ + str = string.join(self.__data,'') + self.__data = [] + return str + + def meta_name(self, attrs): + """ Look in meta tag for textual info""" + foundit = 0 + # Is there a name attribute? + for attr in attrs: + if attr[0] == 'name' and string.lower(attr[1]) in ('description', + 'keywords','title', + 'dc.description','dc.keywords','dc.title' + ): + foundit = 1 + if foundit == 0: + return 0 + + # Is there a content attribute? + content = self.find_attr(attrs,'content') + if content: + self.handle_data(u' ') + self.handle_attr(content) + self.handle_data(u' ') + return 1 + + def meta_encoding(self, tag, attrs): + """ Look in meta tag for page encoding (Content-Type)""" + foundit = 0 + # Is there a content-type attribute? + for attr in attrs: + if attr[0] == 'http-equiv' and string.lower(attr[1]) == 'content-type': + foundit = 1 + if foundit == 0: + return 0 + + # Is there a content attribute? + for attr in attrs: + if attr[0] == 'content': + (ct, parms) = parse_header(attr[1]) + if parms.has_key('charset'): + self.encoding = parms['charset'] + return 1 + + def s_ignorexml(self, tag, attrs): + self.processelem = False + + def output_base(self, tag, attrs): + """ Change the document base if there is a base tag """ + baseurl = listget(attrs, 'href', self.baseurl) + (scheme, host, path, params, fragment) = urlparse.urlsplit(baseurl) + lastslash = path.rfind('/') + if lastslash > -1: + path = path[:lastslash] + self.baseurl = urlparse.urlunsplit((scheme, host, path,'','')) + self.basehost = urlparse.urlunsplit((scheme, host, '','','')) + + def output_br(self, tag, attrs): + self.curr.addElement(text.LineBreak()) + + def s_html_font(self, tag, attrs): + """ 15.2.1 Font style elements: the TT, I, B, BIG, SMALL, + STRIKE, S, and U elements + """ + tagdict = { + } + + def s_html_emphasis(self, tag, attrs): + """ 9.2.1 Phrase elements: EM, STRONG, DFN, CODE, SAMP, KBD, + VAR, CITE, ABBR, and ACRONYM + """ + tagdict = { + 'cite': ['Citation', {'fontstyle':"italic", 'fontstyleasian':"italic", 'fontstylecomplex':"italic" }], + 'code': ['Source_20_Text', {'fontname':"Courier", 'fontnameasian':"Courier",'fontnamecomplex':"Courier" }], + 'dfn': ['Definition',{ }], + 'em': ['Emphasis', {'fontstyle':"italic", 'fontstyleasian':"italic", 'fontstylecomplex':"italic" }], + 'strong': ['Strong_20_Emphasis': {'fontweight':"bold",'fontweightasian':"bold",'fontweightcomplex':"bold"}], + 'var': ['Variable', {'fontstyle':"italic", 'fontstyleasian':"italic", 'fontstylecomplex':"italic" }], + } + stylename = tagdict.get(tag,'Emphasis') + # Add the styles we need to the stylesheet + if stylename == "Source_20_Text" and self.doc.getStyleByName(stylename) is None: + style = Style(name="Source_20_Text", displayname="Source Text", family="text") + p = TextProperties(fontname="Courier", fontnameasian="Courier", fontnamecomplex="Courier") + style.addElement(p) + self.doc.styles.addElement(style) + + e = text.Span(stylename=stylename) + self.curr.addElement(e) + self.curr = e + + def s_html_fontstyle(self, tag, attrs): + """ 15.2.1 Font style elements: the TT, I, B, BIG, SMALL, + STRIKE, S, and U elements + ('tt' is not considered an automatic style by OOo) + """ + tagdict = { + 'b': ['BoldX',{'fontweight':"bold", + 'fontweightasian':"bold",'fontweightcomplex':"bold" }], + 'big': ['BigX', {'fontsize':"120%"}], + 'i': ['ItalicX', {'fontstyle':"italic", 'fontstyleasian':"italic", 'fontstylecomplex':"italic" }], + 'tt': ['TeletypeX', {'fontname':"Courier", 'fontnameasian':"Courier", 'fontnamecomplex':"Courier" }], + 's': ['StrikeX', {'textlinethroughstyle':"solid"}], + 'small': ['SmallX', {'fontsize':"80%"}], + 'strike': ['StrikeX', {'textlinethroughstyle':"solid"}], + 'u': ['UnderlineX', {'textunderlinestyle':"solid", 'textunderlinewidth':"auto", + 'textunderlinecolor':"fontcolor"}], + } + stylename,styledecl = tagdict.get(tag,[None,None]) + if stylename and self.doc.getStyleByName(stylename) is None: + style = Style(name=stylename, family="text") + style.addElement(TextProperties(attributes=styledecl)) + self.doc.automaticstyles.addElement(style) + if stylename: + e = text.Span(stylename=stylename) + else: + e = text.Span() + self.curr.addElement(e) + self.curr = e + + + def s_html_span(self, tag, attrs): + e = text.Span() + self.curr.addElement(e) + self.curr = e + + def s_html_title(self, tag, attrs): + e = dc.Title() + self.doc.meta.addElement(e) + self.curr = e + + def e_html_title(self, tag): + self.curr = self.curr.parentNode + + def output_img(self, tag, attrs): + src = listget(attrs, 'src', "Illegal IMG tag!") + alt = listget(attrs, 'alt', src) + # Must remember name of image and download it. + self.write_odt(u'' % '00000.png') + + def s_html_a(self, tag, attrs): + href = None + href = listget(attrs, 'href', None) + if href: + if href in ("", "#"): + href == self.baseurl + elif href.find("://") >= 0: + pass + elif href[0] == '/': + href = self.basehost + href + e = text.A(type="simple", href=href) + else: + e = text.A() +# if self.curr.parentNode.qname != text.P().qname: +# p = text.P() +# self.curr.addElement(p) +# self.curr = p + self.curr.addElement(e) + self.curr = e + + def close_tag(self, tag): + self.curr = self.curr.parentNode + + def s_html_dd(self, tag, attrs): + if self.doc.getStyleByName("List_20_Contents") is None: + style = Style(name="List_20_Contents", displayname="List Contents", family="paragraph", + parentstylename="Standard", attributes={'class':"html"}) + p = ParagraphProperties(marginleft="1cm", marginright="0cm", textindent="0cm", autotextindent="false") + style.addElement(p) + self.doc.styles.addElement(style) + e = text.P(stylename="List_20_Contents") + self.curr.addElement(e) + self.curr = e + + def s_html_dt(self, tag, attrs): + if self.doc.getStyleByName("List_20_Heading") is None: + style = Style(name="List_20_Heading", displayname="List Heading", family="paragraph", parentstylename="Standard", + nextstylename="List_20_Contents", attributes={'class':"html"}) + p = ParagraphProperties(marginleft="0cm", marginright="0cm", textindent="0cm", autotextindent="false") + style.addElement(p) + self.doc.styles.addElement(style) + e = text.P(stylename="List_20_Heading") + self.curr.addElement(e) + self.curr = e + + def output_ul(self, tag, attrs): + self.write_odt(u'') + + def output_ol(self, tag, attrs): + self.write_odt(u'') + + def e_html_list(self, tag): + self.write_odt(u'') + + def s_html_li(self, tag, attrs): + self.write_odt(u'') + + def e_html_li(self, tag): + self.write_odt(u'') + + def s_html_headline(self, tag, attrs): + stylename = "Heading_20_%s" % tag[1] + if stylename == "Heading_20_1" and self.doc.getStyleByName("Heading_20_1") is None: + style = Style(name="Heading_20_1", displayname="Heading 1", + family="paragraph", parentstylename="Heading", nextstylename="Text_20_body", + attributes={'class':"text"}, defaultoutlinelevel=1) + p = TextProperties(fontsize="115%", fontweight="bold", fontsizeasian="115%", + fontweightasian="bold", fontsizecomplex="115%", fontweightcomplex="bold") + style.addElement(p) + self.doc.styles.addElement(style) + + if stylename == "Heading_20_2" and self.doc.getStyleByName("Heading_20_2") is None: + style = Style(name="Heading_20_2", displayname="Heading 2", + family="paragraph", parentstylename="Heading", nextstylename="Text_20_body", + attributes={'class':"text"}, defaultoutlinelevel=2) + p = TextProperties(fontsize="14pt", fontstyle="italic", fontweight="bold", + fontsizeasian="14pt", fontstyleasian="italic", fontweightasian="bold", + fontsizecomplex="14pt", fontstylecomplex="italic", fontweightcomplex="bold") + style.addElement(p) + self.doc.styles.addElement(style) + + if stylename == "Heading_20_3" and self.doc.getStyleByName("Heading_20_3") is None: + style = Style(name="Heading_20_3", displayname="Heading 3", + family="paragraph", parentstylename="Heading", nextstylename="Text_20_body", + attributes={'class':"text"}, defaultoutlinelevel=3) + p = TextProperties(fontsize="14pt", fontweight="bold", fontsizeasian="14pt", + fontweightasian="bold", fontsizecomplex="14pt", fontweightcomplex="bold") + style.addElement(p) + self.doc.styles.addElement(style) + + e = text.H(stylename="Heading_20_%s" % tag[1], outlinelevel=tag[1]) + self.curr.addElement(e) + self.curr = e + + def s_html_table(self, tag, attrs): + e = table.Table() + self.curr.addElement(e) + self.curr = e + + def e_html_table(self, tag): + self.curr = self.curr.parentNode + + def s_html_td(self, tag, attrs): + e = table.TableCell() + self.curr.addElement(e) + self.curr = e + + def s_html_tr(self, tag, attrs): + e = table.TableRow() + self.curr.addElement(e) + self.curr = e + + def s_html_col(self, tag, attrs): + e = table.TableColumn() + self.curr.addElement(e) + + def s_html_section(self, tag, attrs): + """ Outputs block tag such as

and

""" + name = self.find_attr(attrs,'id') + if name is None: + self.sectnum = self.sectnum + 1 + name = "Sect%d" % self.sectnum + e = text.Section(name=name) + self.curr.addElement(e) + self.curr = e + + def e_html_section(self, tag): + """ Outputs block tag such as

and

""" + self.curr = self.curr.parentNode + + def s_html_block(self, tag, attrs): + """ Outputs block tag such as

and

""" + e = text.P(stylename="Text_20_body") + self.curr.addElement(e) + self.curr = e + + def e_html_block(self, tag): + """ Outputs block tag such as

and

""" + self.curr = self.curr.parentNode +# +# HANDLE STARTTAG +# + def handle_starttag(self, tag, attrs): + self.pstack.append( (self.processelem, self.processcont) ) + tagobj = TagObject(tag, attrs, self.last_data_pos()) + self.tagstack.append(tagobj) + + method = self.elements.get(tag, (None, None))[0] + if self.processelem and method: + method(tag, attrs) +# +# HANDLE END +# + def handle_endtag(self, tag): + """ + """ + tagobj = self.tagstack.pop() + method = self.elements.get(tag, (None, None))[1] + if self.processelem and method: + method(tag) + self.processelem, self.processcont = self.pstack.pop() + + +# +# Data operations +# + def handle_data(self, data): + if data.strip() == '': return + if self.processelem and self.processcont: + self.curr.addText(data) + + def write_odt(self, data): + """ Collect the data to show on the webpage """ + if type(data) == StringType: + data = unicode(data, self.encoding) + self.__data.append(data) + + def last_data_pos(self): + return len(self.__data) + + def find_attr(self, attrs, key): + """ Run through the attibutes to find a specific one + return None if not found + """ + for attr in attrs: + if attr[0] == key: + return attr[1] + return None + +# +# Tagstack operations +# + def find_tag(self, tag): + """ Run down the stack to find the last entry with the same tag name + Not Tested + """ + for tagitem in range(len(self.tagstack), 0, -1): + if tagitem.tag == tag: + return tagitem + return None + + def handle_charref(self, name): + """ Handle character reference for UNICODE + """ + if name[0] in ('x', 'X'): + try: + n = int(name[1:],16) + except ValueError: + return + else: + try: + n = int(name) + except ValueError: + return + if not 0 <= n <= 65535: + return + self.handle_data(unichr(n)) + + def handle_entityref(self, name): + """Handle entity references. + """ + table = htmlentitydefs.name2codepoint + if name in table: + self.handle_data(unichr(table[name])) + else: + return + + def handle_attr(self, attrval): + """ Scan attribute values for entities and resolve them + Simply calls handle_data + """ + i = 0 + n = len(attrval) + while i < n: + match = ampersand.search(attrval, i) # + if match: + j = match.start() + else: + j = n + if i < j: self.handle_data(attrval[i:j]) + i = j + if i == n: break + startswith = attrval.startswith + if startswith('&#', i): + match = charref.match(attrval, i) + if match: + name = match.group()[2:-1] + self.handle_charref(name) + k = match.end() + if not startswith(';', k-1): + k = k - 1 + i = k + continue + else: + break + elif startswith('&', i): + match = entityref.match(attrval, i) + if match: + name = match.group(1) + self.handle_entityref(name) + k = match.end() + if not startswith(';', k-1): + k = k - 1 + i = k + continue + match = incomplete.match(attrval, i) + if match: + # match.group() will contain at least 2 chars + if match.group() == attrval[i:]: + self.error("EOF in middle of entity or char ref") + # incomplete + break + elif (i + 1) < n: + # not the end of the buffer, and can't be confused + # with some other construct + self.handle_data("&") + i = i + 1 + else: + break + else: + assert 0, "interesting.search() lied" + # end while + if i < n: + self.handle_data(attrval[i:n]) + i = n + +def usage(): + sys.stderr.write("Usage: %s [-a] inputurl outputfile\n" % sys.argv[0]) + +if __name__ == "__main__": + try: + opts, args = getopt.getopt(sys.argv[1:], "a", ["append"]) + + except getopt.GetoptError: + usage() + sys.exit(2) + + appendto = False + for o, a in opts: + if o in ("-a", "--append"): + appendto = True + + if appendto: + doc = load(args[1]) + else: + doc = OpenDocumentText() + + result = converturl(args[0], doc) + print result.doc.xml() + result.doc.save(args[1]) + + diff --git a/contrib/odf2epub/Makefile b/contrib/odf2epub/Makefile new file mode 100644 index 0000000..5937d6d --- /dev/null +++ b/contrib/odf2epub/Makefile @@ -0,0 +1,15 @@ +all: odf odf2epub.1 + +txt: odf2epub.txt + +%.1: %.docbook + xmlto man $< + +%.txt: %.docbook + xmlto txt $< + +clean: + rm -f *.txt odf + +odf: + ln -s ../../odf diff --git a/contrib/odf2epub/odf2epub b/contrib/odf2epub/odf2epub new file mode 100755 index 0000000..31158d6 --- /dev/null +++ b/contrib/odf2epub/odf2epub @@ -0,0 +1,350 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2010 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +from odf.odf2xhtml import ODF2XHTML +from odf.namespaces import TEXTNS, XLINKNS +from odf.opendocument import load +import sys, getopt, time, zipfile +from StringIO import StringIO +from cgi import escape + +UNIXPERMS = 0100644 << 16L # -rw-r--r-- + +def escaped(string): + return escape(string).encode('us-ascii','xmlcharrefreplace') + +def usage(): + sys.stderr.write("Usage: %s [-c cover-image] [-o output-file] [-p] inputfile\n" % sys.argv[0]) + +class NavpointEntry: + def __init__(self, anchor, title, chapter, level): + self.anchor = anchor + self.title = title + self.chapter = chapter + self.level = level + +class ODF2EPUB(ODF2XHTML): + + in_toc = False + navpoint_list = [] + chapters = [] + headerpart = [] + cur_html_name = 'chapter0.xhtml' + + def __init__(self, generate_css=True, embedable=False): + ODF2XHTML.__init__(self, generate_css, embedable) + self.elements[(TEXTNS, "table-of-content")] = (self.s_text_table_of_content, self.e_text_table_of_content) + + def s_text_table_of_content(self, tag, attrs): + self.in_toc = True + + def e_text_table_of_content(self, tag, attrs): + self.in_toc = False + +# def s_text_a(self, tag, attrs): +# if self.in_toc: +# href = attrs[(XLINKNS,"href")].split("|")[0] +# if href[0] == "#": +# n = NavpointEntry(self.get_anchor(href[1:]), href[1:]) +# self.navpoint_list.append(n) +# return ODF2XHTML.s_text_a(self, tag, attrs) + +# def e_text_a(self, tag, attrs): +# pass + + def s_text_h(self, tag, attrs): + """ Handle a heading + If the heading is a level 1 heading, then split the HTML file. + We have to be careful, because the heading can be inside a frame or a table. + """ + level = int(attrs[(TEXTNS,'outline-level')]) + if level == 1: + tags_to_keep = self.htmlstack[:] + tags_to_close = self.htmlstack[:] + tags_to_close.reverse() + for htag,hattrs,hblock in tags_to_close: + if htag == 'body': + self.generate_footnotes() + self._resetfootnotes() + self.closetag(htag) + # I have to do this rather ugly, as the saved header part doesn't + # go through the self.opentag() method + self.chapters.append(''.join(self.headerpart + self.lines)) + self.lines = [] + self.htmlstack = tags_to_keep[:2] # Only and + for htag,hattrs,hblock in tags_to_keep[2:]: + self.opentag(htag,hattrs,hblock) + return ODF2XHTML.s_text_h(self, tag, attrs) + + def e_text_h(self, tag, attrs): + """ Headings end """ + level = int(attrs[(TEXTNS,'outline-level')]) + if level > 6: level = 6 # Heading levels go only to 6 in XHTML + if level < 1: level = 1 + lev = self.headinglevels[1:level+1] + outline = '.'.join(map(str,lev) ) + heading = ''.join(self.data) + anchor = self.get_anchor("%s.%s" % ( outline, heading)) + n = NavpointEntry(anchor, heading, len(self.chapters), level) + self.navpoint_list.append(n) + return ODF2XHTML.e_text_h(self, tag, attrs) + + def s_office_text(self, tag, attrs): + """ Save all the lines up to and including the tag + so I can split the file into more files + """ + ODF2XHTML.s_office_text(self, tag, attrs) + self.headerpart = self.lines + self.lines = [] + + def e_office_document_content(self, tag, attrs): + ODF2XHTML.e_office_document_content(self, tag, attrs) + self.chapters.append(''.join(self.headerpart + self.lines)) + self.lines = [] + +class EPublication: + + mimetype = "application/epub+zip" + coverimage = None + + coverhtml = """ + + + Cover + + + +
+ Cover image +
+ +""" + + container = """ + + + + +""" + + content_opf_head = """ + + + %s + %s + %s + %s + %s + + + + """ + + toc_ncx_head = """ + + + + + + + + + + + %s + + + + + Start + + + """ + toc_ncx_foot = """ +""" + + def __init__(self, filename, coverimage): + self.doc = load(filename) + self.coverimage = coverimage + self.odhandler = ODF2EPUB(True, False) + self.odhandler.add_style_file("styles.css") + self.odhandler.load(self.doc) + + def save(self, outputfile): + """ Save the document under the filename """ + if outputfile == '-': + outputfp = zipfile.ZipFile(sys.stdout,"w") + else: + outputfp = zipfile.ZipFile(outputfile, "w") + self._zipwrite(outputfp) + outputfp.close() + + def _zipwrite(self, outputfp): + """ Write the document to an open file pointer """ + now = time.localtime()[:6] + xhtml = self.odhandler.xhtml() + + # Write mimetype - uncompressed + zout = zipfile.ZipInfo('mimetype', now) + zout.compress_type = zipfile.ZIP_STORED + zout.external_attr = UNIXPERMS + outputfp.writestr(zout, self.mimetype) + + # Write META-INF/container.xml + zout = zipfile.ZipInfo('META-INF/container.xml', now) + zout.compress_type = zipfile.ZIP_DEFLATED + zout.external_attr = UNIXPERMS + outputfp.writestr(zout, self.container) + + # Write CSS part + zout = zipfile.ZipInfo('OEBPS/styles.css', now) + zout.compress_type = zipfile.ZIP_DEFLATED + zout.external_attr = UNIXPERMS + outputfp.writestr(zout, self.odhandler.css()) + + # Write HTML parts + for chapter in range(len(self.odhandler.chapters)): + zout = zipfile.ZipInfo('OEBPS/chapter%d.xhtml' % chapter, now) + zout.compress_type = zipfile.ZIP_DEFLATED + zout.external_attr = UNIXPERMS + xhtml = self.odhandler.chapters[chapter].encode('us-ascii','xmlcharrefreplace') + outputfp.writestr(zout, xhtml) + + # Copy images over to output + for arcname, picturerec in self.doc.Pictures.items(): + what_it_is, fileobj, mediatype = picturerec + zi = zipfile.ZipInfo("OEBPS/" + str(arcname), now) + zi.compress_type = zipfile.ZIP_STORED + zi.external_attr = UNIXPERMS + outputfp.writestr(zi, fileobj) + + # Write content.opf + zout = zipfile.ZipInfo('OEBPS/content.opf', now) + zout.compress_type = zipfile.ZIP_DEFLATED + zout.external_attr = UNIXPERMS + opf = [] + if self.coverimage: + covermeta = """""" + else: + covermeta = "" + opf.append(self.content_opf_head % (escaped(self.odhandler.title), escaped(self.odhandler.language), + escaped(args[0]), escaped(self.odhandler.creator), covermeta)) + if self.coverimage: + opf.append(""" """) + opf.append(""" """) + for chapter in range(len(self.odhandler.chapters)): + opf.append(""" """ % (chapter, chapter)) + # Write manifest of images. + for arcname, picturerec in self.doc.Pictures.items(): + what_it_is, fileobj, mediatype = picturerec + opf.append(""" """ % (arcname.replace('/','_'), arcname, mediatype)) + opf.append("""""") + opf.append("""""") + if self.coverimage: + opf.append(""" """) + for chapter in range(len(self.odhandler.chapters)): + opf.append(""" """ % chapter) + opf.append("""""") + + if self.coverimage: + opf.append("""""") + opf.append(""" """) + opf.append("""""") + + opf.append('') + outputfp.writestr(zout, '\n'.join(opf)) + + # Write toc.ncx + zout = zipfile.ZipInfo('OEBPS/toc.ncx', now) + zout.compress_type = zipfile.ZIP_DEFLATED + zout.external_attr = UNIXPERMS + opf = [] + opf.append(self.toc_ncx_head % (escaped(args[0]), escaped(self.odhandler.title))) + # We basically force the first navpoint to be a level 1 heading, no + # matter what it was in reality. Then all other headings are either level 1 or 2. + np_inx = 2 + np_level = 1 + for np in self.odhandler.navpoint_list: + if np_inx == 2: + np.level = 1 + if np.level > 2: np.level = 2 + if np_inx != 2 and np.level <= np_level: + opf.append(""" """); + if np_inx != 2 and np.level < np_level: + opf.append(""" """); + opf.append(""" + + %s + + + """ % (np_inx, np_inx, np.level, escaped(np.title), np.chapter, np.anchor)) + np_inx += 1 + np_level = np.level + opf.append(""" """); + if np_level > 1: + opf.append(""" """); + opf.append(self.toc_ncx_foot) + outputfp.writestr(zout, '\n'.join(opf)) + + # Write cover image + if self.coverimage: + outputfp.write(coverimage,'OEBPS/Pictures/cover.jpg', zipfile.ZIP_STORED) + zout = zipfile.ZipInfo('OEBPS/cover.xhtml', now) + zout.compress_type = zipfile.ZIP_DEFLATED + zout.external_attr = UNIXPERMS + outputfp.writestr(zout, self.coverhtml) + +# zout = zipfile.ZipInfo('OEBPS/styles.css', now) +# zout.compress_type = zipfile.ZIP_DEFLATED +# zout.external_attr = UNIXPERMS +# css = self.odhandler.css().encode('us-ascii','xmlcharrefreplace') +# outputfp.writestr(zout, css) + +try: + opts, args = getopt.getopt(sys.argv[1:], "c:po:", ["cover", "plain","output"]) +except getopt.GetoptError: + usage() + sys.exit(2) + +generatecss = True +embedable = False +outputfilename = "-" +coverimage = None + +for o, a in opts: + if o in ("-c", "--cover"): + coverimage = a + if o in ("-p", "--plain"): + generatecss = False + if o in ("-o", "--output"): + outputfilename = a + +if len(args) != 1: + usage() + sys.exit(2) + +try: + epub = EPublication(args[0], coverimage) + epub.save(outputfilename) +except: + sys.stderr.write("Unable to open file %s or file is not OpenDocument\n" % sys.argv[1]) + sys.exit(1) +sys.exit(0) + diff --git a/contrib/odf2epub/odf2epub.1 b/contrib/odf2epub/odf2epub.1 new file mode 100644 index 0000000..4da6142 --- /dev/null +++ b/contrib/odf2epub/odf2epub.1 @@ -0,0 +1,72 @@ +'\" t +.\" Title: odf2epub +.\" Author: S\(/oren Roug +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 05/16/2010 +.\" Manual: User commands +.\" Source: odfpy +.\" Language: English +.\" +.TH "ODF2EPUB" "1" "05/16/2010" "odfpy" "User commands" +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +odf2epub \- Convert ODF to an ePub ebook +.SH "SYNOPSIS" +.HP \w'\fBodf2epub\fR\ 'u +\fBodf2epub\fR [\-p] [\-o\ \fIoutputfile\fR] [\-c\ \fIcover_image\fR] \fIpath\fR +.SH "DESCRIPTION" +.PP +\fBodf2epub\fR +is a program that will create an ebook (\&.epub) from the input file and will write the ebook to stdout or a file specified by \-o\&. "Path" is assumed to be an OpenDocument file of text, spreadsheet or presentation type\&. +.PP +If the document doesn\'t have a title in the properties, then the first heading of any level is used\&. +.SH "OPTIONS" +.PP +\-c, \-\-cover +.RS 4 +The \-c argument add a cover image to the EPUB file\&. Make sure the cover image itself is scaled to less than 1000px in width and height\&. Best practice is to use an image in JPG or PNG format at 600 pixels wide by 800 pixels in height\&. +.RE +.PP +\-p, \-\-plain +.RS 4 +The \-p flag will generate HTML without CSS\&. +.RE +.PP +\-o, \-\-output +.RS 4 +Specify the output file with this flag\&. "\-" implies standard out\&. +.RE +.SH "EXAMPLE" +.sp +.if n \{\ +.RS 4 +.\} +.nf +odf2epub \-o example\&.epub odf\-file\&.odt +.fi +.if n \{\ +.RE +.\} +.SH "BUGS" +.PP +The EPUB format has the following limitations when running on a mobile device\&. If these limits are not adhered to, EPUB files +\fImight\fR +not work on mobile devices\&. Image Size: 10MB uncompressed\&. Individual XHTML file sizes: 300k uncompressed/100k compressed\&. Odf2epub does not ensure that these limits are adhered to\&. +.SH "SEE ALSO" +.PP +\fBodf2xhtml\fR(1) +.SH "AUTHOR" +.PP +\fBS\(/oren Roug\fR +.RS 4 +Original author +.RE diff --git a/contrib/odf2epub/odf2epub.docbook b/contrib/odf2epub/odf2epub.docbook new file mode 100644 index 0000000..7c6ddea --- /dev/null +++ b/contrib/odf2epub/odf2epub.docbook @@ -0,0 +1,92 @@ + + + + + odfpy + SørenRoug + Original author + + + + odf2epub + 1 + User commands + + + odf2epub + Convert ODF to an ePub ebook + + + + odf2epub + -p + -o outputfile + -c cover_image + + path + + + + + Description + odf2epub is a program that will create +an ebook (.epub) from the input file and will write the ebook to stdout or a file specified by -o. +"Path" is assumed to be an +OpenDocument file of text, spreadsheet or presentation type. + + +If the document doesn't have a title in the properties, then the first heading of any level is used. + + + + + Options + + + -c, --cover + + +The -c argument add a cover image to the EPUB file. +Make sure the cover image itself is scaled to less than 1000px in width and height. Best practice +is to use an image in JPG or PNG format at 600 pixels wide by 800 pixels in height. + + + + + -p, --plain + + +The -p flag will generate HTML without CSS. + + + + + -o, --output + + +Specify the output file with this flag. "-" implies standard out. + + + + + + + + Example + +odf2epub -o example.epub odf-file.odt + + + + Bugs + The EPUB format has the following limitations when running on a mobile device. + If these limits are not adhered to, EPUB files might not work on mobile devices. Image Size: 10MB uncompressed. + Individual XHTML file sizes: 300k uncompressed/100k compressed. Odf2epub does not ensure + that these limits are adhered to. + + + + See Also + odf2xhtml(1) + + diff --git a/contrib/odf2gbzip/Makefile b/contrib/odf2gbzip/Makefile new file mode 100644 index 0000000..2643261 --- /dev/null +++ b/contrib/odf2gbzip/Makefile @@ -0,0 +1,15 @@ +all: odf odf2gbzip.1 + +txt: odf2gbzip.txt + +%.1: %.docbook + xmlto man $< + +%.txt: %.docbook + xmlto txt $< + +clean: + rm -f *.txt odf + +odf: + ln -s ../../odf diff --git a/contrib/odf2gbzip/odf2gbzip b/contrib/odf2gbzip/odf2gbzip new file mode 100755 index 0000000..1e0df1d --- /dev/null +++ b/contrib/odf2gbzip/odf2gbzip @@ -0,0 +1,64 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2006 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +from odf.odf2xhtml import ODF2XHTML +import zipfile +import sys +from time import localtime + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +if len(sys.argv) != 3: + sys.stderr.write("Usage: %s inputfile outputfile\n" % sys.argv[0]) + sys.exit(1) + +inpath = sys.argv[1] +basename = inpath[max(inpath.rfind('/'), inpath.rfind('\\'), inpath.rfind(':'))+1:] +dot = basename.rfind('.') +if dot > 0: basename = basename[:dot] + +now = localtime()[:6] + +odhandler = ODF2XHTML() +result = odhandler.odf2xhtml(inpath).encode('us-ascii','xmlcharrefreplace') + +try: + zout = zipfile.ZipFile(sys.argv[2], "w", zipfile.ZIP_DEFLATED) +except: + sys.stderr.write("Unable to open %s for writing\n" % sys.argv[2]) + +zipinfo = zipfile.ZipInfo('%s/%s.htm' % (basename, basename), now) +zipinfo.external_attr = 0100644 << 16L # Unix permissions +zout.writestr(zipinfo, result) + +try: + z = zipfile.ZipFile(inpath) +except: + sys.stderr.write("Unable to open %s or file is not OpenDocument\n" % sys.argv[2]) + +for zinfo in z.infolist(): + if zinfo.filename[0:9] == 'Pictures/': + zipinfo = zipfile.ZipInfo(basename + "/" + zinfo.filename, now) + zipinfo.external_attr = 0100644 << 16L # Unix permissions + zout.writestr(zipinfo, z.read(zinfo.filename)) +z.close() +zout.close() diff --git a/contrib/odf2gbzip/odf2gbzip.1 b/contrib/odf2gbzip/odf2gbzip.1 new file mode 100644 index 0000000..11cf1d5 --- /dev/null +++ b/contrib/odf2gbzip/odf2gbzip.1 @@ -0,0 +1,35 @@ +.\" Title: odf2gbzip +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.72.0 +.\" Date: 09/29/2007 +.\" Manual: +.\" Source: +.\" +.TH "ODF2GBZIP" "1" "09/29/2007" "" "" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +odf2gbzip \- Convert ODF to zipped web archive +.SH "SYNOPSIS" +.HP 10 +\fBodf2gbzip\fR \fIpath\fR +.SH "DESCRIPTION" +.PP +\fBodf2gbzip\fR +is a program that will create a zipped web archive according to the convention followed by Project Gutenberg. +.PP +"Path" is assumed to be an OpenDocument file of text, spreadsheet or presentation type. +.SH "EXAMPLE" +.sp +.RS 4 +.nf +odf2gbzip odf\-file +.fi +.RE +.SH "SEE ALSO" +.PP + +\fBodf2mht\fR(1) +\fBodf2war\fR(1) diff --git a/contrib/odf2gbzip/odf2gbzip.docbook b/contrib/odf2gbzip/odf2gbzip.docbook new file mode 100644 index 0000000..982ef54 --- /dev/null +++ b/contrib/odf2gbzip/odf2gbzip.docbook @@ -0,0 +1,38 @@ + + + + +odf2gbzip +Convert ODF to zipped web archive + + + + + odf2gbzip + path + + + +Description +odf2gbzip is a program that will create +a zipped web archive according to the convention followed by Project Gutenberg. + + +"Path" is assumed to be an +OpenDocument file of text, spreadsheet or presentation type. + + +Example + +odf2gbzip odf-file + + +See Also + +odf2mht(1) +odf2war(1) + + + + diff --git a/contrib/odf2war/Makefile b/contrib/odf2war/Makefile new file mode 100644 index 0000000..84da278 --- /dev/null +++ b/contrib/odf2war/Makefile @@ -0,0 +1,15 @@ +all: odf odf2war.1 + +txt: odf2war.txt + +%.1: %.docbook + xmlto man $< + +%.txt: %.docbook + xmlto txt $< + +clean: + rm -f *.txt odf + +odf: + ln -s ../odf diff --git a/contrib/odf2war/odf2war b/contrib/odf2war/odf2war new file mode 100755 index 0000000..139c20c --- /dev/null +++ b/contrib/odf2war/odf2war @@ -0,0 +1,61 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2006 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +from odf.odf2xhtml import ODF2XHTML +import tarfile +import zipfile +import sys +from time import time + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +if len(sys.argv) != 3: + sys.stderr.write("Usage: %s inputfile outputfile\n" % sys.argv[0]) + sys.exit(1) + +now = long(time()) +odhandler = ODF2XHTML() +result = odhandler.odf2xhtml(sys.argv[1]).encode('us-ascii','xmlcharrefreplace') +tar = tarfile.open(sys.argv[2], "w:gz") +tarinfo = tarfile.TarInfo() +tarinfo.name = 'index.html' +tarinfo.uid = 501 +tarinfo.gid = 100 +tarinfo.size = len(result) +tarinfo.mtime = now +#tarinfo.uname = "johndoe" +#tarinfo.gname = "fake" +tar.addfile(tarinfo, StringIO(result)) +z = zipfile.ZipFile(sys.argv[1]) +for zinfo in z.infolist(): + if zinfo.filename[0:9] == 'Pictures/': + tarinfo = tarfile.TarInfo() + tarinfo.name = zinfo.filename + tarinfo.uid = 501 + tarinfo.gid = 456 + tarinfo.size = zinfo.file_size + tarinfo.mtime = now + #tarinfo.uname = "johndoe" + #tarinfo.gname = "fake" + tar.addfile(tarinfo, StringIO(z.read(zinfo.filename))) +z.close() +tar.close() diff --git a/contrib/odf2war/odf2war.1 b/contrib/odf2war/odf2war.1 new file mode 100644 index 0000000..fcfded1 --- /dev/null +++ b/contrib/odf2war/odf2war.1 @@ -0,0 +1,217 @@ +.\" Title: odf2war +.\" Author: S\(/oren Roug +.\" Generator: DocBook XSL Stylesheets v1.74.0 +.\" Date: 01/04/2009 +.\" Manual: User commands +.\" Source: odfpy +.\" Language: English +.\" +.TH "ODF2WAR" "1" "01/04/2009" "odfpy" "User commands" +.\" ----------------------------------------------------------------- +.\" * (re)Define some macros +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" toupper - uppercase a string (locale-aware) +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de toupper +.tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ +\\$* +.tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SH-xref - format a cross-reference to an SH section +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de SH-xref +.ie n \{\ +.\} +.toupper \\$* +.el \{\ +\\$* +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SH - level-one heading that works better for non-TTY output +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de1 SH +.\" put an extra blank line of space above the head in non-TTY output +.if t \{\ +.sp 1 +.\} +.sp \\n[PD]u +.nr an-level 1 +.set-an-margin +.nr an-prevailing-indent \\n[IN] +.fi +.in \\n[an-margin]u +.ti 0 +.HTML-TAG ".NH \\n[an-level]" +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +\." make the size of the head bigger +.ps +3 +.ft B +.ne (2v + 1u) +.ie n \{\ +.\" if n (TTY output), use uppercase +.toupper \\$* +.\} +.el \{\ +.nr an-break-flag 0 +.\" if not n (not TTY), use normal case (not uppercase) +\\$1 +.in \\n[an-margin]u +.ti 0 +.\" if not n (not TTY), put a border/line under subheading +.sp -.6 +\l'\n(.lu' +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SS - level-two heading that works better for non-TTY output +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de1 SS +.sp \\n[PD]u +.nr an-level 1 +.set-an-margin +.nr an-prevailing-indent \\n[IN] +.fi +.in \\n[IN]u +.ti \\n[SN]u +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.ps \\n[PS-SS]u +\." make the size of the head bigger +.ps +2 +.ft B +.ne (2v + 1u) +.if \\n[.$] \&\\$* +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" BB/BE - put background/screen (filled box) around block of text +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de BB +.if t \{\ +.sp -.5 +.br +.in +2n +.ll -2n +.gcolor red +.di BX +.\} +.. +.de EB +.if t \{\ +.if "\\$2"adjust-for-leading-newline" \{\ +.sp -1 +.\} +.br +.di +.in +.ll +.gcolor +.nr BW \\n(.lu-\\n(.i +.nr BH \\n(dn+.5v +.ne \\n(BHu+.5v +.ie "\\$2"adjust-for-leading-newline" \{\ +\M[\\$1]\h'1n'\v'+.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] +.\} +.el \{\ +\M[\\$1]\h'1n'\v'-.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] +.\} +.in 0 +.sp -.5v +.nf +.BX +.in +.sp .5v +.fi +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" BM/EM - put colored marker in margin next to block of text +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de BM +.if t \{\ +.br +.ll -2n +.gcolor red +.di BX +.\} +.. +.de EM +.if t \{\ +.br +.di +.ll +.gcolor +.nr BH \\n(dn +.ne \\n(BHu +\M[\\$1]\D'P -.75n 0 0 \\n(BHu -(\\n[.i]u - \\n(INu - .75n) 0 0 -\\n(BHu'\M[] +.in 0 +.nf +.BX +.in +.fi +.\} +.. +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "Name" +odf2war \- Convert ODF to KDE web archive +.SH "Synopsis" +.fam C +.HP \w'\fBodf2war\fR\ 'u +\fBodf2war\fR \fIpath\fR +.fam +.SH "Description" +.PP +\fBodf2war\fR +is a program that will create a KDE Web Archive (\&.war) that can be read by Konqueror filemanager\&. It will write the web archive to stdout\&. The WAR plugin is part of the kdeaddons package\&. +.PP +"Path" is assumed to be an OpenDocument file of text, spreadsheet or presentation type\&. +.SH "Example" +.sp +.if n \{\ +.RS 4 +.\} +.fam C +.ps -1 +.nf +.if t \{\ +.sp -1 +.\} +.BB lightgray adjust-for-leading-newline +.sp -1 + +odf2war odf\-file +.EB lightgray adjust-for-leading-newline +.if t \{\ +.sp 1 +.\} +.fi +.fam +.ps +1 +.if n \{\ +.RE +.\} +.SH "See Also" +.PP + +\fBodftools\fR(1), +\fBodf2mht\fR(1) +.SH "Author" +.PP +\fBS\(/oren Roug\fR +.RS 4 +Original author +.RE diff --git a/contrib/odf2war/odf2war.docbook b/contrib/odf2war/odf2war.docbook new file mode 100644 index 0000000..44bd057 --- /dev/null +++ b/contrib/odf2war/odf2war.docbook @@ -0,0 +1,51 @@ + + + + + odfpy + SørenRoug + Original author + + + + odf2war + 1 + User commands + + +odf2war +Convert ODF to KDE web archive + + + + + odf2war + path + + + +Description +odf2war is a program that will create +a KDE Web Archive (.war) that can be read by Konqueror filemanager. It +will write the web archive to stdout. The WAR plugin is part of the +kdeaddons package. + + +"Path" is assumed to be an +OpenDocument file of text, spreadsheet or presentation type. + + +Example + +odf2war odf-file + + +See Also + +odftools(1), +odf2mht(1) + + + + diff --git a/contrib/odfsign/Makefile b/contrib/odfsign/Makefile new file mode 100644 index 0000000..d07d1e5 --- /dev/null +++ b/contrib/odfsign/Makefile @@ -0,0 +1,14 @@ +all: odf odfsign.1 + +txt: odfsign.txt + +%.1: %.docbook + xmlto man $< + +%.txt: %.docbook + xmlto txt $< + +clean: + rm -f *.txt odf +odf: + ln -s ../../odf diff --git a/contrib/odfsign/odfsign b/contrib/odfsign/odfsign new file mode 100755 index 0000000..216ecbb --- /dev/null +++ b/contrib/odfsign/odfsign @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2006 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +# Requires PyXML +import sha,base64,zipfile,sys +from xml.dom.ext.reader import PyExpat +from xml.dom.ext.c14n import Canonicalize +import StringIO + + +def data_digest(data): + return base64.b64encode(sha.new(data).digest()) + +def xml_digest(dom): + s = StringIO.StringIO() + Canonicalize(dom,s) + canon = s.getvalue().encode('utf-8') + return data_digest(canon) + +def get_signatureproperty(dom, ref): + property_list = dom.getElementsByTagNameNS('http://www.w3.org/2000/09/xmldsig#','SignatureProperty') + for p in property_list: + id = p.getAttributeNS(None,'Id') + if ref == id: return p + return None + +def exitwithusage(exitcode=2): + sys.stderr.write("Usage: %s inputfile\n" % sys.argv[0]) + sys.exit(exitcode) + +if __name__ == '__main__': + if len(sys.argv) != 2: + exitwithusage() + z = zipfile.ZipFile(sys.argv[1]) + namelist = z.namelist() + if "META-INF/documentsignatures.xml" not in namelist: + print "This document is not signed" + sys.exit() + documentsignatures_xml = z.read('META-INF/documentsignatures.xml') + reader = PyExpat.Reader() + doc = reader.fromString(documentsignatures_xml) + + signature_list = doc.getElementsByTagNameNS('http://www.w3.org/2000/09/xmldsig#','Signature') + print "Document has %s signature(s)" % len(signature_list) + signnum = 1 + for signature in signature_list: + date = signature.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/","date")[0].firstChild.nodeValue +# print date.__dict__ + + print "Checking signature #%d - signed on %s" % (signnum, date), + refs = signature.getElementsByTagNameNS('http://www.w3.org/2000/09/xmldsig#','Reference') + for ref in refs: + status = "OK" + uri = ref.getAttributeNS(None,'URI') + digest_value = ref.getElementsByTagNameNS('http://www.w3.org/2000/09/xmldsig#','DigestValue')[0].firstChild.nodeValue + if uri[0] != '#': + document = z.read(uri) + if uri[-4:] == ".xml" and len(document) != 0: + dom = PyExpat.Reader().fromString(document) + digest_actual = xml_digest(dom) + else: + digest_actual = data_digest(document) + else: + # FIXME + # fragments aren't canonicalized. See http://www.w3.org/TR/xmldsig-core/#sec-URI + xmlfragment = get_signatureproperty(doc, uri[1:]) + if xmlfragment is None: + continue + digest_actual = digest_value + #digest_actual = xml_digest(xmlfragment) + if digest_value != digest_actual: + status = "failed" + + print status + signnum += 1 + diff --git a/contrib/odfsign/odfsign.1 b/contrib/odfsign/odfsign.1 new file mode 100644 index 0000000..e135af0 --- /dev/null +++ b/contrib/odfsign/odfsign.1 @@ -0,0 +1,217 @@ +.\" Title: odfsign +.\" Author: S\(/oren Roug +.\" Generator: DocBook XSL Stylesheets v1.74.0 +.\" Date: 03/16/2009 +.\" Manual: User commands +.\" Source: odfpy +.\" Language: English +.\" +.TH "ODFSIGN" "1" "03/16/2009" "odfpy" "User commands" +.\" ----------------------------------------------------------------- +.\" * (re)Define some macros +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" toupper - uppercase a string (locale-aware) +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de toupper +.tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ +\\$* +.tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SH-xref - format a cross-reference to an SH section +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de SH-xref +.ie n \{\ +.\} +.toupper \\$* +.el \{\ +\\$* +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SH - level-one heading that works better for non-TTY output +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de1 SH +.\" put an extra blank line of space above the head in non-TTY output +.if t \{\ +.sp 1 +.\} +.sp \\n[PD]u +.nr an-level 1 +.set-an-margin +.nr an-prevailing-indent \\n[IN] +.fi +.in \\n[an-margin]u +.ti 0 +.HTML-TAG ".NH \\n[an-level]" +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +\." make the size of the head bigger +.ps +3 +.ft B +.ne (2v + 1u) +.ie n \{\ +.\" if n (TTY output), use uppercase +.toupper \\$* +.\} +.el \{\ +.nr an-break-flag 0 +.\" if not n (not TTY), use normal case (not uppercase) +\\$1 +.in \\n[an-margin]u +.ti 0 +.\" if not n (not TTY), put a border/line under subheading +.sp -.6 +\l'\n(.lu' +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SS - level-two heading that works better for non-TTY output +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de1 SS +.sp \\n[PD]u +.nr an-level 1 +.set-an-margin +.nr an-prevailing-indent \\n[IN] +.fi +.in \\n[IN]u +.ti \\n[SN]u +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.ps \\n[PS-SS]u +\." make the size of the head bigger +.ps +2 +.ft B +.ne (2v + 1u) +.if \\n[.$] \&\\$* +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" BB/BE - put background/screen (filled box) around block of text +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de BB +.if t \{\ +.sp -.5 +.br +.in +2n +.ll -2n +.gcolor red +.di BX +.\} +.. +.de EB +.if t \{\ +.if "\\$2"adjust-for-leading-newline" \{\ +.sp -1 +.\} +.br +.di +.in +.ll +.gcolor +.nr BW \\n(.lu-\\n(.i +.nr BH \\n(dn+.5v +.ne \\n(BHu+.5v +.ie "\\$2"adjust-for-leading-newline" \{\ +\M[\\$1]\h'1n'\v'+.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] +.\} +.el \{\ +\M[\\$1]\h'1n'\v'-.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] +.\} +.in 0 +.sp -.5v +.nf +.BX +.in +.sp .5v +.fi +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" BM/EM - put colored marker in margin next to block of text +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de BM +.if t \{\ +.br +.ll -2n +.gcolor red +.di BX +.\} +.. +.de EM +.if t \{\ +.br +.di +.ll +.gcolor +.nr BH \\n(dn +.ne \\n(BHu +\M[\\$1]\D'P -.75n 0 0 \\n(BHu -(\\n[.i]u - \\n(INu - .75n) 0 0 -\\n(BHu'\M[] +.in 0 +.nf +.BX +.in +.fi +.\} +.. +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "Name" +odfsign \- Verify a signed ODF document +.SH "Synopsis" +.fam C +.HP \w'\fBodfsign\fR\ 'u +\fBodfsign\fR \fIpath\fR +.fam +.SH "Description" +.PP +\fBodfsign\fR +checks that the checksums used in the signature are correct\&. +\fIIt does not check that the x509 digest is correct!\fR +Therefore it is currently of little use\&. +.PP +"Path" is assumed to be an OpenDocument file of text, spreadsheet or presentation type\&. +.SH "Example" +.sp +.if n \{\ +.RS 4 +.\} +.fam C +.ps -1 +.nf +.if t \{\ +.sp -1 +.\} +.BB lightgray adjust-for-leading-newline +.sp -1 + +odfsign odf\-file +.EB lightgray adjust-for-leading-newline +.if t \{\ +.sp 1 +.\} +.fi +.fam +.ps +1 +.if n \{\ +.RE +.\} +.SH "See Also" +.PP +http://www\&.w3\&.org/TR/xmldsig\-core +.SH "Author" +.PP +\fBS\(/oren Roug\fR +.RS 4 +Original author +.RE diff --git a/contrib/odfsign/odfsign.docbook b/contrib/odfsign/odfsign.docbook new file mode 100644 index 0000000..f268f28 --- /dev/null +++ b/contrib/odfsign/odfsign.docbook @@ -0,0 +1,50 @@ + + + + + odfpy + SørenRoug + Original author + + + + odfsign + 1 + User commands + + +odfsign +Verify a signed ODF document + + + + + odfsign + path + + + +Description +odfsign checks that the checksums +used in the signature are correct. +It does not check that the x509 digest is correct! +Therefore it is currently of little use. + + +"Path" is assumed to be an +OpenDocument file of text, spreadsheet or presentation type. + + +Example + +odfsign odf-file + + +See Also + +http://www.w3.org/TR/xmldsig-core + + + + diff --git a/contrib/odfsign/testdocs/ClimateChange2.odt b/contrib/odfsign/testdocs/ClimateChange2.odt new file mode 100644 index 0000000000000000000000000000000000000000..f4fa709042edfe74715f6625fce66305530e4b02 GIT binary patch literal 57571 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 literal 0 HcmV?d00001 diff --git a/contrib/odfsign/testdocs/ClimateChange3.odt b/contrib/odfsign/testdocs/ClimateChange3.odt new file mode 100644 index 0000000000000000000000000000000000000000..b3805568f0411d6f88a563648df9397a4f9f83f9 GIT binary patch literal 73828 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

)xl*g;p9!}-4q-o(QOk!88v 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 literal 0 HcmV?d00001 diff --git a/contrib/odftohtmlplugin/0.10/setup.py b/contrib/odftohtmlplugin/0.10/setup.py new file mode 100644 index 0000000..045e319 --- /dev/null +++ b/contrib/odftohtmlplugin/0.10/setup.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2007 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from setuptools import setup + +PACKAGE = 'OdfToHtml' +VERSION = '0.1' + +setup(name='OdfToHtml', + version='0.1', + packages=['odftohtml'], + author='Soren Roug', + author_email='soren.roug@eea.europa.eu', + description='A plugin for viewing ODF pages as HTML', + url='http://trac-hacks.org/wiki/OdfToHtmlConverter', + entry_points={'trac.plugins': ['odftohtml.odftohtml=odftohtml.odftohtml']}) diff --git a/contrib/odscell/Makefile b/contrib/odscell/Makefile new file mode 100644 index 0000000..83b1a73 --- /dev/null +++ b/contrib/odscell/Makefile @@ -0,0 +1,14 @@ +all: odf odscell.1 + +txt: odscell.txt + +%.1: %.docbook + xmlto man $< + +%.txt: %.docbook + xmlto txt $< + +clean: + rm -f *.txt odf +odf: + ln -s ../../odf diff --git a/contrib/odscell/odscell b/contrib/odscell/odscell new file mode 100755 index 0000000..316ad30 --- /dev/null +++ b/contrib/odscell/odscell @@ -0,0 +1,184 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2010 Kartikaya Gupta, https://staktrace.com/ +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from odf import opendocument +from odf.element import Text +from odf.table import * +from odf.text import P +from optparse import OptionParser +import sys,csv,re + +def getSheet( file, sheetIndex ): + doc = opendocument.load( file ) + try: + spreadsheet = doc.spreadsheet + except NameError: + sys.stderr.write("Error: file is not a spreadsheet\n") + return (None, None) + + sheets = spreadsheet.getElementsByType( Table ) + if sheetIndex > len( sheets ): + sys.stderr.write( "Error: spreadsheet has only %d sheets; requested invalid sheet %d\n" % (len( sheets ), sheetIndex + 1) ) + return (None, None) + + sheet = sheets[sheetIndex] + return (doc, sheet) + +def displayCells( file, sheetIndex, rowIndex, colIndex, rowCount, colCount ): + (doc, sheet) = getSheet( file, sheetIndex ) + if (doc == None or sheet == None): + return 1 + + rows = sheet.getElementsByType( TableRow ) + if rowIndex + rowCount > len( rows ): + sys.stderr.write( "Error: sheet has only %d rows; requested invalid row %d\n" % (len( rows ), rowIndex + rowCount) ) + return 1 + + csv_writer = csv.writer( sys.stdout ) + for i in range( rowIndex, rowIndex + rowCount ): + row = rows[ i ] + cells = row.getElementsByType( TableCell ) + if colIndex + colCount > len( cells ): + sys.stderr.write( "Error: row has only %d cells; requested invalid column %d\n" % (len( cells ), colIndex + colCount) ) + return 1 + for j in range( colIndex, colIndex + colCount ): + cells[ j ] = unicode( cells[ j ] ) + csv_writer.writerow( cells[ colIndex : colIndex + colCount ] ) + return 0 + +def updateCells( file, sheetIndex, rowIndex, colIndex, rowCount, colCount ): + (doc, sheet) = getSheet( file, sheetIndex ) + if (doc == None or sheet == None): + return 1 + + data = sys.stdin.readlines() + if rowCount < 0: + rowCount = len( data ) + elif len( data ) < rowCount: + sys.stderr.write( "Error: not enough rows in input\n" ) + return 1 + + # add table rows as necessary + rows = sheet.getElementsByType( TableRow ) + if rowIndex + rowCount > len( rows ): + for i in range( rowIndex + rowCount - len( rows ) ): + sheet.addElement( TableRow() ) + rows = sheet.getElementsByType( TableRow ) + + csv_reader = csv.reader( data ) + for i in range( rowIndex, rowIndex + rowCount ): + row = rows[ i ] + dataRow = csv_reader.next() + rowColCount = colCount + if rowColCount < 0: + rowColCount = len( dataRow ) + elif len( dataRow ) < rowColCount: + sys.stderr.write( "Error: not enough columns in input on row %d\n" % (rowIndex - i + 1) ) + return 1 + + cells = row.getElementsByType( TableCell ) + if colIndex > len( cells ): + for j in range( len( cells ), colIndex ): + row.addElement( TableCell() ) + cells = row.getElementsByType( TableCell ) + + for j in range( colIndex, colIndex + rowColCount ): + if j < len( cells ): + row.insertBefore( TableCell(), cells[ j ].nextSibling ); + row.removeChild( cells[ j ] ) + else: + row.addElement( TableCell() ) + + cells = row.getElementsByType( TableCell ) + value = dataRow[ j - colIndex ] + if re.match( r'^[-]?\d+(\.\d+)?$', value.strip() ): + cells[ j ].setAttribute( 'valuetype', 'float' ) + cells[ j ].setAttribute( 'value', value ) + else: + cells[ j ].setAttribute( 'valuetype', 'string' ) + cells[ j ].addElement( P( text = dataRow[ j - colIndex ] ) ) + + doc.save( file ) + return 0 + +def parseCell( cell ): + cellmatch = re.match( r'^([A-Z]+)([0-9]+)$', cell ) + if cellmatch == None: + sys.stderr.write( "Error: the cell specified was not in the required format of (e.g. A1)" ) + exit( 1 ) + + cellcol = cellmatch.group( 1 ) + colIndex = 0 + for i in range( len( cellcol ) ): + colIndex = (colIndex * 26) + (ord( cellcol[i] ) - ord( 'A' ) + 1) + colIndex = colIndex - 1 + + rowIndex = int( cellmatch.group( 2 ) ) - 1 + + return (colIndex, rowIndex) + +def getCount( value, write, label ): + if value == None: + if write: + return -1 + else: + return 1 + + value = int( value ) + if value <= 0: + sys.stderr.write( "Error: illegal value specified for %s\n" % label ) + exit( 1 ) + return value + +if __name__ == "__main__": + usage = "%prog file.ods cell" + parser = OptionParser( usage=usage, version="%prog 0.1" ) + parser.add_option( '-r', '--rows', action='store', dest='rows', help= +'''Specify the height of the block of cells, in rows. Must be greater than zero. Defaults to 1 when +the -w option is not present. Defaults to the number of input rows when the -w option is present.''', default=None ) + parser.add_option( '-c', '--cols', action='store', dest='cols', help= +'''Specify the width of the block of cells, in columns. Must be greater than zero. Defaults to 1 when +the -w option is not present. Defaults to the number of input columns when the -w option is present.''', default=None ) + parser.add_option( '-s', '--sheet', action='store', dest='sheet', help='The sheet in the ODS file to read/modify. Must be greater than zero; defaults to 1.', default=1 ) + parser.add_option( '-w', '--write', action='store_true', dest='write', help= +'''If specified, the spreadsheet will be modified with data from standard input. If not specified, +the cells from the spreadsheet will be written to standard output.''' ) + + (options, args) = parser.parse_args() + + if len( args ) != 2: + parser.print_help() + exit( 1 ) + + file = args[0] + (colIndex, rowIndex) = parseCell( args[1] ) + + rowCount = getCount( options.rows, options.write, 'rows' ) + colCount = getCount( options.cols, options.write, 'cols' ) + sheet = int( options.sheet ) - 1 + + if sheet < 0: + sys.stderr.write( "Error: illegal value specified for sheet\n" ) + exit( 1 ) + + if options.write: + exit( updateCells( file, sheet, rowIndex, colIndex, rowCount, colCount ) ) + else: + exit( displayCells( file, sheet, rowIndex, colIndex, rowCount, colCount ) ) diff --git a/contrib/odscell/odscell.1 b/contrib/odscell/odscell.1 new file mode 100644 index 0000000..25f5e6f --- /dev/null +++ b/contrib/odscell/odscell.1 @@ -0,0 +1,98 @@ +'\" t +.\" Title: odscell +.\" Author: Kartikaya Gupta +.\" Generator: DocBook XSL Stylesheets v1.76.0 +.\" Date: 12/22/2010 +.\" Manual: User commands +.\" Source: odfpy +.\" Language: English +.\" +.TH "ODSCELL" "1" "12/22/2010" "odfpy" "User commands" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +odscell \- Read and update blocks of cells in OpenDocument spreadsheets files +.SH "SYNOPSIS" +.HP \w'\fBodscell\fR\ 'u +\fBodscell\fR \fIfile\&.ods\fR \fIcell\fR +.SH "DESCRIPTION" +.PP +This program reads a cell or block of cells from a file in ODS format, and prints it out in a CSV format to standard output\&. Alternatively, if the \-w flag is set, the program reads in a CSV\-formatted block of cells from standard input, and overwites a cell or block of cells in a file in ODS format\&. +.SH "OPTIONS" +.PP +\-\-version +.RS 4 +Display the version and exit\&. +.RE +.PP +\-h, \-\-help +.RS 4 +Display command usage\&. +.RE +.PP +\-r \fIROWS\fR, \-\-rows=\fIROWS\fR +.RS 4 +Specify the height of the block of cells, in rows\&. Must be greater than zero\&. Defaults to 1 when the \-w option is not present\&. Defaults to the number of input rows when the \-w option is present\&. +.RE +.PP +\-c \fICOLS\fR, \-\-cols=\fICOLS\fR +.RS 4 +Specify the width of the block of cells, in columns\&. Must be greater than zero\&. Defaults to 1 when the \-w option is not present\&. Defaults to the number of input columns when the \-w option is present\&. +.RE +.PP +\-s \fISHEET\fR, \-\-sheet=\fISHEET\fR +.RS 4 +The sheet in the ODS file to read/modify\&. Must be greater than zero; defaults to 1\&. +.RE +.PP +\-w +.RS 4 +If specified, the spreadsheet will be modified with data from standard input\&. If not specified, the cells from the spreadsheet will be written to standard output\&. +.RE +.PP +\fIfile\&.ods\fR +.RS 4 +The ODS file to be read from or modified\&. +.RE +.PP +\fIcell\fR +.RS 4 +The top\-left cell of the block of cells to be read from or modified\&. This should be specified in normal spreadsheet format, e\&.g\&. "A1" or "BA23"\&. +.RE +.SH "EXAMPLE" +.sp +.if n \{\ +.RS 4 +.\} +.nf +odscell foo\&.ods A4 # display value in cell A4 on sheet 1 of foo\&.ods +odscell \-r 2 \-c 2 foo\&.ods B2 # display values for cells B2,B3,C2,C3 on sheet 1 of foo\&.ods +echo "hello,world,garbage" | odscell \-c 2 \-w foo\&.ods A1 # write "hello" to cell A1 and "world" to cell A2 on sheet 1 of foo\&.ods +cat bar\&.csv | odscell \-s 2 \-w foo\&.ods A1 # put the CSV data from bar\&.csv into sheet 2 of foo\&.ods +.fi +.if n \{\ +.RE +.\} +.SH "AUTHOR" +.PP +\fBKartikaya Gupta\fR +.RS 4 +Original author of odscell +.RE diff --git a/contrib/odscell/odscell.docbook b/contrib/odscell/odscell.docbook new file mode 100644 index 0000000..982b933 --- /dev/null +++ b/contrib/odscell/odscell.docbook @@ -0,0 +1,117 @@ + + + + + odfpy + KartikayaGupta + Original author of odscell + + + + odscell + 1 + User commands + + + odscell + Read and update blocks of cells in OpenDocument spreadsheets files + + + + odscell + file.ods + cell + + + + Description + +This program reads a cell or block of cells from a file in ODS format, and prints it out +in a CSV format to standard output. Alternatively, if the -w flag is set, the program reads +in a CSV-formatted block of cells from standard input, and overwites a cell or block of cells +in a file in ODS format. + + + + Options + + + --version + + +Display the version and exit. + + + + + -h, --help + + +Display command usage. + + + + + -r ROWS, --rows=ROWS + + +Specify the height of the block of cells, in rows. Must be greater than zero. Defaults to 1 when +the -w option is not present. Defaults to the number of input rows when the -w option is present. + + + + + -c COLS, --cols=COLS + + +Specify the width of the block of cells, in columns. Must be greater than zero. Defaults to 1 when +the -w option is not present. Defaults to the number of input columns when the -w option is present. + + + + + -s SHEET, --sheet=SHEET + + +The sheet in the ODS file to read/modify. Must be greater than zero; defaults to 1. + + + + + -w + + +If specified, the spreadsheet will be modified with data from standard input. If not specified, +the cells from the spreadsheet will be written to standard output. + + + + + file.ods + + +The ODS file to be read from or modified. + + + + + cell + + +The top-left cell of the block of cells to be read from or modified. This should be specified +in normal spreadsheet format, e.g. "A1" or "BA23". + + + + + + + Example + +odscell foo.ods A4 # display value in cell A4 on sheet 1 of foo.ods +odscell -r 2 -c 2 foo.ods B2 # display values for cells B2,B3,C2,C3 on sheet 1 of foo.ods +echo "hello,world,garbage" | odscell -c 2 -w foo.ods A1 # write "hello" to cell A1 and "world" to cell A2 on sheet 1 of foo.ods +cat bar.csv | odscell -s 2 -w foo.ods A1 # put the CSV data from bar.csv into sheet 2 of foo.ods + + + diff --git a/contrib/odt2tracwiki/Makefile b/contrib/odt2tracwiki/Makefile new file mode 100644 index 0000000..efa816e --- /dev/null +++ b/contrib/odt2tracwiki/Makefile @@ -0,0 +1,15 @@ +all: odf odt2tracwiki.1 + +txt: odt2tracwiki.txt + +%.1: %.docbook + xmlto man $< + +%.txt: %.docbook + xmlto txt $< + +clean: + rm -f *.txt odf + +odf: + ln -s ../../odf diff --git a/contrib/odt2tracwiki/odt2tracwiki.1 b/contrib/odt2tracwiki/odt2tracwiki.1 new file mode 100644 index 0000000..ca0d88a --- /dev/null +++ b/contrib/odt2tracwiki/odt2tracwiki.1 @@ -0,0 +1,57 @@ +'\" t +.\" Title: odt2tracwiki +.\" Author: S\(/oren Roug +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 01/09/2013 +.\" Manual: User commands +.\" Source: odfpy +.\" Language: English +.\" +.TH "ODT2TRACWIKI" "1" "01/09/2013" "odfpy" "User commands" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +odt2tracwiki \- Convert ODF to Trac Wiki format +.SH "SYNOPSIS" +.HP \w'\fBodt2tracwiki\fR\ 'u +\fBodt2tracwiki\fR \fIpath\fR +.SH "DESCRIPTION" +.PP +\fBodt2tracwiki\fR +is a program that will create a Trac Wiki format\&. See http://trac\&.edgewall\&.org/\&. I expect to add a feature that will upload the page with images to a Trac Wiki page using XML\-RPC\&. http://trac\-hacks\&.org/wiki/XmlRpcPlugin +.PP +"Path" is assumed to be an OpenDocument file of text, spreadsheet or presentation type\&. +.SH "EXAMPLE" +.sp +.if n \{\ +.RS 4 +.\} +.nf +odt2tracwiki odf\-file +.fi +.if n \{\ +.RE +.\} +.SH "AUTHOR" +.PP +\fBS\(/oren Roug\fR +.RS 4 +Original author +.RE diff --git a/contrib/odt2tracwiki/odt2tracwiki.docbook b/contrib/odt2tracwiki/odt2tracwiki.docbook new file mode 100644 index 0000000..0340160 --- /dev/null +++ b/contrib/odt2tracwiki/odt2tracwiki.docbook @@ -0,0 +1,46 @@ + + + + + odfpy + SørenRoug + Original author + + + + odt2tracwiki + 1 + User commands + + +odt2tracwiki +Convert ODF to Trac Wiki format + + + + + odt2tracwiki + path + + + +Description +odt2tracwiki is a program that will create +a Trac Wiki format. +See http://trac.edgewall.org/. +I expect to add a feature that will upload the page with images to a Trac Wiki page +using XML-RPC. http://trac-hacks.org/wiki/XmlRpcPlugin + + +"Path" is assumed to be an +OpenDocument file of text, spreadsheet or presentation type. + + +Example + +odt2tracwiki odf-file + + + + diff --git a/contrib/odt2tracwiki/odt2tracwiki.py b/contrib/odt2tracwiki/odt2tracwiki.py new file mode 100644 index 0000000..7a64309 --- /dev/null +++ b/contrib/odt2tracwiki/odt2tracwiki.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2007 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +import sys +from odf.odf2moinmoin import ODF2MoinMoin + + +if __name__ == "__main__": + odt = ODF2MoinMoin(sys.argv[1]) + out_utf8 = odt.toString().encode("utf-8") + sys.stdout.write(out_utf8) diff --git a/contrib/odt2zwiki/Makefile b/contrib/odt2zwiki/Makefile new file mode 100644 index 0000000..6f49bc9 --- /dev/null +++ b/contrib/odt2zwiki/Makefile @@ -0,0 +1,15 @@ +all: odf odf2zwikimoin.1 + +txt: odf2zwikimoin.txt + +%.1: %.docbook + xmlto man $< + +%.txt: %.docbook + xmlto txt $< + +clean: + rm -f *.txt odf + +odf: + ln -s ../../odf diff --git a/contrib/odt2zwiki/odf2zwikimoin.1 b/contrib/odt2zwiki/odf2zwikimoin.1 new file mode 100644 index 0000000..c7b7abf --- /dev/null +++ b/contrib/odt2zwiki/odf2zwikimoin.1 @@ -0,0 +1,51 @@ +'\" t +.\" Title: odf2zwikimoin +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 01/09/2013 +.\" Manual: [FIXME: manual] +.\" Source: [FIXME: source] +.\" Language: English +.\" +.TH "ODF2ZWIKIMOIN" "1" "01/09/2013" "[FIXME: source]" "[FIXME: manual]" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +odf2zwikimoin \- Convert ODF to ZWiki MoinMoin format +.SH "SYNOPSIS" +.HP \w'\fBodf2zwikimoin\fR\ 'u +\fBodf2zwikimoin\fR \fIpath\fR +.SH "DESCRIPTION" +.PP +\fBodf2zwikimoin\fR +is a program that will create a ZWiki MoinMoin format\&. See http://zwiki\&.org/\&. +.PP +"Path" is assumed to be an OpenDocument file of text, spreadsheet or presentation type\&. +.SH "EXAMPLE" +.sp +.if n \{\ +.RS 4 +.\} +.nf +odf2zwikimoin odf\-file +.fi +.if n \{\ +.RE +.\} diff --git a/contrib/odt2zwiki/odf2zwikimoin.docbook b/contrib/odt2zwiki/odf2zwikimoin.docbook new file mode 100644 index 0000000..659151a --- /dev/null +++ b/contrib/odt2zwiki/odf2zwikimoin.docbook @@ -0,0 +1,33 @@ + + + + +odf2zwikimoin +Convert ODF to ZWiki MoinMoin format + + + + + odf2zwikimoin + path + + + +Description +odf2zwikimoin is a program that will create +a ZWiki MoinMoin format. +See http://zwiki.org/. + + +"Path" is assumed to be an +OpenDocument file of text, spreadsheet or presentation type. + + +Example + +odf2zwikimoin odf-file + + + + diff --git a/contrib/odt2zwiki/odf2zwikimoin.py b/contrib/odt2zwiki/odf2zwikimoin.py new file mode 100644 index 0000000..5356e6c --- /dev/null +++ b/contrib/odt2zwiki/odf2zwikimoin.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2007 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +import sys +from odf.odf2moinmoin import ODF2MoinMoin + +class ODF2ZWikiMoin(ODF2MoinMoin): + + def __init__(self, filepath): + super(ODF2ZWikiMoin, self).__init__(filepath) + self.baseURL = "BaseURL" + + def draw_image(self, node): + """ + """ + link = node.getAttribute("xlink:href") + if link and link[:2] == './': # Indicates a sub-object, which isn't supported + return "%s\n" % link + if link and link[:9] == 'Pictures/': + link = self.baseURL + "/" + link[9:] + return "%s\n" % link + + def text_line_break(self, node): + return "\n" + +if __name__ == "__main__": + odt = ODF2ZWikiMoin(sys.argv[1]) + out_utf8 = odt.toString().encode("utf-8") + sys.stdout.write(out_utf8) diff --git a/contrib/odt2zwiki/odt2moinmoin.py b/contrib/odt2zwiki/odt2moinmoin.py new file mode 100644 index 0000000..f61ffd1 --- /dev/null +++ b/contrib/odt2zwiki/odt2moinmoin.py @@ -0,0 +1,533 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2007 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + + +""" + import pdb; pdb.set_trace() +odt2moinmoin +======= + +odt2moinmoin converts files in Open Document Text format (ODT) into +ZWiki MoinMoin-formatted plain text. + +Written by by [Yuri Takhteyev](http://www.freewisdom.org). + +Project website: http://www.freewisdom.org/projects/odt2txt/ +Contact: yuri [at] freewisdom.org + +License: GPL 2 (http://www.gnu.org/copyleft/gpl.html) or BSD + +Version: 0.1 (April 7, 2006) + +""" + + + +import sys, zipfile, xml.dom.minidom +from odf.namespaces import nsdict +from odf.elementtypes import * + +IGNORED_TAGS = [ + 'draw:a' + 'draw:g', + 'draw:line', + 'draw:object-ole', + 'office:annotation', + 'svg:desc', +] + [ nsdict[item[0]]+":"+item[1] for item in empty_elements] + +INLINE_TAGS = [ nsdict[item[0]]+":"+item[1] for item in inline_elements] + +FOOTNOTE_STYLES = ["Footnote"] + + +class TextProps: + """ Holds properties for a text style. """ + + def __init__ (self): + + self.italic = False + self.bold = False + self.fixed = False + self.underlined = False + + def setItalic (self, value): + if value == "italic": + self.italic = True + + def setBold (self, value): + if value == "bold": + self.bold = True + + def setFixed (self, value): + self.fixed = value + + def __str__ (self): + + return "[i=%s, h=i%s, fixed=%s]" % (str(self.italic), + str(self.bold), + str(self.fixed)) + +class ParagraphProps: + """ Holds properties of a paragraph style. """ + + def __init__ (self): + + self.blockquote = False + self.headingLevel = 0 + self.code = False + self.title = False + self.indented = 0 + + def setIndented (self, value): + self.indented = value + + def setHeading (self, level): + self.headingLevel = level + + def setTitle (self, value): + self.title = value + + def setCode (self, value): + self.code = value + + + def __str__ (self): + + return "[bq=%s, h=%d, code=%s]" % (str(self.blockquote), + self.headingLevel, + str(self.code)) + + +class ListProperties: + """ Holds properties for a list style. """ + + def __init__ (self): + self.ordered = False + + def setOrdered (self, value): + self.ordered = value + + + +class OpenDocumentTextFile: + + + def __init__ (self, filepath): + self.footnotes = [] + self.footnoteCounter = 0 + self.textStyles = {"Standard": TextProps()} + self.paragraphStyles = {"Standard": ParagraphProps()} + self.listStyles = {} + self.fixedFonts = [] + self.hasTitle = 0 + self.baseURL = "BaseURL" + + self.load(filepath) + + + def processFontDeclarations (self, fontDecl): + """ Extracts necessary font information from a font-declaration + element. + """ + for fontFace in fontDecl.getElementsByTagName("style:font-face"): + if fontFace.getAttribute("style:font-pitch") == "fixed": + self.fixedFonts.append(fontFace.getAttribute("style:name")) + + + + def extractTextProperties (self, style, parent=None): + """ Extracts text properties from a style element. """ + + textProps = TextProps() + + if parent: + parentProp = self.textStyles.get(parent, None) + if parentProp: + textProp = parentProp + + textPropEl = style.getElementsByTagName("style:text-properties") + if not textPropEl: return textProps + + textPropEl = textPropEl[0] + + italic = textPropEl.getAttribute("fo:font-style") + bold = textPropEl.getAttribute("fo:font-weight") + + textProps.setItalic(italic) + textProps.setBold(bold) + + if textPropEl.getAttribute("style:font-name") in self.fixedFonts: + textProps.setFixed(True) + + return textProps + + def extractParagraphProperties (self, style, parent=None): + """ Extracts paragraph properties from a style element. """ + + paraProps = ParagraphProps() + + name = style.getAttribute("style:name") + + if name.startswith("Heading_20_"): + level = name[11:] + try: + level = int(level) + paraProps.setHeading(level) + except: + level = 0 + + if name == "Title": + paraProps.setTitle(True) + + paraPropEl = style.getElementsByTagName("style:paragraph-properties") + if paraPropEl: + paraPropEl = paraPropEl[0] + leftMargin = paraPropEl.getAttribute("fo:margin-left") + if leftMargin: + try: + leftMargin = float(leftMargin[:-2]) + if leftMargin > 0.01: + paraProps.setIndented(True) + except: + pass + + textProps = self.extractTextProperties(style) + if textProps.fixed: + paraProps.setCode(True) + + return paraProps + + + def processStyles(self, styleElements): + """ Runs through "style" elements extracting necessary information. + """ + + for style in styleElements: + + name = style.getAttribute("style:name") + + if name == "Standard": continue + + family = style.getAttribute("style:family") + parent = style.getAttribute("style:parent-style-name") + + if family == "text": + self.textStyles[name] = self.extractTextProperties(style, + parent) + + elif family == "paragraph": + self.paragraphStyles[name] = ( + self.extractParagraphProperties(style, + parent)) + def processListStyles (self, listStyleElements): + + for style in listStyleElements: + name = style.getAttribute("style:name") + + prop = ListProperties() + if style.childNodes: + if ( style.childNodes[0].tagName + == "text:list-level-style-number" ): + prop.setOrdered(True) + + self.listStyles[name] = prop + + + def load(self, filepath): + """ Loads an ODT file. """ + + zip = zipfile.ZipFile(filepath) + + styles_doc = xml.dom.minidom.parseString(zip.read("styles.xml")) + self.processFontDeclarations(styles_doc.getElementsByTagName( + "office:font-face-decls")[0]) + self.processStyles(styles_doc.getElementsByTagName("style:style")) + self.processListStyles(styles_doc.getElementsByTagName( + "text:list-style")) + + self.content = xml.dom.minidom.parseString(zip.read("content.xml")) + self.processFontDeclarations(self.content.getElementsByTagName( + "office:font-face-decls")[0]) + self.processStyles(self.content.getElementsByTagName("style:style")) + self.processListStyles(self.content.getElementsByTagName( + "text:list-style")) + + def compressCodeBlocks(self, text): + """ Removes extra blank lines from code blocks. """ + + lines = text.split("\n") + buffer = [] + numLines = len(lines) + for i in range(numLines): + + if (lines[i].strip() or i == numLines-1 or i == 0 or + not ( lines[i-1].startswith(" ") + and lines[i+1].startswith(" ") ) ): + buffer.append("\n" + lines[i]) + + return ''.join(buffer) + + + def listToString (self, listElement, indent = 0): + + buffer = [] + + styleName = listElement.getAttribute("text:style-name") + props = self.listStyles.get(styleName, ListProperties()) + + i = 0 + for item in listElement.childNodes: + buffer.append(" "*indent) + i += 1 + if props.ordered: + number = str(i) + number = " " + number + ". " + buffer.append(" 1. ") + else: + buffer.append(" * ") + subitems = [el for el in item.childNodes + if el.tagName in ["text:p", "text:h", "text:list"]] + for subitem in subitems: + if subitem.tagName == "text:list": + buffer.append("\n") + buffer.append(self.listToString(subitem, indent+3)) + else: + buffer.append(self.paragraphToString(subitem, indent+3)) + buffer.append("\n") + + return ''.join(buffer) + + def tableToString (self, tableElement): + """ MoinMoin used || to delimit table cells + """ + + buffer = [] + + for item in tableElement.childNodes: + if item.tagName == "table:table-header-rows": + buffer.append(self.tableToString(item)) + if item.tagName == "table:table-row": + buffer.append("\n||") + for cell in item.childNodes: + buffer.append(self.paragraphToString(cell)) + buffer.append("||") + return ''.join(buffer) + + + def toString (self): + """ Converts the document to a string. """ + body = self.content.getElementsByTagName("office:body")[0] + text = body.childNodes[0] + + buffer = [] + + paragraphs = [el for el in text.childNodes + if el.tagName in ["text:p", "text:h","text:section", + "text:list", "table:table"]] + + for paragraph in paragraphs: + if paragraph.tagName == "text:list": + text = self.listToString(paragraph) + elif paragraph.tagName == "text:section": + text = self.textToString(paragraph) + elif paragraph.tagName == "table:table": + text = self.tableToString(paragraph) + else: + text = self.paragraphToString(paragraph) + if text: + buffer.append(text) + + if self.footnotes: + + buffer.append("----") + for cite, body in self.footnotes: + buffer.append("%s: %s" % (cite, body)) + + + buffer.append("") + return self.compressCodeBlocks('\n\n'.join(buffer)) + + + def textToString(self, element): + + buffer = [] + + for node in element.childNodes: + + if node.nodeType == xml.dom.Node.TEXT_NODE: + buffer.append(node.nodeValue) + + elif node.nodeType == xml.dom.Node.ELEMENT_NODE: + tag = node.tagName + + if tag == "text:note": + cite = (node.getElementsByTagName("text:note-citation")[0] + .childNodes[0].nodeValue) + + body = (node.getElementsByTagName("text:note-body")[0] + .childNodes[0]) + + self.footnotes.append((cite, self.textToString(body))) + + buffer.append("^%s^" % cite) + + elif tag == "text:s": + try: + num = int(node.getAttribute("text:c")) + buffer.append(" "*num) + except: + buffer.append(" ") + + elif tag == "text:tab": + buffer.append(" ") + + + elif tag == "text:a": + + text = self.textToString(node) + link = node.getAttribute("xlink:href") + if link.strip() == text.strip(): + buffer.append("[%s] " % link.strip()) + else: + buffer.append("[%s %s] " % (link.strip(), text.strip())) + + elif tag == "draw:image": + link = node.getAttribute("xlink:href") + if link and link[:2] == './': # Indicates a sub-object, which isn't supported + continue + if link and link[:9] == 'Pictures/': + link = self.baseURL + "/" + link[9:] + buffer.append("%s\n" % link) + + elif tag == "text:line-break": + buffer.append("\n") + + elif tag in ("draw:text-box", "draw:frame"): + text = self.textToString(node) + buffer.append(text) + + elif tag in ("text:p", "text:h"): + text = self.paragraphToString(node) + if text: + buffer.append(text + "\n\n") + + elif tag in IGNORED_TAGS: + pass + + elif tag in INLINE_TAGS: + text = self.textToString(node) + + if not text.strip(): + continue # don't apply styles to white space + + styleName = node.getAttribute("text:style-name") + style = self.textStyles.get(styleName, TextProps()) + + if style.fixed: + buffer.append("`" + text + "`") + continue + + if style: + if style.italic and style.bold: + mark = "'''''" + elif style.italic: + mark = "''" + elif style.bold: + mark = "'''" + else: + mark = "" + else: + mark = "/" + styleName + "/" + + buffer.append("%s%s%s " % (mark, text, mark)) + + + else: + buffer.append(" {" + tag + "} ") + + return ''.join(buffer) + + def paragraphToString(self, paragraph, indent = 0): + + dummyParaProps = ParagraphProps() + + style_name = paragraph.getAttribute("text:style-name") + paraProps = self.paragraphStyles.get(style_name, dummyParaProps) + text = self.textToString(paragraph) + + #print style_name + + if paraProps and not paraProps.code: + text = text.strip() + + if paraProps.title: + self.hasTitle = 1 + return "= " + text + " =\n" + + outlinelevel = paragraph.getAttribute("text:outline-level") + if outlinelevel: + + level = int(outlinelevel) + if self.hasTitle: level += 1 + + if level >= 1: + return "\n" + "=" * level + " " + text + " " + "=" * level + "\n" + + elif paraProps.code: + return "{{{\n" + text + "\n}}}\n" + + if paraProps.indented: + return self.wrapParagraph(text, indent = indent, blockquote = True) + + else: + return self.wrapParagraph(text, indent = indent) + + + def wrapParagraph(self, text, indent = 0, blockquote=False): + + counter = 0 + buffer = [] + LIMIT = 50 + + if blockquote: + buffer.append(" ") + + return ''.join(buffer) + text + for token in text.split(): + + if counter > LIMIT - indent: + buffer.append("\n" + " "*indent) + if blockquote: + buffer.append(" ") + counter = 0 + + buffer.append(token + " ") + counter += len(token) + + return ''.join(buffer) + + + +if __name__ == "__main__": + odt = OpenDocumentTextFile(sys.argv[1]) + unicode = odt.toString() + out_utf8 = unicode.encode("utf-8") + sys.stdout.write(out_utf8) diff --git a/contrib/sqlite2ods/README b/contrib/sqlite2ods/README new file mode 100644 index 0000000..98f3eb3 --- /dev/null +++ b/contrib/sqlite2ods/README @@ -0,0 +1,4 @@ +Example of script that extracts a table from an SQLite database and produces a spreadsheet. + +Issues: +Numbers in the table become strings in the spreadsheet. diff --git a/contrib/sqlite2ods/sqlite2ods.py b/contrib/sqlite2ods/sqlite2ods.py new file mode 100644 index 0000000..63e243b --- /dev/null +++ b/contrib/sqlite2ods/sqlite2ods.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2007 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +import os, sys +import sqlite +from odf.opendocument import OpenDocumentSpreadsheet +from odf.style import Style, TextProperties, ParagraphProperties, TableColumnProperties +from odf.text import P +from odf.table import Table, TableColumn, TableRow, TableCell + +if len(sys.argv) != 3: + print "Usage: sqlite-db table" + sys.exit(2) + +sqldb = sys.argv[1] +sqltable = sys.argv[2] +textdoc = OpenDocumentSpreadsheet() +# Create a style for the table content. One we can modify +# later in the word processor. +tablecontents = Style(name="Table Contents", family="paragraph") +tablecontents.addElement(ParagraphProperties(numberlines="false", linenumber="0")) +#tablecontents.addElement(TextProperties(fontweight="bold")) +textdoc.styles.addElement(tablecontents) + +# Create automatic styles for the column widths. +# We want two different widths, one in inches, the other one in metric. +# ODF Standard section 15.9.1 +widthshort = Style(name="Wshort", family="table-column") +widthshort.addElement(TableColumnProperties(columnwidth="1.7cm")) +textdoc.automaticstyles.addElement(widthshort) + +widthwide = Style(name="Wwide", family="table-column") +widthwide.addElement(TableColumnProperties(columnwidth="1.5in")) +textdoc.automaticstyles.addElement(widthwide) + +# Start the table, and describe the columns +table = Table(name=sqltable) +#table.addElement(TableColumn(numbercolumnsrepeated=4,stylename=widthshort)) +#table.addElement(TableColumn(numbercolumnsrepeated=3,stylename=widthwide)) + +cx = sqlite.connect(sqldb) +cu = cx.cursor() +cu.execute("select * from %s" % sqltable) +for row in cu.fetchall(): + tr = TableRow() + table.addElement(tr) + for val in row: + tc = TableCell() + tr.addElement(tc) + if type(val) == type(''): + textval = unicode(val,'utf-8') + else: + textval = str(val) + p = P(stylename=tablecontents,text=textval) + tc.addElement(p) + +cx.close() + +textdoc.spreadsheet.addElement(table) +textdoc.save(sqltable, True) + diff --git a/contrib/syntaxhighlight/Makefile b/contrib/syntaxhighlight/Makefile new file mode 100644 index 0000000..6c8b873 --- /dev/null +++ b/contrib/syntaxhighlight/Makefile @@ -0,0 +1,14 @@ +all: odf syntaxhighlight.1 + +txt: syntaxhighlight.txt + +%.1: %.docbook + xmlto man $< + +%.txt: %.docbook + xmlto txt $< + +clean: + rm -f *.txt odf +odf: + ln -s ../../odf diff --git a/contrib/syntaxhighlight/syntaxhighlight.1 b/contrib/syntaxhighlight/syntaxhighlight.1 new file mode 100644 index 0000000..53f9fec --- /dev/null +++ b/contrib/syntaxhighlight/syntaxhighlight.1 @@ -0,0 +1,220 @@ +.\" Title: syntaxhighlight +.\" Author: S\(/oren Roug +.\" Generator: DocBook XSL Stylesheets v1.74.0 +.\" Date: 03/08/2009 +.\" Manual: User commands +.\" Source: odfpy +.\" Language: English +.\" +.TH "SYNTAXHIGHLIGHT" "1" "03/08/2009" "odfpy" "User commands" +.\" ----------------------------------------------------------------- +.\" * (re)Define some macros +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" toupper - uppercase a string (locale-aware) +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de toupper +.tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ +\\$* +.tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SH-xref - format a cross-reference to an SH section +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de SH-xref +.ie n \{\ +.\} +.toupper \\$* +.el \{\ +\\$* +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SH - level-one heading that works better for non-TTY output +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de1 SH +.\" put an extra blank line of space above the head in non-TTY output +.if t \{\ +.sp 1 +.\} +.sp \\n[PD]u +.nr an-level 1 +.set-an-margin +.nr an-prevailing-indent \\n[IN] +.fi +.in \\n[an-margin]u +.ti 0 +.HTML-TAG ".NH \\n[an-level]" +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +\." make the size of the head bigger +.ps +3 +.ft B +.ne (2v + 1u) +.ie n \{\ +.\" if n (TTY output), use uppercase +.toupper \\$* +.\} +.el \{\ +.nr an-break-flag 0 +.\" if not n (not TTY), use normal case (not uppercase) +\\$1 +.in \\n[an-margin]u +.ti 0 +.\" if not n (not TTY), put a border/line under subheading +.sp -.6 +\l'\n(.lu' +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SS - level-two heading that works better for non-TTY output +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de1 SS +.sp \\n[PD]u +.nr an-level 1 +.set-an-margin +.nr an-prevailing-indent \\n[IN] +.fi +.in \\n[IN]u +.ti \\n[SN]u +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.ps \\n[PS-SS]u +\." make the size of the head bigger +.ps +2 +.ft B +.ne (2v + 1u) +.if \\n[.$] \&\\$* +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" BB/BE - put background/screen (filled box) around block of text +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de BB +.if t \{\ +.sp -.5 +.br +.in +2n +.ll -2n +.gcolor red +.di BX +.\} +.. +.de EB +.if t \{\ +.if "\\$2"adjust-for-leading-newline" \{\ +.sp -1 +.\} +.br +.di +.in +.ll +.gcolor +.nr BW \\n(.lu-\\n(.i +.nr BH \\n(dn+.5v +.ne \\n(BHu+.5v +.ie "\\$2"adjust-for-leading-newline" \{\ +\M[\\$1]\h'1n'\v'+.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] +.\} +.el \{\ +\M[\\$1]\h'1n'\v'-.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] +.\} +.in 0 +.sp -.5v +.nf +.BX +.in +.sp .5v +.fi +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" BM/EM - put colored marker in margin next to block of text +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de BM +.if t \{\ +.br +.ll -2n +.gcolor red +.di BX +.\} +.. +.de EM +.if t \{\ +.br +.di +.ll +.gcolor +.nr BH \\n(dn +.ne \\n(BHu +\M[\\$1]\D'P -.75n 0 0 \\n(BHu -(\\n[.i]u - \\n(INu - .75n) 0 0 -\\n(BHu'\M[] +.in 0 +.nf +.BX +.in +.fi +.\} +.. +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "Name" +syntaxhighlight \- Create OpenDocument with syntax highlighted programming code +.SH "Synopsis" +.fam C +.HP \w'\fBsyntaxhighlight\fR\ 'u +\fBsyntaxhighlight\fR [\-e\ \fIencoding\fR] [\-l\ \fIlanguage\fR] [\fIinputfile\fR] [\fIoutputfile\fR] +.fam +.SH "Description" +.PP +The syntaxhighlight program will read a source code file, format it with syntax highlighting and write an OpenDocument text file\&. +.SH "Options" +.PP +\-e \fIencoding\fR +.RS 4 +Enter the encoding of the source file\&. Common encodings are: iso\-8859\-1, cp1252, ascii and utf\-8 (default)\&. +.RE +.PP +\-l \fIlanguage\fR +.RS 4 +Programming language of the input file\&. If not specified, it is guessed fron the file ending\&. Values can be: Python, HTML, C, C++ and PHP\&. +.RE +.SH "Example" +.sp +.if n \{\ +.RS 4 +.\} +.fam C +.ps -1 +.nf +.if t \{\ +.sp -1 +.\} +.BB lightgray adjust-for-leading-newline +.sp -1 + +syntaxhighlight \-e cp1252 \-l Python example\&.py example\&.odt +.EB lightgray adjust-for-leading-newline +.if t \{\ +.sp 1 +.\} +.fi +.fam +.ps +1 +.if n \{\ +.RE +.\} +.SH "Author" +.PP +\fBS\(/oren Roug\fR +.RS 4 +Original author +.RE diff --git a/contrib/syntaxhighlight/syntaxhighlight.docbook b/contrib/syntaxhighlight/syntaxhighlight.docbook new file mode 100644 index 0000000..dcc0ffd --- /dev/null +++ b/contrib/syntaxhighlight/syntaxhighlight.docbook @@ -0,0 +1,72 @@ + + + + + odfpy + + Søren + Roug + Original author + + + + syntaxhighlight + 1 + User commands + + + syntaxhighlight + Create OpenDocument with syntax highlighted programming code + + + + syntaxhighlight + -e encoding + -l language + + inputfile + + + outputfile + + + + + Description + +The syntaxhighlight program will read a source code file, +format it with syntax highlighting and write an OpenDocument text file. + + + + Options + + + -e encoding + + +Enter the encoding of the source file. Common encodings are: iso-8859-1, +cp1252, ascii and utf-8 (default). + + + + + -l language + + +Programming language of the input file. If not specified, +it is guessed fron the file ending. +Values can be: +Python, HTML, C, C++ and PHP. + + + + + + + Example + +syntaxhighlight -e cp1252 -l Python example.py example.odt + + + diff --git a/contrib/syntaxhighlight/syntaxhighlight.py b/contrib/syntaxhighlight/syntaxhighlight.py new file mode 100644 index 0000000..a76ec6d --- /dev/null +++ b/contrib/syntaxhighlight/syntaxhighlight.py @@ -0,0 +1,508 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2007 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +# +# Syntax Highlighting +# Originally from Peter Clive Wilkinson (http://www.petersblog.org/node/763) +# +import os, sys, re, getopt +from odf.opendocument import OpenDocumentText +from odf.style import FontFace, Style, TextProperties, ParagraphProperties +from odf.text import P, Span, S + +class Highlight: + """ + Do syntax highlighting. + """ + + courierfont = FontFace(name="Courier", fontfamily="Courier", + fontadornments="Normal", fontfamilygeneric="modern", fontpitch="fixed") + + #--- Paragraph style -- + + programliststyle = Style(name="Program Listing", family="paragraph") + programliststyle.addElement(ParagraphProperties(border="0.002cm solid #000000", margin="0cm", padding="0.2cm")) + programliststyle.addElement(TextProperties(fontname="Courier", fontsize="9pt", language="none", country="none")) + + #--- Text styles -- + puncstyle = Style(name="Highlighted Punctuation", family="text") + puncstyle.addElement(TextProperties(fontweight="bold")) # Bold + + numberstyle = Style(name="Highlighted Number", family="text") + numberstyle.addElement(TextProperties(color="#ff0000")) # Red + + keywordstyle = Style(name="Highlighted Keyword", family="text") + keywordstyle.addElement(TextProperties(color="#b218b2", fontweight="bold")) # Blue, bold + + variablestyle = Style(name="Highlighted Magic", family="text") + variablestyle.addElement(TextProperties(color="#0000ff")) # Blue + + tagstyle = Style(name="Highlighted Tag", family="text") + tagstyle.addElement(TextProperties(color="#800000")) # Darkred + + attrstyle = Style(name="Highlighted Tag", family="text") + attrstyle.addElement(TextProperties(color="#008000", fontweight="bold")) # Dark green bold + + stringstyle = Style(name="Highlighted String", family="text") + stringstyle.addElement(TextProperties(color="#800000")) # Red + + commentstyle = Style(name="Highlighted Comment", family="text") + commentstyle.addElement(TextProperties(color="#0000ff", fontstyle="italic")) # Blue, Italic + + preprocstyle = Style(name="Highlighted Preprocessing", family="text") + preprocstyle.addElement(TextProperties(color="#ff00ff", fontstyle="italic")) # Magenta, Italic + + def __init__(self, strMode): + """ + Initialise highlighter: strMode = language (PYTHON, C, CPP, PHP, HTML) + """ + + self.textdoc = OpenDocumentText() + + self.textdoc.fontfacedecls.addElement(self.courierfont) + + self.textdoc.styles.addElement(self.programliststyle) + self.textdoc.styles.addElement(self.puncstyle) + self.textdoc.styles.addElement(self.numberstyle) + self.textdoc.styles.addElement(self.keywordstyle) + self.textdoc.styles.addElement(self.variablestyle) + self.textdoc.styles.addElement(self.tagstyle) + self.textdoc.styles.addElement(self.attrstyle) + self.textdoc.styles.addElement(self.stringstyle) + self.textdoc.styles.addElement(self.commentstyle) + self.textdoc.styles.addElement(self.preprocstyle) + + self.strSpanStyle = None + self.currPara = P(stylename=self.programliststyle) + self.textdoc.text.addElement(self.currPara) + self.currSpan = None + if strMode == 'CPP': + strMode = 'C' + self.strSuppressTokens = [] + elif strMode == 'C': + self.strSuppressTokens = ['CPPKEYWORD'] + else: + self.strSuppressTokens = [] + + self.strMode = strMode + + def PythonHighlightToken(self, strTok, oMatch, strStyle): + """ + Callback for python specific highlighting. + """ + # + # Input matches this type. + # + strValue = oMatch.group() + + if strTok == 'MULTILINESTRING': + # + # If not inside a multiline string then start one now. + # + self.ChangeStyle(strStyle) + self.WriteContent(strValue) + # + # Remember you are in a string and remember how it was + # started (""" vs ''') + # + self.strMultilineString = oMatch.group(1) + return 'PythonMultilineString' + + elif strTok == 'ENDMULTILINESTRING': + # + # Multiline Token found within a multiline string + # + if oMatch.group(1) == self.strMultilineString: + # + # Token is end of multiline so stop here. + # + self.WriteMultiline(strValue) + self.strMultilineString = '' + return 'PYTHON' + + self.ChangeStyle(strStyle) + self.WriteContent(strValue) + + def CHighlightToken(self, strTok, oMatch, strStyle): + """ + Callback for C specific highlighting. + """ + # + # Input matches this type. + # + strValue = oMatch.group() + + # + # Not in multiline mode so change display style as appropriate + # and output the text. + # + self.ChangeStyle(strStyle) + self.WriteContent(strValue) + + def PHPHighlightToken(self, strTok, oMatch, strStyle): + """ + Callback for PHP specific highlighting. + """ + # + # Input matches this type. + # + strValue = oMatch.group() + + if strTok == 'MULTILINESTRING': + # + # If not inside a multiline string then start one now. + # + self.ChangeStyle(strStyle) + self.WriteContent(strValue) + # + # Remember you are in a string and remember how it was + # started (""" vs ''') + # + self.strMultilineString = oMatch.group(1) + return 'PHPMultilineString' + + elif strTok == 'ENDMULTILINESTRING': + # + # Multiline Token found within a multiline string + # + if oMatch.group(1) == self.strMultilineString: + # + # Token is end of multiline so stop here. + # + self.WriteMultiline(strValue) + self.strMultilineString = '' + return 'PHP' + + self.ChangeStyle(strStyle) + self.WriteContent(strValue) + + if strTok == 'GOTOHTML': + # + # Embedded HTML + # + return 'HTML' + else: + return None + + def HTMLHighlightToken(self, strTok, oMatch, strStyle): + """ + Callback for HTML specific highlighting. + """ + # + # Input matches this type. + # + strValue = oMatch.group() + self.ChangeStyle(strStyle) + self.WriteContent(strValue) + + if strTok == 'TAG': + # + # Change to mode 1, 'within tag'. + # + return 'HTMLTag' + + elif strTok == 'ENDTAG': + # + # Change to mode 1, 'within tag'. + # + return 'HTML' + + elif strTok == 'GOTOPHP': + # + # Embedded PHP + # + return 'PHP' + + else: + # + # No state change. + # + return None + + oStyles = { + 'PYTHON': ( PythonHighlightToken, + ( + ('PUNC', re.compile( r'[-+*!|&^~/%\=<>\[\]{}(),.:]'), puncstyle), + ('NUMBER', re.compile( r'0x[0-9a-fA-F]+|[+-]?\d+(\.\d+)?([eE][+-]\d+)?|\d+'), numberstyle), + ('KEYWORD', re.compile( r'(def|class|break|continue|del|exec|finally|pass|' + + r'print|raise|return|try|except|global|assert|lambda|' + + r'yield|for|while|if|elif|else|and|in|is|not|or|import|' + + r'from|True|False)(?![a-zA-Z0-9_])'), keywordstyle), + ('MAGIC', re.compile( r'self|None'), variablestyle), + ('MULTILINESTRING', re.compile( r'r?u?(\'\'\'|""")'), stringstyle), + ('STRING', re.compile( r'r?u?\'(.*?)(?\[\]{}(),.:]'), puncstyle), + ('NUMBER', re.compile( r'0x[0-9a-fA-F]+|[+-]?\d+(\.\d+)?([eE][+-]\d+)?|\d+'), + numberstyle), + ('KEYWORD', re.compile( r'(sizeof|int|long|short|char|void|' + + r'signed|unsigned|float|double|' + + r'goto|break|return|continue|asm|' + + r'case|default|if|else|switch|while|for|do|' + + r'struct|union|enum|typedef|' + + r'static|register|auto|volatile|extern|const)(?![a-zA-Z0-9_])'), keywordstyle), + ( 'CPPKEYWORD', re.compile( r'(class|private|protected|public|template|new|delete|' + + r'this|friend|using|inline|export|bool|throw|try|catch|' + + r'operator|typeid|virtual)(?![a-zA-Z0-9_])'), keywordstyle), + ('STRING', re.compile( r'r?u?\'(.*?)(?\[\]{}(),.:]'), puncstyle), + ('NUMBER', re.compile( r'0x[0-9a-fA-F]+|[+-]?\d+(\.\d+)?([eE][+-]\d+)?|\d+'), + numberstyle), + ('KEYWORD', re.compile( r'(declare|else|enddeclare|endswitch|elseif|endif|if|switch|' + + r'as|do|endfor|endforeach|endwhile|for|foreach|while|' + + r'case|default|switch|function|return|break|continue|exit|' + + r'var|const|boolean|bool|integer|int|real|double|float|string|' + + r'array|object|NULL|extends|implements|instanceof|parent|self|' + + r'include|require|include_once|require_once|new|true|false)(?![a-zA-Z0-9_])'), keywordstyle), + + ('STRING', re.compile( r'r?u?\'(.*?)(?'), stringstyle), + ('UNKNOWN', re.compile( r'.'), None) + )), + + 'PHPMultilineString': ( PHPHighlightToken, + ( + ('ENDMULTILINESTRING', re.compile( r'.*?\n([a-zA-Z0-9_]+)', re.DOTALL), stringstyle), + ('UNKNOWN', re.compile( r'.*?(?!\n)'), 'Keep') + )), + + 'HTML': ( HTMLHighlightToken, + # Mode 0: just look for tags + ( + ('COMMENT', re.compile( r'|'), commentstyle), + ('XMLCRAP', re.compile( r']*>'), preprocstyle), + ('SCRIPT', re.compile( r' + + +
+ + + + + +""" + +def elmcmp(e1, e2): + n1 = nsdict[e1[0]] + n2 = nsdict[e2[0]] + if cmp(n1,n2) != 0: return cmp(n1,n2) + return cmp(e1[1], e2[1]) + + +def listofelements(elements, anytext, nonetext): + global textfd + if elements is None: + x = anytext + elif elements is () or elements is []: + x = nonetext + else: + elclasses = [ makehref(e) for e in elements] + elclasses.sort() + x = ", ".join(elclasses) + print >>textfd, """%s.""" % x + +# Invert the children dictionary to construct parents +parents = {} + +ns='' +for parent, children in grammar.allowed_children.items(): + if children: + for child in children: + if not parents.has_key(child): + parents[child] = [] + if not parent in parents[child]: + parents[child].append(parent) + + +def makeid(t): + return t[1].title().replace('-','') + +def makehref(t): + + return """%s.%s""" % ( nsdict[t[0]], t[1].title().replace('-',''), + nsdict[t[0]], t[1].title().replace('-','')) + +def makeclass(t): + return "%s.%s" % ( nsdict[t[0]], t[1].title().replace('-','')) + + + +childkeys = grammar.allowed_children.keys() +childkeys.sort(elmcmp) +ns = '' + + +for element in childkeys: + children = grammar.allowed_children[element] + if ns != nsdict[element[0]]: + if ns != '': + footer() + textfd.close() + ns = nsdict[element[0]] + textfd = open("%s.html" % ns, "w") + header(ns) + print >>textfd, "

%s module

" % ns + classname = makeclass(element) + print >>textfd, """

%s

""" % ( makeid(element), classname) + + # Required attributes + print >>textfd, "

Requires the following attributes:", + required_attributes = grammar.required_attributes.get(element) + if required_attributes is None or required_attributes is (): + info = "No attribute is required" + else: + required_args = [ a[1].lower().replace('-','') for a in required_attributes] + required_args.sort() + info = ', '.join(required_args) + print >>textfd, """%s.

""" % info + + # Allowed attributes + print >>textfd, "

Allows the following attributes:", + allowed_attrs = grammar.allowed_attributes.get(element) + if allowed_attrs is None or allowed_attrs is (): + info = "No attribute is allowed" + else: + allowed_args = [ a[1].lower().replace('-','') for a in allowed_attrs] + allowed_args.sort() + info = ', '.join(allowed_args) + print >>textfd, """%s.

""" % info + + #PARENTS + print >>textfd, "

These elements contain %s:" % classname, + listofelements(parents.get(element),"This is a toplevel element","This is a toplevel element") + print >>textfd, "

" + + #CHILDREN + print >>textfd, "

The following elements occur in %s: " % classname, + listofelements(children,"Any element is allowed","No element is allowed") + print >>textfd, "

" diff --git a/odf/__init__.py b/odf/__init__.py new file mode 100644 index 0000000..17c80e0 --- /dev/null +++ b/odf/__init__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2007 Søren Roug, European Environment Agency +# +# This is free software. You may redistribute it under the terms +# of the Apache license and the GNU General Public License Version +# 2 or at your option any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + diff --git a/odf/anim.py b/odf/anim.py new file mode 100644 index 0000000..27dca36 --- /dev/null +++ b/odf/anim.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import ANIMNS +from element import Element + + +# Autogenerated +def Animate(**args): + return Element(qname = (ANIMNS,'animate'), **args) + +def Animatecolor(**args): + return Element(qname = (ANIMNS,'animateColor'), **args) + +def Animatemotion(**args): + return Element(qname = (ANIMNS,'animateMotion'), **args) + +def Animatetransform(**args): + return Element(qname = (ANIMNS,'animateTransform'), **args) + +def Audio(**args): + return Element(qname = (ANIMNS,'audio'), **args) + +def Command(**args): + return Element(qname = (ANIMNS,'command'), **args) + +def Iterate(**args): + return Element(qname = (ANIMNS,'iterate'), **args) + +def Par(**args): + return Element(qname = (ANIMNS,'par'), **args) + +def Param(**args): + return Element(qname = (ANIMNS,'param'), **args) + +def Seq(**args): + return Element(qname = (ANIMNS,'seq'), **args) + +def Set(**args): + return Element(qname = (ANIMNS,'set'), **args) + +def Transitionfilter(**args): + return Element(qname = (ANIMNS,'transitionFilter'), **args) + diff --git a/odf/attrconverters.py b/odf/attrconverters.py new file mode 100644 index 0000000..fd48f6a --- /dev/null +++ b/odf/attrconverters.py @@ -0,0 +1,1612 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2013 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +import sys, os.path +sys.path.append(os.path.dirname(__file__)) +from namespaces import * +import re, types + +pattern_color = re.compile(r'#[0-9a-fA-F]{6}') +pattern_vector3D = re.compile(r'\([ ]*-?([0-9]+(\.[0-9]*)?|\.[0-9]+)([ ]+-?([0-9]+(\.[0-9]*)?|\.[0-9]+)){2}[ ]*\)') + +def make_NCName(arg): + for c in (':',' '): + arg = arg.replace(c,"_%x_" % ord(c)) + return arg + +def cnv_angle(attribute, arg, element): + if sys.version_info[0]==2: + return unicode(arg) + else: + return str(arg) + +def cnv_anyURI(attribute, arg, element): + return str(arg) + +def cnv_boolean(attribute, arg, element): + """ XML Schema Part 2: Datatypes Second Edition + An instance of a datatype that is defined as boolean can have the + following legal literals {true, false, 1, 0} + """ + if str(arg).lower() in ("0","false","no"): + return "false" + if str(arg).lower() in ("1","true","yes"): + return "true" + raise ValueError( "'%s' not allowed as Boolean value for %s" % (str(arg), attribute[1])) + +# Potentially accept color values +def cnv_color(attribute, arg, element): + """ A RGB color in conformance with §5.9.11 of [XSL], that is a RGB color in notation “#rrggbb”, where + rr, gg and bb are 8-bit hexadecimal digits. + """ + return str(arg) + +def cnv_configtype(attribute, arg, element): + if str(arg) not in ("boolean", "short", "int", "long", + "double", "string", "datetime", "base64Binary"): + raise ValueError( "'%s' not allowed" % str(arg)) + return str(arg) + +def cnv_data_source_has_labels(attribute, arg, element): + if str(arg) not in ("none","row","column","both"): + raise ValueError( "'%s' not allowed" % str(arg)) + return str(arg) + +# Understand different date formats +def cnv_date(attribute, arg, element): + """ A dateOrDateTime value is either an [xmlschema-2] date value or an [xmlschema-2] dateTime + value. + """ + return str(arg) + +def cnv_dateTime(attribute, arg, element): + """ A dateOrDateTime value is either an [xmlschema-2] date value or an [xmlschema-2] dateTime + value. + """ + return str(arg) + +def cnv_double(attribute, arg, element): + return str(arg) + +def cnv_draw_aspect(attribute, arg, element): + if str(arg) not in ("content", "thumbnail", "icon", "print-view"): + raise ValueError( "'%s' not allowed" % str(arg)) + return str(arg) + +def cnv_duration(attribute, arg, element): + return str(arg) + +def cnv_family(attribute, arg, element): + """ A style family """ + if str(arg) not in ("text", "paragraph", "section", "ruby", "table", "table-column", "table-row", "table-cell", + "graphic", "presentation", "drawing-page", "chart"): + raise ValueError( "'%s' not allowed" % str(arg)) + return str(arg) + +def __save_prefix(attribute, arg, element): + prefix = arg.split(':',1)[0] + if prefix == arg: + return arg + namespace = element.get_knownns(prefix) + if namespace is None: + #raise ValueError( "'%s' is an unknown prefix" % str(prefix)) + return str(arg) + p = element.get_nsprefix(namespace) + return str(arg) + +def cnv_formula(attribute, arg, element): + """ A string containing a formula. Formulas do not have a predefined syntax, but the string should + begin with a namespace prefix, followed by a “:” (COLON, U+003A) separator, followed by the text + of the formula. The namespace bound to the prefix determines the syntax and semantics of the + formula. + """ + return __save_prefix(attribute, arg, element) + +def cnv_ID(attribute, arg, element): + return str(arg) + +def cnv_IDREF(attribute, arg, element): + return str(arg) + +def cnv_integer(attribute, arg, element): + return str(arg) + +pattern_language = re.compile(r'[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*') + +def cnv_language(attribute, arg, element): + global pattern_language + if not pattern_language.match(arg): + raise ValueError( "'%s' is not a valid language token" % arg) + return arg + +def cnv_legend_position(attribute, arg, element): + if str(arg) not in ("start", "end", "top", "bottom", "top-start", "bottom-start", "top-end", "bottom-end"): + raise ValueError( "'%s' not allowed" % str(arg)) + return str(arg) + +pattern_length = re.compile(r'-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)|(px))') + +def cnv_length(attribute, arg, element): + """ A (positive or negative) physical length, consisting of magnitude and unit, in conformance with the + Units of Measure defined in §5.9.13 of [XSL]. + """ + global pattern_length + if not pattern_length.match(arg): + raise ValueError( "'%s' is not a valid length" % arg) + return arg + +def cnv_lengthorpercent(attribute, arg, element): + failed = False + try: return cnv_length(attribute, arg, element) + except: failed = True + try: return cnv_percent(attribute, arg, element) + except: failed = True + if failed: + raise ValueError( "'%s' is not a valid length or percent" % arg) + return arg + +def cnv_list_linkage_type(attribute, arg, element): + if arg not in ('selection','selection-indices'): + raise ValueError( "'%s' is not either 'selection' or 'selection-indices'" % arg) + return str(arg) + +def cnv_metavaluetype(attribute, arg, element): + if str(arg) not in ("float", "date", "time", "boolean", "string"): + raise ValueError( "'%s' not allowed" % str(arg)) + return str(arg) + +def cnv_major_minor(attribute, arg, element): + if arg not in ('major','minor'): + raise ValueError( "'%s' is not either 'minor' or 'major'" % arg) + return str(arg) + +pattern_namespacedToken = re.compile(r'[0-9a-zA-Z_]+:[0-9a-zA-Z._\-]+') + +def cnv_namespacedToken(attribute, arg, element): + global pattern_namespacedToken + + if not pattern_namespacedToken.match(arg): + raise ValueError( "'%s' is not a valid namespaced token" % arg) + return __save_prefix(attribute, arg, element) + +def cnv_NCName(attribute, arg, element): + """ NCName is defined in http://www.w3.org/TR/REC-xml-names/#NT-NCName + Essentially an XML name minus ':' + """ + if (sys.version_info[0]==3 and isinstance(arg, str)) or (sys.version_info[0]==2 and type(arg) in types.StringTypes): + return make_NCName(arg) + else: + return arg.getAttrNS(STYLENS, 'name') + +# This function takes either an instance of a style (preferred) +# or a text string naming the style. If it is a text string, then it must +# already have been converted to an NCName +# The text-string argument is mainly for when we build a structure from XML +def cnv_StyleNameRef(attribute, arg, element): + try: + return arg.getAttrNS(STYLENS, 'name') + except: + return arg + +# This function takes either an instance of a style (preferred) +# or a text string naming the style. If it is a text string, then it must +# already have been converted to an NCName +# The text-string argument is mainly for when we build a structure from XML +def cnv_DrawNameRef(attribute, arg, element): + try: + return arg.getAttrNS(DRAWNS, 'name') + except: + return arg + +# Must accept list of Style objects +def cnv_NCNames(attribute, arg, element): + return ' '.join(arg) + +def cnv_nonNegativeInteger(attribute, arg, element): + return str(arg) + +pattern_percent = re.compile(r'-?([0-9]+(\.[0-9]*)?|\.[0-9]+)%') + +def cnv_percent(attribute, arg, element): + global pattern_percent + if not pattern_percent.match(arg): + raise ValueError( "'%s' is not a valid length" % arg) + return arg + +# Real one doesn't allow floating point values +pattern_points = re.compile(r'-?[0-9]+,-?[0-9]+([ ]+-?[0-9]+,-?[0-9]+)*') +#pattern_points = re.compile(r'-?[0-9.]+,-?[0-9.]+([ ]+-?[0-9.]+,-?[0-9.]+)*') +def cnv_points(attribute, arg, element): + global pattern_points + if (sys.version_info[0]==3 and isinstance(arg, str)) or (sys.version_info[0]==2 and type(arg) in types.StringTypes): + if not pattern_points.match(arg): + raise ValueError( "x,y are separated by a comma and the points are separated by white spaces") + return arg + else: + try: + strarg = ' '.join([ "%d,%d" % p for p in arg]) + except: + raise ValueError( "Points must be string or [(0,0),(1,1)] - not %s" % arg) + return strarg + +def cnv_positiveInteger(attribute, arg, element): + return str(arg) + +def cnv_rowOrCol(attribute, arg, element): + if str(arg) not in ("row","column"): + raise ValueError( "'%s' not allowed" % str(arg)) + return str(arg) + +def cnv_string(attribute, arg, element): + if sys.version_info[0]==2: + return unicode(arg) + else: + return str(arg) + +def cnv_stroke_linecap(attribute, arg, element): + if str(arg) not in ("butt", "square", "round"): + raise ValueError( "'%s' not allowed" % str(arg)) + return str(arg) + +def cnv_textnoteclass(attribute, arg, element): + if str(arg) not in ("footnote", "endnote"): + raise ValueError( "'%s' not allowed" % str(arg)) + return str(arg) + +# Understand different time formats +def cnv_time(attribute, arg, element): + return str(arg) + +def cnv_token(attribute, arg, element): + return str(arg) + +pattern_viewbox = re.compile(r'-?[0-9]+([ ]+-?[0-9]+){3}$') + +def cnv_viewbox(attribute, arg, element): + global pattern_viewbox + if not pattern_viewbox.match(arg): + raise ValueError( "viewBox must be four integers separated by whitespaces") + return arg + +def cnv_xlinkshow(attribute, arg, element): + if str(arg) not in ("new", "replace", "embed"): + raise ValueError( "'%s' not allowed" % str(arg)) + return str(arg) + +def cnv_xlinktype(attribute, arg, element): + if arg != "simple": + raise ValueError( "Value of '%s' must be 'simple'" % attribute[1]) + return arg + + +attrconverters = { + ((ANIMNS,u'audio-level'), None): cnv_double, + ((ANIMNS,u'color-interpolation'), None): cnv_string, + ((ANIMNS,u'color-interpolation-direction'), None): cnv_string, + ((ANIMNS,u'command'), None): cnv_string, + ((ANIMNS,u'formula'), None): cnv_string, + ((ANIMNS,u'id'), None): cnv_ID, + ((ANIMNS,u'iterate-interval'), None): cnv_duration, + ((ANIMNS,u'iterate-type'), None): cnv_string, + ((ANIMNS,u'name'), None): cnv_string, + ((ANIMNS,u'sub-item'), None): cnv_string, + ((ANIMNS,u'value'), None): cnv_string, +# ((DBNS,u'type'), None): cnv_namespacedToken, + ((CHARTNS,u'angle-offset'), None): cnv_angle, + ((CHARTNS,u'automatic-content'), None): cnv_boolean, + ((CHARTNS,u'auto-position'), None): cnv_boolean, + ((CHARTNS,u'auto-size'), None): cnv_boolean, + ((CHARTNS,u'axis-label-position'), None): cnv_string, # Multi-value + ((CHARTNS,u'axis-position'), None): cnv_string, # Multi-value + ((CHARTNS,u'attached-axis'), None): cnv_string, + ((CHARTNS,u'class'), (CHARTNS,u'grid')): cnv_major_minor, + ((CHARTNS,u'class'), None): cnv_namespacedToken, + ((CHARTNS,u'column-mapping'), None): cnv_string, + ((CHARTNS,u'connect-bars'), None): cnv_boolean, + ((CHARTNS,u'data-label-number'), None): cnv_string, + ((CHARTNS,u'data-label-symbol'), None): cnv_boolean, + ((CHARTNS,u'data-label-text'), None): cnv_boolean, + ((CHARTNS,u'data-source-has-labels'), None): cnv_data_source_has_labels, + ((CHARTNS,u'deep'), None): cnv_boolean, + ((CHARTNS,u'dimension'), None): cnv_string, + ((CHARTNS,u'display-equation'), None): cnv_boolean, + ((CHARTNS,u'display-label'), None): cnv_boolean, + ((CHARTNS,u'display-r-square'), None): cnv_boolean, + ((CHARTNS,u'error-category'), None): cnv_string, + ((CHARTNS,u'error-lower-indicator'), None): cnv_boolean, + ((CHARTNS,u'error-lower-limit'), None): cnv_string, + ((CHARTNS,u'error-margin'), None): cnv_string, + ((CHARTNS,u'error-percentage'), None): cnv_string, + ((CHARTNS,u'error-lower-range'), None): cnv_string, + ((CHARTNS,u'error-upper-indicator'), None): cnv_boolean, + ((CHARTNS,u'error-upper-limit'), None): cnv_string, + ((CHARTNS,u'error-upper-range'), None): cnv_string, + ((CHARTNS,u'gap-width'), None): cnv_string, + ((CHARTNS,u'group-bars-per-axis'), None): cnv_boolean, + ((CHARTNS,u'hole-size'), None): cnv_percent, + ((CHARTNS,u'include-hidden-cells'), None): cnv_boolean, + ((CHARTNS,u'interpolation'), None): cnv_string, + ((CHARTNS,u'interval-major'), None): cnv_string, + ((CHARTNS,u'interval-minor-divisor'), None): cnv_string, + ((CHARTNS,u'japanese-candle-stick'), None): cnv_boolean, + ((CHARTNS,u'label-arrangement'), None): cnv_string, + ((CHARTNS,u'label-cell-address'), None): cnv_string, + ((CHARTNS,u'label-position'), None): cnv_string, # Multi-value + ((CHARTNS,u'label-position-negative'), None): cnv_string, # Multi-value + ((CHARTNS,u'legend-align'), None): cnv_string, + ((CHARTNS,u'legend-position'), None): cnv_legend_position, + ((CHARTNS,u'lines'), None): cnv_boolean, + ((CHARTNS,u'link-data-style-to-source'), None): cnv_boolean, + ((CHARTNS,u'logarithmic'), None): cnv_boolean, + ((CHARTNS,u'maximum'), None): cnv_string, + ((CHARTNS,u'mean-value'), None): cnv_boolean, + ((CHARTNS,u'minimum'), None): cnv_string, + ((CHARTNS,u'name'), None): cnv_string, + ((CHARTNS,u'origin'), None): cnv_string, + ((CHARTNS,u'overlap'), None): cnv_string, + ((CHARTNS,u'percentage'), None): cnv_boolean, + ((CHARTNS,u'pie-offset'), None): cnv_string, + ((CHARTNS,u'regression-type'), None): cnv_string, + ((CHARTNS,u'repeated'), None): cnv_nonNegativeInteger, + ((CHARTNS,u'reverse-direction'), None): cnv_boolean, + ((CHARTNS,u'right-angled-axes'), None): cnv_boolean, + ((CHARTNS,u'row-mapping'), None): cnv_string, + ((CHARTNS,u'scale-text'), None): cnv_boolean, + ((CHARTNS,u'series-source'), None): cnv_string, + ((CHARTNS,u'solid-type'), None): cnv_string, + ((CHARTNS,u'sort-by-x-values'), None): cnv_boolean, + ((CHARTNS,u'spline-order'), None): cnv_string, + ((CHARTNS,u'spline-resolution'), None): cnv_string, + ((CHARTNS,u'stacked'), None): cnv_boolean, + ((CHARTNS,u'style-name'), None): cnv_StyleNameRef, + ((CHARTNS,u'symbol-height'), None): cnv_string, + ((CHARTNS,u'symbol-name'), None): cnv_string, + ((CHARTNS,u'symbol-type'), None): cnv_string, + ((CHARTNS,u'symbol-width'), None): cnv_string, + ((CHARTNS,u'text-overlap'), None): cnv_boolean, + ((CHARTNS,u'three-dimensional'), None): cnv_boolean, + ((CHARTNS,u'tick-mark-position'), None): cnv_string, # Multi-value + ((CHARTNS,u'tick-marks-major-inner'), None): cnv_boolean, + ((CHARTNS,u'tick-marks-major-outer'), None): cnv_boolean, + ((CHARTNS,u'tick-marks-minor-inner'), None): cnv_boolean, + ((CHARTNS,u'tick-marks-minor-outer'), None): cnv_boolean, + ((CHARTNS,u'treat-empty-cells'), None): cnv_string, # Multi-value + ((CHARTNS,u'values-cell-range-address'), None): cnv_string, + ((CHARTNS,u'vertical'), None): cnv_boolean, + ((CHARTNS,u'visible'), None): cnv_boolean, + ((CONFIGNS,u'name'), None): cnv_formula, + ((CONFIGNS,u'type'), None): cnv_configtype, + ((DR3DNS,u'ambient-color'), None): cnv_string, + ((DR3DNS,u'back-scale'), None): cnv_string, + ((DR3DNS,u'backface-culling'), None): cnv_string, + ((DR3DNS,u'center'), None): cnv_string, + ((DR3DNS,u'close-back'), None): cnv_boolean, + ((DR3DNS,u'close-front'), None): cnv_boolean, + ((DR3DNS,u'depth'), None): cnv_length, + ((DR3DNS,u'diffuse-color'), None): cnv_string, + ((DR3DNS,u'direction'), None): cnv_string, + ((DR3DNS,u'distance'), None): cnv_length, + ((DR3DNS,u'edge-rounding'), None): cnv_string, + ((DR3DNS,u'edge-rounding-mode'), None): cnv_string, + ((DR3DNS,u'emissive-color'), None): cnv_string, + ((DR3DNS,u'enabled'), None): cnv_boolean, + ((DR3DNS,u'end-angle'), None): cnv_string, + ((DR3DNS,u'focal-length'), None): cnv_length, + ((DR3DNS,u'horizontal-segments'), None): cnv_string, + ((DR3DNS,u'lighting-mode'), None): cnv_boolean, + ((DR3DNS,u'max-edge'), None): cnv_string, + ((DR3DNS,u'min-edge'), None): cnv_string, + ((DR3DNS,u'normals-direction'), None): cnv_string, + ((DR3DNS,u'normals-kind'), None): cnv_string, + ((DR3DNS,u'projection'), None): cnv_string, + ((DR3DNS,u'shade-mode'), None): cnv_string, + ((DR3DNS,u'shadow'), None): cnv_string, + ((DR3DNS,u'shadow-slant'), None): cnv_nonNegativeInteger, + ((DR3DNS,u'shininess'), None): cnv_string, + ((DR3DNS,u'size'), None): cnv_string, + ((DR3DNS,u'specular'), None): cnv_boolean, + ((DR3DNS,u'specular-color'), None): cnv_string, + ((DR3DNS,u'texture-filter'), None): cnv_string, + ((DR3DNS,u'texture-generation-mode-x'), None): cnv_string, + ((DR3DNS,u'texture-generation-mode-y'), None): cnv_string, + ((DR3DNS,u'texture-kind'), None): cnv_string, + ((DR3DNS,u'texture-mode'), None): cnv_string, + ((DR3DNS,u'transform'), None): cnv_string, + ((DR3DNS,u'vertical-segments'), None): cnv_string, + ((DR3DNS,u'vpn'), None): cnv_string, + ((DR3DNS,u'vrp'), None): cnv_string, + ((DR3DNS,u'vup'), None): cnv_string, + ((DRAWNS,u'align'), None): cnv_string, + ((DRAWNS,u'angle'), None): cnv_integer, + ((DRAWNS,u'archive'), None): cnv_string, + ((DRAWNS,u'auto-grow-height'), None): cnv_boolean, + ((DRAWNS,u'auto-grow-width'), None): cnv_boolean, + ((DRAWNS,u'background-size'), None): cnv_string, + ((DRAWNS,u'blue'), None): cnv_string, + ((DRAWNS,u'border'), None): cnv_string, + ((DRAWNS,u'caption-angle'), None): cnv_string, + ((DRAWNS,u'caption-angle-type'), None): cnv_string, + ((DRAWNS,u'caption-escape'), None): cnv_string, + ((DRAWNS,u'caption-escape-direction'), None): cnv_string, + ((DRAWNS,u'caption-fit-line-length'), None): cnv_boolean, + ((DRAWNS,u'caption-gap'), None): cnv_string, + ((DRAWNS,u'caption-line-length'), None): cnv_length, + ((DRAWNS,u'caption-point-x'), None): cnv_string, + ((DRAWNS,u'caption-point-y'), None): cnv_string, + ((DRAWNS,u'caption-id'), None): cnv_IDREF, + ((DRAWNS,u'caption-type'), None): cnv_string, + ((DRAWNS,u'chain-next-name'), None): cnv_string, + ((DRAWNS,u'class-id'), None): cnv_string, + ((DRAWNS,u'class-names'), None): cnv_NCNames, + ((DRAWNS,u'code'), None): cnv_string, + ((DRAWNS,u'color'), None): cnv_string, + ((DRAWNS,u'color-inversion'), None): cnv_boolean, + ((DRAWNS,u'color-mode'), None): cnv_string, + ((DRAWNS,u'concave'), None): cnv_string, + ((DRAWNS,u'concentric-gradient-fill-allowed'), None): cnv_boolean, + ((DRAWNS,u'contrast'), None): cnv_string, + ((DRAWNS,u'control'), None): cnv_IDREF, + ((DRAWNS,u'copy-of'), None): cnv_string, + ((DRAWNS,u'corner-radius'), None): cnv_length, + ((DRAWNS,u'corners'), None): cnv_positiveInteger, + ((DRAWNS,u'cx'), None): cnv_string, + ((DRAWNS,u'cy'), None): cnv_string, + ((DRAWNS,u'data'), None): cnv_string, + ((DRAWNS,u'decimal-places'), None): cnv_string, + ((DRAWNS,u'display'), None): cnv_string, + ((DRAWNS,u'display-name'), None): cnv_string, + ((DRAWNS,u'distance'), None): cnv_lengthorpercent, + ((DRAWNS,u'dots1'), None): cnv_integer, + ((DRAWNS,u'dots1-length'), None): cnv_lengthorpercent, + ((DRAWNS,u'dots2'), None): cnv_integer, + ((DRAWNS,u'dots2-length'), None): cnv_lengthorpercent, + ((DRAWNS,u'draw-aspect'), None): cnv_draw_aspect, + ((DRAWNS,u'end-angle'), None): cnv_angle, + ((DRAWNS,u'end'), None): cnv_string, + ((DRAWNS,u'end-color'), None): cnv_string, + ((DRAWNS,u'end-glue-point'), None): cnv_nonNegativeInteger, + ((DRAWNS,u'end-guide'), None): cnv_length, + ((DRAWNS,u'end-intensity'), None): cnv_string, + ((DRAWNS,u'end-line-spacing-horizontal'), None): cnv_string, + ((DRAWNS,u'end-line-spacing-vertical'), None): cnv_string, + ((DRAWNS,u'end-shape'), None): cnv_IDREF, + ((DRAWNS,u'engine'), None): cnv_namespacedToken, + ((DRAWNS,u'enhanced-path'), None): cnv_string, + ((DRAWNS,u'escape-direction'), None): cnv_string, + ((DRAWNS,u'extrusion-allowed'), None): cnv_boolean, + ((DRAWNS,u'extrusion-brightness'), None): cnv_string, + ((DRAWNS,u'extrusion'), None): cnv_boolean, + ((DRAWNS,u'extrusion-color'), None): cnv_boolean, + ((DRAWNS,u'extrusion-depth'), None): cnv_double, + ((DRAWNS,u'extrusion-diffusion'), None): cnv_string, + ((DRAWNS,u'extrusion-first-light-direction'), None): cnv_string, + ((DRAWNS,u'extrusion-first-light-harsh'), None): cnv_boolean, + ((DRAWNS,u'extrusion-first-light-level'), None): cnv_string, + ((DRAWNS,u'extrusion-light-face'), None): cnv_boolean, + ((DRAWNS,u'extrusion-metal'), None): cnv_boolean, + ((DRAWNS,u'extrusion-number-of-line-segments'), None): cnv_integer, + ((DRAWNS,u'extrusion-origin'), None): cnv_double, + ((DRAWNS,u'extrusion-rotation-angle'), None): cnv_double, + ((DRAWNS,u'extrusion-rotation-center'), None): cnv_string, + ((DRAWNS,u'extrusion-second-light-direction'), None): cnv_string, + ((DRAWNS,u'extrusion-second-light-harsh'), None): cnv_boolean, + ((DRAWNS,u'extrusion-second-light-level'), None): cnv_string, + ((DRAWNS,u'extrusion-shininess'), None): cnv_string, + ((DRAWNS,u'extrusion-skew'), None): cnv_double, + ((DRAWNS,u'extrusion-specularity'), None): cnv_string, + ((DRAWNS,u'extrusion-viewpoint'), None): cnv_string, + ((DRAWNS,u'fill'), None): cnv_string, + ((DRAWNS,u'fill-color'), None): cnv_string, + ((DRAWNS,u'fill-gradient-name'), None): cnv_string, + ((DRAWNS,u'fill-hatch-name'), None): cnv_string, + ((DRAWNS,u'fill-hatch-solid'), None): cnv_boolean, + ((DRAWNS,u'fill-image-height'), None): cnv_lengthorpercent, + ((DRAWNS,u'fill-image-name'), None): cnv_DrawNameRef, + ((DRAWNS,u'fill-image-ref-point'), None): cnv_string, + ((DRAWNS,u'fill-image-ref-point-x'), None): cnv_string, + ((DRAWNS,u'fill-image-ref-point-y'), None): cnv_string, + ((DRAWNS,u'fill-image-width'), None): cnv_lengthorpercent, + ((DRAWNS,u'filter-name'), None): cnv_string, + ((DRAWNS,u'fit-to-contour'), None): cnv_boolean, + ((DRAWNS,u'fit-to-size'), None): cnv_string, # ODF 1.2 says boolean + ((DRAWNS,u'formula'), None): cnv_string, + ((DRAWNS,u'frame-display-border'), None): cnv_boolean, + ((DRAWNS,u'frame-display-scrollbar'), None): cnv_boolean, + ((DRAWNS,u'frame-margin-horizontal'), None): cnv_string, + ((DRAWNS,u'frame-margin-vertical'), None): cnv_string, + ((DRAWNS,u'frame-name'), None): cnv_string, + ((DRAWNS,u'gamma'), None): cnv_string, + ((DRAWNS,u'glue-point-leaving-directions'), None): cnv_string, + ((DRAWNS,u'glue-point-type'), None): cnv_string, + ((DRAWNS,u'glue-points'), None): cnv_string, + ((DRAWNS,u'gradient-step-count'), None): cnv_string, + ((DRAWNS,u'green'), None): cnv_string, + ((DRAWNS,u'guide-distance'), None): cnv_string, + ((DRAWNS,u'guide-overhang'), None): cnv_length, + ((DRAWNS,u'handle-mirror-horizontal'), None): cnv_boolean, + ((DRAWNS,u'handle-mirror-vertical'), None): cnv_boolean, + ((DRAWNS,u'handle-polar'), None): cnv_string, + ((DRAWNS,u'handle-position'), None): cnv_string, + ((DRAWNS,u'handle-radius-range-maximum'), None): cnv_string, + ((DRAWNS,u'handle-radius-range-minimum'), None): cnv_string, + ((DRAWNS,u'handle-range-x-maximum'), None): cnv_string, + ((DRAWNS,u'handle-range-x-minimum'), None): cnv_string, + ((DRAWNS,u'handle-range-y-maximum'), None): cnv_string, + ((DRAWNS,u'handle-range-y-minimum'), None): cnv_string, + ((DRAWNS,u'handle-switched'), None): cnv_boolean, +# ((DRAWNS,u'id'), None): cnv_ID, +# ((DRAWNS,u'id'), None): cnv_nonNegativeInteger, # ?? line 6581 in RNG + ((DRAWNS,u'id'), None): cnv_string, + ((DRAWNS,u'image-opacity'), None): cnv_string, + ((DRAWNS,u'kind'), None): cnv_string, + ((DRAWNS,u'layer'), None): cnv_string, + ((DRAWNS,u'line-distance'), None): cnv_string, + ((DRAWNS,u'line-skew'), None): cnv_string, + ((DRAWNS,u'luminance'), None): cnv_string, + ((DRAWNS,u'marker-end-center'), None): cnv_boolean, + ((DRAWNS,u'marker-end'), None): cnv_string, + ((DRAWNS,u'marker-end-width'), None): cnv_length, + ((DRAWNS,u'marker-start-center'), None): cnv_boolean, + ((DRAWNS,u'marker-start'), None): cnv_string, + ((DRAWNS,u'marker-start-width'), None): cnv_length, + ((DRAWNS,u'master-page-name'), None): cnv_StyleNameRef, + ((DRAWNS,u'may-script'), None): cnv_boolean, + ((DRAWNS,u'measure-align'), None): cnv_string, + ((DRAWNS,u'measure-vertical-align'), None): cnv_string, + ((DRAWNS,u'mime-type'), None): cnv_string, + ((DRAWNS,u'mirror-horizontal'), None): cnv_boolean, + ((DRAWNS,u'mirror-vertical'), None): cnv_boolean, + ((DRAWNS,u'modifiers'), None): cnv_string, + ((DRAWNS,u'name'), None): cnv_NCName, +# ((DRAWNS,u'name'), None): cnv_string, + ((DRAWNS,u'nav-order'), None): cnv_IDREF, + ((DRAWNS,u'nohref'), None): cnv_string, + ((DRAWNS,u'notify-on-update-of-ranges'), None): cnv_string, + ((DRAWNS,u'object'), None): cnv_string, + ((DRAWNS,u'ole-draw-aspect'), None): cnv_string, + ((DRAWNS,u'opacity'), None): cnv_string, + ((DRAWNS,u'opacity-name'), None): cnv_string, + ((DRAWNS,u'page-number'), None): cnv_positiveInteger, + ((DRAWNS,u'parallel'), None): cnv_boolean, + ((DRAWNS,u'path-stretchpoint-x'), None): cnv_double, + ((DRAWNS,u'path-stretchpoint-y'), None): cnv_double, + ((DRAWNS,u'placing'), None): cnv_string, + ((DRAWNS,u'points'), None): cnv_points, + ((DRAWNS,u'protected'), None): cnv_boolean, + ((DRAWNS,u'recreate-on-edit'), None): cnv_boolean, + ((DRAWNS,u'red'), None): cnv_string, + ((DRAWNS,u'rotation'), None): cnv_integer, + ((DRAWNS,u'secondary-fill-color'), None): cnv_string, + ((DRAWNS,u'shadow'), None): cnv_string, + ((DRAWNS,u'shadow-color'), None): cnv_string, + ((DRAWNS,u'shadow-offset-x'), None): cnv_length, + ((DRAWNS,u'shadow-offset-y'), None): cnv_length, + ((DRAWNS,u'shadow-opacity'), None): cnv_string, + ((DRAWNS,u'shape-id'), None): cnv_IDREF, + ((DRAWNS,u'sharpness'), None): cnv_string, + ((DRAWNS,u'show-unit'), None): cnv_boolean, + ((DRAWNS,u'start-angle'), None): cnv_angle, + ((DRAWNS,u'start'), None): cnv_string, + ((DRAWNS,u'start-color'), None): cnv_string, + ((DRAWNS,u'start-glue-point'), None): cnv_nonNegativeInteger, + ((DRAWNS,u'start-guide'), None): cnv_length, + ((DRAWNS,u'start-intensity'), None): cnv_string, + ((DRAWNS,u'start-line-spacing-horizontal'), None): cnv_string, + ((DRAWNS,u'start-line-spacing-vertical'), None): cnv_string, + ((DRAWNS,u'start-shape'), None): cnv_IDREF, + ((DRAWNS,u'stroke'), None): cnv_string, + ((DRAWNS,u'stroke-dash'), None): cnv_string, + ((DRAWNS,u'stroke-dash-names'), None): cnv_string, + ((DRAWNS,u'stroke-linejoin'), None): cnv_string, + ((DRAWNS,u'style'), None): cnv_string, + ((DRAWNS,u'style-name'), None): cnv_StyleNameRef, + ((DRAWNS,u'symbol-color'), None): cnv_string, + ((DRAWNS,u'text-areas'), None): cnv_string, + ((DRAWNS,u'text-path-allowed'), None): cnv_boolean, + ((DRAWNS,u'text-path'), None): cnv_boolean, + ((DRAWNS,u'text-path-mode'), None): cnv_string, + ((DRAWNS,u'text-path-same-letter-heights'), None): cnv_boolean, + ((DRAWNS,u'text-path-scale'), None): cnv_string, + ((DRAWNS,u'text-rotate-angle'), None): cnv_double, + ((DRAWNS,u'text-style-name'), None): cnv_StyleNameRef, + ((DRAWNS,u'textarea-horizontal-align'), None): cnv_string, + ((DRAWNS,u'textarea-vertical-align'), None): cnv_string, + ((DRAWNS,u'tile-repeat-offset'), None): cnv_string, + ((DRAWNS,u'transform'), None): cnv_string, + ((DRAWNS,u'type'), None): cnv_string, + ((DRAWNS,u'unit'), None): cnv_string, + ((DRAWNS,u'value'), None): cnv_string, + ((DRAWNS,u'visible-area-height'), None): cnv_string, + ((DRAWNS,u'visible-area-left'), None): cnv_string, + ((DRAWNS,u'visible-area-top'), None): cnv_string, + ((DRAWNS,u'visible-area-width'), None): cnv_string, + ((DRAWNS,u'wrap-influence-on-position'), None): cnv_string, + ((DRAWNS,u'z-index'), None): cnv_nonNegativeInteger, + ((FONS,u'background-color'), None): cnv_string, + ((FONS,u'border-bottom'), None): cnv_string, + ((FONS,u'border'), None): cnv_string, + ((FONS,u'border-left'), None): cnv_string, + ((FONS,u'border-right'), None): cnv_string, + ((FONS,u'border-top'), None): cnv_string, + ((FONS,u'break-after'), None): cnv_string, + ((FONS,u'break-before'), None): cnv_string, + ((FONS,u'clip'), None): cnv_string, + ((FONS,u'color'), None): cnv_string, + ((FONS,u'column-count'), None): cnv_positiveInteger, + ((FONS,u'column-gap'), None): cnv_length, + ((FONS,u'country'), None): cnv_token, + ((FONS,u'end-indent'), None): cnv_length, + ((FONS,u'font-family'), None): cnv_string, + ((FONS,u'font-size'), None): cnv_string, + ((FONS,u'font-style'), None): cnv_string, + ((FONS,u'font-variant'), None): cnv_string, + ((FONS,u'font-weight'), None): cnv_string, + ((FONS,u'height'), None): cnv_string, + ((FONS,u'hyphenate'), None): cnv_boolean, + ((FONS,u'hyphenation-keep'), None): cnv_string, + ((FONS,u'hyphenation-ladder-count'), None): cnv_string, + ((FONS,u'hyphenation-push-char-count'), None): cnv_string, + ((FONS,u'hyphenation-remain-char-count'), None): cnv_string, + ((FONS,u'keep-together'), None): cnv_string, + ((FONS,u'keep-with-next'), None): cnv_string, + ((FONS,u'language'), None): cnv_token, + ((FONS,u'letter-spacing'), None): cnv_string, + ((FONS,u'line-height'), None): cnv_string, + ((FONS,u'margin-bottom'), None): cnv_string, + ((FONS,u'margin'), None): cnv_string, + ((FONS,u'margin-left'), None): cnv_string, + ((FONS,u'margin-right'), None): cnv_string, + ((FONS,u'margin-top'), None): cnv_string, + ((FONS,u'max-height'), None): cnv_string, + ((FONS,u'max-width'), None): cnv_string, + ((FONS,u'min-height'), None): cnv_length, + ((FONS,u'min-width'), None): cnv_string, + ((FONS,u'orphans'), None): cnv_string, + ((FONS,u'padding-bottom'), None): cnv_string, + ((FONS,u'padding'), None): cnv_string, + ((FONS,u'padding-left'), None): cnv_string, + ((FONS,u'padding-right'), None): cnv_string, + ((FONS,u'padding-top'), None): cnv_string, + ((FONS,u'page-height'), None): cnv_length, + ((FONS,u'page-width'), None): cnv_length, + ((FONS,u'script'), None): cnv_token, + ((FONS,u'space-after'), None): cnv_length, + ((FONS,u'space-before'), None): cnv_length, + ((FONS,u'start-indent'), None): cnv_length, + ((FONS,u'text-align'), None): cnv_string, + ((FONS,u'text-align-last'), None): cnv_string, + ((FONS,u'text-indent'), None): cnv_string, + ((FONS,u'text-shadow'), None): cnv_string, + ((FONS,u'text-transform'), None): cnv_string, + ((FONS,u'widows'), None): cnv_string, + ((FONS,u'width'), None): cnv_string, + ((FONS,u'wrap-option'), None): cnv_string, + ((FORMNS,u'allow-deletes'), None): cnv_boolean, + ((FORMNS,u'allow-inserts'), None): cnv_boolean, + ((FORMNS,u'allow-updates'), None): cnv_boolean, + ((FORMNS,u'apply-design-mode'), None): cnv_boolean, + ((FORMNS,u'apply-filter'), None): cnv_boolean, + ((FORMNS,u'auto-complete'), None): cnv_boolean, + ((FORMNS,u'automatic-focus'), None): cnv_boolean, + ((FORMNS,u'bound-column'), None): cnv_string, + ((FORMNS,u'button-type'), None): cnv_string, + ((FORMNS,u'command'), None): cnv_string, + ((FORMNS,u'command-type'), None): cnv_string, + ((FORMNS,u'control-implementation'), None): cnv_namespacedToken, + ((FORMNS,u'convert-empty-to-null'), None): cnv_boolean, + ((FORMNS,u'current-selected'), None): cnv_boolean, + ((FORMNS,u'current-state'), None): cnv_string, +# ((FORMNS,u'current-value'), None): cnv_date, +# ((FORMNS,u'current-value'), None): cnv_double, + ((FORMNS,u'current-value'), None): cnv_string, +# ((FORMNS,u'current-value'), None): cnv_time, + ((FORMNS,u'data-field'), None): cnv_string, + ((FORMNS,u'datasource'), None): cnv_string, + ((FORMNS,u'default-button'), None): cnv_boolean, + ((FORMNS,u'delay-for-repeat'), None): cnv_duration, + ((FORMNS,u'detail-fields'), None): cnv_string, + ((FORMNS,u'disabled'), None): cnv_boolean, + ((FORMNS,u'dropdown'), None): cnv_boolean, + ((FORMNS,u'echo-char'), None): cnv_string, + ((FORMNS,u'enctype'), None): cnv_string, + ((FORMNS,u'escape-processing'), None): cnv_boolean, + ((FORMNS,u'filter'), None): cnv_string, + ((FORMNS,u'focus-on-click'), None): cnv_boolean, + ((FORMNS,u'for'), None): cnv_string, + ((FORMNS,u'id'), None): cnv_ID, + ((FORMNS,u'ignore-result'), None): cnv_boolean, + ((FORMNS,u'image-align'), None): cnv_string, + ((FORMNS,u'image-data'), None): cnv_anyURI, + ((FORMNS,u'image-position'), None): cnv_string, + ((FORMNS,u'is-tristate'), None): cnv_boolean, + ((FORMNS,u'label'), None): cnv_string, + ((FORMNS,u'linked-cell'), None): cnv_string, + ((FORMNS,u'list-linkage-type'), None): cnv_list_linkage_type, + ((FORMNS,u'list-source'), None): cnv_string, + ((FORMNS,u'list-source-type'), None): cnv_string, + ((FORMNS,u'master-fields'), None): cnv_string, + ((FORMNS,u'max-length'), None): cnv_nonNegativeInteger, +# ((FORMNS,u'max-value'), None): cnv_date, +# ((FORMNS,u'max-value'), None): cnv_double, + ((FORMNS,u'max-value'), None): cnv_string, +# ((FORMNS,u'max-value'), None): cnv_time, + ((FORMNS,u'method'), None): cnv_string, +# ((FORMNS,u'min-value'), None): cnv_date, +# ((FORMNS,u'min-value'), None): cnv_double, + ((FORMNS,u'min-value'), None): cnv_string, +# ((FORMNS,u'min-value'), None): cnv_time, + ((FORMNS,u'multi-line'), None): cnv_boolean, + ((FORMNS,u'multiple'), None): cnv_boolean, + ((FORMNS,u'name'), None): cnv_string, + ((FORMNS,u'navigation-mode'), None): cnv_string, + ((FORMNS,u'order'), None): cnv_string, + ((FORMNS,u'orientation'), None): cnv_string, + ((FORMNS,u'page-step-size'), None): cnv_positiveInteger, + ((FORMNS,u'printable'), None): cnv_boolean, + ((FORMNS,u'property-name'), None): cnv_string, + ((FORMNS,u'readonly'), None): cnv_boolean, + ((FORMNS,u'repeat'), None): cnv_boolean, + ((FORMNS,u'selected'), None): cnv_boolean, + ((FORMNS,u'size'), None): cnv_nonNegativeInteger, + ((FORMNS,u'source-cell-range'), None): cnv_string, + ((FORMNS,u'spin-button'), None): cnv_boolean, + ((FORMNS,u'state'), None): cnv_string, + ((FORMNS,u'step-size'), None): cnv_positiveInteger, + ((FORMNS,u'tab-cycle'), None): cnv_string, + ((FORMNS,u'tab-index'), None): cnv_nonNegativeInteger, + ((FORMNS,u'tab-stop'), None): cnv_boolean, + ((FORMNS,u'text-style-name'), None): cnv_StyleNameRef, + ((FORMNS,u'title'), None): cnv_string, + ((FORMNS,u'toggle'), None): cnv_boolean, + ((FORMNS,u'validation'), None): cnv_boolean, +# ((FORMNS,u'value'), None): cnv_date, +# ((FORMNS,u'value'), None): cnv_double, + ((FORMNS,u'value'), None): cnv_string, +# ((FORMNS,u'value'), None): cnv_time, + ((FORMNS,u'visual-effect'), None): cnv_string, + ((FORMNS,u'xforms-list-source'), None): cnv_string, + ((FORMNS,u'xforms-submission'), None): cnv_string, + ((GRDDLNS,u'transformation'), None): cnv_string, + ((MANIFESTNS,u'algorithm-name'), None): cnv_string, + ((MANIFESTNS,u'checksum'), None): cnv_string, + ((MANIFESTNS,u'checksum-type'), None): cnv_string, + ((MANIFESTNS,u'full-path'), None): cnv_string, + ((MANIFESTNS,u'initialisation-vector'), None): cnv_string, + ((MANIFESTNS,u'iteration-count'), None): cnv_nonNegativeInteger, + ((MANIFESTNS,u'key-derivation-name'), None): cnv_string, + ((MANIFESTNS,u'media-type'), None): cnv_string, + ((MANIFESTNS,u'preferred-view-mode'), None): cnv_string, + ((MANIFESTNS,u'salt'), None): cnv_string, + ((MANIFESTNS,u'size'), None): cnv_nonNegativeInteger, + ((MANIFESTNS,u'version'), None): cnv_string, + ((METANS,u'cell-count'), None): cnv_nonNegativeInteger, + ((METANS,u'character-count'), None): cnv_nonNegativeInteger, + ((METANS,u'date'), None): cnv_dateTime, + ((METANS,u'delay'), None): cnv_duration, + ((METANS,u'draw-count'), None): cnv_nonNegativeInteger, + ((METANS,u'frame-count'), None): cnv_nonNegativeInteger, + ((METANS,u'image-count'), None): cnv_nonNegativeInteger, + ((METANS,u'name'), None): cnv_string, + ((METANS,u'non-whitespace-character-count'), None): cnv_nonNegativeInteger, + ((METANS,u'object-count'), None): cnv_nonNegativeInteger, + ((METANS,u'ole-object-count'), None): cnv_nonNegativeInteger, + ((METANS,u'page-count'), None): cnv_nonNegativeInteger, + ((METANS,u'paragraph-count'), None): cnv_nonNegativeInteger, + ((METANS,u'row-count'), None): cnv_nonNegativeInteger, + ((METANS,u'sentence-count'), None): cnv_nonNegativeInteger, + ((METANS,u'syllable-count'), None): cnv_nonNegativeInteger, + ((METANS,u'table-count'), None): cnv_nonNegativeInteger, + ((METANS,u'value-type'), None): cnv_metavaluetype, + ((METANS,u'word-count'), None): cnv_nonNegativeInteger, + ((NUMBERNS,u'automatic-order'), None): cnv_boolean, + ((NUMBERNS,u'calendar'), None): cnv_string, + ((NUMBERNS,u'country'), None): cnv_token, + ((NUMBERNS,u'decimal-places'), None): cnv_integer, + ((NUMBERNS,u'decimal-replacement'), None): cnv_string, + ((NUMBERNS,u'denominator-value'), None): cnv_integer, + ((NUMBERNS,u'display-factor'), None): cnv_double, + ((NUMBERNS,u'format-source'), None): cnv_string, + ((NUMBERNS,u'grouping'), None): cnv_boolean, + ((NUMBERNS,u'language'), None): cnv_token, + ((NUMBERNS,u'min-denominator-digits'), None): cnv_integer, + ((NUMBERNS,u'min-exponent-digits'), None): cnv_integer, + ((NUMBERNS,u'min-integer-digits'), None): cnv_integer, + ((NUMBERNS,u'min-numerator-digits'), None): cnv_integer, + ((NUMBERNS,u'position'), None): cnv_integer, + ((NUMBERNS,u'possessive-form'), None): cnv_boolean, + ((NUMBERNS,u'rfc-language-tag'), None): cnv_language, + ((NUMBERNS,u'script'), None): cnv_token, + ((NUMBERNS,u'style'), None): cnv_string, + ((NUMBERNS,u'textual'), None): cnv_boolean, + ((NUMBERNS,u'title'), None): cnv_string, + ((NUMBERNS,u'transliteration-country'), None): cnv_token, + ((NUMBERNS,u'transliteration-format'), None): cnv_string, + ((NUMBERNS,u'transliteration-language'), None): cnv_token, + ((NUMBERNS,u'transliteration-style'), None): cnv_string, + ((NUMBERNS,u'truncate-on-overflow'), None): cnv_boolean, + ((OFFICENS,u'automatic-update'), None): cnv_boolean, + ((OFFICENS,u'boolean-value'), None): cnv_boolean, + ((OFFICENS,u'conversion-mode'), None): cnv_string, + ((OFFICENS,u'currency'), None): cnv_string, + ((OFFICENS,u'date-value'), None): cnv_dateTime, + ((OFFICENS,u'dde-application'), None): cnv_string, + ((OFFICENS,u'dde-item'), None): cnv_string, + ((OFFICENS,u'dde-topic'), None): cnv_string, + ((OFFICENS,u'display'), None): cnv_boolean, + ((OFFICENS,u'mimetype'), None): cnv_string, + ((OFFICENS,u'name'), None): cnv_string, + ((OFFICENS,u'process-content'), None): cnv_boolean, + ((OFFICENS,u'server-map'), None): cnv_boolean, + ((OFFICENS,u'string-value'), None): cnv_string, + ((OFFICENS,u'target-frame'), None): cnv_string, + ((OFFICENS,u'target-frame-name'), None): cnv_string, + ((OFFICENS,u'time-value'), None): cnv_duration, + ((OFFICENS,u'title'), None): cnv_string, + ((OFFICENS,u'value'), None): cnv_double, + ((OFFICENS,u'value-type'), None): cnv_string, + ((OFFICENS,u'version'), None): cnv_string, + ((PRESENTATIONNS,u'action'), None): cnv_string, + ((PRESENTATIONNS,u'animations'), None): cnv_string, + ((PRESENTATIONNS,u'background-objects-visible'), None): cnv_boolean, + ((PRESENTATIONNS,u'background-visible'), None): cnv_boolean, + ((PRESENTATIONNS,u'class'), None): cnv_string, + ((PRESENTATIONNS,u'class-names'), None): cnv_NCNames, + ((PRESENTATIONNS,u'delay'), None): cnv_duration, + ((PRESENTATIONNS,u'direction'), None): cnv_string, + ((PRESENTATIONNS,u'display-date-time'), None): cnv_boolean, + ((PRESENTATIONNS,u'display-footer'), None): cnv_boolean, + ((PRESENTATIONNS,u'display-header'), None): cnv_boolean, + ((PRESENTATIONNS,u'display-page-number'), None): cnv_boolean, + ((PRESENTATIONNS,u'duration'), None): cnv_string, + ((PRESENTATIONNS,u'effect'), None): cnv_string, + ((PRESENTATIONNS,u'endless'), None): cnv_boolean, + ((PRESENTATIONNS,u'force-manual'), None): cnv_boolean, + ((PRESENTATIONNS,u'full-screen'), None): cnv_boolean, + ((PRESENTATIONNS,u'group-id'), None): cnv_string, + ((PRESENTATIONNS,u'master-element'), None): cnv_IDREF, + ((PRESENTATIONNS,u'mouse-as-pen'), None): cnv_boolean, + ((PRESENTATIONNS,u'mouse-visible'), None): cnv_boolean, + ((PRESENTATIONNS,u'name'), None): cnv_string, + ((PRESENTATIONNS,u'node-type'), None): cnv_string, + ((PRESENTATIONNS,u'object'), None): cnv_string, + ((PRESENTATIONNS,u'pages'), None): cnv_string, + ((PRESENTATIONNS,u'path-id'), None): cnv_string, + ((PRESENTATIONNS,u'pause'), None): cnv_duration, + ((PRESENTATIONNS,u'placeholder'), None): cnv_boolean, + ((PRESENTATIONNS,u'play-full'), None): cnv_boolean, + ((PRESENTATIONNS,u'presentation-page-layout-name'), None): cnv_StyleNameRef, + ((PRESENTATIONNS,u'preset-class'), None): cnv_string, + ((PRESENTATIONNS,u'preset-id'), None): cnv_string, + ((PRESENTATIONNS,u'preset-sub-type'), None): cnv_string, + ((PRESENTATIONNS,u'show'), None): cnv_string, + ((PRESENTATIONNS,u'show-end-of-presentation-slide'), None): cnv_boolean, + ((PRESENTATIONNS,u'show-logo'), None): cnv_boolean, + ((PRESENTATIONNS,u'source'), None): cnv_string, + ((PRESENTATIONNS,u'speed'), None): cnv_string, + ((PRESENTATIONNS,u'start-page'), None): cnv_string, + ((PRESENTATIONNS,u'start-scale'), None): cnv_string, + ((PRESENTATIONNS,u'start-with-navigator'), None): cnv_boolean, + ((PRESENTATIONNS,u'stay-on-top'), None): cnv_boolean, + ((PRESENTATIONNS,u'style-name'), None): cnv_StyleNameRef, + ((PRESENTATIONNS,u'transition-on-click'), None): cnv_string, + ((PRESENTATIONNS,u'transition-speed'), None): cnv_string, + ((PRESENTATIONNS,u'transition-style'), None): cnv_string, + ((PRESENTATIONNS,u'transition-type'), None): cnv_string, + ((PRESENTATIONNS,u'use-date-time-name'), None): cnv_string, + ((PRESENTATIONNS,u'use-footer-name'), None): cnv_string, + ((PRESENTATIONNS,u'use-header-name'), None): cnv_string, + ((PRESENTATIONNS,u'user-transformed'), None): cnv_boolean, + ((PRESENTATIONNS,u'verb'), None): cnv_nonNegativeInteger, + ((PRESENTATIONNS,u'visibility'), None): cnv_string, + ((SCRIPTNS,u'event-name'), None): cnv_formula, + ((SCRIPTNS,u'language'), None): cnv_formula, + ((SCRIPTNS,u'macro-name'), None): cnv_string, + ((SMILNS,u'accelerate'), None): cnv_double, + ((SMILNS,u'accumulate'), None): cnv_string, + ((SMILNS,u'additive'), None): cnv_string, + ((SMILNS,u'attributeName'), None): cnv_string, + ((SMILNS,u'autoReverse'), None): cnv_boolean, + ((SMILNS,u'begin'), None): cnv_string, + ((SMILNS,u'by'), None): cnv_string, + ((SMILNS,u'calcMode'), None): cnv_string, + ((SMILNS,u'decelerate'), None): cnv_double, + ((SMILNS,u'direction'), None): cnv_string, + ((SMILNS,u'dur'), None): cnv_string, + ((SMILNS,u'end'), None): cnv_string, + ((SMILNS,u'endsync'), None): cnv_string, + ((SMILNS,u'fadeColor'), None): cnv_string, + ((SMILNS,u'fill'), None): cnv_string, + ((SMILNS,u'fillDefault'), None): cnv_string, + ((SMILNS,u'from'), None): cnv_string, + ((SMILNS,u'keySplines'), None): cnv_string, + ((SMILNS,u'keyTimes'), None): cnv_string, + ((SMILNS,u'mode'), None): cnv_string, + ((SMILNS,u'repeatCount'), None): cnv_nonNegativeInteger, + ((SMILNS,u'repeatDur'), None): cnv_string, + ((SMILNS,u'restart'), None): cnv_string, + ((SMILNS,u'restartDefault'), None): cnv_string, + ((SMILNS,u'subtype'), None): cnv_string, + ((SMILNS,u'targetElement'), None): cnv_IDREF, + ((SMILNS,u'to'), None): cnv_string, + ((SMILNS,u'type'), None): cnv_string, + ((SMILNS,u'values'), None): cnv_string, + ((STYLENS,u'adjustment'), None): cnv_string, + ((STYLENS,u'apply-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'auto-text-indent'), None): cnv_boolean, + ((STYLENS,u'auto-update'), None): cnv_boolean, + ((STYLENS,u'background-transparency'), None): cnv_string, + ((STYLENS,u'base-cell-address'), None): cnv_string, + ((STYLENS,u'border-line-width-bottom'), None): cnv_string, + ((STYLENS,u'border-line-width'), None): cnv_string, + ((STYLENS,u'border-line-width-left'), None): cnv_string, + ((STYLENS,u'border-line-width-right'), None): cnv_string, + ((STYLENS,u'border-line-width-top'), None): cnv_string, + ((STYLENS,u'cell-protect'), None): cnv_string, + ((STYLENS,u'char'), None): cnv_string, + ((STYLENS,u'class'), None): cnv_string, + ((STYLENS,u'color'), None): cnv_string, + ((STYLENS,u'column-width'), None): cnv_string, + ((STYLENS,u'condition'), None): cnv_string, + ((STYLENS,u'country-asian'), None): cnv_string, + ((STYLENS,u'country-complex'), None): cnv_string, + ((STYLENS,u'data-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'decimal-places'), None): cnv_string, + ((STYLENS,u'default-outline-level'), None): cnv_positiveInteger, + ((STYLENS,u'diagonal-bl-tr'), None): cnv_string, + ((STYLENS,u'diagonal-bl-tr-widths'), None): cnv_string, + ((STYLENS,u'diagonal-tl-br'), None): cnv_string, + ((STYLENS,u'diagonal-tl-br-widths'), None): cnv_string, + ((STYLENS,u'direction'), None): cnv_string, + ((STYLENS,u'display'), None): cnv_boolean, + ((STYLENS,u'display-name'), None): cnv_string, + ((STYLENS,u'distance-after-sep'), None): cnv_length, + ((STYLENS,u'distance-before-sep'), None): cnv_length, + ((STYLENS,u'distance'), None): cnv_length, + ((STYLENS,u'dynamic-spacing'), None): cnv_boolean, + ((STYLENS,u'editable'), None): cnv_boolean, + ((STYLENS,u'family'), None): cnv_family, + ((STYLENS,u'filter-name'), None): cnv_string, + ((STYLENS,u'first-page-number'), None): cnv_string, + ((STYLENS,u'flow-with-text'), None): cnv_boolean, + ((STYLENS,u'font-adornments'), None): cnv_string, + ((STYLENS,u'font-charset'), None): cnv_string, + ((STYLENS,u'font-charset-asian'), None): cnv_string, + ((STYLENS,u'font-charset-complex'), None): cnv_string, + ((STYLENS,u'font-family-asian'), None): cnv_string, + ((STYLENS,u'font-family-complex'), None): cnv_string, + ((STYLENS,u'font-family-generic-asian'), None): cnv_string, + ((STYLENS,u'font-family-generic'), None): cnv_string, + ((STYLENS,u'font-family-generic-complex'), None): cnv_string, + ((STYLENS,u'font-independent-line-spacing'), None): cnv_boolean, + ((STYLENS,u'font-name-asian'), None): cnv_string, + ((STYLENS,u'font-name'), None): cnv_string, + ((STYLENS,u'font-name-complex'), None): cnv_string, + ((STYLENS,u'font-pitch-asian'), None): cnv_string, + ((STYLENS,u'font-pitch'), None): cnv_string, + ((STYLENS,u'font-pitch-complex'), None): cnv_string, + ((STYLENS,u'font-relief'), None): cnv_string, + ((STYLENS,u'font-size-asian'), None): cnv_string, + ((STYLENS,u'font-size-complex'), None): cnv_string, + ((STYLENS,u'font-size-rel-asian'), None): cnv_length, + ((STYLENS,u'font-size-rel'), None): cnv_length, + ((STYLENS,u'font-size-rel-complex'), None): cnv_length, + ((STYLENS,u'font-style-asian'), None): cnv_string, + ((STYLENS,u'font-style-complex'), None): cnv_string, + ((STYLENS,u'font-style-name-asian'), None): cnv_string, + ((STYLENS,u'font-style-name'), None): cnv_string, + ((STYLENS,u'font-style-name-complex'), None): cnv_string, + ((STYLENS,u'font-weight-asian'), None): cnv_string, + ((STYLENS,u'font-weight-complex'), None): cnv_string, + ((STYLENS,u'footnote-max-height'), None): cnv_length, + ((STYLENS,u'glyph-orientation-vertical'), None): cnv_string, + ((STYLENS,u'height'), None): cnv_string, + ((STYLENS,u'horizontal-pos'), None): cnv_string, + ((STYLENS,u'horizontal-rel'), None): cnv_string, + ((STYLENS,u'join-border'), None): cnv_boolean, + ((STYLENS,u'justify-single-word'), None): cnv_boolean, + ((STYLENS,u'language-asian'), None): cnv_string, + ((STYLENS,u'language-complex'), None): cnv_string, + ((STYLENS,u'layout-grid-base-height'), None): cnv_length, + ((STYLENS,u'layout-grid-base-width'), None): cnv_length, + ((STYLENS,u'layout-grid-color'), None): cnv_string, + ((STYLENS,u'layout-grid-display'), None): cnv_boolean, + ((STYLENS,u'layout-grid-lines'), None): cnv_string, + ((STYLENS,u'layout-grid-mode'), None): cnv_string, + ((STYLENS,u'layout-grid-print'), None): cnv_boolean, + ((STYLENS,u'layout-grid-ruby-below'), None): cnv_boolean, + ((STYLENS,u'layout-grid-ruby-height'), None): cnv_length, + ((STYLENS,u'layout-grid-snap-to'), None): cnv_boolean, + ((STYLENS,u'layout-grid-standard-mode'), None): cnv_boolean, + ((STYLENS,u'leader-char'), None): cnv_string, + ((STYLENS,u'leader-color'), None): cnv_string, + ((STYLENS,u'leader-style'), None): cnv_string, + ((STYLENS,u'leader-text'), None): cnv_string, + ((STYLENS,u'leader-text-style'), None): cnv_StyleNameRef, + ((STYLENS,u'leader-type'), None): cnv_string, + ((STYLENS,u'leader-width'), None): cnv_string, + ((STYLENS,u'legend-expansion-aspect-ratio'), None): cnv_double, + ((STYLENS,u'legend-expansion'), None): cnv_string, + ((STYLENS,u'length'), None): cnv_positiveInteger, + ((STYLENS,u'letter-kerning'), None): cnv_boolean, + ((STYLENS,u'line-break'), None): cnv_string, + ((STYLENS,u'line-height-at-least'), None): cnv_string, + ((STYLENS,u'line-spacing'), None): cnv_length, + ((STYLENS,u'line-style'), None): cnv_string, + ((STYLENS,u'lines'), None): cnv_positiveInteger, + ((STYLENS,u'list-level'), None): cnv_positiveInteger, + ((STYLENS,u'list-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'master-page-name'), None): cnv_StyleNameRef, + ((STYLENS,u'may-break-between-rows'), None): cnv_boolean, + ((STYLENS,u'min-row-height'), None): cnv_string, + ((STYLENS,u'mirror'), None): cnv_string, + ((STYLENS,u'name'), None): cnv_NCName, + ((STYLENS,u'name'), (STYLENS,u'font-face')): cnv_string, + ((STYLENS,u'next-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'num-format'), None): cnv_string, + ((STYLENS,u'num-letter-sync'), None): cnv_boolean, + ((STYLENS,u'num-prefix'), None): cnv_string, + ((STYLENS,u'num-suffix'), None): cnv_string, + ((STYLENS,u'number-wrapped-paragraphs'), None): cnv_string, + ((STYLENS,u'overflow-behavior'), None): cnv_string, + ((STYLENS,u'page-layout-name'), None): cnv_StyleNameRef, + ((STYLENS,u'page-number'), None): cnv_string, + ((STYLENS,u'page-usage'), None): cnv_string, + ((STYLENS,u'paper-tray-name'), None): cnv_string, + ((STYLENS,u'parent-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'percentage-data-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'position'), (STYLENS,u'tab-stop')): cnv_length, + ((STYLENS,u'position'), None): cnv_string, + ((STYLENS,u'print'), None): cnv_string, + ((STYLENS,u'print-content'), None): cnv_boolean, + ((STYLENS,u'print-orientation'), None): cnv_string, + ((STYLENS,u'print-page-order'), None): cnv_string, + ((STYLENS,u'protect'), (STYLENS,u'section-properties')): cnv_boolean, + ((STYLENS,u'protect'), (STYLENS,u'graphic-properties')): cnv_string, +# ((STYLENS,u'protect'), None): cnv_boolean, + ((STYLENS,u'punctuation-wrap'), None): cnv_string, + ((STYLENS,u'register-true'), None): cnv_boolean, + ((STYLENS,u'register-truth-ref-style-name'), None): cnv_string, + ((STYLENS,u'rel-column-width'), None): cnv_string, + ((STYLENS,u'rel-height'), None): cnv_string, + ((STYLENS,u'rel-width'), None): cnv_string, + ((STYLENS,u'repeat'), None): cnv_string, + ((STYLENS,u'repeat-content'), None): cnv_boolean, + ((STYLENS,u'rfc-language-tag'), None): cnv_language, + ((STYLENS,u'rfc-language-tag-asian'), None): cnv_language, + ((STYLENS,u'rfc-language-tag-complex'), None): cnv_language, + ((STYLENS,u'rotation-align'), None): cnv_string, + ((STYLENS,u'rotation-angle'), None): cnv_string, + ((STYLENS,u'row-height'), None): cnv_string, + ((STYLENS,u'ruby-align'), None): cnv_string, + ((STYLENS,u'ruby-position'), None): cnv_string, + ((STYLENS,u'run-through'), None): cnv_string, + ((STYLENS,u'scale-to'), None): cnv_string, + ((STYLENS,u'scale-to-pages'), None): cnv_string, + ((STYLENS,u'script-asian'), None): cnv_string, + ((STYLENS,u'script-complex'), None): cnv_string, + ((STYLENS,u'script-type'), None): cnv_string, + ((STYLENS,u'shadow'), None): cnv_string, + ((STYLENS,u'shrink-to-fit'), None): cnv_boolean, + ((STYLENS,u'snap-to-layout-grid'), None): cnv_boolean, + ((STYLENS,u'style'), None): cnv_string, + ((STYLENS,u'style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'tab-stop-distance'), None): cnv_string, + ((STYLENS,u'table-centering'), None): cnv_string, + ((STYLENS,u'text-align-source'), None): cnv_string, + ((STYLENS,u'text-autospace'), None): cnv_string, + ((STYLENS,u'text-blinking'), None): cnv_boolean, + ((STYLENS,u'text-combine'), None): cnv_string, + ((STYLENS,u'text-combine-end-char'), None): cnv_string, + ((STYLENS,u'text-combine-start-char'), None): cnv_string, + ((STYLENS,u'text-emphasize'), None): cnv_string, + ((STYLENS,u'text-line-through-color'), None): cnv_string, + ((STYLENS,u'text-line-through-mode'), None): cnv_string, + ((STYLENS,u'text-line-through-style'), None): cnv_string, + ((STYLENS,u'text-line-through-text'), None): cnv_string, + ((STYLENS,u'text-line-through-text-style'), None): cnv_string, + ((STYLENS,u'text-line-through-type'), None): cnv_string, + ((STYLENS,u'text-line-through-width'), None): cnv_string, + ((STYLENS,u'text-outline'), None): cnv_boolean, + ((STYLENS,u'text-overline-color'), None): cnv_string, + ((STYLENS,u'text-overline-mode'), None): cnv_string, + ((STYLENS,u'text-overline-style'), None): cnv_string, + ((STYLENS,u'text-overline-type'), None): cnv_string, + ((STYLENS,u'text-overline-width'), None): cnv_string, + ((STYLENS,u'text-position'), None): cnv_string, + ((STYLENS,u'text-rotation-angle'), None): cnv_string, + ((STYLENS,u'text-rotation-scale'), None): cnv_string, + ((STYLENS,u'text-scale'), None): cnv_string, + ((STYLENS,u'text-underline-color'), None): cnv_string, + ((STYLENS,u'text-underline-mode'), None): cnv_string, + ((STYLENS,u'text-underline-style'), None): cnv_string, + ((STYLENS,u'text-underline-type'), None): cnv_string, + ((STYLENS,u'text-underline-width'), None): cnv_string, + ((STYLENS,u'type'), None): cnv_string, + ((STYLENS,u'use-optimal-column-width'), None): cnv_boolean, + ((STYLENS,u'use-optimal-row-height'), None): cnv_boolean, + ((STYLENS,u'use-window-font-color'), None): cnv_boolean, + ((STYLENS,u'vertical-align'), None): cnv_string, + ((STYLENS,u'vertical-pos'), None): cnv_string, + ((STYLENS,u'vertical-rel'), None): cnv_string, + ((STYLENS,u'volatile'), None): cnv_boolean, + ((STYLENS,u'width'), None): cnv_string, + ((STYLENS,u'wrap'), None): cnv_string, + ((STYLENS,u'wrap-contour'), None): cnv_boolean, + ((STYLENS,u'wrap-contour-mode'), None): cnv_string, + ((STYLENS,u'wrap-dynamic-threshold'), None): cnv_length, + ((STYLENS,u'writing-mode-automatic'), None): cnv_boolean, + ((STYLENS,u'writing-mode'), None): cnv_string, + ((SVGNS,u'accent-height'), None): cnv_integer, + ((SVGNS,u'alphabetic'), None): cnv_integer, + ((SVGNS,u'ascent'), None): cnv_integer, + ((SVGNS,u'bbox'), None): cnv_string, + ((SVGNS,u'cap-height'), None): cnv_integer, + ((SVGNS,u'cx'), None): cnv_string, + ((SVGNS,u'cy'), None): cnv_string, + ((SVGNS,u'd'), None): cnv_string, + ((SVGNS,u'descent'), None): cnv_integer, + ((SVGNS,u'fill-rule'), None): cnv_string, + ((SVGNS,u'font-family'), None): cnv_string, + ((SVGNS,u'font-size'), None): cnv_string, + ((SVGNS,u'font-stretch'), None): cnv_string, + ((SVGNS,u'font-style'), None): cnv_string, + ((SVGNS,u'font-variant'), None): cnv_string, + ((SVGNS,u'font-weight'), None): cnv_string, + ((SVGNS,u'fx'), None): cnv_string, + ((SVGNS,u'fy'), None): cnv_string, + ((SVGNS,u'gradientTransform'), None): cnv_string, + ((SVGNS,u'gradientUnits'), None): cnv_string, + ((SVGNS,u'hanging'), None): cnv_integer, + ((SVGNS,u'height'), None): cnv_length, + ((SVGNS,u'ideographic'), None): cnv_integer, + ((SVGNS,u'mathematical'), None): cnv_integer, + ((SVGNS,u'name'), None): cnv_string, + ((SVGNS,u'offset'), None): cnv_string, + ((SVGNS,u'origin'), None): cnv_string, + ((SVGNS,u'overline-position'), None): cnv_integer, + ((SVGNS,u'overline-thickness'), None): cnv_integer, + ((SVGNS,u'panose-1'), None): cnv_string, + ((SVGNS,u'path'), None): cnv_string, + ((SVGNS,u'r'), None): cnv_length, + ((SVGNS,u'rx'), None): cnv_length, + ((SVGNS,u'ry'), None): cnv_length, + ((SVGNS,u'slope'), None): cnv_integer, + ((SVGNS,u'spreadMethod'), None): cnv_string, + ((SVGNS,u'stemh'), None): cnv_integer, + ((SVGNS,u'stemv'), None): cnv_integer, + ((SVGNS,u'stop-color'), None): cnv_string, + ((SVGNS,u'stop-opacity'), None): cnv_double, + ((SVGNS,u'strikethrough-position'), None): cnv_integer, + ((SVGNS,u'strikethrough-thickness'), None): cnv_integer, + ((SVGNS,u'string'), None): cnv_string, + ((SVGNS,u'stroke-color'), None): cnv_string, + ((SVGNS,u'stroke-linecap'), None): cnv_stroke_linecap, + ((SVGNS,u'stroke-opacity'), None): cnv_string, + ((SVGNS,u'stroke-width'), None): cnv_length, + ((SVGNS,u'type'), None): cnv_string, + ((SVGNS,u'underline-position'), None): cnv_integer, + ((SVGNS,u'underline-thickness'), None): cnv_integer, + ((SVGNS,u'unicode-range'), None): cnv_string, + ((SVGNS,u'units-per-em'), None): cnv_integer, + ((SVGNS,u'v-alphabetic'), None): cnv_integer, + ((SVGNS,u'v-hanging'), None): cnv_integer, + ((SVGNS,u'v-ideographic'), None): cnv_integer, + ((SVGNS,u'v-mathematical'), None): cnv_integer, + ((SVGNS,u'viewBox'), None): cnv_viewbox, + ((SVGNS,u'width'), None): cnv_length, + ((SVGNS,u'widths'), None): cnv_string, + ((SVGNS,u'x'), None): cnv_length, + ((SVGNS,u'x-height'), None): cnv_integer, + ((SVGNS,u'x1'), None): cnv_lengthorpercent, + ((SVGNS,u'x2'), None): cnv_lengthorpercent, + ((SVGNS,u'y'), None): cnv_length, + ((SVGNS,u'y1'), None): cnv_lengthorpercent, + ((SVGNS,u'y2'), None): cnv_lengthorpercent, + ((TABLENS,u'acceptance-state'), None): cnv_string, + ((TABLENS,u'add-empty-lines'), None): cnv_boolean, + ((TABLENS,u'algorithm'), None): cnv_formula, + ((TABLENS,u'align'), None): cnv_string, + ((TABLENS,u'allow-empty-cell'), None): cnv_boolean, + ((TABLENS,u'application-data'), None): cnv_string, + ((TABLENS,u'automatic-find-labels'), None): cnv_boolean, + ((TABLENS,u'base-cell-address'), None): cnv_string, + ((TABLENS,u'bind-styles-to-content'), None): cnv_boolean, + ((TABLENS,u'border-color'), None): cnv_string, + ((TABLENS,u'border-model'), None): cnv_string, + ((TABLENS,u'buttons'), None): cnv_string, + ((TABLENS,u'buttons'), None): cnv_string, + ((TABLENS,u'case-sensitive'), None): cnv_boolean, + ((TABLENS,u'case-sensitive'), None): cnv_string, + ((TABLENS,u'cell-address'), None): cnv_string, + ((TABLENS,u'cell-range-address'), None): cnv_string, + ((TABLENS,u'cell-range-address'), None): cnv_string, + ((TABLENS,u'cell-range'), None): cnv_string, + ((TABLENS,u'column'), None): cnv_integer, + ((TABLENS,u'comment'), None): cnv_string, + ((TABLENS,u'condition'), None): cnv_formula, + ((TABLENS,u'condition-source'), None): cnv_string, + ((TABLENS,u'condition-source-range-address'), None): cnv_string, + ((TABLENS,u'contains-error'), None): cnv_boolean, + ((TABLENS,u'contains-header'), None): cnv_boolean, + ((TABLENS,u'content-validation-name'), None): cnv_string, + ((TABLENS,u'copy-back'), None): cnv_boolean, + ((TABLENS,u'copy-formulas'), None): cnv_boolean, + ((TABLENS,u'copy-styles'), None): cnv_boolean, + ((TABLENS,u'count'), None): cnv_positiveInteger, + ((TABLENS,u'country'), None): cnv_token, + ((TABLENS,u'data-cell-range-address'), None): cnv_string, + ((TABLENS,u'data-field'), None): cnv_string, + ((TABLENS,u'data-type'), None): cnv_string, + ((TABLENS,u'database-name'), None): cnv_string, + ((TABLENS,u'database-table-name'), None): cnv_string, + ((TABLENS,u'date-end'), None): cnv_string, + ((TABLENS,u'date-start'), None): cnv_string, + ((TABLENS,u'date-value'), None): cnv_date, + ((TABLENS,u'default-cell-style-name'), None): cnv_StyleNameRef, + ((TABLENS,u'direction'), None): cnv_string, + ((TABLENS,u'display-border'), None): cnv_boolean, + ((TABLENS,u'display'), None): cnv_boolean, + ((TABLENS,u'display-duplicates'), None): cnv_boolean, + ((TABLENS,u'display-filter-buttons'), None): cnv_boolean, + ((TABLENS,u'display-list'), None): cnv_string, + ((TABLENS,u'display-member-mode'), None): cnv_string, + ((TABLENS,u'drill-down-on-double-click'), None): cnv_boolean, + ((TABLENS,u'embedded-number-behavior'), None): cnv_string, + ((TABLENS,u'enabled'), None): cnv_boolean, + ((TABLENS,u'end-cell-address'), None): cnv_string, + ((TABLENS,u'end'), None): cnv_string, + ((TABLENS,u'end-column'), None): cnv_integer, + ((TABLENS,u'end-position'), None): cnv_integer, + ((TABLENS,u'end-row'), None): cnv_integer, + ((TABLENS,u'end-table'), None): cnv_integer, + ((TABLENS,u'end-x'), None): cnv_length, + ((TABLENS,u'end-y'), None): cnv_length, + ((TABLENS,u'execute'), None): cnv_boolean, + ((TABLENS,u'expression'), None): cnv_formula, + ((TABLENS,u'field-name'), None): cnv_string, + ((TABLENS,u'field-number'), None): cnv_nonNegativeInteger, + ((TABLENS,u'field-number'), None): cnv_string, + ((TABLENS,u'filter-name'), None): cnv_string, + ((TABLENS,u'filter-options'), None): cnv_string, + ((TABLENS,u'first-row-end-column'), None): cnv_rowOrCol, + ((TABLENS,u'first-row-start-column'), None): cnv_rowOrCol, + ((TABLENS,u'formula'), None): cnv_formula, + ((TABLENS,u'function'), None): cnv_string, + ((TABLENS,u'function'), None): cnv_string, + ((TABLENS,u'grand-total'), None): cnv_string, + ((TABLENS,u'group-by-field-number'), None): cnv_nonNegativeInteger, + ((TABLENS,u'grouped-by'), None): cnv_string, + ((TABLENS,u'has-persistent-data'), None): cnv_boolean, + ((TABLENS,u'id'), None): cnv_string, + ((TABLENS,u'identify-categories'), None): cnv_boolean, + ((TABLENS,u'ignore-empty-rows'), None): cnv_boolean, + ((TABLENS,u'index'), None): cnv_nonNegativeInteger, + ((TABLENS,u'is-active'), None): cnv_boolean, + ((TABLENS,u'is-data-layout-field'), None): cnv_string, + ((TABLENS,u'is-selection'), None): cnv_boolean, + ((TABLENS,u'is-sub-table'), None): cnv_boolean, + ((TABLENS,u'label-cell-range-address'), None): cnv_string, + ((TABLENS,u'language'), None): cnv_token, + ((TABLENS,u'language'), None): cnv_token, + ((TABLENS,u'last-column-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'last-row-end-column'), None): cnv_rowOrCol, + ((TABLENS,u'last-row-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'last-row-start-column'), None): cnv_rowOrCol, + ((TABLENS,u'layout-mode'), None): cnv_string, + ((TABLENS,u'link-to-source-data'), None): cnv_boolean, + ((TABLENS,u'marked-invalid'), None): cnv_boolean, + ((TABLENS,u'matrix-covered'), None): cnv_boolean, + ((TABLENS,u'maximum-difference'), None): cnv_double, + ((TABLENS,u'member-count'), None): cnv_nonNegativeInteger, + ((TABLENS,u'member-name'), None): cnv_string, + ((TABLENS,u'member-type'), None): cnv_string, + ((TABLENS,u'message-type'), None): cnv_string, + ((TABLENS,u'mode'), None): cnv_string, + ((TABLENS,u'multi-deletion-spanned'), None): cnv_integer, + ((TABLENS,u'name'), None): cnv_string, + ((TABLENS,u'name'), None): cnv_string, + ((TABLENS,u'null-year'), None): cnv_positiveInteger, + ((TABLENS,u'number-columns-repeated'), None): cnv_positiveInteger, + ((TABLENS,u'number-columns-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'number-matrix-columns-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'number-matrix-rows-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'number-rows-repeated'), None): cnv_positiveInteger, + ((TABLENS,u'number-rows-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'object-name'), None): cnv_string, + ((TABLENS,u'on-update-keep-size'), None): cnv_boolean, + ((TABLENS,u'on-update-keep-styles'), None): cnv_boolean, + ((TABLENS,u'operator'), None): cnv_string, + ((TABLENS,u'operator'), None): cnv_string, + ((TABLENS,u'order'), None): cnv_string, + ((TABLENS,u'orientation'), None): cnv_string, + ((TABLENS,u'orientation'), None): cnv_string, + ((TABLENS,u'page-breaks-on-group-change'), None): cnv_boolean, + ((TABLENS,u'paragraph-style-name'), None): cnv_StyleNameRef, + ((TABLENS,u'parse-sql-statement'), None): cnv_boolean, + ((TABLENS,u'password'), None): cnv_string, + ((TABLENS,u'position'), None): cnv_integer, + ((TABLENS,u'precision-as-shown'), None): cnv_boolean, + ((TABLENS,u'print'), None): cnv_boolean, + ((TABLENS,u'print-ranges'), None): cnv_string, + ((TABLENS,u'protect'), None): cnv_boolean, + ((TABLENS,u'protected'), None): cnv_boolean, + ((TABLENS,u'protection-key'), None): cnv_string, + ((TABLENS,u'protection-key-digest-algorithm'), None): cnv_anyURI, + ((TABLENS,u'query-name'), None): cnv_string, + ((TABLENS,u'range-usable-as'), None): cnv_string, + ((TABLENS,u'rfc-language-tag'), None): cnv_language, + ((TABLENS,u'refresh-delay'), None): cnv_boolean, + ((TABLENS,u'refresh-delay'), None): cnv_duration, + ((TABLENS,u'rejecting-change-id'), None): cnv_string, + ((TABLENS,u'row'), None): cnv_integer, + ((TABLENS,u'scenario-ranges'), None): cnv_string, + ((TABLENS,u'script'), None): cnv_string, + ((TABLENS,u'search-criteria-must-apply-to-whole-cell'), None): cnv_boolean, + ((TABLENS,u'selected-page'), None): cnv_string, + ((TABLENS,u'show-details'), None): cnv_boolean, + ((TABLENS,u'show-empty'), None): cnv_boolean, + ((TABLENS,u'show-empty'), None): cnv_string, + ((TABLENS,u'show-filter-button'), None): cnv_boolean, + ((TABLENS,u'sort-mode'), None): cnv_string, + ((TABLENS,u'source-cell-range-addresses'), None): cnv_string, + ((TABLENS,u'source-cell-range-addresses'), None): cnv_string, + ((TABLENS,u'source-field-name'), None): cnv_string, + ((TABLENS,u'source-field-name'), None): cnv_string, + ((TABLENS,u'source-name'), None): cnv_string, + ((TABLENS,u'sql-statement'), None): cnv_string, + ((TABLENS,u'start'), None): cnv_string, + ((TABLENS,u'start-column'), None): cnv_integer, + ((TABLENS,u'start-position'), None): cnv_integer, + ((TABLENS,u'start-row'), None): cnv_integer, + ((TABLENS,u'start-table'), None): cnv_integer, + ((TABLENS,u'status'), None): cnv_string, + ((TABLENS,u'step'), None): cnv_double, + ((TABLENS,u'steps'), None): cnv_positiveInteger, + ((TABLENS,u'structure-protected'), None): cnv_boolean, + ((TABLENS,u'style-name'), None): cnv_StyleNameRef, + ((TABLENS,u'table-background'), None): cnv_boolean, + ((TABLENS,u'table'), None): cnv_integer, + ((TABLENS,u'table-name'), None): cnv_string, + ((TABLENS,u'target-cell-address'), None): cnv_string, + ((TABLENS,u'target-cell-address'), None): cnv_string, + ((TABLENS,u'target-range-address'), None): cnv_string, + ((TABLENS,u'target-range-address'), None): cnv_string, + ((TABLENS,u'template-name'), None): cnv_string, + ((TABLENS,u'title'), None): cnv_string, + ((TABLENS,u'track-changes'), None): cnv_boolean, + ((TABLENS,u'type'), None): cnv_string, + ((TABLENS,u'use-banding-columns-styles'), None): cnv_boolean, + ((TABLENS,u'use-banding-rows-styles'), None): cnv_boolean, + ((TABLENS,u'use-first-column-styles'), None): cnv_boolean, + ((TABLENS,u'use-first-row-styles'), None): cnv_boolean, + ((TABLENS,u'use-labels'), None): cnv_string, + ((TABLENS,u'use-last-column-styles'), None): cnv_boolean, + ((TABLENS,u'use-last-row-styles'), None): cnv_boolean, + ((TABLENS,u'use-regular-expressions'), None): cnv_boolean, + ((TABLENS,u'use-wildcards'), None): cnv_boolean, + ((TABLENS,u'used-hierarchy'), None): cnv_integer, + ((TABLENS,u'user-name'), None): cnv_string, + ((TABLENS,u'value'), None): cnv_string, + ((TABLENS,u'value'), None): cnv_string, + ((TABLENS,u'value-type'), None): cnv_string, + ((TABLENS,u'visibility'), None): cnv_string, + ((TEXTNS,u'active'), None): cnv_boolean, + ((TEXTNS,u'address'), None): cnv_string, + ((TEXTNS,u'alphabetical-separators'), None): cnv_boolean, + ((TEXTNS,u'anchor-page-number'), None): cnv_positiveInteger, + ((TEXTNS,u'anchor-type'), None): cnv_string, + ((TEXTNS,u'animation'), None): cnv_string, + ((TEXTNS,u'animation-delay'), None): cnv_string, + ((TEXTNS,u'animation-direction'), None): cnv_string, + ((TEXTNS,u'animation-repeat'), None): cnv_string, + ((TEXTNS,u'animation-start-inside'), None): cnv_boolean, + ((TEXTNS,u'animation-steps'), None): cnv_length, + ((TEXTNS,u'animation-stop-inside'), None): cnv_boolean, + ((TEXTNS,u'annote'), None): cnv_string, + ((TEXTNS,u'author'), None): cnv_string, + ((TEXTNS,u'bibliography-data-field'), None): cnv_string, + ((TEXTNS,u'bibliography-type'), None): cnv_string, + ((TEXTNS,u'booktitle'), None): cnv_string, + ((TEXTNS,u'bullet-char'), None): cnv_string, + ((TEXTNS,u'bullet-relative-size'), None): cnv_string, + ((TEXTNS,u'c'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'capitalize-entries'), None): cnv_boolean, + ((TEXTNS,u'caption-sequence-format'), None): cnv_string, + ((TEXTNS,u'caption-sequence-name'), None): cnv_string, + ((TEXTNS,u'change-id'), None): cnv_IDREF, + ((TEXTNS,u'chapter'), None): cnv_string, + ((TEXTNS,u'citation-body-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'citation-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'class-names'), None): cnv_NCNames, + ((TEXTNS,u'column-name'), None): cnv_string, + ((TEXTNS,u'combine-entries'), None): cnv_boolean, + ((TEXTNS,u'combine-entries-with-dash'), None): cnv_boolean, + ((TEXTNS,u'combine-entries-with-pp'), None): cnv_boolean, + ((TEXTNS,u'comma-separated'), None): cnv_boolean, + ((TEXTNS,u'cond-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'condition'), None): cnv_formula, + ((TEXTNS,u'connection-name'), None): cnv_string, + ((TEXTNS,u'consecutive-numbering'), None): cnv_boolean, + ((TEXTNS,u'continue-list'), None): cnv_IDREF, + ((TEXTNS,u'continue-numbering'), None): cnv_boolean, + ((TEXTNS,u'copy-outline-levels'), None): cnv_boolean, + ((TEXTNS,u'count-empty-lines'), None): cnv_boolean, + ((TEXTNS,u'count-in-text-boxes'), None): cnv_boolean, + ((TEXTNS,u'current-value'), None): cnv_boolean, + ((TEXTNS,u'custom1'), None): cnv_string, + ((TEXTNS,u'custom2'), None): cnv_string, + ((TEXTNS,u'custom3'), None): cnv_string, + ((TEXTNS,u'custom4'), None): cnv_string, + ((TEXTNS,u'custom5'), None): cnv_string, + ((TEXTNS,u'database-name'), None): cnv_string, + ((TEXTNS,u'date-adjust'), None): cnv_duration, + ((TEXTNS,u'date-value'), None): cnv_date, +# ((TEXTNS,u'date-value'), None): cnv_dateTime, + ((TEXTNS,u'default-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'description'), None): cnv_string, + ((TEXTNS,u'display'), None): cnv_string, + ((TEXTNS,u'display-levels'), None): cnv_positiveInteger, + ((TEXTNS,u'display-outline-level'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'dont-balance-text-columns'), None): cnv_boolean, + ((TEXTNS,u'duration'), None): cnv_duration, + ((TEXTNS,u'edition'), None): cnv_string, + ((TEXTNS,u'editor'), None): cnv_string, + ((TEXTNS,u'filter-name'), None): cnv_string, + ((TEXTNS,u'fixed'), None): cnv_boolean, + ((TEXTNS,u'footnotes-position'), None): cnv_string, + ((TEXTNS,u'formula'), None): cnv_formula, + ((TEXTNS,u'global'), None): cnv_boolean, + ((TEXTNS,u'howpublished'), None): cnv_string, + ((TEXTNS,u'id'), None): cnv_ID, +# ((TEXTNS,u'id'), None): cnv_string, + ((TEXTNS,u'identifier'), None): cnv_string, + ((TEXTNS,u'ignore-case'), None): cnv_boolean, + ((TEXTNS,u'increment'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'index-name'), None): cnv_string, + ((TEXTNS,u'index-scope'), None): cnv_string, + ((TEXTNS,u'institution'), None): cnv_string, + ((TEXTNS,u'is-hidden'), None): cnv_boolean, + ((TEXTNS,u'is-list-header'), None): cnv_boolean, + ((TEXTNS,u'isbn'), None): cnv_string, + ((TEXTNS,u'issn'), None): cnv_string, + ((TEXTNS,u'issn'), None): cnv_string, + ((TEXTNS,u'journal'), None): cnv_string, + ((TEXTNS,u'key'), None): cnv_string, + ((TEXTNS,u'key1'), None): cnv_string, + ((TEXTNS,u'key1-phonetic'), None): cnv_string, + ((TEXTNS,u'key2'), None): cnv_string, + ((TEXTNS,u'key2-phonetic'), None): cnv_string, + ((TEXTNS,u'kind'), None): cnv_string, + ((TEXTNS,u'label'), None): cnv_string, + ((TEXTNS,u'label-followed-by'), None): cnv_string, + ((TEXTNS,u'level'), None): cnv_positiveInteger, + ((TEXTNS,u'line-break'), None): cnv_boolean, + ((TEXTNS,u'line-number'), None): cnv_string, + ((TEXTNS,u'list-id'), None): cnv_NCName, + ((TEXTNS,u'list-level-position-and-space-mode'), None): cnv_string, + ((TEXTNS,u'list-tab-stop-position'), None): cnv_length, + ((TEXTNS,u'main-entry'), None): cnv_boolean, + ((TEXTNS,u'main-entry-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'master-page-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'min-label-distance'), None): cnv_string, + ((TEXTNS,u'min-label-width'), None): cnv_string, + ((TEXTNS,u'month'), None): cnv_string, + ((TEXTNS,u'name'), None): cnv_string, + ((TEXTNS,u'note-class'), None): cnv_textnoteclass, + ((TEXTNS,u'note'), None): cnv_string, + ((TEXTNS,u'number'), None): cnv_string, + ((TEXTNS,u'number-lines'), None): cnv_boolean, + ((TEXTNS,u'number-position'), None): cnv_string, + ((TEXTNS,u'numbered-entries'), None): cnv_boolean, + ((TEXTNS,u'offset'), None): cnv_string, + ((TEXTNS,u'organizations'), None): cnv_string, + ((TEXTNS,u'outline-level'), None): cnv_string, + ((TEXTNS,u'page-adjust'), None): cnv_integer, + ((TEXTNS,u'pages'), None): cnv_string, + ((TEXTNS,u'placeholder-type'), None): cnv_string, + ((TEXTNS,u'prefix'), None): cnv_string, + ((TEXTNS,u'protected'), None): cnv_boolean, + ((TEXTNS,u'protection-key'), None): cnv_string, + ((TEXTNS,u'protection-key-digest-algorithm'), None): cnv_anyURI, + ((TEXTNS,u'publisher'), None): cnv_string, + ((TEXTNS,u'ref-name'), None): cnv_string, + ((TEXTNS,u'reference-format'), None): cnv_string, + ((TEXTNS,u'relative-tab-stop-position'), None): cnv_boolean, + ((TEXTNS,u'report-type'), None): cnv_string, + ((TEXTNS,u'restart-numbering'), None): cnv_boolean, + ((TEXTNS,u'restart-on-page'), None): cnv_boolean, + ((TEXTNS,u'row-number'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'school'), None): cnv_string, + ((TEXTNS,u'section-name'), None): cnv_string, + ((TEXTNS,u'select-page'), None): cnv_string, + ((TEXTNS,u'separation-character'), None): cnv_string, + ((TEXTNS,u'series'), None): cnv_string, + ((TEXTNS,u'sort-algorithm'), None): cnv_string, + ((TEXTNS,u'sort-ascending'), None): cnv_boolean, + ((TEXTNS,u'sort-by-position'), None): cnv_boolean, + ((TEXTNS,u'space-before'), None): cnv_string, + ((TEXTNS,u'start-numbering-at'), None): cnv_string, + ((TEXTNS,u'start-value'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'start-value'), None): cnv_positiveInteger, + ((TEXTNS,u'string-value'), None): cnv_string, + ((TEXTNS,u'string-value-if-false'), None): cnv_string, + ((TEXTNS,u'string-value-if-true'), None): cnv_string, + ((TEXTNS,u'string-value-phonetic'), None): cnv_string, + ((TEXTNS,u'style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'style-override'), None): cnv_StyleNameRef, + ((TEXTNS,u'suffix'), None): cnv_string, + ((TEXTNS,u'tab-ref'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'table-name'), None): cnv_string, + ((TEXTNS,u'table-type'), None): cnv_string, + ((TEXTNS,u'time-adjust'), None): cnv_duration, + ((TEXTNS,u'time-value'), None): cnv_dateTime, + ((TEXTNS,u'time-value'), None): cnv_time, + ((TEXTNS,u'title'), None): cnv_string, + ((TEXTNS,u'track-changes'), None): cnv_boolean, + ((TEXTNS,u'url'), None): cnv_string, + ((TEXTNS,u'use-caption'), None): cnv_boolean, + ((TEXTNS,u'use-chart-objects'), None): cnv_boolean, + ((TEXTNS,u'use-draw-objects'), None): cnv_boolean, + ((TEXTNS,u'use-floating-frames'), None): cnv_boolean, + ((TEXTNS,u'use-graphics'), None): cnv_boolean, + ((TEXTNS,u'use-index-marks'), None): cnv_boolean, + ((TEXTNS,u'use-index-source-styles'), None): cnv_boolean, + ((TEXTNS,u'use-keys-as-entries'), None): cnv_boolean, + ((TEXTNS,u'use-math-objects'), None): cnv_boolean, + ((TEXTNS,u'use-objects'), None): cnv_boolean, + ((TEXTNS,u'use-other-objects'), None): cnv_boolean, + ((TEXTNS,u'use-outline-level'), None): cnv_boolean, + ((TEXTNS,u'use-soft-page-breaks'), None): cnv_boolean, + ((TEXTNS,u'use-spreadsheet-objects'), None): cnv_boolean, + ((TEXTNS,u'use-tables'), None): cnv_boolean, + ((TEXTNS,u'value'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'visited-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'volume'), None): cnv_string, + ((TEXTNS,u'year'), None): cnv_string, + ((XFORMSNS,u'bind'), None): cnv_string, + ((XHTMLNS,u'about'), None): cnv_anyURI, + ((XHTMLNS,u'content'), None): cnv_string, + ((XHTMLNS,u'datatype'), None): cnv_anyURI, + ((XHTMLNS,u'property'), None): cnv_anyURI, + ((XLINKNS,u'actuate'), None): cnv_string, + ((XLINKNS,u'href'), None): cnv_anyURI, + ((XLINKNS,u'show'), None): cnv_xlinkshow, + ((XLINKNS,u'title'), None): cnv_string, + ((XLINKNS,u'type'), None): cnv_xlinktype, + ((XMLNS,u'id'), None): cnv_NCName, +} + +class AttrConverters: + def convert(self, attribute, value, element): + """ Based on the element, figures out how to check/convert the attribute value + All values are converted to string + """ + conversion = attrconverters.get((attribute, element.qname), None) + if conversion is not None: + return conversion(attribute, value, element) + else: + conversion = attrconverters.get((attribute, None), None) + if conversion is not None: + return conversion(attribute, value, element) + if sys.version_info[0]==2: + return unicode(value) + else: + return str(value) + diff --git a/odf/chart.py b/odf/chart.py new file mode 100644 index 0000000..b05dcce --- /dev/null +++ b/odf/chart.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2013 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +from __future__ import absolute_import +from .namespaces import CHARTNS +from .element import Element + +# Autogenerated +def Axis(**args): + return Element(qname = (CHARTNS,'axis'), **args) + +def Categories(**args): + return Element(qname = (CHARTNS,'categories'), **args) + +def Chart(**args): + return Element(qname = (CHARTNS,'chart'), **args) + +def DataLabel(**args): + return Element(qname = (CHARTNS,'data-label'), **args) + +def DataPoint(**args): + return Element(qname = (CHARTNS,'data-point'), **args) + +def Domain(**args): + return Element(qname = (CHARTNS,'domain'), **args) + +def Equation(**args): + return Element(qname = (CHARTNS,'equation'), **args) + +def ErrorIndicator(**args): + return Element(qname = (CHARTNS,'error-indicator'), **args) + +def Floor(**args): + return Element(qname = (CHARTNS,'floor'), **args) + +def Footer(**args): + return Element(qname = (CHARTNS,'footer'), **args) + +def Grid(**args): + return Element(qname = (CHARTNS,'grid'), **args) + +def LabelSeparator(**args): + return Element(qname = (CHARTNS,'label-separator'), **args) + +def Legend(**args): + return Element(qname = (CHARTNS,'legend'), **args) + +def MeanValue(**args): + return Element(qname = (CHARTNS,'mean-value'), **args) + +def PlotArea(**args): + return Element(qname = (CHARTNS,'plot-area'), **args) + +def RegressionCurve(**args): + return Element(qname = (CHARTNS,'regression-curve'), **args) + +def Series(**args): + return Element(qname = (CHARTNS,'series'), **args) + +def StockGainMarker(**args): + return Element(qname = (CHARTNS,'stock-gain-marker'), **args) + +def StockLossMarker(**args): + return Element(qname = (CHARTNS,'stock-loss-marker'), **args) + +def StockRangeLine(**args): + return Element(qname = (CHARTNS,'stock-range-line'), **args) + +def Subtitle(**args): + return Element(qname = (CHARTNS,'subtitle'), **args) + +def SymbolImage(**args): + return Element(qname = (CHARTNS,'symbol-image'), **args) + +def Title(**args): + return Element(qname = (CHARTNS,'title'), **args) + +def Wall(**args): + return Element(qname = (CHARTNS,'wall'), **args) + diff --git a/odf/config.py b/odf/config.py new file mode 100644 index 0000000..f33f361 --- /dev/null +++ b/odf/config.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import CONFIGNS +from element import Element + +# Autogenerated +def ConfigItem(**args): + return Element(qname = (CONFIGNS, 'config-item'), **args) + +def ConfigItemMapEntry(**args): + return Element(qname = (CONFIGNS,'config-item-map-entry'), **args) + +def ConfigItemMapIndexed(**args): + return Element(qname = (CONFIGNS,'config-item-map-indexed'), **args) + +def ConfigItemMapNamed(**args): + return Element(qname = (CONFIGNS,'config-item-map-named'), **args) + +def ConfigItemSet(**args): + return Element(qname = (CONFIGNS, 'config-item-set'), **args) + diff --git a/odf/dc.py b/odf/dc.py new file mode 100644 index 0000000..7c96776 --- /dev/null +++ b/odf/dc.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import DCNS +from element import Element + +# Autogenerated +def Creator(**args): + return Element(qname = (DCNS,'creator'), **args) + +def Date(**args): + return Element(qname = (DCNS,'date'), **args) + +def Description(**args): + return Element(qname = (DCNS,'description'), **args) + +def Language(**args): + return Element(qname = (DCNS,'language'), **args) + +def Subject(**args): + return Element(qname = (DCNS,'subject'), **args) + +def Title(**args): + return Element(qname = (DCNS,'title'), **args) + +# The following complete the Dublin Core elements, but there is no +# guarantee a compliant implementation of OpenDocument will preserve +# these elements + +#def Contributor(**args): +# return Element(qname = (DCNS,'contributor'), **args) + +#def Coverage(**args): +# return Element(qname = (DCNS,'coverage'), **args) + +#def Format(**args): +# return Element(qname = (DCNS,'format'), **args) + +#def Identifier(**args): +# return Element(qname = (DCNS,'identifier'), **args) + +#def Publisher(**args): +# return Element(qname = (DCNS,'publisher'), **args) + +#def Relation(**args): +# return Element(qname = (DCNS,'relation'), **args) + +#def Rights(**args): +# return Element(qname = (DCNS,'rights'), **args) + +#def Source(**args): +# return Element(qname = (DCNS,'source'), **args) + +#def Type(**args): +# return Element(qname = (DCNS,'type'), **args) diff --git a/odf/dr3d.py b/odf/dr3d.py new file mode 100644 index 0000000..989e114 --- /dev/null +++ b/odf/dr3d.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +import sys, os.path +sys.path.append(os.path.dirname(__file__)) + +from namespaces import DR3DNS +from element import Element +from draw import StyleRefElement + +# Autogenerated +def Cube(**args): + return StyleRefElement(qname = (DR3DNS,'cube'), **args) + +def Extrude(**args): + return StyleRefElement(qname = (DR3DNS,'extrude'), **args) + +def Light(Element): + return StyleRefElement(qname = (DR3DNS,'light'), **args) + +def Rotate(**args): + return StyleRefElement(qname = (DR3DNS,'rotate'), **args) + +def Scene(**args): + return StyleRefElement(qname = (DR3DNS,'scene'), **args) + +def Sphere(**args): + return StyleRefElement(qname = (DR3DNS,'sphere'), **args) + diff --git a/odf/draw.py b/odf/draw.py new file mode 100644 index 0000000..122d40f --- /dev/null +++ b/odf/draw.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +import sys, os.path +sys.path.append(os.path.dirname(__file__)) +from namespaces import DRAWNS, STYLENS, PRESENTATIONNS +from element import Element + +def StyleRefElement(stylename=None, classnames=None, **args): + qattrs = {} + if stylename is not None: + f = stylename.getAttrNS(STYLENS, 'family') + if f == 'graphic': + qattrs[(DRAWNS,u'style-name')]= stylename + elif f == 'presentation': + qattrs[(PRESENTATIONNS,u'style-name')]= stylename + else: + raise ValueError( "Style's family must be either 'graphic' or 'presentation'") + if classnames is not None: + f = classnames[0].getAttrNS(STYLENS, 'family') + if f == 'graphic': + qattrs[(DRAWNS,u'class-names')]= classnames + elif f == 'presentation': + qattrs[(PRESENTATIONNS,u'class-names')]= classnames + else: + raise ValueError( "Style's family must be either 'graphic' or 'presentation'") + return Element(qattributes=qattrs, **args) + +def DrawElement(name=None, **args): + e = Element(name=name, **args) + if 'displayname' not in args: + e.setAttrNS(DRAWNS,'display-name', name) + return e + +# Autogenerated +def A(**args): + args.setdefault('type', 'simple') + return Element(qname = (DRAWNS,'a'), **args) + +def Applet(**args): + return Element(qname = (DRAWNS,'applet'), **args) + +def AreaCircle(**args): + return Element(qname = (DRAWNS,'area-circle'), **args) + +def AreaPolygon(**args): + return Element(qname = (DRAWNS,'area-polygon'), **args) + +def AreaRectangle(**args): + return Element(qname = (DRAWNS,'area-rectangle'), **args) + +def Caption(**args): + return StyleRefElement(qname = (DRAWNS,'caption'), **args) + +def Circle(**args): + return StyleRefElement(qname = (DRAWNS,'circle'), **args) + +def Connector(**args): + return StyleRefElement(qname = (DRAWNS,'connector'), **args) + +def ContourPath(**args): + return Element(qname = (DRAWNS,'contour-path'), **args) + +def ContourPolygon(**args): + return Element(qname = (DRAWNS,'contour-polygon'), **args) + +def Control(**args): + return StyleRefElement(qname = (DRAWNS,'control'), **args) + +def CustomShape(**args): + return StyleRefElement(qname = (DRAWNS,'custom-shape'), **args) + +def Ellipse(**args): + return StyleRefElement(qname = (DRAWNS,'ellipse'), **args) + +def EnhancedGeometry(**args): + return Element(qname = (DRAWNS,'enhanced-geometry'), **args) + +def Equation(**args): + return Element(qname = (DRAWNS,'equation'), **args) + +def FillImage(**args): + args.setdefault('type', 'simple') + return DrawElement(qname = (DRAWNS,'fill-image'), **args) + +def FloatingFrame(**args): + args.setdefault('type', 'simple') + return Element(qname = (DRAWNS,'floating-frame'), **args) + +def Frame(**args): + return StyleRefElement(qname = (DRAWNS,'frame'), **args) + +def G(**args): + return StyleRefElement(qname = (DRAWNS,'g'), **args) + +def GluePoint(**args): + return Element(qname = (DRAWNS,'glue-point'), **args) + +def Gradient(**args): + return DrawElement(qname = (DRAWNS,'gradient'), **args) + +def Handle(**args): + return Element(qname = (DRAWNS,'handle'), **args) + +def Hatch(**args): + return DrawElement(qname = (DRAWNS,'hatch'), **args) + +def Image(**args): + return Element(qname = (DRAWNS,'image'), **args) + +def ImageMap(**args): + return Element(qname = (DRAWNS,'image-map'), **args) + +def Layer(**args): + return Element(qname = (DRAWNS,'layer'), **args) + +def LayerSet(**args): + return Element(qname = (DRAWNS,'layer-set'), **args) + +def Line(**args): + return StyleRefElement(qname = (DRAWNS,'line'), **args) + +def Marker(**args): + return DrawElement(qname = (DRAWNS,'marker'), **args) + +def Measure(**args): + return StyleRefElement(qname = (DRAWNS,'measure'), **args) + +def Object(**args): + return Element(qname = (DRAWNS,'object'), **args) + +def ObjectOle(**args): + return Element(qname = (DRAWNS,'object-ole'), **args) + +def Opacity(**args): + return DrawElement(qname = (DRAWNS,'opacity'), **args) + +def Page(**args): + return Element(qname = (DRAWNS,'page'), **args) + +def PageThumbnail(**args): + return StyleRefElement(qname = (DRAWNS,'page-thumbnail'), **args) + +def Param(**args): + return Element(qname = (DRAWNS,'param'), **args) + +def Path(**args): + return StyleRefElement(qname = (DRAWNS,'path'), **args) + +def Plugin(**args): + args.setdefault('type', 'simple') + return Element(qname = (DRAWNS,'plugin'), **args) + +def Polygon(**args): + return StyleRefElement(qname = (DRAWNS,'polygon'), **args) + +def Polyline(**args): + return StyleRefElement(qname = (DRAWNS,'polyline'), **args) + +def Rect(**args): + return StyleRefElement(qname = (DRAWNS,'rect'), **args) + +def RegularPolygon(**args): + return StyleRefElement(qname = (DRAWNS,'regular-polygon'), **args) + +def StrokeDash(**args): + return DrawElement(qname = (DRAWNS,'stroke-dash'), **args) + +def TextBox(**args): + return Element(qname = (DRAWNS,'text-box'), **args) + diff --git a/odf/easyliststyle.py b/odf/easyliststyle.py new file mode 100644 index 0000000..0576406 --- /dev/null +++ b/odf/easyliststyle.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- +# Create a element from a text string. +# Copyright (C) 2008 J. David Eisenberg +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Contributor(s): +# + +import re, sys, os.path +sys.path.append(os.path.dirname(__file__)) +from style import Style, TextProperties, ListLevelProperties +from text import ListStyle,ListLevelStyleNumber,ListLevelStyleBullet + +""" +Create a element from a string or array. + +List styles require a lot of code to create one level at a time. +These routines take a string and delimiter, or a list of +strings, and creates a element for you. +Each item in the string (or array) represents a list level + * style for levels 1-10.

+ * + *

If an item contains 1, I, + * i, A, or a, then it is presumed + * to be a numbering style; otherwise it is a bulleted style.

+""" + +_MAX_LIST_LEVEL = 10 +SHOW_ALL_LEVELS = True +SHOW_ONE_LEVEL = False + +def styleFromString(name, specifiers, delim, spacing, showAllLevels): + specArray = specifiers.split(delim) + return styleFromList( name, specArray, spacing, showAllLevels ) + +def styleFromList( styleName, specArray, spacing, showAllLevels): + bullet = "" + numPrefix = "" + numSuffix = "" + numberFormat = "" + cssLengthNum = 0 + cssLengthUnits = "" + numbered = False + displayLevels = 0 + listStyle = ListStyle(name=styleName) + numFormatPattern = re.compile("([1IiAa])") + cssLengthPattern = re.compile("([^a-z]+)\\s*([a-z]+)?") + m = cssLengthPattern.search( spacing ) + if (m != None): + cssLengthNum = float(m.group(1)) + if (m.lastindex == 2): + cssLengthUnits = m.group(2) + i = 0 + while i < len(specArray): + specification = specArray[i] + m = numFormatPattern.search(specification) + if (m != None): + numberFormat = m.group(1) + numPrefix = specification[0:m.start(1)] + numSuffix = specification[m.end(1):] + bullet = "" + numbered = True + if (showAllLevels): + displayLevels = i + 1 + else: + displayLevels = 1 + else: # it's a bullet style + bullet = specification + numPrefix = "" + numSuffix = "" + numberFormat = "" + displayLevels = 1 + numbered = False + if (numbered): + lls = ListLevelStyleNumber(level=(i+1)) + if (numPrefix != ''): + lls.setAttribute('numprefix', numPrefix) + if (numSuffix != ''): + lls.setAttribute('numsuffix', numSuffix) + lls.setAttribute('displaylevels', displayLevels) + else: + lls = ListLevelStyleBullet(level=(i+1),bulletchar=bullet[0]) + llp = ListLevelProperties() + llp.setAttribute('spacebefore', str(cssLengthNum * (i+1)) + cssLengthUnits) + llp.setAttribute('minlabelwidth', str(cssLengthNum) + cssLengthUnits) + lls.addElement( llp ) + listStyle.addElement(lls) + i += 1 + return listStyle + +# vim: set expandtab sw=4 : diff --git a/odf/element.py b/odf/element.py new file mode 100644 index 0000000..09e7de5 --- /dev/null +++ b/odf/element.py @@ -0,0 +1,541 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2007-2010 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +# Note: This script has copied a lot of text from xml.dom.minidom. +# Whatever license applies to that file also applies to this file. +# +import sys, os.path +sys.path.append(os.path.dirname(__file__)) +import xml.dom +from xml.dom.minicompat import * +from namespaces import nsdict +import grammar +from attrconverters import AttrConverters + +if sys.version_info[0] == 3: + unicode=str # unicode function does not exist + +# The following code is pasted form xml.sax.saxutils +# Tt makes it possible to run the code without the xml sax package installed +# To make it possible to have in your text elements, it is necessary to escape the texts +def _escape(data, entities={}): + """ Escape &, <, and > in a string of data. + + You can escape other strings of data by passing a dictionary as + the optional entities parameter. The keys and values must all be + strings; each key will be replaced with its corresponding value. + """ + data = data.replace("&", "&") + data = data.replace("<", "<") + data = data.replace(">", ">") + for chars, entity in entities.items(): + data = data.replace(chars, entity) + return data + +def _quoteattr(data, entities={}): + """ Escape and quote an attribute value. + + Escape &, <, and > in a string of data, then quote it for use as + an attribute value. The \" character will be escaped as well, if + necessary. + + You can escape other strings of data by passing a dictionary as + the optional entities parameter. The keys and values must all be + strings; each key will be replaced with its corresponding value. + """ + entities['\n']=' ' + entities['\r']=' ' + data = _escape(data, entities) + if '"' in data: + if "'" in data: + data = '"%s"' % data.replace('"', """) + else: + data = "'%s'" % data + else: + data = '"%s"' % data + return data + +def _nssplit(qualifiedName): + """ Split a qualified name into namespace part and local part. """ + fields = qualifiedName.split(':', 1) + if len(fields) == 2: + return fields + else: + return (None, fields[0]) + +def _nsassign(namespace): + return nsdict.setdefault(namespace,"ns" + str(len(nsdict))) + + +# Exceptions +class IllegalChild(Exception): + """ Complains if you add an element to a parent where it is not allowed """ +class IllegalText(Exception): + """ Complains if you add text or cdata to an element where it is not allowed """ + +class Node(xml.dom.Node): + """ super class for more specific nodes """ + parentNode = None + nextSibling = None + previousSibling = None + + def hasChildNodes(self): + """ Tells whether this element has any children; text nodes, + subelements, whatever. + """ + if self.childNodes: + return True + else: + return False + + def _get_childNodes(self): + return self.childNodes + + def _get_firstChild(self): + if self.childNodes: + return self.childNodes[0] + + def _get_lastChild(self): + if self.childNodes: + return self.childNodes[-1] + + def insertBefore(self, newChild, refChild): + """ Inserts the node newChild before the existing child node refChild. + If refChild is null, insert newChild at the end of the list of children. + """ + if newChild.nodeType not in self._child_node_types: + raise IllegalChild( "%s cannot be child of %s" % (newChild.tagName, self.tagName)) + if newChild.parentNode is not None: + newChild.parentNode.removeChild(newChild) + if refChild is None: + self.appendChild(newChild) + else: + try: + index = self.childNodes.index(refChild) + except ValueError: + raise xml.dom.NotFoundErr() + self.childNodes.insert(index, newChild) + newChild.nextSibling = refChild + refChild.previousSibling = newChild + if index: + node = self.childNodes[index-1] + node.nextSibling = newChild + newChild.previousSibling = node + else: + newChild.previousSibling = None + newChild.parentNode = self + return newChild + + def appendChild(self, newChild): + """ Adds the node newChild to the end of the list of children of this node. + If the newChild is already in the tree, it is first removed. + """ + if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE: + for c in tuple(newChild.childNodes): + self.appendChild(c) + ### The DOM does not clearly specify what to return in this case + return newChild + if newChild.nodeType not in self._child_node_types: + raise IllegalChild( "<%s> is not allowed in %s" % ( newChild.tagName, self.tagName)) + if newChild.parentNode is not None: + newChild.parentNode.removeChild(newChild) + _append_child(self, newChild) + newChild.nextSibling = None + return newChild + + def removeChild(self, oldChild): + """ Removes the child node indicated by oldChild from the list of children, and returns it. + """ + #FIXME: update ownerDocument.element_dict or find other solution + try: + self.childNodes.remove(oldChild) + except ValueError: + raise xml.dom.NotFoundErr() + if oldChild.nextSibling is not None: + oldChild.nextSibling.previousSibling = oldChild.previousSibling + if oldChild.previousSibling is not None: + oldChild.previousSibling.nextSibling = oldChild.nextSibling + oldChild.nextSibling = oldChild.previousSibling = None + if self.ownerDocument: + self.ownerDocument.clear_caches() + oldChild.parentNode = None + return oldChild + + def __str__(self): + val = [] + for c in self.childNodes: + val.append(str(c)) + return ''.join(val) + + def __unicode__(self): + val = [] + for c in self.childNodes: + val.append(unicode(c)) + return u''.join(val) + +defproperty(Node, "firstChild", doc="First child node, or None.") +defproperty(Node, "lastChild", doc="Last child node, or None.") + +def _append_child(self, node): + # fast path with less checks; usable by DOM builders if careful + childNodes = self.childNodes + if childNodes: + last = childNodes[-1] + node.__dict__["previousSibling"] = last + last.__dict__["nextSibling"] = node + childNodes.append(node) + node.__dict__["parentNode"] = self + +class Childless: + """ Mixin that makes childless-ness easy to implement and avoids + the complexity of the Node methods that deal with children. + """ + + attributes = None + childNodes = EmptyNodeList() + firstChild = None + lastChild = None + + def _get_firstChild(self): + return None + + def _get_lastChild(self): + return None + + def appendChild(self, node): + """ Raises an error """ + raise xml.dom.HierarchyRequestErr( + self.tagName + " nodes cannot have children") + + def hasChildNodes(self): + return False + + def insertBefore(self, newChild, refChild): + """ Raises an error """ + raise xml.dom.HierarchyRequestErr( + self.tagName + " nodes do not have children") + + def removeChild(self, oldChild): + """ Raises an error """ + raise xml.dom.NotFoundErr( + self.tagName + " nodes do not have children") + + def replaceChild(self, newChild, oldChild): + """ Raises an error """ + raise xml.dom.HierarchyRequestErr( + self.tagName + " nodes do not have children") + +class Text(Childless, Node): + nodeType = Node.TEXT_NODE + tagName = "Text" + + def __init__(self, data): + self.data = data + + def __str__(self): + return self.data + + def __unicode__(self): + return self.data + + def toXml(self,level,f): + """ Write XML in UTF-8 """ + if self.data: + f.write(_escape(unicode(self.data))) + +class CDATASection(Text, Childless): + nodeType = Node.CDATA_SECTION_NODE + + def toXml(self,level,f): + """ Generate XML output of the node. If the text contains "]]>", then + escape it by going out of CDATA mode (]]>), then write the string + and then go into CDATA mode again. (' % self.data.replace(']]>',']]>]]>" % (r[1].lower().replace('-',''), self.tagName)) + + def get_knownns(self, prefix): + """ Odfpy maintains a list of known namespaces. In some cases a prefix is used, and + we need to know which namespace it resolves to. + """ + global nsdict + for ns,p in nsdict.items(): + if p == prefix: return ns + return None + + def get_nsprefix(self, namespace): + """ Odfpy maintains a list of known namespaces. In some cases we have a namespace URL, + and needs to look up or assign the prefix for it. + """ + if namespace is None: namespace = "" + prefix = _nsassign(namespace) + if not namespace in self.namespaces: + self.namespaces[namespace] = prefix + return prefix + + def allowed_attributes(self): + return grammar.allowed_attributes.get(self.qname) + + def _setOwnerDoc(self, element): + element.ownerDocument = self.ownerDocument + for child in element.childNodes: + self._setOwnerDoc(child) + + def addElement(self, element, check_grammar=True): + """ adds an element to an Element + + Element.addElement(Element) + """ + if check_grammar and self.allowed_children is not None: + if element.qname not in self.allowed_children: + raise IllegalChild( "<%s> is not allowed in <%s>" % ( element.tagName, self.tagName)) + self.appendChild(element) + self._setOwnerDoc(element) + if self.ownerDocument: + self.ownerDocument.rebuild_caches(element) + + def addText(self, text, check_grammar=True): + """ Adds text to an element + Setting check_grammar=False turns off grammar checking + """ + if check_grammar and self.qname not in grammar.allows_text: + raise IllegalText( "The <%s> element does not allow text" % self.tagName) + else: + if text != '': + self.appendChild(Text(text)) + + def addCDATA(self, cdata, check_grammar=True): + """ Adds CDATA to an element + Setting check_grammar=False turns off grammar checking + """ + if check_grammar and self.qname not in grammar.allows_text: + raise IllegalText( "The <%s> element does not allow text" % self.tagName) + else: + self.appendChild(CDATASection(cdata)) + + def removeAttribute(self, attr, check_grammar=True): + """ Removes an attribute by name. """ + allowed_attrs = self.allowed_attributes() + if allowed_attrs is None: + if type(attr) == type(()): + prefix, localname = attr + self.removeAttrNS(prefix, localname) + else: + raise AttributeError( "Unable to add simple attribute - use (namespace, localpart)") + else: + # Construct a list of allowed arguments + allowed_args = [ a[1].lower().replace('-','') for a in allowed_attrs] + if check_grammar and attr not in allowed_args: + raise AttributeError( "Attribute %s is not allowed in <%s>" % ( attr, self.tagName)) + i = allowed_args.index(attr) + self.removeAttrNS(allowed_attrs[i][0], allowed_attrs[i][1]) + + def setAttribute(self, attr, value, check_grammar=True): + """ Add an attribute to the element + This is sort of a convenience method. All attributes in ODF have + namespaces. The library knows what attributes are legal and then allows + the user to provide the attribute as a keyword argument and the + library will add the correct namespace. + Must overwrite, If attribute already exists. + """ + allowed_attrs = self.allowed_attributes() + if allowed_attrs is None: + if type(attr) == type(()): + prefix, localname = attr + self.setAttrNS(prefix, localname, value) + else: + raise AttributeError( "Unable to add simple attribute - use (namespace, localpart)") + else: + # Construct a list of allowed arguments + allowed_args = [ a[1].lower().replace('-','') for a in allowed_attrs] + if check_grammar and attr not in allowed_args: + raise AttributeError( "Attribute %s is not allowed in <%s>" % ( attr, self.tagName)) + i = allowed_args.index(attr) + self.setAttrNS(allowed_attrs[i][0], allowed_attrs[i][1], value) + + def setAttrNS(self, namespace, localpart, value): + """ Add an attribute to the element + In case you need to add an attribute the library doesn't know about + then you must provide the full qualified name + It will not check that the attribute is legal according to the schema. + Must overwrite, If attribute already exists. + """ + allowed_attrs = self.allowed_attributes() + prefix = self.get_nsprefix(namespace) +# if allowed_attrs and (namespace, localpart) not in allowed_attrs: +# raise AttributeError( "Attribute %s:%s is not allowed in element <%s>" % ( prefix, localpart, self.tagName)) + c = AttrConverters() + self.attributes[(namespace, localpart)] = c.convert((namespace, localpart), value, self) + + def getAttrNS(self, namespace, localpart): + """ + gets an attribute, given a namespace and a key + @param namespace a unicode string or a bytes: the namespace + @param localpart a unicode string or a bytes: + the key to get the attribute + @return an attribute as a unicode string or a bytes: if both paramters + are byte strings, it will be a bytes; if both attributes are + unicode strings, it will be a unicode string + """ + prefix = self.get_nsprefix(namespace) + result = self.attributes.get((namespace, localpart)) + + assert( + (type(namespace), type(namespace), type(namespace) == \ + type(b""), type(b""), type(b"")) or + (type(namespace), type(namespace), type(namespace) == \ + type(u""), type(u""), type(u"")) + ) + + return result + + def removeAttrNS(self, namespace, localpart): + del self.attributes[(namespace, localpart)] + + def getAttribute(self, attr): + """ Get an attribute value. The method knows which namespace the attribute is in + """ + allowed_attrs = self.allowed_attributes() + if allowed_attrs is None: + if type(attr) == type(()): + prefix, localname = attr + return self.getAttrNS(prefix, localname) + else: + raise AttributeError( "Unable to get simple attribute - use (namespace, localpart)") + else: + # Construct a list of allowed arguments + allowed_args = [ a[1].lower().replace('-','') for a in allowed_attrs] + i = allowed_args.index(attr) + return self.getAttrNS(allowed_attrs[i][0], allowed_attrs[i][1]) + + def write_open_tag(self, level, f): + f.write(('<'+self.tagName)) + if level == 0: + for namespace, prefix in self.namespaces.items(): + f.write(u' xmlns:' + prefix + u'="'+ _escape(str(namespace))+'"') + for qname in self.attributes.keys(): + prefix = self.get_nsprefix(qname[0]) + f.write(u' '+_escape(str(prefix+u':'+qname[1]))+u'='+_quoteattr(unicode(self.attributes[qname]))) + f.write(u'>') + + def write_close_tag(self, level, f): + f.write('') + + def toXml(self, level, f): + """ + Generate an XML stream out of the tree structure + @param level integer: level in the XML tree; zero at root of the tree + @param f an open writable file able to accept unicode strings + """ + f.write(u'<'+self.tagName) + if level == 0: + for namespace, prefix in self.namespaces.items(): + f.write(u' xmlns:' + prefix + u'="'+ _escape(str(namespace))+u'"') + for qname in self.attributes.keys(): + prefix = self.get_nsprefix(qname[0]) + f.write(u' '+_escape(unicode(prefix+':'+qname[1]))+u'='+_quoteattr(unicode(self.attributes[qname]))) + if self.childNodes: + f.write(u'>') + for element in self.childNodes: + element.toXml(level+1,f) + f.write(u'') + else: + f.write(u'/>') + + def _getElementsByObj(self, obj, accumulator): + if self.qname == obj.qname: + accumulator.append(self) + for e in self.childNodes: + if e.nodeType == Node.ELEMENT_NODE: + accumulator = e._getElementsByObj(obj, accumulator) + return accumulator + + def getElementsByType(self, element): + """ Gets elements based on the type, which is function from text.py, draw.py etc. """ + obj = element(check_grammar=False) + return self._getElementsByObj(obj,[]) + + def isInstanceOf(self, element): + """ This is a check to see if the object is an instance of a type """ + obj = element(check_grammar=False) + return self.qname == obj.qname + + diff --git a/odf/elementtypes.py b/odf/elementtypes.py new file mode 100644 index 0000000..7c19412 --- /dev/null +++ b/odf/elementtypes.py @@ -0,0 +1,325 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2008 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import * + +# Inline element don't cause a box +# They are analogous to the HTML elements SPAN, B, I etc. +inline_elements = ( + (TEXTNS,u'a'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'print-time'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u'ruby-base'), + (TEXTNS,u'ruby-text'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), +) + + +# It is almost impossible to determine what elements are block elements. +# There are so many that don't fit the form +block_elements = ( + (TEXTNS,u'h'), + (TEXTNS,u'p'), + (TEXTNS,u'list'), + (TEXTNS,u'list-item'), + (TEXTNS,u'section'), +) + +declarative_elements = ( + (OFFICENS,u'font-face-decls'), + (PRESENTATIONNS,u'date-time-decl'), + (PRESENTATIONNS,u'footer-decl'), + (PRESENTATIONNS,u'header-decl'), + (TABLENS,u'table-template'), + (TEXTNS,u'alphabetical-index-entry-template'), + (TEXTNS,u'alphabetical-index-source'), + (TEXTNS,u'bibliography-entry-template'), + (TEXTNS,u'bibliography-source'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'illustration-index-entry-template'), + (TEXTNS,u'illustration-index-source'), + (TEXTNS,u'index-source-styles'), + (TEXTNS,u'index-title-template'), + (TEXTNS,u'note-continuation-notice-backward'), + (TEXTNS,u'note-continuation-notice-forward'), + (TEXTNS,u'notes-configuration'), + (TEXTNS,u'object-index-entry-template'), + (TEXTNS,u'object-index-source'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index-entry-template'), + (TEXTNS,u'table-index-source'), + (TEXTNS,u'table-of-content-entry-template'), + (TEXTNS,u'table-of-content-source'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index-entry-template'), + (TEXTNS,u'user-index-source'), + (TEXTNS,u'variable-decls'), +) + +empty_elements = ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'param'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + (CHARTNS,u'categories'), + (CHARTNS,u'data-point'), + (CHARTNS,u'domain'), + (CHARTNS,u'error-indicator'), + (CHARTNS,u'floor'), + (CHARTNS,u'grid'), + (CHARTNS,u'legend'), + (CHARTNS,u'mean-value'), + (CHARTNS,u'regression-curve'), + (CHARTNS,u'stock-gain-marker'), + (CHARTNS,u'stock-loss-marker'), + (CHARTNS,u'stock-range-line'), + (CHARTNS,u'symbol-image'), + (CHARTNS,u'wall'), + (DR3DNS,u'cube'), + (DR3DNS,u'extrude'), + (DR3DNS,u'light'), + (DR3DNS,u'rotate'), + (DR3DNS,u'sphere'), + (DRAWNS,u'contour-path'), + (DRAWNS,u'contour-polygon'), + (DRAWNS,u'equation'), + (DRAWNS,u'fill-image'), + (DRAWNS,u'floating-frame'), + (DRAWNS,u'glue-point'), + (DRAWNS,u'gradient'), + (DRAWNS,u'handle'), + (DRAWNS,u'hatch'), + (DRAWNS,u'layer'), + (DRAWNS,u'marker'), + (DRAWNS,u'opacity'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'param'), + (DRAWNS,u'stroke-dash'), + (FORMNS,u'connection-resource'), + (FORMNS,u'list-value'), + (FORMNS,u'property'), + (MANIFESTNS,u'algorithm'), + (MANIFESTNS,u'key-derivation'), + (METANS,u'auto-reload'), + (METANS,u'document-statistic'), + (METANS,u'hyperlink-behaviour'), + (METANS,u'template'), + (NUMBERNS,u'am-pm'), + (NUMBERNS,u'boolean'), + (NUMBERNS,u'day'), + (NUMBERNS,u'day-of-week'), + (NUMBERNS,u'era'), + (NUMBERNS,u'fraction'), + (NUMBERNS,u'hours'), + (NUMBERNS,u'minutes'), + (NUMBERNS,u'month'), + (NUMBERNS,u'quarter'), + (NUMBERNS,u'scientific-number'), + (NUMBERNS,u'seconds'), + (NUMBERNS,u'text-content'), + (NUMBERNS,u'week-of-year'), + (NUMBERNS,u'year'), + (OFFICENS,u'dde-source'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (PRESENTATIONNS,u'placeholder'), + (PRESENTATIONNS,u'play'), + (PRESENTATIONNS,u'show'), + (PRESENTATIONNS,u'sound'), + (SCRIPTNS,u'event-listener'), + (STYLENS,u'column'), + (STYLENS,u'column-sep'), + (STYLENS,u'drop-cap'), + (STYLENS,u'footnote-sep'), + (STYLENS,u'list-level-properties'), + (STYLENS,u'map'), + (STYLENS,u'ruby-properties'), + (STYLENS,u'table-column-properties'), + (STYLENS,u'tab-stop'), + (STYLENS,u'text-properties'), + (SVGNS,u'definition-src'), + (SVGNS,u'font-face-format'), + (SVGNS,u'font-face-name'), + (SVGNS,u'stop'), + (TABLENS,u'body'), + (TABLENS,u'cell-address'), + (TABLENS,u'cell-range-source'), + (TABLENS,u'change-deletion'), + (TABLENS,u'consolidation'), + (TABLENS,u'database-source-query'), + (TABLENS,u'database-source-sql'), + (TABLENS,u'database-source-table'), + (TABLENS,u'data-pilot-display-info'), + (TABLENS,u'data-pilot-field-reference'), + (TABLENS,u'data-pilot-group-member'), + (TABLENS,u'data-pilot-layout-info'), + (TABLENS,u'data-pilot-member'), + (TABLENS,u'data-pilot-sort-info'), + (TABLENS,u'data-pilot-subtotal'), + (TABLENS,u'dependency'), + (TABLENS,u'error-macro'), + (TABLENS,u'even-columns'), + (TABLENS,u'even-rows'), + (TABLENS,u'filter-condition'), + (TABLENS,u'first-column'), + (TABLENS,u'first-row'), + (TABLENS,u'highlighted-range'), + (TABLENS,u'insertion-cut-off'), + (TABLENS,u'iteration'), + (TABLENS,u'label-range'), + (TABLENS,u'last-column'), + (TABLENS,u'last-row'), + (TABLENS,u'movement-cut-off'), + (TABLENS,u'named-expression'), + (TABLENS,u'named-range'), + (TABLENS,u'null-date'), + (TABLENS,u'odd-columns'), + (TABLENS,u'odd-rows'), + (TABLENS,u'operation'), + (TABLENS,u'scenario'), + (TABLENS,u'sort-by'), + (TABLENS,u'sort-groups'), + (TABLENS,u'source-range-address'), + (TABLENS,u'source-service'), + (TABLENS,u'subtotal-field'), + (TABLENS,u'table-column'), + (TABLENS,u'table-source'), + (TABLENS,u'target-range-address'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decl'), + (TEXTNS,u'index-entry-bibliography'), + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-link-end'), + (TEXTNS,u'index-entry-link-start'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + (TEXTNS,u'index-source-style'), + (TEXTNS,u'line-break'), + (TEXTNS,u'page'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u's'), + (TEXTNS,u'section-source'), + (TEXTNS,u'sequence-decl'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'sort-key'), + (TEXTNS,u'tab'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-field-decl'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-decl') +) diff --git a/odf/form.py b/odf/form.py new file mode 100644 index 0000000..7969b84 --- /dev/null +++ b/odf/form.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import FORMNS +from element import Element + + +# Autogenerated +def Button(**args): + return Element(qname = (FORMNS,'button'), **args) + +def Checkbox(**args): + return Element(qname = (FORMNS,'checkbox'), **args) + +def Column(**args): + return Element(qname = (FORMNS,'column'), **args) + +def Combobox(**args): + return Element(qname = (FORMNS,'combobox'), **args) + +def ConnectionResource(**args): + return Element(qname = (FORMNS,'connection-resource'), **args) + +def Date(**args): + return Element(qname = (FORMNS,'date'), **args) + +def File(**args): + return Element(qname = (FORMNS,'file'), **args) + +def FixedText(**args): + return Element(qname = (FORMNS,'fixed-text'), **args) + +def Form(**args): + return Element(qname = (FORMNS,'form'), **args) + +def FormattedText(**args): + return Element(qname = (FORMNS,'formatted-text'), **args) + +def Frame(**args): + return Element(qname = (FORMNS,'frame'), **args) + +def GenericControl(**args): + return Element(qname = (FORMNS,'generic-control'), **args) + +def Grid(**args): + return Element(qname = (FORMNS,'grid'), **args) + +def Hidden(**args): + return Element(qname = (FORMNS,'hidden'), **args) + +def Image(**args): + return Element(qname = (FORMNS,'image'), **args) + +def ImageFrame(**args): + return Element(qname = (FORMNS,'image-frame'), **args) + +def Item(**args): + return Element(qname = (FORMNS,'item'), **args) + +def ListProperty(**args): + return Element(qname = (FORMNS,'list-property'), **args) + +def ListValue(**args): + return Element(qname = (FORMNS,'list-value'), **args) + +def Listbox(**args): + return Element(qname = (FORMNS,'listbox'), **args) + +def Number(**args): + return Element(qname = (FORMNS,'number'), **args) + +def Option(**args): + return Element(qname = (FORMNS,'option'), **args) + +def Password(**args): + return Element(qname = (FORMNS,'password'), **args) + +def Properties(**args): + return Element(qname = (FORMNS,'properties'), **args) + +def Property(**args): + return Element(qname = (FORMNS,'property'), **args) + +def Radio(**args): + return Element(qname = (FORMNS,'radio'), **args) + +def Text(**args): + return Element(qname = (FORMNS,'text'), **args) + +def Textarea(**args): + return Element(qname = (FORMNS,'textarea'), **args) + +def Time(**args): + return Element(qname = (FORMNS,'time'), **args) + +def ValueRange(**args): + return Element(qname = (FORMNS,'value-range'), **args) + diff --git a/odf/grammar.py b/odf/grammar.py new file mode 100644 index 0000000..dca6519 --- /dev/null +++ b/odf/grammar.py @@ -0,0 +1,9194 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2013 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +__doc__=""" In principle the OpenDocument schema converted to python structures. +Currently it contains the legal child elements of a given element. +To be used for validation check in the API +""" +import sys, os.path +sys.path.append(os.path.dirname(__file__)) +from namespaces import * + +# The following code is generated from the RelaxNG schema with this notice: + +# Open Document Format for Office Applications (OpenDocument) Version 1.2 +# OASIS Standard, 29 September 2011 +# Relax-NG Schema +# Source: http://docs.oasis-open.org/office/v1.2/os/ +# Copyright (c) OASIS Open 2002-2011. All Rights Reserved. + +# All capitalized terms in the following text have the meanings assigned to them +# in the OASIS Intellectual Property Rights Policy (the "OASIS IPR Policy"). The +# full Policy may be found at the OASIS website. + +# This document and translations of it may be copied and furnished to others, and +# derivative works that comment on or otherwise explain it or assist in its +# implementation may be prepared, copied, published, and distributed, in whole or +# in part, without restriction of any kind, provided that the above copyright +# notice and this section are included on all such copies and derivative works. +# However, this document itself may not be modified in any way, including by +# removing the copyright notice or references to OASIS, except as needed for the +# purpose of developing any document or deliverable produced by an OASIS +# Technical Committee (in which case the rules applicable to copyrights, as set +# forth in the OASIS IPR Policy, must be followed) or as required to translate it +# into languages other than English. + +# The limited permissions granted above are perpetual and will not be revoked by +# OASIS or its successors or assigns. + +# This document and the information contained herein is provided on an "AS IS" +# basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +# LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT +# INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR +# FITNESS FOR A PARTICULAR PURPOSE. + +allowed_children = { + (DCNS,u'creator') : ( + ), + (DCNS,u'date') : ( + ), + (DCNS,u'description') : ( + ), + (DCNS,u'language') : ( + ), + (DCNS,u'subject') : ( + ), + (DCNS,u'title') : ( + ), +# Completes Dublin Core start +# (DCNS,'contributor') : ( +# ), +# (DCNS,'coverage') : ( +# ), +# (DCNS,'format') : ( +# ), +# (DCNS,'identifier') : ( +# ), +# (DCNS,'publisher') : ( +# ), +# (DCNS,'relation') : ( +# ), +# (DCNS,'rights') : ( +# ), +# (DCNS,'source') : ( +# ), +# (DCNS,'type') : ( +# ), +# Completes Dublin Core end + (MATHNS,u'math') : None, + + (XFORMSNS,u'model') : None, + + (ANIMNS,u'animate') : ( + ), + (ANIMNS,u'animateColor') : ( + ), + (ANIMNS,u'animateMotion') : ( + ), + (ANIMNS,u'animateTransform') : ( + ), + (ANIMNS,u'audio') : ( + ), + (ANIMNS,u'command') : ( + (ANIMNS,u'param'), + ), +# allowed_children + (ANIMNS,u'iterate') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + ), + (ANIMNS,u'par') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + ), +# allowed_children + (ANIMNS,u'param') : ( + ), + (ANIMNS,u'seq') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + ), + (ANIMNS,u'set') : ( + ), + (ANIMNS,u'transitionFilter') : ( + ), + (CHARTNS,u'axis') : ( + (CHARTNS,u'categories'), + (CHARTNS,u'grid'), + (CHARTNS,u'title'), + ), +# allowed_children + (CHARTNS,u'categories') : ( + ), + (CHARTNS,u'chart') : ( + (CHARTNS,u'footer'), + (CHARTNS,u'legend'), + (CHARTNS,u'plot-area'), + (CHARTNS,u'subtitle'), + (CHARTNS,u'title'), + (TABLENS,u'table'), + ), + (CHARTNS,u'data-label') : ( + (TEXTNS,u'p'), + ), + (CHARTNS,u'data-point') : ( + (CHARTNS,u'data-label'), + ), + (CHARTNS,u'domain') : ( + ), +# allowed_children + (CHARTNS,u'equation') : ( + (TEXTNS,u'p'), + ), + (CHARTNS,u'error-indicator') : ( + ), + (CHARTNS,u'floor') : ( + ), + (CHARTNS,u'footer') : ( + (TEXTNS,u'p'), + ), + (CHARTNS,u'grid') : ( + ), + (CHARTNS,u'label-separator') : ( + (TEXTNS,u'p'), + ), + (CHARTNS,u'legend') : ( + (TEXTNS,u'p'), + ), +# allowed_children + (CHARTNS,u'mean-value') : ( + ), + (CHARTNS,u'plot-area') : ( + (CHARTNS,u'axis'), + (CHARTNS,u'floor'), + (CHARTNS,u'series'), + (CHARTNS,u'stock-gain-marker'), + (CHARTNS,u'stock-loss-marker'), + (CHARTNS,u'stock-range-line'), + (CHARTNS,u'wall'), + (DR3DNS,u'light'), + ), + (CHARTNS,u'regression-curve') : ( + (CHARTNS,u'equation'), + ), + (CHARTNS,u'series') : ( + (CHARTNS,u'data-label'), + (CHARTNS,u'data-point'), + (CHARTNS,u'domain'), + (CHARTNS,u'error-indicator'), + (CHARTNS,u'mean-value'), + (CHARTNS,u'regression-curve'), + ), + (CHARTNS,u'stock-gain-marker') : ( + ), + (CHARTNS,u'stock-loss-marker') : ( + ), +# allowed_children + (CHARTNS,u'stock-range-line') : ( + ), + (CHARTNS,u'subtitle') : ( + (TEXTNS,u'p'), + ), + (CHARTNS,u'symbol-image') : ( + ), + (CHARTNS,u'title') : ( + (TEXTNS,u'p'), + ), + (CHARTNS,u'wall') : ( + ), + (CONFIGNS,u'config-item') : ( + ), + (CONFIGNS,u'config-item-map-entry') : ( + (CONFIGNS,u'config-item'), + (CONFIGNS,u'config-item-map-indexed'), + (CONFIGNS,u'config-item-map-named'), + (CONFIGNS,u'config-item-set'), + ), + (CONFIGNS,u'config-item-map-indexed') : ( + (CONFIGNS,u'config-item-map-entry'), + ), + (CONFIGNS,u'config-item-map-named') : ( + (CONFIGNS,u'config-item-map-entry'), + ), +# allowed_children + (CONFIGNS,u'config-item-set') : ( + (CONFIGNS,u'config-item'), + (CONFIGNS,u'config-item-map-indexed'), + (CONFIGNS,u'config-item-map-named'), + (CONFIGNS,u'config-item-set'), + ), + (MANIFESTNS,u'algorithm') : ( + ), + (MANIFESTNS,u'encryption-data') : ( + (MANIFESTNS,u'algorithm'), + (MANIFESTNS,u'key-derivation'), + ), + (MANIFESTNS,u'file-entry') : ( + (MANIFESTNS,u'encryption-data'), + ), + (MANIFESTNS,u'key-derivation') : ( + ), + (MANIFESTNS,u'manifest') : ( + (MANIFESTNS,u'file-entry'), + ), + (NUMBERNS,u'am-pm') : ( + ), + (NUMBERNS,u'boolean') : ( + ), +# allowed_children + (NUMBERNS,u'boolean-style') : ( + (NUMBERNS,u'boolean'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), + (NUMBERNS,u'currency-style') : ( + (NUMBERNS,u'currency-symbol'), + (NUMBERNS,u'number'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), + (NUMBERNS,u'currency-symbol') : ( + ), + (NUMBERNS,u'date-style') : ( + (NUMBERNS,u'am-pm'), + (NUMBERNS,u'day'), + (NUMBERNS,u'day-of-week'), + (NUMBERNS,u'era'), + (NUMBERNS,u'hours'), + (NUMBERNS,u'minutes'), + (NUMBERNS,u'month'), + (NUMBERNS,u'quarter'), + (NUMBERNS,u'seconds'), + (NUMBERNS,u'text'), + (NUMBERNS,u'week-of-year'), + (NUMBERNS,u'year'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), +# allowed_children + (NUMBERNS,u'day') : ( + ), + (NUMBERNS,u'day-of-week') : ( + ), + (NUMBERNS,u'embedded-text') : ( + ), + (NUMBERNS,u'era') : ( + ), + (NUMBERNS,u'fraction') : ( + ), + (NUMBERNS,u'hours') : ( + ), + (NUMBERNS,u'minutes') : ( + ), + (NUMBERNS,u'month') : ( + ), + (NUMBERNS,u'number') : ( + (NUMBERNS,u'embedded-text'), + ), + (NUMBERNS,u'number-style') : ( + (NUMBERNS,u'fraction'), + (NUMBERNS,u'number'), + (NUMBERNS,u'scientific-number'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), +# allowed_children + (NUMBERNS,u'percentage-style') : ( + (NUMBERNS,u'number'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), + (NUMBERNS,u'quarter') : ( + ), + (NUMBERNS,u'scientific-number') : ( + ), + (NUMBERNS,u'seconds') : ( + ), + (NUMBERNS,u'text') : ( + ), + (NUMBERNS,u'text-content') : ( + ), + (NUMBERNS,u'text-style') : ( + (NUMBERNS,u'text'), + (NUMBERNS,u'text-content'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), +# allowed_children + (NUMBERNS,u'time-style') : ( + (NUMBERNS,u'am-pm'), + (NUMBERNS,u'hours'), + (NUMBERNS,u'minutes'), + (NUMBERNS,u'seconds'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), +# allowed_children + (NUMBERNS,u'week-of-year') : ( + ), + (NUMBERNS,u'year') : ( + ), + (DR3DNS,u'cube') : ( + ), + (DR3DNS,u'extrude') : ( + ), + (DR3DNS,u'light') : ( + ), + (DR3DNS,u'rotate') : ( + ), + (DR3DNS,u'scene') : ( + (DR3DNS,u'cube'), + (DR3DNS,u'extrude'), + (DR3DNS,u'light'), + (DR3DNS,u'rotate'), + (DR3DNS,u'scene'), + (DR3DNS,u'sphere'), + (DRAWNS,u'glue-point'), + (SVGNS,u'title'), + (SVGNS,u'desc'), + ), + (DR3DNS,u'sphere') : ( + ), + (DRAWNS,u'a') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + ), +# allowed_children + (DRAWNS,u'applet') : ( + (DRAWNS,u'param'), + ), + (DRAWNS,u'area-circle') : ( + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), + (DRAWNS,u'area-polygon') : ( + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), + (DRAWNS,u'area-rectangle') : ( + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), + (DRAWNS,u'caption') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'circle') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), +# allowed_children + (DRAWNS,u'connector') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'contour-path') : ( + ), + (DRAWNS,u'contour-polygon') : ( + ), + (DRAWNS,u'control') : ( + (DRAWNS,u'glue-point'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), + (DRAWNS,u'custom-shape') : ( + (DRAWNS,u'enhanced-geometry'), + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), +# allowed_children + (DRAWNS,u'ellipse') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'enhanced-geometry') : ( + (DRAWNS,u'equation'), + (DRAWNS,u'handle'), + ), + (DRAWNS,u'equation') : ( + ), +# allowed_children + (DRAWNS,u'fill-image') : ( + ), + (DRAWNS,u'floating-frame') : ( + ), + (DRAWNS,u'frame') : ( + (DRAWNS,u'applet'), + (DRAWNS,u'contour-path'), + (DRAWNS,u'contour-polygon'), + (DRAWNS,u'floating-frame'), + (DRAWNS,u'glue-point'), + (DRAWNS,u'image'), + (DRAWNS,u'image-map'), + (DRAWNS,u'object'), + (DRAWNS,u'object-ole'), + (DRAWNS,u'plugin'), + (DRAWNS,u'text-box'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TABLENS,u'table'), + ), +# allowed_children + (DRAWNS,u'g') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'glue-point'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (OFFICENS,u'event-listeners'), + ), + (DRAWNS,u'glue-point') : ( + ), + (DRAWNS,u'gradient') : ( + ), + (DRAWNS,u'handle') : ( + ), + (DRAWNS,u'hatch') : ( + ), +# allowed_children + (DRAWNS,u'image') : ( + (OFFICENS,u'binary-data'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'image-map') : ( + (DRAWNS,u'area-circle'), + (DRAWNS,u'area-polygon'), + (DRAWNS,u'area-rectangle'), + ), + (DRAWNS,u'layer') : ( + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), + (DRAWNS,u'layer-set') : ( + (DRAWNS,u'layer'), + ), + (DRAWNS,u'line') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'marker') : ( + ), + (DRAWNS,u'measure') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + (SVGNS,u'title'), + (SVGNS,u'desc'), + ), + (DRAWNS,u'object') : ( + (MATHNS,u'math'), + (OFFICENS,u'document'), + ), +# allowed_children + (DRAWNS,u'object-ole') : ( + (OFFICENS,u'binary-data'), + ), + (DRAWNS,u'opacity') : ( + ), + (DRAWNS,u'page') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'layer-set'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'forms'), + (PRESENTATIONNS,u'animations'), + (PRESENTATIONNS,u'notes'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), +# allowed_children + (DRAWNS,u'page-thumbnail') : ( + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), + (DRAWNS,u'param') : ( + ), + (DRAWNS,u'path') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'plugin') : ( + (DRAWNS,u'param'), + ), + (DRAWNS,u'polygon') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'title'), + (SVGNS,u'desc'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'polyline') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), +# allowed_children + (DRAWNS,u'rect') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'regular-polygon') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'stroke-dash') : ( + ), + (DRAWNS,u'text-box') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), +# allowed_children + (FORMNS,u'button') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'checkbox') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'column') : ( + (FORMNS,u'checkbox'), + (FORMNS,u'combobox'), + (FORMNS,u'date'), + (FORMNS,u'formatted-text'), + (FORMNS,u'listbox'), + (FORMNS,u'number'), + (FORMNS,u'text'), + (FORMNS,u'textarea'), + (FORMNS,u'time'), + ), + (FORMNS,u'combobox') : ( + (FORMNS,u'item'), + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'connection-resource') : ( + ), + (FORMNS,u'date') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'file') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'fixed-text') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), +# allowed_children + (FORMNS,u'form') : ( + (FORMNS,u'button'), + (FORMNS,u'checkbox'), + (FORMNS,u'combobox'), + (FORMNS,u'connection-resource'), + (FORMNS,u'date'), + (FORMNS,u'file'), + (FORMNS,u'fixed-text'), + (FORMNS,u'form'), + (FORMNS,u'formatted-text'), + (FORMNS,u'frame'), + (FORMNS,u'generic-control'), + (FORMNS,u'grid'), + (FORMNS,u'hidden'), + (FORMNS,u'image'), + (FORMNS,u'image-frame'), + (FORMNS,u'listbox'), + (FORMNS,u'number'), + (FORMNS,u'password'), + (FORMNS,u'properties'), + (FORMNS,u'radio'), + (FORMNS,u'text'), + (FORMNS,u'textarea'), + (FORMNS,u'time'), + (FORMNS,u'value-range'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'formatted-text') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'frame') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'generic-control') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'grid') : ( + (FORMNS,u'column'), + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'hidden') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'image') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), +# allowed_children + (FORMNS,u'image-frame') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'item') : ( + ), + (FORMNS,u'list-property') : ( + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + ), + (FORMNS,u'list-value') : ( + ), + (FORMNS,u'listbox') : ( + (FORMNS,u'option'), + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), +# allowed_children + (FORMNS,u'number') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'option') : ( + ), + (FORMNS,u'password') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'properties') : ( + (FORMNS,u'list-property'), + (FORMNS,u'property'), + ), + (FORMNS,u'property') : ( + ), + (FORMNS,u'radio') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'text') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'textarea') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'p'), + ), +# allowed_children + (FORMNS,u'time') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'value-range') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (METANS,u'auto-reload') : ( + ), + (METANS,u'creation-date') : ( + ), + (METANS,u'date-string') : ( + ), + (METANS,u'document-statistic') : ( + ), + (METANS,u'editing-cycles') : ( + ), + (METANS,u'editing-duration') : ( + ), + (METANS,u'generator') : ( + ), + (METANS,u'hyperlink-behaviour') : ( + ), + (METANS,u'initial-creator') : ( + ), + (METANS,u'keyword') : ( + ), + (METANS,u'print-date') : ( + ), + (METANS,u'printed-by') : ( + ), + (METANS,u'template') : ( + ), + (METANS,u'user-defined') : ( + ), +# allowed_children + (OFFICENS,u'annotation') : ( + (DCNS,u'creator'), + (DCNS,u'date'), + (METANS,u'date-string'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), +# allowed_children + (OFFICENS,u'annotation-end') : ( + ), + (OFFICENS,u'automatic-styles') : ( + (NUMBERNS,u'boolean-style'), + (NUMBERNS,u'currency-style'), + (NUMBERNS,u'date-style'), + (NUMBERNS,u'number-style'), + (NUMBERNS,u'percentage-style'), + (NUMBERNS,u'text-style'), + (NUMBERNS,u'time-style'), + (STYLENS,u'page-layout'), + (STYLENS,u'style'), + (TEXTNS,u'list-style'), + ), + (OFFICENS,u'binary-data') : ( + ), + (OFFICENS,u'body') : ( + (OFFICENS,u'chart'), + (OFFICENS,u'drawing'), + (OFFICENS,u'image'), + (OFFICENS,u'presentation'), + (OFFICENS,u'spreadsheet'), + (OFFICENS,u'text'), + ), + (OFFICENS,u'change-info') : ( + (DCNS,u'creator'), + (DCNS,u'date'), + (TEXTNS,u'p'), + ), + (OFFICENS,u'chart') : ( + (CHARTNS,u'chart'), + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'variable-decls'), + ), + (OFFICENS,u'dde-source') : ( + ), + (OFFICENS,u'document') : ( + (OFFICENS,u'automatic-styles'), + (OFFICENS,u'body'), + (OFFICENS,u'font-face-decls'), + (OFFICENS,u'master-styles'), + (OFFICENS,u'meta'), + (OFFICENS,u'scripts'), + (OFFICENS,u'settings'), + (OFFICENS,u'styles'), + ), + (OFFICENS,u'document-content') : ( + (OFFICENS,u'automatic-styles'), + (OFFICENS,u'body'), + (OFFICENS,u'font-face-decls'), + (OFFICENS,u'scripts'), + ), + (OFFICENS,u'document-meta') : ( + (OFFICENS,u'meta'), + ), + (OFFICENS,u'document-settings') : ( + (OFFICENS,u'settings'), + ), + (OFFICENS,u'document-styles') : ( + (OFFICENS,u'automatic-styles'), + (OFFICENS,u'font-face-decls'), + (OFFICENS,u'master-styles'), + (OFFICENS,u'styles'), + ), + (OFFICENS,u'drawing') : ( + (DRAWNS,u'page'), + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'variable-decls'), + ), + (OFFICENS,u'event-listeners') : ( + (PRESENTATIONNS,u'event-listener'), + (SCRIPTNS,u'event-listener'), + ), + (OFFICENS,u'font-face-decls') : ( + (STYLENS,u'font-face'), + ), +# allowed_children + (OFFICENS,u'forms') : ( + (XFORMSNS,u'model'), + (FORMNS,u'form'), + ), + (OFFICENS,u'image') : ( + (DRAWNS,u'frame'), + ), + (OFFICENS,u'master-styles') : ( + (DRAWNS,u'layer-set'), + (STYLENS,u'handout-master'), + (STYLENS,u'master-page'), + ), + (OFFICENS,u'meta') : ( + (DCNS,u'creator'), + (DCNS,u'date'), + (DCNS,u'description'), + (DCNS,u'language'), + (DCNS,u'subject'), + (DCNS,u'title'), +# Completes Dublin Core start +# (DCNS,'contributor'), +# (DCNS,'coverage'), +# (DCNS,'format'), +# (DCNS,'identifier'), +# (DCNS,'publisher'), +# (DCNS,'relation'), +# (DCNS,'rights'), +# (DCNS,'source'), +# (DCNS,'type'), +# Completes Dublin Core end + (METANS,u'auto-reload'), + (METANS,u'creation-date'), + (METANS,u'document-statistic'), + (METANS,u'editing-cycles'), + (METANS,u'editing-duration'), + (METANS,u'generator'), + (METANS,u'hyperlink-behaviour'), + (METANS,u'initial-creator'), + (METANS,u'keyword'), + (METANS,u'print-date'), + (METANS,u'printed-by'), + (METANS,u'template'), + (METANS,u'user-defined'), + ), + (OFFICENS,u'presentation') : ( + (DRAWNS,u'page'), + (PRESENTATIONNS,u'date-time-decl'), + (PRESENTATIONNS,u'footer-decl'), + (PRESENTATIONNS,u'header-decl'), + (PRESENTATIONNS,u'settings'), + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'variable-decls'), + ), +# allowed_children + (OFFICENS,u'script') : None, + + (OFFICENS,u'scripts') : ( + (OFFICENS,u'event-listeners'), + (OFFICENS,u'script'), + ), + (OFFICENS,u'settings') : ( + (CONFIGNS,u'config-item-set'), + ), + (OFFICENS,u'spreadsheet') : ( + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TABLENS,u'table'), + (TABLENS,u'tracked-changes'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'variable-decls'), + ), + (OFFICENS,u'styles') : ( + (NUMBERNS,u'boolean-style'), + (NUMBERNS,u'currency-style'), + (NUMBERNS,u'date-style'), + (NUMBERNS,u'number-style'), + (NUMBERNS,u'percentage-style'), + (NUMBERNS,u'text-style'), + (NUMBERNS,u'time-style'), + (DRAWNS,u'fill-image'), + (DRAWNS,u'gradient'), + (DRAWNS,u'hatch'), + (DRAWNS,u'marker'), + (DRAWNS,u'opacity'), + (DRAWNS,u'stroke-dash'), + (STYLENS,u'default-page-layout'), + (STYLENS,u'default-style'), + (STYLENS,u'presentation-page-layout'), + (STYLENS,u'style'), + (SVGNS,u'linearGradient'), + (SVGNS,u'radialGradient'), + (TABLENS,u'table-template'), + (TEXTNS,u'bibliography-configuration'), + (TEXTNS,u'linenumbering-configuration'), + (TEXTNS,u'list-style'), + (TEXTNS,u'notes-configuration'), + (TEXTNS,u'outline-style'), + ), + (OFFICENS,u'text') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'forms'), + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'page-sequence'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'tracked-changes'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), + (PRESENTATIONNS,u'animation-group') : ( + (PRESENTATIONNS,u'dim'), + (PRESENTATIONNS,u'hide-shape'), + (PRESENTATIONNS,u'hide-text'), + (PRESENTATIONNS,u'play'), + (PRESENTATIONNS,u'show-shape'), + (PRESENTATIONNS,u'show-text'), + ), + (PRESENTATIONNS,u'animations') : ( + (PRESENTATIONNS,u'animation-group'), + (PRESENTATIONNS,u'dim'), + (PRESENTATIONNS,u'hide-shape'), + (PRESENTATIONNS,u'hide-text'), + (PRESENTATIONNS,u'play'), + (PRESENTATIONNS,u'show-shape'), + (PRESENTATIONNS,u'show-text'), + ), + (PRESENTATIONNS,u'date-time') : ( + ), + (PRESENTATIONNS,u'date-time-decl') : ( + ), + (PRESENTATIONNS,u'dim') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'event-listener') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'footer') : ( + ), + (PRESENTATIONNS,u'footer-decl') : ( + ), + (PRESENTATIONNS,u'header') : ( + ), + (PRESENTATIONNS,u'header-decl') : ( + ), + (PRESENTATIONNS,u'hide-shape') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'hide-text') : ( + (PRESENTATIONNS,u'sound'), + ), +# allowed_children + (PRESENTATIONNS,u'notes') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'forms'), + ), + (PRESENTATIONNS,u'placeholder') : ( + ), + (PRESENTATIONNS,u'play') : ( + ), + (PRESENTATIONNS,u'settings') : ( + (PRESENTATIONNS,u'show'), + ), + (PRESENTATIONNS,u'show') : ( + ), + (PRESENTATIONNS,u'show-shape') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'show-text') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'sound') : ( + ), + (SCRIPTNS,u'event-listener') : ( + ), + (STYLENS,u'background-image') : ( + (OFFICENS,u'binary-data'), + ), +# allowed_children + (STYLENS,u'chart-properties') : ( + (CHARTNS,u'label-separator'), + (CHARTNS,u'symbol-image'), + ), + (STYLENS,u'column') : ( + ), + (STYLENS,u'column-sep') : ( + ), + (STYLENS,u'columns') : ( + (STYLENS,u'column'), + (STYLENS,u'column-sep'), + ), +# allowed_children + (STYLENS,u'default-page-layout') : ( + (STYLENS,u'page-layout-properties'), + (STYLENS,u'header-style'), + (STYLENS,u'footer-style'), + ), + (STYLENS,u'default-style') : ( + (STYLENS,u'chart-properties'), + (STYLENS,u'drawing-page-properties'), + (STYLENS,u'graphic-properties'), + (STYLENS,u'paragraph-properties'), + (STYLENS,u'ruby-properties'), + (STYLENS,u'section-properties'), + (STYLENS,u'table-cell-properties'), + (STYLENS,u'table-column-properties'), + (STYLENS,u'table-properties'), + (STYLENS,u'table-row-properties'), + (STYLENS,u'text-properties'), + ), + (STYLENS,u'drawing-page-properties') : ( + (PRESENTATIONNS,u'sound'), + ), + (STYLENS,u'drop-cap') : ( + ), + (STYLENS,u'font-face') : ( + (SVGNS,u'definition-src'), + (SVGNS,u'font-face-src'), + ), + (STYLENS,u'footer') : ( + (STYLENS,u'region-center'), + (STYLENS,u'region-left'), + (STYLENS,u'region-right'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'tracked-changes'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), +# allowed_children + (STYLENS,u'footer-left') : ( + (STYLENS,u'region-center'), + (STYLENS,u'region-left'), + (STYLENS,u'region-right'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'tracked-changes'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), + (STYLENS,u'footer-style') : ( + (STYLENS,u'header-footer-properties'), + ), + (STYLENS,u'footnote-sep') : ( + ), + (STYLENS,u'graphic-properties') : ( + (STYLENS,u'background-image'), + (STYLENS,u'columns'), + (TEXTNS,u'list-style'), + ), +# allowed_children + (STYLENS,u'handout-master') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + ), + (STYLENS,u'header') : ( + (STYLENS,u'region-center'), + (STYLENS,u'region-left'), + (STYLENS,u'region-right'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'tracked-changes'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), +# allowed_children + (STYLENS,u'header-footer-properties') : ( + (STYLENS,u'background-image'), + ), + (STYLENS,u'header-left') : ( + (STYLENS,u'region-center'), + (STYLENS,u'region-left'), + (STYLENS,u'region-right'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'tracked-changes'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), + (STYLENS,u'header-style') : ( + (STYLENS,u'header-footer-properties'), + ), +# allowed_children + (STYLENS,u'list-level-label-alignment') : ( + ), + (STYLENS,u'list-level-properties') : ( + (STYLENS,u'list-level-label-alignment'), + ), + (STYLENS,u'map') : ( + ), + (STYLENS,u'master-page') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'layer-set'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'forms'), + (PRESENTATIONNS,u'notes'), + (STYLENS,u'footer'), + (STYLENS,u'footer-left'), + (STYLENS,u'header'), + (STYLENS,u'header-left'), + ), + (STYLENS,u'page-layout') : ( + (STYLENS,u'footer-style'), + (STYLENS,u'header-style'), + (STYLENS,u'page-layout-properties'), + ), + (STYLENS,u'page-layout-properties') : ( + (STYLENS,u'background-image'), + (STYLENS,u'columns'), + (STYLENS,u'footnote-sep'), + ), +# allowed_children + (STYLENS,u'paragraph-properties') : ( + (STYLENS,u'background-image'), + (STYLENS,u'drop-cap'), + (STYLENS,u'tab-stops'), + ), + (STYLENS,u'presentation-page-layout') : ( + (PRESENTATIONNS,u'placeholder'), + ), + (STYLENS,u'region-center') : ( + (TEXTNS,u'p'), + ), + (STYLENS,u'region-left') : ( + (TEXTNS,u'p'), + ), + (STYLENS,u'region-right') : ( + (TEXTNS,u'p'), + ), + (STYLENS,u'ruby-properties') : ( + ), + (STYLENS,u'section-properties') : ( + (STYLENS,u'background-image'), + (STYLENS,u'columns'), + (TEXTNS,u'notes-configuration'), + ), + (STYLENS,u'style') : ( + (STYLENS,u'chart-properties'), + (STYLENS,u'drawing-page-properties'), + (STYLENS,u'graphic-properties'), + (STYLENS,u'map'), + (STYLENS,u'paragraph-properties'), + (STYLENS,u'ruby-properties'), + (STYLENS,u'section-properties'), + (STYLENS,u'table-cell-properties'), + (STYLENS,u'table-column-properties'), + (STYLENS,u'table-properties'), + (STYLENS,u'table-row-properties'), + (STYLENS,u'text-properties'), + ), + (STYLENS,u'tab-stop') : ( + ), + (STYLENS,u'tab-stops') : ( + (STYLENS,u'tab-stop'), + ), +# allowed_children + (STYLENS,u'table-cell-properties') : ( + (STYLENS,u'background-image'), + ), + (STYLENS,u'table-column-properties') : ( + ), + (STYLENS,u'table-properties') : ( + (STYLENS,u'background-image'), + ), + (STYLENS,u'table-row-properties') : ( + (STYLENS,u'background-image'), + ), + (STYLENS,u'text-properties') : ( + ), + (SVGNS,u'definition-src') : ( + ), + (SVGNS,u'desc') : ( + ), + (SVGNS,u'font-face-format') : ( + ), + (SVGNS,u'font-face-name') : ( + ), + (SVGNS,u'font-face-src') : ( + (SVGNS,u'font-face-name'), + (SVGNS,u'font-face-uri'), + ), + (SVGNS,u'font-face-uri') : ( + (SVGNS,u'font-face-format'), + ), + (SVGNS,u'linearGradient') : ( + (SVGNS,u'stop'), + ), + (SVGNS,u'radialGradient') : ( + (SVGNS,u'stop'), + ), + (SVGNS,u'stop') : ( + ), + (SVGNS,u'title') : ( + ), +# allowed_children + (TABLENS,u'background') : ( + ), + (TABLENS,u'body') : ( + ), + (TABLENS,u'calculation-settings') : ( + (TABLENS,u'iteration'), + (TABLENS,u'null-date'), + ), +# allowed_children + (TABLENS,u'cell-address') : ( + ), + (TABLENS,u'cell-content-change') : ( + (OFFICENS,u'change-info'), + (TABLENS,u'cell-address'), + (TABLENS,u'deletions'), + (TABLENS,u'dependencies'), + (TABLENS,u'previous'), + ), + (TABLENS,u'cell-content-deletion') : ( + (TABLENS,u'cell-address'), + (TABLENS,u'change-track-table-cell'), + ), + (TABLENS,u'cell-range-source') : ( + ), + (TABLENS,u'change-deletion') : ( + ), + (TABLENS,u'change-track-table-cell') : ( + (TEXTNS,u'p'), + ), + (TABLENS,u'consolidation') : ( + ), + (TABLENS,u'content-validation') : ( + (OFFICENS,u'event-listeners'), + (TABLENS,u'error-macro'), + (TABLENS,u'error-message'), + (TABLENS,u'help-message'), + ), +# allowed_children + (TABLENS,u'content-validations') : ( + (TABLENS,u'content-validation'), + ), + (TABLENS,u'covered-table-cell') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (TABLENS,u'cell-range-source'), + (TABLENS,u'detective'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), +# allowed_children + (TABLENS,u'cut-offs') : ( + (TABLENS,u'insertion-cut-off'), + (TABLENS,u'movement-cut-off'), + ), + (TABLENS,u'data-pilot-display-info') : ( + ), + (TABLENS,u'data-pilot-field') : ( + (TABLENS,u'data-pilot-field-reference'), + (TABLENS,u'data-pilot-groups'), + (TABLENS,u'data-pilot-level'), + ), + (TABLENS,u'data-pilot-field-reference') : ( + ), + (TABLENS,u'data-pilot-group') : ( + (TABLENS,u'data-pilot-group-member'), + ), + (TABLENS,u'data-pilot-group-member') : ( + ), + (TABLENS,u'data-pilot-groups') : ( + (TABLENS,u'data-pilot-group'), + ), + (TABLENS,u'data-pilot-layout-info') : ( + ), + (TABLENS,u'data-pilot-level') : ( + (TABLENS,u'data-pilot-display-info'), + (TABLENS,u'data-pilot-layout-info'), + (TABLENS,u'data-pilot-members'), + (TABLENS,u'data-pilot-sort-info'), + (TABLENS,u'data-pilot-subtotals'), + ), + (TABLENS,u'data-pilot-member') : ( + ), + (TABLENS,u'data-pilot-members') : ( + (TABLENS,u'data-pilot-member'), + ), + (TABLENS,u'data-pilot-sort-info') : ( + ), + (TABLENS,u'data-pilot-subtotal') : ( + ), + (TABLENS,u'data-pilot-subtotals') : ( + (TABLENS,u'data-pilot-subtotal'), + ), +# allowed_children + (TABLENS,u'data-pilot-table') : ( + (TABLENS,u'data-pilot-field'), + (TABLENS,u'database-source-query'), + (TABLENS,u'database-source-sql'), + (TABLENS,u'database-source-table'), + (TABLENS,u'source-cell-range'), + (TABLENS,u'source-service'), + ), + (TABLENS,u'data-pilot-tables') : ( + (TABLENS,u'data-pilot-table'), + ), + (TABLENS,u'database-range') : ( + (TABLENS,u'database-source-query'), + (TABLENS,u'database-source-sql'), + (TABLENS,u'database-source-table'), + (TABLENS,u'filter'), + (TABLENS,u'sort'), + (TABLENS,u'subtotal-rules'), + ), + (TABLENS,u'database-ranges') : ( + (TABLENS,u'database-range'), + ), + (TABLENS,u'database-source-query') : ( + ), + (TABLENS,u'database-source-sql') : ( + ), + (TABLENS,u'database-source-table') : ( + ), +# allowed_children + (TABLENS,u'dde-link') : ( + (OFFICENS,u'dde-source'), + (TABLENS,u'table'), + ), + (TABLENS,u'dde-links') : ( + (TABLENS,u'dde-link'), + ), + (TABLENS,u'deletion') : ( + (OFFICENS,u'change-info'), + (TABLENS,u'cut-offs'), + (TABLENS,u'deletions'), + (TABLENS,u'dependencies'), + ), + (TABLENS,u'deletions') : ( + (TABLENS,u'cell-content-deletion'), + (TABLENS,u'change-deletion'), + ), + (TABLENS,u'dependencies') : ( + (TABLENS,u'dependency'), + ), + (TABLENS,u'dependency') : ( + ), +# allowed_children + (TABLENS,u'desc') : ( + ), + (TABLENS,u'detective') : ( + (TABLENS,u'highlighted-range'), + (TABLENS,u'operation'), + ), +# allowed_children + (TABLENS,u'error-macro') : ( + ), + (TABLENS,u'error-message') : ( + (TEXTNS,u'p'), + ), + (TABLENS,u'even-columns') : ( + ), + (TABLENS,u'even-rows') : ( + ), + (TABLENS,u'filter') : ( + (TABLENS,u'filter-and'), + (TABLENS,u'filter-condition'), + (TABLENS,u'filter-or'), + ), + (TABLENS,u'filter-and') : ( + (TABLENS,u'filter-condition'), + (TABLENS,u'filter-or'), + ), + (TABLENS,u'filter-condition') : ( + (TABLENS,u'filter-set-item'), + ), + (TABLENS,u'filter-or') : ( + (TABLENS,u'filter-and'), + (TABLENS,u'filter-condition'), + ), +# allowed_children + (TABLENS,u'filter-set-item') : ( + ), +# allowed_children + (TABLENS,u'first-column') : ( + ), + (TABLENS,u'first-row') : ( + ), + (TABLENS,u'help-message') : ( + (TEXTNS,u'p'), + ), + (TABLENS,u'highlighted-range') : ( + ), + (TABLENS,u'insertion') : ( + (OFFICENS,u'change-info'), + (TABLENS,u'deletions'), + (TABLENS,u'dependencies'), + ), + (TABLENS,u'insertion-cut-off') : ( + ), + (TABLENS,u'iteration') : ( + ), + (TABLENS,u'label-range') : ( + ), + (TABLENS,u'label-ranges') : ( + (TABLENS,u'label-range'), + ), + (TABLENS,u'last-column') : ( + ), + (TABLENS,u'last-row') : ( + ), + (TABLENS,u'movement') : ( + (OFFICENS,u'change-info'), + (TABLENS,u'deletions'), + (TABLENS,u'dependencies'), + (TABLENS,u'source-range-address'), + (TABLENS,u'target-range-address'), + ), + (TABLENS,u'movement-cut-off') : ( + ), + (TABLENS,u'named-expression') : ( + ), + (TABLENS,u'named-expressions') : ( + (TABLENS,u'named-expression'), + (TABLENS,u'named-range'), + ), +# allowed_children + (TABLENS,u'named-range') : ( + ), + (TABLENS,u'null-date') : ( + ), + (TABLENS,u'odd-columns') : ( + ), + (TABLENS,u'odd-rows') : ( + ), + (TABLENS,u'operation') : ( + ), + (TABLENS,u'previous') : ( + (TABLENS,u'change-track-table-cell'), + ), + (TABLENS,u'scenario') : ( + ), + (TABLENS,u'shapes') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + ), +# allowed_children + (TABLENS,u'sort') : ( + (TABLENS,u'sort-by'), + ), + (TABLENS,u'sort-by') : ( + ), + (TABLENS,u'sort-groups') : ( + ), + (TABLENS,u'source-cell-range') : ( + (TABLENS,u'filter'), + ), + (TABLENS,u'source-range-address') : ( + ), + (TABLENS,u'source-service') : ( + ), + (TABLENS,u'subtotal-field') : ( + ), + (TABLENS,u'subtotal-rule') : ( + (TABLENS,u'subtotal-field'), + ), + (TABLENS,u'subtotal-rules') : ( + (TABLENS,u'sort-groups'), + (TABLENS,u'subtotal-rule'), + ), +# allowed_children + (TABLENS,u'table') : ( + (OFFICENS,u'dde-source'), + (OFFICENS,u'forms'), + (TABLENS,u'desc'), + (TABLENS,u'named-expressions'), + (TABLENS,u'scenario'), + (TABLENS,u'shapes'), + (TABLENS,u'table-column'), + (TABLENS,u'table-column-group'), + (TABLENS,u'table-columns'), + (TABLENS,u'table-header-columns'), + (TABLENS,u'table-header-rows'), + (TABLENS,u'table-row'), + (TABLENS,u'table-row-group'), + (TABLENS,u'table-rows'), + (TABLENS,u'table-source'), + (TABLENS,u'title'), + (TEXTNS,u'soft-page-break'), + ), + (TABLENS,u'table-cell') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (TABLENS,u'cell-range-source'), + (TABLENS,u'detective'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), +# allowed_children + (TABLENS,u'table-column') : ( + ), + (TABLENS,u'table-column-group') : ( + (TABLENS,u'table-column'), + (TABLENS,u'table-column-group'), + (TABLENS,u'table-columns'), + (TABLENS,u'table-header-columns'), + ), + (TABLENS,u'table-columns') : ( + (TABLENS,u'table-column'), + ), + (TABLENS,u'table-header-columns') : ( + (TABLENS,u'table-column'), + ), + (TABLENS,u'table-header-rows') : ( + (TABLENS,u'table-row'), + (TEXTNS,u'soft-page-break'), + ), + (TABLENS,u'table-row') : ( + (TABLENS,u'covered-table-cell'), + (TABLENS,u'table-cell'), + ), + (TABLENS,u'table-row-group') : ( + (TABLENS,u'table-header-rows'), + (TABLENS,u'table-row'), + (TABLENS,u'table-row-group'), + (TABLENS,u'table-rows'), + (TEXTNS,u'soft-page-break'), + ), + (TABLENS,u'table-rows') : ( + (TABLENS,u'table-row'), + (TEXTNS,u'soft-page-break'), + ), +# allowed_children + (TABLENS,u'table-source') : ( + ), + (TABLENS,u'table-template') : ( + (TABLENS,u'background'), + (TABLENS,u'body'), + (TABLENS,u'even-columns'), + (TABLENS,u'even-rows'), + (TABLENS,u'first-column'), + (TABLENS,u'first-row'), + (TABLENS,u'last-column'), + (TABLENS,u'last-row'), + (TABLENS,u'odd-columns'), + (TABLENS,u'odd-rows'), + ), + (TABLENS,u'target-range-address') : ( + ), +# allowed_children + (TABLENS,u'title') : ( + ), + (TABLENS,u'tracked-changes') : ( + (TABLENS,u'cell-content-change'), + (TABLENS,u'deletion'), + (TABLENS,u'insertion'), + (TABLENS,u'movement'), + ), +# allowed_children + (TEXTNS,u'a') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (OFFICENS,u'annotation-end'), + (OFFICENS,u'event-listeners'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'meta'), + (TEXTNS,u'meta-field'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'print-time'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), + + ), +# allowed_children + (TEXTNS,u'alphabetical-index') : ( + (TEXTNS,u'alphabetical-index-source'), + (TEXTNS,u'index-body'), + ), + (TEXTNS,u'alphabetical-index-auto-mark-file') : ( + ), + (TEXTNS,u'alphabetical-index-entry-template') : ( + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'alphabetical-index-mark') : ( + ), + (TEXTNS,u'alphabetical-index-mark-end') : ( + ), + (TEXTNS,u'alphabetical-index-mark-start') : ( + ), + (TEXTNS,u'alphabetical-index-source') : ( + (TEXTNS,u'alphabetical-index-entry-template'), + (TEXTNS,u'index-title-template'), + ), + (TEXTNS,u'author-initials') : ( + ), + (TEXTNS,u'author-name') : ( + ), + (TEXTNS,u'bibliography') : ( + (TEXTNS,u'bibliography-source'), + (TEXTNS,u'index-body'), + ), + (TEXTNS,u'bibliography-configuration') : ( + (TEXTNS,u'sort-key'), + ), + (TEXTNS,u'bibliography-entry-template') : ( + (TEXTNS,u'index-entry-bibliography'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + ), +# allowed_children + (TEXTNS,u'bibliography-mark') : ( + ), + (TEXTNS,u'bibliography-source') : ( + (TEXTNS,u'bibliography-entry-template'), + (TEXTNS,u'index-title-template'), + ), + (TEXTNS,u'bookmark') : ( + ), + (TEXTNS,u'bookmark-end') : ( + ), + (TEXTNS,u'bookmark-ref') : ( + ), + (TEXTNS,u'bookmark-start') : ( + ), + (TEXTNS,u'change') : ( + ), + (TEXTNS,u'change-end') : ( + ), + (TEXTNS,u'change-start') : ( + ), + (TEXTNS,u'changed-region') : ( + (TEXTNS,u'deletion'), + (TEXTNS,u'format-change'), + (TEXTNS,u'insertion'), + ), + (TEXTNS,u'chapter') : ( + ), + (TEXTNS,u'character-count') : ( + ), + (TEXTNS,u'conditional-text') : ( + ), + (TEXTNS,u'creation-date') : ( + ), + (TEXTNS,u'creation-time') : ( + ), + (TEXTNS,u'creator') : ( + ), + (TEXTNS,u'database-display') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'database-name') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'database-next') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'database-row-number') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'database-row-select') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'date') : ( + ), + (TEXTNS,u'dde-connection') : ( + ), + (TEXTNS,u'dde-connection-decl') : ( + ), + (TEXTNS,u'dde-connection-decls') : ( + (TEXTNS,u'dde-connection-decl'), + ), +# allowed_children + (TEXTNS,u'deletion') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'change-info'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'description') : ( + ), + (TEXTNS,u'editing-cycles') : ( + ), + (TEXTNS,u'editing-duration') : ( + ), + (TEXTNS,u'execute-macro') : ( + (OFFICENS,u'event-listeners'), + ), + (TEXTNS,u'expression') : ( + ), + (TEXTNS,u'file-name') : ( + ), + (TEXTNS,u'format-change') : ( + (OFFICENS,u'change-info'), + ), +# allowed_children + (TEXTNS,u'h') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (OFFICENS,u'annotation-end'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'meta'), + (TEXTNS,u'meta-field'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'number'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'print-time'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), + + ), +# allowed_children + (TEXTNS,u'hidden-paragraph') : ( + ), + (TEXTNS,u'hidden-text') : ( + ), + (TEXTNS,u'illustration-index') : ( + (TEXTNS,u'illustration-index-source'), + (TEXTNS,u'index-body'), + ), + (TEXTNS,u'illustration-index-entry-template') : ( + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'illustration-index-source') : ( + (TEXTNS,u'illustration-index-entry-template'), + (TEXTNS,u'index-title-template'), + ), + (TEXTNS,u'image-count') : ( + ), +# allowed_children + (TEXTNS,u'index-body') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'index-entry-bibliography') : ( + ), + (TEXTNS,u'index-entry-chapter') : ( + ), + (TEXTNS,u'index-entry-link-end') : ( + ), + (TEXTNS,u'index-entry-link-start') : ( + ), + (TEXTNS,u'index-entry-page-number') : ( + ), + (TEXTNS,u'index-entry-span') : ( + ), + (TEXTNS,u'index-entry-tab-stop') : ( + ), + (TEXTNS,u'index-entry-text') : ( + ), + (TEXTNS,u'index-source-style') : ( + ), + (TEXTNS,u'index-source-styles') : ( + (TEXTNS,u'index-source-style'), + ), +# allowed_children + (TEXTNS,u'index-title') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'index-title-template') : ( + ), + (TEXTNS,u'initial-creator') : ( + ), + (TEXTNS,u'insertion') : ( + (OFFICENS,u'change-info'), + ), + (TEXTNS,u'keywords') : ( + ), + (TEXTNS,u'line-break') : ( + ), + (TEXTNS,u'linenumbering-configuration') : ( + (TEXTNS,u'linenumbering-separator'), + ), + (TEXTNS,u'linenumbering-separator') : ( + ), + (TEXTNS,u'list') : ( + (TEXTNS,u'list-header'), + (TEXTNS,u'list-item'), + ), + (TEXTNS,u'list-header') : ( + (TEXTNS,u'h'), + (TEXTNS,u'list'), + (TEXTNS,u'number'), + (TEXTNS,u'p'), + (TEXTNS,u'soft-page-break'), + ), + (TEXTNS,u'list-item') : ( + (TEXTNS,u'h'), + (TEXTNS,u'list'), + (TEXTNS,u'number'), + (TEXTNS,u'p'), + (TEXTNS,u'soft-page-break'), + ), + (TEXTNS,u'list-level-style-bullet') : ( + (STYLENS,u'list-level-properties'), + (STYLENS,u'text-properties'), + ), + (TEXTNS,u'list-level-style-image') : ( + (OFFICENS,u'binary-data'), + (STYLENS,u'list-level-properties'), + ), + (TEXTNS,u'list-level-style-number') : ( + (STYLENS,u'list-level-properties'), + (STYLENS,u'text-properties'), + ), + (TEXTNS,u'list-style') : ( + (TEXTNS,u'list-level-style-bullet'), + (TEXTNS,u'list-level-style-image'), + (TEXTNS,u'list-level-style-number'), + ), + (TEXTNS,u'measure') : ( + ), +# allowed_children + (TEXTNS,u'meta') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (OFFICENS,u'annotation-end'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'meta'), + (TEXTNS,u'meta-field'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'print-time'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), + ), +# allowed_children + (TEXTNS,u'meta-field') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (OFFICENS,u'annotation-end'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'meta'), + (TEXTNS,u'meta-field'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'print-time'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), + ), +# allowed_children + (TEXTNS,u'modification-date') : ( + ), + (TEXTNS,u'modification-time') : ( + ), + (TEXTNS,u'note') : ( + (TEXTNS,u'note-body'), + (TEXTNS,u'note-citation'), + ), +# allowed_children + (TEXTNS,u'note-body') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'note-citation') : ( + ), + (TEXTNS,u'note-continuation-notice-backward') : ( + ), + (TEXTNS,u'note-continuation-notice-forward') : ( + ), + (TEXTNS,u'note-ref') : ( + ), + (TEXTNS,u'notes-configuration') : ( + (TEXTNS,u'note-continuation-notice-backward'), + (TEXTNS,u'note-continuation-notice-forward'), + ), + (TEXTNS,u'number') : ( + ), + (TEXTNS,u'numbered-paragraph') : ( + (TEXTNS,u'h'), + (TEXTNS,u'number'), + (TEXTNS,u'p'), + ), + (TEXTNS,u'object-count') : ( + ), + (TEXTNS,u'object-index') : ( + (TEXTNS,u'index-body'), + (TEXTNS,u'object-index-source'), + ), + (TEXTNS,u'object-index-entry-template') : ( + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'object-index-source') : ( + (TEXTNS,u'index-title-template'), + (TEXTNS,u'object-index-entry-template'), + ), + (TEXTNS,u'outline-level-style') : ( + (STYLENS,u'list-level-properties'), + (STYLENS,u'text-properties'), + ), + (TEXTNS,u'outline-style') : ( + (TEXTNS,u'outline-level-style'), + ), +# allowed_children + (TEXTNS,u'p') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (OFFICENS,u'annotation-end'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'meta'), + (TEXTNS,u'meta-field'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'print-time'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), + ), + (TEXTNS,u'page') : ( + ), + (TEXTNS,u'page-count') : ( + ), + (TEXTNS,u'page-continuation') : ( + ), + (TEXTNS,u'page-number') : ( + ), + (TEXTNS,u'page-sequence') : ( + (TEXTNS,u'page'), + ), + (TEXTNS,u'page-variable-get') : ( + ), + (TEXTNS,u'page-variable-set') : ( + ), + (TEXTNS,u'paragraph-count') : ( + ), + (TEXTNS,u'placeholder') : ( + ), + (TEXTNS,u'print-date') : ( + ), + (TEXTNS,u'print-time') : ( + ), + (TEXTNS,u'printed-by') : ( + ), + (TEXTNS,u'reference-mark') : ( + ), + (TEXTNS,u'reference-mark-end') : ( + ), +# allowed_children + (TEXTNS,u'reference-mark-start') : ( + ), + (TEXTNS,u'reference-ref') : ( + ), + (TEXTNS,u'ruby') : ( + (TEXTNS,u'ruby-base'), + (TEXTNS,u'ruby-text'), + ), + (TEXTNS,u'ruby-base') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (OFFICENS,u'annotation-end'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'meta'), + (TEXTNS,u'meta-field'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'print-time'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), + + ), +# allowed_children + (TEXTNS,u'ruby-text') : ( + ), + (TEXTNS,u's') : ( + ), + (TEXTNS,u'script') : ( + ), + (TEXTNS,u'section') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'dde-source'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'section-source'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'section-source') : ( + ), + (TEXTNS,u'sender-city') : ( + ), + (TEXTNS,u'sender-company') : ( + ), + (TEXTNS,u'sender-country') : ( + ), +# allowed_children + (TEXTNS,u'sender-email') : ( + ), + (TEXTNS,u'sender-fax') : ( + ), + (TEXTNS,u'sender-firstname') : ( + ), + (TEXTNS,u'sender-initials') : ( + ), + (TEXTNS,u'sender-lastname') : ( + ), + (TEXTNS,u'sender-phone-private') : ( + ), + (TEXTNS,u'sender-phone-work') : ( + ), + (TEXTNS,u'sender-position') : ( + ), + (TEXTNS,u'sender-postal-code') : ( + ), + (TEXTNS,u'sender-state-or-province') : ( + ), + (TEXTNS,u'sender-street') : ( + ), + (TEXTNS,u'sender-title') : ( + ), + (TEXTNS,u'sequence') : ( + ), + (TEXTNS,u'sequence-decl') : ( + ), + (TEXTNS,u'sequence-decls') : ( + (TEXTNS,u'sequence-decl'), + ), + (TEXTNS,u'sequence-ref') : ( + ), + (TEXTNS,u'sheet-name') : ( + ), + (TEXTNS,u'soft-page-break') : ( + ), + (TEXTNS,u'sort-key') : ( + ), +# allowed_children + (TEXTNS,u'span') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (OFFICENS,u'annotation-end'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'meta'), + (TEXTNS,u'meta-field'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'page-count'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'word-count'), + (TEXTNS,u'character-count'), + (TEXTNS,u'table-count'), + (TEXTNS,u'image-count'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'print-time'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + ), +# allowed_children + (TEXTNS,u'subject') : ( + ), + (TEXTNS,u'tab') : ( + ), + (TEXTNS,u'table-count') : ( + ), + (TEXTNS,u'table-formula') : ( + ), + (TEXTNS,u'table-index') : ( + (TEXTNS,u'index-body'), + (TEXTNS,u'table-index-source'), + ), + (TEXTNS,u'table-index-entry-template') : ( + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'table-index-source') : ( + (TEXTNS,u'index-title-template'), + (TEXTNS,u'table-index-entry-template'), + ), + (TEXTNS,u'table-of-content') : ( + (TEXTNS,u'index-body'), + (TEXTNS,u'table-of-content-source'), + ), + (TEXTNS,u'table-of-content-entry-template') : ( + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-link-end'), + (TEXTNS,u'index-entry-link-start'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'table-of-content-source') : ( + (TEXTNS,u'index-source-styles'), + (TEXTNS,u'index-title-template'), + (TEXTNS,u'table-of-content-entry-template'), + ), + (TEXTNS,u'template-name') : ( + ), + (TEXTNS,u'text-input') : ( + ), + (TEXTNS,u'time') : ( + ), + (TEXTNS,u'title') : ( + ), + (TEXTNS,u'toc-mark') : ( + ), + (TEXTNS,u'toc-mark-end') : ( + ), + (TEXTNS,u'toc-mark-start') : ( + ), +# allowed_children + (TEXTNS,u'tracked-changes') : ( + (TEXTNS,u'changed-region'), + ), + (TEXTNS,u'user-defined') : ( + ), + (TEXTNS,u'user-field-decl') : ( + ), + (TEXTNS,u'user-field-decls') : ( + (TEXTNS,u'user-field-decl'), + ), + (TEXTNS,u'user-field-get') : ( + ), + (TEXTNS,u'user-field-input') : ( + ), + (TEXTNS,u'user-index') : ( + (TEXTNS,u'index-body'), + (TEXTNS,u'user-index-source'), + ), + (TEXTNS,u'user-index-entry-template') : ( + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), +# allowed_children + (TEXTNS,u'user-index-mark') : ( + ), + (TEXTNS,u'user-index-mark-end') : ( + ), + (TEXTNS,u'user-index-mark-start') : ( + ), + (TEXTNS,u'user-index-source') : ( + (TEXTNS,u'index-source-styles'), + (TEXTNS,u'index-title-template'), + (TEXTNS,u'user-index-entry-template'), + ), + (TEXTNS,u'variable-decl') : ( + ), + (TEXTNS,u'variable-decls') : ( + (TEXTNS,u'variable-decl'), + ), + (TEXTNS,u'variable-get') : ( + ), + (TEXTNS,u'variable-input') : ( + ), + (TEXTNS,u'variable-set') : ( + ), + (TEXTNS,u'word-count') : ( + ), +} + +# +# List of elements that allows text nodes +# +allows_text = ( + (CONFIGNS,u'config-item'), + (DCNS,u'creator'), + (DCNS,u'date'), + (DCNS,u'description'), + (DCNS,u'language'), + (DCNS,u'subject'), + (DCNS,u'title'), +# Completes Dublin Core start +# (DCNS,'contributor'), +# (DCNS,'coverage'), +# (DCNS,'format'), +# (DCNS,'identifier'), +# (DCNS,'publisher'), +# (DCNS,'relation'), +# (DCNS,'rights'), +# (DCNS,'source'), +# (DCNS,'type'), +# Completes Dublin Core end + (FORMNS,u'item'), + (FORMNS,u'option'), + (MATHNS,u'math'), + (METANS,u'creation-date'), + (METANS,u'date-string'), + (METANS,u'editing-cycles'), + (METANS,u'editing-duration'), +# allows_text + (METANS,u'generator'), + (METANS,u'initial-creator'), + (METANS,u'keyword'), + (METANS,u'print-date'), + (METANS,u'printed-by'), + (METANS,u'user-defined'), + (NUMBERNS,u'currency-symbol'), + (NUMBERNS,u'embedded-text'), + (NUMBERNS,u'text'), + (OFFICENS,u'binary-data'), + (OFFICENS,u'script'), + (PRESENTATIONNS,u'date-time-decl'), + (PRESENTATIONNS,u'footer-decl'), + (PRESENTATIONNS,u'header-decl'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TABLENS,u'desc'), + (TABLENS,u'title'), + (TEXTNS,u'a'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'h'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), +# allows_text + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-title-template'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'linenumbering-separator'), + (TEXTNS,u'measure'), + (TEXTNS,u'meta'), + (TEXTNS,u'meta-field'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note-citation'), + (TEXTNS,u'note-continuation-notice-backward'), + (TEXTNS,u'note-continuation-notice-forward'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'number'), + (TEXTNS,u'object-count'), + (TEXTNS,u'p'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'print-time'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby-base'), + (TEXTNS,u'ruby-text'), +# allows_text + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), +# allows_text + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), +) + +# Only the elements with at least one required attribute is listed + +required_attributes = { + (ANIMNS,u'animate'): ( + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'animateColor'): ( + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'animateMotion'): ( + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'animateTransform'): ( + (SVGNS,u'type'), + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'command'): ( + (ANIMNS,u'command'), + ), + (ANIMNS,u'param'): ( + (ANIMNS,u'name'), + (ANIMNS,u'value'), + ), + (ANIMNS,u'set'): ( + (SMILNS,u'attributeName'), + ), +# required_attributes + (ANIMNS,u'transitionFilter'): ( + (SMILNS,u'type'), + ), + (CHARTNS,u'axis'): ( + (CHARTNS,u'dimension'), + ), + (CHARTNS,u'chart'): ( + (CHARTNS,u'class'), + ), +# required_attributes + (CHARTNS,u'error-indicator'): ( + (CHARTNS,u'dimension'), + ), + (CHARTNS,u'symbol-image'): ( + (XLINKNS,u'href'), + ), + (CONFIGNS,u'config-item'): ( + (CONFIGNS,u'type'), + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-indexed'): ( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-named'): ( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-set'): ( + (CONFIGNS,u'name'), + ), +# required_attributes + (NUMBERNS,u'boolean-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'currency-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'date-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'embedded-text'): ( + (NUMBERNS,u'position'), + ), + (NUMBERNS,u'number-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'percentage-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'text-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'time-style'): ( + (STYLENS,u'name'), + ), + (DR3DNS,u'extrude'): ( + (SVGNS,u'd'), + (SVGNS,u'viewBox'), + ), + (DR3DNS,u'light'): ( + (DR3DNS,u'direction'), + ), + (DR3DNS,u'rotate'): ( + (SVGNS,u'viewBox'), + (SVGNS,u'd'), + ), +# required_attributes + (DRAWNS,u'a'): ( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (DRAWNS,u'area-circle'): ( + (SVGNS,u'cy'), + (SVGNS,u'cx'), + (SVGNS,u'r'), + ), + (DRAWNS,u'area-polygon'): ( + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'points'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'area-rectangle'): ( + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'height'), + (SVGNS,u'width'), + ), +# required_attributes + (DRAWNS,u'connector'): ( + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'contour-path'): ( + (DRAWNS,u'recreate-on-edit'), + (SVGNS,u'viewBox'), + (SVGNS,u'd'), + ), + (DRAWNS,u'contour-polygon'): ( + (DRAWNS,u'points'), + (DRAWNS,u'recreate-on-edit'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'control'): ( + (DRAWNS,u'control'), + ), + (DRAWNS,u'fill-image'): ( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (DRAWNS,u'name'), + ), + (DRAWNS,u'floating-frame'): ( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (DRAWNS,u'glue-point'): ( + (SVGNS,u'y'), + (SVGNS,u'x'), + (DRAWNS,u'id'), + (DRAWNS,u'escape-direction'), + ), +# required_attributes + (DRAWNS,u'gradient'): ( + (DRAWNS,u'style'), + ), + (DRAWNS,u'handle'): ( + (DRAWNS,u'handle-position'), + ), + (DRAWNS,u'hatch'): ( + (DRAWNS,u'style'), + (DRAWNS,u'name'), + ), + (DRAWNS,u'layer'): ( + (DRAWNS,u'name'), + ), + (DRAWNS,u'line'): ( + (SVGNS,u'y1'), + (SVGNS,u'x2'), + (SVGNS,u'x1'), + (SVGNS,u'y2'), + ), + (DRAWNS,u'marker'): ( + (SVGNS,u'd'), + (DRAWNS,u'name'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'measure'): ( + (SVGNS,u'y1'), + (SVGNS,u'x2'), + (SVGNS,u'x1'), + (SVGNS,u'y2'), + ), + (DRAWNS,u'opacity'): ( + (DRAWNS,u'style'), + ), + (DRAWNS,u'page'): ( + (DRAWNS,u'master-page-name'), + ), + (DRAWNS,u'path'): ( + (SVGNS,u'd'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'plugin'): ( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (DRAWNS,u'polygon'): ( + (DRAWNS,u'points'), + (SVGNS,u'viewBox'), + ), +# required_attributes + (DRAWNS,u'polyline'): ( + (DRAWNS,u'points'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'regular-polygon'): ( + (DRAWNS,u'corners'), + ), + (DRAWNS,u'stroke-dash'): ( + (DRAWNS,u'name'), + ), + (FORMNS,u'button'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'checkbox'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'combobox'): ( + (XMLNS,u'id'), + ), +# required_attributes + (FORMNS,u'connection-resource'): ( + (XLINKNS,u'href'), + ), + (FORMNS,u'date'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'file'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'fixed-text'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'formatted-text'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'frame'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'generic-control'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'grid'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'hidden'): ( + (XMLNS,u'id'), + ), +# required_attributes + (FORMNS,u'image'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'image-frame'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'list-property'): ( + (FORMNS,u'property-name'), + ), + (FORMNS,u'list-value'): ( + (OFFICENS,u'string-value'), + ), + (FORMNS,u'listbox'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'number'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'password'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'property'): ( + (FORMNS,u'property-name'), + ), + (FORMNS,u'radio'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'text'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'textarea'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'time'): ( + (XMLNS,u'id'), + ), + (FORMNS,u'value-range'): ( + (XMLNS,u'id'), + ), + (MANIFESTNS,u'algorithm') : ( + (MANIFESTNS,u'algorithm-name'), + (MANIFESTNS,u'initialisation-vector'), + ), + (MANIFESTNS,u'encryption-data') : ( + (MANIFESTNS,u'checksum-type'), + (MANIFESTNS,u'checksum'), + ), + (MANIFESTNS,u'file-entry') : ( + (MANIFESTNS,u'full-path'), + (MANIFESTNS,u'media-type'), + ), + (MANIFESTNS,u'key-derivation') : ( + (MANIFESTNS,u'key-derivation-name'), + (MANIFESTNS,u'salt'), + (MANIFESTNS,u'iteration-count'), + ), +# required_attributes + (METANS,u'template'): ( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (METANS,u'user-defined'): ( + (METANS,u'name'), + ), +# required_attributes + (OFFICENS,u'annotation-end'): ( + (OFFICENS,u'name'), + ), + (OFFICENS,u'dde-source'): ( + (OFFICENS,u'dde-topic'), + (OFFICENS,u'dde-application'), + (OFFICENS,u'dde-item'), + ), + (OFFICENS,u'document'): ( + (OFFICENS,u'mimetype'), + (OFFICENS,u'version'), + ), +# required_attributes + (OFFICENS,u'document-content'): ( + (OFFICENS,u'version'), + ), +# required_attributes + (OFFICENS,u'document-meta'): ( + (OFFICENS,u'version'), + ), +# required_attributes + (OFFICENS,u'document-settings'): ( + (OFFICENS,u'version'), + ), +# required_attributes + (OFFICENS,u'document-styles'): ( + (OFFICENS,u'version'), + ), + (OFFICENS,u'script'): ( + (SCRIPTNS,u'language'), + ), + (PRESENTATIONNS,u'date-time-decl'): ( + (PRESENTATIONNS,u'source'), + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'dim'): ( + (DRAWNS,u'color'), + (DRAWNS,u'shape-id'), + ), +# required_attributes + (PRESENTATIONNS,u'event-listener'): ( + (PRESENTATIONNS,u'action'), + (SCRIPTNS,u'event-name'), + ), + (PRESENTATIONNS,u'footer-decl'): ( + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'header-decl'): ( + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'hide-shape'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'hide-text'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'placeholder'): ( + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'height'), + (PRESENTATIONNS,u'object'), + (SVGNS,u'width'), + ), + (PRESENTATIONNS,u'play'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'show'): ( + (PRESENTATIONNS,u'name'), + (PRESENTATIONNS,u'pages'), + ), + (PRESENTATIONNS,u'show-shape'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'show-text'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'sound'): ( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (SCRIPTNS,u'event-listener'): ( + (SCRIPTNS,u'language'), + (SCRIPTNS,u'event-name'), + ), + (STYLENS,u'column'): ( + (STYLENS,u'rel-width'), + ), +# required_attributes + (STYLENS,u'column-sep'): ( + (STYLENS,u'width'), + ), + (STYLENS,u'columns'): ( + (FONS,u'column-count'), + ), + (STYLENS,u'font-face'): ( + (STYLENS,u'name'), + ), + (STYLENS,u'handout-master'): ( + (STYLENS,u'page-layout-name'), + ), + (STYLENS,u'map'): ( + (STYLENS,u'apply-style-name'), + (STYLENS,u'condition'), + ), +# required_attributes + (STYLENS,u'list-level-label-alignment'): ( + (TEXTNS,u'label-followed-by'), + ), + (STYLENS,u'master-page'): ( + (STYLENS,u'page-layout-name'), + (STYLENS,u'name'), + ), + (STYLENS,u'page-layout'): ( + (STYLENS,u'name'), + ), + (STYLENS,u'presentation-page-layout'): ( + (STYLENS,u'name'), + ), + (STYLENS,u'style'): ( + (STYLENS,u'name'), + ), + (STYLENS,u'tab-stop'): ( + (STYLENS,u'position'), + ), + (SVGNS,u'definition-src'): ( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (SVGNS,u'font-face-uri'): ( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (SVGNS,u'linearGradient'): ( + (DRAWNS,u'name'), + ), + (SVGNS,u'radialGradient'): ( + (DRAWNS,u'name'), + ), + (SVGNS,u'stop'): ( + (SVGNS,u'offset'), + ), +# required_attributes + (TABLENS,u'background'): ( + (TABLENS,u'style-name'), + ), + (TABLENS,u'body'): ( + (TABLENS,u'style-name'), + ), + (TABLENS,u'cell-address'): ( + (TABLENS,u'column'), + (TABLENS,u'table'), + (TABLENS,u'row'), + ), + (TABLENS,u'cell-content-change'): ( + (TABLENS,u'id'), + ), + (TABLENS,u'cell-range-source'): ( + (TABLENS,u'last-row-spanned'), + (TABLENS,u'last-column-spanned'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (TABLENS,u'name'), + ), + (TABLENS,u'consolidation'): ( + (TABLENS,u'function'), + (TABLENS,u'source-cell-range-addresses'), + (TABLENS,u'target-cell-address'), + ), + (TABLENS,u'content-validation'): ( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-display-info'): ( + (TABLENS,u'member-count'), + (TABLENS,u'data-field'), + (TABLENS,u'enabled'), + (TABLENS,u'display-member-mode'), + ), +# required_attributes + (TABLENS,u'data-pilot-field'): ( + (TABLENS,u'source-field-name'), + ), + (TABLENS,u'data-pilot-field-reference'): ( + (TABLENS,u'field-name'), + (TABLENS,u'type'), + ), + (TABLENS,u'data-pilot-group'): ( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-group-member'): ( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-groups'): ( + (TABLENS,u'source-field-name'), + (TABLENS,u'step'), + (TABLENS,u'grouped-by'), + ), + (TABLENS,u'data-pilot-layout-info'): ( + (TABLENS,u'add-empty-lines'), + (TABLENS,u'layout-mode'), + ), + (TABLENS,u'data-pilot-member'): ( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-sort-info'): ( + (TABLENS,u'order'), + ), + (TABLENS,u'data-pilot-subtotal'): ( + (TABLENS,u'function'), + ), + (TABLENS,u'data-pilot-table'): ( + (TABLENS,u'target-range-address'), + (TABLENS,u'name'), + ), + (TABLENS,u'database-range'): ( + (TABLENS,u'target-range-address'), + ), +# required_attributes + (TABLENS,u'database-source-query'): ( + (TABLENS,u'query-name'), + (TABLENS,u'database-name'), + ), + (TABLENS,u'database-source-sql'): ( + (TABLENS,u'database-name'), + (TABLENS,u'sql-statement'), + ), + (TABLENS,u'database-source-table'): ( + (TABLENS,u'database-table-name'), + (TABLENS,u'database-name'), + ), + (TABLENS,u'deletion'): ( + (TABLENS,u'position'), + (TABLENS,u'type'), + (TABLENS,u'id'), + ), + (TABLENS,u'dependency'): ( + (TABLENS,u'id'), + ), +# required_attributes + (TABLENS,u'even-columns'): ( + (TABLENS,u'style-name'), + ), + (TABLENS,u'even-rows'): ( + (TABLENS,u'style-name'), + ), + (TABLENS,u'filter-condition'): ( + (TABLENS,u'operator'), + (TABLENS,u'field-number'), + (TABLENS,u'value'), + ), +# required_attributes + (TABLENS,u'filter-set-item'): ( + (TABLENS,u'value'), + ), + (TABLENS,u'first-column'): ( + (TABLENS,u'style-name'), + ), + (TABLENS,u'first-row'): ( + (TABLENS,u'style-name'), + ), + (TABLENS,u'insertion'): ( + (TABLENS,u'position'), + (TABLENS,u'type'), + (TABLENS,u'id'), + ), + (TABLENS,u'insertion-cut-off'): ( + (TABLENS,u'position'), + (TABLENS,u'id'), + ), +# required_attributes + (TABLENS,u'label-range'): ( + (TABLENS,u'label-cell-range-address'), + (TABLENS,u'data-cell-range-address'), + (TABLENS,u'orientation'), + ), + (TABLENS,u'last-column'): ( + (TABLENS,u'style-name'), + ), + (TABLENS,u'last-row'): ( + (TABLENS,u'style-name'), + ), + (TABLENS,u'movement'): ( + (TABLENS,u'id'), + ), + (TABLENS,u'named-expression'): ( + (TABLENS,u'expression'), + (TABLENS,u'name'), + ), + (TABLENS,u'named-range'): ( + (TABLENS,u'name'), + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'odd-columns'): ( + (TABLENS,u'style-name'), + ), + (TABLENS,u'odd-rows'): ( + (TABLENS,u'style-name'), + ), + (TABLENS,u'operation'): ( + (TABLENS,u'index'), + (TABLENS,u'name'), + ), +# required_attributes + (TABLENS,u'scenario'): ( + (TABLENS,u'is-active'), + (TABLENS,u'scenario-ranges'), + ), + (TABLENS,u'sort-by'): ( + (TABLENS,u'field-number'), + ), + (TABLENS,u'source-cell-range'): ( + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'source-service'): ( + (TABLENS,u'source-name'), + (TABLENS,u'object-name'), + (TABLENS,u'name'), + ), + (TABLENS,u'subtotal-field'): ( + (TABLENS,u'function'), + (TABLENS,u'field-number'), + ), + (TABLENS,u'subtotal-rule'): ( + (TABLENS,u'group-by-field-number'), + ), + (TABLENS,u'table-source'): ( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (TABLENS,u'table-template'): ( +# (TABLENS,u'last-row-end-column'), # Deprecated +# (TABLENS,u'first-row-end-column'), # Deprecated + (TABLENS,u'name'), +# (TABLENS,u'last-row-start-column'), # Deprecated +# (TABLENS,u'first-row-start-column'), # Deprecated + ), + (TEXTNS,u'a'): ( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), +# required_attributes + (TEXTNS,u'alphabetical-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'alphabetical-index-auto-mark-file'): ( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (TEXTNS,u'alphabetical-index-entry-template'): ( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'alphabetical-index-mark'): ( + (TEXTNS,u'string-value'), + ), + (TEXTNS,u'alphabetical-index-mark-end'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'alphabetical-index-mark-start'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'bibliography'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'bibliography-entry-template'): ( + (TEXTNS,u'style-name'), + (TEXTNS,u'bibliography-type'), + ), + (TEXTNS,u'bibliography-mark'): ( + (TEXTNS,u'bibliography-type'), + ), + (TEXTNS,u'bookmark'): ( + (TEXTNS,u'name'), + ), +# required_attributes + (TEXTNS,u'bookmark-end'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'bookmark-start'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'change'): ( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'change-end'): ( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'change-start'): ( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'changed-region'): ( + (XMLNS,u'id'), + ), + (TEXTNS,u'chapter'): ( + (TEXTNS,u'display'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'conditional-text'): ( + (TEXTNS,u'string-value-if-true'), + (TEXTNS,u'string-value-if-false'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'database-display'): ( + (TEXTNS,u'column-name'), + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'database-name'): ( + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'database-next'): ( + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'database-row-number'): ( + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'database-row-select'): ( + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'dde-connection'): ( + (TEXTNS,u'connection-name'), + ), +# required_attributes + (TEXTNS,u'dde-connection-decl'): ( + (OFFICENS,u'dde-topic'), + (OFFICENS,u'dde-application'), + (OFFICENS,u'name'), + (OFFICENS,u'dde-item'), + ), + (TEXTNS,u'h'): ( + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'hidden-paragraph'): ( + (TEXTNS,u'condition'), + ), + (TEXTNS,u'hidden-text'): ( + (TEXTNS,u'string-value'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'illustration-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'illustration-index-entry-template'): ( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-bibliography'): ( + (TEXTNS,u'bibliography-data-field'), + ), + (TEXTNS,u'index-source-style'): ( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-source-styles'): ( + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'index-title'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'list-level-style-bullet'): ( + (TEXTNS,u'bullet-char'), + (TEXTNS,u'level'), + ), + (TEXTNS,u'list-level-style-image'): ( + (TEXTNS,u'level'), + ), + (TEXTNS,u'list-level-style-number'): ( + (TEXTNS,u'level'), + ), + (TEXTNS,u'list-style'): ( + (STYLENS,u'name'), + ), + (TEXTNS,u'meta-field'): ( + (XMLNS,u'id'), + ), +# required_attributes + (TEXTNS,u'measure'): ( + (TEXTNS,u'kind'), + ), + (TEXTNS,u'note'): ( + (TEXTNS,u'note-class'), + ), + (TEXTNS,u'note-ref'): ( + (TEXTNS,u'note-class'), + ), + (TEXTNS,u'notes-configuration'): ( + (TEXTNS,u'note-class'), + ), +# required_attributes + (TEXTNS,u'numbered-paragraph'): ( + (TEXTNS,u'list-id'), + ), + (TEXTNS,u'object-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'object-index-entry-template'): ( + (TEXTNS,u'style-name'), + ), +# required_attributes + (TEXTNS,u'outline-style'): ( + (STYLENS,u'name'), + ), + (TEXTNS,u'outline-level-style'): ( + (TEXTNS,u'level'), + ), + (TEXTNS,u'page'): ( + (TEXTNS,u'master-page-name'), + ), + (TEXTNS,u'page-continuation'): ( + (TEXTNS,u'select-page'), + ), + (TEXTNS,u'placeholder'): ( + (TEXTNS,u'placeholder-type'), + ), + (TEXTNS,u'reference-mark'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'reference-mark-end'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'reference-mark-start'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'section'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'sequence'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'sequence-decl'): ( + (TEXTNS,u'display-outline-level'), + (TEXTNS,u'name'), + ), +# required_attributes + (TEXTNS,u'sort-key'): ( + (TEXTNS,u'key'), + ), + (TEXTNS,u'table-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'table-index-entry-template'): ( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'table-of-content'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'table-of-content-entry-template'): ( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'toc-mark'): ( + (TEXTNS,u'string-value'), + ), + (TEXTNS,u'toc-mark-end'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'toc-mark-start'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'user-defined'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-field-decl'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-field-get'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-field-input'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-index-entry-template'): ( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), +# required_attributes + (TEXTNS,u'user-index-mark'): ( + (TEXTNS,u'index-name'), + (TEXTNS,u'string-value'), + ), + (TEXTNS,u'user-index-mark-end'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'user-index-mark-start'): ( + (TEXTNS,u'index-name'), + (TEXTNS,u'id'), + ), + (TEXTNS,u'user-index-source'): ( + (TEXTNS,u'index-name'), + ), + (TEXTNS,u'variable-decl'): ( + (TEXTNS,u'name'), + (OFFICENS,u'value-type'), + ), + (TEXTNS,u'variable-get'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'variable-input'): ( + (TEXTNS,u'name'), + (OFFICENS,u'value-type'), + ), + (TEXTNS,u'variable-set'): ( + (TEXTNS,u'name'), + ), +} + +# Empty list means the element has no allowed attributes +# None means anything goes + +allowed_attributes = { + (DCNS,u'creator'):( + ), + (DCNS,u'date'):( + ), + (DCNS,u'description'):( + ), + (DCNS,u'language'):( + ), + (DCNS,u'subject'):( + ), + (DCNS,u'title'):( + ), +# Completes Dublin Core start +# (DCNS,'contributor') : ( +# ), +# (DCNS,'coverage') : ( +# ), +# (DCNS,'format') : ( +# ), +# (DCNS,'identifier') : ( +# ), +# (DCNS,'publisher') : ( +# ), +# (DCNS,'relation') : ( +# ), +# (DCNS,'rights') : ( +# ), +# (DCNS,'source') : ( +# ), +# (DCNS,'type') : ( +# ), +# Completes Dublin Core end + (MATHNS,u'math'): None, + (XFORMSNS,u'model'): None, +# allowed_attributes + (ANIMNS,u'animate'):( + (ANIMNS,u'formula'), + (ANIMNS,u'sub-item'), + (SMILNS,u'accelerate'), + (SMILNS,u'accumulate'), + (SMILNS,u'additive'), + (SMILNS,u'attributeName'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'by'), + (SMILNS,u'calcMode'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'from'), + (SMILNS,u'keySplines'), + (SMILNS,u'keyTimes'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'targetElement'), + (SMILNS,u'to'), + (SMILNS,u'values'), + ), +# allowed_attributes + (ANIMNS,u'animateColor'):( + (ANIMNS,u'color-interpolation'), + (ANIMNS,u'color-interpolation-direction'), + (ANIMNS,u'formula'), + (ANIMNS,u'sub-item'), + (SMILNS,u'accelerate'), + (SMILNS,u'accumulate'), + (SMILNS,u'additive'), + (SMILNS,u'attributeName'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'by'), + (SMILNS,u'calcMode'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'from'), + (SMILNS,u'keySplines'), + (SMILNS,u'keyTimes'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'targetElement'), + (SMILNS,u'to'), + (SMILNS,u'values'), + ), +# allowed_attributes + (ANIMNS,u'animateMotion'):( + (ANIMNS,u'formula'), + (ANIMNS,u'sub-item'), + (SMILNS,u'accelerate'), + (SMILNS,u'accumulate'), + (SMILNS,u'additive'), + (SMILNS,u'attributeName'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'by'), + (SMILNS,u'calcMode'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'from'), + (SMILNS,u'keySplines'), + (SMILNS,u'keyTimes'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'targetElement'), + (SMILNS,u'to'), + (SMILNS,u'values'), + (SVGNS,u'origin'), + (SVGNS,u'path'), + ), +# allowed_attributes + (ANIMNS,u'animateTransform'):( + (ANIMNS,u'formula'), + (ANIMNS,u'sub-item'), + (SMILNS,u'accelerate'), + (SMILNS,u'accumulate'), + (SMILNS,u'additive'), + (SMILNS,u'attributeName'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'by'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'from'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'targetElement'), + (SMILNS,u'to'), + (SMILNS,u'values'), + (SVGNS,u'type'), + ), +# allowed_attributes + (ANIMNS,u'audio'):( + (ANIMNS,u'audio-level'), + (ANIMNS,u'id'), + (PRESENTATIONNS,u'group-id'), + (PRESENTATIONNS,u'master-element'), + (PRESENTATIONNS,u'node-type'), + (PRESENTATIONNS,u'preset-class'), + (PRESENTATIONNS,u'preset-id'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'begin'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (XLINKNS,u'href'), + (XMLNS,u'id'), + ), + (ANIMNS,u'command'):( + (PRESENTATIONNS,u'node-type'), + (SMILNS,u'begin'), + (SMILNS,u'end'), + (PRESENTATIONNS,u'group-id'), + (PRESENTATIONNS,u'preset-class'), + (PRESENTATIONNS,u'preset-id'), + (ANIMNS,u'sub-item'), + (ANIMNS,u'command'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'targetElement'), + (ANIMNS,u'id'), + (PRESENTATIONNS,u'master-element'), + (XMLNS,u'id'), + ), +# allowed_attributes + (ANIMNS,u'iterate'):( + (ANIMNS,u'id'), + (ANIMNS,u'iterate-interval'), + (ANIMNS,u'iterate-type'), + (ANIMNS,u'sub-item'), + (PRESENTATIONNS,u'group-id'), + (PRESENTATIONNS,u'master-element'), + (PRESENTATIONNS,u'node-type'), + (PRESENTATIONNS,u'preset-class'), + (PRESENTATIONNS,u'preset-id'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'accelerate'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'endsync'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'targetElement'), + (XMLNS,u'id'), + ), + (ANIMNS,u'par'):( + (PRESENTATIONNS,u'node-type'), + (SMILNS,u'decelerate'), + (SMILNS,u'begin'), + (SMILNS,u'end'), + (PRESENTATIONNS,u'group-id'), + (SMILNS,u'accelerate'), + (SMILNS,u'repeatDur'), + (SMILNS,u'repeatCount'), + (SMILNS,u'autoReverse'), + (PRESENTATIONNS,u'preset-class'), + (SMILNS,u'fillDefault'), + (PRESENTATIONNS,u'preset-id'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'restartDefault'), + (SMILNS,u'endsync'), + (SMILNS,u'dur'), + (SMILNS,u'fill'), + (ANIMNS,u'id'), + (SMILNS,u'restart'), + (PRESENTATIONNS,u'master-element'), + (XMLNS,u'id'), + ), +# allowed_attributes + (ANIMNS,u'param'):( + (ANIMNS,u'name'), + (ANIMNS,u'value'), + ), + (ANIMNS,u'seq'):( + (ANIMNS,u'id'), + (PRESENTATIONNS,u'group-id'), + (PRESENTATIONNS,u'master-element'), + (PRESENTATIONNS,u'node-type'), + (PRESENTATIONNS,u'preset-class'), + (PRESENTATIONNS,u'preset-id'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'accelerate'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'endsync'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (XMLNS,u'id'), + ), + (ANIMNS,u'set'):( + (ANIMNS,u'sub-item'), + (SMILNS,u'accelerate'), + (SMILNS,u'accumulate'), + (SMILNS,u'autoReverse'), + (SMILNS,u'additive'), + (SMILNS,u'attributeName'), + (SMILNS,u'begin'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'targetElement'), + (SMILNS,u'to'), + + ), +# allowed_attributes + (ANIMNS,u'transitionFilter'):( + (ANIMNS,u'formula'), + (ANIMNS,u'sub-item'), + (SMILNS,u'accelerate'), + (SMILNS,u'accumulate'), + (SMILNS,u'additive'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'by'), + (SMILNS,u'calcMode'), + (SMILNS,u'decelerate'), + (SMILNS,u'direction'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fadeColor'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'from'), + (SMILNS,u'mode'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'subtype'), + (SMILNS,u'targetElement'), + (SMILNS,u'to'), + (SMILNS,u'type'), + (SMILNS,u'values'), + + ), +# allowed_attributes + (CHARTNS,u'axis'):( + (CHARTNS,u'style-name'), + (CHARTNS,u'dimension'), + (CHARTNS,u'name'), + ), + (CHARTNS,u'categories'):( + (TABLENS,u'cell-range-address'), + ), + (CHARTNS,u'chart'):( + (CHARTNS,u'class'), + (CHARTNS,u'column-mapping'), + (CHARTNS,u'row-mapping'), + (CHARTNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (XMLNS,u'id'), + ), + (CHARTNS,u'data-label'):( + (CHARTNS,u'style-name'), + (SVGNS,u'x'), + (SVGNS,u'y'), + ), + (CHARTNS,u'data-point'):( + (CHARTNS,u'repeated'), + (CHARTNS,u'style-name'), + (XMLNS,u'id'), + ), + (CHARTNS,u'domain'):( + (TABLENS,u'cell-range-address'), + ), +# allowed_attributes + (CHARTNS,u'equation'):( + (CHARTNS,u'automatic-content'), + (CHARTNS,u'display-equation'), + (CHARTNS,u'display-r-square'), + (CHARTNS,u'style-name'), + (SVGNS,u'x'), + (SVGNS,u'y'), + ), + (CHARTNS,u'error-indicator'):( + (CHARTNS,u'dimension'), + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'floor'):( + (SVGNS,u'width'), + (CHARTNS,u'style-name'), + ), +# allowed_attributes + (CHARTNS,u'footer'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'cell-range'), + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'grid'):( + (CHARTNS,u'style-name'), + (CHARTNS,u'class'), + ), +# allowed_attributes + (CHARTNS,u'label-separator'):( + ), + (CHARTNS,u'legend'):( + (CHARTNS,u'legend-align'), + (STYLENS,u'legend-expansion-aspect-ratio'), + (STYLENS,u'legend-expansion'), + (CHARTNS,u'legend-position'), + (CHARTNS,u'style-name'), + (SVGNS,u'y'), + (SVGNS,u'x'), + ), + (CHARTNS,u'mean-value'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'plot-area'):( + (CHARTNS,u'data-source-has-labels'), + (CHARTNS,u'style-name'), + (DR3DNS,u'ambient-color'), + (DR3DNS,u'distance'), + (DR3DNS,u'focal-length'), + (DR3DNS,u'lighting-mode'), + (DR3DNS,u'projection'), + (DR3DNS,u'shade-mode'), + (DR3DNS,u'shadow-slant'), + (DR3DNS,u'transform'), + (DR3DNS,u'vpn'), + (DR3DNS,u'vrp'), + (DR3DNS,u'vup'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'cell-range-address'), + (XMLNS,u'id'), + ), + (CHARTNS,u'regression-curve'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'series'):( + (CHARTNS,u'style-name'), + (CHARTNS,u'attached-axis'), + (CHARTNS,u'values-cell-range-address'), + (CHARTNS,u'label-cell-address'), + (CHARTNS,u'class'), + (XMLNS,u'id'), + ), + (CHARTNS,u'stock-gain-marker'):( + (CHARTNS,u'style-name'), + ), +# allowed_attributes + (CHARTNS,u'stock-loss-marker'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'stock-range-line'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'subtitle'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'cell-range'), + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'symbol-image'):( + (XLINKNS,u'href'), + ), + (CHARTNS,u'title'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'cell-range'), + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'wall'):( + (SVGNS,u'width'), + (CHARTNS,u'style-name'), + ), + (CONFIGNS,u'config-item'):( + (CONFIGNS,u'type'), + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-entry'):( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-indexed'):( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-named'):( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-set'):( + (CONFIGNS,u'name'), + ), +# allowed_attributes + (NUMBERNS,u'am-pm'):( + ), + (NUMBERNS,u'boolean'):( + ), + (NUMBERNS,u'boolean-style'):( + (NUMBERNS,u'country'), + (NUMBERNS,u'language'), + (NUMBERNS,u'rfc-language-tag'), + (NUMBERNS,u'script'), + (NUMBERNS,u'title'), + (NUMBERNS,u'transliteration-country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-language'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'display-name'), + (STYLENS,u'name'), + (STYLENS,u'volatile'), + ), + (NUMBERNS,u'currency-style'):( + (NUMBERNS,u'rfc-language-tag'), + (NUMBERNS,u'script'), + (NUMBERNS,u'automatic-order'), + (NUMBERNS,u'country'), + (NUMBERNS,u'language'), + (NUMBERNS,u'rfc-language-tag'), + (NUMBERNS,u'script'), + (NUMBERNS,u'title'), + (NUMBERNS,u'transliteration-country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-language'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'display-name'), + (STYLENS,u'name'), + (STYLENS,u'volatile'), + ), + (NUMBERNS,u'currency-symbol'):( + (NUMBERNS,u'country'), + (NUMBERNS,u'language'), + (NUMBERNS,u'rfc-language-tag'), + (NUMBERNS,u'script'), + ), +# allowed_attributes + (NUMBERNS,u'date-style'):( + (NUMBERNS,u'automatic-order'), + (NUMBERNS,u'country'), + (NUMBERNS,u'format-source'), + (NUMBERNS,u'language'), + (NUMBERNS,u'rfc-language-tag'), + (NUMBERNS,u'script'), + (NUMBERNS,u'title'), + (NUMBERNS,u'transliteration-country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-language'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'display-name'), + (STYLENS,u'name'), + (STYLENS,u'volatile'), + ), + (NUMBERNS,u'day'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'day-of-week'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'embedded-text'):( + (NUMBERNS,u'position'), + ), + (NUMBERNS,u'era'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'fraction'):( + (NUMBERNS,u'grouping'), + (NUMBERNS,u'min-denominator-digits'), + (NUMBERNS,u'min-numerator-digits'), + (NUMBERNS,u'min-integer-digits'), + (NUMBERNS,u'denominator-value'), + ), + (NUMBERNS,u'hours'):( + (NUMBERNS,u'style'), + ), +# allowed_attributes + (NUMBERNS,u'minutes'):( + (NUMBERNS,u'style'), + ), + (NUMBERNS,u'month'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + (NUMBERNS,u'possessive-form'), + (NUMBERNS,u'textual'), + ), + (NUMBERNS,u'number'):( + (NUMBERNS,u'display-factor'), + (NUMBERNS,u'decimal-places'), + (NUMBERNS,u'decimal-replacement'), + (NUMBERNS,u'min-integer-digits'), + (NUMBERNS,u'grouping'), + ), + (NUMBERNS,u'number-style'):( + (NUMBERNS,u'rfc-language-tag'), + (NUMBERNS,u'script'), + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (STYLENS,u'display-name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + ), +# allowed_attributes + (NUMBERNS,u'percentage-style'):( + (NUMBERNS,u'country'), + (NUMBERNS,u'language'), + (NUMBERNS,u'rfc-language-tag'), + (NUMBERNS,u'script'), + (NUMBERNS,u'title'), + (NUMBERNS,u'transliteration-country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-language'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'display-name'), + (STYLENS,u'name'), + (STYLENS,u'volatile'), + ), + (NUMBERNS,u'quarter'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'scientific-number'):( + (NUMBERNS,u'min-exponent-digits'), + (NUMBERNS,u'decimal-places'), + (NUMBERNS,u'min-integer-digits'), + (NUMBERNS,u'grouping'), + ), + (NUMBERNS,u'seconds'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'decimal-places'), + ), + (NUMBERNS,u'text'):( + ), + (NUMBERNS,u'text-content'):( + ), + (NUMBERNS,u'text-style'):( + (NUMBERNS,u'country'), + (NUMBERNS,u'language'), + (NUMBERNS,u'rfc-language-tag'), + (NUMBERNS,u'script'), + (NUMBERNS,u'title'), + (NUMBERNS,u'transliteration-country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-language'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'display-name'), + (STYLENS,u'name'), + (STYLENS,u'volatile'), + ), + (NUMBERNS,u'time-style'):( + (NUMBERNS,u'country'), + (NUMBERNS,u'format-source'), + (NUMBERNS,u'language'), + (NUMBERNS,u'rfc-language-tag'), + (NUMBERNS,u'script'), + (NUMBERNS,u'title'), + (NUMBERNS,u'transliteration-country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-language'), + (NUMBERNS,u'transliteration-style'), + (NUMBERNS,u'truncate-on-overflow'), + (STYLENS,u'display-name'), + (STYLENS,u'name'), + (STYLENS,u'volatile'), + ), + (NUMBERNS,u'week-of-year'):( + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'year'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (DR3DNS,u'cube'):( + (DR3DNS,u'min-edge'), + (DR3DNS,u'max-edge'), + (DRAWNS,u'layer'), + (DR3DNS,u'transform'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'id'), + (XMLNS,u'id'), + ), + (DR3DNS,u'extrude'):( + (DRAWNS,u'layer'), + (SVGNS,u'd'), + (DR3DNS,u'transform'), + (SVGNS,u'viewBox'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'id'), + (XMLNS,u'id'), + ), + (DR3DNS,u'light'):( + (DR3DNS,u'diffuse-color'), + (DR3DNS,u'direction'), + (DR3DNS,u'specular'), + (DR3DNS,u'enabled'), + ), + (DR3DNS,u'rotate'):( + (DRAWNS,u'layer'), + (SVGNS,u'd'), + (DR3DNS,u'transform'), + (SVGNS,u'viewBox'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'id'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DR3DNS,u'scene'):( + (DR3DNS,u'ambient-color'), + (DR3DNS,u'distance'), + (DR3DNS,u'focal-length'), + (DR3DNS,u'lighting-mode'), + (DR3DNS,u'projection'), + (DR3DNS,u'shade-mode'), + (DR3DNS,u'shadow-slant'), + (DR3DNS,u'transform'), + (DR3DNS,u'vpn'), + (DR3DNS,u'vrp'), + (DR3DNS,u'vup'), + (DRAWNS,u'id'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'layer'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DR3DNS,u'sphere'):( + (DRAWNS,u'layer'), + (DR3DNS,u'center'), + (DR3DNS,u'transform'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'id'), + (DR3DNS,u'size'), + (XMLNS,u'id'), + ), + (DRAWNS,u'a'):( + (OFFICENS,u'name'), + (OFFICENS,u'server-map'), + (OFFICENS,u'target-frame-name'), + (OFFICENS,u'title'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'show'), + (XLINKNS,u'type'), + (XMLNS,u'id'), + ), + (DRAWNS,u'applet'):( + (DRAWNS,u'code'), + (XLINKNS,u'show'), + (DRAWNS,u'object'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (DRAWNS,u'archive'), + (DRAWNS,u'may-script'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DRAWNS,u'area-circle'):( + (OFFICENS,u'name'), + (XLINKNS,u'show'), + (SVGNS,u'cx'), + (XLINKNS,u'type'), + (DRAWNS,u'nohref'), + (SVGNS,u'cy'), + (XLINKNS,u'href'), + (SVGNS,u'r'), + (OFFICENS,u'target-frame-name'), + ), + (DRAWNS,u'area-polygon'):( + (OFFICENS,u'name'), + (XLINKNS,u'show'), + (XLINKNS,u'type'), + (SVGNS,u'height'), + (DRAWNS,u'nohref'), + (SVGNS,u'width'), + (XLINKNS,u'href'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (OFFICENS,u'target-frame-name'), + (SVGNS,u'viewBox'), + (DRAWNS,u'points'), + ), + (DRAWNS,u'area-rectangle'):( + (OFFICENS,u'name'), + (XLINKNS,u'show'), + (XLINKNS,u'type'), + (SVGNS,u'height'), + (DRAWNS,u'nohref'), + (SVGNS,u'width'), + (XLINKNS,u'href'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (OFFICENS,u'target-frame-name'), + ), + (DRAWNS,u'caption'):( + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (DRAWNS,u'caption-id'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'caption-point-y'), + (DRAWNS,u'caption-point-x'), + (DRAWNS,u'transform'), + (TABLENS,u'end-y'), + (DRAWNS,u'corner-radius'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'height'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DRAWNS,u'circle'):( + (DRAWNS,u'end-angle'), + (DRAWNS,u'id'), + (DRAWNS,u'kind'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'start-angle'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'cx'), + (SVGNS,u'cy'), + (SVGNS,u'height'), + (SVGNS,u'r'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DRAWNS,u'connector'):( + (DRAWNS,u'caption-id'), + (DRAWNS,u'class-names'), + (DRAWNS,u'end-glue-point'), + (DRAWNS,u'end-shape'), + (DRAWNS,u'id'), + (DRAWNS,u'layer'), + (DRAWNS,u'line-skew'), + (DRAWNS,u'name'), + (DRAWNS,u'start-glue-point'), + (DRAWNS,u'start-shape'), + (DRAWNS,u'style-name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'type'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'd'), + (SVGNS,u'viewBox'), + (SVGNS,u'x1'), + (SVGNS,u'x2'), + (SVGNS,u'y1'), + (SVGNS,u'y2'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DRAWNS,u'contour-path'):( + (SVGNS,u'd'), + (SVGNS,u'width'), + (DRAWNS,u'recreate-on-edit'), + (SVGNS,u'viewBox'), + (SVGNS,u'height'), + ), + (DRAWNS,u'contour-polygon'):( + (SVGNS,u'width'), + (DRAWNS,u'points'), + (DRAWNS,u'recreate-on-edit'), + (SVGNS,u'viewBox'), + (SVGNS,u'height'), + ), + (DRAWNS,u'control'):( + (DRAWNS,u'control'), + (DRAWNS,u'layer'), + (DRAWNS,u'caption-id'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (TABLENS,u'table-background'), + (DRAWNS,u'transform'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), + (DRAWNS,u'custom-shape'):( + (DRAWNS,u'engine'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (TABLENS,u'table-background'), + (DRAWNS,u'transform'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (DRAWNS,u'data'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DRAWNS,u'ellipse'):( + (DRAWNS,u'layer'), + (DRAWNS,u'start-angle'), + (SVGNS,u'cy'), + (SVGNS,u'cx'), + (TABLENS,u'table-background'), + (TABLENS,u'end-cell-address'), + (SVGNS,u'rx'), + (DRAWNS,u'transform'), + (DRAWNS,u'id'), + (SVGNS,u'width'), + (TABLENS,u'end-y'), + (TABLENS,u'end-x'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'end-angle'), + (DRAWNS,u'z-index'), + (DRAWNS,u'caption-id'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (TEXTNS,u'anchor-type'), + (SVGNS,u'ry'), + (DRAWNS,u'kind'), + (DRAWNS,u'name'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (DRAWNS,u'text-style-name'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DRAWNS,u'enhanced-geometry'):( + (DR3DNS,u'projection'), + (DR3DNS,u'shade-mode'), + (DRAWNS,u'concentric-gradient-fill-allowed'), + (DRAWNS,u'enhanced-path'), + (DRAWNS,u'extrusion'), + (DRAWNS,u'extrusion-allowed'), + (DRAWNS,u'extrusion-brightness'), + (DRAWNS,u'extrusion-color'), + (DRAWNS,u'extrusion-depth'), + (DRAWNS,u'extrusion-diffusion'), + (DRAWNS,u'extrusion-first-light-direction'), + (DRAWNS,u'extrusion-first-light-harsh'), + (DRAWNS,u'extrusion-first-light-level'), + (DRAWNS,u'extrusion-light-face'), + (DRAWNS,u'extrusion-metal'), + (DRAWNS,u'extrusion-number-of-line-segments'), + (DRAWNS,u'extrusion-origin'), + (DRAWNS,u'extrusion-rotation-angle'), + (DRAWNS,u'extrusion-rotation-center'), + (DRAWNS,u'extrusion-second-light-direction'), + (DRAWNS,u'extrusion-second-light-harsh'), + (DRAWNS,u'extrusion-second-light-level'), + (DRAWNS,u'extrusion-shininess'), + (DRAWNS,u'extrusion-skew'), + (DRAWNS,u'extrusion-specularity'), + (DRAWNS,u'extrusion-viewpoint'), + (DRAWNS,u'glue-point-leaving-directions'), + (DRAWNS,u'glue-points'), + (DRAWNS,u'glue-point-type'), + (DRAWNS,u'mirror-horizontal'), + (DRAWNS,u'mirror-vertical'), + (DRAWNS,u'modifiers'), + (DRAWNS,u'path-stretchpoint-x'), + (DRAWNS,u'path-stretchpoint-y'), + (DRAWNS,u'text-areas'), + (DRAWNS,u'text-path'), + (DRAWNS,u'text-path-allowed'), + (DRAWNS,u'text-path-mode'), + (DRAWNS,u'text-path-same-letter-heights'), + (DRAWNS,u'text-path-scale'), + (DRAWNS,u'text-rotate-angle'), + (DRAWNS,u'type'), + (SVGNS,u'viewBox'), + ), +# allowed_attributes + (DRAWNS,u'equation'):( + (DRAWNS,u'formula'), + (DRAWNS,u'name'), + ), + (DRAWNS,u'fill-image'):( + (DRAWNS,u'name'), + (XLINKNS,u'show'), + (XLINKNS,u'actuate'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (XLINKNS,u'href'), + (DRAWNS,u'display-name'), + (XLINKNS,u'type'), + ), + (DRAWNS,u'floating-frame'):( + (XLINKNS,u'href'), + (XLINKNS,u'actuate'), + (DRAWNS,u'frame-name'), + (XLINKNS,u'type'), + (XLINKNS,u'show'), + (XMLNS,u'id'), + ), + (DRAWNS,u'frame'):( + (DRAWNS,u'copy-of'), + (DRAWNS,u'id'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'class-names'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'style-name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'placeholder'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'user-transformed'), + (STYLENS,u'rel-height'), + (STYLENS,u'rel-width'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DRAWNS,u'g'):( + (DRAWNS,u'id'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'name'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), + (DRAWNS,u'glue-point'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (DRAWNS,u'align'), + (DRAWNS,u'id'), + (DRAWNS,u'escape-direction'), + ), + (DRAWNS,u'gradient'):( + (DRAWNS,u'style'), + (DRAWNS,u'angle'), + (DRAWNS,u'name'), + (DRAWNS,u'end-color'), + (DRAWNS,u'start-color'), + (DRAWNS,u'cy'), + (DRAWNS,u'cx'), + (DRAWNS,u'display-name'), + (DRAWNS,u'border'), + (DRAWNS,u'end-intensity'), + (DRAWNS,u'start-intensity'), + ), + (DRAWNS,u'handle'):( + (DRAWNS,u'handle-radius-range-minimum'), + (DRAWNS,u'handle-switched'), + (DRAWNS,u'handle-range-y-maximum'), + (DRAWNS,u'handle-mirror-horizontal'), + (DRAWNS,u'handle-range-x-maximum'), + (DRAWNS,u'handle-mirror-vertical'), + (DRAWNS,u'handle-range-y-minimum'), + (DRAWNS,u'handle-radius-range-maximum'), + (DRAWNS,u'handle-range-x-minimum'), + (DRAWNS,u'handle-position'), + (DRAWNS,u'handle-polar'), + ), + (DRAWNS,u'hatch'):( + (DRAWNS,u'distance'), + (DRAWNS,u'style'), + (DRAWNS,u'name'), + (DRAWNS,u'color'), + (DRAWNS,u'display-name'), + (DRAWNS,u'rotation'), + ), + (DRAWNS,u'image'):( + (DRAWNS,u'filter-name'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (XLINKNS,u'actuate'), + (XLINKNS,u'show'), + (XMLNS,u'id'), + ), + (DRAWNS,u'image-map'):( + ), + (DRAWNS,u'layer'):( + (DRAWNS,u'protected'), + (DRAWNS,u'name'), + (DRAWNS,u'display'), + ), +# allowed_attributes + (DRAWNS,u'layer-set'):( + ), + (DRAWNS,u'line'):( + (DRAWNS,u'class-names'), + (DRAWNS,u'id'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'style-name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'x1'), + (SVGNS,u'x2'), + (SVGNS,u'y1'), + (SVGNS,u'y2'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), + (DRAWNS,u'marker'):( + (SVGNS,u'd'), + (DRAWNS,u'display-name'), + (DRAWNS,u'name'), + (SVGNS,u'viewBox'), + ), +# allowed_attributes + (DRAWNS,u'measure'):( + (TABLENS,u'end-cell-address'), + (DRAWNS,u'layer'), + (SVGNS,u'y2'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (TABLENS,u'table-background'), + (SVGNS,u'x2'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y1'), + (DRAWNS,u'caption-id'), + (TABLENS,u'end-y'), + (SVGNS,u'x1'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), + (DRAWNS,u'object'):( + (XLINKNS,u'type'), + (XLINKNS,u'href'), + (DRAWNS,u'notify-on-update-of-ranges'), + (XLINKNS,u'actuate'), + (XLINKNS,u'show'), + (XMLNS,u'id'), + ), + (DRAWNS,u'object-ole'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (DRAWNS,u'class-id'), + (XLINKNS,u'show'), + (XMLNS,u'id'), + ), + (DRAWNS,u'opacity'):( + (DRAWNS,u'style'), + (DRAWNS,u'angle'), + (DRAWNS,u'name'), + (DRAWNS,u'start'), + (DRAWNS,u'cy'), + (DRAWNS,u'cx'), + (DRAWNS,u'end'), + (DRAWNS,u'display-name'), + (DRAWNS,u'border'), + ), + (DRAWNS,u'page'):( + (PRESENTATIONNS,u'presentation-page-layout-name'), + (DRAWNS,u'name'), + (DRAWNS,u'nav-order'), + (PRESENTATIONNS,u'use-footer-name'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'use-header-name'), + (DRAWNS,u'master-page-name'), + (DRAWNS,u'id'), + (PRESENTATIONNS,u'use-date-time-name'), + (XMLNS,u'id'), + ), + (DRAWNS,u'page-thumbnail'):( + (TABLENS,u'table-background'), + (DRAWNS,u'caption-id'), + (PRESENTATIONNS,u'user-transformed'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'id'), + (DRAWNS,u'transform'), + (DRAWNS,u'page-number'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (PRESENTATIONNS,u'placeholder'), + (PRESENTATIONNS,u'class'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), + (DRAWNS,u'param'):( + (DRAWNS,u'name'), + (DRAWNS,u'value'), + ), +# allowed_attributes + (DRAWNS,u'path'):( + (DRAWNS,u'caption-id'), + (DRAWNS,u'class-names'), + (DRAWNS,u'id'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'style-name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'd'), + (SVGNS,u'height'), + (SVGNS,u'viewBox'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DRAWNS,u'plugin'):( + (DRAWNS,u'mime-type'), + (XLINKNS,u'type'), + (XLINKNS,u'href'), + (XLINKNS,u'actuate'), + (XLINKNS,u'show'), + (XMLNS,u'id'), + ), + (DRAWNS,u'polygon'):( + (DRAWNS,u'caption-id'), + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'id'), + (DRAWNS,u'transform'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'points'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (SVGNS,u'viewBox'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DRAWNS,u'polyline'):( + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'id'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'transform'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'points'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (SVGNS,u'viewBox'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DRAWNS,u'rect'):( + (DRAWNS,u'corner-radius'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'id'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (SVGNS,u'rx'), + (SVGNS,u'ry'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), +# allowed_attributes + (DRAWNS,u'regular-polygon'):( + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (TEXTNS,u'anchor-page-number'), + (DRAWNS,u'concave'), + (DRAWNS,u'sharpness'), + (DRAWNS,u'transform'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (DRAWNS,u'corners'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), + (DRAWNS,u'stroke-dash'):( + (DRAWNS,u'distance'), + (DRAWNS,u'dots1-length'), + (DRAWNS,u'name'), + (DRAWNS,u'dots2-length'), + (DRAWNS,u'style'), + (DRAWNS,u'dots1'), + (DRAWNS,u'display-name'), + (DRAWNS,u'dots2'), + ), + (DRAWNS,u'text-box'):( + (FONS,u'min-width'), + (DRAWNS,u'corner-radius'), + (FONS,u'max-height'), + (FONS,u'min-height'), + (DRAWNS,u'chain-next-name'), + (FONS,u'max-width'), + (TEXTNS,u'id'), + (XMLNS,u'id'), + ), +# allowed_attributes + (FORMNS,u'button'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'tab-stop'), + (FORMNS,u'focus-on-click'), + (FORMNS,u'image-align'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'button-type'), + (FORMNS,u'title'), + (FORMNS,u'default-button'), + (FORMNS,u'value'), + (FORMNS,u'label'), + (FORMNS,u'delay-for-repeat'), + (FORMNS,u'repeat'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'image-data'), + (XLINKNS,u'href'), + (FORMNS,u'toggle'), + (FORMNS,u'xforms-submission'), + (OFFICENS,u'target-frame'), + (FORMNS,u'image-position'), + ), + (FORMNS,u'checkbox'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'tab-stop'), + (FORMNS,u'image-align'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'title'), + (FORMNS,u'is-tristate'), + (FORMNS,u'current-state'), + (FORMNS,u'value'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'state'), + (FORMNS,u'visual-effect'), + (FORMNS,u'image-position'), + ), + (FORMNS,u'column'):( + (FORMNS,u'control-implementation'), + (FORMNS,u'text-style-name'), + (FORMNS,u'name'), + (FORMNS,u'label'), + ), +# allowed_attributes + (FORMNS,u'combobox'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'auto-complete'), + (FORMNS,u'control-implementation'), + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'current-value'), + (FORMNS,u'data-field'), + (FORMNS,u'disabled'), + (FORMNS,u'dropdown'), + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'list-source'), + (FORMNS,u'list-source-type'), + (FORMNS,u'max-length'), + (FORMNS,u'name'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'size'), + (FORMNS,u'source-cell-range'), + (FORMNS,u'tab-index'), + (FORMNS,u'tab-stop'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (XFORMSNS,u'bind'), + ), +# allowed_attributes + (FORMNS,u'connection-resource'):( + (XLINKNS,u'href'), + ), + (FORMNS,u'date'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'control-implementation'), + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'current-value'), + (FORMNS,u'data-field'), + (FORMNS,u'delay-for-repeat'), + (FORMNS,u'disabled'), + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'max-length'), + (FORMNS,u'max-value'), + (FORMNS,u'min-value'), + (FORMNS,u'name'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'repeat'), + (FORMNS,u'spin-button'), + (FORMNS,u'tab-index'), + (FORMNS,u'tab-stop'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (XFORMSNS,u'bind'), + ), + (FORMNS,u'file'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'fixed-text'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'name'), + (FORMNS,u'for'), + (FORMNS,u'title'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'multi-line'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + ), +# allowed_attributes + (FORMNS,u'form'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (FORMNS,u'allow-deletes'), + (FORMNS,u'command-type'), + (FORMNS,u'apply-filter'), + (XLINKNS,u'type'), + (FORMNS,u'method'), + (OFFICENS,u'target-frame'), + (FORMNS,u'navigation-mode'), + (FORMNS,u'detail-fields'), + (FORMNS,u'master-fields'), + (FORMNS,u'allow-updates'), + (FORMNS,u'name'), + (FORMNS,u'tab-cycle'), + (FORMNS,u'control-implementation'), + (FORMNS,u'escape-processing'), + (FORMNS,u'filter'), + (FORMNS,u'command'), + (FORMNS,u'datasource'), + (FORMNS,u'enctype'), + (FORMNS,u'allow-inserts'), + (FORMNS,u'ignore-result'), + (FORMNS,u'order'), + ), +# allowed_attributes + (FORMNS,u'formatted-text'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'control-implementation'), + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'current-value'), + (FORMNS,u'data-field'), + (FORMNS,u'delay-for-repeat'), + (FORMNS,u'disabled'), + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'max-length'), + (FORMNS,u'max-value'), + (FORMNS,u'min-value'), + (FORMNS,u'name'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'repeat'), + (FORMNS,u'spin-button'), + (FORMNS,u'tab-index'), + (FORMNS,u'tab-stop'), + (FORMNS,u'title'), + (FORMNS,u'validation'), + (FORMNS,u'value'), + (XFORMSNS,u'bind'), + ), + (FORMNS,u'frame'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'name'), + (FORMNS,u'for'), + (FORMNS,u'title'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + ), +# allowed_attributes + (FORMNS,u'generic-control'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'name'), + ), + (FORMNS,u'grid'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + ), + (FORMNS,u'hidden'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'name'), + (FORMNS,u'value'), + ), + (FORMNS,u'image'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'button-type'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (OFFICENS,u'target-frame'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'image-data'), + (XLINKNS,u'href'), + ), + (FORMNS,u'image-frame'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'name'), + (FORMNS,u'title'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'readonly'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'image-data'), + ), + (FORMNS,u'item'):( + (FORMNS,u'label'), + ), + (FORMNS,u'list-property'):( + (FORMNS,u'property-name'), + (OFFICENS,u'value-type'), + ), + (FORMNS,u'list-value'):( + (OFFICENS,u'string-value'), + ), +# allowed_attributes + (FORMNS,u'listbox'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'bound-column'), + (FORMNS,u'control-implementation'), + (FORMNS,u'data-field'), + (FORMNS,u'disabled'), + (FORMNS,u'dropdown'), + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'list-linkage-type'), + (FORMNS,u'list-source'), + (FORMNS,u'list-source-type'), + (FORMNS,u'multiple'), + (FORMNS,u'name'), + (FORMNS,u'printable'), + (FORMNS,u'size'), + (FORMNS,u'source-cell-range'), + (FORMNS,u'tab-index'), + (FORMNS,u'tab-stop'), + (FORMNS,u'title'), + (FORMNS,u'xforms-list-source'), + (XFORMSNS,u'bind'), + ), + (FORMNS,u'number'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'control-implementation'), + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'current-value'), + (FORMNS,u'data-field'), + (FORMNS,u'delay-for-repeat'), + (FORMNS,u'disabled'), + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'max-length'), + (FORMNS,u'max-value'), + (FORMNS,u'min-value'), + (FORMNS,u'name'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'repeat'), + (FORMNS,u'spin-button'), + (FORMNS,u'tab-index'), + (FORMNS,u'tab-stop'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (XFORMSNS,u'bind'), + ), + (FORMNS,u'option'):( + (FORMNS,u'current-selected'), + (FORMNS,u'selected'), + (FORMNS,u'value'), + (FORMNS,u'label'), + ), + (FORMNS,u'password'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'echo-char'), + ), + (FORMNS,u'properties'):( + ), + (FORMNS,u'property'):( + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (FORMNS,u'property-name'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (OFFICENS,u'value-type'), + (OFFICENS,u'time-value'), + ), + (FORMNS,u'radio'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'tab-stop'), + (FORMNS,u'selected'), + (FORMNS,u'image-align'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'current-selected'), + (FORMNS,u'value'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'title'), + (FORMNS,u'visual-effect'), + (FORMNS,u'image-position'), + ), + (FORMNS,u'text'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'textarea'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'time'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'control-implementation'), + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'current-value'), + (FORMNS,u'data-field'), + (FORMNS,u'delay-for-repeat'), + (FORMNS,u'disabled'), + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'max-length'), + (FORMNS,u'max-value'), + (FORMNS,u'min-value'), + (FORMNS,u'name'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'repeat'), + (FORMNS,u'spin-button'), + (FORMNS,u'tab-index'), + (FORMNS,u'tab-stop'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (XFORMSNS,u'bind'), + ), + (FORMNS,u'value-range'):( + (XMLNS,u'id'), # First choice + (FORMNS,u'id'), + (FORMNS,u'linked-cell'), + (FORMNS,u'tab-stop'), + (FORMNS,u'max-value'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'orientation'), + (FORMNS,u'page-step-size'), + (FORMNS,u'delay-for-repeat'), + (FORMNS,u'repeat'), + (FORMNS,u'min-value'), + (FORMNS,u'step-size'), + ), + (MANIFESTNS,'algorithm') : ( + (MANIFESTNS,'algorithm-name'), + (MANIFESTNS,'initialisation-vector'), + ), + (MANIFESTNS,'encryption-data') : ( + (MANIFESTNS,'checksum-type'), + (MANIFESTNS,'checksum'), + ), + (MANIFESTNS,'file-entry') : ( + (MANIFESTNS,'full-path'), + (MANIFESTNS,'media-type'), + (MANIFESTNS,'preferred-view-mode'), + (MANIFESTNS,'size'), + (MANIFESTNS,'version'), + ), + (MANIFESTNS,'key-derivation') : ( + (MANIFESTNS,'key-derivation-name'), + (MANIFESTNS,'salt'), + (MANIFESTNS,'iteration-count'), + ), + (MANIFESTNS,u'manifest'):( + ), +# allowed_attributes + (METANS,u'auto-reload'):( + (METANS,u'delay'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (XLINKNS,u'show'), + ), + (METANS,u'creation-date'):( + ), + (METANS,u'date-string'):( + ), + (METANS,u'document-statistic'):( + (METANS,u'non-whitespace-character-count'), + (METANS,u'ole-object-count'), + (METANS,u'table-count'), + (METANS,u'row-count'), + (METANS,u'character-count'), + (METANS,u'sentence-count'), + (METANS,u'draw-count'), + (METANS,u'paragraph-count'), + (METANS,u'word-count'), + (METANS,u'object-count'), + (METANS,u'syllable-count'), + (METANS,u'image-count'), + (METANS,u'page-count'), + (METANS,u'frame-count'), + (METANS,u'cell-count'), + ), + (METANS,u'editing-cycles'):( + ), + (METANS,u'editing-duration'):( + ), + (METANS,u'generator'):( + ), +# allowed_attributes + (METANS,u'hyperlink-behaviour'):( + (OFFICENS,u'target-frame-name'), + (XLINKNS,u'show'), + ), + (METANS,u'initial-creator'):( + ), + (METANS,u'keyword'):( + ), + (METANS,u'print-date'):( + ), + (METANS,u'printed-by'):( + ), + (METANS,u'template'):( + (METANS,u'date'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (XLINKNS,u'title'), + ), + (METANS,u'user-defined'):( + (METANS,u'name'), + (METANS,u'value-type'), + ), +# allowed_attributes + (OFFICENS,u'annotation'):( + (DRAWNS,u'caption-point-x'), + (DRAWNS,u'caption-point-y'), + (DRAWNS,u'class-names'), + (DRAWNS,u'corner-radius'), + (DRAWNS,u'id'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'style-name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (OFFICENS,u'display'), + (OFFICENS,u'name'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + (XMLNS,u'id'), + ), + (OFFICENS,u'annotation-end'): ( + (OFFICENS,u'name'), + ), + (OFFICENS,u'automatic-styles'):( + ), + (OFFICENS,u'binary-data'):( + ), + (OFFICENS,u'body'):( + ), + (OFFICENS,u'change-info'):( + ), + (OFFICENS,u'chart'):( + ), +# allowed_attributes + (OFFICENS,u'dde-source'):( + (OFFICENS,u'dde-application'), + (OFFICENS,u'automatic-update'), + (OFFICENS,u'conversion-mode'), + (OFFICENS,u'dde-item'), + (OFFICENS,u'dde-topic'), + (OFFICENS,u'name'), + ), + (OFFICENS,u'document'):( + (OFFICENS,u'mimetype'), + (OFFICENS,u'version'), + (GRDDLNS,u'transformation'), + ), + (OFFICENS,u'document-content'):( + (OFFICENS,u'version'), + (GRDDLNS,u'transformation'), + ), + (OFFICENS,u'document-meta'):( + (OFFICENS,u'version'), + (GRDDLNS,u'transformation'), + ), + (OFFICENS,u'document-settings'):( + (OFFICENS,u'version'), + (GRDDLNS,u'transformation'), + ), + (OFFICENS,u'document-styles'):( + (OFFICENS,u'version'), + (GRDDLNS,u'transformation'), + ), + (OFFICENS,u'drawing'):( + ), + (OFFICENS,u'event-listeners'):( + ), + (OFFICENS,u'font-face-decls'):( + ), + (OFFICENS,u'forms'):( + (FORMNS,u'automatic-focus'), + (FORMNS,u'apply-design-mode'), + ), + (OFFICENS,u'image'):( + ), +# allowed_attributes + (OFFICENS,u'master-styles'):( + ), + (OFFICENS,u'meta'):( + ), + (OFFICENS,u'presentation'):( + ), + (OFFICENS,u'script'):( + (SCRIPTNS,u'language'), + ), + (OFFICENS,u'scripts'):( + ), + (OFFICENS,u'settings'):( + ), + (OFFICENS,u'spreadsheet'):( + (TABLENS,u'structure-protected'), + (TABLENS,u'protection-key'), + (TABLENS,u'protection-key-digest-algorithm'), + ), + (OFFICENS,u'styles'):( + ), + (OFFICENS,u'text'):( + (TEXTNS,u'global'), + (TEXTNS,u'use-soft-page-breaks'), + ), + (PRESENTATIONNS,u'animation-group'):( + ), + (PRESENTATIONNS,u'animations'):( + ), + (PRESENTATIONNS,u'date-time'):( + ), + (PRESENTATIONNS,u'date-time-decl'):( + (PRESENTATIONNS,u'source'), + (STYLENS,u'data-style-name'), + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'dim'):( + (DRAWNS,u'color'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'event-listener'):( + (PRESENTATIONNS,u'direction'), + (XLINKNS,u'show'), + (XLINKNS,u'type'), + (XLINKNS,u'actuate'), + (PRESENTATIONNS,u'effect'), + (SCRIPTNS,u'event-name'), + (PRESENTATIONNS,u'start-scale'), + (XLINKNS,u'href'), + (PRESENTATIONNS,u'verb'), + (PRESENTATIONNS,u'action'), + (PRESENTATIONNS,u'speed'), + ), + (PRESENTATIONNS,u'footer'):( + ), + (PRESENTATIONNS,u'footer-decl'):( + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'header'):( + ), + (PRESENTATIONNS,u'header-decl'):( + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'hide-shape'):( + (PRESENTATIONNS,u'direction'), + (PRESENTATIONNS,u'effect'), + (PRESENTATIONNS,u'delay'), + (PRESENTATIONNS,u'start-scale'), + (PRESENTATIONNS,u'path-id'), + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), +# allowed_attributes + (PRESENTATIONNS,u'hide-text'):( + (PRESENTATIONNS,u'direction'), + (PRESENTATIONNS,u'effect'), + (PRESENTATIONNS,u'delay'), + (PRESENTATIONNS,u'start-scale'), + (PRESENTATIONNS,u'path-id'), + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'notes'):( + (STYLENS,u'page-layout-name'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'use-header-name'), + (PRESENTATIONNS,u'use-date-time-name'), + (PRESENTATIONNS,u'use-footer-name'), + ), + (PRESENTATIONNS,u'placeholder'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'height'), + (PRESENTATIONNS,u'object'), + (SVGNS,u'width'), + ), + (PRESENTATIONNS,u'play'):( + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), +# allowed_attributes + (PRESENTATIONNS,u'settings'):( + (PRESENTATIONNS,u'animations'), + (PRESENTATIONNS,u'endless'), + (PRESENTATIONNS,u'force-manual'), + (PRESENTATIONNS,u'full-screen'), + (PRESENTATIONNS,u'mouse-as-pen'), + (PRESENTATIONNS,u'mouse-visible'), + (PRESENTATIONNS,u'pause'), + (PRESENTATIONNS,u'show'), + (PRESENTATIONNS,u'show-end-of-presentation-slide'), + (PRESENTATIONNS,u'show-logo'), + (PRESENTATIONNS,u'start-page'), + (PRESENTATIONNS,u'start-with-navigator'), + (PRESENTATIONNS,u'stay-on-top'), + (PRESENTATIONNS,u'transition-on-click'), + ), + (PRESENTATIONNS,u'show'):( + (PRESENTATIONNS,u'name'), + (PRESENTATIONNS,u'pages'), + ), + (PRESENTATIONNS,u'show-shape'):( + (PRESENTATIONNS,u'direction'), + (PRESENTATIONNS,u'effect'), + (PRESENTATIONNS,u'delay'), + (PRESENTATIONNS,u'start-scale'), + (PRESENTATIONNS,u'path-id'), + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'show-text'):( + (PRESENTATIONNS,u'direction'), + (PRESENTATIONNS,u'effect'), + (PRESENTATIONNS,u'delay'), + (PRESENTATIONNS,u'start-scale'), + (PRESENTATIONNS,u'path-id'), + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'sound'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (PRESENTATIONNS,u'play-full'), + (XLINKNS,u'show'), + (XMLNS,u'id'), + ), +# allowed_attributes + (SCRIPTNS,u'event-listener'):( + (SCRIPTNS,u'language'), + (SCRIPTNS,u'macro-name'), + (XLINKNS,u'actuate'), + (SCRIPTNS,u'event-name'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (STYLENS,u'background-image'):( + (DRAWNS,u'opacity'), + (STYLENS,u'repeat'), + (XLINKNS,u'show'), + (XLINKNS,u'actuate'), + (STYLENS,u'filter-name'), + (XLINKNS,u'href'), + (STYLENS,u'position'), + (XLINKNS,u'type'), + ), +# allowed_attributes + (STYLENS,u'chart-properties'): ( + (CHARTNS,u'angle-offset'), + (CHARTNS,u'auto-position'), + (CHARTNS,u'auto-size'), + (CHARTNS,u'axis-label-position'), + (CHARTNS,u'axis-position'), + (CHARTNS,u'connect-bars'), + (CHARTNS,u'data-label-number'), + (CHARTNS,u'data-label-symbol'), + (CHARTNS,u'data-label-text'), + (CHARTNS,u'deep'), + (CHARTNS,u'display-label'), + (CHARTNS,u'error-category'), + (CHARTNS,u'error-lower-indicator'), + (CHARTNS,u'error-lower-limit'), + (CHARTNS,u'error-lower-range'), + (CHARTNS,u'error-margin'), + (CHARTNS,u'error-percentage'), + (CHARTNS,u'error-upper-indicator'), + (CHARTNS,u'error-upper-limit'), + (CHARTNS,u'error-upper-range'), + (CHARTNS,u'gap-width'), + (CHARTNS,u'group-bars-per-axis'), + (CHARTNS,u'hole-size'), + (CHARTNS,u'include-hidden-cells'), + (CHARTNS,u'interpolation'), + (CHARTNS,u'interval-major'), + (CHARTNS,u'interval-minor-divisor'), + (CHARTNS,u'japanese-candle-stick'), + (CHARTNS,u'label-arrangement'), + (CHARTNS,u'label-position'), + (CHARTNS,u'label-position-negative'), + (CHARTNS,u'lines'), + (CHARTNS,u'link-data-style-to-source'), + (CHARTNS,u'logarithmic'), + (CHARTNS,u'maximum'), + (CHARTNS,u'mean-value'), + (CHARTNS,u'minimum'), + (CHARTNS,u'origin'), + (CHARTNS,u'overlap'), + (CHARTNS,u'percentage'), + (CHARTNS,u'pie-offset'), + (CHARTNS,u'regression-type'), + (CHARTNS,u'reverse-direction'), + (CHARTNS,u'right-angled-axes'), + (CHARTNS,u'scale-text'), + (CHARTNS,u'series-source'), + (CHARTNS,u'solid-type'), + (CHARTNS,u'sort-by-x-values'), + (CHARTNS,u'spline-order'), + (CHARTNS,u'spline-resolution'), + (CHARTNS,u'stacked'), + (CHARTNS,u'symbol-height'), + (CHARTNS,u'symbol-name'), + (CHARTNS,u'symbol-type'), + (CHARTNS,u'symbol-width'), + (CHARTNS,u'text-overlap'), + (CHARTNS,u'three-dimensional'), + (CHARTNS,u'tick-mark-position'), + (CHARTNS,u'tick-marks-major-inner'), + (CHARTNS,u'tick-marks-major-outer'), + (CHARTNS,u'tick-marks-minor-inner'), + (CHARTNS,u'tick-marks-minor-outer'), + (CHARTNS,u'treat-empty-cells'), + (CHARTNS,u'vertical'), + (CHARTNS,u'visible'), + (STYLENS,u'direction'), + (STYLENS,u'rotation-angle'), + (TEXTNS,u'line-break'), + ), + (STYLENS,u'column'):( + (FONS,u'end-indent'), + (FONS,u'space-before'), + (FONS,u'start-indent'), + (FONS,u'space-after'), + (STYLENS,u'rel-width'), + ), + (STYLENS,u'column-sep'):( + (STYLENS,u'color'), + (STYLENS,u'width'), + (STYLENS,u'style'), + (STYLENS,u'vertical-align'), + (STYLENS,u'height'), + ), + (STYLENS,u'columns'):( + (FONS,u'column-count'), + (FONS,u'column-gap'), + ), +# allowed_attributes + (STYLENS,u'default-page-layout'):( + ), + (STYLENS,u'default-style'):( + (STYLENS,u'family'), + ), +# allowed_attributes + (STYLENS,u'drawing-page-properties'): ( + (DRAWNS,u'fill'), + (DRAWNS,u'fill-color'), + (DRAWNS,u'secondary-fill-color'), + (DRAWNS,u'fill-gradient-name'), + (DRAWNS,u'gradient-step-count'), + (DRAWNS,u'fill-hatch-name'), + (DRAWNS,u'fill-hatch-solid'), + (DRAWNS,u'fill-image-name'), + (STYLENS,u'repeat'), + (DRAWNS,u'fill-image-width'), + (DRAWNS,u'fill-image-height'), + (DRAWNS,u'fill-image-ref-point-x'), + (DRAWNS,u'fill-image-ref-point-y'), + (DRAWNS,u'fill-image-ref-point'), + (DRAWNS,u'tile-repeat-offset'), + (DRAWNS,u'opacity'), + (DRAWNS,u'opacity-name'), + (SVGNS,u'fill-rule'), + (PRESENTATIONNS,u'transition-type'), + (PRESENTATIONNS,u'transition-style'), + (PRESENTATIONNS,u'transition-speed'), + (SMILNS,u'type'), + (SMILNS,u'subtype'), + (SMILNS,u'direction'), + (SMILNS,u'fadeColor'), + (PRESENTATIONNS,u'duration'), + (PRESENTATIONNS,u'visibility'), + (DRAWNS,u'background-size'), + (PRESENTATIONNS,u'background-objects-visible'), + (PRESENTATIONNS,u'background-visible'), + (PRESENTATIONNS,u'display-header'), + (PRESENTATIONNS,u'display-footer'), + (PRESENTATIONNS,u'display-page-number'), + (PRESENTATIONNS,u'display-date-time'), + ), + (STYLENS,u'drop-cap'):( + (STYLENS,u'distance'), + (STYLENS,u'length'), + (STYLENS,u'style-name'), + (STYLENS,u'lines'), + ), +# allowed_attributes + (STYLENS,u'font-face'):( + (STYLENS,u'font-adornments'), + (STYLENS,u'font-charset'), + (STYLENS,u'font-family-generic'), + (STYLENS,u'font-pitch'), + (STYLENS,u'name'), + (SVGNS,u'accent-height'), + (SVGNS,u'alphabetic'), + (SVGNS,u'ascent'), + (SVGNS,u'bbox'), + (SVGNS,u'cap-height'), + (SVGNS,u'descent'), + (SVGNS,u'font-family'), + (SVGNS,u'font-size'), + (SVGNS,u'font-stretch'), + (SVGNS,u'font-style'), + (SVGNS,u'font-variant'), + (SVGNS,u'font-weight'), + (SVGNS,u'hanging'), + (SVGNS,u'ideographic'), + (SVGNS,u'mathematical'), + (SVGNS,u'overline-position'), + (SVGNS,u'overline-thickness'), + (SVGNS,u'panose-1'), + (SVGNS,u'slope'), + (SVGNS,u'stemh'), + (SVGNS,u'stemv'), + (SVGNS,u'strikethrough-position'), + (SVGNS,u'strikethrough-thickness'), + (SVGNS,u'underline-position'), + (SVGNS,u'underline-thickness'), + (SVGNS,u'unicode-range'), + (SVGNS,u'units-per-em'), + (SVGNS,u'v-alphabetic'), + (SVGNS,u'v-hanging'), + (SVGNS,u'v-ideographic'), + (SVGNS,u'v-mathematical'), + (SVGNS,u'widths'), + (SVGNS,u'x-height'), + ), + (STYLENS,u'footer'):( + (STYLENS,u'display'), + ), + (STYLENS,u'footer-left'):( + (STYLENS,u'display'), + ), + (STYLENS,u'footer-style'):( + ), + (STYLENS,u'footnote-sep'):( + (STYLENS,u'distance-after-sep'), + (STYLENS,u'color'), + (STYLENS,u'rel-width'), + (STYLENS,u'width'), + (STYLENS,u'distance-before-sep'), + (STYLENS,u'line-style'), + (STYLENS,u'adjustment'), + ), +# allowed_attributes + (STYLENS,u'graphic-properties'): ( + (DR3DNS,u'ambient-color'), + (DR3DNS,u'back-scale'), + (DR3DNS,u'backface-culling'), + (DR3DNS,u'close-back'), + (DR3DNS,u'close-front'), + (DR3DNS,u'depth'), + (DR3DNS,u'diffuse-color'), + (DR3DNS,u'edge-rounding'), + (DR3DNS,u'edge-rounding-mode'), + (DR3DNS,u'emissive-color'), + (DR3DNS,u'end-angle'), + (DR3DNS,u'horizontal-segments'), + (DR3DNS,u'lighting-mode'), + (DR3DNS,u'normals-direction'), + (DR3DNS,u'normals-kind'), + (DR3DNS,u'shadow'), + (DR3DNS,u'shininess'), + (DR3DNS,u'specular-color'), + (DR3DNS,u'texture-filter'), + (DR3DNS,u'texture-generation-mode-x'), + (DR3DNS,u'texture-generation-mode-y'), + (DR3DNS,u'texture-kind'), + (DR3DNS,u'texture-mode'), + (DR3DNS,u'vertical-segments'), + (DRAWNS,u'auto-grow-height'), + (DRAWNS,u'auto-grow-width'), + (DRAWNS,u'blue'), + (DRAWNS,u'caption-angle'), + (DRAWNS,u'caption-angle-type'), + (DRAWNS,u'caption-escape'), + (DRAWNS,u'caption-escape-direction'), + (DRAWNS,u'caption-fit-line-length'), + (DRAWNS,u'caption-gap'), + (DRAWNS,u'caption-line-length'), + (DRAWNS,u'caption-type'), + (DRAWNS,u'color-inversion'), + (DRAWNS,u'color-mode'), + (DRAWNS,u'contrast'), + (DRAWNS,u'decimal-places'), + (DRAWNS,u'draw-aspect'), + (DRAWNS,u'end-guide'), + (DRAWNS,u'end-line-spacing-horizontal'), + (DRAWNS,u'end-line-spacing-vertical'), + (DRAWNS,u'fill'), + (DRAWNS,u'fill-color'), + (DRAWNS,u'fill-gradient-name'), + (DRAWNS,u'fill-hatch-name'), + (DRAWNS,u'fill-hatch-solid'), + (DRAWNS,u'fill-image-height'), + (DRAWNS,u'fill-image-name'), + (DRAWNS,u'fill-image-ref-point'), + (DRAWNS,u'fill-image-ref-point-x'), + (DRAWNS,u'fill-image-ref-point-y'), + (DRAWNS,u'fill-image-width'), +# allowed_attributes + (DRAWNS,u'fit-to-contour'), + (DRAWNS,u'fit-to-size'), + (DRAWNS,u'frame-display-border'), + (DRAWNS,u'frame-display-scrollbar'), + (DRAWNS,u'frame-margin-horizontal'), + (DRAWNS,u'frame-margin-vertical'), + (DRAWNS,u'gamma'), + (DRAWNS,u'gradient-step-count'), + (DRAWNS,u'green'), + (DRAWNS,u'guide-distance'), + (DRAWNS,u'guide-overhang'), + (DRAWNS,u'image-opacity'), + (DRAWNS,u'line-distance'), + (DRAWNS,u'luminance'), + (DRAWNS,u'marker-end'), + (DRAWNS,u'marker-end-center'), + (DRAWNS,u'marker-end-width'), + (DRAWNS,u'marker-start'), + (DRAWNS,u'marker-start-center'), + (DRAWNS,u'marker-start-width'), + (DRAWNS,u'measure-align'), + (DRAWNS,u'measure-vertical-align'), + (DRAWNS,u'ole-draw-aspect'), + (DRAWNS,u'opacity'), + (DRAWNS,u'opacity-name'), + (DRAWNS,u'parallel'), + (DRAWNS,u'placing'), + (DRAWNS,u'red'), + (DRAWNS,u'secondary-fill-color'), + (DRAWNS,u'shadow'), + (DRAWNS,u'shadow-color'), + (DRAWNS,u'shadow-offset-x'), + (DRAWNS,u'shadow-offset-y'), + (DRAWNS,u'shadow-opacity'), + (DRAWNS,u'show-unit'), + (DRAWNS,u'start-guide'), + (DRAWNS,u'start-line-spacing-horizontal'), + (DRAWNS,u'start-line-spacing-vertical'), + (DRAWNS,u'stroke'), + (DRAWNS,u'stroke-dash'), + (DRAWNS,u'stroke-dash-names'), + (DRAWNS,u'stroke-linejoin'), + (DRAWNS,u'symbol-color'), + (DRAWNS,u'textarea-horizontal-align'), + (DRAWNS,u'textarea-vertical-align'), + (DRAWNS,u'tile-repeat-offset'), + (DRAWNS,u'unit'), + (DRAWNS,u'visible-area-height'), + (DRAWNS,u'visible-area-left'), + (DRAWNS,u'visible-area-top'), + (DRAWNS,u'visible-area-width'), + (DRAWNS,u'wrap-influence-on-position'), +# allowed_attributes + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'clip'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (FONS,u'max-height'), + (FONS,u'max-width'), + (FONS,u'min-height'), + (FONS,u'min-width'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (FONS,u'wrap-option'), + (STYLENS,u'background-transparency'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'editable'), + (STYLENS,u'flow-with-text'), + (STYLENS,u'horizontal-pos'), + (STYLENS,u'horizontal-rel'), + (STYLENS,u'mirror'), + (STYLENS,u'number-wrapped-paragraphs'), + (STYLENS,u'overflow-behavior'), + (STYLENS,u'print-content'), + (STYLENS,u'protect'), + (STYLENS,u'rel-height'), + (STYLENS,u'rel-width'), + (STYLENS,u'repeat'), + (STYLENS,u'run-through'), + (STYLENS,u'shadow'), + (STYLENS,u'shrink-to-fit'), + (STYLENS,u'vertical-pos'), + (STYLENS,u'vertical-rel'), + (STYLENS,u'wrap'), + (STYLENS,u'wrap-contour'), + (STYLENS,u'wrap-contour-mode'), + (STYLENS,u'wrap-dynamic-threshold'), + (STYLENS,u'writing-mode'), + (SVGNS,u'fill-rule'), + (SVGNS,u'height'), + (SVGNS,u'stroke-color'), + (SVGNS,u'stroke-linecap'), + (SVGNS,u'stroke-opacity'), + (SVGNS,u'stroke-width'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + (TEXTNS,u'animation'), + (TEXTNS,u'animation-delay'), + (TEXTNS,u'animation-direction'), + (TEXTNS,u'animation-repeat'), + (TEXTNS,u'animation-start-inside'), + (TEXTNS,u'animation-steps'), + (TEXTNS,u'animation-stop-inside'), + ), + (STYLENS,u'handout-master'):( + (PRESENTATIONNS,u'presentation-page-layout-name'), + (STYLENS,u'page-layout-name'), + (PRESENTATIONNS,u'use-footer-name'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'use-header-name'), + (PRESENTATIONNS,u'use-date-time-name'), + ), +# allowed_attributes + (STYLENS,u'header'):( + (STYLENS,u'display'), + ), + (STYLENS,u'header-footer-properties'): ( + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (FONS,u'min-height'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'dynamic-spacing'), + (STYLENS,u'shadow'), + (SVGNS,u'height'), + ), + (STYLENS,u'header-left'):( + (STYLENS,u'display'), + ), + (STYLENS,u'header-style'):( + ), + (STYLENS,u'list-level-label-alignment'):( + (FONS,u'text-indent'), + (TEXTNS,u'label-followed-by'), + (TEXTNS,u'list-tab-stop-position'), + (FONS,u'margin-left'), + ), +# allowed_attributes + (STYLENS,u'list-level-properties'): ( + (FONS,u'height'), + (FONS,u'text-align'), + (FONS,u'width'), + (STYLENS,u'font-name'), + (STYLENS,u'vertical-pos'), + (STYLENS,u'vertical-rel'), + (SVGNS,u'y'), + (TEXTNS,u'list-level-position-and-space-mode'), + (TEXTNS,u'min-label-distance'), + (TEXTNS,u'min-label-width'), + (TEXTNS,u'space-before'), + ), + (STYLENS,u'map'):( + (STYLENS,u'apply-style-name'), + (STYLENS,u'base-cell-address'), + (STYLENS,u'condition'), + ), + (STYLENS,u'master-page'):( + (STYLENS,u'page-layout-name'), + (STYLENS,u'display-name'), + (DRAWNS,u'style-name'), + (STYLENS,u'name'), + (STYLENS,u'next-style-name'), + ), + (STYLENS,u'page-layout'):( + (STYLENS,u'name'), + (STYLENS,u'page-usage'), + ), +# allowed_attributes + (STYLENS,u'page-layout-properties'): ( + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (FONS,u'page-height'), + (FONS,u'page-width'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'first-page-number'), + (STYLENS,u'footnote-max-height'), + (STYLENS,u'layout-grid-base-height'), + (STYLENS,u'layout-grid-base-width'), + (STYLENS,u'layout-grid-color'), + (STYLENS,u'layout-grid-display'), + (STYLENS,u'layout-grid-lines'), + (STYLENS,u'layout-grid-mode'), + (STYLENS,u'layout-grid-print'), + (STYLENS,u'layout-grid-ruby-below'), + (STYLENS,u'layout-grid-ruby-height'), + (STYLENS,u'layout-grid-snap-to'), + (STYLENS,u'layout-grid-standard-mode'), + (STYLENS,u'num-format'), + (STYLENS,u'num-letter-sync'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-suffix'), + (STYLENS,u'paper-tray-name'), + (STYLENS,u'print'), + (STYLENS,u'print-orientation'), + (STYLENS,u'print-page-order'), + (STYLENS,u'register-truth-ref-style-name'), + (STYLENS,u'scale-to'), + (STYLENS,u'scale-to-pages'), + (STYLENS,u'shadow'), + (STYLENS,u'table-centering'), + (STYLENS,u'writing-mode'), + ), +# allowed_attributes + (STYLENS,u'paragraph-properties'): ( + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'break-after'), + (FONS,u'break-before'), + (FONS,u'hyphenation-keep'), + (FONS,u'hyphenation-ladder-count'), + (FONS,u'keep-together'), + (FONS,u'keep-with-next'), + (FONS,u'line-height'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (FONS,u'orphans'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (FONS,u'text-align'), + (FONS,u'text-align-last'), + (FONS,u'text-indent'), + (FONS,u'widows'), + (STYLENS,u'auto-text-indent'), + (STYLENS,u'background-transparency'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'font-independent-line-spacing'), + (STYLENS,u'join-border'), + (STYLENS,u'justify-single-word'), + (STYLENS,u'line-break'), + (STYLENS,u'line-height-at-least'), + (STYLENS,u'line-spacing'), + (STYLENS,u'page-number'), + (STYLENS,u'punctuation-wrap'), + (STYLENS,u'register-true'), + (STYLENS,u'shadow'), + (STYLENS,u'snap-to-layout-grid'), + (STYLENS,u'tab-stop-distance'), + (STYLENS,u'text-autospace'), + (STYLENS,u'vertical-align'), + (STYLENS,u'writing-mode'), + (STYLENS,u'writing-mode-automatic'), + (TEXTNS,u'line-number'), + (TEXTNS,u'number-lines'), + ), + (STYLENS,u'presentation-page-layout'):( + (STYLENS,u'display-name'), + (STYLENS,u'name'), + ), +# allowed_attributes + (STYLENS,u'region-center'):( + ), + (STYLENS,u'region-left'):( + ), + (STYLENS,u'region-right'):( + ), + (STYLENS,u'ruby-properties'): ( + (STYLENS,u'ruby-position'), + (STYLENS,u'ruby-align'), + ), + (STYLENS,u'section-properties'): ( + (FONS,u'background-color'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (STYLENS,u'editable'), + (STYLENS,u'protect'), + (STYLENS,u'writing-mode'), + (TEXTNS,u'dont-balance-text-columns'), + ), + (STYLENS,u'style'):( + (STYLENS,u'auto-update'), + (STYLENS,u'class'), + (STYLENS,u'data-style-name'), + (STYLENS,u'default-outline-level'), + (STYLENS,u'display-name'), + (STYLENS,u'family'), + (STYLENS,u'list-level'), + (STYLENS,u'list-style-name'), + (STYLENS,u'master-page-name'), + (STYLENS,u'name'), + (STYLENS,u'next-style-name'), + (STYLENS,u'parent-style-name'), + (STYLENS,u'percentage-data-style-name'), + ), +# allowed_attributes + (STYLENS,u'tab-stop'):( + (STYLENS,u'leader-text-style'), + (STYLENS,u'leader-width'), + (STYLENS,u'leader-style'), + (STYLENS,u'char'), + (STYLENS,u'leader-color'), + (STYLENS,u'position'), + (STYLENS,u'leader-text'), + (STYLENS,u'type'), + (STYLENS,u'leader-type'), + ), + (STYLENS,u'tab-stops'):( + ), + (STYLENS,u'table-cell-properties'): ( + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (FONS,u'wrap-option'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'cell-protect'), + (STYLENS,u'decimal-places'), + (STYLENS,u'diagonal-bl-tr'), + (STYLENS,u'diagonal-bl-tr-widths'), + (STYLENS,u'diagonal-tl-br'), + (STYLENS,u'diagonal-tl-br-widths'), + (STYLENS,u'direction'), + (STYLENS,u'glyph-orientation-vertical'), + (STYLENS,u'print-content'), + (STYLENS,u'repeat-content'), + (STYLENS,u'rotation-align'), + (STYLENS,u'rotation-angle'), + (STYLENS,u'shadow'), + (STYLENS,u'shrink-to-fit'), + (STYLENS,u'text-align-source'), + (STYLENS,u'vertical-align'), + (STYLENS,u'writing-mode'), + ), +# allowed_attributes + (STYLENS,u'table-column-properties'): ( + (FONS,u'break-after'), + (FONS,u'break-before'), + (STYLENS,u'column-width'), + (STYLENS,u'rel-column-width'), + (STYLENS,u'use-optimal-column-width'), + ), + (STYLENS,u'table-properties'): ( + (FONS,u'background-color'), + (FONS,u'break-after'), + (FONS,u'break-before'), + (FONS,u'keep-with-next'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (STYLENS,u'may-break-between-rows'), + (STYLENS,u'page-number'), + (STYLENS,u'rel-width'), + (STYLENS,u'shadow'), + (STYLENS,u'width'), + (STYLENS,u'writing-mode'), + (TABLENS,u'align'), + (TABLENS,u'border-model'), + (TABLENS,u'display'), + ), + (STYLENS,u'table-row-properties'): ( + (FONS,u'background-color'), + (FONS,u'break-after'), + (FONS,u'break-before'), + (FONS,u'keep-together'), + (STYLENS,u'min-row-height'), + (STYLENS,u'row-height'), + (STYLENS,u'use-optimal-row-height'), + ), +# allowed_attributes + (STYLENS,u'text-properties'): ( + (FONS,u'background-color'), + (FONS,u'color'), + (FONS,u'country'), + (FONS,u'font-family'), + (FONS,u'font-size'), + (FONS,u'font-style'), + (FONS,u'font-variant'), + (FONS,u'font-weight'), + (FONS,u'hyphenate'), + (FONS,u'hyphenation-push-char-count'), + (FONS,u'hyphenation-remain-char-count'), + (FONS,u'language'), + (FONS,u'letter-spacing'), + (FONS,u'script'), + (FONS,u'text-shadow'), + (FONS,u'text-transform'), + (STYLENS,u'country-asian'), + (STYLENS,u'country-complex'), + (STYLENS,u'font-charset'), + (STYLENS,u'font-charset-asian'), + (STYLENS,u'font-charset-complex'), + (STYLENS,u'font-family-asian'), + (STYLENS,u'font-family-complex'), + (STYLENS,u'font-family-generic'), + (STYLENS,u'font-family-generic-asian'), + (STYLENS,u'font-family-generic-complex'), + (STYLENS,u'font-name'), + (STYLENS,u'font-name-asian'), + (STYLENS,u'font-name-complex'), + (STYLENS,u'font-pitch'), + (STYLENS,u'font-pitch-asian'), + (STYLENS,u'font-pitch-complex'), + (STYLENS,u'font-relief'), + (STYLENS,u'font-size-asian'), + (STYLENS,u'font-size-complex'), + (STYLENS,u'font-size-rel'), + (STYLENS,u'font-size-rel-asian'), + (STYLENS,u'font-size-rel-complex'), + (STYLENS,u'font-style-asian'), + (STYLENS,u'font-style-complex'), + (STYLENS,u'font-style-name'), + (STYLENS,u'font-style-name-asian'), + (STYLENS,u'font-style-name-complex'), + (STYLENS,u'font-weight-asian'), + (STYLENS,u'font-weight-complex'), + (STYLENS,u'language-asian'), + (STYLENS,u'language-complex'), + (STYLENS,u'letter-kerning'), + (STYLENS,u'rfc-language-tag'), + (STYLENS,u'rfc-language-tag-asian'), + (STYLENS,u'rfc-language-tag-complex'), + (STYLENS,u'script-asian'), + (STYLENS,u'script-complex'), + (STYLENS,u'script-type'), + (STYLENS,u'text-blinking'), + (STYLENS,u'text-combine'), + (STYLENS,u'text-combine-end-char'), + (STYLENS,u'text-combine-start-char'), + (STYLENS,u'text-emphasize'), + (STYLENS,u'text-line-through-color'), + (STYLENS,u'text-line-through-mode'), + (STYLENS,u'text-line-through-style'), + (STYLENS,u'text-line-through-text'), + (STYLENS,u'text-line-through-text-style'), + (STYLENS,u'text-line-through-type'), + (STYLENS,u'text-line-through-width'), + (STYLENS,u'text-outline'), + (STYLENS,u'text-overline-color'), + (STYLENS,u'text-overline-mode'), + (STYLENS,u'text-overline-style'), + (STYLENS,u'text-overline-type'), + (STYLENS,u'text-overline-width'), + (STYLENS,u'text-position'), + (STYLENS,u'text-rotation-angle'), + (STYLENS,u'text-rotation-scale'), + (STYLENS,u'text-scale'), + (STYLENS,u'text-underline-color'), + (STYLENS,u'text-underline-mode'), + (STYLENS,u'text-underline-style'), + (STYLENS,u'text-underline-type'), + (STYLENS,u'text-underline-width'), + (STYLENS,u'use-window-font-color'), + (TEXTNS,u'condition'), + (TEXTNS,u'display'), + ), + (SVGNS,u'definition-src'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (SVGNS,u'desc'):( + ), + (SVGNS,u'font-face-format'):( + (SVGNS,u'string'), + ), +# allowed_attributes + (SVGNS,u'font-face-name'):( + (SVGNS,u'name'), + ), + (SVGNS,u'font-face-src'):( + ), + (SVGNS,u'font-face-uri'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (SVGNS,u'linearGradient'):( + (SVGNS,u'y2'), + (DRAWNS,u'name'), + (SVGNS,u'spreadMethod'), + (SVGNS,u'gradientUnits'), + (SVGNS,u'x2'), + (SVGNS,u'gradientTransform'), + (SVGNS,u'y1'), + (DRAWNS,u'display-name'), + (SVGNS,u'x1'), + ), + (SVGNS,u'radialGradient'):( + (DRAWNS,u'name'), + (SVGNS,u'fx'), + (SVGNS,u'fy'), + (SVGNS,u'spreadMethod'), + (SVGNS,u'gradientUnits'), + (SVGNS,u'cy'), + (SVGNS,u'cx'), + (SVGNS,u'gradientTransform'), + (DRAWNS,u'display-name'), + (SVGNS,u'r'), + ), + (SVGNS,u'stop'):( + (SVGNS,u'stop-color'), + (SVGNS,u'stop-opacity'), + (SVGNS,u'offset'), + ), + (SVGNS,u'title'):( + ), +# allowed_attributes + (TABLENS,u'background'):( + (TABLENS,u'style-name'), + ), + (TABLENS,u'body'):( + (TABLENS,u'paragraph-style-name'), + (TABLENS,u'style-name'), + ), + (TABLENS,u'calculation-settings'):( + (TABLENS,u'automatic-find-labels'), + (TABLENS,u'case-sensitive'), + (TABLENS,u'search-criteria-must-apply-to-whole-cell'), + (TABLENS,u'precision-as-shown'), + (TABLENS,u'use-regular-expressions'), + (TABLENS,u'use-wildcards'), + (TABLENS,u'null-year'), + ), + (TABLENS,u'cell-address'):( + (TABLENS,u'column'), + (TABLENS,u'table'), + (TABLENS,u'row'), + ), + (TABLENS,u'cell-content-change'):( + (TABLENS,u'id'), + (TABLENS,u'rejecting-change-id'), + (TABLENS,u'acceptance-state'), + ), +# allowed_attributes + (TABLENS,u'cell-content-deletion'):( + (TABLENS,u'id'), + ), + (TABLENS,u'cell-range-source'):( + (TABLENS,u'last-row-spanned'), + (TABLENS,u'last-column-spanned'), + (TABLENS,u'name'), + (TABLENS,u'filter-options'), + (XLINKNS,u'actuate'), + (TABLENS,u'filter-name'), + (XLINKNS,u'href'), + (TABLENS,u'refresh-delay'), + (XLINKNS,u'type'), + ), + (TABLENS,u'change-deletion'):( + (TABLENS,u'id'), + ), + (TABLENS,u'change-track-table-cell'):( + (OFFICENS,u'string-value'), + (TABLENS,u'cell-address'), + (TABLENS,u'number-matrix-columns-spanned'), + (TABLENS,u'number-matrix-rows-spanned'), + (TABLENS,u'matrix-covered'), + (OFFICENS,u'value-type'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (OFFICENS,u'value'), + (TABLENS,u'formula'), + (OFFICENS,u'time-value'), + ), + (TABLENS,u'consolidation'):( + (TABLENS,u'function'), + (TABLENS,u'source-cell-range-addresses'), + (TABLENS,u'target-cell-address'), + (TABLENS,u'link-to-source-data'), + (TABLENS,u'use-labels'), + ), + (TABLENS,u'content-validation'):( + (TABLENS,u'base-cell-address'), + (TABLENS,u'display-list'), + (TABLENS,u'allow-empty-cell'), + (TABLENS,u'name'), + (TABLENS,u'condition'), + ), + (TABLENS,u'content-validations'):( + ), +# allowed_attributes + (TABLENS,u'covered-table-cell'):( + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (OFFICENS,u'string-value'), + (OFFICENS,u'time-value'), + (OFFICENS,u'value'), + (OFFICENS,u'value-type'), + (TABLENS,u'content-validation-name'), + (TABLENS,u'formula'), + (TABLENS,u'number-columns-repeated'), + (TABLENS,u'protect'), + (TABLENS,u'protected'), + (TABLENS,u'style-name'), + (XHTMLNS,u'about'), + (XHTMLNS,u'content'), + (XHTMLNS,u'datatype'), + (XHTMLNS,u'property'), + (XMLNS,u'id'), + ), + (TABLENS,u'cut-offs'):( + ), + (TABLENS,u'data-pilot-display-info'):( + (TABLENS,u'member-count'), + (TABLENS,u'data-field'), + (TABLENS,u'enabled'), + (TABLENS,u'display-member-mode'), + ), + (TABLENS,u'data-pilot-field'):( + (TABLENS,u'selected-page'), + (TABLENS,u'function'), + (TABLENS,u'orientation'), + (TABLENS,u'used-hierarchy'), + (TABLENS,u'is-data-layout-field'), + (TABLENS,u'source-field-name'), + ), + (TABLENS,u'data-pilot-field-reference'):( + (TABLENS,u'member-name'), + (TABLENS,u'field-name'), + (TABLENS,u'member-type'), + (TABLENS,u'type'), + ), +# allowed_attributes + (TABLENS,u'data-pilot-group'):( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-group-member'):( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-groups'):( + (TABLENS,u'date-end'), + (TABLENS,u'end'), + (TABLENS,u'start'), + (TABLENS,u'source-field-name'), + (TABLENS,u'step'), + (TABLENS,u'date-start'), + (TABLENS,u'grouped-by'), + ), + (TABLENS,u'data-pilot-layout-info'):( + (TABLENS,u'add-empty-lines'), + (TABLENS,u'layout-mode'), + ), + (TABLENS,u'data-pilot-level'):( + (TABLENS,u'show-empty'), + ), +# allowed_attributes + (TABLENS,u'data-pilot-member'):( + (TABLENS,u'show-details'), + (TABLENS,u'name'), + (TABLENS,u'display'), + ), + (TABLENS,u'data-pilot-members'):( + ), + (TABLENS,u'data-pilot-sort-info'):( + (TABLENS,u'data-field'), + (TABLENS,u'sort-mode'), + (TABLENS,u'order'), + ), + (TABLENS,u'data-pilot-subtotal'):( + (TABLENS,u'function'), + ), + (TABLENS,u'data-pilot-subtotals'):( + ), + (TABLENS,u'data-pilot-table'):( + (TABLENS,u'buttons'), + (TABLENS,u'application-data'), + (TABLENS,u'name'), + (TABLENS,u'drill-down-on-double-click'), + (TABLENS,u'target-range-address'), + (TABLENS,u'ignore-empty-rows'), + (TABLENS,u'identify-categories'), + (TABLENS,u'show-filter-button'), + (TABLENS,u'grand-total'), + ), +# allowed_attributes + (TABLENS,u'data-pilot-tables'):( + ), + (TABLENS,u'database-range'):( + (TABLENS,u'orientation'), + (TABLENS,u'target-range-address'), + (TABLENS,u'contains-header'), + (TABLENS,u'on-update-keep-size'), + (TABLENS,u'name'), + (TABLENS,u'is-selection'), + (TABLENS,u'refresh-delay'), + (TABLENS,u'display-filter-buttons'), + (TABLENS,u'has-persistent-data'), + (TABLENS,u'on-update-keep-styles'), + ), + (TABLENS,u'database-ranges'):( + ), + (TABLENS,u'database-source-query'):( + (TABLENS,u'query-name'), + (TABLENS,u'database-name'), + ), +# allowed_attributes + (TABLENS,u'database-source-sql'):( + (TABLENS,u'parse-sql-statement'), + (TABLENS,u'database-name'), + (TABLENS,u'sql-statement'), + ), + (TABLENS,u'database-source-table'):( + (TABLENS,u'database-table-name'), + (TABLENS,u'database-name'), + ), + (TABLENS,u'dde-link'):( + ), + (TABLENS,u'dde-links'):( + ), + (TABLENS,u'deletion'):( + (TABLENS,u'rejecting-change-id'), + (TABLENS,u'multi-deletion-spanned'), + (TABLENS,u'acceptance-state'), + (TABLENS,u'table'), + (TABLENS,u'position'), + (TABLENS,u'type'), + (TABLENS,u'id'), + ), +# allowed_attributes + (TABLENS,u'deletions'):( + ), + (TABLENS,u'dependencies'):( + ), + (TABLENS,u'dependency'):( + (TABLENS,u'id'), + ), + (TABLENS,u'desc'):( + ), + (TABLENS,u'detective'):( + ), + (TABLENS,u'error-macro'):( + (TABLENS,u'execute'), + ), + (TABLENS,u'error-message'):( + (TABLENS,u'display'), + (TABLENS,u'message-type'), + (TABLENS,u'title'), + ), + (TABLENS,u'even-columns'):( + (TABLENS,u'paragraph-style-name'), + (TABLENS,u'style-name'), + ), + (TABLENS,u'even-rows'):( + (TABLENS,u'paragraph-style-name'), + (TABLENS,u'style-name'), + ), +# allowed_attributes + (TABLENS,u'filter'):( + (TABLENS,u'target-range-address'), + (TABLENS,u'display-duplicates'), + (TABLENS,u'condition-source-range-address'), + (TABLENS,u'condition-source'), + ), + (TABLENS,u'filter-and'):( + ), + (TABLENS,u'filter-condition'):( + (TABLENS,u'operator'), + (TABLENS,u'field-number'), + (TABLENS,u'data-type'), + (TABLENS,u'case-sensitive'), + (TABLENS,u'value'), + ), + (TABLENS,u'filter-or'):( + ), +# allowed_attributes + (TABLENS,u'filter-set-item'):( + (TABLENS,u'value'), + ), + (TABLENS,u'first-column'):( + (TABLENS,u'paragraph-style-name'), + (TABLENS,u'style-name'), + ), + (TABLENS,u'first-row'):( + (TABLENS,u'paragraph-style-name'), + (TABLENS,u'style-name'), + ), +# allowed_attributes + (TABLENS,u'help-message'):( + (TABLENS,u'display'), + (TABLENS,u'title'), + ), + (TABLENS,u'highlighted-range'):( + (TABLENS,u'contains-error'), + (TABLENS,u'direction'), + (TABLENS,u'marked-invalid'), + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'insertion'):( + (TABLENS,u'count'), + (TABLENS,u'rejecting-change-id'), + (TABLENS,u'acceptance-state'), + (TABLENS,u'table'), + (TABLENS,u'position'), + (TABLENS,u'type'), + (TABLENS,u'id'), + ), + (TABLENS,u'insertion-cut-off'):( + (TABLENS,u'position'), + (TABLENS,u'id'), + ), + (TABLENS,u'iteration'):( + (TABLENS,u'status'), + (TABLENS,u'maximum-difference'), + (TABLENS,u'steps'), + ), +# allowed_attributes + (TABLENS,u'label-range'):( + (TABLENS,u'label-cell-range-address'), + (TABLENS,u'data-cell-range-address'), + (TABLENS,u'orientation'), + ), + (TABLENS,u'label-ranges'):( + ), + (TABLENS,u'last-column'):( + (TABLENS,u'paragraph-style-name'), + (TABLENS,u'style-name'), + ), + (TABLENS,u'last-row'):( + (TABLENS,u'paragraph-style-name'), + (TABLENS,u'style-name'), + ), + (TABLENS,u'movement'):( + (TABLENS,u'id'), + (TABLENS,u'rejecting-change-id'), + (TABLENS,u'acceptance-state'), + ), + (TABLENS,u'movement-cut-off'):( + (TABLENS,u'position'), + (TABLENS,u'end-position'), + (TABLENS,u'start-position'), + ), + (TABLENS,u'named-expression'):( + (TABLENS,u'base-cell-address'), + (TABLENS,u'expression'), + (TABLENS,u'name'), + ), + (TABLENS,u'named-expressions'):( + ), + (TABLENS,u'named-range'):( + (TABLENS,u'range-usable-as'), + (TABLENS,u'base-cell-address'), + (TABLENS,u'name'), + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'null-date'):( + (TABLENS,u'date-value'), + (TABLENS,u'value-type'), + ), + (TABLENS,u'odd-columns'):( + (TABLENS,u'paragraph-style-name'), + (TABLENS,u'style-name'), + ), + (TABLENS,u'odd-rows'):( + (TABLENS,u'paragraph-style-name'), + (TABLENS,u'style-name'), + ), + (TABLENS,u'operation'):( + (TABLENS,u'index'), + (TABLENS,u'name'), + ), + (TABLENS,u'previous'):( + (TABLENS,u'id'), + ), + (TABLENS,u'scenario'):( + (TABLENS,u'comment'), + (TABLENS,u'border-color'), + (TABLENS,u'copy-back'), + (TABLENS,u'is-active'), + (TABLENS,u'protected'), + (TABLENS,u'copy-formulas'), + (TABLENS,u'copy-styles'), + (TABLENS,u'scenario-ranges'), + (TABLENS,u'display-border'), + ), + (TABLENS,u'shapes'):( + ), +# allowed_attributes + (TABLENS,u'sort'):( + (TABLENS,u'case-sensitive'), + (TABLENS,u'embedded-number-behavior'), + (TABLENS,u'algorithm'), + (TABLENS,u'target-range-address'), + (TABLENS,u'country'), + (TABLENS,u'language'), + (TABLENS,u'bind-styles-to-content'), + (TABLENS,u'rfc-language-tag'), + (TABLENS,u'script'), + ), + (TABLENS,u'sort-by'):( + (TABLENS,u'field-number'), + (TABLENS,u'data-type'), + (TABLENS,u'order'), + ), + (TABLENS,u'sort-groups'):( + (TABLENS,u'data-type'), + (TABLENS,u'order'), + ), + (TABLENS,u'source-cell-range'):( + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'source-range-address'):( + (TABLENS,u'column'), + (TABLENS,u'end-column'), + (TABLENS,u'start-table'), + (TABLENS,u'end-row'), + (TABLENS,u'table'), + (TABLENS,u'start-row'), + (TABLENS,u'row'), + (TABLENS,u'end-table'), + (TABLENS,u'start-column'), + ), +# allowed_attributes + (TABLENS,u'source-service'):( + (TABLENS,u'user-name'), + (TABLENS,u'source-name'), + (TABLENS,u'password'), + (TABLENS,u'object-name'), + (TABLENS,u'name'), + ), + (TABLENS,u'subtotal-field'):( + (TABLENS,u'function'), + (TABLENS,u'field-number'), + ), + (TABLENS,u'subtotal-rule'):( + (TABLENS,u'group-by-field-number'), + ), + (TABLENS,u'subtotal-rules'):( + (TABLENS,u'bind-styles-to-content'), + (TABLENS,u'page-breaks-on-group-change'), + (TABLENS,u'case-sensitive'), + ), + (TABLENS,u'table'):( + (TABLENS,u'is-sub-table'), + (TABLENS,u'name'), + (TABLENS,u'print'), + (TABLENS,u'print-ranges'), + (TABLENS,u'protected'), + (TABLENS,u'protection-key'), + (TABLENS,u'protection-key-digest-algorithm'), + (TABLENS,u'style-name'), + (TABLENS,u'template-name'), + (TABLENS,u'use-banding-columns-styles'), + (TABLENS,u'use-banding-rows-styles'), + (TABLENS,u'use-first-column-styles'), + (TABLENS,u'use-first-row-styles'), + (TABLENS,u'use-last-column-styles'), + (TABLENS,u'use-last-row-styles'), + (XMLNS,u'id'), + ), + (TABLENS,u'table-cell'):( + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (OFFICENS,u'string-value'), + (OFFICENS,u'time-value'), + (OFFICENS,u'value'), + (OFFICENS,u'value-type'), + (TABLENS,u'content-validation-name'), + (TABLENS,u'formula'), + (TABLENS,u'number-columns-repeated'), + (TABLENS,u'number-columns-spanned'), + (TABLENS,u'number-matrix-columns-spanned'), + (TABLENS,u'number-matrix-rows-spanned'), + (TABLENS,u'number-rows-spanned'), + (TABLENS,u'protect'), + (TABLENS,u'protected'), + (TABLENS,u'style-name'), + (XHTMLNS,u'about'), + (XHTMLNS,u'content'), + (XHTMLNS,u'datatype'), + (XHTMLNS,u'property'), + (XMLNS,u'id'), + ), +# allowed_attributes + (TABLENS,u'table-column'):( + (TABLENS,u'style-name'), + (TABLENS,u'default-cell-style-name'), + (TABLENS,u'visibility'), + (TABLENS,u'number-columns-repeated'), + (XMLNS,u'id'), + ), + (TABLENS,u'table-column-group'):( + (TABLENS,u'display'), + ), + (TABLENS,u'table-columns'):( + ), + (TABLENS,u'table-header-columns'):( + ), + (TABLENS,u'table-header-rows'):( + ), + (TABLENS,u'table-row'):( + (TABLENS,u'number-rows-repeated'), + (TABLENS,u'style-name'), + (TABLENS,u'visibility'), + (TABLENS,u'default-cell-style-name'), + (XMLNS,u'id'), + ), + (TABLENS,u'table-row-group'):( + (TABLENS,u'display'), + ), + (TABLENS,u'table-rows'):( + ), + (TABLENS,u'table-source'):( + (TABLENS,u'filter-options'), + (XLINKNS,u'actuate'), + (TABLENS,u'filter-name'), + (XLINKNS,u'href'), + (TABLENS,u'mode'), + (TABLENS,u'table-name'), + (XLINKNS,u'type'), + (TABLENS,u'refresh-delay'), + ), +# allowed_attributes + (TABLENS,u'table-template'):( + (TABLENS,u'last-row-end-column'), + (TABLENS,u'first-row-end-column'), + (TABLENS,u'name'), + (TABLENS,u'last-row-start-column'), + (TABLENS,u'first-row-start-column'), + ), + (TABLENS,u'target-range-address'):( + (TABLENS,u'column'), + (TABLENS,u'end-column'), + (TABLENS,u'start-table'), + (TABLENS,u'end-row'), + (TABLENS,u'table'), + (TABLENS,u'start-row'), + (TABLENS,u'row'), + (TABLENS,u'end-table'), + (TABLENS,u'start-column'), + ), + (TABLENS,u'title'):( + ), + (TABLENS,u'tracked-changes'):( + (TABLENS,u'track-changes'), + ), +# allowed_attributes + (TEXTNS,u'a'):( + (OFFICENS,u'name'), + (OFFICENS,u'target-frame-name'), + (OFFICENS,u'title'), + (TEXTNS,u'style-name'), + (TEXTNS,u'visited-style-name'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'show'), + (XLINKNS,u'type'), + ), + (TEXTNS,u'alphabetical-index'):( + (TEXTNS,u'name'), + (TEXTNS,u'protected'), + (TEXTNS,u'protection-key'), + (TEXTNS,u'protection-key-digest-algorithm'), + (TEXTNS,u'style-name'), + (XMLNS,u'id'), + ), + (TEXTNS,u'alphabetical-index-auto-mark-file'):( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (TEXTNS,u'alphabetical-index-entry-template'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'alphabetical-index-mark'):( + (TEXTNS,u'main-entry'), + (TEXTNS,u'key1-phonetic'), + (TEXTNS,u'key2'), + (TEXTNS,u'key1'), + (TEXTNS,u'string-value'), + (TEXTNS,u'key2-phonetic'), + (TEXTNS,u'string-value-phonetic'), + ), +# allowed_attributes + (TEXTNS,u'alphabetical-index-mark-end'):( + (TEXTNS,u'id'), + ), + (TEXTNS,u'alphabetical-index-mark-start'):( + (TEXTNS,u'main-entry'), + (TEXTNS,u'key1-phonetic'), + (TEXTNS,u'key2'), + (TEXTNS,u'key1'), + (TEXTNS,u'string-value-phonetic'), + (TEXTNS,u'key2-phonetic'), + (TEXTNS,u'id'), + ), + (TEXTNS,u'alphabetical-index-source'):( + (FONS,u'country'), + (FONS,u'language'), + (FONS,u'script'), + (STYLENS,u'rfc-language-tag'), + (TEXTNS,u'alphabetical-separators'), + (TEXTNS,u'capitalize-entries'), + (TEXTNS,u'combine-entries'), + (TEXTNS,u'combine-entries-with-dash'), + (TEXTNS,u'combine-entries-with-pp'), + (TEXTNS,u'comma-separated'), + (TEXTNS,u'ignore-case'), + (TEXTNS,u'index-scope'), + (TEXTNS,u'main-entry-style-name'), + (TEXTNS,u'relative-tab-stop-position'), + (TEXTNS,u'sort-algorithm'), + (TEXTNS,u'use-keys-as-entries'), + ), +# allowed_attributes + (TEXTNS,u'author-initials'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'author-name'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'bibliography'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + (TEXTNS,u'protection-key-digest-algorithm'), + (XMLNS,u'id'), + ), + (TEXTNS,u'bibliography-configuration'):( + (FONS,u'country'), + (FONS,u'language'), + (FONS,u'script'), + (STYLENS,u'rfc-language-tag'), + (TEXTNS,u'numbered-entries'), + (TEXTNS,u'prefix'), + (TEXTNS,u'sort-algorithm'), + (TEXTNS,u'sort-by-position'), + (TEXTNS,u'suffix'), + ), + (TEXTNS,u'bibliography-entry-template'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'bibliography-type'), + ), +# allowed_attributes + (TEXTNS,u'bibliography-mark'):( + (TEXTNS,u'address'), + (TEXTNS,u'annote'), + (TEXTNS,u'author'), + (TEXTNS,u'bibliography-type'), + (TEXTNS,u'booktitle'), + (TEXTNS,u'chapter'), + (TEXTNS,u'custom1'), + (TEXTNS,u'custom2'), + (TEXTNS,u'custom3'), + (TEXTNS,u'custom4'), + (TEXTNS,u'custom5'), + (TEXTNS,u'edition'), + (TEXTNS,u'editor'), + (TEXTNS,u'howpublished'), + (TEXTNS,u'identifier'), + (TEXTNS,u'institution'), + (TEXTNS,u'isbn'), + (TEXTNS,u'issn'), + (TEXTNS,u'journal'), + (TEXTNS,u'month'), + (TEXTNS,u'note'), + (TEXTNS,u'number'), + (TEXTNS,u'organizations'), + (TEXTNS,u'pages'), + (TEXTNS,u'publisher'), + (TEXTNS,u'report-type'), + (TEXTNS,u'school'), + (TEXTNS,u'series'), + (TEXTNS,u'title'), + (TEXTNS,u'url'), + (TEXTNS,u'volume'), + (TEXTNS,u'year'), + ), + (TEXTNS,u'bibliography-source'):( + ), + (TEXTNS,u'bookmark'):( + (TEXTNS,u'name'), + (XMLNS,u'id'), + ), + (TEXTNS,u'bookmark-end'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'bookmark-ref'):( + (TEXTNS,u'ref-name'), + (TEXTNS,u'reference-format'), + ), + (TEXTNS,u'bookmark-start'):( + (XHTMLNS,u'about'), + (XHTMLNS,u'content'), + (XHTMLNS,u'datatype'), + (XHTMLNS,u'property'), + (TEXTNS,u'name'), + (XMLNS,u'id'), + ), +# allowed_attributes + (TEXTNS,u'change'):( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'change-end'):( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'change-start'):( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'changed-region'):( + (TEXTNS,u'id'), + (XMLNS,u'id'), + ), + (TEXTNS,u'chapter'):( + (TEXTNS,u'display'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'conditional-text'):( + (TEXTNS,u'string-value-if-true'), + (TEXTNS,u'current-value'), + (TEXTNS,u'string-value-if-false'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'creation-date'):( + (TEXTNS,u'date-value'), + (TEXTNS,u'fixed'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'creation-time'):( + (TEXTNS,u'fixed'), + (TEXTNS,u'time-value'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'creator'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'database-display'):( + (TEXTNS,u'column-name'), + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + (TEXTNS,u'database-name'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'database-name'):( + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + (TEXTNS,u'database-name'), + ), + (TEXTNS,u'database-next'):( + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + (TEXTNS,u'database-name'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'database-row-number'):( + (STYLENS,u'num-format'), + (TEXTNS,u'database-name'), + (TEXTNS,u'value'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + ), + (TEXTNS,u'database-row-select'):( + (TEXTNS,u'row-number'), + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + (TEXTNS,u'database-name'), + (TEXTNS,u'condition'), + ), +# allowed_attributes + (TEXTNS,u'date'):( + (TEXTNS,u'date-value'), + (TEXTNS,u'fixed'), + (TEXTNS,u'date-adjust'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'dde-connection'):( + (TEXTNS,u'connection-name'), + ), + (TEXTNS,u'dde-connection-decl'):( + (OFFICENS,u'automatic-update'), + (OFFICENS,u'dde-topic'), + (OFFICENS,u'dde-application'), + (OFFICENS,u'name'), + (OFFICENS,u'dde-item'), + ), + (TEXTNS,u'dde-connection-decls'):( + ), + (TEXTNS,u'deletion'):( + ), + (TEXTNS,u'description'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'editing-cycles'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'editing-duration'):( + (TEXTNS,u'duration'), + (TEXTNS,u'fixed'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'execute-macro'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'expression'):( + (TEXTNS,u'display'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (STYLENS,u'data-style-name'), + (OFFICENS,u'value-type'), + (TEXTNS,u'formula'), + (OFFICENS,u'time-value'), + ), + (TEXTNS,u'file-name'):( + (TEXTNS,u'fixed'), + (TEXTNS,u'display'), + ), +# allowed_attributes + (TEXTNS,u'format-change'):( + ), + (TEXTNS,u'h'):( + (TEXTNS,u'restart-numbering'), + (TEXTNS,u'cond-style-name'), + (TEXTNS,u'is-list-header'), + (TEXTNS,u'style-name'), + (TEXTNS,u'class-names'), + (TEXTNS,u'start-value'), + (TEXTNS,u'id'), + (TEXTNS,u'outline-level'), + (XHTMLNS,u'about'), + (XHTMLNS,u'content'), + (XHTMLNS,u'datatype'), + (XHTMLNS,u'property'), + (XMLNS,u'id'), + ), + (TEXTNS,u'hidden-paragraph'):( + (TEXTNS,u'is-hidden'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'hidden-text'):( + (TEXTNS,u'string-value'), + (TEXTNS,u'is-hidden'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'illustration-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + (TEXTNS,u'protection-key-digest-algorithm'), + (XMLNS,u'id'), + ), + (TEXTNS,u'illustration-index-entry-template'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'illustration-index-source'):( + (TEXTNS,u'index-scope'), + (TEXTNS,u'caption-sequence-name'), + (TEXTNS,u'use-caption'), + (TEXTNS,u'caption-sequence-format'), + (TEXTNS,u'relative-tab-stop-position'), + ), + (TEXTNS,u'index-body'):( + ), + (TEXTNS,u'index-entry-bibliography'):( + (TEXTNS,u'bibliography-data-field'), + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-chapter'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + (TEXTNS,u'display'), + ), +# allowed_attributes + (TEXTNS,u'index-entry-link-end'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-link-start'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-page-number'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-span'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-tab-stop'):( + (STYLENS,u'position'), + (TEXTNS,u'style-name'), + (STYLENS,u'type'), + (STYLENS,u'leader-char'), + ), + (TEXTNS,u'index-entry-text'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-source-style'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-source-styles'):( + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'index-title'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + (TEXTNS,u'protection-key-digest-algorithm'), + (XMLNS,u'id'), + ), + (TEXTNS,u'index-title-template'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'initial-creator'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'insertion'):( + ), +# allowed_attributes + (TEXTNS,u'keywords'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'line-break'):( + ), + (TEXTNS,u'linenumbering-configuration'):( + (TEXTNS,u'number-position'), + (TEXTNS,u'number-lines'), + (STYLENS,u'num-format'), + (TEXTNS,u'count-empty-lines'), + (TEXTNS,u'count-in-text-boxes'), + (TEXTNS,u'style-name'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'increment'), + (TEXTNS,u'offset'), + (TEXTNS,u'restart-on-page'), + ), + (TEXTNS,u'linenumbering-separator'):( + (TEXTNS,u'increment'), + ), + (TEXTNS,u'list'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'continue-numbering'), + (TEXTNS,u'continue-list'), + (XMLNS,u'id'), + ), + (TEXTNS,u'list-header'):( + (XMLNS,u'id'), + ), +# allowed_attributes + (TEXTNS,u'list-item'):( + (TEXTNS,u'start-value'), + (TEXTNS,u'style-override'), + (XMLNS,u'id'), + ), + (TEXTNS,u'list-level-style-bullet'):( + (TEXTNS,u'level'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-suffix'), + (TEXTNS,u'bullet-relative-size'), + (TEXTNS,u'style-name'), + (TEXTNS,u'bullet-char'), + ), + (TEXTNS,u'list-level-style-image'):( + (XLINKNS,u'show'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (TEXTNS,u'level'), + ), + (TEXTNS,u'list-level-style-number'):( + (TEXTNS,u'level'), + (TEXTNS,u'display-levels'), + (STYLENS,u'num-format'), + (STYLENS,u'num-suffix'), + (TEXTNS,u'style-name'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'start-value'), + ), +# allowed_attributes + (TEXTNS,u'list-style'):( + (TEXTNS,u'consecutive-numbering'), + (STYLENS,u'display-name'), + (STYLENS,u'name'), + ), + (TEXTNS,u'measure'):( + (TEXTNS,u'kind'), + ), +# allowed_attributes + (TEXTNS,u'meta'):( + (XHTMLNS,u'about'), + (XHTMLNS,u'content'), + (XMLNS,u'id'), + (XHTMLNS,u'property'), + (XHTMLNS,u'datatype'), + ), +# allowed_attributes + (TEXTNS,u'meta-field'):( + (STYLENS,u'data-style-name'), + (XMLNS,u'id'), + ), + (TEXTNS,u'modification-date'):( + (TEXTNS,u'date-value'), + (TEXTNS,u'fixed'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'modification-time'):( + (TEXTNS,u'fixed'), + (TEXTNS,u'time-value'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'note'):( + (TEXTNS,u'note-class'), + (TEXTNS,u'id'), + ), + (TEXTNS,u'note-body'):( + ), + (TEXTNS,u'note-citation'):( + (TEXTNS,u'label'), + ), + (TEXTNS,u'note-continuation-notice-backward'):( + ), + (TEXTNS,u'note-continuation-notice-forward'):( + ), + (TEXTNS,u'note-ref'):( + (TEXTNS,u'ref-name'), + (TEXTNS,u'note-class'), + (TEXTNS,u'reference-format'), + ), + (TEXTNS,u'notes-configuration'):( + (TEXTNS,u'citation-body-style-name'), + (STYLENS,u'num-format'), + (TEXTNS,u'default-style-name'), + (STYLENS,u'num-suffix'), + (TEXTNS,u'start-numbering-at'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'citation-style-name'), + (TEXTNS,u'footnotes-position'), + (TEXTNS,u'master-page-name'), + (TEXTNS,u'start-value'), + (TEXTNS,u'note-class'), + ), + (TEXTNS,u'number'):( + ), + (TEXTNS,u'numbered-paragraph'):( + (TEXTNS,u'continue-numbering'), + (TEXTNS,u'level'), + (TEXTNS,u'list-id'), + (TEXTNS,u'start-value'), + (TEXTNS,u'style-name'), + (XMLNS,u'id'), + ), + (TEXTNS,u'object-count'):( + (STYLENS,u'num-format'), + (STYLENS,u'num-letter-sync'), + ), + (TEXTNS,u'object-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + (TEXTNS,u'protection-key-digest-algorithm'), + (XMLNS,u'id'), + ), +# allowed_attributes + (TEXTNS,u'object-index-entry-template'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'object-index-source'):( + (TEXTNS,u'use-draw-objects'), + (TEXTNS,u'use-math-objects'), + (TEXTNS,u'relative-tab-stop-position'), + (TEXTNS,u'use-chart-objects'), + (TEXTNS,u'index-scope'), + (TEXTNS,u'use-spreadsheet-objects'), + (TEXTNS,u'use-other-objects'), + ), + (TEXTNS,u'outline-level-style'):( + (TEXTNS,u'level'), + (TEXTNS,u'display-levels'), + (STYLENS,u'num-format'), + (STYLENS,u'num-suffix'), + (TEXTNS,u'style-name'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'start-value'), + ), + (TEXTNS,u'outline-style'):( + (STYLENS,u'name'), + ), +# allowed_attributes + (TEXTNS,u'p'):( + (TEXTNS,u'class-names'), + (TEXTNS,u'cond-style-name'), + (TEXTNS,u'id'), + (TEXTNS,u'style-name'), + (XHTMLNS,u'about'), + (XHTMLNS,u'content'), + (XHTMLNS,u'datatype'), + (XHTMLNS,u'property'), + (XMLNS,u'id'), + ), + (TEXTNS,u'page'):( + (TEXTNS,u'master-page-name'), + ), + (TEXTNS,u'page-continuation'):( + (TEXTNS,u'string-value'), + (TEXTNS,u'select-page'), + ), + (TEXTNS,u'page-number'):( + (TEXTNS,u'page-adjust'), + (STYLENS,u'num-format'), + (TEXTNS,u'fixed'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'select-page'), + ), + (TEXTNS,u'page-sequence'):( + ), + (TEXTNS,u'page-variable-get'):( + (STYLENS,u'num-format'), + (STYLENS,u'num-letter-sync'), + ), + (TEXTNS,u'page-variable-set'):( + (TEXTNS,u'active'), + (TEXTNS,u'page-adjust'), + ), + (TEXTNS,u'placeholder'):( + (TEXTNS,u'placeholder-type'), + (TEXTNS,u'description'), + ), + (TEXTNS,u'print-date'):( + (TEXTNS,u'date-value'), + (TEXTNS,u'fixed'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'print-time'):( + (TEXTNS,u'fixed'), + (TEXTNS,u'time-value'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'printed-by'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'reference-mark'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'reference-mark-end'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'reference-mark-start'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'ruby'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'ruby-base'):( + ), + (TEXTNS,u'ruby-text'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u's'):( + (TEXTNS,u'c'), + ), + (TEXTNS,u'script'):( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (SCRIPTNS,u'language'), + ), +# allowed_attributes + (TEXTNS,u'section'):( + (TEXTNS,u'condition'), + (TEXTNS,u'display'), + (TEXTNS,u'name'), + (TEXTNS,u'protected'), + (TEXTNS,u'protection-key'), + (TEXTNS,u'protection-key-digest-algorithm'), + (TEXTNS,u'style-name'), + (XMLNS,u'id'), + ), + (TEXTNS,u'section-source'):( + (TEXTNS,u'filter-name'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (TEXTNS,u'section-name'), + (XLINKNS,u'show'), + ), + (TEXTNS,u'sender-city'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-company'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-country'):( + (TEXTNS,u'fixed'), + ), +# allowed_attributes + (TEXTNS,u'sender-email'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-fax'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-firstname'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-initials'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-lastname'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-phone-private'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-phone-work'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-position'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-postal-code'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-state-or-province'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-street'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-title'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sequence'):( + (TEXTNS,u'formula'), + (STYLENS,u'num-format'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'name'), + (TEXTNS,u'ref-name'), + ), + (TEXTNS,u'sequence-decl'):( + (TEXTNS,u'separation-character'), + (TEXTNS,u'display-outline-level'), + (TEXTNS,u'name'), + ), + (TEXTNS,u'sequence-decls'):( + ), + (TEXTNS,u'sequence-ref'):( + (TEXTNS,u'ref-name'), + (TEXTNS,u'reference-format'), + ), + (TEXTNS,u'sheet-name'):( + ), + (TEXTNS,u'soft-page-break'):( + ), + (TEXTNS,u'sort-key'):( + (TEXTNS,u'sort-ascending'), + (TEXTNS,u'key'), + ), +# allowed_attributes + (TEXTNS,u'span'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'class-names'), + ), + (TEXTNS,u'subject'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'tab'):( + (TEXTNS,u'tab-ref'), + ), + (TEXTNS,u'table-formula'):( + (TEXTNS,u'formula'), + (STYLENS,u'data-style-name'), + (TEXTNS,u'display'), + ), + (TEXTNS,u'table-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + (TEXTNS,u'protection-key-digest-algorithm'), + (XMLNS,u'id'), + ), + (TEXTNS,u'table-index-entry-template'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'table-index-source'):( + (TEXTNS,u'index-scope'), + (TEXTNS,u'caption-sequence-name'), + (TEXTNS,u'use-caption'), + (TEXTNS,u'caption-sequence-format'), + (TEXTNS,u'relative-tab-stop-position'), + ), +# allowed_attributes + (TEXTNS,u'table-of-content'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + (TEXTNS,u'protection-key-digest-algorithm'), + (XMLNS,u'id'), + ), + (TEXTNS,u'table-of-content-entry-template'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'table-of-content-source'):( + (TEXTNS,u'index-scope'), + (TEXTNS,u'outline-level'), + (TEXTNS,u'relative-tab-stop-position'), + (TEXTNS,u'use-index-marks'), + (TEXTNS,u'use-outline-level'), + (TEXTNS,u'use-index-source-styles'), + ), + (TEXTNS,u'template-name'):( + (TEXTNS,u'display'), + ), + (TEXTNS,u'text-input'):( + (TEXTNS,u'description'), + ), + (TEXTNS,u'time'):( + (TEXTNS,u'time-adjust'), + (TEXTNS,u'fixed'), + (TEXTNS,u'time-value'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'title'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'toc-mark'):( + (TEXTNS,u'string-value'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'toc-mark-end'):( + (TEXTNS,u'id'), + ), + (TEXTNS,u'toc-mark-start'):( + (TEXTNS,u'id'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'tracked-changes'):( + (TEXTNS,u'track-changes'), + ), + (TEXTNS,u'user-defined'):( + (TEXTNS,u'name'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'date-value'), + (STYLENS,u'data-style-name'), + (TEXTNS,u'fixed'), + (OFFICENS,u'time-value'), + ), + (TEXTNS,u'user-field-decl'):( + (TEXTNS,u'name'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (OFFICENS,u'value-type'), + (TEXTNS,u'formula'), + (OFFICENS,u'time-value'), + ), + (TEXTNS,u'user-field-decls'):( + ), + (TEXTNS,u'user-field-get'):( + (STYLENS,u'data-style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'display'), + ), +# allowed_attributes + (TEXTNS,u'user-field-input'):( + (STYLENS,u'data-style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'description'), + ), + (TEXTNS,u'user-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + (TEXTNS,u'protection-key-digest-algorithm'), + (XMLNS,u'id'), + ), + (TEXTNS,u'user-index-entry-template'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'user-index-mark'):( + (TEXTNS,u'index-name'), + (TEXTNS,u'string-value'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'user-index-mark-end'):( + (TEXTNS,u'id'), + ), + (TEXTNS,u'user-index-mark-start'):( + (TEXTNS,u'index-name'), + (TEXTNS,u'id'), + (TEXTNS,u'outline-level'), + ), +# allowed_attributes + (TEXTNS,u'user-index-source'):( + (TEXTNS,u'copy-outline-levels'), + (TEXTNS,u'index-name'), + (TEXTNS,u'index-scope'), + (TEXTNS,u'relative-tab-stop-position'), + (TEXTNS,u'use-floating-frames'), + (TEXTNS,u'use-graphics'), + (TEXTNS,u'use-index-marks'), + (TEXTNS,u'use-index-source-styles'), + (TEXTNS,u'use-objects'), + (TEXTNS,u'use-tables'), + ), + (TEXTNS,u'variable-decl'):( + (TEXTNS,u'name'), + (OFFICENS,u'value-type'), + ), + (TEXTNS,u'variable-decls'):( + ), + (TEXTNS,u'variable-get'):( + (STYLENS,u'data-style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'display'), + ), + (TEXTNS,u'variable-input'):( + (STYLENS,u'data-style-name'), + (TEXTNS,u'display'), + (TEXTNS,u'name'), + (OFFICENS,u'value-type'), + (TEXTNS,u'description'), + ), + (TEXTNS,u'variable-set'):( + (TEXTNS,u'name'), + (TEXTNS,u'display'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (STYLENS,u'data-style-name'), + (OFFICENS,u'value-type'), + (TEXTNS,u'formula'), + (OFFICENS,u'time-value'), + ), +# allowed_attributes +} diff --git a/odf/load.py b/odf/load.py new file mode 100644 index 0000000..35bdb82 --- /dev/null +++ b/odf/load.py @@ -0,0 +1,115 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2007-2008 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +# This script is to be embedded in opendocument.py later +# The purpose is to read an ODT/ODP/ODS file and create the datastructure +# in memory. The user should then be able to make operations and then save +# the structure again. + +from xml.sax import make_parser,handler +from xml.sax.xmlreader import InputSource +import xml.sax.saxutils +from element import Element +from namespaces import OFFICENS +try: + from cStringIO import StringIO +except ImportError: + from io import StringIO + +# +# Parse the XML files +# +class LoadParser(handler.ContentHandler): + """ Extract headings from content.xml of an ODT file """ + triggers = ( + (OFFICENS, 'automatic-styles'), (OFFICENS, 'body'), + (OFFICENS, 'font-face-decls'), (OFFICENS, 'master-styles'), + (OFFICENS, 'meta'), (OFFICENS, 'scripts'), + (OFFICENS, 'settings'), (OFFICENS, 'styles') ) + + def __init__(self, document): + self.doc = document + self.data = [] + self.level = 0 + self.parse = False + + def characters(self, data): + if self.parse == False: + return + self.data.append(data) + + def startElementNS(self, tag, qname, attrs): + if tag in self.triggers: + self.parse = True + if self.doc._parsing != "styles.xml" and tag == (OFFICENS, 'font-face-decls'): + self.parse = False + if self.parse == False: + return + + self.level = self.level + 1 + # Add any accumulated text content + content = ''.join(self.data) + if len(content.strip()) > 0: + self.parent.addText(content, check_grammar=False) + self.data = [] + # Create the element + attrdict = {} + for (att,value) in attrs.items(): + attrdict[att] = value + try: + e = Element(qname = tag, qattributes=attrdict, check_grammar=False) + self.curr = e + except AttributeError as v: + print ("Error: %s" % v) + + if tag == (OFFICENS, 'automatic-styles'): + e = self.doc.automaticstyles + elif tag == (OFFICENS, 'body'): + e = self.doc.body + elif tag == (OFFICENS, 'master-styles'): + e = self.doc.masterstyles + elif tag == (OFFICENS, 'meta'): + e = self.doc.meta + elif tag == (OFFICENS,'scripts'): + e = self.doc.scripts + elif tag == (OFFICENS,'settings'): + e = self.doc.settings + elif tag == (OFFICENS,'styles'): + e = self.doc.styles + elif self.doc._parsing == "styles.xml" and tag == (OFFICENS, 'font-face-decls'): + e = self.doc.fontfacedecls + elif hasattr(self,'parent'): + self.parent.addElement(e, check_grammar=False) + self.parent = e + + + def endElementNS(self, tag, qname): + if self.parse == False: + return + self.level = self.level - 1 + str = ''.join(self.data) + if len(str.strip()) > 0: + self.curr.addText(str, check_grammar=False) + self.data = [] + self.curr = self.curr.parentNode + self.parent = self.curr + if tag in self.triggers: + self.parse = False diff --git a/odf/manifest.py b/odf/manifest.py new file mode 100644 index 0000000..1d5524f --- /dev/null +++ b/odf/manifest.py @@ -0,0 +1,44 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +# + +import sys, os.path +sys.path.append(os.path.dirname(__file__)) + +from namespaces import MANIFESTNS +from element import Element + +# Autogenerated +def Manifest(**args): + return Element(qname = (MANIFESTNS,'manifest'), **args) + +def FileEntry(**args): + return Element(qname = (MANIFESTNS,'file-entry'), **args) + +def EncryptionData(**args): + return Element(qname = (MANIFESTNS,'encryption-data'), **args) + +def Algorithm(**args): + return Element(qname = (MANIFESTNS,'algorithm'), **args) + +def KeyDerivation(**args): + return Element(qname = (MANIFESTNS,'key-derivation'), **args) + diff --git a/odf/math.py b/odf/math.py new file mode 100644 index 0000000..5dc38df --- /dev/null +++ b/odf/math.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import MATHNS +from element import Element + +# ODF 1.0 section 12.5 +# Mathematical content is represented by MathML 2.0 + +# Autogenerated +def Math(**args): + return Element(qname = (MATHNS,'math'), **args) + diff --git a/odf/meta.py b/odf/meta.py new file mode 100644 index 0000000..68b1d19 --- /dev/null +++ b/odf/meta.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import METANS +from element import Element + +# Autogenerated +def AutoReload(**args): + return Element(qname = (METANS,'auto-reload'), **args) + +def CreationDate(**args): + return Element(qname = (METANS,'creation-date'), **args) + +def DateString(**args): + return Element(qname = (METANS,'date-string'), **args) + +def DocumentStatistic(**args): + return Element(qname = (METANS,'document-statistic'), **args) + +def EditingCycles(**args): + return Element(qname = (METANS,'editing-cycles'), **args) + +def EditingDuration(**args): + return Element(qname = (METANS,'editing-duration'), **args) + +def Generator(**args): + return Element(qname = (METANS,'generator'), **args) + +def HyperlinkBehaviour(**args): + return Element(qname = (METANS,'hyperlink-behaviour'), **args) + +def InitialCreator(**args): + return Element(qname = (METANS,'initial-creator'), **args) + +def Keyword(**args): + return Element(qname = (METANS,'keyword'), **args) + +def PrintDate(**args): + return Element(qname = (METANS,'print-date'), **args) + +def PrintedBy(**args): + return Element(qname = (METANS,'printed-by'), **args) + +def Template(**args): + args.setdefault('type', 'simple') + return Element(qname = (METANS,'template'), **args) + +def UserDefined(**args): + return Element(qname = (METANS,'user-defined'), **args) + diff --git a/odf/namespaces.py b/odf/namespaces.py new file mode 100644 index 0000000..9573d77 --- /dev/null +++ b/odf/namespaces.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2013 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +TOOLSVERSION = u"ODFPY/1.3.1" + +ANIMNS = u"urn:oasis:names:tc:opendocument:xmlns:animation:1.0" +CHARTNS = u"urn:oasis:names:tc:opendocument:xmlns:chart:1.0" +CHARTOOONS = u"http://openoffice.org/2010/chart" +CONFIGNS = u"urn:oasis:names:tc:opendocument:xmlns:config:1.0" +CSS3TNS = u"http://www.w3.org/TR/css3-text/" +#DBNS = u"http://openoffice.org/2004/database" +DBNS = u"urn:oasis:names:tc:opendocument:xmlns:database:1.0" +DCNS = u"http://purl.org/dc/elements/1.1/" +DOMNS = u"http://www.w3.org/2001/xml-events" +DR3DNS = u"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" +DRAWNS = u"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" +FIELDNS = u"urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" +FONS = u"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" +FORMNS = u"urn:oasis:names:tc:opendocument:xmlns:form:1.0" +FORMXNS = u"urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" +GRDDLNS = u"http://www.w3.org/2003/g/data-view#" +KOFFICENS = u"http://www.koffice.org/2005/" +MANIFESTNS = u"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" +MATHNS = u"http://www.w3.org/1998/Math/MathML" +METANS = u"urn:oasis:names:tc:opendocument:xmlns:meta:1.0" +NUMBERNS = u"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" +OFFICENS = u"urn:oasis:names:tc:opendocument:xmlns:office:1.0" +OFNS = u"urn:oasis:names:tc:opendocument:xmlns:of:1.2" +OOOCNS = u"http://openoffice.org/2004/calc" +OOONS = u"http://openoffice.org/2004/office" +OOOWNS = u"http://openoffice.org/2004/writer" +PRESENTATIONNS = u"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" +RDFANS = u"http://docs.oasis-open.org/opendocument/meta/rdfa#" +RPTNS = u"http://openoffice.org/2005/report" +SCRIPTNS = u"urn:oasis:names:tc:opendocument:xmlns:script:1.0" +SMILNS = u"urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" +STYLENS = u"urn:oasis:names:tc:opendocument:xmlns:style:1.0" +SVGNS = u"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" +TABLENS = u"urn:oasis:names:tc:opendocument:xmlns:table:1.0" +TABLEOOONS = u"http://openoffice.org/2009/table" +TEXTNS = u"urn:oasis:names:tc:opendocument:xmlns:text:1.0" +XFORMSNS = u"http://www.w3.org/2002/xforms" +XHTMLNS = u"http://www.w3.org/1999/xhtml" +XLINKNS = u"http://www.w3.org/1999/xlink" +XMLNS = u"http://www.w3.org/XML/1998/namespace" +XSDNS = u"http://www.w3.org/2001/XMLSchema" +XSINS = u"http://www.w3.org/2001/XMLSchema-instance" + +nsdict = { + ANIMNS: u'anim', + CHARTNS: u'chart', + CHARTOOONS: u'chartooo', + CONFIGNS: u'config', + CSS3TNS: u'css3t', + DBNS: u'db', + DCNS: u'dc', + DOMNS: u'dom', + DR3DNS: u'dr3d', + DRAWNS: u'draw', + FIELDNS: u'field', + FONS: u'fo', + FORMNS: u'form', + FORMXNS: u'formx', + GRDDLNS: u'grddl', + KOFFICENS: u'koffice', + MANIFESTNS: u'manifest', + MATHNS: u'math', + METANS: u'meta', + NUMBERNS: u'number', + OFFICENS: u'office', + OFNS: u'of', + OOONS: u'ooo', + OOOWNS: u'ooow', + OOOCNS: u'oooc', + PRESENTATIONNS: u'presentation', + RDFANS: u'rdfa', + RPTNS: u'rpt', + SCRIPTNS: u'script', + SMILNS: u'smil', + STYLENS: u'style', + SVGNS: u'svg', + TABLENS: u'table', + TABLEOOONS: u'tableooo', + TEXTNS: u'text', + XFORMSNS: u'xforms', + XLINKNS: u'xlink', + XHTMLNS: u'xhtml', + XMLNS: u'xml', + XSDNS: u'xsd', + XSINS: u'xsi', +} diff --git a/odf/number.py b/odf/number.py new file mode 100644 index 0000000..12d81cb --- /dev/null +++ b/odf/number.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import NUMBERNS +from element import Element +from style import StyleElement + + +# Autogenerated +def AmPm(**args): + return Element(qname = (NUMBERNS,'am-pm'), **args) + +def Boolean(**args): + return Element(qname = (NUMBERNS,'boolean'), **args) + +def BooleanStyle(**args): + return StyleElement(qname = (NUMBERNS,'boolean-style'), **args) + +def CurrencyStyle(**args): + return StyleElement(qname = (NUMBERNS,'currency-style'), **args) + +def CurrencySymbol(**args): + return Element(qname = (NUMBERNS,'currency-symbol'), **args) + +def DateStyle(**args): + return StyleElement(qname = (NUMBERNS,'date-style'), **args) + +def Day(**args): + return Element(qname = (NUMBERNS,'day'), **args) + +def DayOfWeek(**args): + return Element(qname = (NUMBERNS,'day-of-week'), **args) + +def EmbeddedText(**args): + return Element(qname = (NUMBERNS,'embedded-text'), **args) + +def Era(**args): + return Element(qname = (NUMBERNS,'era'), **args) + +def Fraction(**args): + return Element(qname = (NUMBERNS,'fraction'), **args) + +def Hours(**args): + return Element(qname = (NUMBERNS,'hours'), **args) + +def Minutes(**args): + return Element(qname = (NUMBERNS,'minutes'), **args) + +def Month(**args): + return Element(qname = (NUMBERNS,'month'), **args) + +def Number(**args): + return Element(qname = (NUMBERNS,'number'), **args) + +def NumberStyle(**args): + return StyleElement(qname = (NUMBERNS,'number-style'), **args) + +def PercentageStyle(**args): + return StyleElement(qname = (NUMBERNS,'percentage-style'), **args) + +def Quarter(**args): + return Element(qname = (NUMBERNS,'quarter'), **args) + +def ScientificNumber(**args): + return Element(qname = (NUMBERNS,'scientific-number'), **args) + +def Seconds(**args): + return Element(qname = (NUMBERNS,'seconds'), **args) + +def Text(**args): + return Element(qname = (NUMBERNS,'text'), **args) + +def TextContent(**args): + return Element(qname = (NUMBERNS,'text-content'), **args) + +def TextStyle(**args): + return StyleElement(qname = (NUMBERNS,'text-style'), **args) + +def TimeStyle(**args): + return StyleElement(qname = (NUMBERNS,'time-style'), **args) + +def WeekOfYear(**args): + return Element(qname = (NUMBERNS,'week-of-year'), **args) + +def Year(**args): + return Element(qname = (NUMBERNS,'year'), **args) + diff --git a/odf/odf2moinmoin.py b/odf/odf2moinmoin.py new file mode 100644 index 0000000..167fcda --- /dev/null +++ b/odf/odf2moinmoin.py @@ -0,0 +1,579 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2008 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# See http://trac.edgewall.org/wiki/WikiFormatting +# +# Contributor(s): +# + +import sys, zipfile, xml.dom.minidom +from namespaces import nsdict +from elementtypes import * + +IGNORED_TAGS = [ + 'draw:a' + 'draw:g', + 'draw:line', + 'draw:object-ole', + 'office:annotation', + 'presentation:notes', + 'svg:desc', +] + [ nsdict[item[0]]+":"+item[1] for item in empty_elements] + +INLINE_TAGS = [ nsdict[item[0]]+":"+item[1] for item in inline_elements] + + +class TextProps: + """ Holds properties for a text style. """ + + def __init__(self): + + self.italic = False + self.bold = False + self.fixed = False + self.underlined = False + self.strikethrough = False + self.superscript = False + self.subscript = False + + def setItalic(self, value): + if value == "italic": + self.italic = True + elif value == "normal": + self.italic = False + + def setBold(self, value): + if value == "bold": + self.bold = True + elif value == "normal": + self.bold = False + + def setFixed(self, value): + self.fixed = value + + def setUnderlined(self, value): + if value and value != "none": + self.underlined = True + + def setStrikethrough(self, value): + if value and value != "none": + self.strikethrough = True + + def setPosition(self, value): + if value is None or value == '': + return + posisize = value.split(' ') + textpos = posisize[0] + if textpos.find('%') == -1: + if textpos == "sub": + self.superscript = False + self.subscript = True + elif textpos == "super": + self.superscript = True + self.subscript = False + else: + itextpos = int(textpos[:textpos.find('%')]) + if itextpos > 10: + self.superscript = False + self.subscript = True + elif itextpos < -10: + self.superscript = True + self.subscript = False + + def __str__(self): + + return "[italic=%s, bold=i%s, fixed=%s]" % (str(self.italic), + str(self.bold), + str(self.fixed)) + +class ParagraphProps: + """ Holds properties of a paragraph style. """ + + def __init__(self): + + self.blockquote = False + self.headingLevel = 0 + self.code = False + self.title = False + self.indented = 0 + + def setIndented(self, value): + self.indented = value + + def setHeading(self, level): + self.headingLevel = level + + def setTitle(self, value): + self.title = value + + def setCode(self, value): + self.code = value + + + def __str__(self): + + return "[bq=%s, h=%d, code=%s]" % (str(self.blockquote), + self.headingLevel, + str(self.code)) + + +class ListProperties: + """ Holds properties for a list style. """ + + def __init__(self): + self.ordered = False + + def setOrdered(self, value): + self.ordered = value + + + +class ODF2MoinMoin(object): + + + def __init__(self, filepath): + self.footnotes = [] + self.footnoteCounter = 0 + self.textStyles = {"Standard": TextProps()} + self.paragraphStyles = {"Standard": ParagraphProps()} + self.listStyles = {} + self.fixedFonts = [] + self.hasTitle = 0 + self.lastsegment = None + + # Tags + self.elements = { + 'draw:page': self.textToString, + 'draw:frame': self.textToString, + 'draw:image': self.draw_image, + 'draw:text-box': self.textToString, + 'text:a': self.text_a, + 'text:note': self.text_note, + } + for tag in IGNORED_TAGS: + self.elements[tag] = self.do_nothing + + for tag in INLINE_TAGS: + self.elements[tag] = self.inline_markup + self.elements['text:line-break'] = self.text_line_break + self.elements['text:s'] = self.text_s + self.elements['text:tab'] = self.text_tab + + self.load(filepath) + + def processFontDeclarations(self, fontDecl): + """ Extracts necessary font information from a font-declaration + element. + """ + for fontFace in fontDecl.getElementsByTagName("style:font-face"): + if fontFace.getAttribute("style:font-pitch") == "fixed": + self.fixedFonts.append(fontFace.getAttribute("style:name")) + + + + def extractTextProperties(self, style, parent=None): + """ Extracts text properties from a style element. """ + + textProps = TextProps() + + if parent: + parentProp = self.textStyles.get(parent, None) + if parentProp: + textProp = parentProp + + textPropEl = style.getElementsByTagName("style:text-properties") + if not textPropEl: return textProps + + textPropEl = textPropEl[0] + + textProps.setItalic(textPropEl.getAttribute("fo:font-style")) + textProps.setBold(textPropEl.getAttribute("fo:font-weight")) + textProps.setUnderlined(textPropEl.getAttribute("style:text-underline-style")) + textProps.setStrikethrough(textPropEl.getAttribute("style:text-line-through-style")) + textProps.setPosition(textPropEl.getAttribute("style:text-position")) + + if textPropEl.getAttribute("style:font-name") in self.fixedFonts: + textProps.setFixed(True) + + return textProps + + def extractParagraphProperties(self, style, parent=None): + """ Extracts paragraph properties from a style element. """ + + paraProps = ParagraphProps() + + name = style.getAttribute("style:name") + + if name.startswith("Heading_20_"): + level = name[11:] + try: + level = int(level) + paraProps.setHeading(level) + except: + level = 0 + + if name == "Title": + paraProps.setTitle(True) + + paraPropEl = style.getElementsByTagName("style:paragraph-properties") + if paraPropEl: + paraPropEl = paraPropEl[0] + leftMargin = paraPropEl.getAttribute("fo:margin-left") + if leftMargin: + try: + leftMargin = float(leftMargin[:-2]) + if leftMargin > 0.01: + paraProps.setIndented(True) + except: + pass + + textProps = self.extractTextProperties(style) + if textProps.fixed: + paraProps.setCode(True) + + return paraProps + + + def processStyles(self, styleElements): + """ Runs through "style" elements extracting necessary information. + """ + + for style in styleElements: + + name = style.getAttribute("style:name") + + if name == "Standard": continue + + family = style.getAttribute("style:family") + parent = style.getAttribute("style:parent-style-name") + + if family == "text": + self.textStyles[name] = self.extractTextProperties(style, parent) + + elif family == "paragraph": + self.paragraphStyles[name] = \ + self.extractParagraphProperties(style, parent) + self.textStyles[name] = self.extractTextProperties(style, parent) + + def processListStyles(self, listStyleElements): + + for style in listStyleElements: + name = style.getAttribute("style:name") + + prop = ListProperties() + if style.hasChildNodes(): + subitems = [el for el in style.childNodes + if el.nodeType == xml.dom.Node.ELEMENT_NODE + and el.tagName == "text:list-level-style-number"] + if len(subitems) > 0: + prop.setOrdered(True) + + self.listStyles[name] = prop + + + def load(self, filepath): + """ Loads an ODT file. """ + + zip = zipfile.ZipFile(filepath) + + styles_doc = xml.dom.minidom.parseString(zip.read("styles.xml")) + fontfacedecls = styles_doc.getElementsByTagName("office:font-face-decls") + if fontfacedecls: + self.processFontDeclarations(fontfacedecls[0]) + self.processStyles(styles_doc.getElementsByTagName("style:style")) + self.processListStyles(styles_doc.getElementsByTagName("text:list-style")) + + self.content = xml.dom.minidom.parseString(zip.read("content.xml")) + fontfacedecls = self.content.getElementsByTagName("office:font-face-decls") + if fontfacedecls: + self.processFontDeclarations(fontfacedecls[0]) + + self.processStyles(self.content.getElementsByTagName("style:style")) + self.processListStyles(self.content.getElementsByTagName("text:list-style")) + + def compressCodeBlocks(self, text): + """ Removes extra blank lines from code blocks. """ + + return text + lines = text.split("\n") + buffer = [] + numLines = len(lines) + for i in range(numLines): + + if (lines[i].strip() or i == numLines-1 or i == 0 or + not ( lines[i-1].startswith(" ") + and lines[i+1].startswith(" ") ) ): + buffer.append("\n" + lines[i]) + + return ''.join(buffer) + +#----------------------------------- + def do_nothing(self, node): + return '' + + def draw_image(self, node): + """ + """ + + link = node.getAttribute("xlink:href") + if link and link[:2] == './': # Indicates a sub-object, which isn't supported + return "%s\n" % link + if link and link[:9] == 'Pictures/': + link = link[9:] + return "[[Image(%s)]]\n" % link + + def text_a(self, node): + text = self.textToString(node) + link = node.getAttribute("xlink:href") + if link.strip() == text.strip(): + return "[%s] " % link.strip() + else: + return "[%s %s] " % (link.strip(), text.strip()) + + + def text_line_break(self, node): + return "[[BR]]" + + def text_note(self, node): + cite = (node.getElementsByTagName("text:note-citation")[0] + .childNodes[0].nodeValue) + body = (node.getElementsByTagName("text:note-body")[0] + .childNodes[0]) + self.footnotes.append((cite, self.textToString(body))) + return "^%s^" % cite + + def text_s(self, node): + try: + num = int(node.getAttribute("text:c")) + return " "*num + except: + return " " + + def text_tab(self, node): + return " " + + def inline_markup(self, node): + text = self.textToString(node) + + if not text.strip(): + return '' # don't apply styles to white space + + styleName = node.getAttribute("text:style-name") + style = self.textStyles.get(styleName, TextProps()) + + if style.fixed: + return "`" + text + "`" + + mark = [] + if style: + if style.italic: + mark.append("''") + if style.bold: + mark.append("'''") + if style.underlined: + mark.append("__") + if style.strikethrough: + mark.append("~~") + if style.superscript: + mark.append("^") + if style.subscript: + mark.append(",,") + revmark = mark[:] + revmark.reverse() + return "%s%s%s" % (''.join(mark), text, ''.join(revmark)) + +#----------------------------------- + def listToString(self, listElement, indent = 0): + + self.lastsegment = listElement.tagName + buffer = [] + + styleName = listElement.getAttribute("text:style-name") + props = self.listStyles.get(styleName, ListProperties()) + + i = 0 + for item in listElement.childNodes: + buffer.append(" "*indent) + i += 1 + if props.ordered: + number = str(i) + number = " " + number + ". " + buffer.append(" 1. ") + else: + buffer.append(" * ") + subitems = [el for el in item.childNodes + if el.tagName in ["text:p", "text:h", "text:list"]] + for subitem in subitems: + if subitem.tagName == "text:list": + buffer.append("\n") + buffer.append(self.listToString(subitem, indent+3)) + else: + buffer.append(self.paragraphToString(subitem, indent+3)) + self.lastsegment = subitem.tagName + self.lastsegment = item.tagName + buffer.append("\n") + + return ''.join(buffer) + + def tableToString(self, tableElement): + """ MoinMoin uses || to delimit table cells + """ + + self.lastsegment = tableElement.tagName + buffer = [] + + for item in tableElement.childNodes: + self.lastsegment = item.tagName + if item.tagName == "table:table-header-rows": + buffer.append(self.tableToString(item)) + if item.tagName == "table:table-row": + buffer.append("\n||") + for cell in item.childNodes: + buffer.append(self.inline_markup(cell)) + buffer.append("||") + self.lastsegment = cell.tagName + return ''.join(buffer) + + + def toString(self): + """ Converts the document to a string. + FIXME: Result from second call differs from first call + """ + body = self.content.getElementsByTagName("office:body")[0] + text = body.childNodes[0] + + buffer = [] + + paragraphs = [el for el in text.childNodes + if el.tagName in ["draw:page", "text:p", "text:h","text:section", + "text:list", "table:table"]] + + for paragraph in paragraphs: + if paragraph.tagName == "text:list": + text = self.listToString(paragraph) + elif paragraph.tagName == "text:section": + text = self.textToString(paragraph) + elif paragraph.tagName == "table:table": + text = self.tableToString(paragraph) + else: + text = self.paragraphToString(paragraph) + if text: + buffer.append(text) + + if self.footnotes: + + buffer.append("----") + for cite, body in self.footnotes: + buffer.append("%s: %s" % (cite, body)) + + + buffer.append("") + return self.compressCodeBlocks('\n'.join(buffer)) + + + def textToString(self, element): + + buffer = [] + + for node in element.childNodes: + + if node.nodeType == xml.dom.Node.TEXT_NODE: + buffer.append(node.nodeValue) + + elif node.nodeType == xml.dom.Node.ELEMENT_NODE: + tag = node.tagName + + if tag in ("draw:text-box", "draw:frame"): + buffer.append(self.textToString(node)) + + elif tag in ("text:p", "text:h"): + text = self.paragraphToString(node) + if text: + buffer.append(text) + elif tag == "text:list": + buffer.append(self.listToString(node)) + else: + method = self.elements.get(tag) + if method: + buffer.append(method(node)) + else: + buffer.append(" {" + tag + "} ") + + return ''.join(buffer) + + def paragraphToString(self, paragraph, indent = 0): + + dummyParaProps = ParagraphProps() + + style_name = paragraph.getAttribute("text:style-name") + paraProps = self.paragraphStyles.get(style_name, dummyParaProps) + text = self.inline_markup(paragraph) + + if paraProps and not paraProps.code: + text = text.strip() + + if paragraph.tagName == "text:p" and self.lastsegment == "text:p": + text = "\n" + text + + self.lastsegment = paragraph.tagName + + if paraProps.title: + self.hasTitle = 1 + return "= " + text + " =\n" + + outlinelevel = paragraph.getAttribute("text:outline-level") + if outlinelevel: + + level = int(outlinelevel) + if self.hasTitle: level += 1 + + if level >= 1: + return "=" * level + " " + text + " " + "=" * level + "\n" + + elif paraProps.code: + return "{{{\n" + text + "\n}}}\n" + + if paraProps.indented: + return self.wrapParagraph(text, indent = indent, blockquote = True) + + else: + return self.wrapParagraph(text, indent = indent) + + + def wrapParagraph(self, text, indent = 0, blockquote=False): + + counter = 0 + buffer = [] + LIMIT = 50 + + if blockquote: + buffer.append(" ") + + return ''.join(buffer) + text + # Unused from here + for token in text.split(): + + if counter > LIMIT - indent: + buffer.append("\n" + " "*indent) + if blockquote: + buffer.append(" ") + counter = 0 + + buffer.append(token + " ") + counter += len(token) + + return ''.join(buffer) diff --git a/odf/odf2xhtml.py b/odf/odf2xhtml.py new file mode 100644 index 0000000..8c5fbb2 --- /dev/null +++ b/odf/odf2xhtml.py @@ -0,0 +1,1617 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2010 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +#import pdb +#pdb.set_trace() + +import sys, os.path +sys.path.append(os.path.dirname(__file__)) +from xml.sax import handler +from xml.sax.saxutils import escape, quoteattr +from xml.dom import Node + +from opendocument import load + +from namespaces import ANIMNS, CHARTNS, CONFIGNS, DCNS, DR3DNS, DRAWNS, FONS, \ + FORMNS, MATHNS, METANS, NUMBERNS, OFFICENS, PRESENTATIONNS, SCRIPTNS, \ + SMILNS, STYLENS, SVGNS, TABLENS, TEXTNS, XLINKNS + +# Handling of styles +# +# First there are font face declarations. These set up a font style that will be +# referenced from a text-property. The declaration describes the font making +# it possible for the application to find a similar font should the system not +# have that particular one. The StyleToCSS stores these attributes to be used +# for the CSS2 font declaration. +# +# Then there are default-styles. These set defaults for various style types: +# "text", "paragraph", "section", "ruby", "table", "table-column", "table-row", +# "table-cell", "graphic", "presentation", "drawing-page", "chart". +# Since CSS2 can't refer to another style, ODF2XHTML add these to all +# styles unless overridden. +# +# The real styles are declared in the element. They have a +# family referring to the default-styles, and may have a parent style. +# +# Styles have scope. The same name can be used for both paragraph and +# character etc. styles Since CSS2 has no scope we use a prefix. (Not elegant) +# In ODF a style can have a parent, these parents can be chained. + +class StyleToCSS: + """ The purpose of the StyleToCSS class is to contain the rules to convert + ODF styles to CSS2. Since it needs the generic fonts, it would probably + make sense to also contain the Styles in a dict as well.. + """ + + def __init__(self): + # Font declarations + self.fontdict = {} + + # Fill-images from presentations for backgrounds + self.fillimages = {} + + self.ruleconversions = { + (DRAWNS,u'fill-image-name'): self.c_drawfillimage, + (FONS,u"background-color"): self.c_fo, + (FONS,u"border"): self.c_fo, + (FONS,u"border-bottom"): self.c_fo, + (FONS,u"border-left"): self.c_fo, + (FONS,u"border-right"): self.c_fo, + (FONS,u"border-top"): self.c_fo, + (FONS,u"color"): self.c_fo, + (FONS,u"font-family"): self.c_fo, + (FONS,u"font-size"): self.c_fo, + (FONS,u"font-style"): self.c_fo, + (FONS,u"font-variant"): self.c_fo, + (FONS,u"font-weight"): self.c_fo, + (FONS,u"line-height"): self.c_fo, + (FONS,u"margin"): self.c_fo, + (FONS,u"margin-bottom"): self.c_fo, + (FONS,u"margin-left"): self.c_fo, + (FONS,u"margin-right"): self.c_fo, + (FONS,u"margin-top"): self.c_fo, + (FONS,u"min-height"): self.c_fo, + (FONS,u"padding"): self.c_fo, + (FONS,u"padding-bottom"): self.c_fo, + (FONS,u"padding-left"): self.c_fo, + (FONS,u"padding-right"): self.c_fo, + (FONS,u"padding-top"): self.c_fo, + (FONS,u"page-width"): self.c_page_width, + (FONS,u"page-height"): self.c_page_height, + (FONS,u"text-align"): self.c_text_align, + (FONS,u"text-indent") :self.c_fo, + (TABLENS,u'border-model') :self.c_border_model, + (STYLENS,u'column-width') : self.c_width, + (STYLENS,u"font-name"): self.c_fn, + (STYLENS,u'horizontal-pos'): self.c_hp, + (STYLENS,u'text-position'): self.c_text_position, + (STYLENS,u'text-line-through-style'): self.c_text_line_through_style, + (STYLENS,u'text-underline-style'): self.c_text_underline_style, + (STYLENS,u'width') : self.c_width, + # FIXME Should do style:vertical-pos here + } + + def save_font(self, name, family, generic): + """ It is possible that the HTML browser doesn't know how to + show a particular font. Fortunately ODF provides generic fallbacks. + Unfortunately they are not the same as CSS2. + CSS2: serif, sans-serif, cursive, fantasy, monospace + ODF: roman, swiss, modern, decorative, script, system + This method put the font and fallback into a dictionary + """ + htmlgeneric = "sans-serif" + if generic == "roman": htmlgeneric = "serif" + elif generic == "swiss": htmlgeneric = "sans-serif" + elif generic == "modern": htmlgeneric = "monospace" + elif generic == "decorative": htmlgeneric = "sans-serif" + elif generic == "script": htmlgeneric = "monospace" + elif generic == "system": htmlgeneric = "serif" + self.fontdict[name] = (family, htmlgeneric) + + def c_drawfillimage(self, ruleset, sdict, rule, val): + """ Fill a figure with an image. Since CSS doesn't let you resize images + this should really be implemented as an absolutely position + with a width and a height + """ + sdict['background-image'] = "url('%s')" % self.fillimages[val] + + def c_fo(self, ruleset, sdict, rule, val): + """ XSL formatting attributes """ + selector = rule[1] + sdict[selector] = val + + def c_border_model(self, ruleset, sdict, rule, val): + """ Convert to CSS2 border model """ + if val == 'collapsing': + sdict['border-collapse'] ='collapse' + else: + sdict['border-collapse'] ='separate' + + def c_width(self, ruleset, sdict, rule, val): + """ Set width of box """ + sdict['width'] = val + + def c_text_align(self, ruleset, sdict, rule, align): + """ Text align """ + if align == "start": align = "left" + if align == "end": align = "right" + sdict['text-align'] = align + + def c_fn(self, ruleset, sdict, rule, fontstyle): + """ Generate the CSS font family + A generic font can be found in two ways. In a + element or as a font-family-generic attribute in text-properties. + """ + generic = ruleset.get((STYLENS,'font-family-generic') ) + if generic is not None: + self.save_font(fontstyle, fontstyle, generic) + family, htmlgeneric = self.fontdict.get(fontstyle, (fontstyle, 'serif')) + sdict['font-family'] = '%s, %s' % (family, htmlgeneric) + + def c_text_position(self, ruleset, sdict, rule, tp): + """ Text position. This is used e.g. to make superscript and subscript + This attribute can have one or two values. + + The first value must be present and specifies the vertical + text position as a percentage that relates to the current font + height or it takes one of the values sub or super. Negative + percentages or the sub value place the text below the + baseline. Positive percentages or the super value place + the text above the baseline. If sub or super is specified, + the application can choose an appropriate text position. + + The second value is optional and specifies the font height + as a percentage that relates to the current font-height. If + this value is not specified, an appropriate font height is + used. Although this value may change the font height that + is displayed, it never changes the current font height that + is used for additional calculations. + """ + textpos = tp.split(' ') + if len(textpos) == 2 and textpos[0] != "0%": + # Bug in OpenOffice. If vertical-align is 0% - ignore the text size. + sdict['font-size'] = textpos[1] + if textpos[0] == "super": + sdict['vertical-align'] = "33%" + elif textpos[0] == "sub": + sdict['vertical-align'] = "-33%" + else: + sdict['vertical-align'] = textpos[0] + + def c_hp(self, ruleset, sdict, rule, hpos): + #FIXME: Frames wrap-style defaults to 'parallel', graphics to 'none'. + # It is properly set in the parent-styles, but the program doesn't + # collect the information. + wrap = ruleset.get((STYLENS,'wrap'),'parallel') + # Can have: from-left, left, center, right, from-inside, inside, outside + if hpos == "center": + sdict['margin-left'] = "auto" + sdict['margin-right'] = "auto" +# else: +# # force it to be *something* then delete it +# sdict['margin-left'] = sdict['margin-right'] = '' +# del sdict['margin-left'], sdict['margin-right'] + + if hpos in ("right","outside"): + if wrap in ( "left", "parallel","dynamic"): + sdict['float'] = "right" + elif wrap == "run-through": + sdict['position'] = "absolute" # Simulate run-through + sdict['top'] = "0" + sdict['right'] = "0"; + else: # No wrapping + sdict['margin-left'] = "auto" + sdict['margin-right'] = "0cm" + elif hpos in ("left", "inside"): + if wrap in ( "right", "parallel","dynamic"): + sdict['float'] = "left" + elif wrap == "run-through": + sdict['position'] = "absolute" # Simulate run-through + sdict['top'] = "0" + sdict['left'] = "0" + else: # No wrapping + sdict['margin-left'] = "0cm" + sdict['margin-right'] = "auto" + elif hpos in ("from-left", "from-inside"): + if wrap in ( "right", "parallel"): + sdict['float'] = "left" + else: + sdict['position'] = "relative" # No wrapping + if (SVGNS,'x') in ruleset: + sdict['left'] = ruleset[(SVGNS,'x')] + + def c_page_width(self, ruleset, sdict, rule, val): + """ Set width of box + HTML doesn't really have a page-width. It is always 100% of the browser width + """ + sdict['width'] = val + + def c_text_underline_style(self, ruleset, sdict, rule, val): + """ Set underline decoration + HTML doesn't really have a page-width. It is always 100% of the browser width + """ + if val and val != "none": + sdict['text-decoration'] = "underline" + + def c_text_line_through_style(self, ruleset, sdict, rule, val): + """ Set underline decoration + HTML doesn't really have a page-width. It is always 100% of the browser width + """ + if val and val != "none": + sdict['text-decoration'] = "line-through" + + def c_page_height(self, ruleset, sdict, rule, val): + """ Set height of box """ + sdict['height'] = val + + def convert_styles(self, ruleset): + """ Rule is a tuple of (namespace, name). If the namespace is '' then + it is already CSS2 + """ + sdict = {} + procedures=[] + for rule,val in ruleset.items(): + if rule[0] == '': + sdict[rule[1]] = val + continue + method = self.ruleconversions.get(rule, None ) + if method: + procedures.append([method, ruleset, sdict, rule, val]) + # this ensures that the procedures for horizontal position + # are run last! It is important since Python3 makes the order + # of dictionaries unpredictable + for p in filter(lambda x: x[0] != self.c_hp, procedures): + method, ruleset, sdict, rule, val = p + method(ruleset, sdict, rule, val) + for p in filter(lambda x: x[0] == self.c_hp, procedures): + method, ruleset, sdict, rule, val = p + method(ruleset, sdict, rule, val) + + return sdict + + +class TagStack: + def __init__(self): + self.stack = [] + + def push(self, tag, attrs): + self.stack.append( (tag, attrs) ) + + def pop(self): + item = self.stack.pop() + return item + + def stackparent(self): + item = self.stack[-1] + return item[1] + + def rfindattr(self, attr): + """ Find a tag with the given attribute """ + for tag, attrs in self.stack: + if attr in attrs: + return attrs[attr] + return None + def count_tags(self, tag): + c = 0 + for ttag, tattrs in self.stack: + if ttag == tag: c = c + 1 + return c + +special_styles = { + 'S-Emphasis':'em', + 'S-Citation':'cite', + 'S-Strong_20_Emphasis':'strong', + 'S-Variable':'var', + 'S-Definition':'dfn', + 'S-Teletype':'tt', + 'P-Heading_20_1':'h1', + 'P-Heading_20_2':'h2', + 'P-Heading_20_3':'h3', + 'P-Heading_20_4':'h4', + 'P-Heading_20_5':'h5', + 'P-Heading_20_6':'h6', +# 'P-Caption':'caption', + 'P-Addressee':'address', +# 'P-List_20_Heading':'dt', +# 'P-List_20_Contents':'dd', + 'P-Preformatted_20_Text':'pre', +# 'P-Table_20_Heading':'th', +# 'P-Table_20_Contents':'td', +# 'P-Text_20_body':'p' +} + +#----------------------------------------------------------------------------- +# +# ODFCONTENTHANDLER +# +#----------------------------------------------------------------------------- +class ODF2XHTML(handler.ContentHandler): + """ The ODF2XHTML parses an ODF file and produces XHTML""" + + def __init__(self, generate_css=True, embedable=False): + # Tags + self.generate_css = generate_css + self.elements = { + (DCNS, 'title'): (self.s_processcont, self.e_dc_title), + (DCNS, 'language'): (self.s_processcont, self.e_dc_contentlanguage), + (DCNS, 'creator'): (self.s_processcont, self.e_dc_creator), + (DCNS, 'description'): (self.s_processcont, self.e_dc_metatag), + (DCNS, 'date'): (self.s_processcont, self.e_dc_metatag), + (DRAWNS, 'custom-shape'): (self.s_custom_shape, self.e_custom_shape), + (DRAWNS, 'frame'): (self.s_draw_frame, self.e_draw_frame), + (DRAWNS, 'image'): (self.s_draw_image, None), + (DRAWNS, 'fill-image'): (self.s_draw_fill_image, None), + (DRAWNS, "layer-set"):(self.s_ignorexml, None), + (DRAWNS, 'object'): (self.s_draw_object, None), + (DRAWNS, 'object-ole'): (self.s_draw_object_ole, None), + (DRAWNS, 'page'): (self.s_draw_page, self.e_draw_page), + (DRAWNS, 'text-box'): (self.s_draw_textbox, self.e_draw_textbox), + (METANS, 'creation-date'):(self.s_processcont, self.e_dc_metatag), + (METANS, 'generator'):(self.s_processcont, self.e_dc_metatag), + (METANS, 'initial-creator'): (self.s_processcont, self.e_dc_metatag), + (METANS, 'keyword'): (self.s_processcont, self.e_dc_metatag), + (NUMBERNS, "boolean-style"):(self.s_ignorexml, None), + (NUMBERNS, "currency-style"):(self.s_ignorexml, None), + (NUMBERNS, "date-style"):(self.s_ignorexml, None), + (NUMBERNS, "number-style"):(self.s_ignorexml, None), + (NUMBERNS, "text-style"):(self.s_ignorexml, None), + (OFFICENS, "annotation"):(self.s_ignorexml, None), + (OFFICENS, "automatic-styles"):(self.s_office_automatic_styles, None), + (OFFICENS, "document"):(self.s_office_document_content, self.e_office_document_content), + (OFFICENS, "document-content"):(self.s_office_document_content, self.e_office_document_content), + (OFFICENS, "forms"):(self.s_ignorexml, None), + (OFFICENS, "master-styles"):(self.s_office_master_styles, None), + (OFFICENS, "meta"):(self.s_ignorecont, None), + (OFFICENS, "presentation"):(self.s_office_presentation, self.e_office_presentation), + (OFFICENS, "spreadsheet"):(self.s_office_spreadsheet, self.e_office_spreadsheet), + (OFFICENS, "styles"):(self.s_office_styles, None), + (OFFICENS, "text"):(self.s_office_text, self.e_office_text), + (OFFICENS, "scripts"):(self.s_ignorexml, None), + (OFFICENS, "settings"):(self.s_ignorexml, None), + (PRESENTATIONNS, "notes"):(self.s_ignorexml, None), +# (STYLENS, "default-page-layout"):(self.s_style_default_page_layout, self.e_style_page_layout), + (STYLENS, "default-page-layout"):(self.s_ignorexml, None), + (STYLENS, "default-style"):(self.s_style_default_style, self.e_style_default_style), + (STYLENS, "drawing-page-properties"):(self.s_style_handle_properties, None), + (STYLENS, "font-face"):(self.s_style_font_face, None), +# (STYLENS, "footer"):(self.s_style_footer, self.e_style_footer), +# (STYLENS, "footer-style"):(self.s_style_footer_style, None), + (STYLENS, "graphic-properties"):(self.s_style_handle_properties, None), + (STYLENS, "handout-master"):(self.s_ignorexml, None), +# (STYLENS, "header"):(self.s_style_header, self.e_style_header), +# (STYLENS, "header-footer-properties"):(self.s_style_handle_properties, None), +# (STYLENS, "header-style"):(self.s_style_header_style, None), + (STYLENS, "master-page"):(self.s_style_master_page, None), + (STYLENS, "page-layout-properties"):(self.s_style_handle_properties, None), + (STYLENS, "page-layout"):(self.s_style_page_layout, self.e_style_page_layout), +# (STYLENS, "page-layout"):(self.s_ignorexml, None), + (STYLENS, "paragraph-properties"):(self.s_style_handle_properties, None), + (STYLENS, "style"):(self.s_style_style, self.e_style_style), + (STYLENS, "table-cell-properties"):(self.s_style_handle_properties, None), + (STYLENS, "table-column-properties"):(self.s_style_handle_properties, None), + (STYLENS, "table-properties"):(self.s_style_handle_properties, None), + (STYLENS, "text-properties"):(self.s_style_handle_properties, None), + (SVGNS, 'desc'): (self.s_ignorexml, None), + (TABLENS, 'covered-table-cell'): (self.s_ignorexml, None), + (TABLENS, 'table-cell'): (self.s_table_table_cell, self.e_table_table_cell), + (TABLENS, 'table-column'): (self.s_table_table_column, None), + (TABLENS, 'table-row'): (self.s_table_table_row, self.e_table_table_row), + (TABLENS, 'table'): (self.s_table_table, self.e_table_table), + (TEXTNS, 'a'): (self.s_text_a, self.e_text_a), + (TEXTNS, "alphabetical-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "bibliography-configuration"):(self.s_ignorexml, None), + (TEXTNS, "bibliography-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, 'bookmark'): (self.s_text_bookmark, None), + (TEXTNS, 'bookmark-start'): (self.s_text_bookmark, None), + (TEXTNS, 'bookmark-ref'): (self.s_text_bookmark_ref, self.e_text_a), + (TEXTNS, 'bookmark-ref-start'): (self.s_text_bookmark_ref, None), + (TEXTNS, 'h'): (self.s_text_h, self.e_text_h), + (TEXTNS, "illustration-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, 'line-break'):(self.s_text_line_break, None), + (TEXTNS, "linenumbering-configuration"):(self.s_ignorexml, None), + (TEXTNS, "list"):(self.s_text_list, self.e_text_list), + (TEXTNS, "list-item"):(self.s_text_list_item, self.e_text_list_item), + (TEXTNS, "list-level-style-bullet"):(self.s_text_list_level_style_bullet, self.e_text_list_level_style_bullet), + (TEXTNS, "list-level-style-number"):(self.s_text_list_level_style_number, self.e_text_list_level_style_number), + (TEXTNS, "list-style"):(None, None), + (TEXTNS, "note"):(self.s_text_note, None), + (TEXTNS, "note-body"):(self.s_text_note_body, self.e_text_note_body), + (TEXTNS, "note-citation"):(None, self.e_text_note_citation), + (TEXTNS, "notes-configuration"):(self.s_ignorexml, None), + (TEXTNS, "object-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, 'p'): (self.s_text_p, self.e_text_p), + (TEXTNS, 's'): (self.s_text_s, None), + (TEXTNS, 'span'): (self.s_text_span, self.e_text_span), + (TEXTNS, 'tab'): (self.s_text_tab, None), + (TEXTNS, "table-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "table-of-content-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "user-index-source"):(self.s_text_x_source, self.e_text_x_source), + } + if embedable: + self.set_embedable() + self._resetobject() + + def set_plain(self): + """ Tell the parser to not generate CSS """ + self.generate_css = False + + def set_embedable(self): + """ Tells the converter to only output the parts inside the """ + self.elements[(OFFICENS, u"text")] = (None,None) + self.elements[(OFFICENS, u"spreadsheet")] = (None,None) + self.elements[(OFFICENS, u"presentation")] = (None,None) + self.elements[(OFFICENS, u"document-content")] = (None,None) + + + def add_style_file(self, stylefilename, media=None): + """ Add a link to an external style file. + Also turns of the embedding of styles in the HTML + """ + self.use_internal_css = False + self.stylefilename = stylefilename + if media: + self.metatags.append('\n' % (stylefilename,media)) + else: + self.metatags.append('\n' % (stylefilename)) + + def _resetfootnotes(self): + # Footnotes and endnotes + self.notedict = {} + self.currentnote = 0 + self.notebody = '' + + def _resetobject(self): + self.lines = [] + self._wfunc = self._wlines + self.xmlfile = '' + self.title = '' + self.language = '' + self.creator = '' + self.data = [] + self.tagstack = TagStack() + self.htmlstack = [] + self.pstack = [] + self.processelem = True + self.processcont = True + self.listtypes = {} + self.headinglevels = [0, 0,0,0,0,0, 0,0,0,0,0] # level 0 to 10 + self.use_internal_css = True + self.cs = StyleToCSS() + self.anchors = {} + + # Style declarations + self.stylestack = [] + self.styledict = {} + self.currentstyle = None + + self._resetfootnotes() + + # Tags from meta.xml + self.metatags = [] + + + def writeout(self, s): + if s != '': + self._wfunc(s) + + def writedata(self): + d = ''.join(self.data) + if d != '': + self.writeout(escape(d)) + + def opentag(self, tag, attrs={}, block=False): + """ Create an open HTML tag """ + self.htmlstack.append((tag,attrs,block)) + a = [] + for key,val in attrs.items(): + a.append('''%s=%s''' % (key, quoteattr(val))) + if len(a) == 0: + self.writeout("<%s>" % tag) + else: + self.writeout("<%s %s>" % (tag, " ".join(a))) + if block == True: + self.writeout("\n") + + def closetag(self, tag, block=True): + """ Close an open HTML tag """ + self.htmlstack.pop() + self.writeout("" % tag) + if block == True: + self.writeout("\n") + + def emptytag(self, tag, attrs={}): + a = [] + for key,val in attrs.items(): + a.append('''%s=%s''' % (key, quoteattr(val))) + self.writeout("<%s %s/>\n" % (tag, " ".join(a))) + +#-------------------------------------------------- +# Interface to parser +#-------------------------------------------------- + def characters(self, data): + if self.processelem and self.processcont: + self.data.append(data) + + def startElementNS(self, tag, qname, attrs): + self.pstack.append( (self.processelem, self.processcont) ) + if self.processelem: + method = self.elements.get(tag, (None, None) )[0] + if method: + self.handle_starttag(tag, method, attrs) + else: + self.unknown_starttag(tag,attrs) + self.tagstack.push( tag, attrs ) + + def endElementNS(self, tag, qname): + stag, attrs = self.tagstack.pop() + if self.processelem: + method = self.elements.get(tag, (None, None) )[1] + if method: + self.handle_endtag(tag, attrs, method) + else: + self.unknown_endtag(tag, attrs) + self.processelem, self.processcont = self.pstack.pop() + +#-------------------------------------------------- + def handle_starttag(self, tag, method, attrs): + method(tag,attrs) + + def handle_endtag(self, tag, attrs, method): + method(tag, attrs) + + def unknown_starttag(self, tag, attrs): + pass + + def unknown_endtag(self, tag, attrs): + pass + + def s_ignorexml(self, tag, attrs): + """ Ignore this xml element and all children of it + It will automatically stop ignoring + """ + self.processelem = False + + def s_ignorecont(self, tag, attrs): + """ Stop processing the text nodes """ + self.processcont = False + + def s_processcont(self, tag, attrs): + """ Start processing the text nodes """ + self.processcont = True + + def classname(self, attrs): + """ Generate a class name from a style name """ + c = attrs.get((TEXTNS,'style-name'),'') + c = c.replace(".","_") + return c + + def get_anchor(self, name): + """ Create a unique anchor id for a href name """ + if name not in self.anchors: + self.anchors[name] = "anchor%03d" % (len(self.anchors) + 1) + return self.anchors.get(name) + + +#-------------------------------------------------- + + def purgedata(self): + self.data = [] + +#----------------------------------------------------------------------------- +# +# Handle meta data +# +#----------------------------------------------------------------------------- + def e_dc_title(self, tag, attrs): + """ Get the title from the meta data and create a HTML + """ + self.title = ''.join(self.data) + #self.metatags.append('<title>%s\n' % escape(self.title)) + self.data = [] + + def e_dc_metatag(self, tag, attrs): + """ Any other meta data is added as a element + """ + self.metatags.append('\n' % (tag[1], quoteattr(''.join(self.data)))) + self.data = [] + + def e_dc_contentlanguage(self, tag, attrs): + """ Set the content language. Identifies the targeted audience + """ + self.language = ''.join(self.data) + self.metatags.append('\n' % escape(self.language)) + self.data = [] + + def e_dc_creator(self, tag, attrs): + """ Set the content creator. Identifies the targeted audience + """ + self.creator = ''.join(self.data) + self.metatags.append('\n' % escape(self.creator)) + self.data = [] + + def s_custom_shape(self, tag, attrs): + """ A is made into a
in HTML which is then styled + """ + anchor_type = attrs.get((TEXTNS,'anchor-type'),'notfound') + htmltag = 'div' + name = "G-" + attrs.get( (DRAWNS,'style-name'), "") + if name == 'G-': + name = "PR-" + attrs.get( (PRESENTATIONNS,'style-name'), "") + name = name.replace(".","_") + if anchor_type == "paragraph": + style = 'position:absolute;' + elif anchor_type == 'char': + style = "position:absolute;" + elif anchor_type == 'as-char': + htmltag = 'div' + style = '' + else: + style = "position: absolute;" + if (SVGNS,"width")in attrs: + style = style + "width:" + attrs[(SVGNS,"width")] + ";" + if (SVGNS,"height") in attrs: + style = style + "height:" + attrs[(SVGNS,"height")] + ";" + if (SVGNS,"x") in attrs: + style = style + "left:" + attrs[(SVGNS,"x")] + ";" + if (SVGNS,"y") in attrs: + style = style + "top:" + attrs[(SVGNS,"y")] + ";" + if self.generate_css: + self.opentag(htmltag, {'class': name, 'style': style}) + else: + self.opentag(htmltag) + + def e_custom_shape(self, tag, attrs): + """ End the + """ + self.closetag('div') + + def s_draw_frame(self, tag, attrs): + """ A is made into a
in HTML which is then styled + """ + anchor_type = attrs.get((TEXTNS,'anchor-type'),'notfound') + htmltag = 'div' + name = "G-" + attrs.get( (DRAWNS,'style-name'), "") + if name == 'G-': + name = "PR-" + attrs.get( (PRESENTATIONNS,'style-name'), "") + name = name.replace(".","_") + if anchor_type == "paragraph": + style = 'position:relative;' + elif anchor_type == 'char': + style = "position:relative;" + elif anchor_type == 'as-char': + htmltag = 'div' + style = '' + else: + style = "position:absolute;" + if (SVGNS,"width") in attrs: + style = style + "width:" + attrs[(SVGNS,"width")] + ";" + if (SVGNS,"height") in attrs: + style = style + "height:" + attrs[(SVGNS,"height")] + ";" + if (SVGNS,"x") in attrs: + style = style + "left:" + attrs[(SVGNS,"x")] + ";" + if (SVGNS,"y") in attrs: + style = style + "top:" + attrs[(SVGNS,"y")] + ";" + if self.generate_css: + self.opentag(htmltag, {'class': name, 'style': style}) + else: + self.opentag(htmltag) + + def e_draw_frame(self, tag, attrs): + """ End the + """ + self.closetag('div') + + def s_draw_fill_image(self, tag, attrs): + name = attrs.get( (DRAWNS,'name'), "NoName") + imghref = attrs[(XLINKNS,"href")] + imghref = self.rewritelink(imghref) + self.cs.fillimages[name] = imghref + + def rewritelink(self, imghref): + """ Intended to be overloaded if you don't store your pictures + in a Pictures subfolder + """ + return imghref + + def s_draw_image(self, tag, attrs): + """ A becomes an element + """ + parent = self.tagstack.stackparent() + anchor_type = parent.get((TEXTNS,'anchor-type')) + imghref = attrs[(XLINKNS,"href")] + imghref = self.rewritelink(imghref) + htmlattrs = {'alt':"", 'src':imghref } + if self.generate_css: + if anchor_type != "char": + htmlattrs['style'] = "display: block;" + self.emptytag('img', htmlattrs) + + def s_draw_object(self, tag, attrs): + """ A is embedded object in the document (e.g. spreadsheet in presentation). + """ + objhref = attrs[(XLINKNS,"href")] + # Remove leading "./": from "./Object 1" to "Object 1" +# objhref = objhref [2:] + + # Not using os.path.join since it fails to find the file on Windows. +# objcontentpath = '/'.join([objhref, 'content.xml']) + + for c in self.document.childnodes: + if c.folder == objhref: + self._walknode(c.topnode) + + def s_draw_object_ole(self, tag, attrs): + """ A is embedded OLE object in the document (e.g. MS Graph). + """ + class_id = attrs[(DRAWNS,"class-id")] + if class_id and class_id.lower() == "00020803-0000-0000-c000-000000000046": ## Microsoft Graph 97 Chart + tagattrs = { 'name':'object_ole_graph', 'class':'ole-graph' } + self.opentag('a', tagattrs) + self.closetag('a', tagattrs) + + def s_draw_page(self, tag, attrs): + """ A is a slide in a presentation. We use a
element in HTML. + Therefore if you convert a ODP file, you get a series of
s. + Override this for your own purpose. + """ + name = attrs.get( (DRAWNS,'name'), "NoName") + stylename = attrs.get( (DRAWNS,'style-name'), "") + stylename = stylename.replace(".","_") + masterpage = attrs.get( (DRAWNS,'master-page-name'),"") + masterpage = masterpage.replace(".","_") + if self.generate_css: + self.opentag('fieldset', {'class':"DP-%s MP-%s" % (stylename, masterpage) }) + else: + self.opentag('fieldset') + self.opentag('legend') + self.writeout(escape(name)) + self.closetag('legend') + + def e_draw_page(self, tag, attrs): + self.closetag('fieldset') + + def s_draw_textbox(self, tag, attrs): + style = '' + if (FONS,"min-height") in attrs: + style = style + "min-height:" + attrs[(FONS,"min-height")] + ";" + self.opentag('div') +# self.opentag('div', {'style': style}) + + def e_draw_textbox(self, tag, attrs): + """ End the + """ + self.closetag('div') + + def html_body(self, tag, attrs): + self.writedata() + if self.generate_css and self.use_internal_css: + self.opentag('style', {'type':"text/css"}, True) + self.writeout('/**/\n') + self.closetag('style') + self.purgedata() + self.closetag('head') + self.opentag('body', block=True) + + default_styles = """ +img { width: 100%; height: 100%; } +* { padding: 0; margin: 0; background-color:white; } +body { margin: 0 1em; } +ol, ul { padding-left: 2em; } +""" + + def generate_stylesheet(self): + for name in self.stylestack: + styles = self.styledict.get(name) + # Preload with the family's default style + if '__style-family'in styles and styles['__style-family'] in self.styledict: + familystyle = self.styledict[styles['__style-family']].copy() + del styles['__style-family'] + for style, val in styles.items(): + familystyle[style] = val + styles = familystyle + # Resolve the remaining parent styles + while '__parent-style-name' in styles and styles['__parent-style-name'] in self.styledict: + parentstyle = self.styledict[styles['__parent-style-name']].copy() + del styles['__parent-style-name'] + for style, val in styles.items(): + parentstyle[style] = val + styles = parentstyle + self.styledict[name] = styles + # Write the styles to HTML + self.writeout(self.default_styles) + for name in self.stylestack: + styles = self.styledict.get(name) + css2 = self.cs.convert_styles(styles) + self.writeout("%s {\n" % name) + for style, val in css2.items(): + self.writeout("\t%s: %s;\n" % (style, val) ) + self.writeout("}\n") + + def generate_footnotes(self): + if self.currentnote == 0: + return + if self.generate_css: + self.opentag('ol', {'style':'border-top: 1px solid black'}, True) + else: + self.opentag('ol') + for key in range(1,self.currentnote+1): + note = self.notedict[key] +# for key,note in self.notedict.items(): + self.opentag('li', { 'id':"footnote-%d" % key }) +# self.opentag('sup') +# self.writeout(escape(note['citation'])) +# self.closetag('sup', False) + self.writeout(note['body']) + self.closetag('li') + self.closetag('ol') + + def s_office_automatic_styles(self, tag, attrs): + if self.xmlfile == 'styles.xml': + self.autoprefix = "A" + else: + self.autoprefix = "" + + def s_office_document_content(self, tag, attrs): + """ First tag in the content.xml file""" + self.writeout('\n') + self.opentag('html', {'xmlns':"http://www.w3.org/1999/xhtml"}, True) + self.opentag('head', block=True) + self.emptytag('meta', { 'http-equiv':"Content-Type", 'content':"text/html;charset=UTF-8"}) + for metaline in self.metatags: + self.writeout(metaline) + self.writeout('%s\n' % escape(self.title)) + + def e_office_document_content(self, tag, attrs): + """ Last tag """ + self.closetag('html') + + def s_office_master_styles(self, tag, attrs): + """ """ + + def s_office_presentation(self, tag, attrs): + """ For some odd reason, OpenOffice Impress doesn't define a default-style + for the 'paragraph'. We therefore force a standard when we see + it is a presentation + """ + self.styledict['p'] = {(FONS,u'font-size'): u"24pt" } + self.styledict['presentation'] = {(FONS,u'font-size'): u"24pt" } + self.html_body(tag, attrs) + + def e_office_presentation(self, tag, attrs): + self.generate_footnotes() + self.closetag('body') + + def s_office_spreadsheet(self, tag, attrs): + self.html_body(tag, attrs) + + def e_office_spreadsheet(self, tag, attrs): + self.generate_footnotes() + self.closetag('body') + + def s_office_styles(self, tag, attrs): + self.autoprefix = "" + + def s_office_text(self, tag, attrs): + """ OpenDocument text """ + self.styledict['frame'] = { (STYLENS,'wrap'): u'parallel'} + self.html_body(tag, attrs) + + def e_office_text(self, tag, attrs): + self.generate_footnotes() + self.closetag('body') + + def s_style_handle_properties(self, tag, attrs): + """ Copy all attributes to a struct. + We will later convert them to CSS2 + """ + for key,attr in attrs.items(): + self.styledict[self.currentstyle][key] = attr + + + familymap = {'frame':'frame', 'paragraph':'p', 'presentation':'presentation', + 'text':'span','section':'div', + 'table':'table','table-cell':'td','table-column':'col', + 'table-row':'tr','graphic':'graphic' } + + def s_style_default_style(self, tag, attrs): + """ A default style is like a style on an HTML tag + """ + family = attrs[(STYLENS,'family')] + htmlfamily = self.familymap.get(family,'unknown') + self.currentstyle = htmlfamily +# self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def e_style_default_style(self, tag, attrs): + self.currentstyle = None + + def s_style_font_face(self, tag, attrs): + """ It is possible that the HTML browser doesn't know how to + show a particular font. Luckily ODF provides generic fallbacks + Unfortunately they are not the same as CSS2. + CSS2: serif, sans-serif, cursive, fantasy, monospace + ODF: roman, swiss, modern, decorative, script, system + """ + name = attrs[(STYLENS,"name")] + family = attrs[(SVGNS,"font-family")] + generic = attrs.get( (STYLENS,'font-family-generic'),"" ) + self.cs.save_font(name, family, generic) + + def s_style_footer(self, tag, attrs): + self.opentag('div', { 'id':"footer" }) + self.purgedata() + + def e_style_footer(self, tag, attrs): + self.writedata() + self.closetag('div') + self.purgedata() + + def s_style_footer_style(self, tag, attrs): + self.currentstyle = "@print #footer" + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def s_style_header(self, tag, attrs): + self.opentag('div', { 'id':"header" }) + self.purgedata() + + def e_style_header(self, tag, attrs): + self.writedata() + self.closetag('div') + self.purgedata() + + def s_style_header_style(self, tag, attrs): + self.currentstyle = "@print #header" + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def s_style_default_page_layout(self, tag, attrs): + """ Collect the formatting for the default page layout style. + """ + self.currentstyle = "@page" + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def s_style_page_layout(self, tag, attrs): + """ Collect the formatting for the page layout style. + This won't work in CSS 2.1, as page identifiers are not allowed. + It is legal in CSS3, but the rest of the application doesn't specify when to use what page layout + """ + name = attrs[(STYLENS,'name')] + name = name.replace(".","_") + self.currentstyle = ".PL-" + name + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def e_style_page_layout(self, tag, attrs): + """ End this style + """ + self.currentstyle = None + + def s_style_master_page(self, tag, attrs): + """ Collect the formatting for the page layout style. + """ + name = attrs[(STYLENS,'name')] + name = name.replace(".","_") + + self.currentstyle = ".MP-" + name + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {('','position'):'relative'} + # Then load the pagelayout style if we find it + pagelayout = attrs.get( (STYLENS,'page-layout-name'), None) + if pagelayout: + pagelayout = ".PL-" + pagelayout + if pagelayout in self.styledict: + styles = self.styledict[pagelayout] + for style, val in styles.items(): + self.styledict[self.currentstyle][style] = val + else: + self.styledict[self.currentstyle]['__parent-style-name'] = pagelayout + self.s_ignorexml(tag, attrs) + + # Short prefixes for class selectors + _familyshort = {'drawing-page':'DP', 'paragraph':'P', 'presentation':'PR', + 'text':'S', 'section':'D', + 'table':'T', 'table-cell':'TD', 'table-column':'TC', + 'table-row':'TR', 'graphic':'G' } + + def s_style_style(self, tag, attrs): + """ Collect the formatting for the style. + Styles have scope. The same name can be used for both paragraph and + character styles Since CSS has no scope we use a prefix. (Not elegant) + In ODF a style can have a parent, these parents can be chained. + We may not have encountered the parent yet, but if we have, we resolve it. + """ + name = attrs[(STYLENS,'name')] + name = name.replace(".","_") + family = attrs[(STYLENS,'family')] + htmlfamily = self.familymap.get(family,'unknown') + sfamily = self._familyshort.get(family,'X') + name = "%s%s-%s" % (self.autoprefix, sfamily, name) + parent = attrs.get( (STYLENS,'parent-style-name') ) + self.currentstyle = special_styles.get(name,"."+name) + self.stylestack.append(self.currentstyle) + if self.currentstyle not in self.styledict: + self.styledict[self.currentstyle] = {} + + self.styledict[self.currentstyle]['__style-family'] = htmlfamily + + # Then load the parent style if we find it + if parent: + parent = "%s-%s" % (sfamily, parent) + parent = special_styles.get(parent, "."+parent) + if parent in self.styledict: + styles = self.styledict[parent] + for style, val in styles.items(): + self.styledict[self.currentstyle][style] = val + else: + self.styledict[self.currentstyle]['__parent-style-name'] = parent + + def e_style_style(self, tag, attrs): + """ End this style + """ + self.currentstyle = None + + def s_table_table(self, tag, attrs): + """ Start a table + """ + c = attrs.get( (TABLENS,'style-name'), None) + if c and self.generate_css: + c = c.replace(".","_") + self.opentag('table',{ 'class': "T-%s" % c }) + else: + self.opentag('table') + self.purgedata() + + def e_table_table(self, tag, attrs): + """ End a table + """ + self.writedata() + self.closetag('table') + self.purgedata() + + def s_table_table_cell(self, tag, attrs): + """ Start a table cell """ + #FIXME: number-columns-repeated § 8.1.3 + #repeated = int(attrs.get( (TABLENS,'number-columns-repeated'), 1)) + htmlattrs = {} + rowspan = attrs.get( (TABLENS,'number-rows-spanned') ) + if rowspan: + htmlattrs['rowspan'] = rowspan + colspan = attrs.get( (TABLENS,'number-columns-spanned') ) + if colspan: + htmlattrs['colspan'] = colspan + + c = attrs.get( (TABLENS,'style-name') ) + if c: + htmlattrs['class'] = 'TD-%s' % c.replace(".","_") + self.opentag('td', htmlattrs) + self.purgedata() + + def e_table_table_cell(self, tag, attrs): + """ End a table cell """ + self.writedata() + self.closetag('td') + self.purgedata() + + def s_table_table_column(self, tag, attrs): + """ Start a table column """ + c = attrs.get( (TABLENS,'style-name'), None) + repeated = int(attrs.get( (TABLENS,'number-columns-repeated'), 1)) + htmlattrs = {} + if c: + htmlattrs['class'] = "TC-%s" % c.replace(".","_") + for x in range(repeated): + self.emptytag('col', htmlattrs) + self.purgedata() + + def s_table_table_row(self, tag, attrs): + """ Start a table row """ + #FIXME: table:number-rows-repeated + c = attrs.get( (TABLENS,'style-name'), None) + htmlattrs = {} + if c: + htmlattrs['class'] = "TR-%s" % c.replace(".","_") + self.opentag('tr', htmlattrs) + self.purgedata() + + def e_table_table_row(self, tag, attrs): + """ End a table row """ + self.writedata() + self.closetag('tr') + self.purgedata() + + def s_text_a(self, tag, attrs): + """ Anchors start """ + self.writedata() + href = attrs[(XLINKNS,"href")].split("|")[0] + if href[0] == "#": + href = "#" + self.get_anchor(href[1:]) + self.opentag('a', {'href':href}) + self.purgedata() + + def e_text_a(self, tag, attrs): + """ End an anchor or bookmark reference """ + self.writedata() + self.closetag('a', False) + self.purgedata() + + def s_text_bookmark(self, tag, attrs): + """ Bookmark definition """ + name = attrs[(TEXTNS,'name')] + html_id = self.get_anchor(name) + self.writedata() + self.opentag('span', {'id':html_id}) + self.closetag('span', False) + self.purgedata() + + def s_text_bookmark_ref(self, tag, attrs): + """ Bookmark reference """ + name = attrs[(TEXTNS,'ref-name')] + html_id = "#" + self.get_anchor(name) + self.writedata() + self.opentag('a', {'href':html_id}) + self.purgedata() + + def s_text_h(self, tag, attrs): + """ Headings start """ + level = int(attrs[(TEXTNS,'outline-level')]) + if level > 6: level = 6 # Heading levels go only to 6 in XHTML + if level < 1: level = 1 + self.headinglevels[level] = self.headinglevels[level] + 1 + name = self.classname(attrs) + for x in range(level + 1,10): + self.headinglevels[x] = 0 + special = special_styles.get("P-"+name) + if special or not self.generate_css: + self.opentag('h%s' % level) + else: + self.opentag('h%s' % level, {'class':"P-%s" % name }) + self.purgedata() + + def e_text_h(self, tag, attrs): + """ Headings end + Side-effect: If there is no title in the metadata, then it is taken + from the first heading of any level. + """ + self.writedata() + level = int(attrs[(TEXTNS,'outline-level')]) + if level > 6: level = 6 # Heading levels go only to 6 in XHTML + if level < 1: level = 1 + lev = self.headinglevels[1:level+1] + outline = '.'.join(map(str,lev) ) + heading = ''.join(self.data) + if self.title == '': self.title = heading + anchor = self.get_anchor("%s.%s" % ( outline, heading)) + self.opentag('a', {'id': anchor} ) + self.closetag('a', False) + self.closetag('h%s' % level) + self.purgedata() + + def s_text_line_break(self, tag, attrs): + """ Force a line break (
) """ + self.writedata() + self.emptytag('br') + self.purgedata() + + def s_text_list(self, tag, attrs): + """ Start a list (