Compare commits
No commits in common. "master" and "debian" have entirely different histories.
|
@ -1,28 +0,0 @@
|
|||
# application builds
|
||||
build/*
|
||||
dist/*
|
||||
MANIFEST
|
||||
|
||||
# python skin
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
||||
# osx noise
|
||||
.DS_Store
|
||||
profile
|
||||
|
||||
# pycharm noise
|
||||
.idea
|
||||
.idea/*
|
||||
|
||||
# vi noise
|
||||
*.swp
|
||||
docs/_build/*
|
||||
coverage.xml
|
||||
nosetests.xml
|
||||
junit-py25.xml
|
||||
junit-py26.xml
|
||||
junit-py27.xml
|
||||
|
||||
# tox noise
|
||||
.tox
|
|
@ -1,8 +0,0 @@
|
|||
language: python
|
||||
python:
|
||||
- 2.6
|
||||
- 2.7
|
||||
- 3.2
|
||||
install:
|
||||
- python setup.py install
|
||||
script: python test_tablib.py
|
24
AUTHORS
24
AUTHORS
|
@ -1,24 +0,0 @@
|
|||
Tablib is written and maintained by Kenneth Reitz and
|
||||
various contributors:
|
||||
|
||||
Development Lead
|
||||
````````````````
|
||||
|
||||
- Kenneth Reitz <_@kennethreitz.com>
|
||||
|
||||
|
||||
Patches and Suggestions
|
||||
```````````````````````
|
||||
|
||||
- Luke Lee
|
||||
- Josh Ourisman
|
||||
- Luca Beltrame
|
||||
- Benjamin Wohlwend
|
||||
- Erik Youngren
|
||||
- Mark Rogers
|
||||
- Mark Walling
|
||||
- Mike Waldner
|
||||
- Joel Friedly
|
||||
- Jakub Janoszek
|
||||
- Marc Abramowitz
|
||||
- Alex Gaynor
|
14
HACKING
14
HACKING
|
@ -1,14 +0,0 @@
|
|||
Where possible, please follow PEP8 with regard to coding style. Sometimes the line
|
||||
length restriction is too hard to follow, so don't bend over backwards there.
|
||||
|
||||
Triple-quotes should always be """, single quotes are ' unless using "
|
||||
would result in less escaping within the string.
|
||||
|
||||
All modules, functions, and methods should be well documented reStructuredText for
|
||||
Sphinx AutoDoc.
|
||||
|
||||
All functionality should be available in pure Python. Optional C (via Cython)
|
||||
implementations may be written for performance reasons, but should never
|
||||
replace the Python implementation.
|
||||
|
||||
Lastly, don't take yourself too seriously :)
|
190
HISTORY.rst
190
HISTORY.rst
|
@ -1,190 +0,0 @@
|
|||
History
|
||||
-------
|
||||
|
||||
++++
|
||||
|
||||
* Unicode Column Headers
|
||||
|
||||
0.9.11 (2011-06-30)
|
||||
+++++++++++++++++++
|
||||
|
||||
* Bugfixes
|
||||
|
||||
0.9.10 (2011-06-22)
|
||||
+++++++++++++++++++
|
||||
|
||||
* Bugfixes
|
||||
|
||||
0.9.9 (2011-06-21)
|
||||
++++++++++++++++++
|
||||
|
||||
* Dataset API Changes
|
||||
* ``stack_rows`` => ``stack``, ``stack_columns`` => ``stack_cols``
|
||||
* column operations have their own methods now (``append_col``, ``insert_col``)
|
||||
* List-style ``pop()``
|
||||
* Redis-style ``rpush``, ``lpush``, ``rpop``, ``lpop``, ``rpush_col``, and ``lpush_col``
|
||||
|
||||
0.9.8 (2011-05-22)
|
||||
++++++++++++++++++
|
||||
|
||||
* OpenDocument Spreadsheet support (.ods)
|
||||
* Full Unicode TSV support
|
||||
|
||||
|
||||
0.9.7 (2011-05-12)
|
||||
++++++++++++++++++
|
||||
|
||||
* Full XLSX Support!
|
||||
* Pickling Bugfix
|
||||
* Compat Module
|
||||
|
||||
|
||||
0.9.6 (2011-05-12)
|
||||
++++++++++++++++++
|
||||
|
||||
* ``seperators`` renamed to ``separators``
|
||||
* Full unicode CSV support
|
||||
|
||||
|
||||
0.9.5 (2011-03-24)
|
||||
++++++++++++++++++
|
||||
|
||||
* Python 3.1, Python 3.2 Support (same code base!)
|
||||
* Formatter callback support
|
||||
* Various bug fixes
|
||||
|
||||
|
||||
|
||||
0.9.4 (2011-02-18)
|
||||
++++++++++++++++++
|
||||
|
||||
* Python 2.5 Support!
|
||||
* Tox Testing for 2.5, 2.6, 2.7
|
||||
* AnyJSON Integrated
|
||||
* OrderedDict support
|
||||
* Caved to community pressure (spaces)
|
||||
|
||||
|
||||
0.9.3 (2011-01-31)
|
||||
++++++++++++++++++
|
||||
|
||||
* Databook duplication leak fix.
|
||||
* HTML Table output.
|
||||
* Added column sorting.
|
||||
|
||||
|
||||
0.9.2 (2010-11-17)
|
||||
++++++++++++++++++
|
||||
|
||||
* Transpose method added to Datasets.
|
||||
* New frozen top row in Excel output.
|
||||
* Pickling support for Datasets and Rows.
|
||||
* Support for row/column stacking.
|
||||
|
||||
|
||||
0.9.1 (2010-11-04)
|
||||
++++++++++++++++++
|
||||
|
||||
* Minor reference shadowing bugfix.
|
||||
|
||||
|
||||
0.9.0 (2010-11-04)
|
||||
++++++++++++++++++
|
||||
|
||||
* Massive documentation update!
|
||||
* Tablib.org!
|
||||
* Row tagging and Dataset filtering!
|
||||
* Column insert/delete support
|
||||
* Column append API change (header required)
|
||||
* Internal Changes (Row object and use thereof)
|
||||
|
||||
|
||||
0.8.5 (2010-10-06)
|
||||
++++++++++++++++++
|
||||
|
||||
* New import system. All dependencies attempt to load from site-packages,
|
||||
then fallback on tenderized modules.
|
||||
|
||||
|
||||
0.8.4 (2010-10-04)
|
||||
++++++++++++++++++
|
||||
|
||||
* Updated XLS output: Only wrap if '\\n' in cell.
|
||||
|
||||
|
||||
0.8.3 (2010-10-04)
|
||||
++++++++++++++++++
|
||||
|
||||
* Ability to append new column passing a callable
|
||||
as the value that will be applied to every row.
|
||||
|
||||
|
||||
0.8.2 (2010-10-04)
|
||||
++++++++++++++++++
|
||||
|
||||
* Added alignment wrapping to written cells.
|
||||
* Added separator support to XLS.
|
||||
|
||||
|
||||
0.8.1 (2010-09-28)
|
||||
++++++++++++++++++
|
||||
|
||||
* Packaging Fix
|
||||
|
||||
|
||||
0.8.0 (2010-09-25)
|
||||
++++++++++++++++++
|
||||
|
||||
* New format plugin system!
|
||||
* Imports! ELEGANT Imports!
|
||||
* Tests. Lots of tests.
|
||||
|
||||
|
||||
0.7.1 (2010-09-20)
|
||||
++++++++++++++++++
|
||||
|
||||
* Reverting methods back to properties.
|
||||
* Windows bug compensated in documentation.
|
||||
|
||||
|
||||
0.7.0 (2010-09-20)
|
||||
++++++++++++++++++
|
||||
|
||||
* Renamed DataBook Databook for consistency.
|
||||
* Export properties changed to methods (XLS filename / StringIO bug).
|
||||
* Optional Dataset.xls(path='filename') support (for writing on windows).
|
||||
* Added utf-8 on the worksheet level.
|
||||
|
||||
|
||||
0.6.4 (2010-09-19)
|
||||
++++++++++++++++++
|
||||
|
||||
* Updated unicode export for XLS.
|
||||
* More exhaustive unit tests.
|
||||
|
||||
|
||||
0.6.3 (2010-09-14)
|
||||
++++++++++++++++++
|
||||
* Added Dataset.append() support for columns.
|
||||
|
||||
|
||||
0.6.2 (2010-09-13)
|
||||
++++++++++++++++++
|
||||
* Fixed Dataset.append() error on empty dataset.
|
||||
* Updated Dataset.headers property w/ validation.
|
||||
* Added Testing Fixtures.
|
||||
|
||||
0.6.1 (2010-09-12)
|
||||
++++++++++++++++++
|
||||
|
||||
* Packaging hotfixes.
|
||||
|
||||
|
||||
0.6.0 (2010-09-11)
|
||||
++++++++++++++++++
|
||||
|
||||
* Public Release.
|
||||
* Export Support for XLS, JSON, YAML, and CSV.
|
||||
* DataBook Export for XLS, JSON, and YAML.
|
||||
* Python Dict Property Support.
|
||||
|
19
LICENSE
19
LICENSE
|
@ -1,19 +0,0 @@
|
|||
Copyright 2011 Kenneth Reitz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -1 +0,0 @@
|
|||
include HISTORY.rst README.rst LICENSE AUTHORS
|
459
NOTICE
459
NOTICE
|
@ -1,459 +0,0 @@
|
|||
Tablib includes some vendorized python libraries: ordereddict, odfpy, pyyaml,
|
||||
simplejson, unicodecsv, xlrd, xlrd3, xlwt, and xlwt3.
|
||||
|
||||
Markup License
|
||||
==============
|
||||
|
||||
Markup is in the public domain.
|
||||
|
||||
|
||||
Odfpy License
|
||||
=============
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
OrderedDict License
|
||||
===================
|
||||
|
||||
Copyright (c) 2009 Raymond Hettinger
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
|
||||
PyYAML License
|
||||
==============
|
||||
|
||||
Copyright (c) 2006 Kirill Simonov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
|
||||
UnicodeCSV License
|
||||
==================
|
||||
|
||||
Copyright 2010 Jeremy Dunck. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
of conditions and the following disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY JEREMY DUNCK ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JEREMY DUNCK OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those of the
|
||||
authors and should not be interpreted as representing official policies, either expressed
|
||||
or implied, of Jeremy Dunck.
|
||||
|
||||
|
||||
|
||||
|
||||
XLWT (and XLWT3) License
|
||||
========================
|
||||
|
||||
Portions copyright © 2007, Stephen John Machin, Lingfo Pty Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. None of the names of Stephen John Machin, Lingfo Pty Ltd and any
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
"""
|
||||
Copyright (C) 2005 Roman V. Kiseliov
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. All advertising materials mentioning features or use of this
|
||||
software must display the following acknowledgment:
|
||||
"This product includes software developed by
|
||||
Roman V. Kiseliov <roman@kiseliov.ru>."
|
||||
|
||||
4. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes software developed by
|
||||
Roman V. Kiseliov <roman@kiseliov.ru>."
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
|
||||
EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
|
||||
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Roman V. Kiseliov
|
||||
Russia
|
||||
Kursk
|
||||
Libknecht St., 4
|
||||
|
||||
+7(0712)56-09-83
|
||||
|
||||
<roman@kiseliov.ru>
|
||||
Subject: pyExcelerator
|
||||
|
||||
|
||||
|
||||
|
||||
XLRD (and XLRD3) License
|
||||
========================
|
||||
|
||||
Portions copyright © 2005-2009, Stephen John Machin, Lingfo Pty Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. None of the names of Stephen John Machin, Lingfo Pty Ltd and any
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Copyright (c) 2001 David Giffin.
|
||||
All rights reserved.
|
||||
|
||||
Based on the the Java version: Andrew Khan Copyright (c) 2000.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. All advertising materials mentioning features or use of this
|
||||
software must display the following acknowledgment:
|
||||
"This product includes software developed by
|
||||
David Giffin <david@giffin.org>."
|
||||
|
||||
4. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes software developed by
|
||||
David Giffin <david@giffin.org>."
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY DAVID GIFFIN ``AS IS'' AND ANY
|
||||
EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID GIFFIN OR
|
||||
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
148
README.rst
148
README.rst
|
@ -1,148 +0,0 @@
|
|||
Tablib: format-agnostic tabular dataset library
|
||||
===============================================
|
||||
|
||||
::
|
||||
|
||||
_____ ______ ___________ ______
|
||||
__ /_______ ____ /_ ___ /___(_)___ /_
|
||||
_ __/_ __ `/__ __ \__ / __ / __ __ \
|
||||
/ /_ / /_/ / _ /_/ /_ / _ / _ /_/ /
|
||||
\__/ \__,_/ /_.___/ /_/ /_/ /_.___/
|
||||
|
||||
|
||||
|
||||
Tablib is a format-agnostic tabular dataset library, written in Python.
|
||||
|
||||
Output formats supported:
|
||||
|
||||
- Excel (Sets + Books)
|
||||
- JSON (Sets + Books)
|
||||
- YAML (Sets + Books)
|
||||
- HTML (Sets)
|
||||
- TSV (Sets)
|
||||
- CSV (Sets)
|
||||
|
||||
Note that tablib *purposefully* excludes XML support. It always will. (Note: This is a joke. Pull requests are welcome.)
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
`tablib.Dataset()`
|
||||
A Dataset is a table of tabular data. It may or may not have a header row. They can be build and manipulated as raw Python datatypes (Lists of tuples|dictionaries). Datasets can be imported from JSON, YAML, and CSV; they can be exported to XLSX, XLS, ODS, JSON, YAML, CSV, TSV, and HTML.
|
||||
|
||||
`tablib.Databook()`
|
||||
A Databook is a set of Datasets. The most common form of a Databook is an Excel file with multiple spreadsheets. Databooks can be imported from JSON and YAML; they can be exported to XLSX, XLS, ODS, JSON, and YAML.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
|
||||
Populate fresh data files: ::
|
||||
|
||||
headers = ('first_name', 'last_name')
|
||||
|
||||
data = [
|
||||
('John', 'Adams'),
|
||||
('George', 'Washington')
|
||||
]
|
||||
|
||||
data = tablib.Dataset(*data, headers=headers)
|
||||
|
||||
|
||||
Intelligently add new rows: ::
|
||||
|
||||
>>> data.append(('Henry', 'Ford'))
|
||||
|
||||
Intelligently add new columns: ::
|
||||
|
||||
>>> data.append_col((90, 67, 83), header='age')
|
||||
|
||||
Slice rows: ::
|
||||
|
||||
>>> print data[:2]
|
||||
[('John', 'Adams', 90), ('George', 'Washington', 67)]
|
||||
|
||||
|
||||
Slice columns by header: ::
|
||||
|
||||
>>> print data['first_name']
|
||||
['John', 'George', 'Henry']
|
||||
|
||||
Easily delete rows: ::
|
||||
|
||||
>>> del data[1]
|
||||
|
||||
Exports
|
||||
-------
|
||||
|
||||
Drumroll please...........
|
||||
|
||||
JSON!
|
||||
+++++
|
||||
::
|
||||
|
||||
>>> print data.json
|
||||
[
|
||||
{
|
||||
"last_name": "Adams",
|
||||
"age": 90,
|
||||
"first_name": "John"
|
||||
},
|
||||
{
|
||||
"last_name": "Ford",
|
||||
"age": 83,
|
||||
"first_name": "Henry"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
YAML!
|
||||
+++++
|
||||
::
|
||||
|
||||
>>> print data.yaml
|
||||
- {age: 90, first_name: John, last_name: Adams}
|
||||
- {age: 83, first_name: Henry, last_name: Ford}
|
||||
|
||||
CSV...
|
||||
++++++
|
||||
::
|
||||
|
||||
>>> print data.csv
|
||||
first_name,last_name,age
|
||||
John,Adams,90
|
||||
Henry,Ford,83
|
||||
|
||||
EXCEL!
|
||||
++++++
|
||||
::
|
||||
|
||||
>>> with open('people.xls', 'wb') as f:
|
||||
... f.write(data.xls)
|
||||
|
||||
It's that easy.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
To install tablib, simply: ::
|
||||
|
||||
$ pip install tablib
|
||||
|
||||
Or, if you absolutely must: ::
|
||||
|
||||
$ easy_install tablib
|
||||
|
||||
Contribute
|
||||
----------
|
||||
|
||||
If you'd like to contribute, simply fork `the repository`_, commit your
|
||||
changes to the **develop** branch (or branch off of it), and send a pull
|
||||
request. Make sure you add yourself to AUTHORS_.
|
||||
|
||||
|
||||
|
||||
|
||||
.. _`the repository`: http://github.com/kennethreitz/tablib
|
||||
.. _AUTHORS: http://github.com/kennethreitz/tablib/blob/master/AUTHORS
|
7
TODO.rst
7
TODO.rst
|
@ -1,7 +0,0 @@
|
|||
* Hooks System
|
||||
- pre/post-append
|
||||
- pre/post-import
|
||||
- pre/post-export
|
||||
* Add Tablib.ext namespace
|
||||
* Width detection for XLS output
|
||||
* Documentation Improvements
|
|
@ -0,0 +1,5 @@
|
|||
tablib (0.9.11-0) unstable; urgency=low
|
||||
|
||||
* Initial packaging
|
||||
|
||||
-- Benjamin Dauvergne <bdauvergne@entrouvert.com> Thu, 13 Oct 2014 23:42:57 +0200
|
|
@ -0,0 +1 @@
|
|||
7
|
|
@ -0,0 +1,12 @@
|
|||
Source: tablib
|
||||
Maintainer: Benjamin Dauvergne <bdauvergne@entrouvert.com>
|
||||
Section: python
|
||||
Priority: optional
|
||||
Build-Depends: python-setuptools (>= 0.6b3), python-all (>= 2.6.6-3), debhelper (>= 7)
|
||||
Standards-Version: 3.9.1
|
||||
X-Python-Version: >= 2.6
|
||||
|
||||
Package: python-tablib
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, ${python:Depends}
|
||||
Description: Format agnostic tabular data library (XLS, JSON, YAML, CSV)
|
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/make -f
|
||||
BUILD_DIR := 'debian/python-tablib'
|
||||
|
||||
%:
|
||||
dh $@ --with python2
|
||||
|
||||
# remove all python3 files
|
||||
override_dh_install:
|
||||
dh_install
|
||||
rm $(BUILD_DIR)/usr/lib/python2.*/dist-packages/tablib/packages/markup3.py
|
||||
rm -r $(BUILD_DIR)/usr/lib/python2.*/dist-packages/tablib/packages/odf3
|
||||
rm -r $(BUILD_DIR)/usr/lib/python2.*/dist-packages/tablib/packages/openpyxl3
|
||||
rm -r $(BUILD_DIR)/usr/lib/python2.*/dist-packages/tablib/packages/xlrd3
|
||||
rm -r $(BUILD_DIR)/usr/lib/python2.*/dist-packages/tablib/packages/xlwt3
|
|
@ -0,0 +1 @@
|
|||
3.0 (quilt)
|
|
@ -0,0 +1 @@
|
|||
extend-diff-ignore="\.egg-info"
|
130
docs/Makefile
130
docs/Makefile
|
@ -1,130 +0,0 @@
|
|||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Tablib.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Tablib.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/Tablib"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Tablib"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
make -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
|
@ -1,20 +0,0 @@
|
|||
<h3><a href="http://docs.python-tablib.org">About Tablib</a></h3>
|
||||
<p>
|
||||
Tablib is an MIT Licensed format-agnostic tabular dataset library, written in Python. It allows you to import, export, and manipulate tabular data sets. Advanced features include, segregation, dynamic columns, tags & filtering, and seamless format import & export.
|
||||
</p>
|
||||
|
||||
<h3>Feedback</h3>
|
||||
<p>
|
||||
Feedback is greatly appreciated. If you have any questions, comments,
|
||||
random praise, or anonymous threats, <a href="mailto:me@kennethreitz.com">
|
||||
shoot me an email</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<h3>Useful Links</h3>
|
||||
<ul>
|
||||
<li><a href="http://docs.python-tablib.org/">The Tablib Website</a></li>
|
||||
<li><a href="http://pypi.python.org/pypi/tablib">Tablib @ PyPI</a></li>
|
||||
<li><a href="http://github.com/kennethreitz/tablib">Tablib @ GitHub</a></li>
|
||||
<li><a href="http://github.com/kennethreitz/tablib/issues">Issue Tracker</a></li>
|
||||
</ul>
|
|
@ -1,4 +0,0 @@
|
|||
<h3><a href="http://docs.python-tablib.org/">About Tablib</a></h3>
|
||||
<p>
|
||||
Tablib is an MIT Licensed format-agnostic tabular dataset library, written in Python. It allows you to import, export, and manipulate tabular data sets. Advanced features include, segregation, dynamic columns, tags & filtering, and seamless format import & export.
|
||||
</p>
|
|
@ -1,3 +0,0 @@
|
|||
*.pyc
|
||||
*.pyo
|
||||
.DS_Store
|
|
@ -1,45 +0,0 @@
|
|||
Modifications:
|
||||
|
||||
Copyright (c) 2011 Kenneth Reitz.
|
||||
|
||||
|
||||
Original Project:
|
||||
|
||||
Copyright (c) 2010 by Armin Ronacher.
|
||||
|
||||
|
||||
Some rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms of the theme, with or
|
||||
without modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* The names of the contributors may not be used to endorse or
|
||||
promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
We kindly ask you to only use these themes in an unmodified manner just
|
||||
for Flask and Flask-related products, not for unrelated projects. If you
|
||||
like the visual style and want to use it for your own projects, please
|
||||
consider making some larger changes to the themes (such as changing
|
||||
font faces, sizes, colors or margins).
|
||||
|
||||
THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,25 +0,0 @@
|
|||
krTheme Sphinx Style
|
||||
====================
|
||||
|
||||
This repository contains sphinx styles Kenneth Reitz uses in most of
|
||||
his projects. It is a drivative of Mitsuhiko's themes for Flask and Flask related
|
||||
projects. To use this style in your Sphinx documentation, follow
|
||||
this guide:
|
||||
|
||||
1. put this folder as _themes into your docs folder. Alternatively
|
||||
you can also use git submodules to check out the contents there.
|
||||
|
||||
2. add this to your conf.py: ::
|
||||
|
||||
sys.path.append(os.path.abspath('_themes'))
|
||||
html_theme_path = ['_themes']
|
||||
html_theme = 'flask'
|
||||
|
||||
The following themes exist:
|
||||
|
||||
**kr**
|
||||
the standard flask documentation theme for large projects
|
||||
|
||||
**kr_small**
|
||||
small one-page theme. Intended to be used by very small addon libraries.
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
# flasky extensions. flasky pygments style based on tango style
|
||||
from pygments.style import Style
|
||||
from pygments.token import Keyword, Name, Comment, String, Error, \
|
||||
Number, Operator, Generic, Whitespace, Punctuation, Other, Literal
|
||||
|
||||
|
||||
class FlaskyStyle(Style):
|
||||
background_color = "#f8f8f8"
|
||||
default_style = ""
|
||||
|
||||
styles = {
|
||||
# No corresponding class for the following:
|
||||
#Text: "", # class: ''
|
||||
Whitespace: "underline #f8f8f8", # class: 'w'
|
||||
Error: "#a40000 border:#ef2929", # class: 'err'
|
||||
Other: "#000000", # class 'x'
|
||||
|
||||
Comment: "italic #8f5902", # class: 'c'
|
||||
Comment.Preproc: "noitalic", # class: 'cp'
|
||||
|
||||
Keyword: "bold #004461", # class: 'k'
|
||||
Keyword.Constant: "bold #004461", # class: 'kc'
|
||||
Keyword.Declaration: "bold #004461", # class: 'kd'
|
||||
Keyword.Namespace: "bold #004461", # class: 'kn'
|
||||
Keyword.Pseudo: "bold #004461", # class: 'kp'
|
||||
Keyword.Reserved: "bold #004461", # class: 'kr'
|
||||
Keyword.Type: "bold #004461", # class: 'kt'
|
||||
|
||||
Operator: "#582800", # class: 'o'
|
||||
Operator.Word: "bold #004461", # class: 'ow' - like keywords
|
||||
|
||||
Punctuation: "bold #000000", # class: 'p'
|
||||
|
||||
# because special names such as Name.Class, Name.Function, etc.
|
||||
# are not recognized as such later in the parsing, we choose them
|
||||
# to look the same as ordinary variables.
|
||||
Name: "#000000", # class: 'n'
|
||||
Name.Attribute: "#c4a000", # class: 'na' - to be revised
|
||||
Name.Builtin: "#004461", # class: 'nb'
|
||||
Name.Builtin.Pseudo: "#3465a4", # class: 'bp'
|
||||
Name.Class: "#000000", # class: 'nc' - to be revised
|
||||
Name.Constant: "#000000", # class: 'no' - to be revised
|
||||
Name.Decorator: "#888", # class: 'nd' - to be revised
|
||||
Name.Entity: "#ce5c00", # class: 'ni'
|
||||
Name.Exception: "bold #cc0000", # class: 'ne'
|
||||
Name.Function: "#000000", # class: 'nf'
|
||||
Name.Property: "#000000", # class: 'py'
|
||||
Name.Label: "#f57900", # class: 'nl'
|
||||
Name.Namespace: "#000000", # class: 'nn' - to be revised
|
||||
Name.Other: "#000000", # class: 'nx'
|
||||
Name.Tag: "bold #004461", # class: 'nt' - like a keyword
|
||||
Name.Variable: "#000000", # class: 'nv' - to be revised
|
||||
Name.Variable.Class: "#000000", # class: 'vc' - to be revised
|
||||
Name.Variable.Global: "#000000", # class: 'vg' - to be revised
|
||||
Name.Variable.Instance: "#000000", # class: 'vi' - to be revised
|
||||
|
||||
Number: "#990000", # class: 'm'
|
||||
|
||||
Literal: "#000000", # class: 'l'
|
||||
Literal.Date: "#000000", # class: 'ld'
|
||||
|
||||
String: "#4e9a06", # class: 's'
|
||||
String.Backtick: "#4e9a06", # class: 'sb'
|
||||
String.Char: "#4e9a06", # class: 'sc'
|
||||
String.Doc: "italic #8f5902", # class: 'sd' - like a comment
|
||||
String.Double: "#4e9a06", # class: 's2'
|
||||
String.Escape: "#4e9a06", # class: 'se'
|
||||
String.Heredoc: "#4e9a06", # class: 'sh'
|
||||
String.Interpol: "#4e9a06", # class: 'si'
|
||||
String.Other: "#4e9a06", # class: 'sx'
|
||||
String.Regex: "#4e9a06", # class: 'sr'
|
||||
String.Single: "#4e9a06", # class: 's1'
|
||||
String.Symbol: "#4e9a06", # class: 'ss'
|
||||
|
||||
Generic: "#000000", # class: 'g'
|
||||
Generic.Deleted: "#a40000", # class: 'gd'
|
||||
Generic.Emph: "italic #000000", # class: 'ge'
|
||||
Generic.Error: "#ef2929", # class: 'gr'
|
||||
Generic.Heading: "bold #000080", # class: 'gh'
|
||||
Generic.Inserted: "#00A000", # class: 'gi'
|
||||
Generic.Output: "#888", # class: 'go'
|
||||
Generic.Prompt: "#745334", # class: 'gp'
|
||||
Generic.Strong: "bold #000000", # class: 'gs'
|
||||
Generic.Subheading: "bold #800080", # class: 'gu'
|
||||
Generic.Traceback: "bold #a40000", # class: 'gt'
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
{%- extends "basic/layout.html" %}
|
||||
{%- block extrahead %}
|
||||
{{ super() }}
|
||||
{% if theme_touch_icon %}
|
||||
<link rel="apple-touch-icon" href="{{ pathto('_static/' ~ theme_touch_icon, 1) }}" />
|
||||
{% endif %}
|
||||
<link media="only screen and (max-device-width: 480px)" href="{{
|
||||
pathto('_static/small_flask.css', 1) }}" type= "text/css" rel="stylesheet" />
|
||||
{% endblock %}
|
||||
{%- block relbar2 %}{% endblock %}
|
||||
{%- block footer %}
|
||||
<div class="footer">
|
||||
© Copyright {{ copyright }}.
|
||||
</div>
|
||||
<a href="https://github.com/kennethreitz/tablib">
|
||||
<img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" />
|
||||
</a>
|
||||
|
||||
<script type="text/javascript" src="//www.hellobar.com/hellobar.js"></script>
|
||||
<script type="text/javascript">
|
||||
new HelloBar(36402,48802);
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-8742933-9']);
|
||||
_gaq.push(['_setDomainName', 'none']);
|
||||
_gaq.push(['_setAllowLinker', true]);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var t = document.createElement('script');
|
||||
t.type = 'text/javascript';
|
||||
t.async = true;
|
||||
t.id = 'gauges-tracker';
|
||||
t.setAttribute('data-site-id',
|
||||
'4ddc284f613f5d2f1a000001');
|
||||
t.src = '//secure.gaug.es/track.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(t, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
{%- endblock %}
|
|
@ -1,19 +0,0 @@
|
|||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="{{ pathto(master_doc) }}">Documentation overview</a><ul>
|
||||
{%- for parent in parents %}
|
||||
<li><a href="{{ parent.link|e }}">{{ parent.title }}</a><ul>
|
||||
{%- endfor %}
|
||||
{%- if prev %}
|
||||
<li>Previous: <a href="{{ prev.link|e }}" title="{{ _('previous chapter')
|
||||
}}">{{ prev.title }}</a></li>
|
||||
{%- endif %}
|
||||
{%- if next %}
|
||||
<li>Next: <a href="{{ next.link|e }}" title="{{ _('next chapter')
|
||||
}}">{{ next.title }}</a></li>
|
||||
{%- endif %}
|
||||
{%- for parent in parents %}
|
||||
</ul></li>
|
||||
{%- endfor %}
|
||||
</ul></li>
|
||||
</ul>
|
|
@ -1,470 +0,0 @@
|
|||
/*
|
||||
* flasky.css_t
|
||||
* ~~~~~~~~~~~~
|
||||
*
|
||||
* :copyright: Copyright 2010 by Armin Ronacher. Modifications by Kenneth Reitz.
|
||||
* :license: Flask Design License, see LICENSE for details.
|
||||
*/
|
||||
|
||||
{% set page_width = '940px' %}
|
||||
{% set sidebar_width = '220px' %}
|
||||
|
||||
@import url("basic.css");
|
||||
|
||||
/* -- page layout ----------------------------------------------------------- */
|
||||
|
||||
body {
|
||||
font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro';
|
||||
font-size: 17px;
|
||||
background-color: white;
|
||||
color: #000;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.document {
|
||||
width: {{ page_width }};
|
||||
margin: 30px auto 0 auto;
|
||||
}
|
||||
|
||||
div.documentwrapper {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.bodywrapper {
|
||||
margin: 0 0 0 {{ sidebar_width }};
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
width: {{ sidebar_width }};
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid #B1B4B6;
|
||||
}
|
||||
|
||||
div.body {
|
||||
background-color: #ffffff;
|
||||
color: #3E4349;
|
||||
padding: 0 30px 0 30px;
|
||||
}
|
||||
|
||||
img.floatingflask {
|
||||
padding: 0 0 10px 10px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
div.footer {
|
||||
width: {{ page_width }};
|
||||
margin: 20px auto 30px auto;
|
||||
font-size: 14px;
|
||||
color: #888;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.footer a {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
div.related {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.sphinxsidebar a {
|
||||
color: #444;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted #999;
|
||||
}
|
||||
|
||||
div.sphinxsidebar a:hover {
|
||||
border-bottom: 1px solid #999;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper {
|
||||
padding: 18px 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper p.logo {
|
||||
padding: 0 0 20px 0;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3,
|
||||
div.sphinxsidebar h4 {
|
||||
font-family: 'Garamond', 'Georgia', serif;
|
||||
color: #444;
|
||||
font-size: 24px;
|
||||
font-weight: normal;
|
||||
margin: 0 0 5px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h4 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3 a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
div.sphinxsidebar p.logo a,
|
||||
div.sphinxsidebar h3 a,
|
||||
div.sphinxsidebar p.logo a:hover,
|
||||
div.sphinxsidebar h3 a:hover {
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.sphinxsidebar p {
|
||||
color: #555;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul {
|
||||
margin: 10px 0;
|
||||
padding: 0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input {
|
||||
border: 1px solid #ccc;
|
||||
font-family: 'Georgia', serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
/* -- body styles ----------------------------------------------------------- */
|
||||
|
||||
a {
|
||||
color: #004B6B;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #6D4100;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.body h1,
|
||||
div.body h2,
|
||||
div.body h3,
|
||||
div.body h4,
|
||||
div.body h5,
|
||||
div.body h6 {
|
||||
font-family: 'Garamond', 'Georgia', serif;
|
||||
font-weight: normal;
|
||||
margin: 30px 0px 10px 0px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
|
||||
div.body h2 { font-size: 180%; }
|
||||
div.body h3 { font-size: 150%; }
|
||||
div.body h4 { font-size: 130%; }
|
||||
div.body h5 { font-size: 100%; }
|
||||
div.body h6 { font-size: 100%; }
|
||||
|
||||
a.headerlink {
|
||||
color: #ddd;
|
||||
padding: 0 4px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a.headerlink:hover {
|
||||
color: #444;
|
||||
background: #eaeaea;
|
||||
}
|
||||
|
||||
div.body p, div.body dd, div.body li {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
div.admonition {
|
||||
background: #fafafa;
|
||||
margin: 20px -30px;
|
||||
padding: 10px 30px;
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
div.admonition tt.xref, div.admonition a tt {
|
||||
border-bottom: 1px solid #fafafa;
|
||||
}
|
||||
|
||||
dd div.admonition {
|
||||
margin-left: -60px;
|
||||
padding-left: 60px;
|
||||
}
|
||||
|
||||
div.admonition p.admonition-title {
|
||||
font-family: 'Garamond', 'Georgia', serif;
|
||||
font-weight: normal;
|
||||
font-size: 24px;
|
||||
margin: 0 0 10px 0;
|
||||
padding: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
div.admonition p.last {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.highlight {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
dt:target, .highlight {
|
||||
background: #FAF3E8;
|
||||
}
|
||||
|
||||
div.note {
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
div.seealso {
|
||||
background-color: #ffc;
|
||||
border: 1px solid #ff6;
|
||||
}
|
||||
|
||||
div.topic {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
p.admonition-title {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
p.admonition-title:after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
pre, tt {
|
||||
font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
img.screenshot {
|
||||
}
|
||||
|
||||
tt.descname, tt.descclassname {
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
tt.descname {
|
||||
padding-right: 0.08em;
|
||||
}
|
||||
|
||||
img.screenshot {
|
||||
-moz-box-shadow: 2px 2px 4px #eee;
|
||||
-webkit-box-shadow: 2px 2px 4px #eee;
|
||||
box-shadow: 2px 2px 4px #eee;
|
||||
}
|
||||
|
||||
table.docutils {
|
||||
border: 1px solid #888;
|
||||
-moz-box-shadow: 2px 2px 4px #eee;
|
||||
-webkit-box-shadow: 2px 2px 4px #eee;
|
||||
box-shadow: 2px 2px 4px #eee;
|
||||
}
|
||||
|
||||
table.docutils td, table.docutils th {
|
||||
border: 1px solid #888;
|
||||
padding: 0.25em 0.7em;
|
||||
}
|
||||
|
||||
table.field-list, table.footnote {
|
||||
border: none;
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
table.footnote {
|
||||
margin: 15px 0;
|
||||
width: 100%;
|
||||
border: 1px solid #eee;
|
||||
background: #fdfdfd;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
table.footnote + table.footnote {
|
||||
margin-top: -15px;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
table.field-list th {
|
||||
padding: 0 0.8em 0 0;
|
||||
}
|
||||
|
||||
table.field-list td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table.footnote td.label {
|
||||
width: 0px;
|
||||
padding: 0.3em 0 0.3em 0.5em;
|
||||
}
|
||||
|
||||
table.footnote td {
|
||||
padding: 0.3em 0.5em;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
dl dd {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 0 30px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin: 10px 0 10px 30px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #eee;
|
||||
padding: 7px 30px;
|
||||
margin: 15px -30px;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
dl pre, blockquote pre, li pre {
|
||||
margin-left: -60px;
|
||||
padding-left: 60px;
|
||||
}
|
||||
|
||||
dl dl pre {
|
||||
margin-left: -90px;
|
||||
padding-left: 90px;
|
||||
}
|
||||
|
||||
tt {
|
||||
background-color: #ecf0f3;
|
||||
color: #222;
|
||||
/* padding: 1px 2px; */
|
||||
}
|
||||
|
||||
tt.xref, a tt {
|
||||
background-color: #FBFBFB;
|
||||
border-bottom: 1px solid white;
|
||||
}
|
||||
|
||||
a.reference {
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted #004B6B;
|
||||
}
|
||||
|
||||
a.reference:hover {
|
||||
border-bottom: 1px solid #6D4100;
|
||||
}
|
||||
|
||||
a.footnote-reference {
|
||||
text-decoration: none;
|
||||
font-size: 0.7em;
|
||||
vertical-align: top;
|
||||
border-bottom: 1px dotted #004B6B;
|
||||
}
|
||||
|
||||
a.footnote-reference:hover {
|
||||
border-bottom: 1px solid #6D4100;
|
||||
}
|
||||
|
||||
a:hover tt {
|
||||
background: #EEE;
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
|
||||
div.sphinxsidebar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.documentwrapper {
|
||||
margin-left: 0;
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.bodywrapper {
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.document {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.bodywrapper {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* scrollbars */
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button:start:decrement,
|
||||
::-webkit-scrollbar-button:end:increment {
|
||||
display: block;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button:vertical:increment {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track-piece {
|
||||
background-color: #eee;
|
||||
-webkit-border-radius: 3px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:vertical {
|
||||
height: 50px;
|
||||
background-color: #ccc;
|
||||
-webkit-border-radius: 3px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:horizontal {
|
||||
width: 50px;
|
||||
background-color: #ccc;
|
||||
-webkit-border-radius: 3px;
|
||||
}
|
||||
|
||||
/* misc. */
|
||||
|
||||
.revsys-inline {
|
||||
display: none!important;
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* small_flask.css_t
|
||||
* ~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* :copyright: Copyright 2010 by Armin Ronacher.
|
||||
* :license: Flask Design License, see LICENSE for details.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 20px 30px;
|
||||
}
|
||||
|
||||
div.documentwrapper {
|
||||
float: none;
|
||||
background: white;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
display: block;
|
||||
float: none;
|
||||
width: 102.5%;
|
||||
margin: 50px -30px -20px -30px;
|
||||
padding: 10px 20px;
|
||||
background: #333;
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
|
||||
div.sphinxsidebar h3 a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.sphinxsidebar a {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
div.sphinxsidebar p.logo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.document {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.related {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 10px 0 20px 0;
|
||||
}
|
||||
|
||||
div.related ul,
|
||||
div.related ul li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.bodywrapper {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.body {
|
||||
min-height: 0;
|
||||
padding: 0;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
[theme]
|
||||
inherit = basic
|
||||
stylesheet = flasky.css
|
||||
pygments_style = flask_theme_support.FlaskyStyle
|
||||
|
||||
[options]
|
||||
touch_icon =
|
|
@ -1,22 +0,0 @@
|
|||
{% extends "basic/layout.html" %}
|
||||
{% block header %}
|
||||
{{ super() }}
|
||||
{% if pagename == 'index' %}
|
||||
<div class=indexwrapper>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block footer %}
|
||||
{% if pagename == 'index' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{# do not display relbars #}
|
||||
{% block relbar1 %}{% endblock %}
|
||||
{% block relbar2 %}
|
||||
{% if theme_github_fork %}
|
||||
<a href="http://github.com/{{ theme_github_fork }}"><img style="position: fixed; top: 0; right: 0; border: 0;"
|
||||
src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block sidebar1 %}{% endblock %}
|
||||
{% block sidebar2 %}{% endblock %}
|
|
@ -1,287 +0,0 @@
|
|||
/*
|
||||
* flasky.css_t
|
||||
* ~~~~~~~~~~~~
|
||||
*
|
||||
* Sphinx stylesheet -- flasky theme based on nature theme.
|
||||
*
|
||||
* :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
|
||||
@import url("basic.css");
|
||||
|
||||
/* -- page layout ----------------------------------------------------------- */
|
||||
|
||||
body {
|
||||
font-family: 'Georgia', serif;
|
||||
font-size: 17px;
|
||||
color: #000;
|
||||
background: white;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.documentwrapper {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.bodywrapper {
|
||||
margin: 40px auto 0 auto;
|
||||
width: 700px;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid #B1B4B6;
|
||||
}
|
||||
|
||||
div.body {
|
||||
background-color: #ffffff;
|
||||
color: #3E4349;
|
||||
padding: 0 30px 30px 30px;
|
||||
}
|
||||
|
||||
img.floatingflask {
|
||||
padding: 0 0 10px 10px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
div.footer {
|
||||
text-align: right;
|
||||
color: #888;
|
||||
padding: 10px;
|
||||
font-size: 14px;
|
||||
width: 650px;
|
||||
margin: 0 auto 40px auto;
|
||||
}
|
||||
|
||||
div.footer a {
|
||||
color: #888;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.related {
|
||||
line-height: 32px;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
div.related ul {
|
||||
padding: 0 0 0 10px;
|
||||
}
|
||||
|
||||
div.related a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
/* -- body styles ----------------------------------------------------------- */
|
||||
|
||||
a {
|
||||
color: #004B6B;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #6D4100;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.body {
|
||||
padding-bottom: 40px; /* saved for footer */
|
||||
}
|
||||
|
||||
div.body h1,
|
||||
div.body h2,
|
||||
div.body h3,
|
||||
div.body h4,
|
||||
div.body h5,
|
||||
div.body h6 {
|
||||
font-family: 'Garamond', 'Georgia', serif;
|
||||
font-weight: normal;
|
||||
margin: 30px 0px 10px 0px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
{% if theme_index_logo %}
|
||||
div.indexwrapper h1 {
|
||||
text-indent: -999999px;
|
||||
background: url({{ theme_index_logo }}) no-repeat center center;
|
||||
height: {{ theme_index_logo_height }};
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
div.body h2 { font-size: 180%; }
|
||||
div.body h3 { font-size: 150%; }
|
||||
div.body h4 { font-size: 130%; }
|
||||
div.body h5 { font-size: 100%; }
|
||||
div.body h6 { font-size: 100%; }
|
||||
|
||||
a.headerlink {
|
||||
color: white;
|
||||
padding: 0 4px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a.headerlink:hover {
|
||||
color: #444;
|
||||
background: #eaeaea;
|
||||
}
|
||||
|
||||
div.body p, div.body dd, div.body li {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
div.admonition {
|
||||
background: #fafafa;
|
||||
margin: 20px -30px;
|
||||
padding: 10px 30px;
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
div.admonition p.admonition-title {
|
||||
font-family: 'Garamond', 'Georgia', serif;
|
||||
font-weight: normal;
|
||||
font-size: 24px;
|
||||
margin: 0 0 10px 0;
|
||||
padding: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
div.admonition p.last {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.highlight{
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
dt:target, .highlight {
|
||||
background: #FAF3E8;
|
||||
}
|
||||
|
||||
div.note {
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
div.seealso {
|
||||
background-color: #ffc;
|
||||
border: 1px solid #ff6;
|
||||
}
|
||||
|
||||
div.topic {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
div.warning {
|
||||
background-color: #ffe4e4;
|
||||
border: 1px solid #f66;
|
||||
}
|
||||
|
||||
p.admonition-title {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
p.admonition-title:after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
pre, tt {
|
||||
font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
img.screenshot {
|
||||
}
|
||||
|
||||
tt.descname, tt.descclassname {
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
tt.descname {
|
||||
padding-right: 0.08em;
|
||||
}
|
||||
|
||||
img.screenshot {
|
||||
-moz-box-shadow: 2px 2px 4px #eee;
|
||||
-webkit-box-shadow: 2px 2px 4px #eee;
|
||||
box-shadow: 2px 2px 4px #eee;
|
||||
}
|
||||
|
||||
table.docutils {
|
||||
border: 1px solid #888;
|
||||
-moz-box-shadow: 2px 2px 4px #eee;
|
||||
-webkit-box-shadow: 2px 2px 4px #eee;
|
||||
box-shadow: 2px 2px 4px #eee;
|
||||
}
|
||||
|
||||
table.docutils td, table.docutils th {
|
||||
border: 1px solid #888;
|
||||
padding: 0.25em 0.7em;
|
||||
}
|
||||
|
||||
table.field-list, table.footnote {
|
||||
border: none;
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
table.footnote {
|
||||
margin: 15px 0;
|
||||
width: 100%;
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
|
||||
table.field-list th {
|
||||
padding: 0 0.8em 0 0;
|
||||
}
|
||||
|
||||
table.field-list td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table.footnote td {
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
dl dd {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 0;
|
||||
margin: 15px -30px;
|
||||
padding: 8px;
|
||||
line-height: 1.3em;
|
||||
padding: 7px 30px;
|
||||
background: #eee;
|
||||
border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
}
|
||||
|
||||
dl pre {
|
||||
margin-left: -60px;
|
||||
padding-left: 60px;
|
||||
}
|
||||
|
||||
tt {
|
||||
background-color: #ecf0f3;
|
||||
color: #222;
|
||||
/* padding: 1px 2px; */
|
||||
}
|
||||
|
||||
tt.xref, a tt {
|
||||
background-color: #FBFBFB;
|
||||
}
|
||||
|
||||
a:hover tt {
|
||||
background: #EEE;
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
[theme]
|
||||
inherit = basic
|
||||
stylesheet = flasky.css
|
||||
nosidebar = true
|
||||
pygments_style = flask_theme_support.FlaskyStyle
|
||||
|
||||
[options]
|
||||
index_logo = ''
|
||||
index_logo_height = 120px
|
||||
github_fork = ''
|
64
docs/api.rst
64
docs/api.rst
|
@ -1,64 +0,0 @@
|
|||
.. _api:
|
||||
|
||||
===
|
||||
API
|
||||
===
|
||||
|
||||
|
||||
.. module:: tablib
|
||||
|
||||
This part of the documentation covers all the interfaces of Tablib. For
|
||||
parts where Tablib depends on external libraries, we document the most
|
||||
important right here and provide links to the canonical documentation.
|
||||
|
||||
|
||||
--------------
|
||||
Dataset Object
|
||||
--------------
|
||||
|
||||
|
||||
.. autoclass:: Dataset
|
||||
:inherited-members:
|
||||
|
||||
|
||||
---------------
|
||||
Databook Object
|
||||
---------------
|
||||
|
||||
|
||||
.. autoclass:: Databook
|
||||
:inherited-members:
|
||||
|
||||
|
||||
|
||||
---------
|
||||
Functions
|
||||
---------
|
||||
|
||||
|
||||
.. autofunction:: detect
|
||||
|
||||
.. autofunction:: import_set
|
||||
|
||||
|
||||
----------
|
||||
Exceptions
|
||||
----------
|
||||
|
||||
|
||||
.. class:: InvalidDatasetType
|
||||
|
||||
You're trying to add something that doesn't quite look right.
|
||||
|
||||
|
||||
.. class:: InvalidDimensions
|
||||
|
||||
You're trying to add something that doesn't quite fit right.
|
||||
|
||||
|
||||
.. class:: UnsupportedFormat
|
||||
|
||||
You're trying to add something that doesn't quite taste right.
|
||||
|
||||
|
||||
Now, go start some :ref:`Tablib Development <development>`.
|
238
docs/conf.py
238
docs/conf.py
|
@ -1,238 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Tablib documentation build configuration file, created by
|
||||
# sphinx-quickstart on Tue Oct 5 15:25:21 2010.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
import tablib
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.viewcode']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Tablib'
|
||||
copyright = u'2011. A <a href="http://kennethreitz.com/pages/open-projects.html">Kenneth Reitz</a> Project'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = tablib.__version__
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = version
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'flask_theme_support.FlaskyStyle'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
html_sidebars = {
|
||||
'index': ['sidebarintro.html', 'sourcelink.html', 'searchbox.html'],
|
||||
'**': ['sidebarlogo.html', 'localtoc.html', 'relations.html',
|
||||
'sourcelink.html', 'searchbox.html']
|
||||
}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
html_show_sphinx = False
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Tablibdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'Tablib.tex', u'Tablib Documentation',
|
||||
u'Kenneth Reitz', 'manual'),
|
||||
]
|
||||
|
||||
latex_use_modindex = False
|
||||
|
||||
latex_elements = {
|
||||
'fontpkg': r'\usepackage{mathpazo}',
|
||||
'papersize': 'a4paper',
|
||||
'pointsize': '12pt',
|
||||
'preamble': r'\usepackage{krstyle}'
|
||||
}
|
||||
latex_use_parts = True
|
||||
|
||||
latex_additional_files = ['krstyle.sty']
|
||||
|
||||
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'tablib', u'Tablib Documentation',
|
||||
[u'Kenneth Reitz'], 1)
|
||||
]
|
||||
|
||||
sys.path.append(os.path.abspath('_themes'))
|
||||
html_theme_path = ['_themes']
|
||||
html_theme = 'kr'
|
|
@ -1,241 +0,0 @@
|
|||
.. _development:
|
||||
|
||||
Development
|
||||
===========
|
||||
|
||||
Tablib is under active development, and contributors are welcome.
|
||||
|
||||
If you have a feature request, suggestion, or bug report, please open a new
|
||||
issue on GitHub_. To submit patches, please send a pull request on GitHub_.
|
||||
|
||||
If you'd like to contribute, there's plenty to do. Here's a short todo list.
|
||||
|
||||
.. include:: ../TODO.rst
|
||||
|
||||
|
||||
.. _GitHub: http://github.com/kennethreitz/tablib/
|
||||
|
||||
|
||||
|
||||
.. _design:
|
||||
|
||||
---------------------
|
||||
Design Considerations
|
||||
---------------------
|
||||
|
||||
Tablib was developed with a few :pep:`20` idioms in mind.
|
||||
|
||||
#. Beautiful is better than ugly.
|
||||
#. Explicit is better than implicit.
|
||||
#. Simple is better than complex.
|
||||
#. Complex is better than complicated.
|
||||
#. Readability counts.
|
||||
|
||||
A few other things to keep in mind:
|
||||
|
||||
#. Keep your code DRY.
|
||||
#. Strive to be as simple (to use) as possible.
|
||||
|
||||
.. _scm:
|
||||
|
||||
--------------
|
||||
Source Control
|
||||
--------------
|
||||
|
||||
|
||||
Tablib source is controlled with Git_, the lean, mean, distributed source
|
||||
control machine.
|
||||
|
||||
The repository is publicly accessible.
|
||||
|
||||
``git clone git://github.com/kennethreitz/tablib.git``
|
||||
|
||||
The project is hosted on **GitHub**.
|
||||
|
||||
|
||||
GitHub:
|
||||
http://github.com/kennethreitz/tablib
|
||||
|
||||
|
||||
Git Branch Structure
|
||||
++++++++++++++++++++
|
||||
|
||||
Feature / Hotfix / Release branches follow a `Successful Git Branching Model`_ . Git-flow_ is a great tool for managing the repository. I highly recommend it.
|
||||
|
||||
``develop``
|
||||
The "next release" branch. Likely unstable.
|
||||
``master``
|
||||
Current production release (|version|) on PyPi.
|
||||
``gh-pages``
|
||||
Current release of http://docs.python-tablib.org.
|
||||
|
||||
Each release is tagged.
|
||||
|
||||
When submitting patches, please place your feature/change in its own branch prior to opening a pull request on GitHub_.
|
||||
|
||||
|
||||
.. _Git: http://git-scm.org
|
||||
.. _`Successful Git Branching Model`: http://nvie.com/posts/a-successful-git-branching-model/
|
||||
.. _git-flow: http://github.com/nvie/gitflow
|
||||
|
||||
|
||||
.. _newformats:
|
||||
|
||||
------------------
|
||||
Adding New Formats
|
||||
------------------
|
||||
|
||||
Tablib welcomes new format additions! Format suggestions include:
|
||||
|
||||
* Tab Separated Values
|
||||
* MySQL Dump
|
||||
* HTML Table
|
||||
|
||||
|
||||
Coding by Convention
|
||||
++++++++++++++++++++
|
||||
|
||||
Tablib features a micro-framework for adding format support. The easiest way to understand it is to use it. So, let's define our own format, named *xxx*.
|
||||
|
||||
1. Write a new format interface.
|
||||
|
||||
:class:`tablib.core` follows a simple pattern for automatically utilizing your format throughout Tablib. Function names are crucial.
|
||||
|
||||
Example **tablib/formats/_xxx.py**: ::
|
||||
|
||||
title = 'xxx'
|
||||
|
||||
def export_set(dset):
|
||||
....
|
||||
# returns string representation of given dataset
|
||||
|
||||
def export_book(dbook):
|
||||
....
|
||||
# returns string representation of given databook
|
||||
|
||||
def import_set(dset, in_stream):
|
||||
...
|
||||
# populates given Dataset with given datastream
|
||||
|
||||
def import_book(dbook, in_stream):
|
||||
...
|
||||
# returns Databook instance
|
||||
|
||||
def detect(stream):
|
||||
...
|
||||
# returns True if given stream is parsable as xxx
|
||||
|
||||
.. admonition:: Excluding Support
|
||||
|
||||
|
||||
If the format excludes support for an import/export mechanism (*eg.* :class:`csv <tablib.Dataset.csv>` excludes :class:`Databook <tablib.Databook>` support), simply don't define the respective functions. Appropriate errors will be raised.
|
||||
|
||||
2.
|
||||
|
||||
Add your new format module to the :class:`tablib.formats.available` tuple.
|
||||
|
||||
3.
|
||||
Add a mock property to the :class:`Dataset <tablib.Dataset>` class with verbose `reStructured Text`_ docstring. This alleviates IDE confusion, and allows for pretty auto-generated Sphinx_ documentation.
|
||||
|
||||
4. Write respective :ref:`tests <testing>`.
|
||||
|
||||
.. _testing:
|
||||
|
||||
--------------
|
||||
Testing Tablib
|
||||
--------------
|
||||
|
||||
Testing is crucial to Tablib's stability. This stable project is used in production by many companies and developers, so it is important to be certain that every version released is fully operational. When developing a new feature for Tablib, be sure to write proper tests for it as well.
|
||||
|
||||
When developing a feature for Tablib, the easiest way to test your changes for potential issues is to simply run the test suite directly. ::
|
||||
|
||||
$ ./test_tablib.py
|
||||
|
||||
|
||||
`Jenkins CI`_, amongst other tools, supports Java's xUnit testing report format. Nose_ allows us to generate our own xUnit reports.
|
||||
|
||||
Installing nose is simple. ::
|
||||
|
||||
$ pip install nose
|
||||
|
||||
Once installed, we can generate our xUnit report with a single command. ::
|
||||
|
||||
$ nosetests test_tablib.py --with-xunit
|
||||
|
||||
This will generate a **nosetests.xml** file, which can then be analyzed.
|
||||
|
||||
.. _Nose: http://somethingaboutorange.com/mrl/projects/nose/
|
||||
|
||||
|
||||
|
||||
.. _jenkins:
|
||||
|
||||
----------------------
|
||||
Continuous Integration
|
||||
----------------------
|
||||
|
||||
Every commit made to the **develop** branch is automatically tested and inspected upon receipt with `Travis CI`_. If you have access to the main repository and broke the build, you will receive an email accordingly.
|
||||
|
||||
Anyone may view the build status and history at any time.
|
||||
|
||||
https://travis-ci.org/kennethreitz/tablib
|
||||
|
||||
Additional reports will also be included here in the future, including :pep:`8` checks and stress reports for extremely large datasets.
|
||||
|
||||
.. _`Jenkins CI`: https://travis-ci.org/
|
||||
|
||||
|
||||
.. _docs:
|
||||
|
||||
-----------------
|
||||
Building the Docs
|
||||
-----------------
|
||||
|
||||
Documentation is written in the powerful, flexible, and standard Python documentation format, `reStructured Text`_.
|
||||
Documentation builds are powered by the powerful Pocoo project, Sphinx_. The :ref:`API Documentation <api>` is mostly documented inline throughout the module.
|
||||
|
||||
The Docs live in ``tablib/docs``. In order to build them, you will first need to install Sphinx. ::
|
||||
|
||||
$ pip install sphinx
|
||||
|
||||
|
||||
Then, to build an HTML version of the docs, simply run the following from the **docs** directory: ::
|
||||
|
||||
$ make html
|
||||
|
||||
Your ``docs/_build/html`` directory will then contain an HTML representation of the documentation, ready for publication on most web servers.
|
||||
|
||||
You can also generate the documentation in **epub**, **latex**, **json**, *&c* similarly.
|
||||
|
||||
.. admonition:: GitHub Pages
|
||||
|
||||
To push the documentation up to `GitHub Pages`_, you will first need to run `sphinx-to-github`_ against your ``docs/_build/html`` directory.
|
||||
|
||||
GitHub Pages are powered by an HTML generation system called Jekyll_, which is configured to ignore files and folders that begin with "``_``" (*ie.* **_static**).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
and `sphinx-to-github`_. ::
|
||||
|
||||
Installing sphinx-to-github is simple. ::
|
||||
|
||||
$ pip install sphinx-to-github
|
||||
|
||||
Running it against the docs is even simpler. ::
|
||||
|
||||
$ sphinx-to-github _build/html
|
||||
|
||||
Move the resulting files to the **gh-pages** branch of your repository, and push it up to GitHub.
|
||||
|
||||
.. _`reStructured Text`: http://docutils.sourceforge.net/rst.html
|
||||
.. _Sphinx: http://sphinx.pocoo.org
|
||||
.. _`GitHub Pages`: http://pages.github.com
|
||||
.. _Jekyll: http://github.com/mojombo/jekyll
|
||||
.. _`sphinx-to-github`: http://github.com/michaeljones/sphinx-to-github
|
||||
|
||||
----------
|
||||
|
||||
Make sure to check out the :ref:`API Documentation <api>`.
|
102
docs/index.rst
102
docs/index.rst
|
@ -1,102 +0,0 @@
|
|||
.. Tablib documentation master file, created by
|
||||
sphinx-quickstart on Tue Oct 5 15:25:21 2010.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Tablib: Pythonic Tabular Datasets
|
||||
=================================
|
||||
|
||||
Release v\ |version|. (:ref:`Installation <install>`)
|
||||
|
||||
.. Contents:
|
||||
..
|
||||
.. .. toctree::
|
||||
.. :maxdepth: 2
|
||||
..
|
||||
|
||||
.. Indices and tables
|
||||
.. ==================
|
||||
..
|
||||
.. * :ref:`genindex`
|
||||
.. * :ref:`modindex`
|
||||
.. * :ref:`search`
|
||||
|
||||
|
||||
Tablib is an :ref:`MIT Licensed <mit>` format-agnostic tabular dataset library, written in Python. It allows you to import, export, and manipulate tabular data sets. Advanced features include, segregation, dynamic columns, tags & filtering, and seamless format import & export.
|
||||
|
||||
::
|
||||
|
||||
>>> data = tablib.Dataset(headers=['First Name', 'Last Name', 'Age'])
|
||||
>>> data.extend([('Kenneth', 'Reitz', 23), ('Bessie', 'Monke', 22)])
|
||||
|
||||
>>> data.json
|
||||
[{"Last Name": "Reitz", "First Name": "Kenneth", "Age": 22}, {"Last Name": "Monke", "First Name": "Bessie", "Age": 21}]
|
||||
|
||||
>>> data.yaml
|
||||
- {Age: 22, First Name: Kenneth, Last Name: Reitz}
|
||||
- {Age: 21, First Name: Bessie, Last Name: Monke}
|
||||
|
||||
>>> data.xlsx
|
||||
<censored binary data>
|
||||
|
||||
|
||||
Testimonials
|
||||
------------
|
||||
|
||||
`National Geographic <http://www.nationalgeographic.com/>`_,
|
||||
`Digg, Inc <http://digg.com/>`_,
|
||||
`Northrop Grumman <http://www.northropgrumman.com/>`_,
|
||||
`Discovery Channel <http://dsc.discovery.com/>`_,
|
||||
and `The Sunlight Foundation <http://sunlightfoundation.com/>`_ use Tablib internally.
|
||||
|
||||
|
||||
|
||||
**Greg Thorton**
|
||||
Tablib by @kennethreitz saved my life. I had to consolidate like 5 huge poorly maintained lists of domains and data. It was a breeze!
|
||||
|
||||
**Dave Coutts**
|
||||
It's turning into one of my most used modules of 2010. You really hit a sweet spot for managing tabular data with a minimal amount of code and effort.
|
||||
|
||||
**Joshua Ourisman**
|
||||
Tablib has made it so much easier to deal with the inevitable 'I want an Excel file!' requests from clients...
|
||||
|
||||
**Brad Montgomery**
|
||||
I think you nailed the "Python Zen" with tablib. Thanks again for an awesome lib!
|
||||
|
||||
|
||||
User's Guide
|
||||
------------
|
||||
|
||||
This part of the documentation, which is mostly prose, begins with some background information about Tablib, then focuses on step-by-step instructions for getting the most out of your datasets.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
intro
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
install
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
tutorial
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
development
|
||||
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
If you are looking for information on a specific function, class or
|
||||
method, this part of the documentation is for you.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
api
|
|
@ -1,92 +0,0 @@
|
|||
.. _install:
|
||||
Installation
|
||||
============
|
||||
|
||||
This part of the documentation covers the installation of Tablib. The first step to using any software package is getting it properly installed. Please read this section carefully, or you may miss out on some nice :ref:`speed enhancements <peed-extensions>`.
|
||||
|
||||
|
||||
.. _installing:
|
||||
|
||||
-----------------
|
||||
Installing Tablib
|
||||
-----------------
|
||||
|
||||
Distribute & Pip
|
||||
----------------
|
||||
|
||||
Installing Tablib is simple with `pip <http://www.pip-installer.org/>`_::
|
||||
|
||||
$ pip install tablib
|
||||
|
||||
or, with `easy_install <http://pypi.python.org/pypi/setuptools>`_::
|
||||
|
||||
$ easy_install tablib
|
||||
|
||||
But, you really `shouldn't do that <http://www.pip-installer.org/en/latest/other-tools.html#pip-compared-to-easy-install>`_.
|
||||
|
||||
|
||||
|
||||
Cheeseshop Mirror
|
||||
-----------------
|
||||
|
||||
If the Cheeseshop is down, you can also install Requests from Kenneth Reitz's personal `Cheeseshop mirror <pip.kreitz.co/>`_::
|
||||
|
||||
$ pip install -i http://pip.kreitz.co/simple tablib
|
||||
|
||||
|
||||
|
||||
|
||||
-------------------
|
||||
Download the Source
|
||||
-------------------
|
||||
|
||||
You can also install tablib from source. The latest release (|version|) is available from GitHub.
|
||||
|
||||
* tarball_
|
||||
* zipball_
|
||||
|
||||
.. _
|
||||
Once you have a copy of the source, you can embed it in your Python package, or install it into your site-packages easily. ::
|
||||
|
||||
$ python setup.py install
|
||||
|
||||
|
||||
To download the full source history from Git, see :ref:`Source Control <scm>`.
|
||||
|
||||
.. _tarball: http://github.com/kennethreitz/tablib/tarball/master
|
||||
.. _zipball: http://github.com/kennethreitz/tablib/zipball/master
|
||||
|
||||
|
||||
.. _speed-extensions:
|
||||
Speed Extensions
|
||||
----------------
|
||||
|
||||
.. versionadded:: 0.8.5
|
||||
|
||||
Tablib is partially dependent on the **pyyaml**, **simplejson**, and **xlwt** modules. To reduce installation issues, fully integrated versions of all required libraries are included in Tablib.
|
||||
|
||||
However, if performance is important to you (and it should be), you can install **pyyaml** with C extensions from PyPi. ::
|
||||
|
||||
$ pip install PyYAML
|
||||
|
||||
If you're using Python 2.5, you should also install the **simplejson** module (pip will do this for you). If you're using Python 2.6+, the built-in **json** module is already optimized and in use. ::
|
||||
|
||||
$ pip install simplejson
|
||||
|
||||
|
||||
|
||||
.. _updates:
|
||||
Staying Updated
|
||||
---------------
|
||||
|
||||
The latest version of Tablib will always be available here:
|
||||
|
||||
* PyPi: http://pypi.python.org/pypi/tablib/
|
||||
* GitHub: http://github.com/kennethreitz/tablib/
|
||||
|
||||
When a new version is available, upgrading is simple::
|
||||
|
||||
$ pip install tablib --upgrade
|
||||
|
||||
|
||||
Now, go get a :ref:`Quick Start <quickstart>`.
|
|
@ -1,93 +0,0 @@
|
|||
.. _intro:
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This part of the documentation covers all the interfaces of Tablib.
|
||||
Tablib is a format-agnostic tabular dataset library, written in Python.
|
||||
It allows you to Pythonically import, export, and manipulate tabular data sets.
|
||||
Advanced features include, segregation, dynamic columns, tags / filtering, and
|
||||
seamless format import/export.
|
||||
|
||||
|
||||
Philosphy
|
||||
---------
|
||||
|
||||
Tablib was developed with a few :pep:`20` idioms in mind.
|
||||
|
||||
|
||||
#. Beautiful is better than ugly.
|
||||
#. Explicit is better than implicit.
|
||||
#. Simple is better than complex.
|
||||
#. Complex is better than complicated.
|
||||
#. Readability counts.
|
||||
|
||||
All contributions to Tablib should keep these important rules in mind.
|
||||
|
||||
.. mit:
|
||||
|
||||
MIT License
|
||||
-----------
|
||||
|
||||
A large number of open source projects you find today are `GPL Licensed`_.
|
||||
While the GPL has its time and place, it should most certainly not be your
|
||||
go-to license for your next open source project.
|
||||
|
||||
A project that is released as GPL cannot be used in any commercial product
|
||||
without the product itself also being offered as open source. The MIT, BSD, and
|
||||
ISC licenses are great alternatives to the GPL that allow your open-source
|
||||
software to be used in proprietary, closed-source software.
|
||||
|
||||
Tablib is released under terms of `The MIT License`_.
|
||||
|
||||
.. _`GPL Licensed`: http://www.opensource.org/licenses/gpl-license.php
|
||||
.. _`The MIT License`: http://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
|
||||
.. _license:
|
||||
|
||||
Tablib License
|
||||
--------------
|
||||
|
||||
Copyright 2011 Kenneth Reitz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
.. _pythonsupport:
|
||||
|
||||
Pythons Supported
|
||||
-----------------
|
||||
|
||||
At this time, the following Python platforms are officially supported:
|
||||
|
||||
* cPython 2.5
|
||||
* cPython 2.6
|
||||
* cPython 2.7
|
||||
* cPython 3.1
|
||||
* cPython 3.2
|
||||
* PyPy-c 1.4
|
||||
* PyPy-c 1.5
|
||||
|
||||
Support for other Pythons will be rolled out soon.
|
||||
|
||||
|
||||
|
||||
|
||||
Now, go :ref:`Install Tablib <install>`.
|
118
docs/krstyle.sty
118
docs/krstyle.sty
|
@ -1,118 +0,0 @@
|
|||
\definecolor{TitleColor}{rgb}{0,0,0}
|
||||
\definecolor{InnerLinkColor}{rgb}{0,0,0}
|
||||
|
||||
\renewcommand{\maketitle}{%
|
||||
\begin{titlepage}%
|
||||
\let\footnotesize\small
|
||||
\let\footnoterule\relax
|
||||
\ifsphinxpdfoutput
|
||||
\begingroup
|
||||
% This \def is required to deal with multi-line authors; it
|
||||
% changes \\ to ', ' (comma-space), making it pass muster for
|
||||
% generating document info in the PDF file.
|
||||
\def\\{, }
|
||||
\pdfinfo{
|
||||
/Author (\@author)
|
||||
/Title (\@title)
|
||||
}
|
||||
\endgroup
|
||||
\fi
|
||||
\begin{flushright}%
|
||||
%\sphinxlogo%
|
||||
{\center
|
||||
\vspace*{3cm}
|
||||
\includegraphics{logo.pdf}
|
||||
\vspace{3cm}
|
||||
\par
|
||||
{\rm\Huge \@title \par}%
|
||||
{\em\LARGE \py@release\releaseinfo \par}
|
||||
{\large
|
||||
\@date \par
|
||||
\py@authoraddress \par
|
||||
}}%
|
||||
\end{flushright}%\par
|
||||
\@thanks
|
||||
\end{titlepage}%
|
||||
\cleardoublepage%
|
||||
\setcounter{footnote}{0}%
|
||||
\let\thanks\relax\let\maketitle\relax
|
||||
%\gdef\@thanks{}\gdef\@author{}\gdef\@title{}
|
||||
}
|
||||
|
||||
\fancypagestyle{normal}{
|
||||
\fancyhf{}
|
||||
\fancyfoot[LE,RO]{{\thepage}}
|
||||
\fancyfoot[LO]{{\nouppercase{\rightmark}}}
|
||||
\fancyfoot[RE]{{\nouppercase{\leftmark}}}
|
||||
\fancyhead[LE,RO]{{ \@title, \py@release}}
|
||||
\renewcommand{\headrulewidth}{0.4pt}
|
||||
\renewcommand{\footrulewidth}{0.4pt}
|
||||
}
|
||||
|
||||
\fancypagestyle{plain}{
|
||||
\fancyhf{}
|
||||
\fancyfoot[LE,RO]{{\thepage}}
|
||||
\renewcommand{\headrulewidth}{0pt}
|
||||
\renewcommand{\footrulewidth}{0.4pt}
|
||||
}
|
||||
|
||||
\titleformat{\section}{\Large}%
|
||||
{\py@TitleColor\thesection}{0.5em}{\py@TitleColor}{\py@NormalColor}
|
||||
\titleformat{\subsection}{\large}%
|
||||
{\py@TitleColor\thesubsection}{0.5em}{\py@TitleColor}{\py@NormalColor}
|
||||
\titleformat{\subsubsection}{}%
|
||||
{\py@TitleColor\thesubsubsection}{0.5em}{\py@TitleColor}{\py@NormalColor}
|
||||
\titleformat{\paragraph}{\large}%
|
||||
{\py@TitleColor}{0em}{\py@TitleColor}{\py@NormalColor}
|
||||
|
||||
\ChNameVar{\raggedleft\normalsize}
|
||||
\ChNumVar{\raggedleft \bfseries\Large}
|
||||
\ChTitleVar{\raggedleft \rm\Huge}
|
||||
|
||||
\renewcommand\thepart{\@Roman\c@part}
|
||||
\renewcommand\part{%
|
||||
\pagestyle{empty}
|
||||
\if@noskipsec \leavevmode \fi
|
||||
\cleardoublepage
|
||||
\vspace*{6cm}%
|
||||
\@afterindentfalse
|
||||
\secdef\@part\@spart}
|
||||
|
||||
\def\@part[#1]#2{%
|
||||
\ifnum \c@secnumdepth >\m@ne
|
||||
\refstepcounter{part}%
|
||||
\addcontentsline{toc}{part}{\thepart\hspace{1em}#1}%
|
||||
\else
|
||||
\addcontentsline{toc}{part}{#1}%
|
||||
\fi
|
||||
{\parindent \z@ %\center
|
||||
\interlinepenalty \@M
|
||||
\normalfont
|
||||
\ifnum \c@secnumdepth >\m@ne
|
||||
\rm\Large \partname~\thepart
|
||||
\par\nobreak
|
||||
\fi
|
||||
\MakeUppercase{\rm\Huge #2}%
|
||||
\markboth{}{}\par}%
|
||||
\nobreak
|
||||
\vskip 8ex
|
||||
\@afterheading}
|
||||
\def\@spart#1{%
|
||||
{\parindent \z@ %\center
|
||||
\interlinepenalty \@M
|
||||
\normalfont
|
||||
\huge \bfseries #1\par}%
|
||||
\nobreak
|
||||
\vskip 3ex
|
||||
\@afterheading}
|
||||
|
||||
% use inconsolata font
|
||||
\usepackage{inconsolata}
|
||||
|
||||
% fix single quotes, for inconsolata. (does not work)
|
||||
%%\usepackage{textcomp}
|
||||
%%\begingroup
|
||||
%% \catcode`'=\active
|
||||
%% \g@addto@macro\@noligs{\let'\textsinglequote}
|
||||
%% \endgroup
|
||||
%%\endinput
|
|
@ -1,360 +0,0 @@
|
|||
.. _quickstart:
|
||||
|
||||
==========
|
||||
Quickstart
|
||||
==========
|
||||
|
||||
|
||||
.. module:: tablib
|
||||
|
||||
|
||||
Eager to get started? This page gives a good introduction in how to get started with Tablib. This assumes you already have Tablib installed. If you do not, head over to the :ref:`Installation <install>` section.
|
||||
|
||||
First, make sure that:
|
||||
|
||||
* Tablib is :ref:`installed <install>`
|
||||
* Tablib is :ref:`up-to-date <updates>`
|
||||
|
||||
|
||||
Lets gets started with some simple use cases and examples.
|
||||
|
||||
|
||||
|
||||
------------------
|
||||
Creating a Dataset
|
||||
------------------
|
||||
|
||||
|
||||
A :class:`Dataset <tablib.Dataset>` is nothing more than what its name implies—a set of data.
|
||||
|
||||
Creating your own instance of the :class:`tablib.Dataset` object is simple. ::
|
||||
|
||||
data = tablib.Dataset()
|
||||
|
||||
You can now start filling this :class:`Dataset <tablib.Dataset>` object with data.
|
||||
|
||||
.. admonition:: Example Context
|
||||
|
||||
From here on out, if you see ``data``, assume that it's a fresh :class:`Dataset <tablib.Dataset>` object.
|
||||
|
||||
|
||||
|
||||
-----------
|
||||
Adding Rows
|
||||
-----------
|
||||
|
||||
|
||||
Let's say you want to collect a simple list of names. ::
|
||||
|
||||
# collection of names
|
||||
names = ['Kenneth Reitz', 'Bessie Monke']
|
||||
|
||||
for name in names:
|
||||
# split name appropriately
|
||||
fname, lname = name.split()
|
||||
|
||||
# add names to Dataset
|
||||
data.append([fname, lname])
|
||||
|
||||
You can get a nice, Pythonic view of the dataset at any time with :class:`Dataset.dict`.
|
||||
|
||||
>>> data.dict
|
||||
[('Kenneth', 'Reitz'), ('Bessie', 'Monke')]
|
||||
|
||||
|
||||
|
||||
--------------
|
||||
Adding Headers
|
||||
--------------
|
||||
|
||||
|
||||
It's time to enhance our :class:`Dataset` by giving our columns some titles. To do so, set :class:`Dataset.headers`. ::
|
||||
|
||||
data.headers = ['First Name', 'Last Name']
|
||||
|
||||
Now our data looks a little different. ::
|
||||
|
||||
>>> data.dict
|
||||
[{'Last Name': 'Reitz', 'First Name': 'Kenneth'}, {'Last Name': 'Monke', 'First Name': 'Bessie'}]
|
||||
|
||||
|
||||
|
||||
|
||||
--------------
|
||||
Adding Columns
|
||||
--------------
|
||||
|
||||
|
||||
Now that we have a basic :class:`Dataset` in place, let's add a column of **ages** to it. ::
|
||||
|
||||
data.append_col([22, 20], header='Age')
|
||||
|
||||
Let's view the data now. ::
|
||||
|
||||
>>> data.dict
|
||||
[{'Last Name': 'Reitz', 'First Name': 'Kenneth', 'Age': 22}, {'Last Name': 'Monke', 'First Name': 'Bessie', 'Age': 20}]
|
||||
|
||||
It's that easy.
|
||||
|
||||
|
||||
--------------
|
||||
Exporting Data
|
||||
--------------
|
||||
|
||||
Tablib's killer feature is the ability to export your :class:`Dataset` objects into a number of formats.
|
||||
|
||||
**Comma-Separated Values** ::
|
||||
|
||||
>>> data.csv
|
||||
Last Name,First Name,Age
|
||||
Reitz,Kenneth,22
|
||||
Monke,Bessie,20
|
||||
|
||||
**JavaScript Object Notation** ::
|
||||
|
||||
>>> data.json
|
||||
[{"Last Name": "Reitz", "First Name": "Kenneth", "Age": 22}, {"Last Name": "Monke", "First Name": "Bessie", "Age": 20}]
|
||||
|
||||
|
||||
**YAML Ain't Markup Language** ::
|
||||
|
||||
>>> data.yaml
|
||||
- {Age: 22, First Name: Kenneth, Last Name: Reitz}
|
||||
- {Age: 20, First Name: Bessie, Last Name: Monke}
|
||||
|
||||
|
||||
**Microsoft Excel** ::
|
||||
|
||||
>>> data.xls
|
||||
<censored binary data>
|
||||
|
||||
|
||||
------------------------
|
||||
Selecting Rows & Columns
|
||||
------------------------
|
||||
|
||||
|
||||
You can slice and dice your data, just like a standard Python list. ::
|
||||
|
||||
>>> data[0]
|
||||
('Kenneth', 'Reitz', 22)
|
||||
|
||||
|
||||
If we had a set of data consisting of thousands of rows, it could be useful to get a list of values in a column.
|
||||
To do so, we access the :class:`Dataset` as if it were a standard Python dictionary. ::
|
||||
|
||||
>>> data['First Name']
|
||||
['Kenneth', 'Bessie']
|
||||
|
||||
You can also access the column using its index. ::
|
||||
|
||||
>>> d.headers
|
||||
['Last Name', 'First Name', 'Age']
|
||||
>>> d.get_col(1)
|
||||
['Kenneth', 'Bessie']
|
||||
|
||||
Let's find the average age. ::
|
||||
|
||||
>>> ages = data['Age']
|
||||
>>> float(sum(ages)) / len(ages)
|
||||
21.0
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
Removing Rows & Columns
|
||||
-----------------------
|
||||
|
||||
It's easier than you could imagine::
|
||||
|
||||
>>> del data['Col Name']
|
||||
|
||||
::
|
||||
|
||||
>>> del data[0:12]
|
||||
|
||||
|
||||
==============
|
||||
Advanced Usage
|
||||
==============
|
||||
|
||||
|
||||
This part of the documentation services to give you an idea that are otherwise hard to extract from the :ref:`API Documentation <api>`
|
||||
|
||||
And now for something completely different.
|
||||
|
||||
|
||||
.. _dyncols:
|
||||
|
||||
---------------
|
||||
Dynamic Columns
|
||||
---------------
|
||||
|
||||
.. versionadded:: 0.8.3
|
||||
|
||||
Thanks to Josh Ourisman, Tablib now supports adding dynamic columns. A dynamic column is a single callable object (*ie.* a function).
|
||||
|
||||
Let's add a dynamic column to our :class:`Dataset` object. In this example, we have a function that generates a random grade for our students. ::
|
||||
|
||||
import random
|
||||
|
||||
def random_grade(row):
|
||||
"""Returns a random integer for entry."""
|
||||
return (random.randint(60,100)/100.0)
|
||||
|
||||
data.append_col(random_grade, header='Grade')
|
||||
|
||||
Let's have a look at our data. ::
|
||||
|
||||
>>> data.yaml
|
||||
- {Age: 22, First Name: Kenneth, Grade: 0.6, Last Name: Reitz}
|
||||
- {Age: 20, First Name: Bessie, Grade: 0.75, Last Name: Monke}
|
||||
|
||||
|
||||
Let's remove that column. ::
|
||||
|
||||
>>> del data['Grade']
|
||||
|
||||
|
||||
When you add a dynamic column, the first argument that is passed in to the given callable is the current data row. You can use this to perform calculations against your data row.
|
||||
|
||||
For example, we can use the data available in the row to guess the gender of a student. ::
|
||||
|
||||
def guess_gender(row):
|
||||
"""Calculates gender of given student data row."""
|
||||
m_names = ('Kenneth', 'Mike', 'Yuri')
|
||||
f_names = ('Bessie', 'Samantha', 'Heather')
|
||||
|
||||
name = row[0]
|
||||
|
||||
if name in m_names:
|
||||
return 'Male'
|
||||
elif name in f_names:
|
||||
return 'Female'
|
||||
else:
|
||||
return 'Unknown'
|
||||
|
||||
Adding this function to our dataset as a dynamic column would result in: ::
|
||||
|
||||
>>> data.yaml
|
||||
- {Age: 22, First Name: Kenneth, Gender: Male, Last Name: Reitz}
|
||||
- {Age: 20, First Name: Bessie, Gender: Female, Last Name: Monke}
|
||||
|
||||
|
||||
.. _tags:
|
||||
|
||||
----------------------------
|
||||
Filtering Datasets with Tags
|
||||
----------------------------
|
||||
|
||||
.. versionadded:: 0.9.0
|
||||
|
||||
|
||||
When constructing a :class:`Dataset` object, you can add tags to rows by specifying the ``tags`` parameter.
|
||||
This allows you to filter your :class:`Dataset` later. This can be useful to separate rows of data based on
|
||||
arbitrary criteria (*e.g.* origin) that you don't want to include in your :class:`Dataset`.
|
||||
|
||||
Let's tag some students. ::
|
||||
|
||||
students = tablib.Dataset()
|
||||
|
||||
students.headers = ['first', 'last']
|
||||
|
||||
students.rpush(['Kenneth', 'Reitz'], tags=['male', 'technical'])
|
||||
students.rpush(['Bessie', 'Monke'], tags=['female', 'creative'])
|
||||
|
||||
Now that we have extra meta-data on our rows, we can easily filter our :class:`Dataset`. Let's just see Male students. ::
|
||||
|
||||
|
||||
>>> students.filter(['male']).yaml
|
||||
- {first: Kenneth, Last: Reitz}
|
||||
|
||||
It's that simple. The original :class:`Dataset` is untouched.
|
||||
|
||||
|
||||
Excel Workbook With Multiple Sheets
|
||||
------------------------------------
|
||||
|
||||
When dealing with a large number of :class:`Datasets <Dataset>` in spreadsheet format, it's quite common to group multiple spreadsheets into a single Excel file, known as a Workbook. Tablib makes it extremely easy to build workbooks with the handy, :class:`Databook` class.
|
||||
|
||||
|
||||
Let's say we have 3 different :class:`Datasets <Dataset>`. All we have to do is add then to a :class:`Databook` object... ::
|
||||
|
||||
book = tablib.Databook((data1, data2, data3))
|
||||
|
||||
... and export to Excel just like :class:`Datasets <Dataset>`. ::
|
||||
|
||||
with open('students.xls', 'wb') as f:
|
||||
f.write(book.xls)
|
||||
|
||||
The resulting **students.xls** file will contain a separate spreadsheet for each :class:`Dataset` object in the :class:`Databook`.
|
||||
|
||||
.. admonition:: Binary Warning
|
||||
|
||||
Make sure to open the output file in binary mode.
|
||||
|
||||
|
||||
.. _separators:
|
||||
|
||||
----------
|
||||
Separators
|
||||
----------
|
||||
|
||||
.. versionadded:: 0.8.2
|
||||
|
||||
When, it's often useful to create a blank row containing information on the upcoming data. So,
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
daniel_tests = [
|
||||
('11/24/09', 'Math 101 Mid-term Exam', 56.),
|
||||
('05/24/10', 'Math 101 Final Exam', 62.)
|
||||
]
|
||||
|
||||
suzie_tests = [
|
||||
('11/24/09', 'Math 101 Mid-term Exam', 56.),
|
||||
('05/24/10', 'Math 101 Final Exam', 62.)
|
||||
]
|
||||
|
||||
# Create new dataset
|
||||
tests = tablib.Dataset()
|
||||
tests.headers = ['Date', 'Test Name', 'Grade']
|
||||
|
||||
# Daniel's Tests
|
||||
tests.append_separator('Daniel\'s Scores')
|
||||
|
||||
for test_row in daniel_tests:
|
||||
tests.append(test_row)
|
||||
|
||||
# Susie's Tests
|
||||
tests.append_separator('Susie\'s Scores')
|
||||
|
||||
for test_row in suzie_tests:
|
||||
tests.append(test_row)
|
||||
|
||||
# Write spreadsheet to disk
|
||||
with open('grades.xls', 'wb') as f:
|
||||
f.write(tests.xls)
|
||||
|
||||
The resulting **tests.xls** will have the following layout:
|
||||
|
||||
|
||||
Daniel's Scores:
|
||||
* '11/24/09', 'Math 101 Mid-term Exam', 56.
|
||||
* '05/24/10', 'Math 101 Final Exam', 62.
|
||||
|
||||
Suzie's Scores:
|
||||
* '11/24/09', 'Math 101 Mid-term Exam', 56.
|
||||
* '05/24/10', 'Math 101 Final Exam', 62.
|
||||
|
||||
|
||||
|
||||
.. admonition:: Format Support
|
||||
|
||||
At this time, only :class:`Excel <Dataset.xls>` output supports separators.
|
||||
|
||||
----
|
||||
|
||||
Now, go check out the :ref:`API Documentation <api>` or begin :ref:`Tablib Development <development>`.
|
84
setup.py
84
setup.py
|
@ -1,84 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import tablib
|
||||
|
||||
try:
|
||||
from setuptools import setup
|
||||
except ImportError:
|
||||
from distutils.core import setup
|
||||
|
||||
|
||||
if sys.argv[-1] == 'publish':
|
||||
os.system("python setup.py sdist upload")
|
||||
sys.exit()
|
||||
|
||||
if sys.argv[-1] == 'speedups':
|
||||
try:
|
||||
__import__('pip')
|
||||
except ImportError:
|
||||
print('Pip required.')
|
||||
sys.exit(1)
|
||||
|
||||
os.system('pip install ujson pyyaml')
|
||||
sys.exit()
|
||||
|
||||
if sys.argv[-1] == 'test':
|
||||
try:
|
||||
__import__('py')
|
||||
except ImportError:
|
||||
print('py.test required.')
|
||||
sys.exit(1)
|
||||
|
||||
os.system('py.test test_tablib.py')
|
||||
sys.exit()
|
||||
|
||||
setup(
|
||||
name='tablib',
|
||||
version=tablib.__version__,
|
||||
description='Format agnostic tabular data library (XLS, JSON, YAML, CSV)',
|
||||
long_description=(open('README.rst').read() + '\n\n' +
|
||||
open('HISTORY.rst').read()),
|
||||
author='Kenneth Reitz',
|
||||
author_email='me@kennethreitz.com',
|
||||
url='http://python-tablib.org',
|
||||
packages=[
|
||||
'tablib', 'tablib.formats',
|
||||
'tablib.packages',
|
||||
'tablib.packages.xlwt',
|
||||
'tablib.packages.xlwt3',
|
||||
'tablib.packages.xlrd',
|
||||
'tablib.packages.xlrd3',
|
||||
'tablib.packages.omnijson',
|
||||
'tablib.packages.odf',
|
||||
'tablib.packages.odf3',
|
||||
'tablib.packages.openpyxl',
|
||||
'tablib.packages.openpyxl.shared',
|
||||
'tablib.packages.openpyxl.reader',
|
||||
'tablib.packages.openpyxl.writer',
|
||||
'tablib.packages.openpyxl3',
|
||||
'tablib.packages.openpyxl3.shared',
|
||||
'tablib.packages.openpyxl3.reader',
|
||||
'tablib.packages.openpyxl3.writer',
|
||||
'tablib.packages.yaml',
|
||||
'tablib.packages.unicodecsv'
|
||||
],
|
||||
license='MIT',
|
||||
classifiers=(
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
'Natural Language :: English',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2.5',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3.0',
|
||||
'Programming Language :: Python :: 3.1',
|
||||
'Programming Language :: Python :: 3.2',
|
||||
),
|
||||
tests_require=['pytest'],
|
||||
)
|
|
@ -1,8 +0,0 @@
|
|||
""" Tablib. """
|
||||
|
||||
from tablib.core import (
|
||||
Databook, Dataset, detect, import_set, import_book,
|
||||
InvalidDatasetType, InvalidDimensions, UnsupportedFormat,
|
||||
__version__
|
||||
)
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
tablib.compat
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Tablib compatiblity module.
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
is_py3 = (sys.version_info[0] > 2)
|
||||
|
||||
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
from tablib.packages.ordereddict import OrderedDict
|
||||
|
||||
|
||||
if is_py3:
|
||||
from io import BytesIO
|
||||
import tablib.packages.xlwt3 as xlwt
|
||||
import tablib.packages.xlrd3 as xlrd
|
||||
from tablib.packages.xlrd3.biffh import XLRDError
|
||||
from tablib.packages import markup3 as markup
|
||||
from tablib.packages import openpyxl3 as openpyxl
|
||||
from tablib.packages.odf3 import opendocument, style, text, table
|
||||
|
||||
import csv
|
||||
from io import StringIO
|
||||
# py3 mappings
|
||||
|
||||
unicode = str
|
||||
bytes = bytes
|
||||
basestring = str
|
||||
|
||||
else:
|
||||
from cStringIO import StringIO as BytesIO
|
||||
from cStringIO import StringIO
|
||||
import tablib.packages.xlwt as xlwt
|
||||
import tablib.packages.xlrd as xlrd
|
||||
from tablib.packages.xlrd.biffh import XLRDError
|
||||
from tablib.packages import markup
|
||||
from itertools import ifilter
|
||||
from tablib.packages import openpyxl
|
||||
from tablib.packages.odf import opendocument, style, text, table
|
||||
|
||||
from tablib.packages import unicodecsv as csv
|
||||
|
||||
unicode = unicode
|
1043
tablib/core.py
1043
tablib/core.py
File diff suppressed because it is too large
Load Diff
|
@ -1,15 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Tablib - formats
|
||||
"""
|
||||
|
||||
from . import _csv as csv
|
||||
from . import _json as json
|
||||
from . import _xls as xls
|
||||
from . import _yaml as yaml
|
||||
from . import _tsv as tsv
|
||||
from . import _html as html
|
||||
from . import _xlsx as xlsx
|
||||
from . import _ods as ods
|
||||
|
||||
available = (json, xls, yaml, csv, tsv, html, xlsx, ods)
|
|
@ -1,55 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Tablib - CSV Support.
|
||||
"""
|
||||
|
||||
from tablib.compat import is_py3, csv, StringIO
|
||||
|
||||
|
||||
title = 'csv'
|
||||
extensions = ('csv',)
|
||||
|
||||
|
||||
DEFAULT_ENCODING = 'utf-8'
|
||||
|
||||
|
||||
|
||||
def export_set(dataset):
|
||||
"""Returns CSV representation of Dataset."""
|
||||
stream = StringIO()
|
||||
|
||||
if is_py3:
|
||||
_csv = csv.writer(stream)
|
||||
else:
|
||||
_csv = csv.writer(stream, encoding=DEFAULT_ENCODING)
|
||||
|
||||
for row in dataset._package(dicts=False):
|
||||
_csv.writerow(row)
|
||||
|
||||
return stream.getvalue()
|
||||
|
||||
|
||||
def import_set(dset, in_stream, headers=True):
|
||||
"""Returns dataset from CSV stream."""
|
||||
|
||||
dset.wipe()
|
||||
|
||||
if is_py3:
|
||||
rows = csv.reader(in_stream.splitlines())
|
||||
else:
|
||||
rows = csv.reader(in_stream.splitlines(), encoding=DEFAULT_ENCODING)
|
||||
for i, row in enumerate(rows):
|
||||
|
||||
if (i == 0) and (headers):
|
||||
dset.headers = row
|
||||
else:
|
||||
dset.append(row)
|
||||
|
||||
|
||||
def detect(stream):
|
||||
"""Returns True if given stream is valid CSV."""
|
||||
try:
|
||||
csv.Sniffer().sniff(stream, delimiters=',')
|
||||
return True
|
||||
except (csv.Error, TypeError):
|
||||
return False
|
|
@ -1,67 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Tablib - HTML export support.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
if sys.version_info[0] > 2:
|
||||
from io import StringIO
|
||||
from tablib.packages import markup3 as markup
|
||||
else:
|
||||
from cStringIO import StringIO
|
||||
from tablib.packages import markup
|
||||
|
||||
import tablib
|
||||
import codecs
|
||||
|
||||
BOOK_ENDINGS = 'h3'
|
||||
|
||||
title = 'html'
|
||||
extensions = ('html', )
|
||||
|
||||
|
||||
def export_set(dataset):
|
||||
"""HTML representation of a Dataset."""
|
||||
|
||||
stream = StringIO()
|
||||
|
||||
page = markup.page()
|
||||
page.table.open()
|
||||
|
||||
if dataset.headers is not None:
|
||||
new_header = [item if item is not None else '' for item in dataset.headers]
|
||||
|
||||
page.thead.open()
|
||||
headers = markup.oneliner.th(new_header)
|
||||
page.tr(headers)
|
||||
page.thead.close()
|
||||
|
||||
for row in dataset:
|
||||
new_row = [item if item is not None else '' for item in row]
|
||||
|
||||
html_row = markup.oneliner.td(new_row)
|
||||
page.tr(html_row)
|
||||
|
||||
page.table.close()
|
||||
|
||||
# Allow unicode characters in output
|
||||
wrapper = codecs.getwriter("utf8")(stream)
|
||||
wrapper.writelines(unicode(page))
|
||||
|
||||
return stream.getvalue()
|
||||
|
||||
|
||||
def export_book(databook):
|
||||
"""HTML representation of a Databook."""
|
||||
|
||||
stream = StringIO()
|
||||
|
||||
for i, dset in enumerate(databook._datasets):
|
||||
title = (dset.title if dset.title else 'Set %s' % (i))
|
||||
stream.write('<%s>%s</%s>\n' % (BOOK_ENDINGS, title, BOOK_ENDINGS))
|
||||
stream.write(dset.html)
|
||||
stream.write('\n')
|
||||
|
||||
return stream.getvalue()
|
|
@ -1,50 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Tablib - JSON Support
|
||||
"""
|
||||
|
||||
import tablib
|
||||
|
||||
import sys
|
||||
from tablib.packages import omnijson as json
|
||||
|
||||
|
||||
title = 'json'
|
||||
extensions = ('json', 'jsn')
|
||||
|
||||
|
||||
def export_set(dataset):
|
||||
"""Returns JSON representation of Dataset."""
|
||||
return json.dumps(dataset.dict)
|
||||
|
||||
|
||||
def export_book(databook):
|
||||
"""Returns JSON representation of Databook."""
|
||||
return json.dumps(databook._package())
|
||||
|
||||
|
||||
def import_set(dset, in_stream):
|
||||
"""Returns dataset from JSON stream."""
|
||||
|
||||
dset.wipe()
|
||||
dset.dict = json.loads(in_stream)
|
||||
|
||||
|
||||
def import_book(dbook, in_stream):
|
||||
"""Returns databook from JSON stream."""
|
||||
|
||||
dbook.wipe()
|
||||
for sheet in json.loads(in_stream):
|
||||
data = tablib.Dataset()
|
||||
data.title = sheet['title']
|
||||
data.dict = sheet['data']
|
||||
dbook.add_sheet(data)
|
||||
|
||||
|
||||
def detect(stream):
|
||||
"""Returns True if given stream is valid JSON."""
|
||||
try:
|
||||
json.loads(stream)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
|
@ -1,100 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Tablib - ODF Support.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
if sys.version_info[0] > 2:
|
||||
from io import BytesIO
|
||||
else:
|
||||
from cStringIO import StringIO as BytesIO
|
||||
|
||||
from tablib.compat import opendocument, style, table, text, unicode
|
||||
|
||||
title = 'ods'
|
||||
extensions = ('ods',)
|
||||
|
||||
bold = style.Style(name="bold", family="paragraph")
|
||||
bold.addElement(style.TextProperties(fontweight="bold", fontweightasian="bold", fontweightcomplex="bold"))
|
||||
|
||||
def export_set(dataset):
|
||||
"""Returns ODF representation of Dataset."""
|
||||
|
||||
wb = opendocument.OpenDocumentSpreadsheet()
|
||||
wb.automaticstyles.addElement(bold)
|
||||
|
||||
ws = table.Table(name=dataset.title if dataset.title else 'Tablib Dataset')
|
||||
wb.spreadsheet.addElement(ws)
|
||||
dset_sheet(dataset, ws)
|
||||
|
||||
stream = BytesIO()
|
||||
wb.save(stream)
|
||||
return stream.getvalue()
|
||||
|
||||
|
||||
def export_book(databook):
|
||||
"""Returns ODF representation of DataBook."""
|
||||
|
||||
wb = opendocument.OpenDocumentSpreadsheet()
|
||||
wb.automaticstyles.addElement(bold)
|
||||
|
||||
for i, dset in enumerate(databook._datasets):
|
||||
ws = table.Table(name=dset.title if dset.title else 'Sheet%s' % (i))
|
||||
wb.spreadsheet.addElement(ws)
|
||||
dset_sheet(dset, ws)
|
||||
|
||||
|
||||
stream = BytesIO()
|
||||
wb.save(stream)
|
||||
return stream.getvalue()
|
||||
|
||||
|
||||
def dset_sheet(dataset, ws):
|
||||
"""Completes given worksheet from given Dataset."""
|
||||
_package = dataset._package(dicts=False)
|
||||
|
||||
for i, sep in enumerate(dataset._separators):
|
||||
_offset = i
|
||||
_package.insert((sep[0] + _offset), (sep[1],))
|
||||
|
||||
for i, row in enumerate(_package):
|
||||
row_number = i + 1
|
||||
odf_row = table.TableRow(stylename=bold, defaultcellstylename='bold')
|
||||
for j, col in enumerate(row):
|
||||
try:
|
||||
col = unicode(col, errors='ignore')
|
||||
except TypeError:
|
||||
## col is already unicode
|
||||
pass
|
||||
ws.addElement(table.TableColumn())
|
||||
|
||||
# bold headers
|
||||
if (row_number == 1) and dataset.headers:
|
||||
odf_row.setAttribute('stylename', bold)
|
||||
ws.addElement(odf_row)
|
||||
cell = table.TableCell()
|
||||
p = text.P()
|
||||
p.addElement(text.Span(text=col, stylename=bold))
|
||||
cell.addElement(p)
|
||||
odf_row.addElement(cell)
|
||||
|
||||
# wrap the rest
|
||||
else:
|
||||
try:
|
||||
if '\n' in col:
|
||||
ws.addElement(odf_row)
|
||||
cell = table.TableCell()
|
||||
cell.addElement(text.P(text=col))
|
||||
odf_row.addElement(cell)
|
||||
else:
|
||||
ws.addElement(odf_row)
|
||||
cell = table.TableCell()
|
||||
cell.addElement(text.P(text=col))
|
||||
odf_row.addElement(cell)
|
||||
except TypeError:
|
||||
ws.addElement(odf_row)
|
||||
cell = table.TableCell()
|
||||
cell.addElement(text.P(text=col))
|
||||
odf_row.addElement(cell)
|
|
@ -1,59 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Tablib - TSV (Tab Separated Values) Support.
|
||||
"""
|
||||
|
||||
from tablib.compat import is_py3, csv, StringIO
|
||||
|
||||
|
||||
|
||||
title = 'tsv'
|
||||
extensions = ('tsv',)
|
||||
|
||||
DEFAULT_ENCODING = 'utf-8'
|
||||
|
||||
def export_set(dataset):
|
||||
"""Returns a TSV representation of Dataset."""
|
||||
|
||||
stream = StringIO()
|
||||
|
||||
if is_py3:
|
||||
_tsv = csv.writer(stream, delimiter='\t')
|
||||
else:
|
||||
_tsv = csv.writer(stream, encoding=DEFAULT_ENCODING, delimiter='\t')
|
||||
|
||||
for row in dataset._package(dicts=False):
|
||||
_tsv.writerow(row)
|
||||
|
||||
return stream.getvalue()
|
||||
|
||||
|
||||
def import_set(dset, in_stream, headers=True):
|
||||
"""Returns dataset from TSV stream."""
|
||||
|
||||
dset.wipe()
|
||||
|
||||
if is_py3:
|
||||
rows = csv.reader(in_stream.splitlines(), delimiter='\t')
|
||||
else:
|
||||
rows = csv.reader(in_stream.splitlines(), delimiter='\t',
|
||||
encoding=DEFAULT_ENCODING)
|
||||
|
||||
for i, row in enumerate(rows):
|
||||
# Skip empty rows
|
||||
if not row:
|
||||
continue
|
||||
|
||||
if (i == 0) and (headers):
|
||||
dset.headers = row
|
||||
else:
|
||||
dset.append(row)
|
||||
|
||||
|
||||
def detect(stream):
|
||||
"""Returns True if given stream is valid TSV."""
|
||||
try:
|
||||
csv.Sniffer().sniff(stream, delimiters='\t')
|
||||
return True
|
||||
except (csv.Error, TypeError):
|
||||
return False
|
|
@ -1,135 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Tablib - XLS Support.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
from tablib.compat import BytesIO, xlwt, xlrd, XLRDError
|
||||
import tablib
|
||||
|
||||
title = 'xls'
|
||||
extensions = ('xls',)
|
||||
|
||||
# special styles
|
||||
wrap = xlwt.easyxf("alignment: wrap on")
|
||||
bold = xlwt.easyxf("font: bold on")
|
||||
|
||||
|
||||
def detect(stream):
|
||||
"""Returns True if given stream is a readable excel file."""
|
||||
try:
|
||||
xlrd.open_workbook(file_contents=stream)
|
||||
return True
|
||||
except (TypeError, XLRDError):
|
||||
pass
|
||||
try:
|
||||
xlrd.open_workbook(file_contents=stream.read())
|
||||
return True
|
||||
except (AttributeError, XLRDError):
|
||||
pass
|
||||
try:
|
||||
xlrd.open_workbook(filename=stream)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
def export_set(dataset):
|
||||
"""Returns XLS representation of Dataset."""
|
||||
|
||||
wb = xlwt.Workbook(encoding='utf8')
|
||||
ws = wb.add_sheet(dataset.title if dataset.title else 'Tablib Dataset')
|
||||
|
||||
dset_sheet(dataset, ws)
|
||||
|
||||
stream = BytesIO()
|
||||
wb.save(stream)
|
||||
return stream.getvalue()
|
||||
|
||||
|
||||
def export_book(databook):
|
||||
"""Returns XLS representation of DataBook."""
|
||||
|
||||
wb = xlwt.Workbook(encoding='utf8')
|
||||
|
||||
for i, dset in enumerate(databook._datasets):
|
||||
ws = wb.add_sheet(dset.title if dset.title else 'Sheet%s' % (i))
|
||||
|
||||
dset_sheet(dset, ws)
|
||||
|
||||
|
||||
stream = BytesIO()
|
||||
wb.save(stream)
|
||||
return stream.getvalue()
|
||||
|
||||
|
||||
def import_set(dset, in_stream, headers=True):
|
||||
"""Returns databook from XLS stream."""
|
||||
|
||||
dset.wipe()
|
||||
|
||||
xls_book = xlrd.open_workbook(file_contents=in_stream)
|
||||
sheet = xls_book.sheet_by_index(0)
|
||||
|
||||
dset.title = sheet.name
|
||||
|
||||
for i in xrange(sheet.nrows):
|
||||
if (i == 0) and (headers):
|
||||
dset.headers = sheet.row_values(0)
|
||||
else:
|
||||
dset.append(sheet.row_values(i))
|
||||
|
||||
def import_book(dbook, in_stream, headers=True):
|
||||
"""Returns databook from XLS stream."""
|
||||
|
||||
dbook.wipe()
|
||||
|
||||
xls_book = xlrd.open_workbook(file_contents=in_stream)
|
||||
|
||||
for sheet in xls_book.sheets():
|
||||
data = tablib.Dataset()
|
||||
data.title = sheet.name
|
||||
|
||||
for i in xrange(sheet.nrows):
|
||||
if (i == 0) and (headers):
|
||||
data.headers = sheet.row_values(0)
|
||||
else:
|
||||
data.append(sheet.row_values(i))
|
||||
|
||||
dbook.add_sheet(data)
|
||||
|
||||
|
||||
def dset_sheet(dataset, ws):
|
||||
"""Completes given worksheet from given Dataset."""
|
||||
_package = dataset._package(dicts=False)
|
||||
|
||||
for i, sep in enumerate(dataset._separators):
|
||||
_offset = i
|
||||
_package.insert((sep[0] + _offset), (sep[1],))
|
||||
|
||||
for i, row in enumerate(_package):
|
||||
for j, col in enumerate(row):
|
||||
|
||||
# bold headers
|
||||
if (i == 0) and dataset.headers:
|
||||
ws.write(i, j, col, bold)
|
||||
|
||||
# frozen header row
|
||||
ws.panes_frozen = True
|
||||
ws.horz_split_pos = 1
|
||||
|
||||
|
||||
# bold separators
|
||||
elif len(row) < dataset.width:
|
||||
ws.write(i, j, col, bold)
|
||||
|
||||
# wrap the rest
|
||||
else:
|
||||
try:
|
||||
if '\n' in col:
|
||||
ws.write(i, j, col, wrap)
|
||||
else:
|
||||
ws.write(i, j, col)
|
||||
except TypeError:
|
||||
ws.write(i, j, col)
|
|
@ -1,153 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Tablib - XLSX Support.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
if sys.version_info[0] > 2:
|
||||
from io import BytesIO
|
||||
else:
|
||||
from cStringIO import StringIO as BytesIO
|
||||
|
||||
from tablib.compat import openpyxl
|
||||
import tablib
|
||||
|
||||
Workbook = openpyxl.workbook.Workbook
|
||||
ExcelWriter = openpyxl.writer.excel.ExcelWriter
|
||||
get_column_letter = openpyxl.cell.get_column_letter
|
||||
|
||||
from tablib.compat import unicode
|
||||
|
||||
|
||||
title = 'xlsx'
|
||||
extensions = ('xlsx',)
|
||||
|
||||
|
||||
def detect(stream):
|
||||
"""Returns True if given stream is a readable excel file."""
|
||||
try:
|
||||
openpyxl.reader.excel.load_workbook(stream)
|
||||
return True
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
def export_set(dataset):
|
||||
"""Returns XLSX representation of Dataset."""
|
||||
|
||||
wb = Workbook()
|
||||
ws = wb.worksheets[0]
|
||||
ws.title = dataset.title if dataset.title else 'Tablib Dataset'
|
||||
|
||||
dset_sheet(dataset, ws)
|
||||
|
||||
stream = BytesIO()
|
||||
wb.save(stream)
|
||||
return stream.getvalue()
|
||||
|
||||
|
||||
def export_book(databook):
|
||||
"""Returns XLSX representation of DataBook."""
|
||||
|
||||
wb = Workbook()
|
||||
wb.worksheets = []
|
||||
ew = ExcelWriter(workbook = wb)
|
||||
for i, dset in enumerate(databook._datasets):
|
||||
ws = wb.create_sheet()
|
||||
ws.title = dset.title if dset.title else 'Sheet%s' % (i)
|
||||
|
||||
dset_sheet(dset, ws)
|
||||
|
||||
|
||||
stream = BytesIO()
|
||||
ew.save(stream)
|
||||
return stream.getvalue()
|
||||
|
||||
|
||||
def import_set(dset, in_stream, headers=True):
|
||||
"""Returns databook from XLS stream."""
|
||||
|
||||
dset.wipe()
|
||||
|
||||
xls_book = openpyxl.reader.excel.load_workbook(in_stream)
|
||||
sheet = xls_book.get_active_sheet()
|
||||
|
||||
dset.title = sheet.title
|
||||
|
||||
for i, row in enumerate(sheet.rows):
|
||||
row_vals = [c.value for c in row]
|
||||
if (i == 0) and (headers):
|
||||
dset.headers = row_vals
|
||||
else:
|
||||
dset.append(row_vals)
|
||||
|
||||
|
||||
def import_book(dbook, in_stream, headers=True):
|
||||
"""Returns databook from XLS stream."""
|
||||
|
||||
dbook.wipe()
|
||||
|
||||
xls_book = openpyxl.reader.excel.load_workbook(in_stream)
|
||||
|
||||
for sheet in xls_book.worksheets:
|
||||
data = tablib.Dataset()
|
||||
data.title = sheet.title
|
||||
|
||||
for i, row in enumerate(sheet.rows):
|
||||
row_vals = [c.value for c in row]
|
||||
if (i == 0) and (headers):
|
||||
data.headers = row_vals
|
||||
else:
|
||||
data.append(row_vals)
|
||||
|
||||
dbook.add_sheet(data)
|
||||
|
||||
|
||||
def dset_sheet(dataset, ws):
|
||||
"""Completes given worksheet from given Dataset."""
|
||||
_package = dataset._package(dicts=False)
|
||||
|
||||
for i, sep in enumerate(dataset._separators):
|
||||
_offset = i
|
||||
_package.insert((sep[0] + _offset), (sep[1],))
|
||||
|
||||
for i, row in enumerate(_package):
|
||||
row_number = i + 1
|
||||
for j, col in enumerate(row):
|
||||
col_idx = get_column_letter(j + 1)
|
||||
# We want to freeze the column after the last column
|
||||
frzn_col_idx = get_column_letter(j + 2)
|
||||
|
||||
# bold headers
|
||||
if (row_number == 1) and dataset.headers:
|
||||
# ws.cell('%s%s'%(col_idx, row_number)).value = unicode(
|
||||
# '%s' % col, errors='ignore')
|
||||
ws.cell('%s%s'%(col_idx, row_number)).value = unicode(col)
|
||||
style = ws.get_style('%s%s' % (col_idx, row_number))
|
||||
style.font.bold = True
|
||||
ws.freeze_panes = '%s%s' % (frzn_col_idx, row_number)
|
||||
|
||||
|
||||
# bold separators
|
||||
elif len(row) < dataset.width:
|
||||
ws.cell('%s%s'%(col_idx, row_number)).value = unicode(
|
||||
'%s' % col, errors='ignore')
|
||||
style = ws.get_style('%s%s' % (col_idx, row_number))
|
||||
style.font.bold = True
|
||||
|
||||
# wrap the rest
|
||||
else:
|
||||
try:
|
||||
if '\n' in col:
|
||||
ws.cell('%s%s'%(col_idx, row_number)).value = unicode(
|
||||
'%s' % col, errors='ignore')
|
||||
style = ws.get_style('%s%s' % (col_idx, row_number))
|
||||
style.alignment.wrap_text
|
||||
else:
|
||||
ws.cell('%s%s'%(col_idx, row_number)).value = unicode(
|
||||
'%s' % col, errors='ignore')
|
||||
except TypeError:
|
||||
ws.cell('%s%s'%(col_idx, row_number)).value = unicode(col)
|
||||
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Tablib - YAML Support.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
if sys.version_info[0] > 2:
|
||||
import tablib.packages.yaml3 as yaml
|
||||
else:
|
||||
import tablib.packages.yaml as yaml
|
||||
|
||||
|
||||
import tablib
|
||||
|
||||
|
||||
|
||||
title = 'yaml'
|
||||
extensions = ('yaml', 'yml')
|
||||
|
||||
|
||||
|
||||
def export_set(dataset):
|
||||
"""Returns YAML representation of Dataset."""
|
||||
|
||||
return yaml.safe_dump(dataset._package(ordered=False))
|
||||
|
||||
|
||||
def export_book(databook):
|
||||
"""Returns YAML representation of Databook."""
|
||||
return yaml.safe_dump(databook._package(ordered=False))
|
||||
|
||||
|
||||
def import_set(dset, in_stream):
|
||||
"""Returns dataset from YAML stream."""
|
||||
|
||||
dset.wipe()
|
||||
dset.dict = yaml.safe_load(in_stream)
|
||||
|
||||
|
||||
def import_book(dbook, in_stream):
|
||||
"""Returns databook from YAML stream."""
|
||||
|
||||
dbook.wipe()
|
||||
|
||||
for sheet in yaml.load(in_stream):
|
||||
data = tablib.Dataset()
|
||||
data.title = sheet['title']
|
||||
data.dict = sheet['data']
|
||||
dbook.add_sheet(data)
|
||||
|
||||
def detect(stream):
|
||||
"""Returns True if given stream is valid YAML."""
|
||||
try:
|
||||
_yaml = yaml.safe_load(stream)
|
||||
if isinstance(_yaml, (list, tuple, dict)):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
except (yaml.parser.ParserError, yaml.reader.ReaderError,
|
||||
yaml.scanner.ScannerError):
|
||||
return False
|
|
@ -1,484 +0,0 @@
|
|||
# This code is in the public domain, it comes
|
||||
# with absolutely no warranty and you can do
|
||||
# absolutely whatever you want with it.
|
||||
|
||||
__date__ = '17 May 2007'
|
||||
__version__ = '1.7'
|
||||
__doc__= """
|
||||
This is markup.py - a Python module that attempts to
|
||||
make it easier to generate HTML/XML from a Python program
|
||||
in an intuitive, lightweight, customizable and pythonic way.
|
||||
|
||||
The code is in the public domain.
|
||||
|
||||
Version: %s as of %s.
|
||||
|
||||
Documentation and further info is at http://markup.sourceforge.net/
|
||||
|
||||
Please send bug reports, feature requests, enhancement
|
||||
ideas or questions to nogradi at gmail dot com.
|
||||
|
||||
Installation: drop markup.py somewhere into your Python path.
|
||||
""" % ( __version__, __date__ )
|
||||
|
||||
import string
|
||||
|
||||
class element:
|
||||
"""This class handles the addition of a new element."""
|
||||
|
||||
def __init__( self, tag, case='lower', parent=None ):
|
||||
self.parent = parent
|
||||
|
||||
if case == 'lower':
|
||||
self.tag = tag.lower( )
|
||||
else:
|
||||
self.tag = tag.upper( )
|
||||
|
||||
def __call__( self, *args, **kwargs ):
|
||||
if len( args ) > 1:
|
||||
raise ArgumentError( self.tag )
|
||||
|
||||
# if class_ was defined in parent it should be added to every element
|
||||
if self.parent is not None and self.parent.class_ is not None:
|
||||
if 'class_' not in kwargs:
|
||||
kwargs['class_'] = self.parent.class_
|
||||
|
||||
if self.parent is None and len( args ) == 1:
|
||||
x = [ self.render( self.tag, False, myarg, mydict ) for myarg, mydict in _argsdicts( args, kwargs ) ]
|
||||
return '\n'.join( x )
|
||||
elif self.parent is None and len( args ) == 0:
|
||||
x = [ self.render( self.tag, True, myarg, mydict ) for myarg, mydict in _argsdicts( args, kwargs ) ]
|
||||
return '\n'.join( x )
|
||||
|
||||
if self.tag in self.parent.twotags:
|
||||
for myarg, mydict in _argsdicts( args, kwargs ):
|
||||
self.render( self.tag, False, myarg, mydict )
|
||||
elif self.tag in self.parent.onetags:
|
||||
if len( args ) == 0:
|
||||
for myarg, mydict in _argsdicts( args, kwargs ):
|
||||
self.render( self.tag, True, myarg, mydict ) # here myarg is always None, because len( args ) = 0
|
||||
else:
|
||||
raise ClosingError( self.tag )
|
||||
elif self.parent.mode == 'strict_html' and self.tag in self.parent.deptags:
|
||||
raise DeprecationError( self.tag )
|
||||
else:
|
||||
raise InvalidElementError( self.tag, self.parent.mode )
|
||||
|
||||
def render( self, tag, single, between, kwargs ):
|
||||
"""Append the actual tags to content."""
|
||||
|
||||
out = u"<%s" % tag
|
||||
for key, value in kwargs.iteritems( ):
|
||||
if value is not None: # when value is None that means stuff like <... checked>
|
||||
key = key.strip('_') # strip this so class_ will mean class, etc.
|
||||
if key == 'http_equiv': # special cases, maybe change _ to - overall?
|
||||
key = 'http-equiv'
|
||||
elif key == 'accept_charset':
|
||||
key = 'accept-charset'
|
||||
out = u"%s %s=\"%s\"" % ( out, key, escape( value ) )
|
||||
else:
|
||||
out = u"%s %s" % ( out, key )
|
||||
if between is not None:
|
||||
out = u"%s>%s</%s>" % ( out, between, tag )
|
||||
else:
|
||||
if single:
|
||||
out = u"%s />" % out
|
||||
else:
|
||||
out = u"%s>" % out
|
||||
if self.parent is not None:
|
||||
self.parent.content.append( out )
|
||||
else:
|
||||
return out
|
||||
|
||||
def close( self ):
|
||||
"""Append a closing tag unless element has only opening tag."""
|
||||
|
||||
if self.tag in self.parent.twotags:
|
||||
self.parent.content.append( "</%s>" % self.tag )
|
||||
elif self.tag in self.parent.onetags:
|
||||
raise ClosingError( self.tag )
|
||||
elif self.parent.mode == 'strict_html' and self.tag in self.parent.deptags:
|
||||
raise DeprecationError( self.tag )
|
||||
|
||||
def open( self, **kwargs ):
|
||||
"""Append an opening tag."""
|
||||
|
||||
if self.tag in self.parent.twotags or self.tag in self.parent.onetags:
|
||||
self.render( self.tag, False, None, kwargs )
|
||||
elif self.mode == 'strict_html' and self.tag in self.parent.deptags:
|
||||
raise DeprecationError( self.tag )
|
||||
|
||||
class page:
|
||||
"""This is our main class representing a document. Elements are added
|
||||
as attributes of an instance of this class."""
|
||||
|
||||
def __init__( self, mode='strict_html', case='lower', onetags=None, twotags=None, separator='\n', class_=None ):
|
||||
"""Stuff that effects the whole document.
|
||||
|
||||
mode -- 'strict_html' for HTML 4.01 (default)
|
||||
'html' alias for 'strict_html'
|
||||
'loose_html' to allow some deprecated elements
|
||||
'xml' to allow arbitrary elements
|
||||
|
||||
case -- 'lower' element names will be printed in lower case (default)
|
||||
'upper' they will be printed in upper case
|
||||
|
||||
onetags -- list or tuple of valid elements with opening tags only
|
||||
twotags -- list or tuple of valid elements with both opening and closing tags
|
||||
these two keyword arguments may be used to select
|
||||
the set of valid elements in 'xml' mode
|
||||
invalid elements will raise appropriate exceptions
|
||||
|
||||
separator -- string to place between added elements, defaults to newline
|
||||
|
||||
class_ -- a class that will be added to every element if defined"""
|
||||
|
||||
valid_onetags = [ "AREA", "BASE", "BR", "COL", "FRAME", "HR", "IMG", "INPUT", "LINK", "META", "PARAM" ]
|
||||
valid_twotags = [ "A", "ABBR", "ACRONYM", "ADDRESS", "B", "BDO", "BIG", "BLOCKQUOTE", "BODY", "BUTTON",
|
||||
"CAPTION", "CITE", "CODE", "COLGROUP", "DD", "DEL", "DFN", "DIV", "DL", "DT", "EM", "FIELDSET",
|
||||
"FORM", "FRAMESET", "H1", "H2", "H3", "H4", "H5", "H6", "HEAD", "HTML", "I", "IFRAME", "INS",
|
||||
"KBD", "LABEL", "LEGEND", "LI", "MAP", "NOFRAMES", "NOSCRIPT", "OBJECT", "OL", "OPTGROUP",
|
||||
"OPTION", "P", "PRE", "Q", "SAMP", "SCRIPT", "SELECT", "SMALL", "SPAN", "STRONG", "STYLE",
|
||||
"SUB", "SUP", "TABLE", "TBODY", "TD", "TEXTAREA", "TFOOT", "TH", "THEAD", "TITLE", "TR",
|
||||
"TT", "UL", "VAR" ]
|
||||
deprecated_onetags = [ "BASEFONT", "ISINDEX" ]
|
||||
deprecated_twotags = [ "APPLET", "CENTER", "DIR", "FONT", "MENU", "S", "STRIKE", "U" ]
|
||||
|
||||
self.header = [ ]
|
||||
self.content = [ ]
|
||||
self.footer = [ ]
|
||||
self.case = case
|
||||
self.separator = separator
|
||||
|
||||
# init( ) sets it to True so we know that </body></html> has to be printed at the end
|
||||
self._full = False
|
||||
self.class_= class_
|
||||
|
||||
if mode == 'strict_html' or mode == 'html':
|
||||
self.onetags = valid_onetags
|
||||
self.onetags += map( string.lower, self.onetags )
|
||||
self.twotags = valid_twotags
|
||||
self.twotags += map( string.lower, self.twotags )
|
||||
self.deptags = deprecated_onetags + deprecated_twotags
|
||||
self.deptags += map( string.lower, self.deptags )
|
||||
self.mode = 'strict_html'
|
||||
elif mode == 'loose_html':
|
||||
self.onetags = valid_onetags + deprecated_onetags
|
||||
self.onetags += map( string.lower, self.onetags )
|
||||
self.twotags = valid_twotags + deprecated_twotags
|
||||
self.twotags += map( string.lower, self.twotags )
|
||||
self.mode = mode
|
||||
elif mode == 'xml':
|
||||
if onetags and twotags:
|
||||
self.onetags = onetags
|
||||
self.twotags = twotags
|
||||
elif ( onetags and not twotags ) or ( twotags and not onetags ):
|
||||
raise CustomizationError( )
|
||||
else:
|
||||
self.onetags = russell( )
|
||||
self.twotags = russell( )
|
||||
self.mode = mode
|
||||
else:
|
||||
raise ModeError( mode )
|
||||
|
||||
def __getattr__( self, attr ):
|
||||
if attr.startswith("__") and attr.endswith("__"):
|
||||
raise AttributeError, attr
|
||||
return element( attr, case=self.case, parent=self )
|
||||
|
||||
def __str__( self ):
|
||||
|
||||
if self._full and ( self.mode == 'strict_html' or self.mode == 'loose_html' ):
|
||||
end = [ '</body>', '</html>' ]
|
||||
else:
|
||||
end = [ ]
|
||||
|
||||
return self.separator.join( self.header + self.content + self.footer + end )
|
||||
|
||||
def __call__( self, escape=False ):
|
||||
"""Return the document as a string.
|
||||
|
||||
escape -- False print normally
|
||||
True replace < and > by < and >
|
||||
the default escape sequences in most browsers"""
|
||||
|
||||
if escape:
|
||||
return _escape( self.__str__( ) )
|
||||
else:
|
||||
return self.__str__( )
|
||||
|
||||
def add( self, text ):
|
||||
"""This is an alias to addcontent."""
|
||||
self.addcontent( text )
|
||||
|
||||
def addfooter( self, text ):
|
||||
"""Add some text to the bottom of the document"""
|
||||
self.footer.append( text )
|
||||
|
||||
def addheader( self, text ):
|
||||
"""Add some text to the top of the document"""
|
||||
self.header.append( text )
|
||||
|
||||
def addcontent( self, text ):
|
||||
"""Add some text to the main part of the document"""
|
||||
self.content.append( text )
|
||||
|
||||
|
||||
def init( self, lang='en', css=None, metainfo=None, title=None, header=None,
|
||||
footer=None, charset=None, encoding=None, doctype=None, bodyattrs=None, script=None ):
|
||||
"""This method is used for complete documents with appropriate
|
||||
doctype, encoding, title, etc information. For an HTML/XML snippet
|
||||
omit this method.
|
||||
|
||||
lang -- language, usually a two character string, will appear
|
||||
as <html lang='en'> in html mode (ignored in xml mode)
|
||||
|
||||
css -- Cascading Style Sheet filename as a string or a list of
|
||||
strings for multiple css files (ignored in xml mode)
|
||||
|
||||
metainfo -- a dictionary in the form { 'name':'content' } to be inserted
|
||||
into meta element(s) as <meta name='name' content='content'>
|
||||
(ignored in xml mode)
|
||||
|
||||
bodyattrs --a dictionary in the form { 'key':'value', ... } which will be added
|
||||
as attributes of the <body> element as <body key='value' ... >
|
||||
(ignored in xml mode)
|
||||
|
||||
script -- dictionary containing src:type pairs, <script type='text/type' src=src></script>
|
||||
|
||||
title -- the title of the document as a string to be inserted into
|
||||
a title element as <title>my title</title> (ignored in xml mode)
|
||||
|
||||
header -- some text to be inserted right after the <body> element
|
||||
(ignored in xml mode)
|
||||
|
||||
footer -- some text to be inserted right before the </body> element
|
||||
(ignored in xml mode)
|
||||
|
||||
charset -- a string defining the character set, will be inserted into a
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=myset'>
|
||||
element (ignored in xml mode)
|
||||
|
||||
encoding -- a string defining the encoding, will be put into to first line of
|
||||
the document as <?xml version='1.0' encoding='myencoding' ?> in
|
||||
xml mode (ignored in html mode)
|
||||
|
||||
doctype -- the document type string, defaults to
|
||||
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>
|
||||
in html mode (ignored in xml mode)"""
|
||||
|
||||
self._full = True
|
||||
|
||||
if self.mode == 'strict_html' or self.mode == 'loose_html':
|
||||
if doctype is None:
|
||||
doctype = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>"
|
||||
self.header.append( doctype )
|
||||
self.html( lang=lang )
|
||||
self.head( )
|
||||
if charset is not None:
|
||||
self.meta( http_equiv='Content-Type', content="text/html; charset=%s" % charset )
|
||||
if metainfo is not None:
|
||||
self.metainfo( metainfo )
|
||||
if css is not None:
|
||||
self.css( css )
|
||||
if title is not None:
|
||||
self.title( title )
|
||||
if script is not None:
|
||||
self.scripts( script )
|
||||
self.head.close()
|
||||
if bodyattrs is not None:
|
||||
self.body( **bodyattrs )
|
||||
else:
|
||||
self.body( )
|
||||
if header is not None:
|
||||
self.content.append( header )
|
||||
if footer is not None:
|
||||
self.footer.append( footer )
|
||||
|
||||
elif self.mode == 'xml':
|
||||
if doctype is None:
|
||||
if encoding is not None:
|
||||
doctype = "<?xml version='1.0' encoding='%s' ?>" % encoding
|
||||
else:
|
||||
doctype = "<?xml version='1.0' ?>"
|
||||
self.header.append( doctype )
|
||||
|
||||
def css( self, filelist ):
|
||||
"""This convenience function is only useful for html.
|
||||
It adds css stylesheet(s) to the document via the <link> element."""
|
||||
|
||||
if isinstance( filelist, basestring ):
|
||||
self.link( href=filelist, rel='stylesheet', type='text/css', media='all' )
|
||||
else:
|
||||
for file in filelist:
|
||||
self.link( href=file, rel='stylesheet', type='text/css', media='all' )
|
||||
|
||||
def metainfo( self, mydict ):
|
||||
"""This convenience function is only useful for html.
|
||||
It adds meta information via the <meta> element, the argument is
|
||||
a dictionary of the form { 'name':'content' }."""
|
||||
|
||||
if isinstance( mydict, dict ):
|
||||
for name, content in mydict.iteritems( ):
|
||||
self.meta( name=name, content=content )
|
||||
else:
|
||||
raise TypeError, "Metainfo should be called with a dictionary argument of name:content pairs."
|
||||
|
||||
def scripts( self, mydict ):
|
||||
"""Only useful in html, mydict is dictionary of src:type pairs will
|
||||
be rendered as <script type='text/type' src=src></script>"""
|
||||
|
||||
if isinstance( mydict, dict ):
|
||||
for src, type in mydict.iteritems( ):
|
||||
self.script( '', src=src, type='text/%s' % type )
|
||||
else:
|
||||
raise TypeError, "Script should be given a dictionary of src:type pairs."
|
||||
|
||||
|
||||
class _oneliner:
|
||||
"""An instance of oneliner returns a string corresponding to one element.
|
||||
This class can be used to write 'oneliners' that return a string
|
||||
immediately so there is no need to instantiate the page class."""
|
||||
|
||||
def __init__( self, case='lower' ):
|
||||
self.case = case
|
||||
|
||||
def __getattr__( self, attr ):
|
||||
if attr.startswith("__") and attr.endswith("__"):
|
||||
raise AttributeError, attr
|
||||
return element( attr, case=self.case, parent=None )
|
||||
|
||||
oneliner = _oneliner( case='lower' )
|
||||
upper_oneliner = _oneliner( case='upper' )
|
||||
|
||||
def _argsdicts( args, mydict ):
|
||||
"""A utility generator that pads argument list and dictionary values, will only be called with len( args ) = 0, 1."""
|
||||
|
||||
if len( args ) == 0:
|
||||
args = None,
|
||||
elif len( args ) == 1:
|
||||
args = _totuple( args[0] )
|
||||
else:
|
||||
raise Exception, "We should have never gotten here."
|
||||
|
||||
mykeys = mydict.keys( )
|
||||
myvalues = map( _totuple, mydict.values( ) )
|
||||
|
||||
maxlength = max( map( len, [ args ] + myvalues ) )
|
||||
|
||||
for i in xrange( maxlength ):
|
||||
thisdict = { }
|
||||
for key, value in zip( mykeys, myvalues ):
|
||||
try:
|
||||
thisdict[ key ] = value[i]
|
||||
except IndexError:
|
||||
thisdict[ key ] = value[-1]
|
||||
try:
|
||||
thisarg = args[i]
|
||||
except IndexError:
|
||||
thisarg = args[-1]
|
||||
|
||||
yield thisarg, thisdict
|
||||
|
||||
def _totuple( x ):
|
||||
"""Utility stuff to convert string, int, float, None or anything to a usable tuple."""
|
||||
|
||||
if isinstance( x, basestring ):
|
||||
out = x,
|
||||
elif isinstance( x, ( int, float ) ):
|
||||
out = str( x ),
|
||||
elif x is None:
|
||||
out = None,
|
||||
else:
|
||||
out = tuple( x )
|
||||
|
||||
return out
|
||||
|
||||
def escape( text, newline=False ):
|
||||
"""Escape special html characters."""
|
||||
|
||||
if isinstance( text, basestring ):
|
||||
if '&' in text:
|
||||
text = text.replace( '&', '&' )
|
||||
if '>' in text:
|
||||
text = text.replace( '>', '>' )
|
||||
if '<' in text:
|
||||
text = text.replace( '<', '<' )
|
||||
if '\"' in text:
|
||||
text = text.replace( '\"', '"' )
|
||||
if '\'' in text:
|
||||
text = text.replace( '\'', '"' )
|
||||
if newline:
|
||||
if '\n' in text:
|
||||
text = text.replace( '\n', '<br>' )
|
||||
|
||||
return text
|
||||
|
||||
_escape = escape
|
||||
|
||||
def unescape( text ):
|
||||
"""Inverse of escape."""
|
||||
|
||||
if isinstance( text, basestring ):
|
||||
if '&' in text:
|
||||
text = text.replace( '&', '&' )
|
||||
if '>' in text:
|
||||
text = text.replace( '>', '>' )
|
||||
if '<' in text:
|
||||
text = text.replace( '<', '<' )
|
||||
if '"' in text:
|
||||
text = text.replace( '"', '\"' )
|
||||
|
||||
return text
|
||||
|
||||
class dummy:
|
||||
"""A dummy class for attaching attributes."""
|
||||
pass
|
||||
|
||||
doctype = dummy( )
|
||||
doctype.frameset = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Frameset//EN' 'http://www.w3.org/TR/html4/frameset.dtd'>"
|
||||
doctype.strict = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>"
|
||||
doctype.loose = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>"
|
||||
|
||||
class russell:
|
||||
"""A dummy class that contains anything."""
|
||||
|
||||
def __contains__( self, item ):
|
||||
return True
|
||||
|
||||
|
||||
class MarkupError( Exception ):
|
||||
"""All our exceptions subclass this."""
|
||||
def __str__( self ):
|
||||
return self.message
|
||||
|
||||
class ClosingError( MarkupError ):
|
||||
def __init__( self, tag ):
|
||||
self.message = "The element '%s' does not accept non-keyword arguments (has no closing tag)." % tag
|
||||
|
||||
class OpeningError( MarkupError ):
|
||||
def __init__( self, tag ):
|
||||
self.message = "The element '%s' can not be opened." % tag
|
||||
|
||||
class ArgumentError( MarkupError ):
|
||||
def __init__( self, tag ):
|
||||
self.message = "The element '%s' was called with more than one non-keyword argument." % tag
|
||||
|
||||
class InvalidElementError( MarkupError ):
|
||||
def __init__( self, tag, mode ):
|
||||
self.message = "The element '%s' is not valid for your mode '%s'." % ( tag, mode )
|
||||
|
||||
class DeprecationError( MarkupError ):
|
||||
def __init__( self, tag ):
|
||||
self.message = "The element '%s' is deprecated, instantiate markup.page with mode='loose_html' to allow it." % tag
|
||||
|
||||
class ModeError( MarkupError ):
|
||||
def __init__( self, mode ):
|
||||
self.message = "Mode '%s' is invalid, possible values: strict_html, loose_html, xml." % mode
|
||||
|
||||
class CustomizationError( MarkupError ):
|
||||
def __init__( self ):
|
||||
self.message = "If you customize the allowed elements, you must define both types 'onetags' and 'twotags'."
|
||||
|
||||
if __name__ == '__main__':
|
||||
print __doc__
|
|
@ -1,484 +0,0 @@
|
|||
# This code is in the public domain, it comes
|
||||
# with absolutely no warranty and you can do
|
||||
# absolutely whatever you want with it.
|
||||
|
||||
__date__ = '17 May 2007'
|
||||
__version__ = '1.7'
|
||||
__doc__= """
|
||||
This is markup.py - a Python module that attempts to
|
||||
make it easier to generate HTML/XML from a Python program
|
||||
in an intuitive, lightweight, customizable and pythonic way.
|
||||
|
||||
The code is in the public domain.
|
||||
|
||||
Version: %s as of %s.
|
||||
|
||||
Documentation and further info is at http://markup.sourceforge.net/
|
||||
|
||||
Please send bug reports, feature requests, enhancement
|
||||
ideas or questions to nogradi at gmail dot com.
|
||||
|
||||
Installation: drop markup.py somewhere into your Python path.
|
||||
""" % ( __version__, __date__ )
|
||||
|
||||
import string
|
||||
|
||||
class element:
|
||||
"""This class handles the addition of a new element."""
|
||||
|
||||
def __init__( self, tag, case='lower', parent=None ):
|
||||
self.parent = parent
|
||||
|
||||
if case == 'lower':
|
||||
self.tag = tag.lower( )
|
||||
else:
|
||||
self.tag = tag.upper( )
|
||||
|
||||
def __call__( self, *args, **kwargs ):
|
||||
if len( args ) > 1:
|
||||
raise ArgumentError( self.tag )
|
||||
|
||||
# if class_ was defined in parent it should be added to every element
|
||||
if self.parent is not None and self.parent.class_ is not None:
|
||||
if 'class_' not in kwargs:
|
||||
kwargs['class_'] = self.parent.class_
|
||||
|
||||
if self.parent is None and len( args ) == 1:
|
||||
x = [ self.render( self.tag, False, myarg, mydict ) for myarg, mydict in _argsdicts( args, kwargs ) ]
|
||||
return '\n'.join( x )
|
||||
elif self.parent is None and len( args ) == 0:
|
||||
x = [ self.render( self.tag, True, myarg, mydict ) for myarg, mydict in _argsdicts( args, kwargs ) ]
|
||||
return '\n'.join( x )
|
||||
|
||||
if self.tag in self.parent.twotags:
|
||||
for myarg, mydict in _argsdicts( args, kwargs ):
|
||||
self.render( self.tag, False, myarg, mydict )
|
||||
elif self.tag in self.parent.onetags:
|
||||
if len( args ) == 0:
|
||||
for myarg, mydict in _argsdicts( args, kwargs ):
|
||||
self.render( self.tag, True, myarg, mydict ) # here myarg is always None, because len( args ) = 0
|
||||
else:
|
||||
raise ClosingError( self.tag )
|
||||
elif self.parent.mode == 'strict_html' and self.tag in self.parent.deptags:
|
||||
raise DeprecationError( self.tag )
|
||||
else:
|
||||
raise InvalidElementError( self.tag, self.parent.mode )
|
||||
|
||||
def render( self, tag, single, between, kwargs ):
|
||||
"""Append the actual tags to content."""
|
||||
|
||||
out = "<%s" % tag
|
||||
for key, value in kwargs.items( ):
|
||||
if value is not None: # when value is None that means stuff like <... checked>
|
||||
key = key.strip('_') # strip this so class_ will mean class, etc.
|
||||
if key == 'http_equiv': # special cases, maybe change _ to - overall?
|
||||
key = 'http-equiv'
|
||||
elif key == 'accept_charset':
|
||||
key = 'accept-charset'
|
||||
out = "%s %s=\"%s\"" % ( out, key, escape( value ) )
|
||||
else:
|
||||
out = "%s %s" % ( out, key )
|
||||
if between is not None:
|
||||
out = "%s>%s</%s>" % ( out, between, tag )
|
||||
else:
|
||||
if single:
|
||||
out = "%s />" % out
|
||||
else:
|
||||
out = "%s>" % out
|
||||
if self.parent is not None:
|
||||
self.parent.content.append( out )
|
||||
else:
|
||||
return out
|
||||
|
||||
def close( self ):
|
||||
"""Append a closing tag unless element has only opening tag."""
|
||||
|
||||
if self.tag in self.parent.twotags:
|
||||
self.parent.content.append( "</%s>" % self.tag )
|
||||
elif self.tag in self.parent.onetags:
|
||||
raise ClosingError( self.tag )
|
||||
elif self.parent.mode == 'strict_html' and self.tag in self.parent.deptags:
|
||||
raise DeprecationError( self.tag )
|
||||
|
||||
def open( self, **kwargs ):
|
||||
"""Append an opening tag."""
|
||||
|
||||
if self.tag in self.parent.twotags or self.tag in self.parent.onetags:
|
||||
self.render( self.tag, False, None, kwargs )
|
||||
elif self.mode == 'strict_html' and self.tag in self.parent.deptags:
|
||||
raise DeprecationError( self.tag )
|
||||
|
||||
class page:
|
||||
"""This is our main class representing a document. Elements are added
|
||||
as attributes of an instance of this class."""
|
||||
|
||||
def __init__( self, mode='strict_html', case='lower', onetags=None, twotags=None, separator='\n', class_=None ):
|
||||
"""Stuff that effects the whole document.
|
||||
|
||||
mode -- 'strict_html' for HTML 4.01 (default)
|
||||
'html' alias for 'strict_html'
|
||||
'loose_html' to allow some deprecated elements
|
||||
'xml' to allow arbitrary elements
|
||||
|
||||
case -- 'lower' element names will be printed in lower case (default)
|
||||
'upper' they will be printed in upper case
|
||||
|
||||
onetags -- list or tuple of valid elements with opening tags only
|
||||
twotags -- list or tuple of valid elements with both opening and closing tags
|
||||
these two keyword arguments may be used to select
|
||||
the set of valid elements in 'xml' mode
|
||||
invalid elements will raise appropriate exceptions
|
||||
|
||||
separator -- string to place between added elements, defaults to newline
|
||||
|
||||
class_ -- a class that will be added to every element if defined"""
|
||||
|
||||
valid_onetags = [ "AREA", "BASE", "BR", "COL", "FRAME", "HR", "IMG", "INPUT", "LINK", "META", "PARAM" ]
|
||||
valid_twotags = [ "A", "ABBR", "ACRONYM", "ADDRESS", "B", "BDO", "BIG", "BLOCKQUOTE", "BODY", "BUTTON",
|
||||
"CAPTION", "CITE", "CODE", "COLGROUP", "DD", "DEL", "DFN", "DIV", "DL", "DT", "EM", "FIELDSET",
|
||||
"FORM", "FRAMESET", "H1", "H2", "H3", "H4", "H5", "H6", "HEAD", "HTML", "I", "IFRAME", "INS",
|
||||
"KBD", "LABEL", "LEGEND", "LI", "MAP", "NOFRAMES", "NOSCRIPT", "OBJECT", "OL", "OPTGROUP",
|
||||
"OPTION", "P", "PRE", "Q", "SAMP", "SCRIPT", "SELECT", "SMALL", "SPAN", "STRONG", "STYLE",
|
||||
"SUB", "SUP", "TABLE", "TBODY", "TD", "TEXTAREA", "TFOOT", "TH", "THEAD", "TITLE", "TR",
|
||||
"TT", "UL", "VAR" ]
|
||||
deprecated_onetags = [ "BASEFONT", "ISINDEX" ]
|
||||
deprecated_twotags = [ "APPLET", "CENTER", "DIR", "FONT", "MENU", "S", "STRIKE", "U" ]
|
||||
|
||||
self.header = [ ]
|
||||
self.content = [ ]
|
||||
self.footer = [ ]
|
||||
self.case = case
|
||||
self.separator = separator
|
||||
|
||||
# init( ) sets it to True so we know that </body></html> has to be printed at the end
|
||||
self._full = False
|
||||
self.class_= class_
|
||||
|
||||
if mode == 'strict_html' or mode == 'html':
|
||||
self.onetags = valid_onetags
|
||||
self.onetags += list(map( str.lower, self.onetags ))
|
||||
self.twotags = valid_twotags
|
||||
self.twotags += list(map( str.lower, self.twotags ))
|
||||
self.deptags = deprecated_onetags + deprecated_twotags
|
||||
self.deptags += list(map( str.lower, self.deptags ))
|
||||
self.mode = 'strict_html'
|
||||
elif mode == 'loose_html':
|
||||
self.onetags = valid_onetags + deprecated_onetags
|
||||
self.onetags += list(map( str.lower, self.onetags ))
|
||||
self.twotags = valid_twotags + deprecated_twotags
|
||||
self.twotags += list(map( str.lower, self.twotags ))
|
||||
self.mode = mode
|
||||
elif mode == 'xml':
|
||||
if onetags and twotags:
|
||||
self.onetags = onetags
|
||||
self.twotags = twotags
|
||||
elif ( onetags and not twotags ) or ( twotags and not onetags ):
|
||||
raise CustomizationError( )
|
||||
else:
|
||||
self.onetags = russell( )
|
||||
self.twotags = russell( )
|
||||
self.mode = mode
|
||||
else:
|
||||
raise ModeError( mode )
|
||||
|
||||
def __getattr__( self, attr ):
|
||||
if attr.startswith("__") and attr.endswith("__"):
|
||||
raise AttributeError(attr)
|
||||
return element( attr, case=self.case, parent=self )
|
||||
|
||||
def __str__( self ):
|
||||
|
||||
if self._full and ( self.mode == 'strict_html' or self.mode == 'loose_html' ):
|
||||
end = [ '</body>', '</html>' ]
|
||||
else:
|
||||
end = [ ]
|
||||
|
||||
return self.separator.join( self.header + self.content + self.footer + end )
|
||||
|
||||
def __call__( self, escape=False ):
|
||||
"""Return the document as a string.
|
||||
|
||||
escape -- False print normally
|
||||
True replace < and > by < and >
|
||||
the default escape sequences in most browsers"""
|
||||
|
||||
if escape:
|
||||
return _escape( self.__str__( ) )
|
||||
else:
|
||||
return self.__str__( )
|
||||
|
||||
def add( self, text ):
|
||||
"""This is an alias to addcontent."""
|
||||
self.addcontent( text )
|
||||
|
||||
def addfooter( self, text ):
|
||||
"""Add some text to the bottom of the document"""
|
||||
self.footer.append( text )
|
||||
|
||||
def addheader( self, text ):
|
||||
"""Add some text to the top of the document"""
|
||||
self.header.append( text )
|
||||
|
||||
def addcontent( self, text ):
|
||||
"""Add some text to the main part of the document"""
|
||||
self.content.append( text )
|
||||
|
||||
|
||||
def init( self, lang='en', css=None, metainfo=None, title=None, header=None,
|
||||
footer=None, charset=None, encoding=None, doctype=None, bodyattrs=None, script=None ):
|
||||
"""This method is used for complete documents with appropriate
|
||||
doctype, encoding, title, etc information. For an HTML/XML snippet
|
||||
omit this method.
|
||||
|
||||
lang -- language, usually a two character string, will appear
|
||||
as <html lang='en'> in html mode (ignored in xml mode)
|
||||
|
||||
css -- Cascading Style Sheet filename as a string or a list of
|
||||
strings for multiple css files (ignored in xml mode)
|
||||
|
||||
metainfo -- a dictionary in the form { 'name':'content' } to be inserted
|
||||
into meta element(s) as <meta name='name' content='content'>
|
||||
(ignored in xml mode)
|
||||
|
||||
bodyattrs --a dictionary in the form { 'key':'value', ... } which will be added
|
||||
as attributes of the <body> element as <body key='value' ... >
|
||||
(ignored in xml mode)
|
||||
|
||||
script -- dictionary containing src:type pairs, <script type='text/type' src=src></script>
|
||||
|
||||
title -- the title of the document as a string to be inserted into
|
||||
a title element as <title>my title</title> (ignored in xml mode)
|
||||
|
||||
header -- some text to be inserted right after the <body> element
|
||||
(ignored in xml mode)
|
||||
|
||||
footer -- some text to be inserted right before the </body> element
|
||||
(ignored in xml mode)
|
||||
|
||||
charset -- a string defining the character set, will be inserted into a
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=myset'>
|
||||
element (ignored in xml mode)
|
||||
|
||||
encoding -- a string defining the encoding, will be put into to first line of
|
||||
the document as <?xml version='1.0' encoding='myencoding' ?> in
|
||||
xml mode (ignored in html mode)
|
||||
|
||||
doctype -- the document type string, defaults to
|
||||
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>
|
||||
in html mode (ignored in xml mode)"""
|
||||
|
||||
self._full = True
|
||||
|
||||
if self.mode == 'strict_html' or self.mode == 'loose_html':
|
||||
if doctype is None:
|
||||
doctype = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>"
|
||||
self.header.append( doctype )
|
||||
self.html( lang=lang )
|
||||
self.head( )
|
||||
if charset is not None:
|
||||
self.meta( http_equiv='Content-Type', content="text/html; charset=%s" % charset )
|
||||
if metainfo is not None:
|
||||
self.metainfo( metainfo )
|
||||
if css is not None:
|
||||
self.css( css )
|
||||
if title is not None:
|
||||
self.title( title )
|
||||
if script is not None:
|
||||
self.scripts( script )
|
||||
self.head.close()
|
||||
if bodyattrs is not None:
|
||||
self.body( **bodyattrs )
|
||||
else:
|
||||
self.body( )
|
||||
if header is not None:
|
||||
self.content.append( header )
|
||||
if footer is not None:
|
||||
self.footer.append( footer )
|
||||
|
||||
elif self.mode == 'xml':
|
||||
if doctype is None:
|
||||
if encoding is not None:
|
||||
doctype = "<?xml version='1.0' encoding='%s' ?>" % encoding
|
||||
else:
|
||||
doctype = "<?xml version='1.0' ?>"
|
||||
self.header.append( doctype )
|
||||
|
||||
def css( self, filelist ):
|
||||
"""This convenience function is only useful for html.
|
||||
It adds css stylesheet(s) to the document via the <link> element."""
|
||||
|
||||
if isinstance( filelist, str ):
|
||||
self.link( href=filelist, rel='stylesheet', type='text/css', media='all' )
|
||||
else:
|
||||
for file in filelist:
|
||||
self.link( href=file, rel='stylesheet', type='text/css', media='all' )
|
||||
|
||||
def metainfo( self, mydict ):
|
||||
"""This convenience function is only useful for html.
|
||||
It adds meta information via the <meta> element, the argument is
|
||||
a dictionary of the form { 'name':'content' }."""
|
||||
|
||||
if isinstance( mydict, dict ):
|
||||
for name, content in mydict.items( ):
|
||||
self.meta( name=name, content=content )
|
||||
else:
|
||||
raise TypeError("Metainfo should be called with a dictionary argument of name:content pairs.")
|
||||
|
||||
def scripts( self, mydict ):
|
||||
"""Only useful in html, mydict is dictionary of src:type pairs will
|
||||
be rendered as <script type='text/type' src=src></script>"""
|
||||
|
||||
if isinstance( mydict, dict ):
|
||||
for src, type in mydict.items( ):
|
||||
self.script( '', src=src, type='text/%s' % type )
|
||||
else:
|
||||
raise TypeError("Script should be given a dictionary of src:type pairs.")
|
||||
|
||||
|
||||
class _oneliner:
|
||||
"""An instance of oneliner returns a string corresponding to one element.
|
||||
This class can be used to write 'oneliners' that return a string
|
||||
immediately so there is no need to instantiate the page class."""
|
||||
|
||||
def __init__( self, case='lower' ):
|
||||
self.case = case
|
||||
|
||||
def __getattr__( self, attr ):
|
||||
if attr.startswith("__") and attr.endswith("__"):
|
||||
raise AttributeError(attr)
|
||||
return element( attr, case=self.case, parent=None )
|
||||
|
||||
oneliner = _oneliner( case='lower' )
|
||||
upper_oneliner = _oneliner( case='upper' )
|
||||
|
||||
def _argsdicts( args, mydict ):
|
||||
"""A utility generator that pads argument list and dictionary values, will only be called with len( args ) = 0, 1."""
|
||||
|
||||
if len( args ) == 0:
|
||||
args = None,
|
||||
elif len( args ) == 1:
|
||||
args = _totuple( args[0] )
|
||||
else:
|
||||
raise Exception("We should have never gotten here.")
|
||||
|
||||
mykeys = list(mydict.keys( ))
|
||||
myvalues = list(map( _totuple, list(mydict.values( )) ))
|
||||
|
||||
maxlength = max( list(map( len, [ args ] + myvalues )) )
|
||||
|
||||
for i in range( maxlength ):
|
||||
thisdict = { }
|
||||
for key, value in zip( mykeys, myvalues ):
|
||||
try:
|
||||
thisdict[ key ] = value[i]
|
||||
except IndexError:
|
||||
thisdict[ key ] = value[-1]
|
||||
try:
|
||||
thisarg = args[i]
|
||||
except IndexError:
|
||||
thisarg = args[-1]
|
||||
|
||||
yield thisarg, thisdict
|
||||
|
||||
def _totuple( x ):
|
||||
"""Utility stuff to convert string, int, float, None or anything to a usable tuple."""
|
||||
|
||||
if isinstance( x, str ):
|
||||
out = x,
|
||||
elif isinstance( x, ( int, float ) ):
|
||||
out = str( x ),
|
||||
elif x is None:
|
||||
out = None,
|
||||
else:
|
||||
out = tuple( x )
|
||||
|
||||
return out
|
||||
|
||||
def escape( text, newline=False ):
|
||||
"""Escape special html characters."""
|
||||
|
||||
if isinstance( text, str ):
|
||||
if '&' in text:
|
||||
text = text.replace( '&', '&' )
|
||||
if '>' in text:
|
||||
text = text.replace( '>', '>' )
|
||||
if '<' in text:
|
||||
text = text.replace( '<', '<' )
|
||||
if '\"' in text:
|
||||
text = text.replace( '\"', '"' )
|
||||
if '\'' in text:
|
||||
text = text.replace( '\'', '"' )
|
||||
if newline:
|
||||
if '\n' in text:
|
||||
text = text.replace( '\n', '<br>' )
|
||||
|
||||
return text
|
||||
|
||||
_escape = escape
|
||||
|
||||
def unescape( text ):
|
||||
"""Inverse of escape."""
|
||||
|
||||
if isinstance( text, str ):
|
||||
if '&' in text:
|
||||
text = text.replace( '&', '&' )
|
||||
if '>' in text:
|
||||
text = text.replace( '>', '>' )
|
||||
if '<' in text:
|
||||
text = text.replace( '<', '<' )
|
||||
if '"' in text:
|
||||
text = text.replace( '"', '\"' )
|
||||
|
||||
return text
|
||||
|
||||
class dummy:
|
||||
"""A dummy class for attaching attributes."""
|
||||
pass
|
||||
|
||||
doctype = dummy( )
|
||||
doctype.frameset = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Frameset//EN' 'http://www.w3.org/TR/html4/frameset.dtd'>"
|
||||
doctype.strict = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>"
|
||||
doctype.loose = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>"
|
||||
|
||||
class russell:
|
||||
"""A dummy class that contains anything."""
|
||||
|
||||
def __contains__( self, item ):
|
||||
return True
|
||||
|
||||
|
||||
class MarkupError( Exception ):
|
||||
"""All our exceptions subclass this."""
|
||||
def __str__( self ):
|
||||
return self.message
|
||||
|
||||
class ClosingError( MarkupError ):
|
||||
def __init__( self, tag ):
|
||||
self.message = "The element '%s' does not accept non-keyword arguments (has no closing tag)." % tag
|
||||
|
||||
class OpeningError( MarkupError ):
|
||||
def __init__( self, tag ):
|
||||
self.message = "The element '%s' can not be opened." % tag
|
||||
|
||||
class ArgumentError( MarkupError ):
|
||||
def __init__( self, tag ):
|
||||
self.message = "The element '%s' was called with more than one non-keyword argument." % tag
|
||||
|
||||
class InvalidElementError( MarkupError ):
|
||||
def __init__( self, tag, mode ):
|
||||
self.message = "The element '%s' is not valid for your mode '%s'." % ( tag, mode )
|
||||
|
||||
class DeprecationError( MarkupError ):
|
||||
def __init__( self, tag ):
|
||||
self.message = "The element '%s' is deprecated, instantiate markup.page with mode='loose_html' to allow it." % tag
|
||||
|
||||
class ModeError( MarkupError ):
|
||||
def __init__( self, mode ):
|
||||
self.message = "Mode '%s' is invalid, possible values: strict_html, loose_html, xml." % mode
|
||||
|
||||
class CustomizationError( MarkupError ):
|
||||
def __init__( self ):
|
||||
self.message = "If you customize the allowed elements, you must define both types 'onetags' and 'twotags'."
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
|
@ -1,61 +0,0 @@
|
|||
# -*- 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)
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,87 +0,0 @@
|
|||
# -*- 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 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 DataPoint(**args):
|
||||
return Element(qname = (CHARTNS,'data-point'), **args)
|
||||
|
||||
def Domain(**args):
|
||||
return Element(qname = (CHARTNS,'domain'), **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 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)
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
# -*- 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)
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
# -*- 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)
|
|
@ -1,43 +0,0 @@
|
|||
# -*- 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 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)
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
# -*- 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 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 not args.has_key('displayname'):
|
||||
e.setAttrNS(DRAWNS,'display-name', name)
|
||||
return e
|
||||
|
||||
# Autogenerated
|
||||
def A(**args):
|
||||
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):
|
||||
return DrawElement(qname = (DRAWNS,'fill-image'), **args)
|
||||
|
||||
def FloatingFrame(**args):
|
||||
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):
|
||||
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)
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Create a <text:list-style> 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
|
||||
from style import Style, TextProperties, ListLevelProperties
|
||||
from text import ListStyle,ListLevelStyleNumber,ListLevelStyleBullet
|
||||
|
||||
"""
|
||||
Create a <text:list-style> 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 <text:list-style> element for you.
|
||||
Each item in the string (or array) represents a list level
|
||||
* style for levels 1-10.</p>
|
||||
*
|
||||
* <p>If an item contains <code>1</code>, <code>I</code>,
|
||||
* <code>i</code>, <code>A</code>, or <code>a</code>, then it is presumed
|
||||
* to be a numbering style; otherwise it is a bulleted style.</p>
|
||||
"""
|
||||
|
||||
_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 :
|
|
@ -1,513 +0,0 @@
|
|||
#!/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 xml.dom
|
||||
from xml.dom.minicompat import *
|
||||
from namespaces import nsdict
|
||||
import grammar
|
||||
from attrconverters import AttrConverters
|
||||
|
||||
# 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 <rubbish> 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(StandardError):
|
||||
""" Complains if you add an element to a parent where it is not allowed """
|
||||
class IllegalText(StandardError):
|
||||
""" 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.encode()
|
||||
|
||||
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).encode('utf-8')))
|
||||
|
||||
class CDATASection(Childless, Text):
|
||||
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. (<![CDATA[)
|
||||
"""
|
||||
if self.data:
|
||||
f.write('<![CDATA[%s]]>' % self.data.replace(']]>',']]>]]><![CDATA['))
|
||||
|
||||
class Element(Node):
|
||||
""" Creates a arbitrary element and is intended to be subclassed not used on its own.
|
||||
This element is the base of every element it defines a class which resembles
|
||||
a xml-element. The main advantage of this kind of implementation is that you don't
|
||||
have to create a toXML method for every different object. Every element
|
||||
consists of an attribute, optional subelements, optional text and optional cdata.
|
||||
"""
|
||||
|
||||
nodeType = Node.ELEMENT_NODE
|
||||
namespaces = {} # Due to shallow copy this is a static variable
|
||||
|
||||
_child_node_types = (Node.ELEMENT_NODE,
|
||||
Node.PROCESSING_INSTRUCTION_NODE,
|
||||
Node.COMMENT_NODE,
|
||||
Node.TEXT_NODE,
|
||||
Node.CDATA_SECTION_NODE,
|
||||
Node.ENTITY_REFERENCE_NODE)
|
||||
|
||||
def __init__(self, attributes=None, text=None, cdata=None, qname=None, qattributes=None, check_grammar=True, **args):
|
||||
if qname is not None:
|
||||
self.qname = qname
|
||||
assert(hasattr(self, 'qname'))
|
||||
self.ownerDocument = None
|
||||
self.childNodes=[]
|
||||
self.allowed_children = grammar.allowed_children.get(self.qname)
|
||||
prefix = self.get_nsprefix(self.qname[0])
|
||||
self.tagName = prefix + ":" + self.qname[1]
|
||||
if text is not None:
|
||||
self.addText(text)
|
||||
if cdata is not None:
|
||||
self.addCDATA(cdata)
|
||||
|
||||
allowed_attrs = self.allowed_attributes()
|
||||
if allowed_attrs is not None:
|
||||
allowed_args = [ a[1].lower().replace('-','') for a in allowed_attrs]
|
||||
self.attributes={}
|
||||
# Load the attributes from the 'attributes' argument
|
||||
if attributes:
|
||||
for attr, value in attributes.items():
|
||||
self.setAttribute(attr, value)
|
||||
# Load the qualified attributes
|
||||
if qattributes:
|
||||
for attr, value in qattributes.items():
|
||||
self.setAttrNS(attr[0], attr[1], value)
|
||||
if allowed_attrs is not None:
|
||||
# Load the attributes from the 'args' argument
|
||||
for arg in args.keys():
|
||||
self.setAttribute(arg, args[arg])
|
||||
else:
|
||||
for arg in args.keys(): # If any attribute is allowed
|
||||
self.attributes[arg]=args[arg]
|
||||
if not check_grammar:
|
||||
return
|
||||
# Test that all mandatory attributes have been added.
|
||||
required = grammar.required_attributes.get(self.qname)
|
||||
if required:
|
||||
for r in required:
|
||||
if self.getAttrNS(r[0],r[1]) is None:
|
||||
raise AttributeError, "Required attribute missing: %s in <%s>" % (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 self.namespaces.has_key(namespace):
|
||||
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):
|
||||
prefix = self.get_nsprefix(namespace)
|
||||
return self.attributes.get((namespace, localpart))
|
||||
|
||||
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(' xmlns:' + prefix + '="'+ _escape(str(namespace))+'"')
|
||||
for qname in self.attributes.keys():
|
||||
prefix = self.get_nsprefix(qname[0])
|
||||
f.write(' '+_escape(str(prefix+':'+qname[1]))+'='+_quoteattr(unicode(self.attributes[qname]).encode('utf-8')))
|
||||
f.write('>')
|
||||
|
||||
def write_close_tag(self, level, f):
|
||||
f.write('</'+self.tagName+'>')
|
||||
|
||||
def toXml(self, level, f):
|
||||
""" Generate XML stream out of the tree structure """
|
||||
f.write('<'+self.tagName)
|
||||
if level == 0:
|
||||
for namespace, prefix in self.namespaces.items():
|
||||
f.write(' xmlns:' + prefix + '="'+ _escape(str(namespace))+'"')
|
||||
for qname in self.attributes.keys():
|
||||
prefix = self.get_nsprefix(qname[0])
|
||||
f.write(' '+_escape(str(prefix+':'+qname[1]))+'='+_quoteattr(unicode(self.attributes[qname]).encode('utf-8')))
|
||||
if self.childNodes:
|
||||
f.write('>')
|
||||
for element in self.childNodes:
|
||||
element.toXml(level+1,f)
|
||||
f.write('</'+self.tagName+'>')
|
||||
else:
|
||||
f.write('/>')
|
||||
|
||||
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
|
||||
|
||||
|
|
@ -1,325 +0,0 @@
|
|||
#!/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')
|
||||
)
|
|
@ -1,115 +0,0 @@
|
|||
# -*- 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)
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,112 +0,0 @@
|
|||
#!/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
|
||||
from cStringIO 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, 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
|
|
@ -1,41 +0,0 @@
|
|||
#!/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):
|
||||
#
|
||||
#
|
||||
|
||||
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)
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
# -*- 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)
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
# -*- 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):
|
||||
return Element(qname = (METANS,'template'), **args)
|
||||
|
||||
def UserDefined(**args):
|
||||
return Element(qname = (METANS,'user-defined'), **args)
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
# -*- 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):
|
||||
#
|
||||
TOOLSVERSION = u"ODFPY/0.9.3"
|
||||
|
||||
ANIMNS = u"urn:oasis:names:tc:opendocument:xmlns:animation:1.0"
|
||||
DBNS = u"urn:oasis:names:tc:opendocument:xmlns:database:1.0"
|
||||
CHARTNS = u"urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
|
||||
CONFIGNS = u"urn:oasis:names:tc:opendocument:xmlns:config:1.0"
|
||||
#DBNS = u"http://openoffice.org/2004/database"
|
||||
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"
|
||||
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"
|
||||
OOONS = u"http://openoffice.org/2004/office"
|
||||
OOOWNS = u"http://openoffice.org/2004/writer"
|
||||
OOOCNS = u"http://openoffice.org/2004/calc"
|
||||
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"
|
||||
TEXTNS = u"urn:oasis:names:tc:opendocument:xmlns:text:1.0"
|
||||
XFORMSNS = u"http://www.w3.org/2002/xforms"
|
||||
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',
|
||||
CONFIGNS: u'config',
|
||||
DBNS: u'db',
|
||||
DCNS: u'dc',
|
||||
DOMNS: u'dom',
|
||||
DR3DNS: u'dr3d',
|
||||
DRAWNS: u'draw',
|
||||
FIELDNS: u'field',
|
||||
FONS: u'fo',
|
||||
FORMNS: u'form',
|
||||
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',
|
||||
TEXTNS: u'text',
|
||||
XFORMSNS: u'xforms',
|
||||
XLINKNS: u'xlink',
|
||||
XMLNS: u'xml',
|
||||
XSDNS: u'xsd',
|
||||
XSINS: u'xsi',
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
# -*- 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)
|
||||
|
|
@ -1,579 +0,0 @@
|
|||
# -*- 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)
|
File diff suppressed because it is too large
Load Diff
|
@ -1,115 +0,0 @@
|
|||
#!/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):
|
||||
#
|
||||
|
||||
# This script lists the content of the manifest.xml file
|
||||
import zipfile
|
||||
from xml.sax import make_parser,handler
|
||||
from xml.sax.xmlreader import InputSource
|
||||
import xml.sax.saxutils
|
||||
from cStringIO import StringIO
|
||||
|
||||
MANIFESTNS="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#
|
||||
# ODFMANIFESTHANDLER
|
||||
#
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class ODFManifestHandler(handler.ContentHandler):
|
||||
""" The ODFManifestHandler parses a manifest file and produces a list of
|
||||
content """
|
||||
|
||||
def __init__(self):
|
||||
self.manifest = {}
|
||||
|
||||
# Tags
|
||||
# FIXME: Also handle encryption data
|
||||
self.elements = {
|
||||
(MANIFESTNS, 'file-entry'): (self.s_file_entry, self.donothing),
|
||||
}
|
||||
|
||||
def handle_starttag(self, tag, method, attrs):
|
||||
method(tag,attrs)
|
||||
|
||||
def handle_endtag(self, tag, method):
|
||||
method(tag)
|
||||
|
||||
def startElementNS(self, tag, qname, attrs):
|
||||
method = self.elements.get(tag, (None, None))[0]
|
||||
if method:
|
||||
self.handle_starttag(tag, method, attrs)
|
||||
else:
|
||||
self.unknown_starttag(tag,attrs)
|
||||
|
||||
def endElementNS(self, tag, qname):
|
||||
method = self.elements.get(tag, (None, None))[1]
|
||||
if method:
|
||||
self.handle_endtag(tag, method)
|
||||
else:
|
||||
self.unknown_endtag(tag)
|
||||
|
||||
def unknown_starttag(self, tag, attrs):
|
||||
pass
|
||||
|
||||
def unknown_endtag(self, tag):
|
||||
pass
|
||||
|
||||
def donothing(self, tag, attrs=None):
|
||||
pass
|
||||
|
||||
def s_file_entry(self, tag, attrs):
|
||||
m = attrs.get((MANIFESTNS, 'media-type'),"application/octet-stream")
|
||||
p = attrs.get((MANIFESTNS, 'full-path'))
|
||||
self.manifest[p] = { 'media-type':m, 'full-path':p }
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#
|
||||
# Reading the file
|
||||
#
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def manifestlist(manifestxml):
|
||||
odhandler = ODFManifestHandler()
|
||||
parser = make_parser()
|
||||
parser.setFeature(handler.feature_namespaces, 1)
|
||||
parser.setContentHandler(odhandler)
|
||||
parser.setErrorHandler(handler.ErrorHandler())
|
||||
|
||||
inpsrc = InputSource()
|
||||
inpsrc.setByteStream(StringIO(manifestxml))
|
||||
parser.parse(inpsrc)
|
||||
|
||||
return odhandler.manifest
|
||||
|
||||
def odfmanifest(odtfile):
|
||||
z = zipfile.ZipFile(odtfile)
|
||||
manifest = z.read('META-INF/manifest.xml')
|
||||
z.close()
|
||||
return manifestlist(manifest)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
result = odfmanifest(sys.argv[1])
|
||||
for file in result.values():
|
||||
print "%-40s %-40s" % (file['media-type'], file['full-path'])
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
# -*- 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 OFFICENS
|
||||
from element import Element
|
||||
from draw import StyleRefElement
|
||||
|
||||
# Autogenerated
|
||||
def Annotation(**args):
|
||||
return StyleRefElement(qname = (OFFICENS,'annotation'), **args)
|
||||
|
||||
def AutomaticStyles(**args):
|
||||
return Element(qname = (OFFICENS, 'automatic-styles'), **args)
|
||||
|
||||
def BinaryData(**args):
|
||||
return Element(qname = (OFFICENS,'binary-data'), **args)
|
||||
|
||||
def Body(**args):
|
||||
return Element(qname = (OFFICENS, 'body'), **args)
|
||||
|
||||
def ChangeInfo(**args):
|
||||
return Element(qname = (OFFICENS,'change-info'), **args)
|
||||
|
||||
def Chart(**args):
|
||||
return Element(qname = (OFFICENS,'chart'), **args)
|
||||
|
||||
def DdeSource(**args):
|
||||
return Element(qname = (OFFICENS,'dde-source'), **args)
|
||||
|
||||
def Document(version="1.1", **args):
|
||||
return Element(qname = (OFFICENS,'document'), version=version, **args)
|
||||
|
||||
def DocumentContent(version="1.1", **args):
|
||||
return Element(qname = (OFFICENS, 'document-content'), version=version, **args)
|
||||
|
||||
def DocumentMeta(version="1.1", **args):
|
||||
return Element(qname = (OFFICENS, 'document-meta'), version=version, **args)
|
||||
|
||||
def DocumentSettings(version="1.1", **args):
|
||||
return Element(qname = (OFFICENS, 'document-settings'), version=version, **args)
|
||||
|
||||
def DocumentStyles(version="1.1", **args):
|
||||
return Element(qname = (OFFICENS, 'document-styles'), version=version, **args)
|
||||
|
||||
def Drawing(**args):
|
||||
return Element(qname = (OFFICENS,'drawing'), **args)
|
||||
|
||||
def EventListeners(**args):
|
||||
return Element(qname = (OFFICENS,'event-listeners'), **args)
|
||||
|
||||
def FontFaceDecls(**args):
|
||||
return Element(qname = (OFFICENS, 'font-face-decls'), **args)
|
||||
|
||||
def Forms(**args):
|
||||
return Element(qname = (OFFICENS,'forms'), **args)
|
||||
|
||||
def Image(**args):
|
||||
return Element(qname = (OFFICENS,'image'), **args)
|
||||
|
||||
def MasterStyles(**args):
|
||||
return Element(qname = (OFFICENS, 'master-styles'), **args)
|
||||
|
||||
def Meta(**args):
|
||||
return Element(qname = (OFFICENS, 'meta'), **args)
|
||||
|
||||
def Presentation(**args):
|
||||
return Element(qname = (OFFICENS,'presentation'), **args)
|
||||
|
||||
def Script(**args):
|
||||
return Element(qname = (OFFICENS, 'script'), **args)
|
||||
|
||||
def Scripts(**args):
|
||||
return Element(qname = (OFFICENS, 'scripts'), **args)
|
||||
|
||||
def Settings(**args):
|
||||
return Element(qname = (OFFICENS, 'settings'), **args)
|
||||
|
||||
def Spreadsheet(**args):
|
||||
return Element(qname = (OFFICENS, 'spreadsheet'), **args)
|
||||
|
||||
def Styles(**args):
|
||||
return Element(qname = (OFFICENS, 'styles'), **args)
|
||||
|
||||
def Text(**args):
|
||||
return Element(qname = (OFFICENS, 'text'), **args)
|
||||
|
||||
# Autogenerated end
|
|
@ -1,654 +0,0 @@
|
|||
# -*- 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):
|
||||
#
|
||||
|
||||
__doc__="""Use OpenDocument to generate your documents."""
|
||||
|
||||
import zipfile, time, sys, mimetypes, copy
|
||||
from cStringIO import StringIO
|
||||
from namespaces import *
|
||||
import manifest, meta
|
||||
from office import *
|
||||
import element
|
||||
from attrconverters import make_NCName
|
||||
from xml.sax.xmlreader import InputSource
|
||||
from odfmanifest import manifestlist
|
||||
|
||||
__version__= TOOLSVERSION
|
||||
|
||||
_XMLPROLOGUE = u"<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||
|
||||
UNIXPERMS = 0100644 << 16L # -rw-r--r--
|
||||
|
||||
IS_FILENAME = 0
|
||||
IS_IMAGE = 1
|
||||
# We need at least Python 2.2
|
||||
assert sys.version_info[0]>=2 and sys.version_info[1] >= 2
|
||||
|
||||
#sys.setrecursionlimit(100)
|
||||
#The recursion limit is set conservative so mistakes like
|
||||
# s=content() s.addElement(s) won't eat up too much processor time.
|
||||
|
||||
odmimetypes = {
|
||||
'application/vnd.oasis.opendocument.text': '.odt',
|
||||
'application/vnd.oasis.opendocument.text-template': '.ott',
|
||||
'application/vnd.oasis.opendocument.graphics': '.odg',
|
||||
'application/vnd.oasis.opendocument.graphics-template': '.otg',
|
||||
'application/vnd.oasis.opendocument.presentation': '.odp',
|
||||
'application/vnd.oasis.opendocument.presentation-template': '.otp',
|
||||
'application/vnd.oasis.opendocument.spreadsheet': '.ods',
|
||||
'application/vnd.oasis.opendocument.spreadsheet-template': '.ots',
|
||||
'application/vnd.oasis.opendocument.chart': '.odc',
|
||||
'application/vnd.oasis.opendocument.chart-template': '.otc',
|
||||
'application/vnd.oasis.opendocument.image': '.odi',
|
||||
'application/vnd.oasis.opendocument.image-template': '.oti',
|
||||
'application/vnd.oasis.opendocument.formula': '.odf',
|
||||
'application/vnd.oasis.opendocument.formula-template': '.otf',
|
||||
'application/vnd.oasis.opendocument.text-master': '.odm',
|
||||
'application/vnd.oasis.opendocument.text-web': '.oth',
|
||||
}
|
||||
|
||||
class OpaqueObject:
|
||||
def __init__(self, filename, mediatype, content=None):
|
||||
self.mediatype = mediatype
|
||||
self.filename = filename
|
||||
self.content = content
|
||||
|
||||
class OpenDocument:
|
||||
""" A class to hold the content of an OpenDocument document
|
||||
Use the xml method to write the XML
|
||||
source to the screen or to a file
|
||||
d = OpenDocument(mimetype)
|
||||
fd.write(d.xml())
|
||||
"""
|
||||
thumbnail = None
|
||||
|
||||
def __init__(self, mimetype, add_generator=True):
|
||||
self.mimetype = mimetype
|
||||
self.childobjects = []
|
||||
self._extra = []
|
||||
self.folder = "" # Always empty for toplevel documents
|
||||
self.topnode = Document(mimetype=self.mimetype)
|
||||
self.topnode.ownerDocument = self
|
||||
|
||||
self.clear_caches()
|
||||
|
||||
self.Pictures = {}
|
||||
self.meta = Meta()
|
||||
self.topnode.addElement(self.meta)
|
||||
if add_generator:
|
||||
self.meta.addElement(meta.Generator(text=TOOLSVERSION))
|
||||
self.scripts = Scripts()
|
||||
self.topnode.addElement(self.scripts)
|
||||
self.fontfacedecls = FontFaceDecls()
|
||||
self.topnode.addElement(self.fontfacedecls)
|
||||
self.settings = Settings()
|
||||
self.topnode.addElement(self.settings)
|
||||
self.styles = Styles()
|
||||
self.topnode.addElement(self.styles)
|
||||
self.automaticstyles = AutomaticStyles()
|
||||
self.topnode.addElement(self.automaticstyles)
|
||||
self.masterstyles = MasterStyles()
|
||||
self.topnode.addElement(self.masterstyles)
|
||||
self.body = Body()
|
||||
self.topnode.addElement(self.body)
|
||||
|
||||
def rebuild_caches(self, node=None):
|
||||
if node is None: node = self.topnode
|
||||
self.build_caches(node)
|
||||
for e in node.childNodes:
|
||||
if e.nodeType == element.Node.ELEMENT_NODE:
|
||||
self.rebuild_caches(e)
|
||||
|
||||
def clear_caches(self):
|
||||
self.element_dict = {}
|
||||
self._styles_dict = {}
|
||||
self._styles_ooo_fix = {}
|
||||
|
||||
def build_caches(self, element):
|
||||
""" Called from element.py
|
||||
"""
|
||||
if not self.element_dict.has_key(element.qname):
|
||||
self.element_dict[element.qname] = []
|
||||
self.element_dict[element.qname].append(element)
|
||||
if element.qname == (STYLENS, u'style'):
|
||||
self.__register_stylename(element) # Add to style dictionary
|
||||
styleref = element.getAttrNS(TEXTNS,u'style-name')
|
||||
if styleref is not None and self._styles_ooo_fix.has_key(styleref):
|
||||
element.setAttrNS(TEXTNS,u'style-name', self._styles_ooo_fix[styleref])
|
||||
|
||||
def __register_stylename(self, element):
|
||||
''' Register a style. But there are three style dictionaries:
|
||||
office:styles, office:automatic-styles and office:master-styles
|
||||
Chapter 14
|
||||
'''
|
||||
name = element.getAttrNS(STYLENS, u'name')
|
||||
if name is None:
|
||||
return
|
||||
if element.parentNode.qname in ((OFFICENS,u'styles'), (OFFICENS,u'automatic-styles')):
|
||||
if self._styles_dict.has_key(name):
|
||||
newname = 'M'+name # Rename style
|
||||
self._styles_ooo_fix[name] = newname
|
||||
# From here on all references to the old name will refer to the new one
|
||||
name = newname
|
||||
element.setAttrNS(STYLENS, u'name', name)
|
||||
self._styles_dict[name] = element
|
||||
|
||||
def toXml(self, filename=''):
|
||||
xml=StringIO()
|
||||
xml.write(_XMLPROLOGUE)
|
||||
self.body.toXml(0, xml)
|
||||
if not filename:
|
||||
return xml.getvalue()
|
||||
else:
|
||||
f=file(filename,'w')
|
||||
f.write(xml.getvalue())
|
||||
f.close()
|
||||
|
||||
def xml(self):
|
||||
""" Generates the full document as an XML file
|
||||
Always written as a bytestream in UTF-8 encoding
|
||||
"""
|
||||
self.__replaceGenerator()
|
||||
xml=StringIO()
|
||||
xml.write(_XMLPROLOGUE)
|
||||
self.topnode.toXml(0, xml)
|
||||
return xml.getvalue()
|
||||
|
||||
|
||||
def contentxml(self):
|
||||
""" Generates the content.xml file
|
||||
Always written as a bytestream in UTF-8 encoding
|
||||
"""
|
||||
xml=StringIO()
|
||||
xml.write(_XMLPROLOGUE)
|
||||
x = DocumentContent()
|
||||
x.write_open_tag(0, xml)
|
||||
if self.scripts.hasChildNodes():
|
||||
self.scripts.toXml(1, xml)
|
||||
if self.fontfacedecls.hasChildNodes():
|
||||
self.fontfacedecls.toXml(1, xml)
|
||||
a = AutomaticStyles()
|
||||
stylelist = self._used_auto_styles([self.styles, self.automaticstyles, self.body])
|
||||
if len(stylelist) > 0:
|
||||
a.write_open_tag(1, xml)
|
||||
for s in stylelist:
|
||||
s.toXml(2, xml)
|
||||
a.write_close_tag(1, xml)
|
||||
else:
|
||||
a.toXml(1, xml)
|
||||
self.body.toXml(1, xml)
|
||||
x.write_close_tag(0, xml)
|
||||
return xml.getvalue()
|
||||
|
||||
def __manifestxml(self):
|
||||
""" Generates the manifest.xml file
|
||||
The self.manifest isn't avaible unless the document is being saved
|
||||
"""
|
||||
xml=StringIO()
|
||||
xml.write(_XMLPROLOGUE)
|
||||
self.manifest.toXml(0,xml)
|
||||
return xml.getvalue()
|
||||
|
||||
def metaxml(self):
|
||||
""" Generates the meta.xml file """
|
||||
self.__replaceGenerator()
|
||||
x = DocumentMeta()
|
||||
x.addElement(self.meta)
|
||||
xml=StringIO()
|
||||
xml.write(_XMLPROLOGUE)
|
||||
x.toXml(0,xml)
|
||||
return xml.getvalue()
|
||||
|
||||
def settingsxml(self):
|
||||
""" Generates the settings.xml file """
|
||||
x = DocumentSettings()
|
||||
x.addElement(self.settings)
|
||||
xml=StringIO()
|
||||
xml.write(_XMLPROLOGUE)
|
||||
x.toXml(0,xml)
|
||||
return xml.getvalue()
|
||||
|
||||
def _parseoneelement(self, top, stylenamelist):
|
||||
""" Finds references to style objects in master-styles
|
||||
and add the style name to the style list if not already there.
|
||||
Recursive
|
||||
"""
|
||||
for e in top.childNodes:
|
||||
if e.nodeType == element.Node.ELEMENT_NODE:
|
||||
for styleref in ( (DRAWNS,u'style-name'),
|
||||
(DRAWNS,u'text-style-name'),
|
||||
(PRESENTATIONNS,u'style-name'),
|
||||
(STYLENS,u'data-style-name'),
|
||||
(STYLENS,u'list-style-name'),
|
||||
(STYLENS,u'page-layout-name'),
|
||||
(STYLENS,u'style-name'),
|
||||
(TABLENS,u'default-cell-style-name'),
|
||||
(TABLENS,u'style-name'),
|
||||
(TEXTNS,u'style-name') ):
|
||||
if e.getAttrNS(styleref[0],styleref[1]):
|
||||
stylename = e.getAttrNS(styleref[0],styleref[1])
|
||||
if stylename not in stylenamelist:
|
||||
stylenamelist.append(stylename)
|
||||
stylenamelist = self._parseoneelement(e, stylenamelist)
|
||||
return stylenamelist
|
||||
|
||||
def _used_auto_styles(self, segments):
|
||||
""" Loop through the masterstyles elements, and find the automatic
|
||||
styles that are used. These will be added to the automatic-styles
|
||||
element in styles.xml
|
||||
"""
|
||||
stylenamelist = []
|
||||
for top in segments:
|
||||
stylenamelist = self._parseoneelement(top, stylenamelist)
|
||||
stylelist = []
|
||||
for e in self.automaticstyles.childNodes:
|
||||
if e.getAttrNS(STYLENS,u'name') in stylenamelist:
|
||||
stylelist.append(e)
|
||||
return stylelist
|
||||
|
||||
def stylesxml(self):
|
||||
""" Generates the styles.xml file """
|
||||
xml=StringIO()
|
||||
xml.write(_XMLPROLOGUE)
|
||||
x = DocumentStyles()
|
||||
x.write_open_tag(0, xml)
|
||||
if self.fontfacedecls.hasChildNodes():
|
||||
self.fontfacedecls.toXml(1, xml)
|
||||
self.styles.toXml(1, xml)
|
||||
a = AutomaticStyles()
|
||||
a.write_open_tag(1, xml)
|
||||
for s in self._used_auto_styles([self.masterstyles]):
|
||||
s.toXml(2, xml)
|
||||
a.write_close_tag(1, xml)
|
||||
if self.masterstyles.hasChildNodes():
|
||||
self.masterstyles.toXml(1, xml)
|
||||
x.write_close_tag(0, xml)
|
||||
return xml.getvalue()
|
||||
|
||||
def addPicture(self, filename, mediatype=None, content=None):
|
||||
""" Add a picture
|
||||
It uses the same convention as OOo, in that it saves the picture in
|
||||
the zipfile in the subdirectory 'Pictures'
|
||||
If passed a file ptr, mediatype must be set
|
||||
"""
|
||||
if content is None:
|
||||
if mediatype is None:
|
||||
mediatype, encoding = mimetypes.guess_type(filename)
|
||||
if mediatype is None:
|
||||
mediatype = ''
|
||||
try: ext = filename[filename.rindex('.'):]
|
||||
except: ext=''
|
||||
else:
|
||||
ext = mimetypes.guess_extension(mediatype)
|
||||
manifestfn = "Pictures/%0.0f%s" % ((time.time()*10000000000), ext)
|
||||
self.Pictures[manifestfn] = (IS_FILENAME, filename, mediatype)
|
||||
else:
|
||||
manifestfn = filename
|
||||
self.Pictures[manifestfn] = (IS_IMAGE, content, mediatype)
|
||||
return manifestfn
|
||||
|
||||
def addPictureFromFile(self, filename, mediatype=None):
|
||||
""" Add a picture
|
||||
It uses the same convention as OOo, in that it saves the picture in
|
||||
the zipfile in the subdirectory 'Pictures'.
|
||||
If mediatype is not given, it will be guessed from the filename
|
||||
extension.
|
||||
"""
|
||||
if mediatype is None:
|
||||
mediatype, encoding = mimetypes.guess_type(filename)
|
||||
if mediatype is None:
|
||||
mediatype = ''
|
||||
try: ext = filename[filename.rindex('.'):]
|
||||
except ValueError: ext=''
|
||||
else:
|
||||
ext = mimetypes.guess_extension(mediatype)
|
||||
manifestfn = "Pictures/%0.0f%s" % ((time.time()*10000000000), ext)
|
||||
self.Pictures[manifestfn] = (IS_FILENAME, filename, mediatype)
|
||||
return manifestfn
|
||||
|
||||
def addPictureFromString(self, content, mediatype):
|
||||
""" Add a picture
|
||||
It uses the same convention as OOo, in that it saves the picture in
|
||||
the zipfile in the subdirectory 'Pictures'. The content variable
|
||||
is a string that contains the binary image data. The mediatype
|
||||
indicates the image format.
|
||||
"""
|
||||
ext = mimetypes.guess_extension(mediatype)
|
||||
manifestfn = "Pictures/%0.0f%s" % ((time.time()*10000000000), ext)
|
||||
self.Pictures[manifestfn] = (IS_IMAGE, content, mediatype)
|
||||
return manifestfn
|
||||
|
||||
def addThumbnail(self, filecontent=None):
|
||||
""" Add a fixed thumbnail
|
||||
The thumbnail in the library is big, so this is pretty useless.
|
||||
"""
|
||||
if filecontent is None:
|
||||
import thumbnail
|
||||
self.thumbnail = thumbnail.thumbnail()
|
||||
else:
|
||||
self.thumbnail = filecontent
|
||||
|
||||
def addObject(self, document, objectname=None):
|
||||
""" Adds an object (subdocument). The object must be an OpenDocument class
|
||||
The return value will be the folder in the zipfile the object is stored in
|
||||
"""
|
||||
self.childobjects.append(document)
|
||||
if objectname is None:
|
||||
document.folder = "%s/Object %d" % (self.folder, len(self.childobjects))
|
||||
else:
|
||||
document.folder = objectname
|
||||
return ".%s" % document.folder
|
||||
|
||||
def _savePictures(self, object, folder):
|
||||
hasPictures = False
|
||||
for arcname, picturerec in object.Pictures.items():
|
||||
what_it_is, fileobj, mediatype = picturerec
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath="%s%s" % ( folder ,arcname), mediatype=mediatype))
|
||||
hasPictures = True
|
||||
if what_it_is == IS_FILENAME:
|
||||
self._z.write(fileobj, arcname, zipfile.ZIP_STORED)
|
||||
else:
|
||||
zi = zipfile.ZipInfo(str(arcname), self._now)
|
||||
zi.compress_type = zipfile.ZIP_STORED
|
||||
zi.external_attr = UNIXPERMS
|
||||
self._z.writestr(zi, fileobj)
|
||||
# According to section 17.7.3 in ODF 1.1, the pictures folder should not have a manifest entry
|
||||
# if hasPictures:
|
||||
# self.manifest.addElement(manifest.FileEntry(fullpath="%sPictures/" % folder, mediatype=""))
|
||||
# Look in subobjects
|
||||
subobjectnum = 1
|
||||
for subobject in object.childobjects:
|
||||
self._savePictures(subobject,'%sObject %d/' % (folder, subobjectnum))
|
||||
subobjectnum += 1
|
||||
|
||||
def __replaceGenerator(self):
|
||||
""" Section 3.1.1: The application MUST NOT export the original identifier
|
||||
belonging to the application that created the document.
|
||||
"""
|
||||
for m in self.meta.childNodes[:]:
|
||||
if m.qname == (METANS, u'generator'):
|
||||
self.meta.removeChild(m)
|
||||
self.meta.addElement(meta.Generator(text=TOOLSVERSION))
|
||||
|
||||
def save(self, outputfile, addsuffix=False):
|
||||
""" Save the document under the filename.
|
||||
If the filename is '-' then save to stdout
|
||||
"""
|
||||
if outputfile == '-':
|
||||
outputfp = zipfile.ZipFile(sys.stdout,"w")
|
||||
else:
|
||||
if addsuffix:
|
||||
outputfile = outputfile + odmimetypes.get(self.mimetype,'.xxx')
|
||||
outputfp = zipfile.ZipFile(outputfile, "w")
|
||||
self.__zipwrite(outputfp)
|
||||
outputfp.close()
|
||||
|
||||
def write(self, outputfp):
|
||||
""" User API to write the ODF file to an open file descriptor
|
||||
Writes the ZIP format
|
||||
"""
|
||||
zipoutputfp = zipfile.ZipFile(outputfp,"w")
|
||||
self.__zipwrite(zipoutputfp)
|
||||
|
||||
def __zipwrite(self, outputfp):
|
||||
""" Write the document to an open file pointer
|
||||
This is where the real work is done
|
||||
"""
|
||||
self._z = outputfp
|
||||
self._now = time.localtime()[:6]
|
||||
self.manifest = manifest.Manifest()
|
||||
|
||||
# Write mimetype
|
||||
zi = zipfile.ZipInfo('mimetype', self._now)
|
||||
zi.compress_type = zipfile.ZIP_STORED
|
||||
zi.external_attr = UNIXPERMS
|
||||
self._z.writestr(zi, self.mimetype)
|
||||
|
||||
self._saveXmlObjects(self,"")
|
||||
|
||||
# Write pictures
|
||||
self._savePictures(self,"")
|
||||
|
||||
# Write the thumbnail
|
||||
if self.thumbnail is not None:
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath="Thumbnails/", mediatype=''))
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath="Thumbnails/thumbnail.png", mediatype=''))
|
||||
zi = zipfile.ZipInfo("Thumbnails/thumbnail.png", self._now)
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.external_attr = UNIXPERMS
|
||||
self._z.writestr(zi, self.thumbnail)
|
||||
|
||||
# Write any extra files
|
||||
for op in self._extra:
|
||||
if op.filename == "META-INF/documentsignatures.xml": continue # Don't save signatures
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath=op.filename, mediatype=op.mediatype))
|
||||
zi = zipfile.ZipInfo(op.filename.encode('utf-8'), self._now)
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.external_attr = UNIXPERMS
|
||||
if op.content is not None:
|
||||
self._z.writestr(zi, op.content)
|
||||
# Write manifest
|
||||
zi = zipfile.ZipInfo("META-INF/manifest.xml", self._now)
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.external_attr = UNIXPERMS
|
||||
self._z.writestr(zi, self.__manifestxml() )
|
||||
del self._z
|
||||
del self._now
|
||||
del self.manifest
|
||||
|
||||
|
||||
def _saveXmlObjects(self, object, folder):
|
||||
if self == object:
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath="/", mediatype=object.mimetype))
|
||||
else:
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath=folder, mediatype=object.mimetype))
|
||||
# Write styles
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath="%sstyles.xml" % folder, mediatype="text/xml"))
|
||||
zi = zipfile.ZipInfo("%sstyles.xml" % folder, self._now)
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.external_attr = UNIXPERMS
|
||||
self._z.writestr(zi, object.stylesxml() )
|
||||
|
||||
# Write content
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath="%scontent.xml" % folder, mediatype="text/xml"))
|
||||
zi = zipfile.ZipInfo("%scontent.xml" % folder, self._now)
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.external_attr = UNIXPERMS
|
||||
self._z.writestr(zi, object.contentxml() )
|
||||
|
||||
# Write settings
|
||||
if object.settings.hasChildNodes():
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath="%ssettings.xml" % folder, mediatype="text/xml"))
|
||||
zi = zipfile.ZipInfo("%ssettings.xml" % folder, self._now)
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.external_attr = UNIXPERMS
|
||||
self._z.writestr(zi, object.settingsxml() )
|
||||
|
||||
# Write meta
|
||||
if self == object:
|
||||
self.manifest.addElement(manifest.FileEntry(fullpath="meta.xml", mediatype="text/xml"))
|
||||
zi = zipfile.ZipInfo("meta.xml", self._now)
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.external_attr = UNIXPERMS
|
||||
self._z.writestr(zi, object.metaxml() )
|
||||
|
||||
# Write subobjects
|
||||
subobjectnum = 1
|
||||
for subobject in object.childobjects:
|
||||
self._saveXmlObjects(subobject, '%sObject %d/' % (folder, subobjectnum))
|
||||
subobjectnum += 1
|
||||
|
||||
# Document's DOM methods
|
||||
def createElement(self, element):
|
||||
""" Inconvenient interface to create an element, but follows XML-DOM.
|
||||
Does not allow attributes as argument, therefore can't check grammar.
|
||||
"""
|
||||
return element(check_grammar=False)
|
||||
|
||||
def createTextNode(self, data):
|
||||
""" Method to create a text node """
|
||||
return element.Text(data)
|
||||
|
||||
def createCDATASection(self, data):
|
||||
""" Method to create a CDATA section """
|
||||
return element.CDATASection(cdata)
|
||||
|
||||
def getMediaType(self):
|
||||
""" Returns the media type """
|
||||
return self.mimetype
|
||||
|
||||
def getStyleByName(self, name):
|
||||
""" Finds a style object based on the name """
|
||||
ncname = make_NCName(name)
|
||||
if self._styles_dict == {}:
|
||||
self.rebuild_caches()
|
||||
return self._styles_dict.get(ncname, None)
|
||||
|
||||
def getElementsByType(self, element):
|
||||
""" Gets elements based on the type, which is function from text.py, draw.py etc. """
|
||||
obj = element(check_grammar=False)
|
||||
if self.element_dict == {}:
|
||||
self.rebuild_caches()
|
||||
return self.element_dict.get(obj.qname, [])
|
||||
|
||||
# Convenience functions
|
||||
def OpenDocumentChart():
|
||||
""" Creates a chart document """
|
||||
doc = OpenDocument('application/vnd.oasis.opendocument.chart')
|
||||
doc.chart = Chart()
|
||||
doc.body.addElement(doc.chart)
|
||||
return doc
|
||||
|
||||
def OpenDocumentDrawing():
|
||||
""" Creates a drawing document """
|
||||
doc = OpenDocument('application/vnd.oasis.opendocument.graphics')
|
||||
doc.drawing = Drawing()
|
||||
doc.body.addElement(doc.drawing)
|
||||
return doc
|
||||
|
||||
def OpenDocumentImage():
|
||||
""" Creates an image document """
|
||||
doc = OpenDocument('application/vnd.oasis.opendocument.image')
|
||||
doc.image = Image()
|
||||
doc.body.addElement(doc.image)
|
||||
return doc
|
||||
|
||||
def OpenDocumentPresentation():
|
||||
""" Creates a presentation document """
|
||||
doc = OpenDocument('application/vnd.oasis.opendocument.presentation')
|
||||
doc.presentation = Presentation()
|
||||
doc.body.addElement(doc.presentation)
|
||||
return doc
|
||||
|
||||
def OpenDocumentSpreadsheet():
|
||||
""" Creates a spreadsheet document """
|
||||
doc = OpenDocument('application/vnd.oasis.opendocument.spreadsheet')
|
||||
doc.spreadsheet = Spreadsheet()
|
||||
doc.body.addElement(doc.spreadsheet)
|
||||
return doc
|
||||
|
||||
def OpenDocumentText():
|
||||
""" Creates a text document """
|
||||
doc = OpenDocument('application/vnd.oasis.opendocument.text')
|
||||
doc.text = Text()
|
||||
doc.body.addElement(doc.text)
|
||||
return doc
|
||||
|
||||
def OpenDocumentTextMaster():
|
||||
""" Creates a text master document """
|
||||
doc = OpenDocument('application/vnd.oasis.opendocument.text-master')
|
||||
doc.text = Text()
|
||||
doc.body.addElement(doc.text)
|
||||
return doc
|
||||
|
||||
def __loadxmlparts(z, manifest, doc, objectpath):
|
||||
from load import LoadParser
|
||||
from xml.sax import make_parser, handler
|
||||
|
||||
for xmlfile in (objectpath+'settings.xml', objectpath+'meta.xml', objectpath+'content.xml', objectpath+'styles.xml'):
|
||||
if not manifest.has_key(xmlfile):
|
||||
continue
|
||||
try:
|
||||
xmlpart = z.read(xmlfile)
|
||||
doc._parsing = xmlfile
|
||||
|
||||
parser = make_parser()
|
||||
parser.setFeature(handler.feature_namespaces, 1)
|
||||
parser.setContentHandler(LoadParser(doc))
|
||||
parser.setErrorHandler(handler.ErrorHandler())
|
||||
|
||||
inpsrc = InputSource()
|
||||
inpsrc.setByteStream(StringIO(xmlpart))
|
||||
parser.parse(inpsrc)
|
||||
del doc._parsing
|
||||
except KeyError, v: pass
|
||||
|
||||
def load(odffile):
|
||||
""" Load an ODF file into memory
|
||||
Returns a reference to the structure
|
||||
"""
|
||||
z = zipfile.ZipFile(odffile)
|
||||
mimetype = z.read('mimetype')
|
||||
doc = OpenDocument(mimetype, add_generator=False)
|
||||
|
||||
# Look in the manifest file to see if which of the four files there are
|
||||
manifestpart = z.read('META-INF/manifest.xml')
|
||||
manifest = manifestlist(manifestpart)
|
||||
__loadxmlparts(z, manifest, doc, '')
|
||||
for mentry,mvalue in manifest.items():
|
||||
if mentry[:9] == "Pictures/" and len(mentry) > 9:
|
||||
doc.addPicture(mvalue['full-path'], mvalue['media-type'], z.read(mentry))
|
||||
elif mentry == "Thumbnails/thumbnail.png":
|
||||
doc.addThumbnail(z.read(mentry))
|
||||
elif mentry in ('settings.xml', 'meta.xml', 'content.xml', 'styles.xml'):
|
||||
pass
|
||||
# Load subobjects into structure
|
||||
elif mentry[:7] == "Object " and len(mentry) < 11 and mentry[-1] == "/":
|
||||
subdoc = OpenDocument(mvalue['media-type'], add_generator=False)
|
||||
doc.addObject(subdoc, "/" + mentry[:-1])
|
||||
__loadxmlparts(z, manifest, subdoc, mentry)
|
||||
elif mentry[:7] == "Object ":
|
||||
pass # Don't load subobjects as opaque objects
|
||||
else:
|
||||
if mvalue['full-path'][-1] == '/':
|
||||
doc._extra.append(OpaqueObject(mvalue['full-path'], mvalue['media-type'], None))
|
||||
else:
|
||||
doc._extra.append(OpaqueObject(mvalue['full-path'], mvalue['media-type'], z.read(mentry)))
|
||||
# Add the SUN junk here to the struct somewhere
|
||||
# It is cached data, so it can be out-of-date
|
||||
z.close()
|
||||
b = doc.getElementsByType(Body)
|
||||
if mimetype[:39] == 'application/vnd.oasis.opendocument.text':
|
||||
doc.text = b[0].firstChild
|
||||
elif mimetype[:43] == 'application/vnd.oasis.opendocument.graphics':
|
||||
doc.graphics = b[0].firstChild
|
||||
elif mimetype[:47] == 'application/vnd.oasis.opendocument.presentation':
|
||||
doc.presentation = b[0].firstChild
|
||||
elif mimetype[:46] == 'application/vnd.oasis.opendocument.spreadsheet':
|
||||
doc.spreadsheet = b[0].firstChild
|
||||
elif mimetype[:40] == 'application/vnd.oasis.opendocument.chart':
|
||||
doc.chart = b[0].firstChild
|
||||
elif mimetype[:40] == 'application/vnd.oasis.opendocument.image':
|
||||
doc.image = b[0].firstChild
|
||||
elif mimetype[:42] == 'application/vnd.oasis.opendocument.formula':
|
||||
doc.formula = b[0].firstChild
|
||||
return doc
|
||||
|
||||
# vim: set expandtab sw=4 :
|
|
@ -1,85 +0,0 @@
|
|||
# -*- 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 PRESENTATIONNS
|
||||
from element import Element
|
||||
|
||||
# ODF 1.0 section 9.6 and 9.7
|
||||
# Autogenerated
|
||||
def AnimationGroup(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'animation-group'), **args)
|
||||
|
||||
def Animations(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'animations'), **args)
|
||||
|
||||
def DateTime(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'date-time'), **args)
|
||||
|
||||
def DateTimeDecl(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'date-time-decl'), **args)
|
||||
|
||||
def Dim(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'dim'), **args)
|
||||
|
||||
def EventListener(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'event-listener'), **args)
|
||||
|
||||
def Footer(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'footer'), **args)
|
||||
|
||||
def FooterDecl(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'footer-decl'), **args)
|
||||
|
||||
def Header(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'header'), **args)
|
||||
|
||||
def HeaderDecl(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'header-decl'), **args)
|
||||
|
||||
def HideShape(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'hide-shape'), **args)
|
||||
|
||||
def HideText(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'hide-text'), **args)
|
||||
|
||||
def Notes(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'notes'), **args)
|
||||
|
||||
def Placeholder(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'placeholder'), **args)
|
||||
|
||||
def Play(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'play'), **args)
|
||||
|
||||
def Settings(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'settings'), **args)
|
||||
|
||||
def Show(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'show'), **args)
|
||||
|
||||
def ShowShape(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'show-shape'), **args)
|
||||
|
||||
def ShowText(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'show-text'), **args)
|
||||
|
||||
def Sound(**args):
|
||||
return Element(qname = (PRESENTATIONNS,'sound'), **args)
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
# -*- 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 SCRIPTNS
|
||||
from element import Element
|
||||
|
||||
# ODF 1.0 section 12.4.1
|
||||
# The <script:event-listener> element binds an event to a macro.
|
||||
|
||||
# Autogenerated
|
||||
def EventListener(**args):
|
||||
return Element(qname = (SCRIPTNS,'event-listener'), **args)
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
# -*- 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 STYLENS
|
||||
from element import Element
|
||||
|
||||
def StyleElement(**args):
|
||||
e = Element(**args)
|
||||
if args.get('check_grammar', True) == True:
|
||||
if not args.has_key('displayname'):
|
||||
e.setAttrNS(STYLENS,'display-name', args.get('name'))
|
||||
return e
|
||||
|
||||
# Autogenerated
|
||||
def BackgroundImage(**args):
|
||||
return Element(qname = (STYLENS,'background-image'), **args)
|
||||
|
||||
def ChartProperties(**args):
|
||||
return Element(qname = (STYLENS,'chart-properties'), **args)
|
||||
|
||||
def Column(**args):
|
||||
return Element(qname = (STYLENS,'column'), **args)
|
||||
|
||||
def ColumnSep(**args):
|
||||
return Element(qname = (STYLENS,'column-sep'), **args)
|
||||
|
||||
def Columns(**args):
|
||||
return Element(qname = (STYLENS,'columns'), **args)
|
||||
|
||||
def DefaultStyle(**args):
|
||||
return Element(qname = (STYLENS,'default-style'), **args)
|
||||
|
||||
def DrawingPageProperties(**args):
|
||||
return Element(qname = (STYLENS,'drawing-page-properties'), **args)
|
||||
|
||||
def DropCap(**args):
|
||||
return Element(qname = (STYLENS,'drop-cap'), **args)
|
||||
|
||||
def FontFace(**args):
|
||||
return Element(qname = (STYLENS,'font-face'), **args)
|
||||
|
||||
def Footer(**args):
|
||||
return Element(qname = (STYLENS,'footer'), **args)
|
||||
|
||||
def FooterLeft(**args):
|
||||
return Element(qname = (STYLENS,'footer-left'), **args)
|
||||
|
||||
def FooterStyle(**args):
|
||||
return Element(qname = (STYLENS,'footer-style'), **args)
|
||||
|
||||
def FootnoteSep(**args):
|
||||
return Element(qname = (STYLENS,'footnote-sep'), **args)
|
||||
|
||||
def GraphicProperties(**args):
|
||||
return Element(qname = (STYLENS,'graphic-properties'), **args)
|
||||
|
||||
def HandoutMaster(**args):
|
||||
return Element(qname = (STYLENS,'handout-master'), **args)
|
||||
|
||||
def Header(**args):
|
||||
return Element(qname = (STYLENS,'header'), **args)
|
||||
|
||||
def HeaderFooterProperties(**args):
|
||||
return Element(qname = (STYLENS,'header-footer-properties'), **args)
|
||||
|
||||
def HeaderLeft(**args):
|
||||
return Element(qname = (STYLENS,'header-left'), **args)
|
||||
|
||||
def HeaderStyle(**args):
|
||||
return Element(qname = (STYLENS,'header-style'), **args)
|
||||
|
||||
def ListLevelProperties(**args):
|
||||
return Element(qname = (STYLENS,'list-level-properties'), **args)
|
||||
|
||||
def Map(**args):
|
||||
return Element(qname = (STYLENS,'map'), **args)
|
||||
|
||||
def MasterPage(**args):
|
||||
return StyleElement(qname = (STYLENS,'master-page'), **args)
|
||||
|
||||
def PageLayout(**args):
|
||||
return Element(qname = (STYLENS,'page-layout'), **args)
|
||||
|
||||
def PageLayoutProperties(**args):
|
||||
return Element(qname = (STYLENS,'page-layout-properties'), **args)
|
||||
|
||||
def ParagraphProperties(**args):
|
||||
return Element(qname = (STYLENS,'paragraph-properties'), **args)
|
||||
|
||||
def PresentationPageLayout(**args):
|
||||
return StyleElement(qname = (STYLENS,'presentation-page-layout'), **args)
|
||||
|
||||
def RegionCenter(**args):
|
||||
return Element(qname = (STYLENS,'region-center'), **args)
|
||||
|
||||
def RegionLeft(**args):
|
||||
return Element(qname = (STYLENS,'region-left'), **args)
|
||||
|
||||
def RegionRight(**args):
|
||||
return Element(qname = (STYLENS,'region-right'), **args)
|
||||
|
||||
def RubyProperties(**args):
|
||||
return Element(qname = (STYLENS,'ruby-properties'), **args)
|
||||
|
||||
def SectionProperties(**args):
|
||||
return Element(qname = (STYLENS,'section-properties'), **args)
|
||||
|
||||
def Style(**args):
|
||||
return StyleElement(qname = (STYLENS,'style'), **args)
|
||||
|
||||
def TabStop(**args):
|
||||
return Element(qname = (STYLENS,'tab-stop'), **args)
|
||||
|
||||
def TabStops(**args):
|
||||
return Element(qname = (STYLENS,'tab-stops'), **args)
|
||||
|
||||
def TableCellProperties(**args):
|
||||
return Element(qname = (STYLENS,'table-cell-properties'), **args)
|
||||
|
||||
def TableColumnProperties(**args):
|
||||
return Element(qname = (STYLENS,'table-column-properties'), **args)
|
||||
|
||||
def TableProperties(**args):
|
||||
return Element(qname = (STYLENS,'table-properties'), **args)
|
||||
|
||||
def TableRowProperties(**args):
|
||||
return Element(qname = (STYLENS,'table-row-properties'), **args)
|
||||
|
||||
def TextProperties(**args):
|
||||
return Element(qname = (STYLENS,'text-properties'), **args)
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
# -*- 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 SVGNS
|
||||
from element import Element
|
||||
from draw import DrawElement
|
||||
|
||||
# Autogenerated
|
||||
def DefinitionSrc(**args):
|
||||
return Element(qname = (SVGNS,'definition-src'), **args)
|
||||
|
||||
def Desc(**args):
|
||||
return Element(qname = (SVGNS,'desc'), **args)
|
||||
|
||||
def FontFaceFormat(**args):
|
||||
return Element(qname = (SVGNS,'font-face-format'), **args)
|
||||
|
||||
def FontFaceName(**args):
|
||||
return Element(qname = (SVGNS,'font-face-name'), **args)
|
||||
|
||||
def FontFaceSrc(**args):
|
||||
return Element(qname = (SVGNS,'font-face-src'), **args)
|
||||
|
||||
def FontFaceUri(**args):
|
||||
return Element(qname = (SVGNS,'font-face-uri'), **args)
|
||||
|
||||
def Lineargradient(**args):
|
||||
return DrawElement(qname = (SVGNS,'linearGradient'), **args)
|
||||
|
||||
def Radialgradient(**args):
|
||||
return DrawElement(qname = (SVGNS,'radialGradient'), **args)
|
||||
|
||||
def Stop(**args):
|
||||
return Element(qname = (SVGNS,'stop'), **args)
|
||||
|
||||
def Title(**args):
|
||||
return Element(qname = (SVGNS,'title'), **args)
|
|
@ -1,307 +0,0 @@
|
|||
# -*- 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 TABLENS
|
||||
from element import Element
|
||||
|
||||
|
||||
# Autogenerated
|
||||
def Body(**args):
|
||||
return Element(qname = (TABLENS,'body'), **args)
|
||||
|
||||
def CalculationSettings(**args):
|
||||
return Element(qname = (TABLENS,'calculation-settings'), **args)
|
||||
|
||||
def CellAddress(**args):
|
||||
return Element(qname = (TABLENS,'cell-address'), **args)
|
||||
|
||||
def CellContentChange(**args):
|
||||
return Element(qname = (TABLENS,'cell-content-change'), **args)
|
||||
|
||||
def CellContentDeletion(**args):
|
||||
return Element(qname = (TABLENS,'cell-content-deletion'), **args)
|
||||
|
||||
def CellRangeSource(**args):
|
||||
return Element(qname = (TABLENS,'cell-range-source'), **args)
|
||||
|
||||
def ChangeDeletion(**args):
|
||||
return Element(qname = (TABLENS,'change-deletion'), **args)
|
||||
|
||||
def ChangeTrackTableCell(**args):
|
||||
return Element(qname = (TABLENS,'change-track-table-cell'), **args)
|
||||
|
||||
def Consolidation(**args):
|
||||
return Element(qname = (TABLENS,'consolidation'), **args)
|
||||
|
||||
def ContentValidation(**args):
|
||||
return Element(qname = (TABLENS,'content-validation'), **args)
|
||||
|
||||
def ContentValidations(**args):
|
||||
return Element(qname = (TABLENS,'content-validations'), **args)
|
||||
|
||||
def CoveredTableCell(**args):
|
||||
return Element(qname = (TABLENS,'covered-table-cell'), **args)
|
||||
|
||||
def CutOffs(**args):
|
||||
return Element(qname = (TABLENS,'cut-offs'), **args)
|
||||
|
||||
def DataPilotDisplayInfo(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-display-info'), **args)
|
||||
|
||||
def DataPilotField(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-field'), **args)
|
||||
|
||||
def DataPilotFieldReference(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-field-reference'), **args)
|
||||
|
||||
def DataPilotGroup(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-group'), **args)
|
||||
|
||||
def DataPilotGroupMember(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-group-member'), **args)
|
||||
|
||||
def DataPilotGroups(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-groups'), **args)
|
||||
|
||||
def DataPilotLayoutInfo(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-layout-info'), **args)
|
||||
|
||||
def DataPilotLevel(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-level'), **args)
|
||||
|
||||
def DataPilotMember(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-member'), **args)
|
||||
|
||||
def DataPilotMembers(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-members'), **args)
|
||||
|
||||
def DataPilotSortInfo(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-sort-info'), **args)
|
||||
|
||||
def DataPilotSubtotal(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-subtotal'), **args)
|
||||
|
||||
def DataPilotSubtotals(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-subtotals'), **args)
|
||||
|
||||
def DataPilotTable(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-table'), **args)
|
||||
|
||||
def DataPilotTables(**args):
|
||||
return Element(qname = (TABLENS,'data-pilot-tables'), **args)
|
||||
|
||||
def DatabaseRange(**args):
|
||||
return Element(qname = (TABLENS,'database-range'), **args)
|
||||
|
||||
def DatabaseRanges(**args):
|
||||
return Element(qname = (TABLENS,'database-ranges'), **args)
|
||||
|
||||
def DatabaseSourceQuery(**args):
|
||||
return Element(qname = (TABLENS,'database-source-query'), **args)
|
||||
|
||||
def DatabaseSourceSql(**args):
|
||||
return Element(qname = (TABLENS,'database-source-sql'), **args)
|
||||
|
||||
def DatabaseSourceTable(**args):
|
||||
return Element(qname = (TABLENS,'database-source-table'), **args)
|
||||
|
||||
def DdeLink(**args):
|
||||
return Element(qname = (TABLENS,'dde-link'), **args)
|
||||
|
||||
def DdeLinks(**args):
|
||||
return Element(qname = (TABLENS,'dde-links'), **args)
|
||||
|
||||
def Deletion(**args):
|
||||
return Element(qname = (TABLENS,'deletion'), **args)
|
||||
|
||||
def Deletions(**args):
|
||||
return Element(qname = (TABLENS,'deletions'), **args)
|
||||
|
||||
def Dependencies(**args):
|
||||
return Element(qname = (TABLENS,'dependencies'), **args)
|
||||
|
||||
def Dependency(**args):
|
||||
return Element(qname = (TABLENS,'dependency'), **args)
|
||||
|
||||
def Detective(**args):
|
||||
return Element(qname = (TABLENS,'detective'), **args)
|
||||
|
||||
def ErrorMacro(**args):
|
||||
return Element(qname = (TABLENS,'error-macro'), **args)
|
||||
|
||||
def ErrorMessage(**args):
|
||||
return Element(qname = (TABLENS,'error-message'), **args)
|
||||
|
||||
def EvenColumns(**args):
|
||||
return Element(qname = (TABLENS,'even-columns'), **args)
|
||||
|
||||
def EvenRows(**args):
|
||||
return Element(qname = (TABLENS,'even-rows'), **args)
|
||||
|
||||
def Filter(**args):
|
||||
return Element(qname = (TABLENS,'filter'), **args)
|
||||
|
||||
def FilterAnd(**args):
|
||||
return Element(qname = (TABLENS,'filter-and'), **args)
|
||||
|
||||
def FilterCondition(**args):
|
||||
return Element(qname = (TABLENS,'filter-condition'), **args)
|
||||
|
||||
def FilterOr(**args):
|
||||
return Element(qname = (TABLENS,'filter-or'), **args)
|
||||
|
||||
def FirstColumn(**args):
|
||||
return Element(qname = (TABLENS,'first-column'), **args)
|
||||
|
||||
def FirstRow(**args):
|
||||
return Element(qname = (TABLENS,'first-row'), **args)
|
||||
|
||||
def HelpMessage(**args):
|
||||
return Element(qname = (TABLENS,'help-message'), **args)
|
||||
|
||||
def HighlightedRange(**args):
|
||||
return Element(qname = (TABLENS,'highlighted-range'), **args)
|
||||
|
||||
def Insertion(**args):
|
||||
return Element(qname = (TABLENS,'insertion'), **args)
|
||||
|
||||
def InsertionCutOff(**args):
|
||||
return Element(qname = (TABLENS,'insertion-cut-off'), **args)
|
||||
|
||||
def Iteration(**args):
|
||||
return Element(qname = (TABLENS,'iteration'), **args)
|
||||
|
||||
def LabelRange(**args):
|
||||
return Element(qname = (TABLENS,'label-range'), **args)
|
||||
|
||||
def LabelRanges(**args):
|
||||
return Element(qname = (TABLENS,'label-ranges'), **args)
|
||||
|
||||
def LastColumn(**args):
|
||||
return Element(qname = (TABLENS,'last-column'), **args)
|
||||
|
||||
def LastRow(**args):
|
||||
return Element(qname = (TABLENS,'last-row'), **args)
|
||||
|
||||
def Movement(**args):
|
||||
return Element(qname = (TABLENS,'movement'), **args)
|
||||
|
||||
def MovementCutOff(**args):
|
||||
return Element(qname = (TABLENS,'movement-cut-off'), **args)
|
||||
|
||||
def NamedExpression(**args):
|
||||
return Element(qname = (TABLENS,'named-expression'), **args)
|
||||
|
||||
def NamedExpressions(**args):
|
||||
return Element(qname = (TABLENS,'named-expressions'), **args)
|
||||
|
||||
def NamedRange(**args):
|
||||
return Element(qname = (TABLENS,'named-range'), **args)
|
||||
|
||||
def NullDate(**args):
|
||||
return Element(qname = (TABLENS,'null-date'), **args)
|
||||
|
||||
def OddColumns(**args):
|
||||
return Element(qname = (TABLENS,'odd-columns'), **args)
|
||||
|
||||
def OddRows(**args):
|
||||
return Element(qname = (TABLENS,'odd-rows'), **args)
|
||||
|
||||
def Operation(**args):
|
||||
return Element(qname = (TABLENS,'operation'), **args)
|
||||
|
||||
def Previous(**args):
|
||||
return Element(qname = (TABLENS,'previous'), **args)
|
||||
|
||||
def Scenario(**args):
|
||||
return Element(qname = (TABLENS,'scenario'), **args)
|
||||
|
||||
def Shapes(**args):
|
||||
return Element(qname = (TABLENS,'shapes'), **args)
|
||||
|
||||
def Sort(**args):
|
||||
return Element(qname = (TABLENS,'sort'), **args)
|
||||
|
||||
def SortBy(**args):
|
||||
return Element(qname = (TABLENS,'sort-by'), **args)
|
||||
|
||||
def SortGroups(**args):
|
||||
return Element(qname = (TABLENS,'sort-groups'), **args)
|
||||
|
||||
def SourceCellRange(**args):
|
||||
return Element(qname = (TABLENS,'source-cell-range'), **args)
|
||||
|
||||
def SourceRangeAddress(**args):
|
||||
return Element(qname = (TABLENS,'source-range-address'), **args)
|
||||
|
||||
def SourceService(**args):
|
||||
return Element(qname = (TABLENS,'source-service'), **args)
|
||||
|
||||
def SubtotalField(**args):
|
||||
return Element(qname = (TABLENS,'subtotal-field'), **args)
|
||||
|
||||
def SubtotalRule(**args):
|
||||
return Element(qname = (TABLENS,'subtotal-rule'), **args)
|
||||
|
||||
def SubtotalRules(**args):
|
||||
return Element(qname = (TABLENS,'subtotal-rules'), **args)
|
||||
|
||||
def Table(**args):
|
||||
return Element(qname = (TABLENS,'table'), **args)
|
||||
|
||||
def TableCell(**args):
|
||||
return Element(qname = (TABLENS,'table-cell'), **args)
|
||||
|
||||
def TableColumn(**args):
|
||||
return Element(qname = (TABLENS,'table-column'), **args)
|
||||
|
||||
def TableColumnGroup(**args):
|
||||
return Element(qname = (TABLENS,'table-column-group'), **args)
|
||||
|
||||
def TableColumns(**args):
|
||||
return Element(qname = (TABLENS,'table-columns'), **args)
|
||||
|
||||
def TableHeaderColumns(**args):
|
||||
return Element(qname = (TABLENS,'table-header-columns'), **args)
|
||||
|
||||
def TableHeaderRows(**args):
|
||||
return Element(qname = (TABLENS,'table-header-rows'), **args)
|
||||
|
||||
def TableRow(**args):
|
||||
return Element(qname = (TABLENS,'table-row'), **args)
|
||||
|
||||
def TableRowGroup(**args):
|
||||
return Element(qname = (TABLENS,'table-row-group'), **args)
|
||||
|
||||
def TableRows(**args):
|
||||
return Element(qname = (TABLENS,'table-rows'), **args)
|
||||
|
||||
def TableSource(**args):
|
||||
return Element(qname = (TABLENS,'table-source'), **args)
|
||||
|
||||
def TableTemplate(**args):
|
||||
return Element(qname = (TABLENS,'table-template'), **args)
|
||||
|
||||
def TargetRangeAddress(**args):
|
||||
return Element(qname = (TABLENS,'target-range-address'), **args)
|
||||
|
||||
def TrackedChanges(**args):
|
||||
return Element(qname = (TABLENS,'tracked-changes'), **args)
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Create and extract text from ODF, handling whitespace correctly.
|
||||
# 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.
|
||||
|
||||
|
||||
"""
|
||||
Class for handling whitespace properly in OpenDocument.
|
||||
|
||||
While it is possible to use getTextContent() and setTextContent()
|
||||
to extract or create ODF content, these won't extract or create
|
||||
the appropriate <text:s>, <text:tab>, or <text:line-break>
|
||||
elements. This module takes care of that problem.
|
||||
"""
|
||||
|
||||
from odf.element import Node
|
||||
import odf.opendocument
|
||||
from odf.text import S,LineBreak,Tab
|
||||
|
||||
class WhitespaceText(object):
|
||||
|
||||
def __init__(self):
|
||||
self.textBuffer = []
|
||||
self.spaceCount = 0
|
||||
|
||||
def addTextToElement(self, odfElement, s):
|
||||
""" Process an input string, inserting
|
||||
<text:tab> elements for '\t',
|
||||
<text:line-break> elements for '\n', and
|
||||
<text:s> elements for runs of more than one blank.
|
||||
These will be added to the given element.
|
||||
"""
|
||||
i = 0
|
||||
ch = ' '
|
||||
|
||||
# When we encounter a tab or newline, we can immediately
|
||||
# dump any accumulated text and then emit the appropriate
|
||||
# ODF element.
|
||||
#
|
||||
# When we encounter a space, we add it to the text buffer,
|
||||
# and then collect more spaces. If there are more spaces
|
||||
# after the first one, we dump the text buffer and then
|
||||
# then emit the appropriate <text:s> element.
|
||||
|
||||
while i < len(s):
|
||||
ch = s[i]
|
||||
if ch == '\t':
|
||||
self._emitTextBuffer(odfElement)
|
||||
odfElement.addElement(Tab())
|
||||
i += 1
|
||||
elif ch == '\n':
|
||||
self._emitTextBuffer(odfElement);
|
||||
odfElement.addElement(LineBreak())
|
||||
i += 1
|
||||
elif ch == ' ':
|
||||
self.textBuffer.append(' ')
|
||||
i += 1
|
||||
self.spaceCount = 0
|
||||
while i < len(s) and (s[i] == ' '):
|
||||
self.spaceCount += 1
|
||||
i += 1
|
||||
if self.spaceCount > 0:
|
||||
self._emitTextBuffer(odfElement)
|
||||
self._emitSpaces(odfElement)
|
||||
else:
|
||||
self.textBuffer.append(ch)
|
||||
i += 1
|
||||
|
||||
self._emitTextBuffer(odfElement)
|
||||
|
||||
def _emitTextBuffer(self, odfElement):
|
||||
""" Creates a Text Node whose contents are the current textBuffer.
|
||||
Side effect: clears the text buffer.
|
||||
"""
|
||||
if len(self.textBuffer) > 0:
|
||||
odfElement.addText(''.join(self.textBuffer))
|
||||
self.textBuffer = []
|
||||
|
||||
|
||||
def _emitSpaces(self, odfElement):
|
||||
""" Creates a <text:s> element for the current spaceCount.
|
||||
Side effect: sets spaceCount back to zero
|
||||
"""
|
||||
if self.spaceCount > 0:
|
||||
spaceElement = S(c=self.spaceCount)
|
||||
odfElement.addElement(spaceElement)
|
||||
self.spaceCount = 0
|
||||
|
||||
def addTextToElement(odfElement, s):
|
||||
wst = WhitespaceText()
|
||||
wst.addTextToElement(odfElement, s)
|
||||
|
||||
def extractText(odfElement):
|
||||
""" Extract text content from an Element, with whitespace represented
|
||||
properly. Returns the text, with tabs, spaces, and newlines
|
||||
correctly evaluated. This method recursively descends through the
|
||||
children of the given element, accumulating text and "unwrapping"
|
||||
<text:s>, <text:tab>, and <text:line-break> elements along the way.
|
||||
"""
|
||||
result = [];
|
||||
|
||||
if len(odfElement.childNodes) != 0:
|
||||
for child in odfElement.childNodes:
|
||||
if child.nodeType == Node.TEXT_NODE:
|
||||
result.append(child.data)
|
||||
elif child.nodeType == Node.ELEMENT_NODE:
|
||||
subElement = child
|
||||
tagName = subElement.qname;
|
||||
if tagName == (u"urn:oasis:names:tc:opendocument:xmlns:text:1.0", u"line-break"):
|
||||
result.append("\n")
|
||||
elif tagName == (u"urn:oasis:names:tc:opendocument:xmlns:text:1.0", u"tab"):
|
||||
result.append("\t")
|
||||
elif tagName == (u"urn:oasis:names:tc:opendocument:xmlns:text:1.0", u"s"):
|
||||
c = subElement.getAttribute('c')
|
||||
if c:
|
||||
spaceCount = int(c)
|
||||
else:
|
||||
spaceCount = 1
|
||||
|
||||
result.append(" " * spaceCount)
|
||||
else:
|
||||
result.append(extractText(subElement))
|
||||
return ''.join(result)
|
|
@ -1,562 +0,0 @@
|
|||
# -*- 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 TEXTNS
|
||||
from element import Element
|
||||
from style import StyleElement
|
||||
|
||||
# Autogenerated
|
||||
def A(**args):
|
||||
return Element(qname = (TEXTNS,'a'), **args)
|
||||
|
||||
def AlphabeticalIndex(**args):
|
||||
return Element(qname = (TEXTNS,'alphabetical-index'), **args)
|
||||
|
||||
def AlphabeticalIndexAutoMarkFile(**args):
|
||||
return Element(qname = (TEXTNS,'alphabetical-index-auto-mark-file'), **args)
|
||||
|
||||
def AlphabeticalIndexEntryTemplate(**args):
|
||||
return Element(qname = (TEXTNS,'alphabetical-index-entry-template'), **args)
|
||||
|
||||
def AlphabeticalIndexMark(**args):
|
||||
return Element(qname = (TEXTNS,'alphabetical-index-mark'), **args)
|
||||
|
||||
def AlphabeticalIndexMarkEnd(**args):
|
||||
return Element(qname = (TEXTNS,'alphabetical-index-mark-end'), **args)
|
||||
|
||||
def AlphabeticalIndexMarkStart(**args):
|
||||
return Element(qname = (TEXTNS,'alphabetical-index-mark-start'), **args)
|
||||
|
||||
def AlphabeticalIndexSource(**args):
|
||||
return Element(qname = (TEXTNS,'alphabetical-index-source'), **args)
|
||||
|
||||
def AuthorInitials(**args):
|
||||
return Element(qname = (TEXTNS,'author-initials'), **args)
|
||||
|
||||
def AuthorName(**args):
|
||||
return Element(qname = (TEXTNS,'author-name'), **args)
|
||||
|
||||
def Bibliography(**args):
|
||||
return Element(qname = (TEXTNS,'bibliography'), **args)
|
||||
|
||||
def BibliographyConfiguration(**args):
|
||||
return Element(qname = (TEXTNS,'bibliography-configuration'), **args)
|
||||
|
||||
def BibliographyEntryTemplate(**args):
|
||||
return Element(qname = (TEXTNS,'bibliography-entry-template'), **args)
|
||||
|
||||
def BibliographyMark(**args):
|
||||
return Element(qname = (TEXTNS,'bibliography-mark'), **args)
|
||||
|
||||
def BibliographySource(**args):
|
||||
return Element(qname = (TEXTNS,'bibliography-source'), **args)
|
||||
|
||||
def Bookmark(**args):
|
||||
return Element(qname = (TEXTNS,'bookmark'), **args)
|
||||
|
||||
def BookmarkEnd(**args):
|
||||
return Element(qname = (TEXTNS,'bookmark-end'), **args)
|
||||
|
||||
def BookmarkRef(**args):
|
||||
return Element(qname = (TEXTNS,'bookmark-ref'), **args)
|
||||
|
||||
def BookmarkStart(**args):
|
||||
return Element(qname = (TEXTNS,'bookmark-start'), **args)
|
||||
|
||||
def Change(**args):
|
||||
return Element(qname = (TEXTNS,'change'), **args)
|
||||
|
||||
def ChangeEnd(**args):
|
||||
return Element(qname = (TEXTNS,'change-end'), **args)
|
||||
|
||||
def ChangeStart(**args):
|
||||
return Element(qname = (TEXTNS,'change-start'), **args)
|
||||
|
||||
def ChangedRegion(**args):
|
||||
return Element(qname = (TEXTNS,'changed-region'), **args)
|
||||
|
||||
def Chapter(**args):
|
||||
return Element(qname = (TEXTNS,'chapter'), **args)
|
||||
|
||||
def CharacterCount(**args):
|
||||
return Element(qname = (TEXTNS,'character-count'), **args)
|
||||
|
||||
def ConditionalText(**args):
|
||||
return Element(qname = (TEXTNS,'conditional-text'), **args)
|
||||
|
||||
def CreationDate(**args):
|
||||
return Element(qname = (TEXTNS,'creation-date'), **args)
|
||||
|
||||
def CreationTime(**args):
|
||||
return Element(qname = (TEXTNS,'creation-time'), **args)
|
||||
|
||||
def Creator(**args):
|
||||
return Element(qname = (TEXTNS,'creator'), **args)
|
||||
|
||||
def DatabaseDisplay(**args):
|
||||
return Element(qname = (TEXTNS,'database-display'), **args)
|
||||
|
||||
def DatabaseName(**args):
|
||||
return Element(qname = (TEXTNS,'database-name'), **args)
|
||||
|
||||
def DatabaseNext(**args):
|
||||
return Element(qname = (TEXTNS,'database-next'), **args)
|
||||
|
||||
def DatabaseRowNumber(**args):
|
||||
return Element(qname = (TEXTNS,'database-row-number'), **args)
|
||||
|
||||
def DatabaseRowSelect(**args):
|
||||
return Element(qname = (TEXTNS,'database-row-select'), **args)
|
||||
|
||||
def Date(**args):
|
||||
return Element(qname = (TEXTNS,'date'), **args)
|
||||
|
||||
def DdeConnection(**args):
|
||||
return Element(qname = (TEXTNS,'dde-connection'), **args)
|
||||
|
||||
def DdeConnectionDecl(**args):
|
||||
return Element(qname = (TEXTNS,'dde-connection-decl'), **args)
|
||||
|
||||
def DdeConnectionDecls(**args):
|
||||
return Element(qname = (TEXTNS,'dde-connection-decls'), **args)
|
||||
|
||||
def Deletion(**args):
|
||||
return Element(qname = (TEXTNS,'deletion'), **args)
|
||||
|
||||
def Description(**args):
|
||||
return Element(qname = (TEXTNS,'description'), **args)
|
||||
|
||||
def EditingCycles(**args):
|
||||
return Element(qname = (TEXTNS,'editing-cycles'), **args)
|
||||
|
||||
def EditingDuration(**args):
|
||||
return Element(qname = (TEXTNS,'editing-duration'), **args)
|
||||
|
||||
def ExecuteMacro(**args):
|
||||
return Element(qname = (TEXTNS,'execute-macro'), **args)
|
||||
|
||||
def Expression(**args):
|
||||
return Element(qname = (TEXTNS,'expression'), **args)
|
||||
|
||||
def FileName(**args):
|
||||
return Element(qname = (TEXTNS,'file-name'), **args)
|
||||
|
||||
def FormatChange(**args):
|
||||
return Element(qname = (TEXTNS,'format-change'), **args)
|
||||
|
||||
def H(**args):
|
||||
return Element(qname = (TEXTNS, 'h'), **args)
|
||||
|
||||
def HiddenParagraph(**args):
|
||||
return Element(qname = (TEXTNS,'hidden-paragraph'), **args)
|
||||
|
||||
def HiddenText(**args):
|
||||
return Element(qname = (TEXTNS,'hidden-text'), **args)
|
||||
|
||||
def IllustrationIndex(**args):
|
||||
return Element(qname = (TEXTNS,'illustration-index'), **args)
|
||||
|
||||
def IllustrationIndexEntryTemplate(**args):
|
||||
return Element(qname = (TEXTNS,'illustration-index-entry-template'), **args)
|
||||
|
||||
def IllustrationIndexSource(**args):
|
||||
return Element(qname = (TEXTNS,'illustration-index-source'), **args)
|
||||
|
||||
def ImageCount(**args):
|
||||
return Element(qname = (TEXTNS,'image-count'), **args)
|
||||
|
||||
def IndexBody(**args):
|
||||
return Element(qname = (TEXTNS,'index-body'), **args)
|
||||
|
||||
def IndexEntryBibliography(**args):
|
||||
return Element(qname = (TEXTNS,'index-entry-bibliography'), **args)
|
||||
|
||||
def IndexEntryChapter(**args):
|
||||
return Element(qname = (TEXTNS,'index-entry-chapter'), **args)
|
||||
|
||||
def IndexEntryLinkEnd(**args):
|
||||
return Element(qname = (TEXTNS,'index-entry-link-end'), **args)
|
||||
|
||||
def IndexEntryLinkStart(**args):
|
||||
return Element(qname = (TEXTNS,'index-entry-link-start'), **args)
|
||||
|
||||
def IndexEntryPageNumber(**args):
|
||||
return Element(qname = (TEXTNS,'index-entry-page-number'), **args)
|
||||
|
||||
def IndexEntrySpan(**args):
|
||||
return Element(qname = (TEXTNS,'index-entry-span'), **args)
|
||||
|
||||
def IndexEntryTabStop(**args):
|
||||
return Element(qname = (TEXTNS,'index-entry-tab-stop'), **args)
|
||||
|
||||
def IndexEntryText(**args):
|
||||
return Element(qname = (TEXTNS,'index-entry-text'), **args)
|
||||
|
||||
def IndexSourceStyle(**args):
|
||||
return Element(qname = (TEXTNS,'index-source-style'), **args)
|
||||
|
||||
def IndexSourceStyles(**args):
|
||||
return Element(qname = (TEXTNS,'index-source-styles'), **args)
|
||||
|
||||
def IndexTitle(**args):
|
||||
return Element(qname = (TEXTNS,'index-title'), **args)
|
||||
|
||||
def IndexTitleTemplate(**args):
|
||||
return Element(qname = (TEXTNS,'index-title-template'), **args)
|
||||
|
||||
def InitialCreator(**args):
|
||||
return Element(qname = (TEXTNS,'initial-creator'), **args)
|
||||
|
||||
def Insertion(**args):
|
||||
return Element(qname = (TEXTNS,'insertion'), **args)
|
||||
|
||||
def Keywords(**args):
|
||||
return Element(qname = (TEXTNS,'keywords'), **args)
|
||||
|
||||
def LineBreak(**args):
|
||||
return Element(qname = (TEXTNS,'line-break'), **args)
|
||||
|
||||
def LinenumberingConfiguration(**args):
|
||||
return Element(qname = (TEXTNS,'linenumbering-configuration'), **args)
|
||||
|
||||
def LinenumberingSeparator(**args):
|
||||
return Element(qname = (TEXTNS,'linenumbering-separator'), **args)
|
||||
|
||||
def List(**args):
|
||||
return Element(qname = (TEXTNS,'list'), **args)
|
||||
|
||||
def ListHeader(**args):
|
||||
return Element(qname = (TEXTNS,'list-header'), **args)
|
||||
|
||||
def ListItem(**args):
|
||||
return Element(qname = (TEXTNS,'list-item'), **args)
|
||||
|
||||
def ListLevelStyleBullet(**args):
|
||||
return Element(qname = (TEXTNS,'list-level-style-bullet'), **args)
|
||||
|
||||
def ListLevelStyleImage(**args):
|
||||
return Element(qname = (TEXTNS,'list-level-style-image'), **args)
|
||||
|
||||
def ListLevelStyleNumber(**args):
|
||||
return Element(qname = (TEXTNS,'list-level-style-number'), **args)
|
||||
|
||||
def ListStyle(**args):
|
||||
return StyleElement(qname = (TEXTNS,'list-style'), **args)
|
||||
|
||||
def Measure(**args):
|
||||
return Element(qname = (TEXTNS,'measure'), **args)
|
||||
|
||||
def ModificationDate(**args):
|
||||
return Element(qname = (TEXTNS,'modification-date'), **args)
|
||||
|
||||
def ModificationTime(**args):
|
||||
return Element(qname = (TEXTNS,'modification-time'), **args)
|
||||
|
||||
def Note(**args):
|
||||
return Element(qname = (TEXTNS,'note'), **args)
|
||||
|
||||
def NoteBody(**args):
|
||||
return Element(qname = (TEXTNS,'note-body'), **args)
|
||||
|
||||
def NoteCitation(**args):
|
||||
return Element(qname = (TEXTNS,'note-citation'), **args)
|
||||
|
||||
def NoteContinuationNoticeBackward(**args):
|
||||
return Element(qname = (TEXTNS,'note-continuation-notice-backward'), **args)
|
||||
|
||||
def NoteContinuationNoticeForward(**args):
|
||||
return Element(qname = (TEXTNS,'note-continuation-notice-forward'), **args)
|
||||
|
||||
def NoteRef(**args):
|
||||
return Element(qname = (TEXTNS,'note-ref'), **args)
|
||||
|
||||
def NotesConfiguration(**args):
|
||||
return Element(qname = (TEXTNS,'notes-configuration'), **args)
|
||||
|
||||
def Number(**args):
|
||||
return Element(qname = (TEXTNS,'number'), **args)
|
||||
|
||||
def NumberedParagraph(**args):
|
||||
return Element(qname = (TEXTNS,'numbered-paragraph'), **args)
|
||||
|
||||
def ObjectCount(**args):
|
||||
return Element(qname = (TEXTNS,'object-count'), **args)
|
||||
|
||||
def ObjectIndex(**args):
|
||||
return Element(qname = (TEXTNS,'object-index'), **args)
|
||||
|
||||
def ObjectIndexEntryTemplate(**args):
|
||||
return Element(qname = (TEXTNS,'object-index-entry-template'), **args)
|
||||
|
||||
def ObjectIndexSource(**args):
|
||||
return Element(qname = (TEXTNS,'object-index-source'), **args)
|
||||
|
||||
def OutlineLevelStyle(**args):
|
||||
return Element(qname = (TEXTNS,'outline-level-style'), **args)
|
||||
|
||||
def OutlineStyle(**args):
|
||||
return Element(qname = (TEXTNS,'outline-style'), **args)
|
||||
|
||||
def P(**args):
|
||||
return Element(qname = (TEXTNS, 'p'), **args)
|
||||
|
||||
def Page(**args):
|
||||
return Element(qname = (TEXTNS,'page'), **args)
|
||||
|
||||
def PageContinuation(**args):
|
||||
return Element(qname = (TEXTNS,'page-continuation'), **args)
|
||||
|
||||
def PageCount(**args):
|
||||
return Element(qname = (TEXTNS,'page-count'), **args)
|
||||
|
||||
def PageNumber(**args):
|
||||
return Element(qname = (TEXTNS,'page-number'), **args)
|
||||
|
||||
def PageSequence(**args):
|
||||
return Element(qname = (TEXTNS,'page-sequence'), **args)
|
||||
|
||||
def PageVariableGet(**args):
|
||||
return Element(qname = (TEXTNS,'page-variable-get'), **args)
|
||||
|
||||
def PageVariableSet(**args):
|
||||
return Element(qname = (TEXTNS,'page-variable-set'), **args)
|
||||
|
||||
def ParagraphCount(**args):
|
||||
return Element(qname = (TEXTNS,'paragraph-count'), **args)
|
||||
|
||||
def Placeholder(**args):
|
||||
return Element(qname = (TEXTNS,'placeholder'), **args)
|
||||
|
||||
def PrintDate(**args):
|
||||
return Element(qname = (TEXTNS,'print-date'), **args)
|
||||
|
||||
def PrintTime(**args):
|
||||
return Element(qname = (TEXTNS,'print-time'), **args)
|
||||
|
||||
def PrintedBy(**args):
|
||||
return Element(qname = (TEXTNS,'printed-by'), **args)
|
||||
|
||||
def ReferenceMark(**args):
|
||||
return Element(qname = (TEXTNS,'reference-mark'), **args)
|
||||
|
||||
def ReferenceMarkEnd(**args):
|
||||
return Element(qname = (TEXTNS,'reference-mark-end'), **args)
|
||||
|
||||
def ReferenceMarkStart(**args):
|
||||
return Element(qname = (TEXTNS,'reference-mark-start'), **args)
|
||||
|
||||
def ReferenceRef(**args):
|
||||
return Element(qname = (TEXTNS,'reference-ref'), **args)
|
||||
|
||||
def Ruby(**args):
|
||||
return Element(qname = (TEXTNS,'ruby'), **args)
|
||||
|
||||
def RubyBase(**args):
|
||||
return Element(qname = (TEXTNS,'ruby-base'), **args)
|
||||
|
||||
def RubyText(**args):
|
||||
return Element(qname = (TEXTNS,'ruby-text'), **args)
|
||||
|
||||
def S(**args):
|
||||
return Element(qname = (TEXTNS,'s'), **args)
|
||||
|
||||
def Script(**args):
|
||||
return Element(qname = (TEXTNS,'script'), **args)
|
||||
|
||||
def Section(**args):
|
||||
return Element(qname = (TEXTNS,'section'), **args)
|
||||
|
||||
def SectionSource(**args):
|
||||
return Element(qname = (TEXTNS,'section-source'), **args)
|
||||
|
||||
def SenderCity(**args):
|
||||
return Element(qname = (TEXTNS,'sender-city'), **args)
|
||||
|
||||
def SenderCompany(**args):
|
||||
return Element(qname = (TEXTNS,'sender-company'), **args)
|
||||
|
||||
def SenderCountry(**args):
|
||||
return Element(qname = (TEXTNS,'sender-country'), **args)
|
||||
|
||||
def SenderEmail(**args):
|
||||
return Element(qname = (TEXTNS,'sender-email'), **args)
|
||||
|
||||
def SenderFax(**args):
|
||||
return Element(qname = (TEXTNS,'sender-fax'), **args)
|
||||
|
||||
def SenderFirstname(**args):
|
||||
return Element(qname = (TEXTNS,'sender-firstname'), **args)
|
||||
|
||||
def SenderInitials(**args):
|
||||
return Element(qname = (TEXTNS,'sender-initials'), **args)
|
||||
|
||||
def SenderLastname(**args):
|
||||
return Element(qname = (TEXTNS,'sender-lastname'), **args)
|
||||
|
||||
def SenderPhonePrivate(**args):
|
||||
return Element(qname = (TEXTNS,'sender-phone-private'), **args)
|
||||
|
||||
def SenderPhoneWork(**args):
|
||||
return Element(qname = (TEXTNS,'sender-phone-work'), **args)
|
||||
|
||||
def SenderPosition(**args):
|
||||
return Element(qname = (TEXTNS,'sender-position'), **args)
|
||||
|
||||
def SenderPostalCode(**args):
|
||||
return Element(qname = (TEXTNS,'sender-postal-code'), **args)
|
||||
|
||||
def SenderStateOrProvince(**args):
|
||||
return Element(qname = (TEXTNS,'sender-state-or-province'), **args)
|
||||
|
||||
def SenderStreet(**args):
|
||||
return Element(qname = (TEXTNS,'sender-street'), **args)
|
||||
|
||||
def SenderTitle(**args):
|
||||
return Element(qname = (TEXTNS,'sender-title'), **args)
|
||||
|
||||
def Sequence(**args):
|
||||
return Element(qname = (TEXTNS,'sequence'), **args)
|
||||
|
||||
def SequenceDecl(**args):
|
||||
return Element(qname = (TEXTNS,'sequence-decl'), **args)
|
||||
|
||||
def SequenceDecls(**args):
|
||||
return Element(qname = (TEXTNS,'sequence-decls'), **args)
|
||||
|
||||
def SequenceRef(**args):
|
||||
return Element(qname = (TEXTNS,'sequence-ref'), **args)
|
||||
|
||||
def SheetName(**args):
|
||||
return Element(qname = (TEXTNS,'sheet-name'), **args)
|
||||
|
||||
def SoftPageBreak(**args):
|
||||
return Element(qname = (TEXTNS,'soft-page-break'), **args)
|
||||
|
||||
def SortKey(**args):
|
||||
return Element(qname = (TEXTNS,'sort-key'), **args)
|
||||
|
||||
def Span(**args):
|
||||
return Element(qname = (TEXTNS,'span'), **args)
|
||||
|
||||
def Subject(**args):
|
||||
return Element(qname = (TEXTNS,'subject'), **args)
|
||||
|
||||
def Tab(**args):
|
||||
return Element(qname = (TEXTNS,'tab'), **args)
|
||||
|
||||
def TableCount(**args):
|
||||
return Element(qname = (TEXTNS,'table-count'), **args)
|
||||
|
||||
def TableFormula(**args):
|
||||
return Element(qname = (TEXTNS,'table-formula'), **args)
|
||||
|
||||
def TableIndex(**args):
|
||||
return Element(qname = (TEXTNS,'table-index'), **args)
|
||||
|
||||
def TableIndexEntryTemplate(**args):
|
||||
return Element(qname = (TEXTNS,'table-index-entry-template'), **args)
|
||||
|
||||
def TableIndexSource(**args):
|
||||
return Element(qname = (TEXTNS,'table-index-source'), **args)
|
||||
|
||||
def TableOfContent(**args):
|
||||
return Element(qname = (TEXTNS,'table-of-content'), **args)
|
||||
|
||||
def TableOfContentEntryTemplate(**args):
|
||||
return Element(qname = (TEXTNS,'table-of-content-entry-template'), **args)
|
||||
|
||||
def TableOfContentSource(**args):
|
||||
return Element(qname = (TEXTNS,'table-of-content-source'), **args)
|
||||
|
||||
def TemplateName(**args):
|
||||
return Element(qname = (TEXTNS,'template-name'), **args)
|
||||
|
||||
def TextInput(**args):
|
||||
return Element(qname = (TEXTNS,'text-input'), **args)
|
||||
|
||||
def Time(**args):
|
||||
return Element(qname = (TEXTNS,'time'), **args)
|
||||
|
||||
def Title(**args):
|
||||
return Element(qname = (TEXTNS,'title'), **args)
|
||||
|
||||
def TocMark(**args):
|
||||
return Element(qname = (TEXTNS,'toc-mark'), **args)
|
||||
|
||||
def TocMarkEnd(**args):
|
||||
return Element(qname = (TEXTNS,'toc-mark-end'), **args)
|
||||
|
||||
def TocMarkStart(**args):
|
||||
return Element(qname = (TEXTNS,'toc-mark-start'), **args)
|
||||
|
||||
def TrackedChanges(**args):
|
||||
return Element(qname = (TEXTNS,'tracked-changes'), **args)
|
||||
|
||||
def UserDefined(**args):
|
||||
return Element(qname = (TEXTNS,'user-defined'), **args)
|
||||
|
||||
def UserFieldDecl(**args):
|
||||
return Element(qname = (TEXTNS,'user-field-decl'), **args)
|
||||
|
||||
def UserFieldDecls(**args):
|
||||
return Element(qname = (TEXTNS,'user-field-decls'), **args)
|
||||
|
||||
def UserFieldGet(**args):
|
||||
return Element(qname = (TEXTNS,'user-field-get'), **args)
|
||||
|
||||
def UserFieldInput(**args):
|
||||
return Element(qname = (TEXTNS,'user-field-input'), **args)
|
||||
|
||||
def UserIndex(**args):
|
||||
return Element(qname = (TEXTNS,'user-index'), **args)
|
||||
|
||||
def UserIndexEntryTemplate(**args):
|
||||
return Element(qname = (TEXTNS,'user-index-entry-template'), **args)
|
||||
|
||||
def UserIndexMark(**args):
|
||||
return Element(qname = (TEXTNS,'user-index-mark'), **args)
|
||||
|
||||
def UserIndexMarkEnd(**args):
|
||||
return Element(qname = (TEXTNS,'user-index-mark-end'), **args)
|
||||
|
||||
def UserIndexMarkStart(**args):
|
||||
return Element(qname = (TEXTNS,'user-index-mark-start'), **args)
|
||||
|
||||
def UserIndexSource(**args):
|
||||
return Element(qname = (TEXTNS,'user-index-source'), **args)
|
||||
|
||||
def VariableDecl(**args):
|
||||
return Element(qname = (TEXTNS,'variable-decl'), **args)
|
||||
|
||||
def VariableDecls(**args):
|
||||
return Element(qname = (TEXTNS,'variable-decls'), **args)
|
||||
|
||||
def VariableGet(**args):
|
||||
return Element(qname = (TEXTNS,'variable-get'), **args)
|
||||
|
||||
def VariableInput(**args):
|
||||
return Element(qname = (TEXTNS,'variable-input'), **args)
|
||||
|
||||
def VariableSet(**args):
|
||||
return Element(qname = (TEXTNS,'variable-set'), **args)
|
||||
|
||||
def WordCount(**args):
|
||||
return Element(qname = (TEXTNS,'word-count'), **args)
|
||||
|
|
@ -1,427 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# This contains a 128x128 px thumbnail in PNG format
|
||||
# Taken from http://www.zwahlendesign.ch/en/node/20
|
||||
# openoffice_icons/openoffice_icons_linux/openoffice11.png
|
||||
# License: Freeware
|
||||
import base64
|
||||
|
||||
iconstr = """\
|
||||
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
|
||||
N38FAAAAAElFTkSuQmCC\
|
||||
"""
|
||||
|
||||
def thumbnail():
|
||||
icon = base64.decodestring(iconstr)
|
||||
return icon
|
||||
|
||||
if __name__ == "__main__":
|
||||
icon = thumbnail()
|
||||
f = file("thumbnail.png","wb")
|
||||
f.write(icon)
|
||||
f.close()
|
|
@ -1,169 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2006-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): Michael Howitz, gocept gmbh & co. kg
|
||||
#
|
||||
# $Id: userfield.py 447 2008-07-10 20:01:30Z roug $
|
||||
|
||||
"""Class to show and manipulate user fields in odf documents."""
|
||||
|
||||
import sys
|
||||
import zipfile
|
||||
|
||||
from odf.text import UserFieldDecl
|
||||
from odf.namespaces import OFFICENS
|
||||
from odf.opendocument import load
|
||||
|
||||
OUTENCODING = "utf-8"
|
||||
|
||||
|
||||
# OpenDocument v.1.0 section 6.7.1
|
||||
VALUE_TYPES = {
|
||||
'float': (OFFICENS, u'value'),
|
||||
'percentage': (OFFICENS, u'value'),
|
||||
'currency': (OFFICENS, u'value'),
|
||||
'date': (OFFICENS, u'date-value'),
|
||||
'time': (OFFICENS, u'time-value'),
|
||||
'boolean': (OFFICENS, u'boolean-value'),
|
||||
'string': (OFFICENS, u'string-value'),
|
||||
}
|
||||
|
||||
|
||||
class UserFields(object):
|
||||
"""List, view and manipulate user fields."""
|
||||
|
||||
# these attributes can be a filename or a file like object
|
||||
src_file = None
|
||||
dest_file = None
|
||||
|
||||
def __init__(self, src=None, dest=None):
|
||||
"""Constructor
|
||||
|
||||
src ... source document name, file like object or None for stdin
|
||||
dest ... destination document name, file like object or None for stdout
|
||||
|
||||
"""
|
||||
self.src_file = src
|
||||
self.dest_file = dest
|
||||
self.document = None
|
||||
|
||||
def loaddoc(self):
|
||||
if isinstance(self.src_file, basestring):
|
||||
# src_file is a filename, check if it is a zip-file
|
||||
if not zipfile.is_zipfile(self.src_file):
|
||||
raise TypeError("%s is no odt file." % self.src_file)
|
||||
elif self.src_file is None:
|
||||
# use stdin if no file given
|
||||
self.src_file = sys.stdin
|
||||
|
||||
self.document = load(self.src_file)
|
||||
|
||||
def savedoc(self):
|
||||
# write output
|
||||
if self.dest_file is None:
|
||||
# use stdout if no filename given
|
||||
self.document.save('-')
|
||||
else:
|
||||
self.document.save(self.dest_file)
|
||||
|
||||
def list_fields(self):
|
||||
"""List (extract) all known user-fields.
|
||||
|
||||
Returns list of user-field names.
|
||||
|
||||
"""
|
||||
return [x[0] for x in self.list_fields_and_values()]
|
||||
|
||||
def list_fields_and_values(self, field_names=None):
|
||||
"""List (extract) user-fields with type and value.
|
||||
|
||||
field_names ... list of field names to show or None for all.
|
||||
|
||||
Returns list of tuples (<field name>, <field type>, <value>).
|
||||
|
||||
"""
|
||||
self.loaddoc()
|
||||
found_fields = []
|
||||
all_fields = self.document.getElementsByType(UserFieldDecl)
|
||||
for f in all_fields:
|
||||
value_type = f.getAttribute('valuetype')
|
||||
if value_type == 'string':
|
||||
value = f.getAttribute('stringvalue')
|
||||
else:
|
||||
value = f.getAttribute('value')
|
||||
field_name = f.getAttribute('name')
|
||||
|
||||
if field_names is None or field_name in field_names:
|
||||
found_fields.append((field_name.encode(OUTENCODING),
|
||||
value_type.encode(OUTENCODING),
|
||||
value.encode(OUTENCODING)))
|
||||
return found_fields
|
||||
|
||||
def list_values(self, field_names):
|
||||
"""Extract the contents of given field names from the file.
|
||||
|
||||
field_names ... list of field names
|
||||
|
||||
Returns list of field values.
|
||||
|
||||
"""
|
||||
return [x[2] for x in self.list_fields_and_values(field_names)]
|
||||
|
||||
def get(self, field_name):
|
||||
"""Extract the contents of this field from the file.
|
||||
|
||||
Returns field value or None if field does not exist.
|
||||
|
||||
"""
|
||||
values = self.list_values([field_name])
|
||||
if not values:
|
||||
return None
|
||||
return values[0]
|
||||
|
||||
def get_type_and_value(self, field_name):
|
||||
"""Extract the type and contents of this field from the file.
|
||||
|
||||
Returns tuple (<type>, <field-value>) or None if field does not exist.
|
||||
|
||||
"""
|
||||
fields = self.list_fields_and_values([field_name])
|
||||
if not fields:
|
||||
return None
|
||||
field_name, value_type, value = fields[0]
|
||||
return value_type, value
|
||||
|
||||
def update(self, data):
|
||||
"""Set the value of user fields. The field types will be the same.
|
||||
|
||||
data ... dict, with field name as key, field value as value
|
||||
|
||||
Returns None
|
||||
|
||||
"""
|
||||
self.loaddoc()
|
||||
all_fields = self.document.getElementsByType(UserFieldDecl)
|
||||
for f in all_fields:
|
||||
field_name = f.getAttribute('name')
|
||||
if data.has_key(field_name):
|
||||
value_type = f.getAttribute('valuetype')
|
||||
value = data.get(field_name)
|
||||
if value_type == 'string':
|
||||
f.setAttribute('stringvalue', value)
|
||||
else:
|
||||
f.setAttribute('value', value)
|
||||
self.savedoc()
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
# -*- 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 XFORMSNS
|
||||
from element import Element
|
||||
|
||||
# ODF 1.0 section 11.2
|
||||
# XForms is designed to be embedded in another XML format.
|
||||
# Autogenerated
|
||||
def Model(**args):
|
||||
return Element(qname = (XFORMSNS,'model'), **args)
|
||||
|
||||
def Instance(**args):
|
||||
return Element(qname = (XFORMSNS,'instance'), **args)
|
||||
|
||||
def Bind(**args):
|
||||
return Element(qname = (XFORMSNS,'bind'), **args)
|
|
@ -1,61 +0,0 @@
|
|||
# -*- 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)
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,87 +0,0 @@
|
|||
# -*- 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 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 DataPoint(**args):
|
||||
return Element(qname = (CHARTNS,'data-point'), **args)
|
||||
|
||||
def Domain(**args):
|
||||
return Element(qname = (CHARTNS,'domain'), **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 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)
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
# -*- 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)
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
# -*- 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)
|
|
@ -1,43 +0,0 @@
|
|||
# -*- 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 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)
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
# -*- 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 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,'style-name')]= stylename
|
||||
elif f == 'presentation':
|
||||
qattrs[(PRESENTATIONNS,'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,'class-names')]= classnames
|
||||
elif f == 'presentation':
|
||||
qattrs[(PRESENTATIONNS,'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):
|
||||
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):
|
||||
return DrawElement(qname = (DRAWNS,'fill-image'), **args)
|
||||
|
||||
def FloatingFrame(**args):
|
||||
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):
|
||||
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)
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Create a <text:list-style> 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
|
||||
from .style import Style, TextProperties, ListLevelProperties
|
||||
from .text import ListStyle,ListLevelStyleNumber,ListLevelStyleBullet
|
||||
|
||||
"""
|
||||
Create a <text:list-style> 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 <text:list-style> element for you.
|
||||
Each item in the string (or array) represents a list level
|
||||
* style for levels 1-10.</p>
|
||||
*
|
||||
* <p>If an item contains <code>1</code>, <code>I</code>,
|
||||
* <code>i</code>, <code>A</code>, or <code>a</code>, then it is presumed
|
||||
* to be a numbering style; otherwise it is a bulleted style.</p>
|
||||
"""
|
||||
|
||||
_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 :
|
|
@ -1,519 +0,0 @@
|
|||
#!/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 xml.dom
|
||||
from xml.dom.minicompat import *
|
||||
from .namespaces import nsdict
|
||||
from . import grammar
|
||||
from .attrconverters import AttrConverters
|
||||
|
||||
# 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 <rubbish> 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.
|
||||
"""
|
||||
try:
|
||||
data = data.decode('utf-8')
|
||||
except (TypeError, AttributeError):
|
||||
## Make sure our stream is a string
|
||||
## If it comes through as bytes it fails
|
||||
pass
|
||||
data = data.replace("&", "&")
|
||||
data = data.replace("<", "<")
|
||||
data = data.replace(">", ">")
|
||||
for chars, entity in list(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(str(c))
|
||||
return ''.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(object):
|
||||
""" 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.encode()
|
||||
|
||||
def __unicode__(self):
|
||||
return self.data
|
||||
|
||||
def toXml(self,level,f):
|
||||
""" Write XML in UTF-8 """
|
||||
if self.data:
|
||||
f.write(_escape(str(self.data).encode('utf-8')))
|
||||
|
||||
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. (<![CDATA[)
|
||||
"""
|
||||
if self.data:
|
||||
f.write('<![CDATA[%s]]>' % self.data.replace(']]>',']]>]]><![CDATA['))
|
||||
|
||||
class Element(Node):
|
||||
""" Creates a arbitrary element and is intended to be subclassed not used on its own.
|
||||
This element is the base of every element it defines a class which resembles
|
||||
a xml-element. The main advantage of this kind of implementation is that you don't
|
||||
have to create a toXML method for every different object. Every element
|
||||
consists of an attribute, optional subelements, optional text and optional cdata.
|
||||
"""
|
||||
|
||||
nodeType = Node.ELEMENT_NODE
|
||||
namespaces = {} # Due to shallow copy this is a static variable
|
||||
|
||||
_child_node_types = (Node.ELEMENT_NODE,
|
||||
Node.PROCESSING_INSTRUCTION_NODE,
|
||||
Node.COMMENT_NODE,
|
||||
Node.TEXT_NODE,
|
||||
Node.CDATA_SECTION_NODE,
|
||||
Node.ENTITY_REFERENCE_NODE)
|
||||
|
||||
def __init__(self, attributes=None, text=None, cdata=None, qname=None, qattributes=None, check_grammar=True, **args):
|
||||
if qname is not None:
|
||||
self.qname = qname
|
||||
assert(hasattr(self, 'qname'))
|
||||
self.ownerDocument = None
|
||||
self.childNodes=[]
|
||||
self.allowed_children = grammar.allowed_children.get(self.qname)
|
||||
prefix = self.get_nsprefix(self.qname[0])
|
||||
self.tagName = prefix + ":" + self.qname[1]
|
||||
if text is not None:
|
||||
self.addText(text)
|
||||
if cdata is not None:
|
||||
self.addCDATA(cdata)
|
||||
|
||||
allowed_attrs = self.allowed_attributes()
|
||||
if allowed_attrs is not None:
|
||||
allowed_args = [ a[1].lower().replace('-','') for a in allowed_attrs]
|
||||
self.attributes={}
|
||||
# Load the attributes from the 'attributes' argument
|
||||
if attributes:
|
||||
for attr, value in list(attributes.items()):
|
||||
self.setAttribute(attr, value)
|
||||
# Load the qualified attributes
|
||||
if qattributes:
|
||||
for attr, value in list(qattributes.items()):
|
||||
self.setAttrNS(attr[0], attr[1], value)
|
||||
if allowed_attrs is not None:
|
||||
# Load the attributes from the 'args' argument
|
||||
for arg in list(args.keys()):
|
||||
self.setAttribute(arg, args[arg])
|
||||
else:
|
||||
for arg in list(args.keys()): # If any attribute is allowed
|
||||
self.attributes[arg]=args[arg]
|
||||
if not check_grammar:
|
||||
return
|
||||
# Test that all mandatory attributes have been added.
|
||||
required = grammar.required_attributes.get(self.qname)
|
||||
if required:
|
||||
for r in required:
|
||||
if self.getAttrNS(r[0],r[1]) is None:
|
||||
raise AttributeError("Required attribute missing: %s in <%s>" % (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 list(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 namespace not 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):
|
||||
prefix = self.get_nsprefix(namespace)
|
||||
return self.attributes.get((namespace, localpart))
|
||||
|
||||
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 list(self.namespaces.items()):
|
||||
f.write(' xmlns:' + prefix + '="'+ _escape(str(namespace))+'"')
|
||||
for qname in list(self.attributes.keys()):
|
||||
prefix = self.get_nsprefix(qname[0])
|
||||
f.write(' '+_escape(str(prefix+':'+qname[1]))+'='+_quoteattr(str(self.attributes[qname]).encode('utf-8')))
|
||||
f.write('>')
|
||||
|
||||
def write_close_tag(self, level, f):
|
||||
f.write('</'+self.tagName+'>')
|
||||
|
||||
def toXml(self, level, f):
|
||||
""" Generate XML stream out of the tree structure """
|
||||
f.write('<'+self.tagName)
|
||||
if level == 0:
|
||||
for namespace, prefix in list(self.namespaces.items()):
|
||||
f.write(' xmlns:' + prefix + '="'+ _escape(str(namespace))+'"')
|
||||
for qname in list(self.attributes.keys()):
|
||||
prefix = self.get_nsprefix(qname[0])
|
||||
f.write(' '+_escape(str(prefix+':'+qname[1]))+'='+_quoteattr(str(self.attributes[qname]).encode('utf-8')))
|
||||
if self.childNodes:
|
||||
f.write('>')
|
||||
for element in self.childNodes:
|
||||
element.toXml(level+1,f)
|
||||
f.write('</'+self.tagName+'>')
|
||||
else:
|
||||
f.write('/>')
|
||||
|
||||
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
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue