http://www.mediawiki.org/wiki/Special:Code/pywikipedia/10761
Revision: 10761 Author: drtrigon Date: 2012-12-02 19:17:58 +0000 (Sun, 02 Dec 2012) Log Message: ----------- add bot script "SubsterBot" used in dewiki, enwiki, nlwiki, meta, ... (includes ALL bot scripts and ALL third-party libraries BUT NO TS tools)
Added Paths: ----------- trunk/pywikipedia/crontab/ trunk/pywikipedia/crontab/PKG-INFO trunk/pywikipedia/crontab/README trunk/pywikipedia/crontab/__init__.py trunk/pywikipedia/crontab/_crontab.py trunk/pywikipedia/odf/ trunk/pywikipedia/odf/APACHE-LICENSE-2.0.txt trunk/pywikipedia/odf/PKG-INFO trunk/pywikipedia/odf/README trunk/pywikipedia/odf/__init__.py trunk/pywikipedia/odf/anim.py trunk/pywikipedia/odf/attrconverters.py trunk/pywikipedia/odf/chart.py trunk/pywikipedia/odf/config.py trunk/pywikipedia/odf/dc.py trunk/pywikipedia/odf/dr3d.py trunk/pywikipedia/odf/draw.py trunk/pywikipedia/odf/easyliststyle.py trunk/pywikipedia/odf/element.py trunk/pywikipedia/odf/elementtypes.py trunk/pywikipedia/odf/form.py trunk/pywikipedia/odf/grammar.py trunk/pywikipedia/odf/load.py trunk/pywikipedia/odf/manifest.py trunk/pywikipedia/odf/math.py trunk/pywikipedia/odf/meta.py trunk/pywikipedia/odf/namespaces.py trunk/pywikipedia/odf/number.py trunk/pywikipedia/odf/odf2moinmoin.py trunk/pywikipedia/odf/odf2xhtml.py trunk/pywikipedia/odf/odfmanifest.py trunk/pywikipedia/odf/office.py trunk/pywikipedia/odf/opendocument.py trunk/pywikipedia/odf/presentation.py trunk/pywikipedia/odf/script.py trunk/pywikipedia/odf/style.py trunk/pywikipedia/odf/svg.py trunk/pywikipedia/odf/table.py trunk/pywikipedia/odf/teletype.py trunk/pywikipedia/odf/text.py trunk/pywikipedia/odf/thumbnail.py trunk/pywikipedia/odf/userfield.py trunk/pywikipedia/odf/xforms.py trunk/pywikipedia/openpyxl/ trunk/pywikipedia/openpyxl/INFO trunk/pywikipedia/openpyxl/LICENCE trunk/pywikipedia/openpyxl/README trunk/pywikipedia/openpyxl/__init__.py trunk/pywikipedia/openpyxl/cell.py trunk/pywikipedia/openpyxl/chart.py trunk/pywikipedia/openpyxl/drawing.py trunk/pywikipedia/openpyxl/namedrange.py trunk/pywikipedia/openpyxl/reader/ trunk/pywikipedia/openpyxl/reader/__init__.py trunk/pywikipedia/openpyxl/reader/excel.py trunk/pywikipedia/openpyxl/reader/iter_worksheet.py trunk/pywikipedia/openpyxl/reader/strings.py trunk/pywikipedia/openpyxl/reader/style.py trunk/pywikipedia/openpyxl/reader/workbook.py trunk/pywikipedia/openpyxl/reader/worksheet.py trunk/pywikipedia/openpyxl/shared/ trunk/pywikipedia/openpyxl/shared/__init__.py trunk/pywikipedia/openpyxl/shared/compat/ trunk/pywikipedia/openpyxl/shared/compat/__init__.py trunk/pywikipedia/openpyxl/shared/compat/allany.py trunk/pywikipedia/openpyxl/shared/compat/elementtree.py trunk/pywikipedia/openpyxl/shared/compat/sax.py trunk/pywikipedia/openpyxl/shared/compat/tempnamedfile.py trunk/pywikipedia/openpyxl/shared/date_time.py trunk/pywikipedia/openpyxl/shared/exc.py trunk/pywikipedia/openpyxl/shared/ooxml.py trunk/pywikipedia/openpyxl/shared/password_hasher.py trunk/pywikipedia/openpyxl/shared/units.py trunk/pywikipedia/openpyxl/shared/xmltools.py trunk/pywikipedia/openpyxl/style.py trunk/pywikipedia/openpyxl/workbook.py trunk/pywikipedia/openpyxl/worksheet.py trunk/pywikipedia/openpyxl/writer/ trunk/pywikipedia/openpyxl/writer/__init__.py trunk/pywikipedia/openpyxl/writer/charts.py trunk/pywikipedia/openpyxl/writer/drawings.py trunk/pywikipedia/openpyxl/writer/dump_worksheet.py trunk/pywikipedia/openpyxl/writer/excel.py trunk/pywikipedia/openpyxl/writer/odict.py trunk/pywikipedia/openpyxl/writer/strings.py trunk/pywikipedia/openpyxl/writer/styles.py trunk/pywikipedia/openpyxl/writer/theme.py trunk/pywikipedia/openpyxl/writer/workbook.py trunk/pywikipedia/openpyxl/writer/worksheet.py trunk/pywikipedia/subster.py trunk/pywikipedia/subster_irc.py
Added: trunk/pywikipedia/crontab/PKG-INFO =================================================================== --- trunk/pywikipedia/crontab/PKG-INFO (rev 0) +++ trunk/pywikipedia/crontab/PKG-INFO 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,109 @@ +Metadata-Version: 1.0 +Name: crontab +Version: .14 +Summary: Parse and use crontab schedules in Python +Home-page: https://github.com/josiahcarlson/parse-crontab +Author: Josiah Carlson +Author-email: josiah.carlson@gmail.com +License: GNU LGPL v2.1 +Description: Description + =========== + + This package intends to offer a method of parsing crontab schedule entries and + determining when an item should next be run. More specifically, it calculates + a delay in seconds from when the .next() method is called to when the item + should next be executed. + + Comparing the below chart to http://en.wikipedia.org/wiki/Cron#CRON_expression + you will note that W and # symbols are not supported. + + ============= =========== ================= =========================== + Field Name Mandatory Allowed Values Allowed Special Characters + ============= =========== ================= =========================== + Minutes Yes 0-59 * / , - + Hours Yes 0-23 * / , - + Day of month Yes 1-31 * / , - ? L + Month Yes 1-12 or JAN-DEC * / , - + Day of week Yes 0-6 or SUN-SAT * / , - ? L + Year No 1970-2099 * / , - + ============= =========== ================= =========================== + + + Sample individual crontab fields + ================================ + + Examples of supported entries are as follows:: + + * + */5 + 7/8 + 3-25/7 + 3,7,9 + 0-10,30-40/5 + + For month or day of week entries, 3 letter abbreviations of the month or day + can be used to the left of any optional / where a number could be used. + + For days of the week:: + + mon-fri + sun-thu/2 + + For month:: + + apr-jul + mar-sep/3 + + + Example uses + ============ + + :: + + >>> from crontab import CronTab + >>> from datetime import datetime + >>> # define the crontab for 25 minutes past the hour every hour + ... entry = CronTab('25 * * * *') + >>> # find the delay from when this was run (around 11:13AM) + ... entry.next() + 720.81637899999998 + >>> # find the delay from when it was last scheduled + ... entry.next(datetime(2011, 7, 17, 11, 25)) + 3600.0 + + + Notes + ===== + + At most one of 'day of week' or 'day of month' can be a value other than '?' + or '*'. We violate spec here and allow '*' to be an alias for '?', in the case + where one of those values is specified (seeing as some platforms don't support + '?'). + + This module also supports the convenient aliases:: + + @yearly + @annually + @monthly + @weekly + @daily + @hourly + + Example full crontab entries and their meanings:: + + 30 */2 * * * -> 30 minutes past the hour every 2 hours + 15,45 23 * * * -> 11:15PM and 11:45PM every day + 0 1 ? * SUN -> 1AM every Sunday + 0 1 * * SUN -> 1AM every Sunday (same as above) + 0 0 1 jan/2 * 2011-2013 -> + midnight on January 1, 2011 and the first of every odd month until + the end of 2013 + 24 7 L * * -> 7:24 AM on the last day of every month + 24 7 * * L5 -> 7:24 AM on the last friday of every month + 24 7 * * Lwed-fri -> + 7:24 AM on the last wednesday, thursday, and friday of every month + +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) +Classifier: Programming Language :: Python
Added: trunk/pywikipedia/crontab/README =================================================================== --- trunk/pywikipedia/crontab/README (rev 0) +++ trunk/pywikipedia/crontab/README 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,96 @@ +Description +=========== + +This package intends to offer a method of parsing crontab schedule entries and +determining when an item should next be run. More specifically, it calculates +a delay in seconds from when the .next() method is called to when the item +should next be executed. + +Comparing the below chart to http://en.wikipedia.org/wiki/Cron#CRON_expression +you will note that W and # symbols are not supported. + +============= =========== ================= =========================== +Field Name Mandatory Allowed Values Allowed Special Characters +============= =========== ================= =========================== +Minutes Yes 0-59 * / , - +Hours Yes 0-23 * / , - +Day of month Yes 1-31 * / , - ? L +Month Yes 1-12 or JAN-DEC * / , - +Day of week Yes 0-6 or SUN-SAT * / , - ? L +Year No 1970-2099 * / , - +============= =========== ================= =========================== + + +Sample individual crontab fields +================================ + +Examples of supported entries are as follows:: + + * + */5 + 7/8 + 3-25/7 + 3,7,9 + 0-10,30-40/5 + +For month or day of week entries, 3 letter abbreviations of the month or day +can be used to the left of any optional / where a number could be used. + +For days of the week:: + + mon-fri + sun-thu/2 + +For month:: + + apr-jul + mar-sep/3 + + +Example uses +============ + +:: + + >>> from crontab import CronTab + >>> from datetime import datetime + >>> # define the crontab for 25 minutes past the hour every hour + ... entry = CronTab('25 * * * *') + >>> # find the delay from when this was run (around 11:13AM) + ... entry.next() + 720.81637899999998 + >>> # find the delay from when it was last scheduled + ... entry.next(datetime(2011, 7, 17, 11, 25)) + 3600.0 + + +Notes +===== + +At most one of 'day of week' or 'day of month' can be a value other than '?' +or '*'. We violate spec here and allow '*' to be an alias for '?', in the case +where one of those values is specified (seeing as some platforms don't support +'?'). + +This module also supports the convenient aliases:: + + @yearly + @annually + @monthly + @weekly + @daily + @hourly + +Example full crontab entries and their meanings:: + + 30 */2 * * * -> 30 minutes past the hour every 2 hours + 15,45 23 * * * -> 11:15PM and 11:45PM every day + 0 1 ? * SUN -> 1AM every Sunday + 0 1 * * SUN -> 1AM every Sunday (same as above) + 0 0 1 jan/2 * 2011-2013 -> + midnight on January 1, 2011 and the first of every odd month until + the end of 2013 + 24 7 L * * -> 7:24 AM on the last day of every month + 24 7 * * L5 -> 7:24 AM on the last friday of every month + 24 7 * * Lwed-fri -> + 7:24 AM on the last wednesday, thursday, and friday of every month
Added: trunk/pywikipedia/crontab/__init__.py =================================================================== --- trunk/pywikipedia/crontab/__init__.py (rev 0) +++ trunk/pywikipedia/crontab/__init__.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,4 @@ + +from ._crontab import CronTab + +__all__ = ['CronTab']
Property changes on: trunk/pywikipedia/crontab/__init__.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/crontab/_crontab.py =================================================================== --- trunk/pywikipedia/crontab/_crontab.py (rev 0) +++ trunk/pywikipedia/crontab/_crontab.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,257 @@ + +''' +crontab.py + +Written July 15, 2011 by Josiah Carlson +Released under the GNU LGPL v2.1 +available: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + +Other licenses may be available upon request. + +''' + +from collections import namedtuple +import datetime + +_ranges = [ + (0, 59), + (0, 23), + (1, 31), + (1, 12), + (0, 6), + (1970, 2099), +] +_attribute = [ + 'minute', + 'hour', + 'day', + 'month', + 'isoweekday', + 'year' +] +_alternate = { + 3: {'jan': 1, 'feb': 2, 'mar': 3, 'apr': 4, 'may': 5, 'jun': 6, + 'jul': 7, 'aug': 8, 'sep': 9, 'oct': 10, 'nov':11, 'dec':12}, + 4: {'sun': 0, 'mon': 1, 'tue': 2, 'wed': 3, 'thu': 4, 'fri': 5, 'sat': 6}, +} +_aliases = { + '@yearly': '0 0 1 1 *', + '@annually': '0 0 1 1 *', + '@monthly': '0 0 1 * *', + '@weekly': '0 0 * * 0', + '@daily': '0 0 * * *', + '@hourly': '0 * * * *', +} + +MINUTE = datetime.timedelta(minutes=1) +HOUR = datetime.timedelta(hours=1) +DAY = datetime.timedelta(days=1) +WEEK = datetime.timedelta(days=7) +MONTH = datetime.timedelta(days=28) +YEAR = datetime.timedelta(days=365) + +def _day_incr(dt, m): + if m.day.input != 'l': + return DAY + odt = dt + ndt = dt = dt + DAY + while dt.month == ndt.month: + dt += DAY + return dt - odt + +def _month_incr(dt, m): + odt = dt + dt += MONTH + while dt.month == odt.month: + dt += DAY + # get to the first of next month, let the backtracking handle it + dt = dt.replace(day=1) + return dt - odt + +def _year_incr(dt, m): + # simple leapyear stuff works for 1970-2099 :) + mod = dt.year % 4 + if mod == 0 and (dt.month, dt.day) < (2, 29): + return YEAR + DAY + if mod == 3 and (dt.month, dt.day) > (2, 29): + return YEAR + DAY + return YEAR + +_increments = [ + lambda *a: MINUTE, + lambda *a: HOUR, + _day_incr, + _month_incr, + lambda *a: DAY, + _year_incr, +] + +Matcher = namedtuple('Matcher', 'minute, hour, day, month, weekday, year') + +def _assert(condition, message, *args): + if not condition: + raise ValueError(message%args) + +class _Matcher(object): + __slots__ = 'allowed', 'end', 'any', 'input', 'which' + def __init__(self, which, entry): + _assert(0 <= which <= 5, + "improper number of cron entries specified") + self.input = entry.lower() + self.which = which + self.allowed, self.end = self._parse_crontab(which, entry.lower()) + self.any = self.allowed is None + def __call__(self, v, dt): + if self.input == 'l': + return v != (dt + DAY).month + elif self.input.startswith('l'): + okay = dt.month != (dt + WEEK).month + return okay and (self.any or v in self.allowed) + return self.any or v in self.allowed + def __lt__(self, other): + if self.any: + return self.end < other + return all(item < other for item in self.allowed) + def _parse_crontab(self, which, entry): + ''' + This parses a single crontab field and returns the data necessary for + this matcher to accept the proper values. + + See the README for information about what is accepted. + ''' + # this handles day of week/month abbreviations + def _fix(it): + if which in _alternate and not it.isdigit(): + if it in _alternate[which]: + return _alternate[which][it] + _assert(it.isdigit(), + "invalid range specifier: %r (%r)", it, entry) + return int(it, 10) + + # this handles individual items/ranges + def _parse_piece(it): + if '-' in it: + start, end = map(_fix, it.split('-')) + elif it == '*': + start = _start + end = _end + else: + start = _fix(it) + end = _end + if increment is None: + return set([start]) + _assert(_start <= start <= _end, + "range start value %r out of range [%r, %r]", start, _start, _end) + _assert(_start <= end <= _end, + "range end value %r out of range [%r, %r]", end, _start, _end) + _assert(start <= end, + "range start value %r > end value %r", start, end) + return set(range(start, end+1, increment or 1)) + + _start, _end = _ranges[which] + # wildcards + if entry in ('*', '?'): + if entry == '?': + _assert(which in (2, 4), + "cannot use '?' in the %r field", _attribute[which]) + return None, _end + + # last day of the month + if entry == 'l': + _assert(which == 2, + "you can only specify a bare 'L' in the 'day' field") + return None, _end + + # last day of the week + elif entry.startswith('l'): + _assert(which == 4, + "you can only specify a leading 'L' in the 'weekday' field") + entry = entry.lstrip('l') + + increment = None + # increments + if '/' in entry: + entry, increment = entry.split('/') + increment = int(increment, 10) + _assert(increment > 0, + "you can only use positive increment values, you provided %r", + increment) + + # handle all of the a,b,c and x-y,a,b entries + good = set() + for it in entry.split(','): + good.update(_parse_piece(it)) + + return good, _end + +class CronTab(object): + __slots__ = 'matchers', + def __init__(self, crontab): + self.matchers = self._make_matchers(crontab) + + def _make_matchers(self, crontab): + ''' + This constructs the full matcher struct. + ''' + crontab = _aliases.get(crontab, crontab) + matchers = [_Matcher(which, entry) + for which, entry in enumerate(crontab.split())] + if len(matchers) == 5: + matchers.append(_Matcher(5, '*')) + _assert(len(matchers) == 6, + "improper number of cron entries specified") + matchers = Matcher(*matchers) + if not matchers.day.any: + _assert(matchers.weekday.any, + "missing a wildcard specifier for weekday") + if not matchers.weekday.any: + _assert(matchers.day.any, + "missing a wildcard specifier for day") + return matchers + + def _test_match(self, index, dt): + ''' + This tests the given field for whether it matches with the current + datetime object passed. + ''' + at = _attribute[index] + attr = getattr(dt, at) + if at == 'isoweekday': + attr = attr() % 7 + return self.matchers[index](attr, dt) + + def next(self, now=None): + ''' + How long to wait in seconds before this crontab entry can next be + executed. + ''' + now = now or datetime.datetime.now() + if isinstance(now, (int, long, float)): + now = datetime.datetime.fromtimestamp(now) + # get a reasonable future start time + future = now.replace(second=0, microsecond=0) + datetime.timedelta(minutes=1) + to_test = 0 + while to_test < 6: + incr = _increments[to_test] + while not self._test_match(to_test, future): + future += incr(future, self.matchers) + if self.matchers.year < future.year: + return None + # check for backtrack conditions + if to_test >= 3: + for tt in xrange(2, to_test): + if not self._test_match(tt, future): + # rely on the increment below to get us back to 2 + to_test = 1 + break + to_test += 1 + + # verify the match + match = [self._test_match(i, future) for i in xrange(6)] + _assert(all(match), + "\nYou have discovered a bug with crontab, please notify the\n" \ + "author with the following information:\n" \ + "crontab: %r\n" \ + "now: %r", ' '.join(m.input for m in self.matchers), now) + delay = future - now + return delay.days * 86400 + delay.seconds + delay.microseconds / 1000000.
Property changes on: trunk/pywikipedia/crontab/_crontab.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/APACHE-LICENSE-2.0.txt =================================================================== --- trunk/pywikipedia/odf/APACHE-LICENSE-2.0.txt (rev 0) +++ trunk/pywikipedia/odf/APACHE-LICENSE-2.0.txt 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
Property changes on: trunk/pywikipedia/odf/APACHE-LICENSE-2.0.txt ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/PKG-INFO =================================================================== --- trunk/pywikipedia/odf/PKG-INFO (rev 0) +++ trunk/pywikipedia/odf/PKG-INFO 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,49 @@ +Metadata-Version: 1.0 +Name: odfpy +Version: 0.9.4 +Summary: Python API and tools to manipulate OpenDocument files +Home-page: https://joinup.ec.europa.eu/software/odfpy/home +Author: Soren Roug +Author-email: soren.roug@eea.europa.eu +License: UNKNOWN +Description: + Odfpy is a library to read and write OpenDocument v. 1.1 files. + The main focus has been to prevent the programmer from creating invalid + documents. It has checks that raise an exception if the programmer adds + an invalid element, adds an attribute unknown to the grammar, forgets to + add a required attribute or adds text to an element that doesn't allow it. + + These checks and the API itself were generated from the RelaxNG + schema, and then hand-edited. Therefore the API is complete and can + handle all ODF constructions. + + In addition to the API, there are a few scripts: + + - csv2odf - Create OpenDocument spreadsheet from comma separated values + - mailodf - Email ODF file as HTML archive + - odf2xhtml - Convert ODF to (X)HTML + - odf2mht - Convert ODF to HTML archive + - odf2xml - Create OpenDocument XML file from OD? package + - odfimgimport - Import external images + - odflint - Check ODF file for problems + - odfmeta - List or change the metadata of an ODF file + - odfoutline - Show outline of OpenDocument + - odfuserfield - List or change the user-field declarations in an ODF file + - xml2odf - Create OD? package from OpenDocument in XML form + + Visit https://joinup.ec.europa.eu/software/odfpy/home for documentation and examples. +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: End Users/Desktop +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: Apache Software License +Classifier: License :: OSI Approved :: GNU General Public License (GPL) +Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX +Classifier: Programming Language :: Python :: 2 :: Only +Classifier: Topic :: Office/Business +Classifier: Topic :: Software Development :: Libraries :: Python Modules
Added: trunk/pywikipedia/odf/README =================================================================== --- trunk/pywikipedia/odf/README (rev 0) +++ trunk/pywikipedia/odf/README 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,62 @@ +This is a collection of utility programs written in Python to manipulate +OpenDocument files. + +How to proceed: Each application has its own directory. In there, look +at the manual pages. The Python-based tools need the odf library. Just +make a symbolic link like this: ln -s ../odf odf +... or type: make + +For your own use of the odf library, see api-for-odfpy.odt + + -o- INSTALLATION -o- + +First you get the package. + +$ svn export https://svn.forge.osor.eu/svn/odfpy/trunk odfpy + +$ python setup.py build +$ su +# python setup.py install + +The library is incompatible with PyXML. + + -o- TODO / IDEAS -o- + +* html2odf + Alex Hudson has been contracted to produce a command-line html2odf + converter. It should include support for images, tables, CSS, etc. + He will provide a C# version first, and later a C version. + +* odf2pdf + A valuable tool, but one that is hard to do. PDF is an immensely + popular format, but it's tricky to make PDFs. With an odf2pdf tool + available, many developers would use ODF purely for the purpose of + generating a PDF later. The latest idea is to hire KOffice + developers and get them to trim down KOffice into a converter. + +* pdf2odf + This conversion is less likely to produce good results, but it + might be worth a shot. Poppler is a pdf library that can convert + PDF into XML. Maybe we can convert that XML to ODF. + http://webcvs.freedesktop.org/poppler/poppler/ + +* odfclean + A command-line program that removes unused automatic styles, + metadata and track-changes. Some companies might like to send all + out-going files through odfclean to remove any information they + don't want others to see. + +* odf2xliff + Create XLIFF extraction and merge application. XLIFF is a OASIS file + for translations. You extract the text strings, send them to the translator + and then import them. It allows you to work on the document in the + meantime and only retranslate the changed parts. + +* odfdiff + A program that can generate a diff between two ODF files. Useful for + SVN commit messages. This is very difficult to do. But see: + http://www.manageability.org/blog/stuff/open-source-xml-diff-in-java/view + http://freshmeat.net/projects/xmldiff/ + +* odfsign + Sign and verify the signature(s) of an ODF document.
Property changes on: trunk/pywikipedia/odf/__init__.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/anim.py =================================================================== --- trunk/pywikipedia/odf/anim.py (rev 0) +++ trunk/pywikipedia/odf/anim.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import ANIMNS +from element import Element + + +# Autogenerated +def Animate(**args): + return Element(qname = (ANIMNS,'animate'), **args) + +def Animatecolor(**args): + return Element(qname = (ANIMNS,'animateColor'), **args) + +def Animatemotion(**args): + return Element(qname = (ANIMNS,'animateMotion'), **args) + +def Animatetransform(**args): + return Element(qname = (ANIMNS,'animateTransform'), **args) + +def Audio(**args): + return Element(qname = (ANIMNS,'audio'), **args) + +def Command(**args): + return Element(qname = (ANIMNS,'command'), **args) + +def Iterate(**args): + return Element(qname = (ANIMNS,'iterate'), **args) + +def Par(**args): + return Element(qname = (ANIMNS,'par'), **args) + +def Param(**args): + return Element(qname = (ANIMNS,'param'), **args) + +def Seq(**args): + return Element(qname = (ANIMNS,'seq'), **args) + +def Set(**args): + return Element(qname = (ANIMNS,'set'), **args) + +def Transitionfilter(**args): + return Element(qname = (ANIMNS,'transitionFilter'), **args) +
Property changes on: trunk/pywikipedia/odf/anim.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/attrconverters.py =================================================================== --- trunk/pywikipedia/odf/attrconverters.py (rev 0) +++ trunk/pywikipedia/odf/attrconverters.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,1484 @@ +# -*- 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): +# +from namespaces import * +import re, types + +pattern_color = re.compile(r'#[0-9a-fA-F]{6}') +pattern_vector3D = re.compile(r'([ ]*-?([0-9]+(.[0-9]*)?|.[0-9]+)([ ]+-?([0-9]+(.[0-9]*)?|.[0-9]+)){2}[ ]*)') + +def make_NCName(arg): + for c in (':',' '): + arg = arg.replace(c,"_%x_" % ord(c)) + return arg + +def cnv_anyURI(attribute, arg, element): + return unicode(arg) + +def cnv_boolean(attribute, arg, element): + if arg.lower() in ("false","no"): + return "false" + if arg: + return "true" + return "false" + +# Potentially accept color values +def cnv_color(attribute, arg, element): + """ A RGB color in conformance with §5.9.11 of [XSL], that is a RGB color in notation “#rrggbb”, where + rr, gg and bb are 8-bit hexadecimal digits. + """ + return str(arg) + +def cnv_configtype(attribute, arg, element): + if str(arg) not in ("boolean", "short", "int", "long", + "double", "string", "datetime", "base64Binary"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + +def cnv_data_source_has_labels(attribute, arg, element): + if str(arg) not in ("none","row","column","both"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + +# Understand different date formats +def cnv_date(attribute, arg, element): + """ A dateOrDateTime value is either an [xmlschema-2] date value or an [xmlschema-2] dateTime + value. + """ + return str(arg) + +def cnv_dateTime(attribute, arg, element): + """ A dateOrDateTime value is either an [xmlschema-2] date value or an [xmlschema-2] dateTime + value. + """ + return str(arg) + +def cnv_double(attribute, arg, element): + return str(arg) + +def cnv_duration(attribute, arg, element): + return str(arg) + +def cnv_family(attribute, arg, element): + """ A style family """ + if str(arg) not in ("text", "paragraph", "section", "ruby", "table", "table-column", "table-row", "table-cell", + "graphic", "presentation", "drawing-page", "chart"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + +def __save_prefix(attribute, arg, element): + prefix = arg.split(':',1)[0] + if prefix == arg: + return unicode(arg) + namespace = element.get_knownns(prefix) + if namespace is None: + #raise ValueError, "'%s' is an unknown prefix" % str(prefix) + return unicode(arg) + p = element.get_nsprefix(namespace) + return unicode(arg) + +def cnv_formula(attribute, arg, element): + """ A string containing a formula. Formulas do not have a predefined syntax, but the string should + begin with a namespace prefix, followed by a “:” (COLON, U+003A) separator, followed by the text + of the formula. The namespace bound to the prefix determines the syntax and semantics of the + formula. + """ + return __save_prefix(attribute, arg, element) + +def cnv_ID(attribute, arg, element): + return str(arg) + +def cnv_IDREF(attribute, arg, element): + return str(arg) + +def cnv_integer(attribute, arg, element): + return str(arg) + +def cnv_legend_position(attribute, arg, element): + if str(arg) not in ("start", "end", "top", "bottom", "top-start", "bottom-start", "top-end", "bottom-end"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + +pattern_length = re.compile(r'-?([0-9]+(.[0-9]*)?|.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)|(px))') + +def cnv_length(attribute, arg, element): + """ A (positive or negative) physical length, consisting of magnitude and unit, in conformance with the + Units of Measure defined in §5.9.13 of [XSL]. + """ + global pattern_length + if not pattern_length.match(arg): + raise ValueError, "'%s' is not a valid length" % arg + return arg + +def cnv_lengthorpercent(attribute, arg, element): + failed = False + try: return cnv_length(attribute, arg, element) + except: failed = True + try: return cnv_percent(attribute, arg, element) + except: failed = True + if failed: + raise ValueError, "'%s' is not a valid length or percent" % arg + return arg + +def cnv_metavaluetype(attribute, arg, element): + if str(arg) not in ("float", "date", "time", "boolean", "string"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + +def cnv_major_minor(attribute, arg, element): + if arg not in ('major','minor'): + raise ValueError, "'%s' is not either 'minor' or 'major'" % arg + +pattern_namespacedToken = re.compile(r'[0-9a-zA-Z_]+:[0-9a-zA-Z._-]+') + +def cnv_namespacedToken(attribute, arg, element): + global pattern_namespacedToken + + if not pattern_namespacedToken.match(arg): + raise ValueError, "'%s' is not a valid namespaced token" % arg + return __save_prefix(attribute, arg, element) + +def cnv_NCName(attribute, arg, element): + """ NCName is defined in http://www.w3.org/TR/REC-xml-names/#NT-NCName + Essentially an XML name minus ':' + """ + if type(arg) in types.StringTypes: + return make_NCName(arg) + else: + return arg.getAttrNS(STYLENS, 'name') + +# This function takes either an instance of a style (preferred) +# or a text string naming the style. If it is a text string, then it must +# already have been converted to an NCName +# The text-string argument is mainly for when we build a structure from XML +def cnv_StyleNameRef(attribute, arg, element): + try: + return arg.getAttrNS(STYLENS, 'name') + except: + return arg + +# This function takes either an instance of a style (preferred) +# or a text string naming the style. If it is a text string, then it must +# already have been converted to an NCName +# The text-string argument is mainly for when we build a structure from XML +def cnv_DrawNameRef(attribute, arg, element): + try: + return arg.getAttrNS(DRAWNS, 'name') + except: + return arg + +# Must accept list of Style objects +def cnv_NCNames(attribute, arg, element): + return ' '.join(arg) + +def cnv_nonNegativeInteger(attribute, arg, element): + return str(arg) + +pattern_percent = re.compile(r'-?([0-9]+(.[0-9]*)?|.[0-9]+)%') + +def cnv_percent(attribute, arg, element): + global pattern_percent + if not pattern_percent.match(arg): + raise ValueError, "'%s' is not a valid length" % arg + return arg + +# Real one doesn't allow floating point values +pattern_points = re.compile(r'-?[0-9]+,-?[0-9]+([ ]+-?[0-9]+,-?[0-9]+)*') +#pattern_points = re.compile(r'-?[0-9.]+,-?[0-9.]+([ ]+-?[0-9.]+,-?[0-9.]+)*') +def cnv_points(attribute, arg, element): + global pattern_points + if type(arg) in types.StringTypes: + if not pattern_points.match(arg): + raise ValueError, "x,y are separated by a comma and the points are separated by white spaces" + return arg + else: + try: + strarg = ' '.join([ "%d,%d" % p for p in arg]) + except: + raise ValueError, "Points must be string or [(0,0),(1,1)] - not %s" % arg + return strarg + +def cnv_positiveInteger(attribute, arg, element): + return str(arg) + +def cnv_string(attribute, arg, element): + return unicode(arg) + +def cnv_textnoteclass(attribute, arg, element): + if str(arg) not in ("footnote", "endnote"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + +# Understand different time formats +def cnv_time(attribute, arg, element): + return str(arg) + +def cnv_token(attribute, arg, element): + return str(arg) + +pattern_viewbox = re.compile(r'-?[0-9]+([ ]+-?[0-9]+){3}$') + +def cnv_viewbox(attribute, arg, element): + global pattern_viewbox + if not pattern_viewbox.match(arg): + raise ValueError, "viewBox must be four integers separated by whitespaces" + return arg + +def cnv_xlinkshow(attribute, arg, element): + if str(arg) not in ("new", "replace", "embed"): + raise ValueError, "'%s' not allowed" % str(arg) + return str(arg) + + +attrconverters = { + ((ANIMNS,u'audio-level'), None): cnv_double, + ((ANIMNS,u'color-interpolation'), None): cnv_string, + ((ANIMNS,u'color-interpolation-direction'), None): cnv_string, + ((ANIMNS,u'command'), None): cnv_string, + ((ANIMNS,u'formula'), None): cnv_string, + ((ANIMNS,u'id'), None): cnv_ID, + ((ANIMNS,u'iterate-interval'), None): cnv_duration, + ((ANIMNS,u'iterate-type'), None): cnv_string, + ((ANIMNS,u'name'), None): cnv_string, + ((ANIMNS,u'sub-item'), None): cnv_string, + ((ANIMNS,u'value'), None): cnv_string, +# ((DBNS,u'type'), None): cnv_namespacedToken, + ((CHARTNS,u'attached-axis'), None): cnv_string, + ((CHARTNS,u'class'), (CHARTNS,u'grid')): cnv_major_minor, + ((CHARTNS,u'class'), None): cnv_namespacedToken, + ((CHARTNS,u'column-mapping'), None): cnv_string, + ((CHARTNS,u'connect-bars'), None): cnv_boolean, + ((CHARTNS,u'data-label-number'), None): cnv_string, + ((CHARTNS,u'data-label-symbol'), None): cnv_boolean, + ((CHARTNS,u'data-label-text'), None): cnv_boolean, + ((CHARTNS,u'data-source-has-labels'), None): cnv_data_source_has_labels, + ((CHARTNS,u'deep'), None): cnv_boolean, + ((CHARTNS,u'dimension'), None): cnv_string, + ((CHARTNS,u'display-label'), None): cnv_boolean, + ((CHARTNS,u'error-category'), None): cnv_string, + ((CHARTNS,u'error-lower-indicator'), None): cnv_boolean, + ((CHARTNS,u'error-lower-limit'), None): cnv_string, + ((CHARTNS,u'error-margin'), None): cnv_string, + ((CHARTNS,u'error-percentage'), None): cnv_string, + ((CHARTNS,u'error-upper-indicator'), None): cnv_boolean, + ((CHARTNS,u'error-upper-limit'), None): cnv_string, + ((CHARTNS,u'gap-width'), None): cnv_string, + ((CHARTNS,u'interpolation'), None): cnv_string, + ((CHARTNS,u'interval-major'), None): cnv_string, + ((CHARTNS,u'interval-minor-divisor'), None): cnv_string, + ((CHARTNS,u'japanese-candle-stick'), None): cnv_boolean, + ((CHARTNS,u'label-arrangement'), None): cnv_string, + ((CHARTNS,u'label-cell-address'), None): cnv_string, + ((CHARTNS,u'legend-align'), None): cnv_string, + ((CHARTNS,u'legend-position'), None): cnv_legend_position, + ((CHARTNS,u'lines'), None): cnv_boolean, + ((CHARTNS,u'link-data-style-to-source'), None): cnv_boolean, + ((CHARTNS,u'logarithmic'), None): cnv_boolean, + ((CHARTNS,u'maximum'), None): cnv_string, + ((CHARTNS,u'mean-value'), None): cnv_boolean, + ((CHARTNS,u'minimum'), None): cnv_string, + ((CHARTNS,u'name'), None): cnv_string, + ((CHARTNS,u'origin'), None): cnv_string, + ((CHARTNS,u'overlap'), None): cnv_string, + ((CHARTNS,u'percentage'), None): cnv_boolean, + ((CHARTNS,u'pie-offset'), None): cnv_string, + ((CHARTNS,u'regression-type'), None): cnv_string, + ((CHARTNS,u'repeated'), None): cnv_nonNegativeInteger, + ((CHARTNS,u'row-mapping'), None): cnv_string, + ((CHARTNS,u'scale-text'), None): cnv_boolean, + ((CHARTNS,u'series-source'), None): cnv_string, + ((CHARTNS,u'solid-type'), None): cnv_string, + ((CHARTNS,u'spline-order'), None): cnv_string, + ((CHARTNS,u'spline-resolution'), None): cnv_string, + ((CHARTNS,u'stacked'), None): cnv_boolean, + ((CHARTNS,u'style-name'), None): cnv_StyleNameRef, + ((CHARTNS,u'symbol-height'), None): cnv_string, + ((CHARTNS,u'symbol-name'), None): cnv_string, + ((CHARTNS,u'symbol-type'), None): cnv_string, + ((CHARTNS,u'symbol-width'), None): cnv_string, + ((CHARTNS,u'text-overlap'), None): cnv_boolean, + ((CHARTNS,u'three-dimensional'), None): cnv_boolean, + ((CHARTNS,u'tick-marks-major-inner'), None): cnv_boolean, + ((CHARTNS,u'tick-marks-major-outer'), None): cnv_boolean, + ((CHARTNS,u'tick-marks-minor-inner'), None): cnv_boolean, + ((CHARTNS,u'tick-marks-minor-outer'), None): cnv_boolean, + ((CHARTNS,u'values-cell-range-address'), None): cnv_string, + ((CHARTNS,u'vertical'), None): cnv_boolean, + ((CHARTNS,u'visible'), None): cnv_boolean, + ((CONFIGNS,u'name'), None): cnv_formula, + ((CONFIGNS,u'type'), None): cnv_configtype, + ((DR3DNS,u'ambient-color'), None): cnv_string, + ((DR3DNS,u'back-scale'), None): cnv_string, + ((DR3DNS,u'backface-culling'), None): cnv_string, + ((DR3DNS,u'center'), None): cnv_string, + ((DR3DNS,u'close-back'), None): cnv_boolean, + ((DR3DNS,u'close-front'), None): cnv_boolean, + ((DR3DNS,u'depth'), None): cnv_length, + ((DR3DNS,u'diffuse-color'), None): cnv_string, + ((DR3DNS,u'direction'), None): cnv_string, + ((DR3DNS,u'distance'), None): cnv_length, + ((DR3DNS,u'edge-rounding'), None): cnv_string, + ((DR3DNS,u'edge-rounding-mode'), None): cnv_string, + ((DR3DNS,u'emissive-color'), None): cnv_string, + ((DR3DNS,u'enabled'), None): cnv_boolean, + ((DR3DNS,u'end-angle'), None): cnv_string, + ((DR3DNS,u'focal-length'), None): cnv_length, + ((DR3DNS,u'horizontal-segments'), None): cnv_string, + ((DR3DNS,u'lighting-mode'), None): cnv_boolean, + ((DR3DNS,u'max-edge'), None): cnv_string, + ((DR3DNS,u'min-edge'), None): cnv_string, + ((DR3DNS,u'normals-direction'), None): cnv_string, + ((DR3DNS,u'normals-kind'), None): cnv_string, + ((DR3DNS,u'projection'), None): cnv_string, + ((DR3DNS,u'shade-mode'), None): cnv_string, + ((DR3DNS,u'shadow'), None): cnv_string, + ((DR3DNS,u'shadow-slant'), None): cnv_nonNegativeInteger, + ((DR3DNS,u'shininess'), None): cnv_string, + ((DR3DNS,u'size'), None): cnv_string, + ((DR3DNS,u'specular'), None): cnv_boolean, + ((DR3DNS,u'specular-color'), None): cnv_string, + ((DR3DNS,u'texture-filter'), None): cnv_string, + ((DR3DNS,u'texture-generation-mode-x'), None): cnv_string, + ((DR3DNS,u'texture-generation-mode-y'), None): cnv_string, + ((DR3DNS,u'texture-kind'), None): cnv_string, + ((DR3DNS,u'texture-mode'), None): cnv_string, + ((DR3DNS,u'transform'), None): cnv_string, + ((DR3DNS,u'vertical-segments'), None): cnv_string, + ((DR3DNS,u'vpn'), None): cnv_string, + ((DR3DNS,u'vrp'), None): cnv_string, + ((DR3DNS,u'vup'), None): cnv_string, + ((DRAWNS,u'align'), None): cnv_string, + ((DRAWNS,u'angle'), None): cnv_integer, + ((DRAWNS,u'archive'), None): cnv_string, + ((DRAWNS,u'auto-grow-height'), None): cnv_boolean, + ((DRAWNS,u'auto-grow-width'), None): cnv_boolean, + ((DRAWNS,u'background-size'), None): cnv_string, + ((DRAWNS,u'blue'), None): cnv_string, + ((DRAWNS,u'border'), None): cnv_string, + ((DRAWNS,u'caption-angle'), None): cnv_string, + ((DRAWNS,u'caption-angle-type'), None): cnv_string, + ((DRAWNS,u'caption-escape'), None): cnv_string, + ((DRAWNS,u'caption-escape-direction'), None): cnv_string, + ((DRAWNS,u'caption-fit-line-length'), None): cnv_boolean, + ((DRAWNS,u'caption-gap'), None): cnv_string, + ((DRAWNS,u'caption-line-length'), None): cnv_length, + ((DRAWNS,u'caption-point-x'), None): cnv_string, + ((DRAWNS,u'caption-point-y'), None): cnv_string, + ((DRAWNS,u'caption-id'), None): cnv_IDREF, + ((DRAWNS,u'caption-type'), None): cnv_string, + ((DRAWNS,u'chain-next-name'), None): cnv_string, + ((DRAWNS,u'class-id'), None): cnv_string, + ((DRAWNS,u'class-names'), None): cnv_NCNames, + ((DRAWNS,u'code'), None): cnv_string, + ((DRAWNS,u'color'), None): cnv_string, + ((DRAWNS,u'color-inversion'), None): cnv_boolean, + ((DRAWNS,u'color-mode'), None): cnv_string, + ((DRAWNS,u'concave'), None): cnv_string, + ((DRAWNS,u'concentric-gradient-fill-allowed'), None): cnv_boolean, + ((DRAWNS,u'contrast'), None): cnv_string, + ((DRAWNS,u'control'), None): cnv_IDREF, + ((DRAWNS,u'copy-of'), None): cnv_string, + ((DRAWNS,u'corner-radius'), None): cnv_length, + ((DRAWNS,u'corners'), None): cnv_positiveInteger, + ((DRAWNS,u'cx'), None): cnv_string, + ((DRAWNS,u'cy'), None): cnv_string, + ((DRAWNS,u'data'), None): cnv_string, + ((DRAWNS,u'decimal-places'), None): cnv_string, + ((DRAWNS,u'display'), None): cnv_string, + ((DRAWNS,u'display-name'), None): cnv_string, + ((DRAWNS,u'distance'), None): cnv_lengthorpercent, + ((DRAWNS,u'dots1'), None): cnv_integer, + ((DRAWNS,u'dots1-length'), None): cnv_lengthorpercent, + ((DRAWNS,u'dots2'), None): cnv_integer, + ((DRAWNS,u'dots2-length'), None): cnv_lengthorpercent, + ((DRAWNS,u'end-angle'), None): cnv_double, + ((DRAWNS,u'end'), None): cnv_string, + ((DRAWNS,u'end-color'), None): cnv_string, + ((DRAWNS,u'end-glue-point'), None): cnv_nonNegativeInteger, + ((DRAWNS,u'end-guide'), None): cnv_length, + ((DRAWNS,u'end-intensity'), None): cnv_string, + ((DRAWNS,u'end-line-spacing-horizontal'), None): cnv_string, + ((DRAWNS,u'end-line-spacing-vertical'), None): cnv_string, + ((DRAWNS,u'end-shape'), None): cnv_IDREF, + ((DRAWNS,u'engine'), None): cnv_namespacedToken, + ((DRAWNS,u'enhanced-path'), None): cnv_string, + ((DRAWNS,u'escape-direction'), None): cnv_string, + ((DRAWNS,u'extrusion-allowed'), None): cnv_boolean, + ((DRAWNS,u'extrusion-brightness'), None): cnv_string, + ((DRAWNS,u'extrusion'), None): cnv_boolean, + ((DRAWNS,u'extrusion-color'), None): cnv_boolean, + ((DRAWNS,u'extrusion-depth'), None): cnv_double, + ((DRAWNS,u'extrusion-diffusion'), None): cnv_string, + ((DRAWNS,u'extrusion-first-light-direction'), None): cnv_string, + ((DRAWNS,u'extrusion-first-light-harsh'), None): cnv_boolean, + ((DRAWNS,u'extrusion-first-light-level'), None): cnv_string, + ((DRAWNS,u'extrusion-light-face'), None): cnv_boolean, + ((DRAWNS,u'extrusion-metal'), None): cnv_boolean, + ((DRAWNS,u'extrusion-number-of-line-segments'), None): cnv_integer, + ((DRAWNS,u'extrusion-origin'), None): cnv_double, + ((DRAWNS,u'extrusion-rotation-angle'), None): cnv_double, + ((DRAWNS,u'extrusion-rotation-center'), None): cnv_string, + ((DRAWNS,u'extrusion-second-light-direction'), None): cnv_string, + ((DRAWNS,u'extrusion-second-light-harsh'), None): cnv_boolean, + ((DRAWNS,u'extrusion-second-light-level'), None): cnv_string, + ((DRAWNS,u'extrusion-shininess'), None): cnv_string, + ((DRAWNS,u'extrusion-skew'), None): cnv_double, + ((DRAWNS,u'extrusion-specularity'), None): cnv_string, + ((DRAWNS,u'extrusion-viewpoint'), None): cnv_string, + ((DRAWNS,u'fill'), None): cnv_string, + ((DRAWNS,u'fill-color'), None): cnv_string, + ((DRAWNS,u'fill-gradient-name'), None): cnv_string, + ((DRAWNS,u'fill-hatch-name'), None): cnv_string, + ((DRAWNS,u'fill-hatch-solid'), None): cnv_boolean, + ((DRAWNS,u'fill-image-height'), None): cnv_lengthorpercent, + ((DRAWNS,u'fill-image-name'), None): cnv_DrawNameRef, + ((DRAWNS,u'fill-image-ref-point'), None): cnv_string, + ((DRAWNS,u'fill-image-ref-point-x'), None): cnv_string, + ((DRAWNS,u'fill-image-ref-point-y'), None): cnv_string, + ((DRAWNS,u'fill-image-width'), None): cnv_lengthorpercent, + ((DRAWNS,u'filter-name'), None): cnv_string, + ((DRAWNS,u'fit-to-contour'), None): cnv_boolean, + ((DRAWNS,u'fit-to-size'), None): cnv_boolean, + ((DRAWNS,u'formula'), None): cnv_string, + ((DRAWNS,u'frame-display-border'), None): cnv_boolean, + ((DRAWNS,u'frame-display-scrollbar'), None): cnv_boolean, + ((DRAWNS,u'frame-margin-horizontal'), None): cnv_string, + ((DRAWNS,u'frame-margin-vertical'), None): cnv_string, + ((DRAWNS,u'frame-name'), None): cnv_string, + ((DRAWNS,u'gamma'), None): cnv_string, + ((DRAWNS,u'glue-point-leaving-directions'), None): cnv_string, + ((DRAWNS,u'glue-point-type'), None): cnv_string, + ((DRAWNS,u'glue-points'), None): cnv_string, + ((DRAWNS,u'gradient-step-count'), None): cnv_string, + ((DRAWNS,u'green'), None): cnv_string, + ((DRAWNS,u'guide-distance'), None): cnv_string, + ((DRAWNS,u'guide-overhang'), None): cnv_length, + ((DRAWNS,u'handle-mirror-horizontal'), None): cnv_boolean, + ((DRAWNS,u'handle-mirror-vertical'), None): cnv_boolean, + ((DRAWNS,u'handle-polar'), None): cnv_string, + ((DRAWNS,u'handle-position'), None): cnv_string, + ((DRAWNS,u'handle-radius-range-maximum'), None): cnv_string, + ((DRAWNS,u'handle-radius-range-minimum'), None): cnv_string, + ((DRAWNS,u'handle-range-x-maximum'), None): cnv_string, + ((DRAWNS,u'handle-range-x-minimum'), None): cnv_string, + ((DRAWNS,u'handle-range-y-maximum'), None): cnv_string, + ((DRAWNS,u'handle-range-y-minimum'), None): cnv_string, + ((DRAWNS,u'handle-switched'), None): cnv_boolean, +# ((DRAWNS,u'id'), None): cnv_ID, +# ((DRAWNS,u'id'), None): cnv_nonNegativeInteger, # ?? line 6581 in RNG + ((DRAWNS,u'id'), None): cnv_string, + ((DRAWNS,u'image-opacity'), None): cnv_string, + ((DRAWNS,u'kind'), None): cnv_string, + ((DRAWNS,u'layer'), None): cnv_string, + ((DRAWNS,u'line-distance'), None): cnv_string, + ((DRAWNS,u'line-skew'), None): cnv_string, + ((DRAWNS,u'luminance'), None): cnv_string, + ((DRAWNS,u'marker-end-center'), None): cnv_boolean, + ((DRAWNS,u'marker-end'), None): cnv_string, + ((DRAWNS,u'marker-end-width'), None): cnv_length, + ((DRAWNS,u'marker-start-center'), None): cnv_boolean, + ((DRAWNS,u'marker-start'), None): cnv_string, + ((DRAWNS,u'marker-start-width'), None): cnv_length, + ((DRAWNS,u'master-page-name'), None): cnv_StyleNameRef, + ((DRAWNS,u'may-script'), None): cnv_boolean, + ((DRAWNS,u'measure-align'), None): cnv_string, + ((DRAWNS,u'measure-vertical-align'), None): cnv_string, + ((DRAWNS,u'mime-type'), None): cnv_string, + ((DRAWNS,u'mirror-horizontal'), None): cnv_boolean, + ((DRAWNS,u'mirror-vertical'), None): cnv_boolean, + ((DRAWNS,u'modifiers'), None): cnv_string, + ((DRAWNS,u'name'), None): cnv_NCName, +# ((DRAWNS,u'name'), None): cnv_string, + ((DRAWNS,u'nav-order'), None): cnv_IDREF, + ((DRAWNS,u'nohref'), None): cnv_string, + ((DRAWNS,u'notify-on-update-of-ranges'), None): cnv_string, + ((DRAWNS,u'object'), None): cnv_string, + ((DRAWNS,u'ole-draw-aspect'), None): cnv_string, + ((DRAWNS,u'opacity'), None): cnv_string, + ((DRAWNS,u'opacity-name'), None): cnv_string, + ((DRAWNS,u'page-number'), None): cnv_positiveInteger, + ((DRAWNS,u'parallel'), None): cnv_boolean, + ((DRAWNS,u'path-stretchpoint-x'), None): cnv_double, + ((DRAWNS,u'path-stretchpoint-y'), None): cnv_double, + ((DRAWNS,u'placing'), None): cnv_string, + ((DRAWNS,u'points'), None): cnv_points, + ((DRAWNS,u'protected'), None): cnv_boolean, + ((DRAWNS,u'recreate-on-edit'), None): cnv_boolean, + ((DRAWNS,u'red'), None): cnv_string, + ((DRAWNS,u'rotation'), None): cnv_integer, + ((DRAWNS,u'secondary-fill-color'), None): cnv_string, + ((DRAWNS,u'shadow'), None): cnv_string, + ((DRAWNS,u'shadow-color'), None): cnv_string, + ((DRAWNS,u'shadow-offset-x'), None): cnv_length, + ((DRAWNS,u'shadow-offset-y'), None): cnv_length, + ((DRAWNS,u'shadow-opacity'), None): cnv_string, + ((DRAWNS,u'shape-id'), None): cnv_IDREF, + ((DRAWNS,u'sharpness'), None): cnv_string, + ((DRAWNS,u'show-unit'), None): cnv_boolean, + ((DRAWNS,u'start-angle'), None): cnv_double, + ((DRAWNS,u'start'), None): cnv_string, + ((DRAWNS,u'start-color'), None): cnv_string, + ((DRAWNS,u'start-glue-point'), None): cnv_nonNegativeInteger, + ((DRAWNS,u'start-guide'), None): cnv_length, + ((DRAWNS,u'start-intensity'), None): cnv_string, + ((DRAWNS,u'start-line-spacing-horizontal'), None): cnv_string, + ((DRAWNS,u'start-line-spacing-vertical'), None): cnv_string, + ((DRAWNS,u'start-shape'), None): cnv_IDREF, + ((DRAWNS,u'stroke'), None): cnv_string, + ((DRAWNS,u'stroke-dash'), None): cnv_string, + ((DRAWNS,u'stroke-dash-names'), None): cnv_string, + ((DRAWNS,u'stroke-linejoin'), None): cnv_string, + ((DRAWNS,u'style'), None): cnv_string, + ((DRAWNS,u'style-name'), None): cnv_StyleNameRef, + ((DRAWNS,u'symbol-color'), None): cnv_string, + ((DRAWNS,u'text-areas'), None): cnv_string, + ((DRAWNS,u'text-path-allowed'), None): cnv_boolean, + ((DRAWNS,u'text-path'), None): cnv_boolean, + ((DRAWNS,u'text-path-mode'), None): cnv_string, + ((DRAWNS,u'text-path-same-letter-heights'), None): cnv_boolean, + ((DRAWNS,u'text-path-scale'), None): cnv_string, + ((DRAWNS,u'text-rotate-angle'), None): cnv_double, + ((DRAWNS,u'text-style-name'), None): cnv_StyleNameRef, + ((DRAWNS,u'textarea-horizontal-align'), None): cnv_string, + ((DRAWNS,u'textarea-vertical-align'), None): cnv_string, + ((DRAWNS,u'tile-repeat-offset'), None): cnv_string, + ((DRAWNS,u'transform'), None): cnv_string, + ((DRAWNS,u'type'), None): cnv_string, + ((DRAWNS,u'unit'), None): cnv_string, + ((DRAWNS,u'value'), None): cnv_string, + ((DRAWNS,u'visible-area-height'), None): cnv_string, + ((DRAWNS,u'visible-area-left'), None): cnv_string, + ((DRAWNS,u'visible-area-top'), None): cnv_string, + ((DRAWNS,u'visible-area-width'), None): cnv_string, + ((DRAWNS,u'wrap-influence-on-position'), None): cnv_string, + ((DRAWNS,u'z-index'), None): cnv_nonNegativeInteger, + ((FONS,u'background-color'), None): cnv_string, + ((FONS,u'border-bottom'), None): cnv_string, + ((FONS,u'border'), None): cnv_string, + ((FONS,u'border-left'), None): cnv_string, + ((FONS,u'border-right'), None): cnv_string, + ((FONS,u'border-top'), None): cnv_string, + ((FONS,u'break-after'), None): cnv_string, + ((FONS,u'break-before'), None): cnv_string, + ((FONS,u'clip'), None): cnv_string, + ((FONS,u'color'), None): cnv_string, + ((FONS,u'column-count'), None): cnv_positiveInteger, + ((FONS,u'column-gap'), None): cnv_length, + ((FONS,u'country'), None): cnv_token, + ((FONS,u'end-indent'), None): cnv_length, + ((FONS,u'font-family'), None): cnv_string, + ((FONS,u'font-size'), None): cnv_string, + ((FONS,u'font-style'), None): cnv_string, + ((FONS,u'font-variant'), None): cnv_string, + ((FONS,u'font-weight'), None): cnv_string, + ((FONS,u'height'), None): cnv_string, + ((FONS,u'hyphenate'), None): cnv_boolean, + ((FONS,u'hyphenation-keep'), None): cnv_string, + ((FONS,u'hyphenation-ladder-count'), None): cnv_string, + ((FONS,u'hyphenation-push-char-count'), None): cnv_string, + ((FONS,u'hyphenation-remain-char-count'), None): cnv_string, + ((FONS,u'keep-together'), None): cnv_string, + ((FONS,u'keep-with-next'), None): cnv_string, + ((FONS,u'language'), None): cnv_token, + ((FONS,u'letter-spacing'), None): cnv_string, + ((FONS,u'line-height'), None): cnv_string, + ((FONS,u'margin-bottom'), None): cnv_string, + ((FONS,u'margin'), None): cnv_string, + ((FONS,u'margin-left'), None): cnv_string, + ((FONS,u'margin-right'), None): cnv_string, + ((FONS,u'margin-top'), None): cnv_string, + ((FONS,u'max-height'), None): cnv_string, + ((FONS,u'max-width'), None): cnv_string, + ((FONS,u'min-height'), None): cnv_length, + ((FONS,u'min-width'), None): cnv_string, + ((FONS,u'orphans'), None): cnv_string, + ((FONS,u'padding-bottom'), None): cnv_string, + ((FONS,u'padding'), None): cnv_string, + ((FONS,u'padding-left'), None): cnv_string, + ((FONS,u'padding-right'), None): cnv_string, + ((FONS,u'padding-top'), None): cnv_string, + ((FONS,u'page-height'), None): cnv_length, + ((FONS,u'page-width'), None): cnv_length, + ((FONS,u'space-after'), None): cnv_length, + ((FONS,u'space-before'), None): cnv_length, + ((FONS,u'start-indent'), None): cnv_length, + ((FONS,u'text-align'), None): cnv_string, + ((FONS,u'text-align-last'), None): cnv_string, + ((FONS,u'text-indent'), None): cnv_string, + ((FONS,u'text-shadow'), None): cnv_string, + ((FONS,u'text-transform'), None): cnv_string, + ((FONS,u'widows'), None): cnv_string, + ((FONS,u'width'), None): cnv_string, + ((FONS,u'wrap-option'), None): cnv_string, + ((FORMNS,u'allow-deletes'), None): cnv_boolean, + ((FORMNS,u'allow-inserts'), None): cnv_boolean, + ((FORMNS,u'allow-updates'), None): cnv_boolean, + ((FORMNS,u'apply-design-mode'), None): cnv_boolean, + ((FORMNS,u'apply-filter'), None): cnv_boolean, + ((FORMNS,u'auto-complete'), None): cnv_boolean, + ((FORMNS,u'automatic-focus'), None): cnv_boolean, + ((FORMNS,u'bound-column'), None): cnv_string, + ((FORMNS,u'button-type'), None): cnv_string, + ((FORMNS,u'command'), None): cnv_string, + ((FORMNS,u'command-type'), None): cnv_string, + ((FORMNS,u'control-implementation'), None): cnv_namespacedToken, + ((FORMNS,u'convert-empty-to-null'), None): cnv_boolean, + ((FORMNS,u'current-selected'), None): cnv_boolean, + ((FORMNS,u'current-state'), None): cnv_string, +# ((FORMNS,u'current-value'), None): cnv_date, +# ((FORMNS,u'current-value'), None): cnv_double, + ((FORMNS,u'current-value'), None): cnv_string, +# ((FORMNS,u'current-value'), None): cnv_time, + ((FORMNS,u'data-field'), None): cnv_string, + ((FORMNS,u'datasource'), None): cnv_string, + ((FORMNS,u'default-button'), None): cnv_boolean, + ((FORMNS,u'delay-for-repeat'), None): cnv_duration, + ((FORMNS,u'detail-fields'), None): cnv_string, + ((FORMNS,u'disabled'), None): cnv_boolean, + ((FORMNS,u'dropdown'), None): cnv_boolean, + ((FORMNS,u'echo-char'), None): cnv_string, + ((FORMNS,u'enctype'), None): cnv_string, + ((FORMNS,u'escape-processing'), None): cnv_boolean, + ((FORMNS,u'filter'), None): cnv_string, + ((FORMNS,u'focus-on-click'), None): cnv_boolean, + ((FORMNS,u'for'), None): cnv_string, + ((FORMNS,u'id'), None): cnv_ID, + ((FORMNS,u'ignore-result'), None): cnv_boolean, + ((FORMNS,u'image-align'), None): cnv_string, + ((FORMNS,u'image-data'), None): cnv_anyURI, + ((FORMNS,u'image-position'), None): cnv_string, + ((FORMNS,u'is-tristate'), None): cnv_boolean, + ((FORMNS,u'label'), None): cnv_string, + ((FORMNS,u'list-source'), None): cnv_string, + ((FORMNS,u'list-source-type'), None): cnv_string, + ((FORMNS,u'master-fields'), None): cnv_string, + ((FORMNS,u'max-length'), None): cnv_nonNegativeInteger, +# ((FORMNS,u'max-value'), None): cnv_date, +# ((FORMNS,u'max-value'), None): cnv_double, + ((FORMNS,u'max-value'), None): cnv_string, +# ((FORMNS,u'max-value'), None): cnv_time, + ((FORMNS,u'method'), None): cnv_string, +# ((FORMNS,u'min-value'), None): cnv_date, +# ((FORMNS,u'min-value'), None): cnv_double, + ((FORMNS,u'min-value'), None): cnv_string, +# ((FORMNS,u'min-value'), None): cnv_time, + ((FORMNS,u'multi-line'), None): cnv_boolean, + ((FORMNS,u'multiple'), None): cnv_boolean, + ((FORMNS,u'name'), None): cnv_string, + ((FORMNS,u'navigation-mode'), None): cnv_string, + ((FORMNS,u'order'), None): cnv_string, + ((FORMNS,u'orientation'), None): cnv_string, + ((FORMNS,u'page-step-size'), None): cnv_positiveInteger, + ((FORMNS,u'printable'), None): cnv_boolean, + ((FORMNS,u'property-name'), None): cnv_string, + ((FORMNS,u'readonly'), None): cnv_boolean, + ((FORMNS,u'selected'), None): cnv_boolean, + ((FORMNS,u'size'), None): cnv_nonNegativeInteger, + ((FORMNS,u'state'), None): cnv_string, + ((FORMNS,u'step-size'), None): cnv_positiveInteger, + ((FORMNS,u'tab-cycle'), None): cnv_string, + ((FORMNS,u'tab-index'), None): cnv_nonNegativeInteger, + ((FORMNS,u'tab-stop'), None): cnv_boolean, + ((FORMNS,u'text-style-name'), None): cnv_StyleNameRef, + ((FORMNS,u'title'), None): cnv_string, + ((FORMNS,u'toggle'), None): cnv_boolean, + ((FORMNS,u'validation'), None): cnv_boolean, +# ((FORMNS,u'value'), None): cnv_date, +# ((FORMNS,u'value'), None): cnv_double, + ((FORMNS,u'value'), None): cnv_string, +# ((FORMNS,u'value'), None): cnv_time, + ((FORMNS,u'visual-effect'), None): cnv_string, + ((FORMNS,u'xforms-list-source'), None): cnv_string, + ((FORMNS,u'xforms-submission'), None): cnv_string, + ((MANIFESTNS,'algorithm-name'), None): cnv_string, + ((MANIFESTNS,'checksum'), None): cnv_string, + ((MANIFESTNS,'checksum-type'), None): cnv_string, + ((MANIFESTNS,'full-path'), None): cnv_string, + ((MANIFESTNS,'initialisation-vector'), None): cnv_string, + ((MANIFESTNS,'iteration-count'), None): cnv_nonNegativeInteger, + ((MANIFESTNS,'key-derivation-name'), None): cnv_string, + ((MANIFESTNS,'media-type'), None): cnv_string, + ((MANIFESTNS,'salt'), None): cnv_string, + ((MANIFESTNS,'size'), None): cnv_nonNegativeInteger, + ((METANS,u'cell-count'), None): cnv_nonNegativeInteger, + ((METANS,u'character-count'), None): cnv_nonNegativeInteger, + ((METANS,u'date'), None): cnv_dateTime, + ((METANS,u'delay'), None): cnv_duration, + ((METANS,u'draw-count'), None): cnv_nonNegativeInteger, + ((METANS,u'frame-count'), None): cnv_nonNegativeInteger, + ((METANS,u'image-count'), None): cnv_nonNegativeInteger, + ((METANS,u'name'), None): cnv_string, + ((METANS,u'non-whitespace-character-count'), None): cnv_nonNegativeInteger, + ((METANS,u'object-count'), None): cnv_nonNegativeInteger, + ((METANS,u'ole-object-count'), None): cnv_nonNegativeInteger, + ((METANS,u'page-count'), None): cnv_nonNegativeInteger, + ((METANS,u'paragraph-count'), None): cnv_nonNegativeInteger, + ((METANS,u'row-count'), None): cnv_nonNegativeInteger, + ((METANS,u'sentence-count'), None): cnv_nonNegativeInteger, + ((METANS,u'syllable-count'), None): cnv_nonNegativeInteger, + ((METANS,u'table-count'), None): cnv_nonNegativeInteger, + ((METANS,u'value-type'), None): cnv_metavaluetype, + ((METANS,u'word-count'), None): cnv_nonNegativeInteger, + ((NUMBERNS,u'automatic-order'), None): cnv_boolean, + ((NUMBERNS,u'calendar'), None): cnv_string, + ((NUMBERNS,u'country'), None): cnv_token, + ((NUMBERNS,u'decimal-places'), None): cnv_integer, + ((NUMBERNS,u'decimal-replacement'), None): cnv_string, + ((NUMBERNS,u'denominator-value'), None): cnv_integer, + ((NUMBERNS,u'display-factor'), None): cnv_double, + ((NUMBERNS,u'format-source'), None): cnv_string, + ((NUMBERNS,u'grouping'), None): cnv_boolean, + ((NUMBERNS,u'language'), None): cnv_token, + ((NUMBERNS,u'min-denominator-digits'), None): cnv_integer, + ((NUMBERNS,u'min-exponent-digits'), None): cnv_integer, + ((NUMBERNS,u'min-integer-digits'), None): cnv_integer, + ((NUMBERNS,u'min-numerator-digits'), None): cnv_integer, + ((NUMBERNS,u'position'), None): cnv_integer, + ((NUMBERNS,u'possessive-form'), None): cnv_boolean, + ((NUMBERNS,u'style'), None): cnv_string, + ((NUMBERNS,u'textual'), None): cnv_boolean, + ((NUMBERNS,u'title'), None): cnv_string, + ((NUMBERNS,u'transliteration-country'), None): cnv_token, + ((NUMBERNS,u'transliteration-format'), None): cnv_string, + ((NUMBERNS,u'transliteration-language'), None): cnv_token, + ((NUMBERNS,u'transliteration-style'), None): cnv_string, + ((NUMBERNS,u'truncate-on-overflow'), None): cnv_boolean, + ((OFFICENS,u'automatic-update'), None): cnv_boolean, + ((OFFICENS,u'boolean-value'), None): cnv_boolean, + ((OFFICENS,u'conversion-mode'), None): cnv_string, + ((OFFICENS,u'currency'), None): cnv_string, + ((OFFICENS,u'date-value'), None): cnv_dateTime, + ((OFFICENS,u'dde-application'), None): cnv_string, + ((OFFICENS,u'dde-item'), None): cnv_string, + ((OFFICENS,u'dde-topic'), None): cnv_string, + ((OFFICENS,u'display'), None): cnv_boolean, + ((OFFICENS,u'mimetype'), None): cnv_string, + ((OFFICENS,u'name'), None): cnv_string, + ((OFFICENS,u'process-content'), None): cnv_boolean, + ((OFFICENS,u'server-map'), None): cnv_boolean, + ((OFFICENS,u'string-value'), None): cnv_string, + ((OFFICENS,u'target-frame'), None): cnv_string, + ((OFFICENS,u'target-frame-name'), None): cnv_string, + ((OFFICENS,u'time-value'), None): cnv_duration, + ((OFFICENS,u'title'), None): cnv_string, + ((OFFICENS,u'value'), None): cnv_double, + ((OFFICENS,u'value-type'), None): cnv_string, + ((OFFICENS,u'version'), None): cnv_string, + ((PRESENTATIONNS,u'action'), None): cnv_string, + ((PRESENTATIONNS,u'animations'), None): cnv_string, + ((PRESENTATIONNS,u'background-objects-visible'), None): cnv_boolean, + ((PRESENTATIONNS,u'background-visible'), None): cnv_boolean, + ((PRESENTATIONNS,u'class'), None): cnv_string, + ((PRESENTATIONNS,u'class-names'), None): cnv_NCNames, + ((PRESENTATIONNS,u'delay'), None): cnv_duration, + ((PRESENTATIONNS,u'direction'), None): cnv_string, + ((PRESENTATIONNS,u'display-date-time'), None): cnv_boolean, + ((PRESENTATIONNS,u'display-footer'), None): cnv_boolean, + ((PRESENTATIONNS,u'display-header'), None): cnv_boolean, + ((PRESENTATIONNS,u'display-page-number'), None): cnv_boolean, + ((PRESENTATIONNS,u'duration'), None): cnv_string, + ((PRESENTATIONNS,u'effect'), None): cnv_string, + ((PRESENTATIONNS,u'endless'), None): cnv_boolean, + ((PRESENTATIONNS,u'force-manual'), None): cnv_boolean, + ((PRESENTATIONNS,u'full-screen'), None): cnv_boolean, + ((PRESENTATIONNS,u'group-id'), None): cnv_string, + ((PRESENTATIONNS,u'master-element'), None): cnv_IDREF, + ((PRESENTATIONNS,u'mouse-as-pen'), None): cnv_boolean, + ((PRESENTATIONNS,u'mouse-visible'), None): cnv_boolean, + ((PRESENTATIONNS,u'name'), None): cnv_string, + ((PRESENTATIONNS,u'node-type'), None): cnv_string, + ((PRESENTATIONNS,u'object'), None): cnv_string, + ((PRESENTATIONNS,u'pages'), None): cnv_string, + ((PRESENTATIONNS,u'path-id'), None): cnv_string, + ((PRESENTATIONNS,u'pause'), None): cnv_duration, + ((PRESENTATIONNS,u'placeholder'), None): cnv_boolean, + ((PRESENTATIONNS,u'play-full'), None): cnv_boolean, + ((PRESENTATIONNS,u'presentation-page-layout-name'), None): cnv_StyleNameRef, + ((PRESENTATIONNS,u'preset-class'), None): cnv_string, + ((PRESENTATIONNS,u'preset-id'), None): cnv_string, + ((PRESENTATIONNS,u'preset-sub-type'), None): cnv_string, + ((PRESENTATIONNS,u'show'), None): cnv_string, + ((PRESENTATIONNS,u'show-end-of-presentation-slide'), None): cnv_boolean, + ((PRESENTATIONNS,u'show-logo'), None): cnv_boolean, + ((PRESENTATIONNS,u'source'), None): cnv_string, + ((PRESENTATIONNS,u'speed'), None): cnv_string, + ((PRESENTATIONNS,u'start-page'), None): cnv_string, + ((PRESENTATIONNS,u'start-scale'), None): cnv_string, + ((PRESENTATIONNS,u'start-with-navigator'), None): cnv_boolean, + ((PRESENTATIONNS,u'stay-on-top'), None): cnv_boolean, + ((PRESENTATIONNS,u'style-name'), None): cnv_StyleNameRef, + ((PRESENTATIONNS,u'transition-on-click'), None): cnv_string, + ((PRESENTATIONNS,u'transition-speed'), None): cnv_string, + ((PRESENTATIONNS,u'transition-style'), None): cnv_string, + ((PRESENTATIONNS,u'transition-type'), None): cnv_string, + ((PRESENTATIONNS,u'use-date-time-name'), None): cnv_string, + ((PRESENTATIONNS,u'use-footer-name'), None): cnv_string, + ((PRESENTATIONNS,u'use-header-name'), None): cnv_string, + ((PRESENTATIONNS,u'user-transformed'), None): cnv_boolean, + ((PRESENTATIONNS,u'verb'), None): cnv_nonNegativeInteger, + ((PRESENTATIONNS,u'visibility'), None): cnv_string, + ((SCRIPTNS,u'event-name'), None): cnv_formula, + ((SCRIPTNS,u'language'), None): cnv_formula, + ((SCRIPTNS,u'macro-name'), None): cnv_string, + ((SMILNS,u'accelerate'), None): cnv_double, + ((SMILNS,u'accumulate'), None): cnv_string, + ((SMILNS,u'additive'), None): cnv_string, + ((SMILNS,u'attributeName'), None): cnv_string, + ((SMILNS,u'autoReverse'), None): cnv_boolean, + ((SMILNS,u'begin'), None): cnv_string, + ((SMILNS,u'by'), None): cnv_string, + ((SMILNS,u'calcMode'), None): cnv_string, + ((SMILNS,u'decelerate'), None): cnv_double, + ((SMILNS,u'direction'), None): cnv_string, + ((SMILNS,u'dur'), None): cnv_string, + ((SMILNS,u'end'), None): cnv_string, + ((SMILNS,u'endsync'), None): cnv_string, + ((SMILNS,u'fadeColor'), None): cnv_string, + ((SMILNS,u'fill'), None): cnv_string, + ((SMILNS,u'fillDefault'), None): cnv_string, + ((SMILNS,u'from'), None): cnv_string, + ((SMILNS,u'keySplines'), None): cnv_string, + ((SMILNS,u'keyTimes'), None): cnv_string, + ((SMILNS,u'mode'), None): cnv_string, + ((SMILNS,u'repeatCount'), None): cnv_nonNegativeInteger, + ((SMILNS,u'repeatDur'), None): cnv_string, + ((SMILNS,u'restart'), None): cnv_string, + ((SMILNS,u'restartDefault'), None): cnv_string, + ((SMILNS,u'subtype'), None): cnv_string, + ((SMILNS,u'targetElement'), None): cnv_IDREF, + ((SMILNS,u'to'), None): cnv_string, + ((SMILNS,u'type'), None): cnv_string, + ((SMILNS,u'values'), None): cnv_string, + ((STYLENS,u'adjustment'), None): cnv_string, + ((STYLENS,u'apply-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'auto-text-indent'), None): cnv_boolean, + ((STYLENS,u'auto-update'), None): cnv_boolean, + ((STYLENS,u'background-transparency'), None): cnv_string, + ((STYLENS,u'base-cell-address'), None): cnv_string, + ((STYLENS,u'border-line-width-bottom'), None): cnv_string, + ((STYLENS,u'border-line-width'), None): cnv_string, + ((STYLENS,u'border-line-width-left'), None): cnv_string, + ((STYLENS,u'border-line-width-right'), None): cnv_string, + ((STYLENS,u'border-line-width-top'), None): cnv_string, + ((STYLENS,u'cell-protect'), None): cnv_string, + ((STYLENS,u'char'), None): cnv_string, + ((STYLENS,u'class'), None): cnv_string, + ((STYLENS,u'color'), None): cnv_string, + ((STYLENS,u'column-width'), None): cnv_string, + ((STYLENS,u'condition'), None): cnv_string, + ((STYLENS,u'country-asian'), None): cnv_string, + ((STYLENS,u'country-complex'), None): cnv_string, + ((STYLENS,u'data-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'decimal-places'), None): cnv_string, + ((STYLENS,u'default-outline-level'), None): cnv_positiveInteger, + ((STYLENS,u'diagonal-bl-tr'), None): cnv_string, + ((STYLENS,u'diagonal-bl-tr-widths'), None): cnv_string, + ((STYLENS,u'diagonal-tl-br'), None): cnv_string, + ((STYLENS,u'diagonal-tl-br-widths'), None): cnv_string, + ((STYLENS,u'direction'), None): cnv_string, + ((STYLENS,u'display'), None): cnv_boolean, + ((STYLENS,u'display-name'), None): cnv_string, + ((STYLENS,u'distance-after-sep'), None): cnv_length, + ((STYLENS,u'distance-before-sep'), None): cnv_length, + ((STYLENS,u'distance'), None): cnv_length, + ((STYLENS,u'dynamic-spacing'), None): cnv_boolean, + ((STYLENS,u'editable'), None): cnv_boolean, + ((STYLENS,u'family'), None): cnv_family, + ((STYLENS,u'filter-name'), None): cnv_string, + ((STYLENS,u'first-page-number'), None): cnv_string, + ((STYLENS,u'flow-with-text'), None): cnv_boolean, + ((STYLENS,u'font-adornments'), None): cnv_string, + ((STYLENS,u'font-charset'), None): cnv_string, + ((STYLENS,u'font-charset-asian'), None): cnv_string, + ((STYLENS,u'font-charset-complex'), None): cnv_string, + ((STYLENS,u'font-family-asian'), None): cnv_string, + ((STYLENS,u'font-family-complex'), None): cnv_string, + ((STYLENS,u'font-family-generic-asian'), None): cnv_string, + ((STYLENS,u'font-family-generic'), None): cnv_string, + ((STYLENS,u'font-family-generic-complex'), None): cnv_string, + ((STYLENS,u'font-independent-line-spacing'), None): cnv_boolean, + ((STYLENS,u'font-name-asian'), None): cnv_string, + ((STYLENS,u'font-name'), None): cnv_string, + ((STYLENS,u'font-name-complex'), None): cnv_string, + ((STYLENS,u'font-pitch-asian'), None): cnv_string, + ((STYLENS,u'font-pitch'), None): cnv_string, + ((STYLENS,u'font-pitch-complex'), None): cnv_string, + ((STYLENS,u'font-relief'), None): cnv_string, + ((STYLENS,u'font-size-asian'), None): cnv_string, + ((STYLENS,u'font-size-complex'), None): cnv_string, + ((STYLENS,u'font-size-rel-asian'), None): cnv_length, + ((STYLENS,u'font-size-rel'), None): cnv_length, + ((STYLENS,u'font-size-rel-complex'), None): cnv_length, + ((STYLENS,u'font-style-asian'), None): cnv_string, + ((STYLENS,u'font-style-complex'), None): cnv_string, + ((STYLENS,u'font-style-name-asian'), None): cnv_string, + ((STYLENS,u'font-style-name'), None): cnv_string, + ((STYLENS,u'font-style-name-complex'), None): cnv_string, + ((STYLENS,u'font-weight-asian'), None): cnv_string, + ((STYLENS,u'font-weight-complex'), None): cnv_string, + ((STYLENS,u'footnote-max-height'), None): cnv_length, + ((STYLENS,u'glyph-orientation-vertical'), None): cnv_string, + ((STYLENS,u'height'), None): cnv_string, + ((STYLENS,u'horizontal-pos'), None): cnv_string, + ((STYLENS,u'horizontal-rel'), None): cnv_string, + ((STYLENS,u'justify-single-word'), None): cnv_boolean, + ((STYLENS,u'language-asian'), None): cnv_string, + ((STYLENS,u'language-complex'), None): cnv_string, + ((STYLENS,u'layout-grid-base-height'), None): cnv_length, + ((STYLENS,u'layout-grid-color'), None): cnv_string, + ((STYLENS,u'layout-grid-display'), None): cnv_boolean, + ((STYLENS,u'layout-grid-lines'), None): cnv_string, + ((STYLENS,u'layout-grid-mode'), None): cnv_string, + ((STYLENS,u'layout-grid-print'), None): cnv_boolean, + ((STYLENS,u'layout-grid-ruby-below'), None): cnv_boolean, + ((STYLENS,u'layout-grid-ruby-height'), None): cnv_length, + ((STYLENS,u'leader-char'), None): cnv_string, + ((STYLENS,u'leader-color'), None): cnv_string, + ((STYLENS,u'leader-style'), None): cnv_string, + ((STYLENS,u'leader-text'), None): cnv_string, + ((STYLENS,u'leader-text-style'), None): cnv_StyleNameRef, + ((STYLENS,u'leader-type'), None): cnv_string, + ((STYLENS,u'leader-width'), None): cnv_string, + ((STYLENS,u'legend-expansion-aspect-ratio'), None): cnv_double, + ((STYLENS,u'legend-expansion'), None): cnv_string, + ((STYLENS,u'length'), None): cnv_positiveInteger, + ((STYLENS,u'letter-kerning'), None): cnv_boolean, + ((STYLENS,u'line-break'), None): cnv_string, + ((STYLENS,u'line-height-at-least'), None): cnv_string, + ((STYLENS,u'line-spacing'), None): cnv_length, + ((STYLENS,u'line-style'), None): cnv_string, + ((STYLENS,u'lines'), None): cnv_positiveInteger, + ((STYLENS,u'list-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'master-page-name'), None): cnv_StyleNameRef, + ((STYLENS,u'may-break-between-rows'), None): cnv_boolean, + ((STYLENS,u'min-row-height'), None): cnv_string, + ((STYLENS,u'mirror'), None): cnv_string, + ((STYLENS,u'name'), None): cnv_NCName, + ((STYLENS,u'name'), (STYLENS,u'font-face')): cnv_string, + ((STYLENS,u'next-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'num-format'), None): cnv_string, + ((STYLENS,u'num-letter-sync'), None): cnv_boolean, + ((STYLENS,u'num-prefix'), None): cnv_string, + ((STYLENS,u'num-suffix'), None): cnv_string, + ((STYLENS,u'number-wrapped-paragraphs'), None): cnv_string, + ((STYLENS,u'overflow-behavior'), None): cnv_string, + ((STYLENS,u'page-layout-name'), None): cnv_StyleNameRef, + ((STYLENS,u'page-number'), None): cnv_string, + ((STYLENS,u'page-usage'), None): cnv_string, + ((STYLENS,u'paper-tray-name'), None): cnv_string, + ((STYLENS,u'parent-style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'position'), (STYLENS,u'tab-stop')): cnv_length, + ((STYLENS,u'position'), None): cnv_string, + ((STYLENS,u'print'), None): cnv_string, + ((STYLENS,u'print-content'), None): cnv_boolean, + ((STYLENS,u'print-orientation'), None): cnv_string, + ((STYLENS,u'print-page-order'), None): cnv_string, + ((STYLENS,u'protect'), None): cnv_boolean, + ((STYLENS,u'punctuation-wrap'), None): cnv_string, + ((STYLENS,u'register-true'), None): cnv_boolean, + ((STYLENS,u'register-truth-ref-style-name'), None): cnv_string, + ((STYLENS,u'rel-column-width'), None): cnv_string, + ((STYLENS,u'rel-height'), None): cnv_string, + ((STYLENS,u'rel-width'), None): cnv_string, + ((STYLENS,u'repeat'), None): cnv_string, + ((STYLENS,u'repeat-content'), None): cnv_boolean, + ((STYLENS,u'rotation-align'), None): cnv_string, + ((STYLENS,u'rotation-angle'), None): cnv_string, + ((STYLENS,u'row-height'), None): cnv_string, + ((STYLENS,u'ruby-align'), None): cnv_string, + ((STYLENS,u'ruby-position'), None): cnv_string, + ((STYLENS,u'run-through'), None): cnv_string, + ((STYLENS,u'scale-to'), None): cnv_string, + ((STYLENS,u'scale-to-pages'), None): cnv_string, + ((STYLENS,u'script-type'), None): cnv_string, + ((STYLENS,u'shadow'), None): cnv_string, + ((STYLENS,u'shrink-to-fit'), None): cnv_boolean, + ((STYLENS,u'snap-to-layout-grid'), None): cnv_boolean, + ((STYLENS,u'style'), None): cnv_string, + ((STYLENS,u'style-name'), None): cnv_StyleNameRef, + ((STYLENS,u'tab-stop-distance'), None): cnv_string, + ((STYLENS,u'table-centering'), None): cnv_string, + ((STYLENS,u'text-align-source'), None): cnv_string, + ((STYLENS,u'text-autospace'), None): cnv_string, + ((STYLENS,u'text-blinking'), None): cnv_boolean, + ((STYLENS,u'text-combine'), None): cnv_string, + ((STYLENS,u'text-combine-end-char'), None): cnv_string, + ((STYLENS,u'text-combine-start-char'), None): cnv_string, + ((STYLENS,u'text-emphasize'), None): cnv_string, + ((STYLENS,u'text-line-through-color'), None): cnv_string, + ((STYLENS,u'text-line-through-mode'), None): cnv_string, + ((STYLENS,u'text-line-through-style'), None): cnv_string, + ((STYLENS,u'text-line-through-text'), None): cnv_string, + ((STYLENS,u'text-line-through-text-style'), None): cnv_string, + ((STYLENS,u'text-line-through-type'), None): cnv_string, + ((STYLENS,u'text-line-through-width'), None): cnv_string, + ((STYLENS,u'text-outline'), None): cnv_boolean, + ((STYLENS,u'text-position'), None): cnv_string, + ((STYLENS,u'text-rotation-angle'), None): cnv_string, + ((STYLENS,u'text-rotation-scale'), None): cnv_string, + ((STYLENS,u'text-scale'), None): cnv_string, + ((STYLENS,u'text-underline-color'), None): cnv_string, + ((STYLENS,u'text-underline-mode'), None): cnv_string, + ((STYLENS,u'text-underline-style'), None): cnv_string, + ((STYLENS,u'text-underline-type'), None): cnv_string, + ((STYLENS,u'text-underline-width'), None): cnv_string, + ((STYLENS,u'type'), None): cnv_string, + ((STYLENS,u'use-optimal-column-width'), None): cnv_boolean, + ((STYLENS,u'use-optimal-row-height'), None): cnv_boolean, + ((STYLENS,u'use-window-font-color'), None): cnv_boolean, + ((STYLENS,u'vertical-align'), None): cnv_string, + ((STYLENS,u'vertical-pos'), None): cnv_string, + ((STYLENS,u'vertical-rel'), None): cnv_string, + ((STYLENS,u'volatile'), None): cnv_boolean, + ((STYLENS,u'width'), None): cnv_string, + ((STYLENS,u'wrap'), None): cnv_string, + ((STYLENS,u'wrap-contour'), None): cnv_boolean, + ((STYLENS,u'wrap-contour-mode'), None): cnv_string, + ((STYLENS,u'wrap-dynamic-threshold'), None): cnv_length, + ((STYLENS,u'writing-mode-automatic'), None): cnv_boolean, + ((STYLENS,u'writing-mode'), None): cnv_string, + ((SVGNS,u'accent-height'), None): cnv_integer, + ((SVGNS,u'alphabetic'), None): cnv_integer, + ((SVGNS,u'ascent'), None): cnv_integer, + ((SVGNS,u'bbox'), None): cnv_string, + ((SVGNS,u'cap-height'), None): cnv_integer, + ((SVGNS,u'cx'), None): cnv_string, + ((SVGNS,u'cy'), None): cnv_string, + ((SVGNS,u'd'), None): cnv_string, + ((SVGNS,u'descent'), None): cnv_integer, + ((SVGNS,u'fill-rule'), None): cnv_string, + ((SVGNS,u'font-family'), None): cnv_string, + ((SVGNS,u'font-size'), None): cnv_string, + ((SVGNS,u'font-stretch'), None): cnv_string, + ((SVGNS,u'font-style'), None): cnv_string, + ((SVGNS,u'font-variant'), None): cnv_string, + ((SVGNS,u'font-weight'), None): cnv_string, + ((SVGNS,u'fx'), None): cnv_string, + ((SVGNS,u'fy'), None): cnv_string, + ((SVGNS,u'gradientTransform'), None): cnv_string, + ((SVGNS,u'gradientUnits'), None): cnv_string, + ((SVGNS,u'hanging'), None): cnv_integer, + ((SVGNS,u'height'), None): cnv_length, + ((SVGNS,u'ideographic'), None): cnv_integer, + ((SVGNS,u'mathematical'), None): cnv_integer, + ((SVGNS,u'name'), None): cnv_string, + ((SVGNS,u'offset'), None): cnv_string, + ((SVGNS,u'origin'), None): cnv_string, + ((SVGNS,u'overline-position'), None): cnv_integer, + ((SVGNS,u'overline-thickness'), None): cnv_integer, + ((SVGNS,u'panose-1'), None): cnv_string, + ((SVGNS,u'path'), None): cnv_string, + ((SVGNS,u'r'), None): cnv_length, + ((SVGNS,u'rx'), None): cnv_length, + ((SVGNS,u'ry'), None): cnv_length, + ((SVGNS,u'slope'), None): cnv_integer, + ((SVGNS,u'spreadMethod'), None): cnv_string, + ((SVGNS,u'stemh'), None): cnv_integer, + ((SVGNS,u'stemv'), None): cnv_integer, + ((SVGNS,u'stop-color'), None): cnv_string, + ((SVGNS,u'stop-opacity'), None): cnv_double, + ((SVGNS,u'strikethrough-position'), None): cnv_integer, + ((SVGNS,u'strikethrough-thickness'), None): cnv_integer, + ((SVGNS,u'string'), None): cnv_string, + ((SVGNS,u'stroke-color'), None): cnv_string, + ((SVGNS,u'stroke-opacity'), None): cnv_string, + ((SVGNS,u'stroke-width'), None): cnv_length, + ((SVGNS,u'type'), None): cnv_string, + ((SVGNS,u'underline-position'), None): cnv_integer, + ((SVGNS,u'underline-thickness'), None): cnv_integer, + ((SVGNS,u'unicode-range'), None): cnv_string, + ((SVGNS,u'units-per-em'), None): cnv_integer, + ((SVGNS,u'v-alphabetic'), None): cnv_integer, + ((SVGNS,u'v-hanging'), None): cnv_integer, + ((SVGNS,u'v-ideographic'), None): cnv_integer, + ((SVGNS,u'v-mathematical'), None): cnv_integer, + ((SVGNS,u'viewBox'), None): cnv_viewbox, + ((SVGNS,u'width'), None): cnv_length, + ((SVGNS,u'widths'), None): cnv_string, + ((SVGNS,u'x'), None): cnv_length, + ((SVGNS,u'x-height'), None): cnv_integer, + ((SVGNS,u'x1'), None): cnv_lengthorpercent, + ((SVGNS,u'x2'), None): cnv_lengthorpercent, + ((SVGNS,u'y'), None): cnv_length, + ((SVGNS,u'y1'), None): cnv_lengthorpercent, + ((SVGNS,u'y2'), None): cnv_lengthorpercent, + ((TABLENS,u'acceptance-state'), None): cnv_string, + ((TABLENS,u'add-empty-lines'), None): cnv_boolean, + ((TABLENS,u'algorithm'), None): cnv_formula, + ((TABLENS,u'align'), None): cnv_string, + ((TABLENS,u'allow-empty-cell'), None): cnv_boolean, + ((TABLENS,u'application-data'), None): cnv_string, + ((TABLENS,u'automatic-find-labels'), None): cnv_boolean, + ((TABLENS,u'base-cell-address'), None): cnv_string, + ((TABLENS,u'bind-styles-to-content'), None): cnv_boolean, + ((TABLENS,u'border-color'), None): cnv_string, + ((TABLENS,u'border-model'), None): cnv_string, + ((TABLENS,u'buttons'), None): cnv_string, + ((TABLENS,u'buttons'), None): cnv_string, + ((TABLENS,u'case-sensitive'), None): cnv_boolean, + ((TABLENS,u'case-sensitive'), None): cnv_string, + ((TABLENS,u'cell-address'), None): cnv_string, + ((TABLENS,u'cell-range-address'), None): cnv_string, + ((TABLENS,u'cell-range-address'), None): cnv_string, + ((TABLENS,u'cell-range'), None): cnv_string, + ((TABLENS,u'column'), None): cnv_integer, + ((TABLENS,u'comment'), None): cnv_string, + ((TABLENS,u'condition'), None): cnv_formula, + ((TABLENS,u'condition-source'), None): cnv_string, + ((TABLENS,u'condition-source-range-address'), None): cnv_string, + ((TABLENS,u'contains-error'), None): cnv_boolean, + ((TABLENS,u'contains-header'), None): cnv_boolean, + ((TABLENS,u'content-validation-name'), None): cnv_string, + ((TABLENS,u'copy-back'), None): cnv_boolean, + ((TABLENS,u'copy-formulas'), None): cnv_boolean, + ((TABLENS,u'copy-styles'), None): cnv_boolean, + ((TABLENS,u'count'), None): cnv_positiveInteger, + ((TABLENS,u'country'), None): cnv_token, + ((TABLENS,u'data-cell-range-address'), None): cnv_string, + ((TABLENS,u'data-field'), None): cnv_string, + ((TABLENS,u'data-type'), None): cnv_string, + ((TABLENS,u'database-name'), None): cnv_string, + ((TABLENS,u'database-table-name'), None): cnv_string, + ((TABLENS,u'date-end'), None): cnv_string, + ((TABLENS,u'date-start'), None): cnv_string, + ((TABLENS,u'date-value'), None): cnv_date, + ((TABLENS,u'default-cell-style-name'), None): cnv_StyleNameRef, + ((TABLENS,u'direction'), None): cnv_string, + ((TABLENS,u'display-border'), None): cnv_boolean, + ((TABLENS,u'display'), None): cnv_boolean, + ((TABLENS,u'display-duplicates'), None): cnv_boolean, + ((TABLENS,u'display-filter-buttons'), None): cnv_boolean, + ((TABLENS,u'display-list'), None): cnv_string, + ((TABLENS,u'display-member-mode'), None): cnv_string, + ((TABLENS,u'drill-down-on-double-click'), None): cnv_boolean, + ((TABLENS,u'enabled'), None): cnv_boolean, + ((TABLENS,u'end-cell-address'), None): cnv_string, + ((TABLENS,u'end'), None): cnv_string, + ((TABLENS,u'end-column'), None): cnv_integer, + ((TABLENS,u'end-position'), None): cnv_integer, + ((TABLENS,u'end-row'), None): cnv_integer, + ((TABLENS,u'end-table'), None): cnv_integer, + ((TABLENS,u'end-x'), None): cnv_length, + ((TABLENS,u'end-y'), None): cnv_length, + ((TABLENS,u'execute'), None): cnv_boolean, + ((TABLENS,u'expression'), None): cnv_formula, + ((TABLENS,u'field-name'), None): cnv_string, + ((TABLENS,u'field-number'), None): cnv_nonNegativeInteger, + ((TABLENS,u'field-number'), None): cnv_string, + ((TABLENS,u'filter-name'), None): cnv_string, + ((TABLENS,u'filter-options'), None): cnv_string, + ((TABLENS,u'formula'), None): cnv_formula, + ((TABLENS,u'function'), None): cnv_string, + ((TABLENS,u'function'), None): cnv_string, + ((TABLENS,u'grand-total'), None): cnv_string, + ((TABLENS,u'group-by-field-number'), None): cnv_nonNegativeInteger, + ((TABLENS,u'grouped-by'), None): cnv_string, + ((TABLENS,u'has-persistent-data'), None): cnv_boolean, + ((TABLENS,u'id'), None): cnv_string, + ((TABLENS,u'identify-categories'), None): cnv_boolean, + ((TABLENS,u'ignore-empty-rows'), None): cnv_boolean, + ((TABLENS,u'index'), None): cnv_nonNegativeInteger, + ((TABLENS,u'is-active'), None): cnv_boolean, + ((TABLENS,u'is-data-layout-field'), None): cnv_string, + ((TABLENS,u'is-selection'), None): cnv_boolean, + ((TABLENS,u'is-sub-table'), None): cnv_boolean, + ((TABLENS,u'label-cell-range-address'), None): cnv_string, + ((TABLENS,u'language'), None): cnv_token, + ((TABLENS,u'language'), None): cnv_token, + ((TABLENS,u'last-column-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'last-row-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'layout-mode'), None): cnv_string, + ((TABLENS,u'link-to-source-data'), None): cnv_boolean, + ((TABLENS,u'marked-invalid'), None): cnv_boolean, + ((TABLENS,u'matrix-covered'), None): cnv_boolean, + ((TABLENS,u'maximum-difference'), None): cnv_double, + ((TABLENS,u'member-count'), None): cnv_nonNegativeInteger, + ((TABLENS,u'member-name'), None): cnv_string, + ((TABLENS,u'member-type'), None): cnv_string, + ((TABLENS,u'message-type'), None): cnv_string, + ((TABLENS,u'mode'), None): cnv_string, + ((TABLENS,u'multi-deletion-spanned'), None): cnv_integer, + ((TABLENS,u'name'), None): cnv_string, + ((TABLENS,u'name'), None): cnv_string, + ((TABLENS,u'null-year'), None): cnv_positiveInteger, + ((TABLENS,u'number-columns-repeated'), None): cnv_positiveInteger, + ((TABLENS,u'number-columns-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'number-matrix-columns-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'number-matrix-rows-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'number-rows-repeated'), None): cnv_positiveInteger, + ((TABLENS,u'number-rows-spanned'), None): cnv_positiveInteger, + ((TABLENS,u'object-name'), None): cnv_string, + ((TABLENS,u'on-update-keep-size'), None): cnv_boolean, + ((TABLENS,u'on-update-keep-styles'), None): cnv_boolean, + ((TABLENS,u'operator'), None): cnv_string, + ((TABLENS,u'operator'), None): cnv_string, + ((TABLENS,u'order'), None): cnv_string, + ((TABLENS,u'orientation'), None): cnv_string, + ((TABLENS,u'orientation'), None): cnv_string, + ((TABLENS,u'page-breaks-on-group-change'), None): cnv_boolean, + ((TABLENS,u'parse-sql-statement'), None): cnv_boolean, + ((TABLENS,u'password'), None): cnv_string, + ((TABLENS,u'position'), None): cnv_integer, + ((TABLENS,u'precision-as-shown'), None): cnv_boolean, + ((TABLENS,u'print'), None): cnv_boolean, + ((TABLENS,u'print-ranges'), None): cnv_string, + ((TABLENS,u'protect'), None): cnv_boolean, + ((TABLENS,u'protected'), None): cnv_boolean, + ((TABLENS,u'protection-key'), None): cnv_string, + ((TABLENS,u'query-name'), None): cnv_string, + ((TABLENS,u'range-usable-as'), None): cnv_string, + ((TABLENS,u'refresh-delay'), None): cnv_boolean, + ((TABLENS,u'refresh-delay'), None): cnv_duration, + ((TABLENS,u'rejecting-change-id'), None): cnv_string, + ((TABLENS,u'row'), None): cnv_integer, + ((TABLENS,u'scenario-ranges'), None): cnv_string, + ((TABLENS,u'search-criteria-must-apply-to-whole-cell'), None): cnv_boolean, + ((TABLENS,u'selected-page'), None): cnv_string, + ((TABLENS,u'show-details'), None): cnv_boolean, + ((TABLENS,u'show-empty'), None): cnv_boolean, + ((TABLENS,u'show-empty'), None): cnv_string, + ((TABLENS,u'show-filter-button'), None): cnv_boolean, + ((TABLENS,u'sort-mode'), None): cnv_string, + ((TABLENS,u'source-cell-range-addresses'), None): cnv_string, + ((TABLENS,u'source-cell-range-addresses'), None): cnv_string, + ((TABLENS,u'source-field-name'), None): cnv_string, + ((TABLENS,u'source-field-name'), None): cnv_string, + ((TABLENS,u'source-name'), None): cnv_string, + ((TABLENS,u'sql-statement'), None): cnv_string, + ((TABLENS,u'start'), None): cnv_string, + ((TABLENS,u'start-column'), None): cnv_integer, + ((TABLENS,u'start-position'), None): cnv_integer, + ((TABLENS,u'start-row'), None): cnv_integer, + ((TABLENS,u'start-table'), None): cnv_integer, + ((TABLENS,u'status'), None): cnv_string, + ((TABLENS,u'step'), None): cnv_double, + ((TABLENS,u'steps'), None): cnv_positiveInteger, + ((TABLENS,u'structure-protected'), None): cnv_boolean, + ((TABLENS,u'style-name'), None): cnv_StyleNameRef, + ((TABLENS,u'table-background'), None): cnv_boolean, + ((TABLENS,u'table'), None): cnv_integer, + ((TABLENS,u'table-name'), None): cnv_string, + ((TABLENS,u'target-cell-address'), None): cnv_string, + ((TABLENS,u'target-cell-address'), None): cnv_string, + ((TABLENS,u'target-range-address'), None): cnv_string, + ((TABLENS,u'target-range-address'), None): cnv_string, + ((TABLENS,u'title'), None): cnv_string, + ((TABLENS,u'track-changes'), None): cnv_boolean, + ((TABLENS,u'type'), None): cnv_string, + ((TABLENS,u'use-labels'), None): cnv_string, + ((TABLENS,u'use-regular-expressions'), None): cnv_boolean, + ((TABLENS,u'used-hierarchy'), None): cnv_integer, + ((TABLENS,u'user-name'), None): cnv_string, + ((TABLENS,u'value'), None): cnv_string, + ((TABLENS,u'value'), None): cnv_string, + ((TABLENS,u'value-type'), None): cnv_string, + ((TABLENS,u'visibility'), None): cnv_string, + ((TEXTNS,u'active'), None): cnv_boolean, + ((TEXTNS,u'address'), None): cnv_string, + ((TEXTNS,u'alphabetical-separators'), None): cnv_boolean, + ((TEXTNS,u'anchor-page-number'), None): cnv_positiveInteger, + ((TEXTNS,u'anchor-type'), None): cnv_string, + ((TEXTNS,u'animation'), None): cnv_string, + ((TEXTNS,u'animation-delay'), None): cnv_string, + ((TEXTNS,u'animation-direction'), None): cnv_string, + ((TEXTNS,u'animation-repeat'), None): cnv_string, + ((TEXTNS,u'animation-start-inside'), None): cnv_boolean, + ((TEXTNS,u'animation-steps'), None): cnv_length, + ((TEXTNS,u'animation-stop-inside'), None): cnv_boolean, + ((TEXTNS,u'annote'), None): cnv_string, + ((TEXTNS,u'author'), None): cnv_string, + ((TEXTNS,u'bibliography-data-field'), None): cnv_string, + ((TEXTNS,u'bibliography-type'), None): cnv_string, + ((TEXTNS,u'booktitle'), None): cnv_string, + ((TEXTNS,u'bullet-char'), None): cnv_string, + ((TEXTNS,u'bullet-relative-size'), None): cnv_string, + ((TEXTNS,u'c'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'capitalize-entries'), None): cnv_boolean, + ((TEXTNS,u'caption-sequence-format'), None): cnv_string, + ((TEXTNS,u'caption-sequence-name'), None): cnv_string, + ((TEXTNS,u'change-id'), None): cnv_IDREF, + ((TEXTNS,u'chapter'), None): cnv_string, + ((TEXTNS,u'citation-body-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'citation-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'class-names'), None): cnv_NCNames, + ((TEXTNS,u'column-name'), None): cnv_string, + ((TEXTNS,u'combine-entries'), None): cnv_boolean, + ((TEXTNS,u'combine-entries-with-dash'), None): cnv_boolean, + ((TEXTNS,u'combine-entries-with-pp'), None): cnv_boolean, + ((TEXTNS,u'comma-separated'), None): cnv_boolean, + ((TEXTNS,u'cond-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'condition'), None): cnv_formula, + ((TEXTNS,u'connection-name'), None): cnv_string, + ((TEXTNS,u'consecutive-numbering'), None): cnv_boolean, + ((TEXTNS,u'continue-numbering'), None): cnv_boolean, + ((TEXTNS,u'copy-outline-levels'), None): cnv_boolean, + ((TEXTNS,u'count-empty-lines'), None): cnv_boolean, + ((TEXTNS,u'count-in-text-boxes'), None): cnv_boolean, + ((TEXTNS,u'current-value'), None): cnv_boolean, + ((TEXTNS,u'custom1'), None): cnv_string, + ((TEXTNS,u'custom2'), None): cnv_string, + ((TEXTNS,u'custom3'), None): cnv_string, + ((TEXTNS,u'custom4'), None): cnv_string, + ((TEXTNS,u'custom5'), None): cnv_string, + ((TEXTNS,u'database-name'), None): cnv_string, + ((TEXTNS,u'date-adjust'), None): cnv_duration, + ((TEXTNS,u'date-value'), None): cnv_date, +# ((TEXTNS,u'date-value'), None): cnv_dateTime, + ((TEXTNS,u'default-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'description'), None): cnv_string, + ((TEXTNS,u'display'), None): cnv_string, + ((TEXTNS,u'display-levels'), None): cnv_positiveInteger, + ((TEXTNS,u'display-outline-level'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'dont-balance-text-columns'), None): cnv_boolean, + ((TEXTNS,u'duration'), None): cnv_duration, + ((TEXTNS,u'edition'), None): cnv_string, + ((TEXTNS,u'editor'), None): cnv_string, + ((TEXTNS,u'filter-name'), None): cnv_string, + ((TEXTNS,u'first-row-end-column'), None): cnv_string, + ((TEXTNS,u'first-row-start-column'), None): cnv_string, + ((TEXTNS,u'fixed'), None): cnv_boolean, + ((TEXTNS,u'footnotes-position'), None): cnv_string, + ((TEXTNS,u'formula'), None): cnv_formula, + ((TEXTNS,u'global'), None): cnv_boolean, + ((TEXTNS,u'howpublished'), None): cnv_string, + ((TEXTNS,u'id'), None): cnv_ID, +# ((TEXTNS,u'id'), None): cnv_string, + ((TEXTNS,u'identifier'), None): cnv_string, + ((TEXTNS,u'ignore-case'), None): cnv_boolean, + ((TEXTNS,u'increment'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'index-name'), None): cnv_string, + ((TEXTNS,u'index-scope'), None): cnv_string, + ((TEXTNS,u'institution'), None): cnv_string, + ((TEXTNS,u'is-hidden'), None): cnv_boolean, + ((TEXTNS,u'is-list-header'), None): cnv_boolean, + ((TEXTNS,u'isbn'), None): cnv_string, + ((TEXTNS,u'issn'), None): cnv_string, + ((TEXTNS,u'issn'), None): cnv_string, + ((TEXTNS,u'journal'), None): cnv_string, + ((TEXTNS,u'key'), None): cnv_string, + ((TEXTNS,u'key1'), None): cnv_string, + ((TEXTNS,u'key1-phonetic'), None): cnv_string, + ((TEXTNS,u'key2'), None): cnv_string, + ((TEXTNS,u'key2-phonetic'), None): cnv_string, + ((TEXTNS,u'kind'), None): cnv_string, + ((TEXTNS,u'label'), None): cnv_string, + ((TEXTNS,u'last-row-end-column'), None): cnv_string, + ((TEXTNS,u'last-row-start-column'), None): cnv_string, + ((TEXTNS,u'level'), None): cnv_positiveInteger, + ((TEXTNS,u'line-break'), None): cnv_boolean, + ((TEXTNS,u'line-number'), None): cnv_string, + ((TEXTNS,u'main-entry'), None): cnv_boolean, + ((TEXTNS,u'main-entry-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'master-page-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'min-label-distance'), None): cnv_string, + ((TEXTNS,u'min-label-width'), None): cnv_string, + ((TEXTNS,u'month'), None): cnv_string, + ((TEXTNS,u'name'), None): cnv_string, + ((TEXTNS,u'note-class'), None): cnv_textnoteclass, + ((TEXTNS,u'note'), None): cnv_string, + ((TEXTNS,u'number'), None): cnv_string, + ((TEXTNS,u'number-lines'), None): cnv_boolean, + ((TEXTNS,u'number-position'), None): cnv_string, + ((TEXTNS,u'numbered-entries'), None): cnv_boolean, + ((TEXTNS,u'offset'), None): cnv_string, + ((TEXTNS,u'organizations'), None): cnv_string, + ((TEXTNS,u'outline-level'), None): cnv_string, + ((TEXTNS,u'page-adjust'), None): cnv_integer, + ((TEXTNS,u'pages'), None): cnv_string, + ((TEXTNS,u'paragraph-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'placeholder-type'), None): cnv_string, + ((TEXTNS,u'prefix'), None): cnv_string, + ((TEXTNS,u'protected'), None): cnv_boolean, + ((TEXTNS,u'protection-key'), None): cnv_string, + ((TEXTNS,u'publisher'), None): cnv_string, + ((TEXTNS,u'ref-name'), None): cnv_string, + ((TEXTNS,u'reference-format'), None): cnv_string, + ((TEXTNS,u'relative-tab-stop-position'), None): cnv_boolean, + ((TEXTNS,u'report-type'), None): cnv_string, + ((TEXTNS,u'restart-numbering'), None): cnv_boolean, + ((TEXTNS,u'restart-on-page'), None): cnv_boolean, + ((TEXTNS,u'row-number'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'school'), None): cnv_string, + ((TEXTNS,u'section-name'), None): cnv_string, + ((TEXTNS,u'select-page'), None): cnv_string, + ((TEXTNS,u'separation-character'), None): cnv_string, + ((TEXTNS,u'series'), None): cnv_string, + ((TEXTNS,u'sort-algorithm'), None): cnv_string, + ((TEXTNS,u'sort-ascending'), None): cnv_boolean, + ((TEXTNS,u'sort-by-position'), None): cnv_boolean, + ((TEXTNS,u'space-before'), None): cnv_string, + ((TEXTNS,u'start-numbering-at'), None): cnv_string, + ((TEXTNS,u'start-value'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'start-value'), None): cnv_positiveInteger, + ((TEXTNS,u'string-value'), None): cnv_string, + ((TEXTNS,u'string-value-if-false'), None): cnv_string, + ((TEXTNS,u'string-value-if-true'), None): cnv_string, + ((TEXTNS,u'string-value-phonetic'), None): cnv_string, + ((TEXTNS,u'style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'suffix'), None): cnv_string, + ((TEXTNS,u'tab-ref'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'table-name'), None): cnv_string, + ((TEXTNS,u'table-type'), None): cnv_string, + ((TEXTNS,u'time-adjust'), None): cnv_duration, + ((TEXTNS,u'time-value'), None): cnv_dateTime, + ((TEXTNS,u'time-value'), None): cnv_time, + ((TEXTNS,u'title'), None): cnv_string, + ((TEXTNS,u'track-changes'), None): cnv_boolean, + ((TEXTNS,u'url'), None): cnv_string, + ((TEXTNS,u'use-caption'), None): cnv_boolean, + ((TEXTNS,u'use-chart-objects'), None): cnv_boolean, + ((TEXTNS,u'use-draw-objects'), None): cnv_boolean, + ((TEXTNS,u'use-floating-frames'), None): cnv_boolean, + ((TEXTNS,u'use-graphics'), None): cnv_boolean, + ((TEXTNS,u'use-index-marks'), None): cnv_boolean, + ((TEXTNS,u'use-index-source-styles'), None): cnv_boolean, + ((TEXTNS,u'use-keys-as-entries'), None): cnv_boolean, + ((TEXTNS,u'use-math-objects'), None): cnv_boolean, + ((TEXTNS,u'use-objects'), None): cnv_boolean, + ((TEXTNS,u'use-other-objects'), None): cnv_boolean, + ((TEXTNS,u'use-outline-level'), None): cnv_boolean, + ((TEXTNS,u'use-soft-page-breaks'), None): cnv_boolean, + ((TEXTNS,u'use-spreadsheet-objects'), None): cnv_boolean, + ((TEXTNS,u'use-tables'), None): cnv_boolean, + ((TEXTNS,u'value'), None): cnv_nonNegativeInteger, + ((TEXTNS,u'visited-style-name'), None): cnv_StyleNameRef, + ((TEXTNS,u'volume'), None): cnv_string, + ((TEXTNS,u'year'), None): cnv_string, + ((XFORMSNS,u'bind'), None): cnv_string, + ((XLINKNS,u'actuate'), None): cnv_string, + ((XLINKNS,u'href'), None): cnv_anyURI, + ((XLINKNS,u'show'), None): cnv_xlinkshow, + ((XLINKNS,u'title'), None): cnv_string, + ((XLINKNS,u'type'), None): cnv_string, +} + +class AttrConverters: + def convert(self, attribute, value, element): + """ Based on the element, figures out how to check/convert the attribute value + All values are converted to string + """ + conversion = attrconverters.get((attribute, element.qname), None) + if conversion is not None: + return conversion(attribute, value, element) + else: + conversion = attrconverters.get((attribute, None), None) + if conversion is not None: + return conversion(attribute, value, element) + return unicode(value) +
Property changes on: trunk/pywikipedia/odf/attrconverters.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/chart.py =================================================================== --- trunk/pywikipedia/odf/chart.py (rev 0) +++ trunk/pywikipedia/odf/chart.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,87 @@ +# -*- 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) +
Property changes on: trunk/pywikipedia/odf/chart.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/config.py =================================================================== --- trunk/pywikipedia/odf/config.py (rev 0) +++ trunk/pywikipedia/odf/config.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import CONFIGNS +from element import Element + +# Autogenerated +def ConfigItem(**args): + return Element(qname = (CONFIGNS, 'config-item'), **args) + +def ConfigItemMapEntry(**args): + return Element(qname = (CONFIGNS,'config-item-map-entry'), **args) + +def ConfigItemMapIndexed(**args): + return Element(qname = (CONFIGNS,'config-item-map-indexed'), **args) + +def ConfigItemMapNamed(**args): + return Element(qname = (CONFIGNS,'config-item-map-named'), **args) + +def ConfigItemSet(**args): + return Element(qname = (CONFIGNS, 'config-item-set'), **args) +
Property changes on: trunk/pywikipedia/odf/config.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/dc.py =================================================================== --- trunk/pywikipedia/odf/dc.py (rev 0) +++ trunk/pywikipedia/odf/dc.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import DCNS +from element import Element + +# Autogenerated +def Creator(**args): + return Element(qname = (DCNS,'creator'), **args) + +def Date(**args): + return Element(qname = (DCNS,'date'), **args) + +def Description(**args): + return Element(qname = (DCNS,'description'), **args) + +def Language(**args): + return Element(qname = (DCNS,'language'), **args) + +def Subject(**args): + return Element(qname = (DCNS,'subject'), **args) + +def Title(**args): + return Element(qname = (DCNS,'title'), **args) + +# The following complete the Dublin Core elements, but there is no +# guarantee a compliant implementation of OpenDocument will preserve +# these elements + +#def Contributor(**args): +# return Element(qname = (DCNS,'contributor'), **args) + +#def Coverage(**args): +# return Element(qname = (DCNS,'coverage'), **args) + +#def Format(**args): +# return Element(qname = (DCNS,'format'), **args) + +#def Identifier(**args): +# return Element(qname = (DCNS,'identifier'), **args) + +#def Publisher(**args): +# return Element(qname = (DCNS,'publisher'), **args) + +#def Relation(**args): +# return Element(qname = (DCNS,'relation'), **args) + +#def Rights(**args): +# return Element(qname = (DCNS,'rights'), **args) + +#def Source(**args): +# return Element(qname = (DCNS,'source'), **args) + +#def Type(**args): +# return Element(qname = (DCNS,'type'), **args)
Property changes on: trunk/pywikipedia/odf/dc.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/dr3d.py =================================================================== --- trunk/pywikipedia/odf/dr3d.py (rev 0) +++ trunk/pywikipedia/odf/dr3d.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,43 @@ +# -*- 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) +
Property changes on: trunk/pywikipedia/odf/dr3d.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/draw.py =================================================================== --- trunk/pywikipedia/odf/draw.py (rev 0) +++ trunk/pywikipedia/odf/draw.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,182 @@ +# -*- 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) +
Property changes on: trunk/pywikipedia/odf/draw.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/easyliststyle.py =================================================================== --- trunk/pywikipedia/odf/easyliststyle.py (rev 0) +++ trunk/pywikipedia/odf/easyliststyle.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,103 @@ +# -*- 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 :
Property changes on: trunk/pywikipedia/odf/easyliststyle.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/element.py =================================================================== --- trunk/pywikipedia/odf/element.py (rev 0) +++ trunk/pywikipedia/odf/element.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,513 @@ +#!/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 + +
Property changes on: trunk/pywikipedia/odf/element.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/elementtypes.py =================================================================== --- trunk/pywikipedia/odf/elementtypes.py (rev 0) +++ trunk/pywikipedia/odf/elementtypes.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,325 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2008 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import * + +# Inline element don't cause a box +# They are analogous to the HTML elements SPAN, B, I etc. +inline_elements = ( + (TEXTNS,u'a'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'print-time'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u'ruby-base'), + (TEXTNS,u'ruby-text'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), +) + + +# It is almost impossible to determine what elements are block elements. +# There are so many that don't fit the form +block_elements = ( + (TEXTNS,u'h'), + (TEXTNS,u'p'), + (TEXTNS,u'list'), + (TEXTNS,u'list-item'), + (TEXTNS,u'section'), +) + +declarative_elements = ( + (OFFICENS,u'font-face-decls'), + (PRESENTATIONNS,u'date-time-decl'), + (PRESENTATIONNS,u'footer-decl'), + (PRESENTATIONNS,u'header-decl'), + (TABLENS,u'table-template'), + (TEXTNS,u'alphabetical-index-entry-template'), + (TEXTNS,u'alphabetical-index-source'), + (TEXTNS,u'bibliography-entry-template'), + (TEXTNS,u'bibliography-source'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'illustration-index-entry-template'), + (TEXTNS,u'illustration-index-source'), + (TEXTNS,u'index-source-styles'), + (TEXTNS,u'index-title-template'), + (TEXTNS,u'note-continuation-notice-backward'), + (TEXTNS,u'note-continuation-notice-forward'), + (TEXTNS,u'notes-configuration'), + (TEXTNS,u'object-index-entry-template'), + (TEXTNS,u'object-index-source'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index-entry-template'), + (TEXTNS,u'table-index-source'), + (TEXTNS,u'table-of-content-entry-template'), + (TEXTNS,u'table-of-content-source'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index-entry-template'), + (TEXTNS,u'user-index-source'), + (TEXTNS,u'variable-decls'), +) + +empty_elements = ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'param'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + (CHARTNS,u'categories'), + (CHARTNS,u'data-point'), + (CHARTNS,u'domain'), + (CHARTNS,u'error-indicator'), + (CHARTNS,u'floor'), + (CHARTNS,u'grid'), + (CHARTNS,u'legend'), + (CHARTNS,u'mean-value'), + (CHARTNS,u'regression-curve'), + (CHARTNS,u'stock-gain-marker'), + (CHARTNS,u'stock-loss-marker'), + (CHARTNS,u'stock-range-line'), + (CHARTNS,u'symbol-image'), + (CHARTNS,u'wall'), + (DR3DNS,u'cube'), + (DR3DNS,u'extrude'), + (DR3DNS,u'light'), + (DR3DNS,u'rotate'), + (DR3DNS,u'sphere'), + (DRAWNS,u'contour-path'), + (DRAWNS,u'contour-polygon'), + (DRAWNS,u'equation'), + (DRAWNS,u'fill-image'), + (DRAWNS,u'floating-frame'), + (DRAWNS,u'glue-point'), + (DRAWNS,u'gradient'), + (DRAWNS,u'handle'), + (DRAWNS,u'hatch'), + (DRAWNS,u'layer'), + (DRAWNS,u'marker'), + (DRAWNS,u'opacity'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'param'), + (DRAWNS,u'stroke-dash'), + (FORMNS,u'connection-resource'), + (FORMNS,u'list-value'), + (FORMNS,u'property'), + (MANIFESTNS,u'algorithm'), + (MANIFESTNS,u'key-derivation'), + (METANS,u'auto-reload'), + (METANS,u'document-statistic'), + (METANS,u'hyperlink-behaviour'), + (METANS,u'template'), + (NUMBERNS,u'am-pm'), + (NUMBERNS,u'boolean'), + (NUMBERNS,u'day'), + (NUMBERNS,u'day-of-week'), + (NUMBERNS,u'era'), + (NUMBERNS,u'fraction'), + (NUMBERNS,u'hours'), + (NUMBERNS,u'minutes'), + (NUMBERNS,u'month'), + (NUMBERNS,u'quarter'), + (NUMBERNS,u'scientific-number'), + (NUMBERNS,u'seconds'), + (NUMBERNS,u'text-content'), + (NUMBERNS,u'week-of-year'), + (NUMBERNS,u'year'), + (OFFICENS,u'dde-source'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (PRESENTATIONNS,u'placeholder'), + (PRESENTATIONNS,u'play'), + (PRESENTATIONNS,u'show'), + (PRESENTATIONNS,u'sound'), + (SCRIPTNS,u'event-listener'), + (STYLENS,u'column'), + (STYLENS,u'column-sep'), + (STYLENS,u'drop-cap'), + (STYLENS,u'footnote-sep'), + (STYLENS,u'list-level-properties'), + (STYLENS,u'map'), + (STYLENS,u'ruby-properties'), + (STYLENS,u'table-column-properties'), + (STYLENS,u'tab-stop'), + (STYLENS,u'text-properties'), + (SVGNS,u'definition-src'), + (SVGNS,u'font-face-format'), + (SVGNS,u'font-face-name'), + (SVGNS,u'stop'), + (TABLENS,u'body'), + (TABLENS,u'cell-address'), + (TABLENS,u'cell-range-source'), + (TABLENS,u'change-deletion'), + (TABLENS,u'consolidation'), + (TABLENS,u'database-source-query'), + (TABLENS,u'database-source-sql'), + (TABLENS,u'database-source-table'), + (TABLENS,u'data-pilot-display-info'), + (TABLENS,u'data-pilot-field-reference'), + (TABLENS,u'data-pilot-group-member'), + (TABLENS,u'data-pilot-layout-info'), + (TABLENS,u'data-pilot-member'), + (TABLENS,u'data-pilot-sort-info'), + (TABLENS,u'data-pilot-subtotal'), + (TABLENS,u'dependency'), + (TABLENS,u'error-macro'), + (TABLENS,u'even-columns'), + (TABLENS,u'even-rows'), + (TABLENS,u'filter-condition'), + (TABLENS,u'first-column'), + (TABLENS,u'first-row'), + (TABLENS,u'highlighted-range'), + (TABLENS,u'insertion-cut-off'), + (TABLENS,u'iteration'), + (TABLENS,u'label-range'), + (TABLENS,u'last-column'), + (TABLENS,u'last-row'), + (TABLENS,u'movement-cut-off'), + (TABLENS,u'named-expression'), + (TABLENS,u'named-range'), + (TABLENS,u'null-date'), + (TABLENS,u'odd-columns'), + (TABLENS,u'odd-rows'), + (TABLENS,u'operation'), + (TABLENS,u'scenario'), + (TABLENS,u'sort-by'), + (TABLENS,u'sort-groups'), + (TABLENS,u'source-range-address'), + (TABLENS,u'source-service'), + (TABLENS,u'subtotal-field'), + (TABLENS,u'table-column'), + (TABLENS,u'table-source'), + (TABLENS,u'target-range-address'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decl'), + (TEXTNS,u'index-entry-bibliography'), + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-link-end'), + (TEXTNS,u'index-entry-link-start'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + (TEXTNS,u'index-source-style'), + (TEXTNS,u'line-break'), + (TEXTNS,u'page'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u's'), + (TEXTNS,u'section-source'), + (TEXTNS,u'sequence-decl'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'sort-key'), + (TEXTNS,u'tab'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-field-decl'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-decl') +)
Property changes on: trunk/pywikipedia/odf/elementtypes.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/form.py =================================================================== --- trunk/pywikipedia/odf/form.py (rev 0) +++ trunk/pywikipedia/odf/form.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import FORMNS +from element import Element + + +# Autogenerated +def Button(**args): + return Element(qname = (FORMNS,'button'), **args) + +def Checkbox(**args): + return Element(qname = (FORMNS,'checkbox'), **args) + +def Column(**args): + return Element(qname = (FORMNS,'column'), **args) + +def Combobox(**args): + return Element(qname = (FORMNS,'combobox'), **args) + +def ConnectionResource(**args): + return Element(qname = (FORMNS,'connection-resource'), **args) + +def Date(**args): + return Element(qname = (FORMNS,'date'), **args) + +def File(**args): + return Element(qname = (FORMNS,'file'), **args) + +def FixedText(**args): + return Element(qname = (FORMNS,'fixed-text'), **args) + +def Form(**args): + return Element(qname = (FORMNS,'form'), **args) + +def FormattedText(**args): + return Element(qname = (FORMNS,'formatted-text'), **args) + +def Frame(**args): + return Element(qname = (FORMNS,'frame'), **args) + +def GenericControl(**args): + return Element(qname = (FORMNS,'generic-control'), **args) + +def Grid(**args): + return Element(qname = (FORMNS,'grid'), **args) + +def Hidden(**args): + return Element(qname = (FORMNS,'hidden'), **args) + +def Image(**args): + return Element(qname = (FORMNS,'image'), **args) + +def ImageFrame(**args): + return Element(qname = (FORMNS,'image-frame'), **args) + +def Item(**args): + return Element(qname = (FORMNS,'item'), **args) + +def ListProperty(**args): + return Element(qname = (FORMNS,'list-property'), **args) + +def ListValue(**args): + return Element(qname = (FORMNS,'list-value'), **args) + +def Listbox(**args): + return Element(qname = (FORMNS,'listbox'), **args) + +def Number(**args): + return Element(qname = (FORMNS,'number'), **args) + +def Option(**args): + return Element(qname = (FORMNS,'option'), **args) + +def Password(**args): + return Element(qname = (FORMNS,'password'), **args) + +def Properties(**args): + return Element(qname = (FORMNS,'properties'), **args) + +def Property(**args): + return Element(qname = (FORMNS,'property'), **args) + +def Radio(**args): + return Element(qname = (FORMNS,'radio'), **args) + +def Text(**args): + return Element(qname = (FORMNS,'text'), **args) + +def Textarea(**args): + return Element(qname = (FORMNS,'textarea'), **args) + +def Time(**args): + return Element(qname = (FORMNS,'time'), **args) + +def ValueRange(**args): + return Element(qname = (FORMNS,'value-range'), **args) +
Property changes on: trunk/pywikipedia/odf/form.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/grammar.py =================================================================== --- trunk/pywikipedia/odf/grammar.py (rev 0) +++ trunk/pywikipedia/odf/grammar.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,8426 @@ +# -*- 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__=""" In principle the OpenDocument schema converted to python structures. +Currently it contains the legal child elements of a given element. +To be used for validation check in the API +""" + +from namespaces import * + +# The following code is generated from the RelaxNG schema with this notice: + +# OASIS OpenDocument v1.1 +# OASIS Standard, 1 Feb 2007 +# Relax-NG Schema + +# $Id$ + +# © 2002-2007 OASIS Open +# © 1999-2007 Sun Microsystems, Inc. + +# This document and translations of it may be copied and furnished +# to others, and derivative works that comment on or otherwise explain +# it or assist in its implementation may be prepared, copied, +# published and distributed, in whole or in part, without restriction +# of any kind, provided that the above copyright notice and this +# paragraph are included on all such copies and derivative works. +# However, this document itself does not be modified in any way, such +# as by removing the copyright notice or references to OASIS, except +# as needed for the purpose of developing OASIS specifications, in +# which case the procedures for copyrights defined in the OASIS +# Intellectual Property Rights document must be followed, or as +# required to translate it into languages other than English. +# + +allowed_children = { + (DCNS,u'creator') : ( + ), + (DCNS,u'date') : ( + ), + (DCNS,u'description') : ( + ), + (DCNS,u'language') : ( + ), + (DCNS,u'subject') : ( + ), + (DCNS,u'title') : ( + ), +# Completes Dublin Core start +# (DCNS,'contributor') : ( +# ), +# (DCNS,'coverage') : ( +# ), +# (DCNS,'format') : ( +# ), +# (DCNS,'identifier') : ( +# ), +# (DCNS,'publisher') : ( +# ), +# (DCNS,'relation') : ( +# ), +# (DCNS,'rights') : ( +# ), +# (DCNS,'source') : ( +# ), +# (DCNS,'type') : ( +# ), +# Completes Dublin Core end + (MATHNS,u'math') : None, + + (XFORMSNS,u'model') : None, + + (ANIMNS,u'animate') : ( + ), + (ANIMNS,u'animateColor') : ( + ), + (ANIMNS,u'animateMotion') : ( + ), + (ANIMNS,u'animateTransform') : ( + ), + (ANIMNS,u'audio') : ( + ), + (ANIMNS,u'command') : ( + (ANIMNS,u'param'), + ), +# allowed_children + (ANIMNS,u'iterate') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + ), + (ANIMNS,u'par') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + ), +# allowed_children + (ANIMNS,u'param') : ( + ), + (ANIMNS,u'seq') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + ), + (ANIMNS,u'set') : ( + ), + (ANIMNS,u'transitionFilter') : ( + ), + (CHARTNS,u'axis') : ( + (CHARTNS,u'categories'), + (CHARTNS,u'grid'), + (CHARTNS,u'title'), + ), +# allowed_children + (CHARTNS,u'categories') : ( + ), + (CHARTNS,u'chart') : ( + (CHARTNS,u'footer'), + (CHARTNS,u'legend'), + (CHARTNS,u'plot-area'), + (CHARTNS,u'subtitle'), + (CHARTNS,u'title'), + (TABLENS,u'table'), + ), + (CHARTNS,u'data-point') : ( + ), + (CHARTNS,u'domain') : ( + ), + (CHARTNS,u'error-indicator') : ( + ), + (CHARTNS,u'floor') : ( + ), + (CHARTNS,u'footer') : ( + (TEXTNS,u'p'), + ), + (CHARTNS,u'grid') : ( + ), + (CHARTNS,u'legend') : ( + ), +# allowed_children + (CHARTNS,u'mean-value') : ( + ), + (CHARTNS,u'plot-area') : ( + (CHARTNS,u'axis'), + (CHARTNS,u'floor'), + (CHARTNS,u'series'), + (CHARTNS,u'stock-gain-marker'), + (CHARTNS,u'stock-loss-marker'), + (CHARTNS,u'stock-range-line'), + (CHARTNS,u'wall'), + (DR3DNS,u'light'), + ), + (CHARTNS,u'regression-curve') : ( + ), + (CHARTNS,u'series') : ( + (CHARTNS,u'data-point'), + (CHARTNS,u'domain'), + (CHARTNS,u'error-indicator'), + (CHARTNS,u'mean-value'), + (CHARTNS,u'regression-curve'), + ), + (CHARTNS,u'stock-gain-marker') : ( + ), + (CHARTNS,u'stock-loss-marker') : ( + ), +# allowed_children + (CHARTNS,u'stock-range-line') : ( + ), + (CHARTNS,u'subtitle') : ( + (TEXTNS,u'p'), + ), + (CHARTNS,u'symbol-image') : ( + ), + (CHARTNS,u'title') : ( + (TEXTNS,u'p'), + ), + (CHARTNS,u'wall') : ( + ), + (CONFIGNS,u'config-item') : ( + ), + (CONFIGNS,u'config-item-map-entry') : ( + (CONFIGNS,u'config-item'), + (CONFIGNS,u'config-item-map-indexed'), + (CONFIGNS,u'config-item-map-named'), + (CONFIGNS,u'config-item-set'), + ), + (CONFIGNS,u'config-item-map-indexed') : ( + (CONFIGNS,u'config-item-map-entry'), + ), + (CONFIGNS,u'config-item-map-named') : ( + (CONFIGNS,u'config-item-map-entry'), + ), +# allowed_children + (CONFIGNS,u'config-item-set') : ( + (CONFIGNS,u'config-item'), + (CONFIGNS,u'config-item-map-indexed'), + (CONFIGNS,u'config-item-map-named'), + (CONFIGNS,u'config-item-set'), + ), + (MANIFESTNS,u'algorithm') : ( + ), + (MANIFESTNS,u'encryption-data') : ( + (MANIFESTNS,u'algorithm'), + (MANIFESTNS,u'key-derivation'), + ), + (MANIFESTNS,u'file-entry') : ( + (MANIFESTNS,u'encryption-data'), + ), + (MANIFESTNS,u'key-derivation') : ( + ), + (MANIFESTNS,u'manifest') : ( + (MANIFESTNS,u'file-entry'), + ), + (NUMBERNS,u'am-pm') : ( + ), + (NUMBERNS,u'boolean') : ( + ), +# allowed_children + (NUMBERNS,u'boolean-style') : ( + (NUMBERNS,u'boolean'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), + (NUMBERNS,u'currency-style') : ( + (NUMBERNS,u'currency-symbol'), + (NUMBERNS,u'number'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), + (NUMBERNS,u'currency-symbol') : ( + ), + (NUMBERNS,u'date-style') : ( + (NUMBERNS,u'am-pm'), + (NUMBERNS,u'day'), + (NUMBERNS,u'day-of-week'), + (NUMBERNS,u'era'), + (NUMBERNS,u'hours'), + (NUMBERNS,u'minutes'), + (NUMBERNS,u'month'), + (NUMBERNS,u'quarter'), + (NUMBERNS,u'seconds'), + (NUMBERNS,u'text'), + (NUMBERNS,u'week-of-year'), + (NUMBERNS,u'year'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), +# allowed_children + (NUMBERNS,u'day') : ( + ), + (NUMBERNS,u'day-of-week') : ( + ), + (NUMBERNS,u'embedded-text') : ( + ), + (NUMBERNS,u'era') : ( + ), + (NUMBERNS,u'fraction') : ( + ), + (NUMBERNS,u'hours') : ( + ), + (NUMBERNS,u'minutes') : ( + ), + (NUMBERNS,u'month') : ( + ), + (NUMBERNS,u'number') : ( + (NUMBERNS,u'embedded-text'), + ), + (NUMBERNS,u'number-style') : ( + (NUMBERNS,u'fraction'), + (NUMBERNS,u'number'), + (NUMBERNS,u'scientific-number'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), +# allowed_children + (NUMBERNS,u'percentage-style') : ( + (NUMBERNS,u'number'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), + (NUMBERNS,u'quarter') : ( + ), + (NUMBERNS,u'scientific-number') : ( + ), + (NUMBERNS,u'seconds') : ( + ), + (NUMBERNS,u'text') : ( + ), + (NUMBERNS,u'text-content') : ( + ), + (NUMBERNS,u'text-style') : ( + (NUMBERNS,u'text'), + (NUMBERNS,u'text-content'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), +# allowed_children + (NUMBERNS,u'time-style') : ( + (NUMBERNS,u'am-pm'), + (NUMBERNS,u'hours'), + (NUMBERNS,u'minutes'), + (NUMBERNS,u'seconds'), + (NUMBERNS,u'text'), + (STYLENS,u'map'), + (STYLENS,u'text-properties'), + ), +# allowed_children + (NUMBERNS,u'week-of-year') : ( + ), + (NUMBERNS,u'year') : ( + ), + (DR3DNS,u'cube') : ( + ), + (DR3DNS,u'extrude') : ( + ), + (DR3DNS,u'light') : ( + ), + (DR3DNS,u'rotate') : ( + ), + (DR3DNS,u'scene') : ( + (DR3DNS,u'cube'), + (DR3DNS,u'extrude'), + (DR3DNS,u'light'), + (DR3DNS,u'rotate'), + (DR3DNS,u'scene'), + (DR3DNS,u'sphere'), + (SVGNS,u'title'), + (SVGNS,u'desc'), + ), + (DR3DNS,u'sphere') : ( + ), + (DRAWNS,u'a') : ( + (DRAWNS,u'frame'), + ), +# allowed_children + (DRAWNS,u'applet') : ( + (DRAWNS,u'param'), + ), + (DRAWNS,u'area-circle') : ( + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), + (DRAWNS,u'area-polygon') : ( + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), + (DRAWNS,u'area-rectangle') : ( + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), + (DRAWNS,u'caption') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'circle') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), +# allowed_children + (DRAWNS,u'connector') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'contour-path') : ( + ), + (DRAWNS,u'contour-polygon') : ( + ), + (DRAWNS,u'control') : ( + (DRAWNS,u'glue-point'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), + (DRAWNS,u'custom-shape') : ( + (DRAWNS,u'enhanced-geometry'), + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), +# allowed_children + (DRAWNS,u'ellipse') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'enhanced-geometry') : ( + (DRAWNS,u'equation'), + (DRAWNS,u'handle'), + ), + (DRAWNS,u'equation') : ( + ), +# allowed_children + (DRAWNS,u'fill-image') : ( + ), + (DRAWNS,u'floating-frame') : ( + ), + (DRAWNS,u'frame') : ( + (DRAWNS,u'applet'), + (DRAWNS,u'contour-path'), + (DRAWNS,u'contour-polygon'), + (DRAWNS,u'floating-frame'), + (DRAWNS,u'glue-point'), + (DRAWNS,u'image'), + (DRAWNS,u'image-map'), + (DRAWNS,u'object'), + (DRAWNS,u'object-ole'), + (DRAWNS,u'plugin'), + (DRAWNS,u'text-box'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), +# allowed_children + (DRAWNS,u'g') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'glue-point'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (OFFICENS,u'event-listeners'), + ), + (DRAWNS,u'glue-point') : ( + ), + (DRAWNS,u'gradient') : ( + ), + (DRAWNS,u'handle') : ( + ), + (DRAWNS,u'hatch') : ( + ), +# allowed_children + (DRAWNS,u'image') : ( + (OFFICENS,u'binary-data'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'image-map') : ( + (DRAWNS,u'area-circle'), + (DRAWNS,u'area-polygon'), + (DRAWNS,u'area-rectangle'), + ), + (DRAWNS,u'layer') : ( + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), + (DRAWNS,u'layer-set') : ( + (DRAWNS,u'layer'), + ), + (DRAWNS,u'line') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'marker') : ( + ), + (DRAWNS,u'measure') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + (SVGNS,u'title'), + (SVGNS,u'desc'), + ), + (DRAWNS,u'object') : ( + (MATHNS,u'math'), + (OFFICENS,u'document'), + ), +# allowed_children + (DRAWNS,u'object-ole') : ( + (OFFICENS,u'binary-data'), + ), + (DRAWNS,u'opacity') : ( + ), + (DRAWNS,u'page') : ( + (ANIMNS,u'animate'), + (ANIMNS,u'animateColor'), + (ANIMNS,u'animateMotion'), + (ANIMNS,u'animateTransform'), + (ANIMNS,u'audio'), + (ANIMNS,u'command'), + (ANIMNS,u'iterate'), + (ANIMNS,u'par'), + (ANIMNS,u'seq'), + (ANIMNS,u'set'), + (ANIMNS,u'transitionFilter'), + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'forms'), + (PRESENTATIONNS,u'animations'), + (PRESENTATIONNS,u'notes'), + ), +# allowed_children + (DRAWNS,u'page-thumbnail') : ( + (SVGNS,u'desc'), + (SVGNS,u'title'), + ), + (DRAWNS,u'param') : ( + ), + (DRAWNS,u'path') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'plugin') : ( + (DRAWNS,u'param'), + ), + (DRAWNS,u'polygon') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'title'), + (SVGNS,u'desc'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'polyline') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), +# allowed_children + (DRAWNS,u'rect') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'regular-polygon') : ( + (DRAWNS,u'glue-point'), + (OFFICENS,u'event-listeners'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (DRAWNS,u'stroke-dash') : ( + ), + (DRAWNS,u'text-box') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), +# allowed_children + (FORMNS,u'button') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'checkbox') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'column') : ( + (FORMNS,u'checkbox'), + (FORMNS,u'combobox'), + (FORMNS,u'date'), + (FORMNS,u'formatted-text'), + (FORMNS,u'listbox'), + (FORMNS,u'number'), + (FORMNS,u'text'), + (FORMNS,u'textarea'), + ), + (FORMNS,u'combobox') : ( + (FORMNS,u'item'), + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'connection-resource') : ( + ), + (FORMNS,u'date') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'file') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'fixed-text') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), +# allowed_children + (FORMNS,u'form') : ( + (FORMNS,u'button'), + (FORMNS,u'checkbox'), + (FORMNS,u'combobox'), + (FORMNS,u'connection-resource'), + (FORMNS,u'date'), + (FORMNS,u'file'), + (FORMNS,u'fixed-text'), + (FORMNS,u'form'), + (FORMNS,u'formatted-text'), + (FORMNS,u'frame'), + (FORMNS,u'generic-control'), + (FORMNS,u'grid'), + (FORMNS,u'hidden'), + (FORMNS,u'image'), + (FORMNS,u'image-frame'), + (FORMNS,u'listbox'), + (FORMNS,u'number'), + (FORMNS,u'password'), + (FORMNS,u'properties'), + (FORMNS,u'radio'), + (FORMNS,u'text'), + (FORMNS,u'textarea'), + (FORMNS,u'time'), + (FORMNS,u'value-range'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'formatted-text') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'frame') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'generic-control') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'grid') : ( + (FORMNS,u'column'), + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'hidden') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'image') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), +# allowed_children + (FORMNS,u'image-frame') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'item') : ( + ), + (FORMNS,u'list-property') : ( + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + (FORMNS,u'list-value'), + ), + (FORMNS,u'list-value') : ( + ), + (FORMNS,u'listbox') : ( + (FORMNS,u'option'), + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'number') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'option') : ( + ), + (FORMNS,u'password') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'properties') : ( + (FORMNS,u'list-property'), + (FORMNS,u'property'), + ), + (FORMNS,u'property') : ( + ), + (FORMNS,u'radio') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'text') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'textarea') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + (TEXTNS,u'p'), + ), + (FORMNS,u'time') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (FORMNS,u'value-range') : ( + (FORMNS,u'properties'), + (OFFICENS,u'event-listeners'), + ), + (METANS,u'auto-reload') : ( + ), + (METANS,u'creation-date') : ( + ), + (METANS,u'date-string') : ( + ), + (METANS,u'document-statistic') : ( + ), + (METANS,u'editing-cycles') : ( + ), + (METANS,u'editing-duration') : ( + ), + (METANS,u'generator') : ( + ), + (METANS,u'hyperlink-behaviour') : ( + ), + (METANS,u'initial-creator') : ( + ), + (METANS,u'keyword') : ( + ), + (METANS,u'print-date') : ( + ), + (METANS,u'printed-by') : ( + ), + (METANS,u'template') : ( + ), + (METANS,u'user-defined') : ( + ), +# allowed_children + (OFFICENS,u'annotation') : ( + (DCNS,u'creator'), + (DCNS,u'date'), + (METANS,u'date-string'), + (TEXTNS,u'list'), + (TEXTNS,u'p'), + ), + (OFFICENS,u'automatic-styles') : ( + (NUMBERNS,u'boolean-style'), + (NUMBERNS,u'currency-style'), + (NUMBERNS,u'date-style'), + (NUMBERNS,u'number-style'), + (NUMBERNS,u'percentage-style'), + (NUMBERNS,u'text-style'), + (NUMBERNS,u'time-style'), + (STYLENS,u'page-layout'), + (STYLENS,u'style'), + (TEXTNS,u'list-style'), + ), + (OFFICENS,u'binary-data') : ( + ), + (OFFICENS,u'body') : ( + (OFFICENS,u'chart'), + (OFFICENS,u'drawing'), + (OFFICENS,u'image'), + (OFFICENS,u'presentation'), + (OFFICENS,u'spreadsheet'), + (OFFICENS,u'text'), + ), + (OFFICENS,u'change-info') : ( + (DCNS,u'creator'), + (DCNS,u'date'), + (TEXTNS,u'p'), + ), + (OFFICENS,u'chart') : ( + (CHARTNS,u'chart'), + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'variable-decls'), + ), + (OFFICENS,u'dde-source') : ( + ), + (OFFICENS,u'document') : ( + (OFFICENS,u'automatic-styles'), + (OFFICENS,u'body'), + (OFFICENS,u'font-face-decls'), + (OFFICENS,u'master-styles'), + (OFFICENS,u'meta'), + (OFFICENS,u'scripts'), + (OFFICENS,u'settings'), + (OFFICENS,u'styles'), + ), + (OFFICENS,u'document-content') : ( + (OFFICENS,u'automatic-styles'), + (OFFICENS,u'body'), + (OFFICENS,u'font-face-decls'), + (OFFICENS,u'scripts'), + ), + (OFFICENS,u'document-meta') : ( + (OFFICENS,u'meta'), + ), + (OFFICENS,u'document-settings') : ( + (OFFICENS,u'settings'), + ), + (OFFICENS,u'document-styles') : ( + (OFFICENS,u'automatic-styles'), + (OFFICENS,u'font-face-decls'), + (OFFICENS,u'master-styles'), + (OFFICENS,u'styles'), + ), + (OFFICENS,u'drawing') : ( + (DRAWNS,u'page'), + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'variable-decls'), + ), + (OFFICENS,u'event-listeners') : ( + (PRESENTATIONNS,u'event-listener'), + (SCRIPTNS,u'event-listener'), + ), + (OFFICENS,u'font-face-decls') : ( + (STYLENS,u'font-face'), + ), +# allowed_children + (OFFICENS,u'forms') : ( + (XFORMSNS,u'model'), + (FORMNS,u'form'), + ), + (OFFICENS,u'image') : ( + (DRAWNS,u'frame'), + ), + (OFFICENS,u'master-styles') : ( + (DRAWNS,u'layer-set'), + (STYLENS,u'handout-master'), + (STYLENS,u'master-page'), + (TABLENS,u'table-template'), + ), + (OFFICENS,u'meta') : ( + (DCNS,u'creator'), + (DCNS,u'date'), + (DCNS,u'description'), + (DCNS,u'language'), + (DCNS,u'subject'), + (DCNS,u'title'), +# Completes Dublin Core start +# (DCNS,'contributor'), +# (DCNS,'coverage'), +# (DCNS,'format'), +# (DCNS,'identifier'), +# (DCNS,'publisher'), +# (DCNS,'relation'), +# (DCNS,'rights'), +# (DCNS,'source'), +# (DCNS,'type'), +# Completes Dublin Core end + (METANS,u'auto-reload'), + (METANS,u'creation-date'), + (METANS,u'document-statistic'), + (METANS,u'editing-cycles'), + (METANS,u'editing-duration'), + (METANS,u'generator'), + (METANS,u'hyperlink-behaviour'), + (METANS,u'initial-creator'), + (METANS,u'keyword'), + (METANS,u'print-date'), + (METANS,u'printed-by'), + (METANS,u'template'), + (METANS,u'user-defined'), + ), + (OFFICENS,u'presentation') : ( + (DRAWNS,u'page'), + (PRESENTATIONNS,u'date-time-decl'), + (PRESENTATIONNS,u'footer-decl'), + (PRESENTATIONNS,u'header-decl'), + (PRESENTATIONNS,u'settings'), + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'variable-decls'), + ), +# allowed_children + (OFFICENS,u'script') : None, + + (OFFICENS,u'scripts') : ( + (OFFICENS,u'event-listeners'), + (OFFICENS,u'script'), + ), + (OFFICENS,u'settings') : ( + (CONFIGNS,u'config-item-set'), + ), + (OFFICENS,u'spreadsheet') : ( + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TABLENS,u'table'), + (TABLENS,u'tracked-changes'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'variable-decls'), + ), + (OFFICENS,u'styles') : ( + (NUMBERNS,u'boolean-style'), + (NUMBERNS,u'currency-style'), + (NUMBERNS,u'date-style'), + (NUMBERNS,u'number-style'), + (NUMBERNS,u'percentage-style'), + (NUMBERNS,u'text-style'), + (NUMBERNS,u'time-style'), + (DRAWNS,u'fill-image'), + (DRAWNS,u'gradient'), + (DRAWNS,u'hatch'), + (DRAWNS,u'marker'), + (DRAWNS,u'opacity'), + (DRAWNS,u'stroke-dash'), + (STYLENS,u'default-style'), + (STYLENS,u'presentation-page-layout'), + (STYLENS,u'style'), + (SVGNS,u'linearGradient'), + (SVGNS,u'radialGradient'), + (TEXTNS,u'bibliography-configuration'), + (TEXTNS,u'linenumbering-configuration'), + (TEXTNS,u'list-style'), + (TEXTNS,u'notes-configuration'), + (TEXTNS,u'outline-style'), + ), + (OFFICENS,u'text') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'forms'), + (TABLENS,u'calculation-settings'), + (TABLENS,u'consolidation'), + (TABLENS,u'content-validations'), + (TABLENS,u'data-pilot-tables'), + (TABLENS,u'database-ranges'), + (TABLENS,u'dde-links'), + (TABLENS,u'label-ranges'), + (TABLENS,u'named-expressions'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'page-sequence'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'tracked-changes'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), + (PRESENTATIONNS,u'animation-group') : ( + (PRESENTATIONNS,u'dim'), + (PRESENTATIONNS,u'hide-shape'), + (PRESENTATIONNS,u'hide-text'), + (PRESENTATIONNS,u'play'), + (PRESENTATIONNS,u'show-shape'), + (PRESENTATIONNS,u'show-text'), + ), + (PRESENTATIONNS,u'animations') : ( + (PRESENTATIONNS,u'animation-group'), + (PRESENTATIONNS,u'dim'), + (PRESENTATIONNS,u'hide-shape'), + (PRESENTATIONNS,u'hide-text'), + (PRESENTATIONNS,u'play'), + (PRESENTATIONNS,u'show-shape'), + (PRESENTATIONNS,u'show-text'), + ), + (PRESENTATIONNS,u'date-time') : ( + ), + (PRESENTATIONNS,u'date-time-decl') : ( + ), + (PRESENTATIONNS,u'dim') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'event-listener') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'footer') : ( + ), + (PRESENTATIONNS,u'footer-decl') : ( + ), + (PRESENTATIONNS,u'header') : ( + ), + (PRESENTATIONNS,u'header-decl') : ( + ), + (PRESENTATIONNS,u'hide-shape') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'hide-text') : ( + (PRESENTATIONNS,u'sound'), + ), +# allowed_children + (PRESENTATIONNS,u'notes') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'forms'), + ), + (PRESENTATIONNS,u'placeholder') : ( + ), + (PRESENTATIONNS,u'play') : ( + ), + (PRESENTATIONNS,u'settings') : ( + (PRESENTATIONNS,u'show'), + ), + (PRESENTATIONNS,u'show') : ( + ), + (PRESENTATIONNS,u'show-shape') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'show-text') : ( + (PRESENTATIONNS,u'sound'), + ), + (PRESENTATIONNS,u'sound') : ( + ), + (SCRIPTNS,u'event-listener') : ( + ), + (STYLENS,u'background-image') : ( + (OFFICENS,u'binary-data'), + ), + (STYLENS,u'chart-properties') : ( + (CHARTNS,u'symbol-image'), + ), + (STYLENS,u'column') : ( + ), + (STYLENS,u'column-sep') : ( + ), + (STYLENS,u'columns') : ( + (STYLENS,u'column'), + (STYLENS,u'column-sep'), + ), + (STYLENS,u'default-style') : ( + (STYLENS,u'chart-properties'), + (STYLENS,u'drawing-page-properties'), + (STYLENS,u'graphic-properties'), + (STYLENS,u'paragraph-properties'), + (STYLENS,u'ruby-properties'), + (STYLENS,u'section-properties'), + (STYLENS,u'table-cell-properties'), + (STYLENS,u'table-column-properties'), + (STYLENS,u'table-properties'), + (STYLENS,u'table-row-properties'), + (STYLENS,u'text-properties'), + ), + (STYLENS,u'drawing-page-properties') : ( + (PRESENTATIONNS,u'sound'), + ), + (STYLENS,u'drop-cap') : ( + ), + (STYLENS,u'font-face') : ( + (SVGNS,u'definition-src'), + (SVGNS,u'font-face-src'), + ), + (STYLENS,u'footer') : ( + (STYLENS,u'region-center'), + (STYLENS,u'region-left'), + (STYLENS,u'region-right'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'tracked-changes'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), +# allowed_children + (STYLENS,u'footer-left') : ( + (STYLENS,u'region-center'), + (STYLENS,u'region-left'), + (STYLENS,u'region-right'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'tracked-changes'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), + (STYLENS,u'footer-style') : ( + (STYLENS,u'header-footer-properties'), + ), + (STYLENS,u'footnote-sep') : ( + ), + (STYLENS,u'graphic-properties') : ( + (STYLENS,u'background-image'), + (STYLENS,u'columns'), + (TEXTNS,u'list-style'), + ), +# allowed_children + (STYLENS,u'handout-master') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + ), + (STYLENS,u'header') : ( + (STYLENS,u'region-center'), + (STYLENS,u'region-left'), + (STYLENS,u'region-right'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'tracked-changes'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), +# allowed_children + (STYLENS,u'header-footer-properties') : ( + (STYLENS,u'background-image'), + ), + (STYLENS,u'header-left') : ( + (STYLENS,u'region-center'), + (STYLENS,u'region-left'), + (STYLENS,u'region-right'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'alphabetical-index-auto-mark-file'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'dde-connection-decls'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'sequence-decls'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'tracked-changes'), + (TEXTNS,u'user-field-decls'), + (TEXTNS,u'user-index'), + (TEXTNS,u'variable-decls'), + ), + (STYLENS,u'header-style') : ( + (STYLENS,u'header-footer-properties'), + ), + (STYLENS,u'list-level-properties') : ( + ), + (STYLENS,u'map') : ( + ), + (STYLENS,u'master-page') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'forms'), + (PRESENTATIONNS,u'notes'), + (STYLENS,u'footer'), + (STYLENS,u'footer-left'), + (STYLENS,u'header'), + (STYLENS,u'header-left'), + (STYLENS,u'style'), + ), + (STYLENS,u'page-layout') : ( + (STYLENS,u'footer-style'), + (STYLENS,u'header-style'), + (STYLENS,u'page-layout-properties'), + ), + (STYLENS,u'page-layout-properties') : ( + (STYLENS,u'background-image'), + (STYLENS,u'columns'), + (STYLENS,u'footnote-sep'), + ), +# allowed_children + (STYLENS,u'paragraph-properties') : ( + (STYLENS,u'background-image'), + (STYLENS,u'drop-cap'), + (STYLENS,u'tab-stops'), + ), + (STYLENS,u'presentation-page-layout') : ( + (PRESENTATIONNS,u'placeholder'), + ), + (STYLENS,u'region-center') : ( + (TEXTNS,u'p'), + ), + (STYLENS,u'region-left') : ( + (TEXTNS,u'p'), + ), + (STYLENS,u'region-right') : ( + (TEXTNS,u'p'), + ), + (STYLENS,u'ruby-properties') : ( + ), + (STYLENS,u'section-properties') : ( + (STYLENS,u'background-image'), + (STYLENS,u'columns'), + (TEXTNS,u'notes-configuration'), + ), + (STYLENS,u'style') : ( + (STYLENS,u'chart-properties'), + (STYLENS,u'drawing-page-properties'), + (STYLENS,u'graphic-properties'), + (STYLENS,u'map'), + (STYLENS,u'paragraph-properties'), + (STYLENS,u'ruby-properties'), + (STYLENS,u'section-properties'), + (STYLENS,u'table-cell-properties'), + (STYLENS,u'table-column-properties'), + (STYLENS,u'table-properties'), + (STYLENS,u'table-row-properties'), + (STYLENS,u'text-properties'), + ), + (STYLENS,u'tab-stop') : ( + ), + (STYLENS,u'tab-stops') : ( + (STYLENS,u'tab-stop'), + ), +# allowed_children + (STYLENS,u'table-cell-properties') : ( + (STYLENS,u'background-image'), + ), + (STYLENS,u'table-column-properties') : ( + ), + (STYLENS,u'table-properties') : ( + (STYLENS,u'background-image'), + ), + (STYLENS,u'table-row-properties') : ( + (STYLENS,u'background-image'), + ), + (STYLENS,u'text-properties') : ( + ), + (SVGNS,u'definition-src') : ( + ), + (SVGNS,u'desc') : ( + ), + (SVGNS,u'font-face-format') : ( + ), + (SVGNS,u'font-face-name') : ( + ), + (SVGNS,u'font-face-src') : ( + (SVGNS,u'font-face-name'), + (SVGNS,u'font-face-uri'), + ), + (SVGNS,u'font-face-uri') : ( + (SVGNS,u'font-face-format'), + ), + (SVGNS,u'linearGradient') : ( + (SVGNS,u'stop'), + ), + (SVGNS,u'radialGradient') : ( + (SVGNS,u'stop'), + ), + (SVGNS,u'stop') : ( + ), + (SVGNS,u'title') : ( + ), + (TABLENS,u'body') : ( + ), + (TABLENS,u'calculation-settings') : ( + (TABLENS,u'iteration'), + (TABLENS,u'null-date'), + ), +# allowed_children + (TABLENS,u'cell-address') : ( + ), + (TABLENS,u'cell-content-change') : ( + (OFFICENS,u'change-info'), + (TABLENS,u'cell-address'), + (TABLENS,u'deletions'), + (TABLENS,u'dependencies'), + (TABLENS,u'previous'), + ), + (TABLENS,u'cell-content-deletion') : ( + (TABLENS,u'cell-address'), + (TABLENS,u'change-track-table-cell'), + ), + (TABLENS,u'cell-range-source') : ( + ), + (TABLENS,u'change-deletion') : ( + ), + (TABLENS,u'change-track-table-cell') : ( + (TEXTNS,u'p'), + ), + (TABLENS,u'consolidation') : ( + ), + (TABLENS,u'content-validation') : ( + (OFFICENS,u'event-listeners'), + (TABLENS,u'error-macro'), + (TABLENS,u'error-message'), + (TABLENS,u'help-message'), + ), +# allowed_children + (TABLENS,u'content-validations') : ( + (TABLENS,u'content-validation'), + ), + (TABLENS,u'covered-table-cell') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (TABLENS,u'cell-range-source'), + (TABLENS,u'detective'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), +# allowed_children + (TABLENS,u'cut-offs') : ( + (TABLENS,u'insertion-cut-off'), + (TABLENS,u'movement-cut-off'), + ), + (TABLENS,u'data-pilot-display-info') : ( + ), + (TABLENS,u'data-pilot-field') : ( + (TABLENS,u'data-pilot-field-reference'), + (TABLENS,u'data-pilot-groups'), + (TABLENS,u'data-pilot-level'), + ), + (TABLENS,u'data-pilot-field-reference') : ( + ), + (TABLENS,u'data-pilot-group') : ( + (TABLENS,u'data-pilot-group-member'), + ), + (TABLENS,u'data-pilot-group-member') : ( + ), + (TABLENS,u'data-pilot-groups') : ( + (TABLENS,u'data-pilot-group'), + ), + (TABLENS,u'data-pilot-layout-info') : ( + ), + (TABLENS,u'data-pilot-level') : ( + (TABLENS,u'data-pilot-display-info'), + (TABLENS,u'data-pilot-layout-info'), + (TABLENS,u'data-pilot-members'), + (TABLENS,u'data-pilot-sort-info'), + (TABLENS,u'data-pilot-subtotals'), + ), + (TABLENS,u'data-pilot-member') : ( + ), + (TABLENS,u'data-pilot-members') : ( + (TABLENS,u'data-pilot-member'), + ), + (TABLENS,u'data-pilot-sort-info') : ( + ), + (TABLENS,u'data-pilot-subtotal') : ( + ), + (TABLENS,u'data-pilot-subtotals') : ( + (TABLENS,u'data-pilot-subtotal'), + ), +# allowed_children + (TABLENS,u'data-pilot-table') : ( + (TABLENS,u'data-pilot-field'), + (TABLENS,u'database-source-query'), + (TABLENS,u'database-source-sql'), + (TABLENS,u'database-source-table'), + (TABLENS,u'source-cell-range'), + (TABLENS,u'source-service'), + ), + (TABLENS,u'data-pilot-tables') : ( + (TABLENS,u'data-pilot-table'), + ), + (TABLENS,u'database-range') : ( + (TABLENS,u'database-source-query'), + (TABLENS,u'database-source-sql'), + (TABLENS,u'database-source-table'), + (TABLENS,u'filter'), + (TABLENS,u'sort'), + (TABLENS,u'subtotal-rules'), + ), + (TABLENS,u'database-ranges') : ( + (TABLENS,u'database-range'), + ), + (TABLENS,u'database-source-query') : ( + ), + (TABLENS,u'database-source-sql') : ( + ), + (TABLENS,u'database-source-table') : ( + ), +# allowed_children + (TABLENS,u'dde-link') : ( + (OFFICENS,u'dde-source'), + (TABLENS,u'table'), + ), + (TABLENS,u'dde-links') : ( + (TABLENS,u'dde-link'), + ), + (TABLENS,u'deletion') : ( + (OFFICENS,u'change-info'), + (TABLENS,u'cut-offs'), + (TABLENS,u'deletions'), + (TABLENS,u'dependencies'), + ), + (TABLENS,u'deletions') : ( + (TABLENS,u'cell-content-deletion'), + (TABLENS,u'change-deletion'), + ), + (TABLENS,u'dependencies') : ( + (TABLENS,u'dependency'), + ), + (TABLENS,u'dependency') : ( + ), + (TABLENS,u'detective') : ( + (TABLENS,u'highlighted-range'), + (TABLENS,u'operation'), + ), +# allowed_children + (TABLENS,u'error-macro') : ( + ), + (TABLENS,u'error-message') : ( + (TEXTNS,u'p'), + ), + (TABLENS,u'even-columns') : ( + ), + (TABLENS,u'even-rows') : ( + ), + (TABLENS,u'filter') : ( + (TABLENS,u'filter-and'), + (TABLENS,u'filter-condition'), + (TABLENS,u'filter-or'), + ), + (TABLENS,u'filter-and') : ( + (TABLENS,u'filter-condition'), + (TABLENS,u'filter-or'), + ), + (TABLENS,u'filter-condition') : ( + ), + (TABLENS,u'filter-or') : ( + (TABLENS,u'filter-and'), + (TABLENS,u'filter-condition'), + ), +# allowed_children + (TABLENS,u'first-column') : ( + ), + (TABLENS,u'first-row') : ( + ), + (TABLENS,u'help-message') : ( + (TEXTNS,u'p'), + ), + (TABLENS,u'highlighted-range') : ( + ), + (TABLENS,u'insertion') : ( + (OFFICENS,u'change-info'), + (TABLENS,u'deletions'), + (TABLENS,u'dependencies'), + ), + (TABLENS,u'insertion-cut-off') : ( + ), + (TABLENS,u'iteration') : ( + ), + (TABLENS,u'label-range') : ( + ), + (TABLENS,u'label-ranges') : ( + (TABLENS,u'label-range'), + ), + (TABLENS,u'last-column') : ( + ), + (TABLENS,u'last-row') : ( + ), + (TABLENS,u'movement') : ( + (OFFICENS,u'change-info'), + (TABLENS,u'deletions'), + (TABLENS,u'dependencies'), + (TABLENS,u'source-range-address'), + (TABLENS,u'target-range-address'), + ), + (TABLENS,u'movement-cut-off') : ( + ), + (TABLENS,u'named-expression') : ( + ), + (TABLENS,u'named-expressions') : ( + (TABLENS,u'named-expression'), + (TABLENS,u'named-range'), + ), +# allowed_children + (TABLENS,u'named-range') : ( + ), + (TABLENS,u'null-date') : ( + ), + (TABLENS,u'odd-columns') : ( + ), + (TABLENS,u'odd-rows') : ( + ), + (TABLENS,u'operation') : ( + ), + (TABLENS,u'previous') : ( + (TABLENS,u'change-track-table-cell'), + ), + (TABLENS,u'scenario') : ( + ), + (TABLENS,u'shapes') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + ), +# allowed_children + (TABLENS,u'sort') : ( + (TABLENS,u'sort-by'), + ), + (TABLENS,u'sort-by') : ( + ), + (TABLENS,u'sort-groups') : ( + ), + (TABLENS,u'source-cell-range') : ( + (TABLENS,u'filter'), + ), + (TABLENS,u'source-range-address') : ( + ), + (TABLENS,u'source-service') : ( + ), + (TABLENS,u'subtotal-field') : ( + ), + (TABLENS,u'subtotal-rule') : ( + (TABLENS,u'subtotal-field'), + ), + (TABLENS,u'subtotal-rules') : ( + (TABLENS,u'sort-groups'), + (TABLENS,u'subtotal-rule'), + ), +# allowed_children + (TABLENS,u'table') : ( + (OFFICENS,u'dde-source'), + (OFFICENS,u'forms'), + (TEXTNS,u'soft-page-break'), + (TABLENS,u'scenario'), + (TABLENS,u'shapes'), + (TABLENS,u'table-column'), + (TABLENS,u'table-column-group'), + (TABLENS,u'table-columns'), + (TABLENS,u'table-header-columns'), + (TABLENS,u'table-header-rows'), + (TABLENS,u'table-row'), + (TABLENS,u'table-row-group'), + (TABLENS,u'table-rows'), + (TABLENS,u'table-source'), + ), + (TABLENS,u'table-cell') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (TABLENS,u'cell-range-source'), + (TABLENS,u'detective'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), +# allowed_children + (TABLENS,u'table-column') : ( + ), + (TABLENS,u'table-column-group') : ( + (TABLENS,u'table-column'), + (TABLENS,u'table-column-group'), + (TABLENS,u'table-columns'), + (TABLENS,u'table-header-columns'), + ), + (TABLENS,u'table-columns') : ( + (TABLENS,u'table-column'), + ), + (TABLENS,u'table-header-columns') : ( + (TABLENS,u'table-column'), + ), + (TABLENS,u'table-header-rows') : ( + (TABLENS,u'table-row'), + (TEXTNS,u'soft-page-break'), + ), + (TABLENS,u'table-row') : ( + (TABLENS,u'covered-table-cell'), + (TABLENS,u'table-cell'), + ), + (TABLENS,u'table-row-group') : ( + (TABLENS,u'table-header-rows'), + (TABLENS,u'table-row'), + (TABLENS,u'table-row-group'), + (TABLENS,u'table-rows'), + (TEXTNS,u'soft-page-break'), + ), + (TABLENS,u'table-rows') : ( + (TABLENS,u'table-row'), + (TEXTNS,u'soft-page-break'), + ), +# allowed_children + (TABLENS,u'table-source') : ( + ), + (TABLENS,u'table-template') : ( + (TABLENS,u'body'), + (TABLENS,u'even-columns'), + (TABLENS,u'even-rows'), + (TABLENS,u'first-column'), + (TABLENS,u'first-row'), + (TABLENS,u'last-column'), + (TABLENS,u'last-row'), + (TABLENS,u'odd-columns'), + (TABLENS,u'odd-rows'), + ), + (TABLENS,u'target-range-address') : ( + ), + (TABLENS,u'tracked-changes') : ( + (TABLENS,u'cell-content-change'), + (TABLENS,u'deletion'), + (TABLENS,u'insertion'), + (TABLENS,u'movement'), + ), +# allowed_children + (TEXTNS,u'a') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (OFFICENS,u'event-listeners'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'page-count'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'word-count'), + (TEXTNS,u'character-count'), + (TEXTNS,u'table-count'), + (TEXTNS,u'image-count'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'print-time'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + ), +# allowed_children + (TEXTNS,u'alphabetical-index') : ( + (TEXTNS,u'alphabetical-index-source'), + (TEXTNS,u'index-body'), + ), + (TEXTNS,u'alphabetical-index-auto-mark-file') : ( + ), + (TEXTNS,u'alphabetical-index-entry-template') : ( + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'alphabetical-index-mark') : ( + ), + (TEXTNS,u'alphabetical-index-mark-end') : ( + ), + (TEXTNS,u'alphabetical-index-mark-start') : ( + ), + (TEXTNS,u'alphabetical-index-source') : ( + (TEXTNS,u'alphabetical-index-entry-template'), + (TEXTNS,u'index-title-template'), + ), + (TEXTNS,u'author-initials') : ( + ), + (TEXTNS,u'author-name') : ( + ), + (TEXTNS,u'bibliography') : ( + (TEXTNS,u'bibliography-source'), + (TEXTNS,u'index-body'), + ), + (TEXTNS,u'bibliography-configuration') : ( + (TEXTNS,u'sort-key'), + ), + (TEXTNS,u'bibliography-entry-template') : ( + (TEXTNS,u'index-entry-bibliography'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + ), +# allowed_children + (TEXTNS,u'bibliography-mark') : ( + ), + (TEXTNS,u'bibliography-source') : ( + (TEXTNS,u'bibliography-entry-template'), + (TEXTNS,u'index-title-template'), + ), + (TEXTNS,u'bookmark') : ( + ), + (TEXTNS,u'bookmark-end') : ( + ), + (TEXTNS,u'bookmark-ref') : ( + ), + (TEXTNS,u'bookmark-start') : ( + ), + (TEXTNS,u'change') : ( + ), + (TEXTNS,u'change-end') : ( + ), + (TEXTNS,u'change-start') : ( + ), + (TEXTNS,u'changed-region') : ( + (TEXTNS,u'deletion'), + (TEXTNS,u'format-change'), + (TEXTNS,u'insertion'), + ), + (TEXTNS,u'chapter') : ( + ), + (TEXTNS,u'character-count') : ( + ), + (TEXTNS,u'conditional-text') : ( + ), + (TEXTNS,u'creation-date') : ( + ), + (TEXTNS,u'creation-time') : ( + ), + (TEXTNS,u'creator') : ( + ), + (TEXTNS,u'database-display') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'database-name') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'database-next') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'database-row-number') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'database-row-select') : ( + (FORMNS,u'connection-resource'), + ), + (TEXTNS,u'date') : ( + ), + (TEXTNS,u'dde-connection') : ( + ), + (TEXTNS,u'dde-connection-decl') : ( + ), + (TEXTNS,u'dde-connection-decls') : ( + (TEXTNS,u'dde-connection-decl'), + ), +# allowed_children + (TEXTNS,u'deletion') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'change-info'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'description') : ( + ), + (TEXTNS,u'editing-cycles') : ( + ), + (TEXTNS,u'editing-duration') : ( + ), + (TEXTNS,u'execute-macro') : ( + (OFFICENS,u'event-listeners'), + ), + (TEXTNS,u'expression') : ( + ), + (TEXTNS,u'file-name') : ( + ), + (TEXTNS,u'format-change') : ( + (OFFICENS,u'change-info'), + ), +# allowed_children + (TEXTNS,u'h') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'number'), + (TEXTNS,u'page-count'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'word-count'), + (TEXTNS,u'character-count'), + (TEXTNS,u'table-count'), + (TEXTNS,u'image-count'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'print-time'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + ), +# allowed_children + (TEXTNS,u'hidden-paragraph') : ( + ), + (TEXTNS,u'hidden-text') : ( + ), + (TEXTNS,u'illustration-index') : ( + (TEXTNS,u'illustration-index-source'), + (TEXTNS,u'index-body'), + ), + (TEXTNS,u'illustration-index-entry-template') : ( + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'illustration-index-source') : ( + (TEXTNS,u'illustration-index-entry-template'), + (TEXTNS,u'index-title-template'), + ), + (TEXTNS,u'image-count') : ( + ), +# allowed_children + (TEXTNS,u'index-body') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'index-entry-bibliography') : ( + ), + (TEXTNS,u'index-entry-chapter') : ( + ), + (TEXTNS,u'index-entry-link-end') : ( + ), + (TEXTNS,u'index-entry-link-start') : ( + ), + (TEXTNS,u'index-entry-page-number') : ( + ), + (TEXTNS,u'index-entry-span') : ( + ), + (TEXTNS,u'index-entry-tab-stop') : ( + ), + (TEXTNS,u'index-entry-text') : ( + ), + (TEXTNS,u'index-source-style') : ( + ), + (TEXTNS,u'index-source-styles') : ( + (TEXTNS,u'index-source-style'), + ), +# allowed_children + (TEXTNS,u'index-title') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'index-title'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'index-title-template') : ( + ), + (TEXTNS,u'initial-creator') : ( + ), + (TEXTNS,u'insertion') : ( + (OFFICENS,u'change-info'), + ), + (TEXTNS,u'keywords') : ( + ), + (TEXTNS,u'line-break') : ( + ), + (TEXTNS,u'linenumbering-configuration') : ( + (TEXTNS,u'linenumbering-separator'), + ), + (TEXTNS,u'linenumbering-separator') : ( + ), + (TEXTNS,u'list') : ( + (TEXTNS,u'list-header'), + (TEXTNS,u'list-item'), + ), + (TEXTNS,u'list-header') : ( + (TEXTNS,u'h'), + (TEXTNS,u'list'), + (TEXTNS,u'number'), + (TEXTNS,u'p'), + (TEXTNS,u'soft-page-break'), + ), + (TEXTNS,u'list-item') : ( + (TEXTNS,u'h'), + (TEXTNS,u'list'), + (TEXTNS,u'number'), + (TEXTNS,u'p'), + (TEXTNS,u'soft-page-break'), + ), + (TEXTNS,u'list-level-style-bullet') : ( + (STYLENS,u'list-level-properties'), + (STYLENS,u'text-properties'), + ), + (TEXTNS,u'list-level-style-image') : ( + (OFFICENS,u'binary-data'), + (STYLENS,u'list-level-properties'), + ), + (TEXTNS,u'list-level-style-number') : ( + (STYLENS,u'list-level-properties'), + (STYLENS,u'text-properties'), + ), + (TEXTNS,u'list-style') : ( + (TEXTNS,u'list-level-style-bullet'), + (TEXTNS,u'list-level-style-image'), + (TEXTNS,u'list-level-style-number'), + ), + (TEXTNS,u'measure') : ( + ), + (TEXTNS,u'modification-date') : ( + ), + (TEXTNS,u'modification-time') : ( + ), + (TEXTNS,u'note') : ( + (TEXTNS,u'note-body'), + (TEXTNS,u'note-citation'), + ), +# allowed_children + (TEXTNS,u'note-body') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'note-citation') : ( + ), + (TEXTNS,u'note-continuation-notice-backward') : ( + ), + (TEXTNS,u'note-continuation-notice-forward') : ( + ), + (TEXTNS,u'note-ref') : ( + ), + (TEXTNS,u'notes-configuration') : ( + (TEXTNS,u'note-continuation-notice-backward'), + (TEXTNS,u'note-continuation-notice-forward'), + ), + (TEXTNS,u'number') : ( + ), + (TEXTNS,u'numbered-paragraph') : ( + (TEXTNS,u'h'), + (TEXTNS,u'number'), + (TEXTNS,u'p'), + ), + (TEXTNS,u'object-count') : ( + ), + (TEXTNS,u'object-index') : ( + (TEXTNS,u'index-body'), + (TEXTNS,u'object-index-source'), + ), + (TEXTNS,u'object-index-entry-template') : ( + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'object-index-source') : ( + (TEXTNS,u'index-title-template'), + (TEXTNS,u'object-index-entry-template'), + ), + (TEXTNS,u'outline-level-style') : ( + (STYLENS,u'list-level-properties'), + (STYLENS,u'text-properties'), + ), + (TEXTNS,u'outline-style') : ( + (TEXTNS,u'outline-level-style'), + ), +# allowed_children + (TEXTNS,u'p') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'print-time'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), + ), + (TEXTNS,u'page') : ( + ), + (TEXTNS,u'page-count') : ( + ), + (TEXTNS,u'page-continuation') : ( + ), + (TEXTNS,u'page-number') : ( + ), + (TEXTNS,u'page-sequence') : ( + (TEXTNS,u'page'), + ), + (TEXTNS,u'page-variable-get') : ( + ), + (TEXTNS,u'page-variable-set') : ( + ), + (TEXTNS,u'paragraph-count') : ( + ), + (TEXTNS,u'placeholder') : ( + ), + (TEXTNS,u'print-date') : ( + ), + (TEXTNS,u'print-time') : ( + ), + (TEXTNS,u'printed-by') : ( + ), + (TEXTNS,u'reference-mark') : ( + ), + (TEXTNS,u'reference-mark-end') : ( + ), +# allowed_children + (TEXTNS,u'reference-mark-start') : ( + ), + (TEXTNS,u'reference-ref') : ( + ), + (TEXTNS,u'ruby') : ( + (TEXTNS,u'ruby-base'), + (TEXTNS,u'ruby-text'), + ), + (TEXTNS,u'ruby-base') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'page-count'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'word-count'), + (TEXTNS,u'character-count'), + (TEXTNS,u'table-count'), + (TEXTNS,u'image-count'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'print-time'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + ), +# allowed_children + (TEXTNS,u'ruby-text') : ( + ), + (TEXTNS,u's') : ( + ), + (TEXTNS,u'script') : ( + ), + (TEXTNS,u'section') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'dde-source'), + (TABLENS,u'table'), + (TEXTNS,u'alphabetical-index'), + (TEXTNS,u'bibliography'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'h'), + (TEXTNS,u'illustration-index'), + (TEXTNS,u'list'), + (TEXTNS,u'numbered-paragraph'), + (TEXTNS,u'object-index'), + (TEXTNS,u'p'), + (TEXTNS,u'section'), + (TEXTNS,u'section-source'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'table-index'), + (TEXTNS,u'table-of-content'), + (TEXTNS,u'user-index'), + ), + (TEXTNS,u'section-source') : ( + ), + (TEXTNS,u'sender-city') : ( + ), + (TEXTNS,u'sender-company') : ( + ), + (TEXTNS,u'sender-country') : ( + ), +# allowed_children + (TEXTNS,u'sender-email') : ( + ), + (TEXTNS,u'sender-fax') : ( + ), + (TEXTNS,u'sender-firstname') : ( + ), + (TEXTNS,u'sender-initials') : ( + ), + (TEXTNS,u'sender-lastname') : ( + ), + (TEXTNS,u'sender-phone-private') : ( + ), + (TEXTNS,u'sender-phone-work') : ( + ), + (TEXTNS,u'sender-position') : ( + ), + (TEXTNS,u'sender-postal-code') : ( + ), + (TEXTNS,u'sender-state-or-province') : ( + ), + (TEXTNS,u'sender-street') : ( + ), + (TEXTNS,u'sender-title') : ( + ), + (TEXTNS,u'sequence') : ( + ), + (TEXTNS,u'sequence-decl') : ( + ), + (TEXTNS,u'sequence-decls') : ( + (TEXTNS,u'sequence-decl'), + ), + (TEXTNS,u'sequence-ref') : ( + ), + (TEXTNS,u'sheet-name') : ( + ), + (TEXTNS,u'soft-page-break') : ( + ), + (TEXTNS,u'sort-key') : ( + ), +# allowed_children + (TEXTNS,u'span') : ( + (DR3DNS,u'scene'), + (DRAWNS,u'a'), + (DRAWNS,u'caption'), + (DRAWNS,u'circle'), + (DRAWNS,u'connector'), + (DRAWNS,u'control'), + (DRAWNS,u'custom-shape'), + (DRAWNS,u'ellipse'), + (DRAWNS,u'frame'), + (DRAWNS,u'g'), + (DRAWNS,u'line'), + (DRAWNS,u'measure'), + (DRAWNS,u'page-thumbnail'), + (DRAWNS,u'path'), + (DRAWNS,u'polygon'), + (DRAWNS,u'polyline'), + (DRAWNS,u'rect'), + (DRAWNS,u'regular-polygon'), + (OFFICENS,u'annotation'), + (PRESENTATIONNS,u'date-time'), + (PRESENTATIONNS,u'footer'), + (PRESENTATIONNS,u'header'), + (TEXTNS,u'a'), + (TEXTNS,u'alphabetical-index-mark'), + (TEXTNS,u'alphabetical-index-mark-end'), + (TEXTNS,u'alphabetical-index-mark-start'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark'), + (TEXTNS,u'bookmark-end'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'bookmark-start'), + (TEXTNS,u'change'), + (TEXTNS,u'change-end'), + (TEXTNS,u'change-start'), + (TEXTNS,u'chapter'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-next'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'database-row-select'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'line-break'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'page-count'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'word-count'), + (TEXTNS,u'character-count'), + (TEXTNS,u'table-count'), + (TEXTNS,u'image-count'), + (TEXTNS,u'object-count'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'print-time'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'reference-mark'), + (TEXTNS,u'reference-mark-end'), + (TEXTNS,u'reference-mark-start'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby'), + (TEXTNS,u's'), + (TEXTNS,u'script'), + (TEXTNS,u'sender-city'), + (TEXTNS,u'sender-company'), + (TEXTNS,u'sender-country'), + (TEXTNS,u'sender-email'), + (TEXTNS,u'sender-fax'), + (TEXTNS,u'sender-firstname'), + (TEXTNS,u'sender-initials'), + (TEXTNS,u'sender-lastname'), + (TEXTNS,u'sender-phone-private'), + (TEXTNS,u'sender-phone-work'), + (TEXTNS,u'sender-position'), + (TEXTNS,u'sender-postal-code'), + (TEXTNS,u'sender-state-or-province'), + (TEXTNS,u'sender-street'), + (TEXTNS,u'sender-title'), + (TEXTNS,u'sequence'), + (TEXTNS,u'sequence-ref'), + (TEXTNS,u'sheet-name'), + (TEXTNS,u'soft-page-break'), + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'tab'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'toc-mark'), + (TEXTNS,u'toc-mark-end'), + (TEXTNS,u'toc-mark-start'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'user-index-mark'), + (TEXTNS,u'user-index-mark-end'), + (TEXTNS,u'user-index-mark-start'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + ), +# allowed_children + (TEXTNS,u'subject') : ( + ), + (TEXTNS,u'tab') : ( + ), + (TEXTNS,u'table-count') : ( + ), + (TEXTNS,u'table-formula') : ( + ), + (TEXTNS,u'table-index') : ( + (TEXTNS,u'index-body'), + (TEXTNS,u'table-index-source'), + ), + (TEXTNS,u'table-index-entry-template') : ( + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'table-index-source') : ( + (TEXTNS,u'index-title-template'), + (TEXTNS,u'table-index-entry-template'), + ), + (TEXTNS,u'table-of-content') : ( + (TEXTNS,u'index-body'), + (TEXTNS,u'table-of-content-source'), + ), + (TEXTNS,u'table-of-content-entry-template') : ( + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-link-end'), + (TEXTNS,u'index-entry-link-start'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), + (TEXTNS,u'table-of-content-source') : ( + (TEXTNS,u'index-source-styles'), + (TEXTNS,u'index-title-template'), + (TEXTNS,u'table-of-content-entry-template'), + ), + (TEXTNS,u'template-name') : ( + ), + (TEXTNS,u'text-input') : ( + ), + (TEXTNS,u'time') : ( + ), + (TEXTNS,u'title') : ( + ), + (TEXTNS,u'toc-mark') : ( + ), + (TEXTNS,u'toc-mark-end') : ( + ), + (TEXTNS,u'toc-mark-start') : ( + ), +# allowed_children + (TEXTNS,u'tracked-changes') : ( + (TEXTNS,u'changed-region'), + ), + (TEXTNS,u'user-defined') : ( + ), + (TEXTNS,u'user-field-decl') : ( + ), + (TEXTNS,u'user-field-decls') : ( + (TEXTNS,u'user-field-decl'), + ), + (TEXTNS,u'user-field-get') : ( + ), + (TEXTNS,u'user-field-input') : ( + ), + (TEXTNS,u'user-index') : ( + (TEXTNS,u'index-body'), + (TEXTNS,u'user-index-source'), + ), + (TEXTNS,u'user-index-entry-template') : ( + (TEXTNS,u'index-entry-chapter'), + (TEXTNS,u'index-entry-page-number'), + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-entry-tab-stop'), + (TEXTNS,u'index-entry-text'), + ), +# allowed_children + (TEXTNS,u'user-index-mark') : ( + ), + (TEXTNS,u'user-index-mark-end') : ( + ), + (TEXTNS,u'user-index-mark-start') : ( + ), + (TEXTNS,u'user-index-source') : ( + (TEXTNS,u'index-source-styles'), + (TEXTNS,u'index-title-template'), + (TEXTNS,u'user-index-entry-template'), + ), + (TEXTNS,u'variable-decl') : ( + ), + (TEXTNS,u'variable-decls') : ( + (TEXTNS,u'variable-decl'), + ), + (TEXTNS,u'variable-get') : ( + ), + (TEXTNS,u'variable-input') : ( + ), + (TEXTNS,u'variable-set') : ( + ), + (TEXTNS,u'word-count') : ( + ), +} + +# +# List of elements that allows text nodes +# +allows_text = ( + (CONFIGNS,u'config-item'), + (DCNS,u'creator'), + (DCNS,u'date'), + (DCNS,u'description'), + (DCNS,u'language'), + (DCNS,u'subject'), + (DCNS,u'title'), +# Completes Dublin Core start +# (DCNS,'contributor'), +# (DCNS,'coverage'), +# (DCNS,'format'), +# (DCNS,'identifier'), +# (DCNS,'publisher'), +# (DCNS,'relation'), +# (DCNS,'rights'), +# (DCNS,'source'), +# (DCNS,'type'), +# Completes Dublin Core end + (FORMNS,u'item'), + (FORMNS,u'option'), + (MATHNS,u'math'), + (METANS,u'creation-date'), + (METANS,u'date-string'), + (METANS,u'editing-cycles'), + (METANS,u'editing-duration'), +# allows_text + (METANS,u'generator'), + (METANS,u'initial-creator'), + (METANS,u'keyword'), + (METANS,u'print-date'), + (METANS,u'printed-by'), + (METANS,u'user-defined'), + (NUMBERNS,u'currency-symbol'), + (NUMBERNS,u'embedded-text'), + (NUMBERNS,u'text'), + (OFFICENS,u'binary-data'), + (OFFICENS,u'script'), + (PRESENTATIONNS,u'date-time-decl'), + (PRESENTATIONNS,u'footer-decl'), + (PRESENTATIONNS,u'header-decl'), + (SVGNS,u'desc'), + (SVGNS,u'title'), + (TEXTNS,u'a'), + (TEXTNS,u'author-initials'), + (TEXTNS,u'author-name'), + (TEXTNS,u'bibliography-mark'), + (TEXTNS,u'bookmark-ref'), + (TEXTNS,u'chapter'), + (TEXTNS,u'character-count'), + (TEXTNS,u'conditional-text'), + (TEXTNS,u'creation-date'), + (TEXTNS,u'creation-time'), + (TEXTNS,u'creator'), + (TEXTNS,u'database-display'), + (TEXTNS,u'database-name'), + (TEXTNS,u'database-row-number'), + (TEXTNS,u'date'), + (TEXTNS,u'dde-connection'), + (TEXTNS,u'description'), + (TEXTNS,u'editing-cycles'), + (TEXTNS,u'editing-duration'), + (TEXTNS,u'execute-macro'), + (TEXTNS,u'expression'), + (TEXTNS,u'file-name'), + (TEXTNS,u'h'), + (TEXTNS,u'hidden-paragraph'), + (TEXTNS,u'hidden-text'), + (TEXTNS,u'image-count'), +# allowed_children + (TEXTNS,u'index-entry-span'), + (TEXTNS,u'index-title-template'), + (TEXTNS,u'initial-creator'), + (TEXTNS,u'keywords'), + (TEXTNS,u'linenumbering-separator'), + (TEXTNS,u'measure'), + (TEXTNS,u'modification-date'), + (TEXTNS,u'modification-time'), + (TEXTNS,u'note-citation'), + (TEXTNS,u'note-continuation-notice-backward'), + (TEXTNS,u'note-continuation-notice-forward'), + (TEXTNS,u'note-ref'), + (TEXTNS,u'number'), + (TEXTNS,u'object-count'), + (TEXTNS,u'p'), + (TEXTNS,u'page-continuation'), + (TEXTNS,u'page-count'), + (TEXTNS,u'page-number'), + (TEXTNS,u'page-variable-get'), + (TEXTNS,u'page-variable-set'), + (TEXTNS,u'paragraph-count'), + (TEXTNS,u'placeholder'), + (TEXTNS,u'print-date'), + (TEXTNS,u'print-time'), + (TEXTNS,u'printed-by'), + (TEXTNS,u'reference-ref'), + (TEXTNS,u'ruby-base'), + (TEXTNS,u'ruby-text'), + (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'), +# allowed_children + (TEXTNS,u'span'), + (TEXTNS,u'subject'), + (TEXTNS,u'table-count'), + (TEXTNS,u'table-formula'), + (TEXTNS,u'template-name'), + (TEXTNS,u'text-input'), + (TEXTNS,u'time'), + (TEXTNS,u'title'), + (TEXTNS,u'user-defined'), + (TEXTNS,u'user-field-get'), + (TEXTNS,u'user-field-input'), + (TEXTNS,u'variable-get'), + (TEXTNS,u'variable-input'), + (TEXTNS,u'variable-set'), + (TEXTNS,u'word-count'), +) + +# Only the elements with at least one required attribute is listed + +required_attributes = { + (ANIMNS,u'animate'): ( + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'animateColor'): ( + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'animateMotion'): ( + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'animateTransform'): ( + (SVGNS,u'type'), + (SMILNS,u'attributeName'), + ), + (ANIMNS,u'command'): ( + (ANIMNS,u'command'), + ), + (ANIMNS,u'param'): ( + (ANIMNS,u'name'), + (ANIMNS,u'value'), + ), + (ANIMNS,u'set'): ( + (SMILNS,u'attributeName'), + ), +# required_attributes + (ANIMNS,u'transitionFilter'): ( + (SMILNS,u'type'), + ), + (CHARTNS,u'axis'): ( + (CHARTNS,u'dimension'), + ), + (CHARTNS,u'chart'): ( + (CHARTNS,u'class'), + ), + (CHARTNS,u'symbol-image'): ( + (XLINKNS,u'href'), + ), + (CONFIGNS,u'config-item'): ( + (CONFIGNS,u'type'), + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-indexed'): ( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-named'): ( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-set'): ( + (CONFIGNS,u'name'), + ), +# required_attributes + (NUMBERNS,u'boolean-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'currency-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'date-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'embedded-text'): ( + (NUMBERNS,u'position'), + ), + (NUMBERNS,u'number-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'percentage-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'text-style'): ( + (STYLENS,u'name'), + ), + (NUMBERNS,u'time-style'): ( + (STYLENS,u'name'), + ), + (DR3DNS,u'extrude'): ( + (SVGNS,u'd'), + (SVGNS,u'viewBox'), + ), + (DR3DNS,u'light'): ( + (DR3DNS,u'direction'), + ), + (DR3DNS,u'rotate'): ( + (SVGNS,u'viewBox'), + (SVGNS,u'd'), + ), +# required_attributes + (DRAWNS,u'a'): ( + (XLINKNS,u'href'), + ), + (DRAWNS,u'area-circle'): ( + (SVGNS,u'cy'), + (SVGNS,u'cx'), + (SVGNS,u'r'), + ), + (DRAWNS,u'area-polygon'): ( + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'points'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'area-rectangle'): ( + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'height'), + (SVGNS,u'width'), + ), + (DRAWNS,u'contour-path'): ( + (DRAWNS,u'recreate-on-edit'), + (SVGNS,u'viewBox'), + (SVGNS,u'd'), + ), + (DRAWNS,u'contour-polygon'): ( + (DRAWNS,u'points'), + (DRAWNS,u'recreate-on-edit'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'control'): ( + (DRAWNS,u'control'), + ), + (DRAWNS,u'fill-image'): ( + (XLINKNS,u'href'), + (DRAWNS,u'name'), + ), + (DRAWNS,u'floating-frame'): ( + (XLINKNS,u'href'), + ), + (DRAWNS,u'glue-point'): ( + (SVGNS,u'y'), + (SVGNS,u'x'), + (DRAWNS,u'id'), + (DRAWNS,u'escape-direction'), + ), +# required_attributes + (DRAWNS,u'gradient'): ( + (DRAWNS,u'style'), + ), + (DRAWNS,u'handle'): ( + (DRAWNS,u'handle-position'), + ), + (DRAWNS,u'hatch'): ( + (DRAWNS,u'style'), + (DRAWNS,u'name'), + ), + (DRAWNS,u'layer'): ( + (DRAWNS,u'name'), + ), + (DRAWNS,u'line'): ( + (SVGNS,u'y1'), + (SVGNS,u'x2'), + (SVGNS,u'x1'), + (SVGNS,u'y2'), + ), + (DRAWNS,u'marker'): ( + (SVGNS,u'd'), + (DRAWNS,u'name'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'measure'): ( + (SVGNS,u'y1'), + (SVGNS,u'x2'), + (SVGNS,u'x1'), + (SVGNS,u'y2'), + ), + (DRAWNS,u'opacity'): ( + (DRAWNS,u'style'), + ), + (DRAWNS,u'page'): ( + (DRAWNS,u'master-page-name'), + ), + (DRAWNS,u'path'): ( + (SVGNS,u'd'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'plugin'): ( + (XLINKNS,u'href'), + ), + (DRAWNS,u'polygon'): ( + (DRAWNS,u'points'), + (SVGNS,u'viewBox'), + ), +# required_attributes + (DRAWNS,u'polyline'): ( + (DRAWNS,u'points'), + (SVGNS,u'viewBox'), + ), + (DRAWNS,u'regular-polygon'): ( + (DRAWNS,u'corners'), + ), + (DRAWNS,u'stroke-dash'): ( + (DRAWNS,u'name'), + ), + (FORMNS,u'button'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'checkbox'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'combobox'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'connection-resource'): ( + (XLINKNS,u'href'), + ), + (FORMNS,u'date'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'file'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'fixed-text'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'formatted-text'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'frame'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'generic-control'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'grid'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'hidden'): ( + (FORMNS,u'id'), + ), +# required_attributes + (FORMNS,u'image'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'image-frame'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'list-property'): ( + (FORMNS,u'property-name'), + ), + (FORMNS,u'list-value'): ( + (OFFICENS,u'string-value'), + ), + (FORMNS,u'listbox'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'number'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'password'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'property'): ( + (FORMNS,u'property-name'), + ), + (FORMNS,u'radio'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'text'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'textarea'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'time'): ( + (FORMNS,u'id'), + ), + (FORMNS,u'value-range'): ( + (FORMNS,u'id'), + ), + (MANIFESTNS,u'algorithm') : ( + (MANIFESTNS,u'algorithm-name'), + (MANIFESTNS,u'initialisation-vector'), + ), + (MANIFESTNS,u'encryption-data') : ( + (MANIFESTNS,u'checksum-type'), + (MANIFESTNS,u'checksum'), + ), + (MANIFESTNS,u'file-entry') : ( + (MANIFESTNS,u'full-path'), + (MANIFESTNS,u'media-type'), + ), + (MANIFESTNS,u'key-derivation') : ( + (MANIFESTNS,u'key-derivation-name'), + (MANIFESTNS,u'salt'), + (MANIFESTNS,u'iteration-count'), + ), +# required_attributes + (METANS,u'template'): ( + (XLINKNS,u'href'), + ), + (METANS,u'user-defined'): ( + (METANS,u'name'), + ), + (OFFICENS,u'dde-source'): ( + (OFFICENS,u'dde-topic'), + (OFFICENS,u'dde-application'), + (OFFICENS,u'dde-item'), + ), + (OFFICENS,u'document'): ( + (OFFICENS,u'mimetype'), + ), + (OFFICENS,u'script'): ( + (SCRIPTNS,u'language'), + ), + (PRESENTATIONNS,u'date-time-decl'): ( + (PRESENTATIONNS,u'source'), + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'dim'): ( + (DRAWNS,u'color'), + (DRAWNS,u'shape-id'), + ), +# required_attributes + (PRESENTATIONNS,u'event-listener'): ( + (PRESENTATIONNS,u'action'), + (SCRIPTNS,u'event-name'), + ), + (PRESENTATIONNS,u'footer-decl'): ( + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'header-decl'): ( + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'hide-shape'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'hide-text'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'placeholder'): ( + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'height'), + (PRESENTATIONNS,u'object'), + (SVGNS,u'width'), + ), + (PRESENTATIONNS,u'play'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'show'): ( + (PRESENTATIONNS,u'name'), + (PRESENTATIONNS,u'pages'), + ), + (PRESENTATIONNS,u'show-shape'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'show-text'): ( + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'sound'): ( + (XLINKNS,u'href'), + ), + (SCRIPTNS,u'event-listener'): ( + (SCRIPTNS,u'language'), + (SCRIPTNS,u'event-name'), + ), + (STYLENS,u'column'): ( + (STYLENS,u'rel-width'), + ), +# required_attributes + (STYLENS,u'column-sep'): ( + (STYLENS,u'width'), + ), + (STYLENS,u'columns'): ( + (FONS,u'column-count'), + ), + (STYLENS,u'font-face'): ( + (STYLENS,u'name'), + ), + (STYLENS,u'handout-master'): ( + (STYLENS,u'page-layout-name'), + ), + (STYLENS,u'map'): ( + (STYLENS,u'apply-style-name'), + (STYLENS,u'condition'), + ), + (STYLENS,u'master-page'): ( + (STYLENS,u'page-layout-name'), + (STYLENS,u'name'), + ), + (STYLENS,u'page-layout'): ( + (STYLENS,u'name'), + ), + (STYLENS,u'presentation-page-layout'): ( + (STYLENS,u'name'), + ), + (STYLENS,u'style'): ( + (STYLENS,u'name'), + ), + (STYLENS,u'tab-stop'): ( + (STYLENS,u'position'), + ), + (SVGNS,u'definition-src'): ( + (XLINKNS,u'href'), + ), + (SVGNS,u'font-face-uri'): ( + (XLINKNS,u'href'), + ), + (SVGNS,u'linearGradient'): ( + (DRAWNS,u'name'), + ), + (SVGNS,u'radialGradient'): ( + (DRAWNS,u'name'), + ), + (SVGNS,u'stop'): ( + (SVGNS,u'offset'), + ), +# required_attributes + (TABLENS,u'body'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'cell-address'): ( + (TABLENS,u'column'), + (TABLENS,u'table'), + (TABLENS,u'row'), + ), + (TABLENS,u'cell-content-change'): ( + (TABLENS,u'id'), + ), + (TABLENS,u'cell-range-source'): ( + (TABLENS,u'last-row-spanned'), + (TABLENS,u'last-column-spanned'), + (XLINKNS,u'href'), + (TABLENS,u'name'), + ), + (TABLENS,u'consolidation'): ( + (TABLENS,u'function'), + (TABLENS,u'source-cell-range-addresses'), + (TABLENS,u'target-cell-address'), + ), + (TABLENS,u'content-validation'): ( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-display-info'): ( + (TABLENS,u'member-count'), + (TABLENS,u'data-field'), + (TABLENS,u'enabled'), + (TABLENS,u'display-member-mode'), + ), +# required_attributes + (TABLENS,u'data-pilot-field'): ( + (TABLENS,u'source-field-name'), + ), + (TABLENS,u'data-pilot-field-reference'): ( + (TABLENS,u'field-name'), + (TABLENS,u'type'), + ), + (TABLENS,u'data-pilot-group'): ( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-group-member'): ( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-groups'): ( + (TABLENS,u'source-field-name'), + (TABLENS,u'step'), + (TABLENS,u'grouped-by'), + ), + (TABLENS,u'data-pilot-layout-info'): ( + (TABLENS,u'add-empty-lines'), + (TABLENS,u'layout-mode'), + ), + (TABLENS,u'data-pilot-member'): ( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-sort-info'): ( + (TABLENS,u'order'), + ), + (TABLENS,u'data-pilot-subtotal'): ( + (TABLENS,u'function'), + ), + (TABLENS,u'data-pilot-table'): ( + (TABLENS,u'target-range-address'), + (TABLENS,u'name'), + ), + (TABLENS,u'database-range'): ( + (TABLENS,u'target-range-address'), + ), +# required_attributes + (TABLENS,u'database-source-query'): ( + (TABLENS,u'query-name'), + (TABLENS,u'database-name'), + ), + (TABLENS,u'database-source-sql'): ( + (TABLENS,u'database-name'), + (TABLENS,u'sql-statement'), + ), + (TABLENS,u'database-source-table'): ( + (TABLENS,u'database-table-name'), + (TABLENS,u'database-name'), + ), + (TABLENS,u'deletion'): ( + (TABLENS,u'position'), + (TABLENS,u'type'), + (TABLENS,u'id'), + ), + (TABLENS,u'dependency'): ( + (TABLENS,u'id'), + ), + (TABLENS,u'even-columns'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'even-rows'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'filter-condition'): ( + (TABLENS,u'operator'), + (TABLENS,u'field-number'), + (TABLENS,u'value'), + ), + (TABLENS,u'first-column'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'first-row'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'insertion'): ( + (TABLENS,u'position'), + (TABLENS,u'type'), + (TABLENS,u'id'), + ), + (TABLENS,u'insertion-cut-off'): ( + (TABLENS,u'position'), + (TABLENS,u'id'), + ), +# required_attributes + (TABLENS,u'label-range'): ( + (TABLENS,u'label-cell-range-address'), + (TABLENS,u'data-cell-range-address'), + (TABLENS,u'orientation'), + ), + (TABLENS,u'last-column'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'last-row'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'movement'): ( + (TABLENS,u'id'), + ), + (TABLENS,u'named-expression'): ( + (TABLENS,u'expression'), + (TABLENS,u'name'), + ), + (TABLENS,u'named-range'): ( + (TABLENS,u'name'), + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'odd-columns'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'odd-rows'): ( + (TEXTNS,u'style-name'), + ), + (TABLENS,u'operation'): ( + (TABLENS,u'index'), + (TABLENS,u'name'), + ), +# required_attributes + (TABLENS,u'scenario'): ( + (TABLENS,u'is-active'), + (TABLENS,u'scenario-ranges'), + ), + (TABLENS,u'sort-by'): ( + (TABLENS,u'field-number'), + ), + (TABLENS,u'source-cell-range'): ( + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'source-service'): ( + (TABLENS,u'source-name'), + (TABLENS,u'object-name'), + (TABLENS,u'name'), + ), + (TABLENS,u'subtotal-field'): ( + (TABLENS,u'function'), + (TABLENS,u'field-number'), + ), + (TABLENS,u'subtotal-rule'): ( + (TABLENS,u'group-by-field-number'), + ), + (TABLENS,u'table-source'): ( + (XLINKNS,u'href'), + ), + (TABLENS,u'table-template'): ( + (TEXTNS,u'last-row-end-column'), + (TEXTNS,u'first-row-end-column'), + (TEXTNS,u'name'), + (TEXTNS,u'last-row-start-column'), + (TEXTNS,u'first-row-start-column'), + ), + (TEXTNS,u'a'): ( + (XLINKNS,u'href'), + ), +# required_attributes + (TEXTNS,u'alphabetical-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'alphabetical-index-auto-mark-file'): ( + (XLINKNS,u'href'), + ), + (TEXTNS,u'alphabetical-index-entry-template'): ( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'alphabetical-index-mark'): ( + (TEXTNS,u'string-value'), + ), + (TEXTNS,u'alphabetical-index-mark-end'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'alphabetical-index-mark-start'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'bibliography'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'bibliography-entry-template'): ( + (TEXTNS,u'style-name'), + (TEXTNS,u'bibliography-type'), + ), + (TEXTNS,u'bibliography-mark'): ( + (TEXTNS,u'bibliography-type'), + ), + (TEXTNS,u'bookmark'): ( + (TEXTNS,u'name'), + ), +# required_attributes + (TEXTNS,u'bookmark-end'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'bookmark-start'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'change'): ( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'change-end'): ( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'change-start'): ( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'changed-region'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'chapter'): ( + (TEXTNS,u'display'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'conditional-text'): ( + (TEXTNS,u'string-value-if-true'), + (TEXTNS,u'string-value-if-false'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'database-display'): ( + (TEXTNS,u'column-name'), + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'database-name'): ( + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'database-next'): ( + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'database-row-number'): ( + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'database-row-select'): ( + (TEXTNS,u'table-name'), + ), + (TEXTNS,u'dde-connection'): ( + (TEXTNS,u'connection-name'), + ), +# required_attributes + (TEXTNS,u'dde-connection-decl'): ( + (OFFICENS,u'dde-topic'), + (OFFICENS,u'dde-application'), + (OFFICENS,u'name'), + (OFFICENS,u'dde-item'), + ), + (TEXTNS,u'h'): ( + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'hidden-paragraph'): ( + (TEXTNS,u'condition'), + ), + (TEXTNS,u'hidden-text'): ( + (TEXTNS,u'string-value'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'illustration-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'illustration-index-entry-template'): ( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-bibliography'): ( + (TEXTNS,u'bibliography-data-field'), + ), + (TEXTNS,u'index-source-style'): ( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-source-styles'): ( + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'index-title'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'list-level-style-bullet'): ( + (TEXTNS,u'bullet-char'), + (TEXTNS,u'level'), + ), + (TEXTNS,u'list-level-style-image'): ( + (TEXTNS,u'level'), + ), + (TEXTNS,u'list-level-style-number'): ( + (TEXTNS,u'level'), + ), + (TEXTNS,u'list-style'): ( + (STYLENS,u'name'), + ), +# required_attributes + (TEXTNS,u'measure'): ( + (TEXTNS,u'kind'), + ), + (TEXTNS,u'note'): ( + (TEXTNS,u'note-class'), + ), + (TEXTNS,u'note-ref'): ( + (TEXTNS,u'note-class'), + ), + (TEXTNS,u'notes-configuration'): ( + (TEXTNS,u'note-class'), + ), + (TEXTNS,u'object-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'object-index-entry-template'): ( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'outline-level-style'): ( + (TEXTNS,u'level'), + ), + (TEXTNS,u'page'): ( + (TEXTNS,u'master-page-name'), + ), + (TEXTNS,u'page-continuation'): ( + (TEXTNS,u'select-page'), + ), + (TEXTNS,u'placeholder'): ( + (TEXTNS,u'placeholder-type'), + ), + (TEXTNS,u'reference-mark'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'reference-mark-end'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'reference-mark-start'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'section'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'sequence'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'sequence-decl'): ( + (TEXTNS,u'display-outline-level'), + (TEXTNS,u'name'), + ), +# required_attributes + (TEXTNS,u'sort-key'): ( + (TEXTNS,u'key'), + ), + (TEXTNS,u'table-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'table-index-entry-template'): ( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'table-of-content'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'table-of-content-entry-template'): ( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'toc-mark'): ( + (TEXTNS,u'string-value'), + ), + (TEXTNS,u'toc-mark-end'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'toc-mark-start'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'user-defined'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-field-decl'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-field-get'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-field-input'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-index'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'user-index-entry-template'): ( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), +# required_attributes + (TEXTNS,u'user-index-mark'): ( + (TEXTNS,u'index-name'), + (TEXTNS,u'string-value'), + ), + (TEXTNS,u'user-index-mark-end'): ( + (TEXTNS,u'id'), + ), + (TEXTNS,u'user-index-mark-start'): ( + (TEXTNS,u'index-name'), + (TEXTNS,u'id'), + ), + (TEXTNS,u'user-index-source'): ( + (TEXTNS,u'index-name'), + ), + (TEXTNS,u'variable-decl'): ( + (TEXTNS,u'name'), + (OFFICENS,u'value-type'), + ), + (TEXTNS,u'variable-get'): ( + (TEXTNS,u'name'), + ), + (TEXTNS,u'variable-input'): ( + (TEXTNS,u'name'), + (OFFICENS,u'value-type'), + ), + (TEXTNS,u'variable-set'): ( + (TEXTNS,u'name'), + ), +} + +# Empty list means the element has no allowed attributes +# None means anything goes + +allowed_attributes = { + (DCNS,u'creator'):( + ), + (DCNS,u'date'):( + ), + (DCNS,u'description'):( + ), + (DCNS,u'language'):( + ), + (DCNS,u'subject'):( + ), + (DCNS,u'title'):( + ), +# Completes Dublin Core start +# (DCNS,'contributor') : ( +# ), +# (DCNS,'coverage') : ( +# ), +# (DCNS,'format') : ( +# ), +# (DCNS,'identifier') : ( +# ), +# (DCNS,'publisher') : ( +# ), +# (DCNS,'relation') : ( +# ), +# (DCNS,'rights') : ( +# ), +# (DCNS,'source') : ( +# ), +# (DCNS,'type') : ( +# ), +# Completes Dublin Core end + (MATHNS,u'math'): None, + (XFORMSNS,u'model'): None, +# allowed_attributes + (ANIMNS,u'animate'):( + (ANIMNS,u'formula'), + (ANIMNS,u'sub-item'), + (SMILNS,u'accelerate'), + (SMILNS,u'accumulate'), + (SMILNS,u'additive'), + (SMILNS,u'attributeName'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'by'), + (SMILNS,u'calcMode'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'from'), + (SMILNS,u'keySplines'), + (SMILNS,u'keyTimes'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'targetElement'), + (SMILNS,u'to'), + (SMILNS,u'values'), + ), +# allowed_attributes + (ANIMNS,u'animateColor'):( + (ANIMNS,u'color-interpolation'), + (ANIMNS,u'color-interpolation-direction'), + (ANIMNS,u'formula'), + (ANIMNS,u'sub-item'), + (SMILNS,u'accelerate'), + (SMILNS,u'accumulate'), + (SMILNS,u'additive'), + (SMILNS,u'attributeName'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'by'), + (SMILNS,u'calcMode'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'from'), + (SMILNS,u'keySplines'), + (SMILNS,u'keyTimes'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'targetElement'), + (SMILNS,u'to'), + (SMILNS,u'values'), + ), +# allowed_attributes + (ANIMNS,u'animateMotion'):( + (ANIMNS,u'formula'), + (ANIMNS,u'sub-item'), + (SMILNS,u'accelerate'), + (SMILNS,u'accumulate'), + (SMILNS,u'additive'), + (SMILNS,u'attributeName'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'by'), + (SMILNS,u'calcMode'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'from'), + (SMILNS,u'keySplines'), + (SMILNS,u'keyTimes'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'targetElement'), + (SMILNS,u'to'), + (SMILNS,u'values'), + (SVGNS,u'origin'), + (SVGNS,u'path'), + ), +# allowed_attributes + (ANIMNS,u'animateTransform'):( + (ANIMNS,u'formula'), + (ANIMNS,u'sub-item'), + (SMILNS,u'accelerate'), + (SMILNS,u'accumulate'), + (SMILNS,u'additive'), + (SMILNS,u'attributeName'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'by'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'from'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'targetElement'), + (SMILNS,u'to'), + (SMILNS,u'values'), + (SVGNS,u'type'), + ), +# allowed_attributes + (ANIMNS,u'audio'):( + (ANIMNS,u'audio-level'), + (ANIMNS,u'id'), + (PRESENTATIONNS,u'group-id'), + (PRESENTATIONNS,u'master-element'), + (PRESENTATIONNS,u'node-type'), + (PRESENTATIONNS,u'preset-class'), + (PRESENTATIONNS,u'preset-id'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'begin'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (XLINKNS,u'href'), + ), + (ANIMNS,u'command'):( + (PRESENTATIONNS,u'node-type'), + (SMILNS,u'begin'), + (SMILNS,u'end'), + (PRESENTATIONNS,u'group-id'), + (PRESENTATIONNS,u'preset-class'), + (PRESENTATIONNS,u'preset-id'), + (ANIMNS,u'sub-item'), + (ANIMNS,u'command'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'targetElement'), + (ANIMNS,u'id'), + (PRESENTATIONNS,u'master-element'), + ), +# allowed_attributes + (ANIMNS,u'iterate'):( + (ANIMNS,u'id'), + (ANIMNS,u'iterate-interval'), + (ANIMNS,u'iterate-type'), + (ANIMNS,u'sub-item'), + (PRESENTATIONNS,u'group-id'), + (PRESENTATIONNS,u'master-element'), + (PRESENTATIONNS,u'node-type'), + (PRESENTATIONNS,u'preset-class'), + (PRESENTATIONNS,u'preset-id'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'accelerate'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'endsync'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'targetElement'), + ), + (ANIMNS,u'par'):( + (PRESENTATIONNS,u'node-type'), + (SMILNS,u'decelerate'), + (SMILNS,u'begin'), + (SMILNS,u'end'), + (PRESENTATIONNS,u'group-id'), + (SMILNS,u'accelerate'), + (SMILNS,u'repeatDur'), + (SMILNS,u'repeatCount'), + (SMILNS,u'autoReverse'), + (PRESENTATIONNS,u'preset-class'), + (SMILNS,u'fillDefault'), + (PRESENTATIONNS,u'preset-id'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'restartDefault'), + (SMILNS,u'endsync'), + (SMILNS,u'dur'), + (SMILNS,u'fill'), + (ANIMNS,u'id'), + (SMILNS,u'restart'), + (PRESENTATIONNS,u'master-element'), + ), +# allowed_attributes + (ANIMNS,u'param'):( + (ANIMNS,u'name'), + (ANIMNS,u'value'), + ), + (ANIMNS,u'seq'):( + (ANIMNS,u'id'), + (PRESENTATIONNS,u'group-id'), + (PRESENTATIONNS,u'master-element'), + (PRESENTATIONNS,u'node-type'), + (PRESENTATIONNS,u'preset-class'), + (PRESENTATIONNS,u'preset-id'), + (PRESENTATIONNS,u'preset-sub-type'), + (SMILNS,u'accelerate'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'endsync'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + ), + (ANIMNS,u'set'):( + (ANIMNS,u'sub-item'), + (SMILNS,u'accelerate'), + (SMILNS,u'accumulate'), + (SMILNS,u'autoReverse'), + (SMILNS,u'additive'), + (SMILNS,u'attributeName'), + (SMILNS,u'begin'), + (SMILNS,u'decelerate'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'targetElement'), + (SMILNS,u'to'), + + ), +# allowed_attributes + (ANIMNS,u'transitionFilter'):( + (ANIMNS,u'formula'), + (ANIMNS,u'sub-item'), + (SMILNS,u'accelerate'), + (SMILNS,u'accumulate'), + (SMILNS,u'additive'), + (SMILNS,u'autoReverse'), + (SMILNS,u'begin'), + (SMILNS,u'by'), + (SMILNS,u'calcMode'), + (SMILNS,u'decelerate'), + (SMILNS,u'direction'), + (SMILNS,u'dur'), + (SMILNS,u'end'), + (SMILNS,u'fadeColor'), + (SMILNS,u'fill'), + (SMILNS,u'fillDefault'), + (SMILNS,u'from'), + (SMILNS,u'mode'), + (SMILNS,u'repeatCount'), + (SMILNS,u'repeatDur'), + (SMILNS,u'restart'), + (SMILNS,u'restartDefault'), + (SMILNS,u'subtype'), + (SMILNS,u'targetElement'), + (SMILNS,u'to'), + (SMILNS,u'type'), + (SMILNS,u'values'), + + ), +# allowed_attributes + (CHARTNS,u'axis'):( + (CHARTNS,u'style-name'), + (CHARTNS,u'dimension'), + (CHARTNS,u'name'), + ), + (CHARTNS,u'categories'):( + (TABLENS,u'cell-range-address'), + ), + (CHARTNS,u'chart'):( + (CHARTNS,u'column-mapping'), + (CHARTNS,u'row-mapping'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (CHARTNS,u'style-name'), + (CHARTNS,u'class'), + ), + (CHARTNS,u'data-point'):( + (CHARTNS,u'repeated'), + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'domain'):( + (TABLENS,u'cell-range-address'), + ), + (CHARTNS,u'error-indicator'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'floor'):( + (SVGNS,u'width'), + (CHARTNS,u'style-name'), + ), +# allowed_attributes + (CHARTNS,u'footer'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'cell-range'), + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'grid'):( + (CHARTNS,u'style-name'), + (CHARTNS,u'class'), + ), + (CHARTNS,u'legend'):( + (CHARTNS,u'legend-align'), + (STYLENS,u'legend-expansion-aspect-ratio'), + (STYLENS,u'legend-expansion'), + (CHARTNS,u'legend-position'), + (CHARTNS,u'style-name'), + (SVGNS,u'y'), + (SVGNS,u'x'), + ), + (CHARTNS,u'mean-value'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'plot-area'):( + (DR3DNS,u'ambient-color'), + (DR3DNS,u'distance'), + (DR3DNS,u'vrp'), + (DR3DNS,u'focal-length'), + (CHARTNS,u'data-source-has-labels'), + (DR3DNS,u'lighting-mode'), + (DR3DNS,u'shade-mode'), + (DR3DNS,u'transform'), + (DR3DNS,u'shadow-slant'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (CHARTNS,u'style-name'), + (DR3DNS,u'vup'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (DR3DNS,u'vpn'), + (TABLENS,u'cell-range-address'), + (DR3DNS,u'projection'), + ), + (CHARTNS,u'regression-curve'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'series'):( + (CHARTNS,u'style-name'), + (CHARTNS,u'attached-axis'), + (CHARTNS,u'values-cell-range-address'), + (CHARTNS,u'label-cell-address'), + (CHARTNS,u'class'), + ), + (CHARTNS,u'stock-gain-marker'):( + (CHARTNS,u'style-name'), + ), +# allowed_attributes + (CHARTNS,u'stock-loss-marker'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'stock-range-line'):( + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'subtitle'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'cell-range'), + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'symbol-image'):( + (XLINKNS,u'href'), + ), + (CHARTNS,u'title'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'cell-range'), + (CHARTNS,u'style-name'), + ), + (CHARTNS,u'wall'):( + (SVGNS,u'width'), + (CHARTNS,u'style-name'), + ), + (CONFIGNS,u'config-item'):( + (CONFIGNS,u'type'), + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-entry'):( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-indexed'):( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-map-named'):( + (CONFIGNS,u'name'), + ), + (CONFIGNS,u'config-item-set'):( + (CONFIGNS,u'name'), + ), +# allowed_attributes + (NUMBERNS,u'am-pm'):( + ), + (NUMBERNS,u'boolean'):( + ), + (NUMBERNS,u'boolean-style'):( + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (STYLENS,u'display-name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + ), + (NUMBERNS,u'currency-style'):( + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (STYLENS,u'display-name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + (NUMBERNS,u'automatic-order'), + ), + (NUMBERNS,u'currency-symbol'):( + (NUMBERNS,u'country'), + (NUMBERNS,u'language'), + ), +# allowed_attributes + (NUMBERNS,u'date-style'):( + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (STYLENS,u'display-name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (NUMBERNS,u'format-source'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + (NUMBERNS,u'automatic-order'), + ), + (NUMBERNS,u'day'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'day-of-week'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'embedded-text'):( + (NUMBERNS,u'position'), + ), + (NUMBERNS,u'era'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'fraction'):( + (NUMBERNS,u'grouping'), + (NUMBERNS,u'min-denominator-digits'), + (NUMBERNS,u'min-numerator-digits'), + (NUMBERNS,u'min-integer-digits'), + (NUMBERNS,u'denominator-value'), + ), + (NUMBERNS,u'hours'):( + (NUMBERNS,u'style'), + ), +# allowed_attributes + (NUMBERNS,u'minutes'):( + (NUMBERNS,u'style'), + ), + (NUMBERNS,u'month'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + (NUMBERNS,u'possessive-form'), + (NUMBERNS,u'textual'), + ), + (NUMBERNS,u'number'):( + (NUMBERNS,u'display-factor'), + (NUMBERNS,u'decimal-places'), + (NUMBERNS,u'decimal-replacement'), + (NUMBERNS,u'min-integer-digits'), + (NUMBERNS,u'grouping'), + ), + (NUMBERNS,u'number-style'):( + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (STYLENS,u'display-name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + ), +# allowed_attributes + (NUMBERNS,u'percentage-style'):( + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (STYLENS,u'display-name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + ), + (NUMBERNS,u'quarter'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'scientific-number'):( + (NUMBERNS,u'min-exponent-digits'), + (NUMBERNS,u'decimal-places'), + (NUMBERNS,u'min-integer-digits'), + (NUMBERNS,u'grouping'), + ), + (NUMBERNS,u'seconds'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'decimal-places'), + ), + (NUMBERNS,u'text'):( + ), + (NUMBERNS,u'text-content'):( + ), + (NUMBERNS,u'text-style'):( + (NUMBERNS,u'transliteration-language'), + (STYLENS,u'name'), + (STYLENS,u'display-name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'transliteration-format'), + (NUMBERNS,u'transliteration-style'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + ), + (NUMBERNS,u'time-style'):( + (NUMBERNS,u'transliteration-language'), + (NUMBERNS,u'transliteration-format'), + (STYLENS,u'name'), + (STYLENS,u'display-name'), + (NUMBERNS,u'language'), + (NUMBERNS,u'title'), + (NUMBERNS,u'country'), + (NUMBERNS,u'truncate-on-overflow'), + (NUMBERNS,u'transliteration-style'), + (NUMBERNS,u'format-source'), + (STYLENS,u'volatile'), + (NUMBERNS,u'transliteration-country'), + ), + (NUMBERNS,u'week-of-year'):( + (NUMBERNS,u'calendar'), + ), + (NUMBERNS,u'year'):( + (NUMBERNS,u'style'), + (NUMBERNS,u'calendar'), + ), + (DR3DNS,u'cube'):( + (DR3DNS,u'min-edge'), + (DR3DNS,u'max-edge'), + (DRAWNS,u'layer'), + (DR3DNS,u'transform'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'id'), + ), + (DR3DNS,u'extrude'):( + (DRAWNS,u'layer'), + (SVGNS,u'd'), + (DR3DNS,u'transform'), + (SVGNS,u'viewBox'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'id'), + ), + (DR3DNS,u'light'):( + (DR3DNS,u'diffuse-color'), + (DR3DNS,u'direction'), + (DR3DNS,u'specular'), + (DR3DNS,u'enabled'), + ), + (DR3DNS,u'rotate'):( + (DRAWNS,u'layer'), + (SVGNS,u'd'), + (DR3DNS,u'transform'), + (SVGNS,u'viewBox'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'id'), + ), +# allowed_attributes + (DR3DNS,u'scene'):( + (DR3DNS,u'ambient-color'), + (DR3DNS,u'distance'), + (DR3DNS,u'focal-length'), + (DR3DNS,u'lighting-mode'), + (DR3DNS,u'projection'), + (DR3DNS,u'shade-mode'), + (DR3DNS,u'shadow-slant'), + (DR3DNS,u'transform'), + (DR3DNS,u'vpn'), + (DR3DNS,u'vrp'), + (DR3DNS,u'vup'), + (DRAWNS,u'id'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'layer'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + ), + (DR3DNS,u'sphere'):( + (DRAWNS,u'layer'), + (DR3DNS,u'center'), + (DR3DNS,u'transform'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'id'), + (DR3DNS,u'size'), + ), + (DRAWNS,u'a'):( + (OFFICENS,u'name'), + (OFFICENS,u'title'), + (XLINKNS,u'show'), + (OFFICENS,u'target-frame-name'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (OFFICENS,u'server-map'), + ), + (DRAWNS,u'applet'):( + (DRAWNS,u'code'), + (XLINKNS,u'show'), + (DRAWNS,u'object'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (DRAWNS,u'archive'), + (DRAWNS,u'may-script'), + ), + (DRAWNS,u'area-circle'):( + (OFFICENS,u'name'), + (XLINKNS,u'show'), + (SVGNS,u'cx'), + (XLINKNS,u'type'), + (DRAWNS,u'nohref'), + (SVGNS,u'cy'), + (XLINKNS,u'href'), + (SVGNS,u'r'), + (OFFICENS,u'target-frame-name'), + ), + (DRAWNS,u'area-polygon'):( + (OFFICENS,u'name'), + (XLINKNS,u'show'), + (XLINKNS,u'type'), + (SVGNS,u'height'), + (DRAWNS,u'nohref'), + (SVGNS,u'width'), + (XLINKNS,u'href'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (OFFICENS,u'target-frame-name'), + (SVGNS,u'viewBox'), + (DRAWNS,u'points'), + ), + (DRAWNS,u'area-rectangle'):( + (OFFICENS,u'name'), + (XLINKNS,u'show'), + (XLINKNS,u'type'), + (SVGNS,u'height'), + (DRAWNS,u'nohref'), + (SVGNS,u'width'), + (XLINKNS,u'href'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (OFFICENS,u'target-frame-name'), + ), + (DRAWNS,u'caption'):( + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (DRAWNS,u'caption-id'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'caption-point-y'), + (DRAWNS,u'caption-point-x'), + (DRAWNS,u'transform'), + (TABLENS,u'end-y'), + (DRAWNS,u'corner-radius'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'height'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'circle'):( + (DRAWNS,u'end-angle'), + (DRAWNS,u'id'), + (DRAWNS,u'kind'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'start-angle'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'cx'), + (SVGNS,u'cy'), + (SVGNS,u'height'), + (SVGNS,u'r'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'connector'):( + (DRAWNS,u'layer'), + (DRAWNS,u'end-shape'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y1'), + (SVGNS,u'y2'), + (TABLENS,u'table-background'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'transform'), + (DRAWNS,u'id'), + (TABLENS,u'end-y'), + (TABLENS,u'end-x'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'type'), + (DRAWNS,u'start-shape'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'style-name'), + (DRAWNS,u'start-glue-point'), + (SVGNS,u'x2'), + (SVGNS,u'x1'), + (TEXTNS,u'anchor-type'), + (DRAWNS,u'line-skew'), + (DRAWNS,u'name'), + (DRAWNS,u'end-glue-point'), + (DRAWNS,u'text-style-name'), + ), + (DRAWNS,u'contour-path'):( + (SVGNS,u'd'), + (SVGNS,u'width'), + (DRAWNS,u'recreate-on-edit'), + (SVGNS,u'viewBox'), + (SVGNS,u'height'), + ), + (DRAWNS,u'contour-polygon'):( + (SVGNS,u'width'), + (DRAWNS,u'points'), + (DRAWNS,u'recreate-on-edit'), + (SVGNS,u'viewBox'), + (SVGNS,u'height'), + ), + (DRAWNS,u'control'):( + (DRAWNS,u'control'), + (DRAWNS,u'layer'), + (DRAWNS,u'caption-id'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (TABLENS,u'table-background'), + (DRAWNS,u'transform'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'custom-shape'):( + (DRAWNS,u'engine'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (TABLENS,u'table-background'), + (DRAWNS,u'transform'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (DRAWNS,u'data'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + ), +# allowed_attributes + (DRAWNS,u'ellipse'):( + (DRAWNS,u'layer'), + (DRAWNS,u'start-angle'), + (SVGNS,u'cy'), + (SVGNS,u'cx'), + (TABLENS,u'table-background'), + (TABLENS,u'end-cell-address'), + (SVGNS,u'rx'), + (DRAWNS,u'transform'), + (DRAWNS,u'id'), + (SVGNS,u'width'), + (TABLENS,u'end-y'), + (TABLENS,u'end-x'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (DRAWNS,u'end-angle'), + (DRAWNS,u'z-index'), + (DRAWNS,u'caption-id'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (TEXTNS,u'anchor-type'), + (SVGNS,u'ry'), + (DRAWNS,u'kind'), + (DRAWNS,u'name'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (DRAWNS,u'text-style-name'), + ), +# allowed_attributes + (DRAWNS,u'enhanced-geometry'):( + (DRAWNS,u'extrusion-rotation-center'), + (DRAWNS,u'extrusion-shininess'), + (DRAWNS,u'extrusion-rotation-angle'), + (DRAWNS,u'extrusion-allowed'), + (DRAWNS,u'extrusion-first-light-level'), + (DRAWNS,u'extrusion-specularity'), + (DRAWNS,u'extrusion-viewpoint'), + (DRAWNS,u'extrusion-second-light-level'), + (DRAWNS,u'extrusion-origin'), + (DRAWNS,u'extrusion-color'), + (SVGNS,u'viewBox'), + (DR3DNS,u'projection'), + (DRAWNS,u'extrusion-metal'), + (DRAWNS,u'extrusion-number-of-line-segments'), + (DRAWNS,u'text-path-same-letter-heights'), + (DRAWNS,u'extrusion-first-light-harsh'), + (DRAWNS,u'enhanced-path'), + (DRAWNS,u'text-rotate-angle'), + (DRAWNS,u'type'), + (DRAWNS,u'glue-point-leaving-directions'), + (DRAWNS,u'concentric-gradient-fill-allowed'), + (DRAWNS,u'text-path-scale'), + (DRAWNS,u'extrusion-brightness'), + (DRAWNS,u'extrusion-first-light-direction'), + (DRAWNS,u'extrusion-light-face'), + (DRAWNS,u'text-path-allowed'), + (DRAWNS,u'glue-points'), + (DRAWNS,u'mirror-vertical'), + (DRAWNS,u'extrusion-depth'), + (DRAWNS,u'extrusion-diffusion'), + (DRAWNS,u'extrusion-second-light-direction'), + (DRAWNS,u'extrusion-skew'), + (DR3DNS,u'shade-mode'), + (DRAWNS,u'path-stretchpoint-y'), + (DRAWNS,u'modifiers'), + (DRAWNS,u'extrusion'), + (DRAWNS,u'path-stretchpoint-x'), + (DRAWNS,u'text-areas'), + (DRAWNS,u'mirror-horizontal'), + (DRAWNS,u'text-path-mode'), + (DRAWNS,u'extrusion-second-light-harsh'), + (DRAWNS,u'glue-point-type'), + (DRAWNS,u'text-path'), + ), +# allowed_attributes + (DRAWNS,u'equation'):( + (DRAWNS,u'formula'), + (DRAWNS,u'name'), + ), + (DRAWNS,u'fill-image'):( + (DRAWNS,u'name'), + (XLINKNS,u'show'), + (XLINKNS,u'actuate'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (XLINKNS,u'href'), + (DRAWNS,u'display-name'), + (XLINKNS,u'type'), + ), + (DRAWNS,u'floating-frame'):( + (XLINKNS,u'href'), + (XLINKNS,u'actuate'), + (DRAWNS,u'frame-name'), + (XLINKNS,u'type'), + (XLINKNS,u'show'), + ), + (DRAWNS,u'frame'):( + (DRAWNS,u'copy-of'), + (DRAWNS,u'id'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'class-names'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'style-name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'placeholder'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'user-transformed'), + (STYLENS,u'rel-height'), + (STYLENS,u'rel-width'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + ), +# allowed_attributes + (DRAWNS,u'g'):( + (DRAWNS,u'id'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'name'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'glue-point'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (DRAWNS,u'align'), + (DRAWNS,u'id'), + (DRAWNS,u'escape-direction'), + ), + (DRAWNS,u'gradient'):( + (DRAWNS,u'style'), + (DRAWNS,u'angle'), + (DRAWNS,u'name'), + (DRAWNS,u'end-color'), + (DRAWNS,u'start-color'), + (DRAWNS,u'cy'), + (DRAWNS,u'cx'), + (DRAWNS,u'display-name'), + (DRAWNS,u'border'), + (DRAWNS,u'end-intensity'), + (DRAWNS,u'start-intensity'), + ), + (DRAWNS,u'handle'):( + (DRAWNS,u'handle-radius-range-minimum'), + (DRAWNS,u'handle-switched'), + (DRAWNS,u'handle-range-y-maximum'), + (DRAWNS,u'handle-mirror-horizontal'), + (DRAWNS,u'handle-range-x-maximum'), + (DRAWNS,u'handle-mirror-vertical'), + (DRAWNS,u'handle-range-y-minimum'), + (DRAWNS,u'handle-radius-range-maximum'), + (DRAWNS,u'handle-range-x-minimum'), + (DRAWNS,u'handle-position'), + (DRAWNS,u'handle-polar'), + ), + (DRAWNS,u'hatch'):( + (DRAWNS,u'distance'), + (DRAWNS,u'style'), + (DRAWNS,u'name'), + (DRAWNS,u'color'), + (DRAWNS,u'display-name'), + (DRAWNS,u'rotation'), + ), + (DRAWNS,u'image'):( + (DRAWNS,u'filter-name'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (XLINKNS,u'actuate'), + (XLINKNS,u'show'), + ), + (DRAWNS,u'image-map'):( + ), + (DRAWNS,u'layer'):( + (DRAWNS,u'protected'), + (DRAWNS,u'name'), + (DRAWNS,u'display'), + ), +# allowed_attributes + (DRAWNS,u'layer-set'):( + ), + (DRAWNS,u'line'):( + (DRAWNS,u'class-names'), + (DRAWNS,u'id'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'style-name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'x1'), + (SVGNS,u'x2'), + (SVGNS,u'y1'), + (SVGNS,u'y2'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'marker'):( + (SVGNS,u'd'), + (DRAWNS,u'display-name'), + (DRAWNS,u'name'), + (SVGNS,u'viewBox'), + ), +# allowed_attributes + (DRAWNS,u'measure'):( + (TABLENS,u'end-cell-address'), + (DRAWNS,u'layer'), + (SVGNS,u'y2'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (TABLENS,u'table-background'), + (SVGNS,u'x2'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y1'), + (DRAWNS,u'caption-id'), + (TABLENS,u'end-y'), + (SVGNS,u'x1'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'object'):( + (XLINKNS,u'type'), + (XLINKNS,u'href'), + (DRAWNS,u'notify-on-update-of-ranges'), + (XLINKNS,u'actuate'), + (XLINKNS,u'show'), + ), + (DRAWNS,u'object-ole'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (DRAWNS,u'class-id'), + (XLINKNS,u'show'), + ), + (DRAWNS,u'opacity'):( + (DRAWNS,u'style'), + (DRAWNS,u'angle'), + (DRAWNS,u'name'), + (DRAWNS,u'start'), + (DRAWNS,u'cy'), + (DRAWNS,u'cx'), + (DRAWNS,u'end'), + (DRAWNS,u'display-name'), + (DRAWNS,u'border'), + ), + (DRAWNS,u'page'):( + (PRESENTATIONNS,u'presentation-page-layout-name'), + (DRAWNS,u'name'), + (DRAWNS,u'nav-order'), + (PRESENTATIONNS,u'use-footer-name'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'use-header-name'), + (DRAWNS,u'master-page-name'), + (DRAWNS,u'id'), + (PRESENTATIONNS,u'use-date-time-name'), + ), + (DRAWNS,u'page-thumbnail'):( + (TABLENS,u'table-background'), + (DRAWNS,u'caption-id'), + (PRESENTATIONNS,u'user-transformed'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'id'), + (DRAWNS,u'transform'), + (DRAWNS,u'page-number'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (PRESENTATIONNS,u'placeholder'), + (PRESENTATIONNS,u'class'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'param'):( + (DRAWNS,u'name'), + (DRAWNS,u'value'), + ), +# allowed_attributes + (DRAWNS,u'path'):( + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'caption-id'), + (SVGNS,u'd'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'id'), + (DRAWNS,u'transform'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-type'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (SVGNS,u'viewBox'), + (DRAWNS,u'name'), + ), + (DRAWNS,u'plugin'):( + (XLINKNS,u'type'), + (XLINKNS,u'href'), + (DRAWNS,u'mime-type'), + (XLINKNS,u'actuate'), + (XLINKNS,u'show'), + ), + (DRAWNS,u'polygon'):( + (DRAWNS,u'caption-id'), + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'id'), + (DRAWNS,u'transform'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'points'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (SVGNS,u'viewBox'), + (TEXTNS,u'anchor-type'), + ), +# allowed_attributes + (DRAWNS,u'polyline'):( + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'id'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'transform'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'points'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (TEXTNS,u'anchor-page-number'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (SVGNS,u'viewBox'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'rect'):( + (DRAWNS,u'corner-radius'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'id'), + (DRAWNS,u'layer'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'transform'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (PRESENTATIONNS,u'style-name'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TABLENS,u'end-cell-address'), + (TABLENS,u'end-x'), + (TABLENS,u'end-y'), + (TABLENS,u'table-background'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + ), +# allowed_attributes + (DRAWNS,u'regular-polygon'):( + (TABLENS,u'table-background'), + (DRAWNS,u'layer'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'caption-id'), + (DRAWNS,u'name'), + (DRAWNS,u'text-style-name'), + (TEXTNS,u'anchor-page-number'), + (DRAWNS,u'concave'), + (DRAWNS,u'sharpness'), + (DRAWNS,u'transform'), + (SVGNS,u'height'), + (SVGNS,u'width'), + (DRAWNS,u'z-index'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (DRAWNS,u'corners'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (DRAWNS,u'id'), + (TEXTNS,u'anchor-type'), + ), + (DRAWNS,u'stroke-dash'):( + (DRAWNS,u'distance'), + (DRAWNS,u'dots1-length'), + (DRAWNS,u'name'), + (DRAWNS,u'dots2-length'), + (DRAWNS,u'style'), + (DRAWNS,u'dots1'), + (DRAWNS,u'display-name'), + (DRAWNS,u'dots2'), + ), + (DRAWNS,u'text-box'):( + (FONS,u'min-width'), + (DRAWNS,u'corner-radius'), + (FONS,u'max-height'), + (FONS,u'min-height'), + (DRAWNS,u'chain-next-name'), + (FONS,u'max-width'), + (TEXTNS,u'id'), + ), +# allowed_attributes + (FORMNS,u'button'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'focus-on-click'), + (FORMNS,u'image-align'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'button-type'), + (FORMNS,u'title'), + (FORMNS,u'default-button'), + (FORMNS,u'value'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'image-data'), + (XLINKNS,u'href'), + (FORMNS,u'toggle'), + (FORMNS,u'xforms-submission'), + (OFFICENS,u'target-frame'), + (FORMNS,u'id'), + (FORMNS,u'image-position'), + ), + (FORMNS,u'checkbox'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'image-align'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'title'), + (FORMNS,u'is-tristate'), + (FORMNS,u'current-state'), + (FORMNS,u'value'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'state'), + (FORMNS,u'visual-effect'), + (FORMNS,u'id'), + (FORMNS,u'image-position'), + ), + (FORMNS,u'column'):( + (FORMNS,u'control-implementation'), + (FORMNS,u'text-style-name'), + (FORMNS,u'name'), + (FORMNS,u'label'), + ), + (FORMNS,u'combobox'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'dropdown'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'tab-index'), + (FORMNS,u'auto-complete'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'list-source'), + (FORMNS,u'title'), + (FORMNS,u'list-source-type'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + (FORMNS,u'size'), + ), +# allowed_attributes + (FORMNS,u'connection-resource'):( + (XLINKNS,u'href'), + ), + (FORMNS,u'date'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (FORMNS,u'min-value'), + (FORMNS,u'data-field'), + (FORMNS,u'max-value'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'file'):( + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'fixed-text'):( + (FORMNS,u'name'), + (FORMNS,u'for'), + (FORMNS,u'title'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'multi-line'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'id'), + ), +# allowed_attributes + (FORMNS,u'form'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (FORMNS,u'allow-deletes'), + (FORMNS,u'command-type'), + (FORMNS,u'apply-filter'), + (XLINKNS,u'type'), + (FORMNS,u'method'), + (OFFICENS,u'target-frame'), + (FORMNS,u'navigation-mode'), + (FORMNS,u'detail-fields'), + (FORMNS,u'master-fields'), + (FORMNS,u'allow-updates'), + (FORMNS,u'name'), + (FORMNS,u'tab-cycle'), + (FORMNS,u'control-implementation'), + (FORMNS,u'escape-processing'), + (FORMNS,u'filter'), + (FORMNS,u'command'), + (FORMNS,u'datasource'), + (FORMNS,u'enctype'), + (FORMNS,u'allow-inserts'), + (FORMNS,u'ignore-result'), + (FORMNS,u'order'), + ), + (FORMNS,u'formatted-text'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'max-value'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'min-value'), + (FORMNS,u'validation'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'frame'):( + (FORMNS,u'name'), + (FORMNS,u'for'), + (FORMNS,u'title'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'id'), + ), +# allowed_attributes + (FORMNS,u'generic-control'):( + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'name'), + (FORMNS,u'id'), + ), + (FORMNS,u'grid'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'id'), + ), + (FORMNS,u'hidden'):( + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'name'), + (FORMNS,u'value'), + (FORMNS,u'id'), + ), + (FORMNS,u'image'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'button-type'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (OFFICENS,u'target-frame'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'image-data'), + (XLINKNS,u'href'), + (FORMNS,u'id'), + ), + (FORMNS,u'image-frame'):( + (FORMNS,u'name'), + (FORMNS,u'title'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'readonly'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'image-data'), + (FORMNS,u'id'), + ), + (FORMNS,u'item'):( + (FORMNS,u'label'), + ), + (FORMNS,u'list-property'):( + (FORMNS,u'property-name'), + (OFFICENS,u'value-type'), + ), + (FORMNS,u'list-value'):( + (OFFICENS,u'string-value'), + ), +# allowed_attributes + (FORMNS,u'listbox'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'bound-column'), + (FORMNS,u'multiple'), + (FORMNS,u'name'), + (FORMNS,u'dropdown'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'tab-index'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'list-source'), + (FORMNS,u'title'), + (FORMNS,u'list-source-type'), + (FORMNS,u'id'), + (FORMNS,u'xforms-list-source'), + (FORMNS,u'size'), + ), + (FORMNS,u'number'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (FORMNS,u'min-value'), + (FORMNS,u'data-field'), + (FORMNS,u'max-value'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'option'):( + (FORMNS,u'current-selected'), + (FORMNS,u'selected'), + (FORMNS,u'value'), + (FORMNS,u'label'), + ), + (FORMNS,u'password'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'echo-char'), + (FORMNS,u'id'), + ), + (FORMNS,u'properties'):( + ), + (FORMNS,u'property'):( + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (FORMNS,u'property-name'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (OFFICENS,u'value-type'), + (OFFICENS,u'time-value'), + ), + (FORMNS,u'radio'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'selected'), + (FORMNS,u'image-align'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'current-selected'), + (FORMNS,u'value'), + (FORMNS,u'label'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'title'), + (FORMNS,u'visual-effect'), + (FORMNS,u'id'), + (FORMNS,u'image-position'), + ), + (FORMNS,u'text'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'textarea'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'data-field'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'time'):( + (FORMNS,u'convert-empty-to-null'), + (FORMNS,u'max-length'), + (FORMNS,u'tab-stop'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (FORMNS,u'min-value'), + (FORMNS,u'data-field'), + (FORMNS,u'max-value'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'readonly'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'id'), + (FORMNS,u'current-value'), + ), + (FORMNS,u'value-range'):( + (FORMNS,u'tab-stop'), + (FORMNS,u'max-value'), + (FORMNS,u'name'), + (FORMNS,u'tab-index'), + (FORMNS,u'control-implementation'), + (XFORMSNS,u'bind'), + (FORMNS,u'title'), + (FORMNS,u'value'), + (FORMNS,u'disabled'), + (FORMNS,u'printable'), + (FORMNS,u'orientation'), + (FORMNS,u'page-step-size'), + (FORMNS,u'delay-for-repeat'), + (FORMNS,u'min-value'), + (FORMNS,u'id'), + (FORMNS,u'step-size'), + ), + (MANIFESTNS,'algorithm') : ( + (MANIFESTNS,'algorithm-name'), + (MANIFESTNS,'initialisation-vector'), + ), + (MANIFESTNS,'encryption-data') : ( + (MANIFESTNS,'checksum-type'), + (MANIFESTNS,'checksum'), + ), + (MANIFESTNS,'file-entry') : ( + (MANIFESTNS,'full-path'), + (MANIFESTNS,'media-type'), + (MANIFESTNS,'size'), + ), + (MANIFESTNS,'key-derivation') : ( + (MANIFESTNS,'key-derivation-name'), + (MANIFESTNS,'salt'), + (MANIFESTNS,'iteration-count'), + ), + (MANIFESTNS,u'manifest'):( + ), +# allowed_attributes + (METANS,u'auto-reload'):( + (METANS,u'delay'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (XLINKNS,u'show'), + ), + (METANS,u'creation-date'):( + ), + (METANS,u'date-string'):( + ), + (METANS,u'document-statistic'):( + (METANS,u'non-whitespace-character-count'), + (METANS,u'ole-object-count'), + (METANS,u'table-count'), + (METANS,u'row-count'), + (METANS,u'character-count'), + (METANS,u'sentence-count'), + (METANS,u'draw-count'), + (METANS,u'paragraph-count'), + (METANS,u'word-count'), + (METANS,u'object-count'), + (METANS,u'syllable-count'), + (METANS,u'image-count'), + (METANS,u'page-count'), + (METANS,u'frame-count'), + (METANS,u'cell-count'), + ), + (METANS,u'editing-cycles'):( + ), + (METANS,u'editing-duration'):( + ), + (METANS,u'generator'):( + ), +# allowed_attributes + (METANS,u'hyperlink-behaviour'):( + (OFFICENS,u'target-frame-name'), + (XLINKNS,u'show'), + ), + (METANS,u'initial-creator'):( + ), + (METANS,u'keyword'):( + ), + (METANS,u'print-date'):( + ), + (METANS,u'printed-by'):( + ), + (METANS,u'template'):( + (METANS,u'date'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (XLINKNS,u'title'), + ), + (METANS,u'user-defined'):( + (METANS,u'name'), + (METANS,u'value-type'), + ), + (OFFICENS,u'annotation'):( + (DRAWNS,u'layer'), + (SVGNS,u'height'), + (TEXTNS,u'anchor-page-number'), + (TABLENS,u'table-background'), + (TABLENS,u'end-cell-address'), + (DRAWNS,u'transform'), + (DRAWNS,u'id'), + (SVGNS,u'width'), + (DRAWNS,u'class-names'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'class-names'), + (TABLENS,u'end-x'), + (DRAWNS,u'text-style-name'), + (DRAWNS,u'z-index'), + (PRESENTATIONNS,u'style-name'), + (TEXTNS,u'anchor-type'), + (DRAWNS,u'name'), + (DRAWNS,u'caption-point-y'), + (DRAWNS,u'caption-point-x'), + (DRAWNS,u'corner-radius'), + (SVGNS,u'y'), + (SVGNS,u'x'), + (TABLENS,u'end-y'), + (OFFICENS,u'display'), + ), + (OFFICENS,u'automatic-styles'):( + ), + (OFFICENS,u'binary-data'):( + ), + (OFFICENS,u'body'):( + ), + (OFFICENS,u'change-info'):( + ), + (OFFICENS,u'chart'):( + ), + (OFFICENS,u'dde-source'):( + (OFFICENS,u'dde-application'), + (OFFICENS,u'automatic-update'), + (OFFICENS,u'conversion-mode'), + (OFFICENS,u'dde-item'), + (OFFICENS,u'dde-topic'), + (OFFICENS,u'name'), + ), + (OFFICENS,u'document'):( + (OFFICENS,u'mimetype'), + (OFFICENS,u'version'), + ), + (OFFICENS,u'document-content'):( + (OFFICENS,u'version'), + ), + (OFFICENS,u'document-meta'):( + (OFFICENS,u'version'), + ), + (OFFICENS,u'document-settings'):( + (OFFICENS,u'version'), + ), + (OFFICENS,u'document-styles'):( + (OFFICENS,u'version'), + ), + (OFFICENS,u'drawing'):( + ), + (OFFICENS,u'event-listeners'):( + ), + (OFFICENS,u'font-face-decls'):( + ), + (OFFICENS,u'forms'):( + (FORMNS,u'automatic-focus'), + (FORMNS,u'apply-design-mode'), + ), + (OFFICENS,u'image'):( + ), +# allowed_attributes + (OFFICENS,u'master-styles'):( + ), + (OFFICENS,u'meta'):( + ), + (OFFICENS,u'presentation'):( + ), + (OFFICENS,u'script'):( + (SCRIPTNS,u'language'), + ), + (OFFICENS,u'scripts'):( + ), + (OFFICENS,u'settings'):( + ), + (OFFICENS,u'spreadsheet'):( + (TABLENS,u'structure-protected'), + (TABLENS,u'protection-key'), + ), + (OFFICENS,u'styles'):( + ), + (OFFICENS,u'text'):( + (TEXTNS,u'global'), + (TEXTNS,u'use-soft-page-breaks'), + ), + (PRESENTATIONNS,u'animation-group'):( + ), + (PRESENTATIONNS,u'animations'):( + ), + (PRESENTATIONNS,u'date-time'):( + ), + (PRESENTATIONNS,u'date-time-decl'):( + (PRESENTATIONNS,u'source'), + (STYLENS,u'data-style-name'), + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'dim'):( + (DRAWNS,u'color'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'event-listener'):( + (PRESENTATIONNS,u'direction'), + (XLINKNS,u'show'), + (XLINKNS,u'type'), + (XLINKNS,u'actuate'), + (PRESENTATIONNS,u'effect'), + (SCRIPTNS,u'event-name'), + (PRESENTATIONNS,u'start-scale'), + (XLINKNS,u'href'), + (PRESENTATIONNS,u'verb'), + (PRESENTATIONNS,u'action'), + (PRESENTATIONNS,u'speed'), + ), + (PRESENTATIONNS,u'footer'):( + ), + (PRESENTATIONNS,u'footer-decl'):( + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'header'):( + ), + (PRESENTATIONNS,u'header-decl'):( + (PRESENTATIONNS,u'name'), + ), + (PRESENTATIONNS,u'hide-shape'):( + (PRESENTATIONNS,u'direction'), + (PRESENTATIONNS,u'effect'), + (PRESENTATIONNS,u'delay'), + (PRESENTATIONNS,u'start-scale'), + (PRESENTATIONNS,u'path-id'), + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), +# allowed_attributes + (PRESENTATIONNS,u'hide-text'):( + (PRESENTATIONNS,u'direction'), + (PRESENTATIONNS,u'effect'), + (PRESENTATIONNS,u'delay'), + (PRESENTATIONNS,u'start-scale'), + (PRESENTATIONNS,u'path-id'), + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'notes'):( + (STYLENS,u'page-layout-name'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'use-header-name'), + (PRESENTATIONNS,u'use-date-time-name'), + (PRESENTATIONNS,u'use-footer-name'), + ), + (PRESENTATIONNS,u'placeholder'):( + (SVGNS,u'y'), + (SVGNS,u'x'), + (SVGNS,u'height'), + (PRESENTATIONNS,u'object'), + (SVGNS,u'width'), + ), + (PRESENTATIONNS,u'play'):( + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), +# allowed_attributes + (PRESENTATIONNS,u'settings'):( + (PRESENTATIONNS,u'animations'), + (PRESENTATIONNS,u'endless'), + (PRESENTATIONNS,u'force-manual'), + (PRESENTATIONNS,u'full-screen'), + (PRESENTATIONNS,u'mouse-as-pen'), + (PRESENTATIONNS,u'mouse-visible'), + (PRESENTATIONNS,u'pause'), + (PRESENTATIONNS,u'show'), + (PRESENTATIONNS,u'show-end-of-presentation-slide'), + (PRESENTATIONNS,u'show-logo'), + (PRESENTATIONNS,u'start-page'), + (PRESENTATIONNS,u'start-with-navigator'), + (PRESENTATIONNS,u'stay-on-top'), + (PRESENTATIONNS,u'transition-on-click'), + ), + (PRESENTATIONNS,u'show'):( + (PRESENTATIONNS,u'name'), + (PRESENTATIONNS,u'pages'), + ), + (PRESENTATIONNS,u'show-shape'):( + (PRESENTATIONNS,u'direction'), + (PRESENTATIONNS,u'effect'), + (PRESENTATIONNS,u'delay'), + (PRESENTATIONNS,u'start-scale'), + (PRESENTATIONNS,u'path-id'), + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'show-text'):( + (PRESENTATIONNS,u'direction'), + (PRESENTATIONNS,u'effect'), + (PRESENTATIONNS,u'delay'), + (PRESENTATIONNS,u'start-scale'), + (PRESENTATIONNS,u'path-id'), + (PRESENTATIONNS,u'speed'), + (DRAWNS,u'shape-id'), + ), + (PRESENTATIONNS,u'sound'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (PRESENTATIONNS,u'play-full'), + (XLINKNS,u'show'), + ), +# allowed_attributes + (SCRIPTNS,u'event-listener'):( + (SCRIPTNS,u'language'), + (SCRIPTNS,u'macro-name'), + (XLINKNS,u'actuate'), + (SCRIPTNS,u'event-name'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (STYLENS,u'background-image'):( + (DRAWNS,u'opacity'), + (STYLENS,u'repeat'), + (XLINKNS,u'show'), + (XLINKNS,u'actuate'), + (STYLENS,u'filter-name'), + (XLINKNS,u'href'), + (STYLENS,u'position'), + (XLINKNS,u'type'), + ), + (STYLENS,u'chart-properties'): ( + (CHARTNS,u'connect-bars'), + (CHARTNS,u'data-label-number'), + (CHARTNS,u'data-label-symbol'), + (CHARTNS,u'data-label-text'), + (CHARTNS,u'deep'), + (CHARTNS,u'display-label'), + (CHARTNS,u'error-category'), + (CHARTNS,u'error-lower-indicator'), + (CHARTNS,u'error-lower-limit'), + (CHARTNS,u'error-margin'), + (CHARTNS,u'error-percentage'), + (CHARTNS,u'error-upper-indicator'), + (CHARTNS,u'error-upper-limit'), + (CHARTNS,u'gap-width'), + (CHARTNS,u'interpolation'), + (CHARTNS,u'interval-major'), + (CHARTNS,u'interval-minor-divisor'), + (CHARTNS,u'japanese-candle-stick'), + (CHARTNS,u'label-arrangement'), + (CHARTNS,u'lines'), + (CHARTNS,u'link-data-style-to-source'), + (CHARTNS,u'logarithmic'), + (CHARTNS,u'maximum'), + (CHARTNS,u'mean-value'), + (CHARTNS,u'minimum'), + (CHARTNS,u'origin'), + (CHARTNS,u'overlap'), + (CHARTNS,u'percentage'), + (CHARTNS,u'pie-offset'), + (CHARTNS,u'regression-type'), + (CHARTNS,u'scale-text'), + (CHARTNS,u'series-source'), + (CHARTNS,u'solid-type'), + (CHARTNS,u'spline-order'), + (CHARTNS,u'spline-resolution'), + (CHARTNS,u'stacked'), + (CHARTNS,u'symbol-height'), + (CHARTNS,u'symbol-name'), + (CHARTNS,u'symbol-type'), + (CHARTNS,u'symbol-width'), + (CHARTNS,u'text-overlap'), + (CHARTNS,u'three-dimensional'), + (CHARTNS,u'tick-marks-major-inner'), + (CHARTNS,u'tick-marks-major-outer'), + (CHARTNS,u'tick-marks-minor-inner'), + (CHARTNS,u'tick-marks-minor-outer'), + (CHARTNS,u'vertical'), + (CHARTNS,u'visible'), + (STYLENS,u'direction'), + (STYLENS,u'rotation-angle'), + (TEXTNS,u'line-break'), + ), + (STYLENS,u'column'):( + (FONS,u'end-indent'), + (FONS,u'space-before'), + (FONS,u'start-indent'), + (FONS,u'space-after'), + (STYLENS,u'rel-width'), + ), + (STYLENS,u'column-sep'):( + (STYLENS,u'color'), + (STYLENS,u'width'), + (STYLENS,u'style'), + (STYLENS,u'vertical-align'), + (STYLENS,u'height'), + ), + (STYLENS,u'columns'):( + (FONS,u'column-count'), + (FONS,u'column-gap'), + ), + (STYLENS,u'default-style'):( + (STYLENS,u'family'), + ), +# allowed_attributes + (STYLENS,u'drawing-page-properties'): ( + (DRAWNS,u'fill'), + (DRAWNS,u'fill-color'), + (DRAWNS,u'secondary-fill-color'), + (DRAWNS,u'fill-gradient-name'), + (DRAWNS,u'gradient-step-count'), + (DRAWNS,u'fill-hatch-name'), + (DRAWNS,u'fill-hatch-solid'), + (DRAWNS,u'fill-image-name'), + (STYLENS,u'repeat'), + (DRAWNS,u'fill-image-width'), + (DRAWNS,u'fill-image-height'), + (DRAWNS,u'fill-image-ref-point-x'), + (DRAWNS,u'fill-image-ref-point-y'), + (DRAWNS,u'fill-image-ref-point'), + (DRAWNS,u'tile-repeat-offset'), + (DRAWNS,u'opacity'), + (DRAWNS,u'opacity-name'), + (SVGNS,u'fill-rule'), + (PRESENTATIONNS,u'transition-type'), + (PRESENTATIONNS,u'transition-style'), + (PRESENTATIONNS,u'transition-speed'), + (SMILNS,u'type'), + (SMILNS,u'subtype'), + (SMILNS,u'direction'), + (SMILNS,u'fadeColor'), + (PRESENTATIONNS,u'duration'), + (PRESENTATIONNS,u'visibility'), + (DRAWNS,u'background-size'), + (PRESENTATIONNS,u'background-objects-visible'), + (PRESENTATIONNS,u'background-visible'), + (PRESENTATIONNS,u'display-header'), + (PRESENTATIONNS,u'display-footer'), + (PRESENTATIONNS,u'display-page-number'), + (PRESENTATIONNS,u'display-date-time'), + ), + (STYLENS,u'drop-cap'):( + (STYLENS,u'distance'), + (STYLENS,u'length'), + (STYLENS,u'style-name'), + (STYLENS,u'lines'), + ), +# allowed_attributes + (STYLENS,u'font-face'):( + (STYLENS,u'font-adornments'), + (STYLENS,u'font-charset'), + (STYLENS,u'font-family-generic'), + (STYLENS,u'font-pitch'), + (STYLENS,u'name'), + (SVGNS,u'accent-height'), + (SVGNS,u'alphabetic'), + (SVGNS,u'ascent'), + (SVGNS,u'bbox'), + (SVGNS,u'cap-height'), + (SVGNS,u'descent'), + (SVGNS,u'font-family'), + (SVGNS,u'font-size'), + (SVGNS,u'font-stretch'), + (SVGNS,u'font-style'), + (SVGNS,u'font-variant'), + (SVGNS,u'font-weight'), + (SVGNS,u'hanging'), + (SVGNS,u'ideographic'), + (SVGNS,u'mathematical'), + (SVGNS,u'overline-position'), + (SVGNS,u'overline-thickness'), + (SVGNS,u'panose-1'), + (SVGNS,u'slope'), + (SVGNS,u'stemh'), + (SVGNS,u'stemv'), + (SVGNS,u'strikethrough-position'), + (SVGNS,u'strikethrough-thickness'), + (SVGNS,u'underline-position'), + (SVGNS,u'underline-thickness'), + (SVGNS,u'unicode-range'), + (SVGNS,u'units-per-em'), + (SVGNS,u'v-alphabetic'), + (SVGNS,u'v-hanging'), + (SVGNS,u'v-ideographic'), + (SVGNS,u'v-mathematical'), + (SVGNS,u'widths'), + (SVGNS,u'x-height'), + ), + (STYLENS,u'footer'):( + (STYLENS,u'display'), + ), + (STYLENS,u'footer-left'):( + (STYLENS,u'display'), + ), + (STYLENS,u'footer-style'):( + ), + (STYLENS,u'footnote-sep'):( + (STYLENS,u'distance-after-sep'), + (STYLENS,u'color'), + (STYLENS,u'rel-width'), + (STYLENS,u'width'), + (STYLENS,u'distance-before-sep'), + (STYLENS,u'line-style'), + (STYLENS,u'adjustment'), + ), +# allowed_attributes + (STYLENS,u'graphic-properties'): ( + (DR3DNS,u'ambient-color'), + (DR3DNS,u'back-scale'), + (DR3DNS,u'backface-culling'), + (DR3DNS,u'close-back'), + (DR3DNS,u'close-front'), + (DR3DNS,u'depth'), + (DR3DNS,u'diffuse-color'), + (DR3DNS,u'edge-rounding'), + (DR3DNS,u'edge-rounding-mode'), + (DR3DNS,u'emissive-color'), + (DR3DNS,u'end-angle'), + (DR3DNS,u'horizontal-segments'), + (DR3DNS,u'lighting-mode'), + (DR3DNS,u'normals-direction'), + (DR3DNS,u'normals-kind'), + (DR3DNS,u'shadow'), + (DR3DNS,u'shininess'), + (DR3DNS,u'specular-color'), + (DR3DNS,u'texture-filter'), + (DR3DNS,u'texture-generation-mode-x'), + (DR3DNS,u'texture-generation-mode-y'), + (DR3DNS,u'texture-kind'), + (DR3DNS,u'texture-mode'), + (DR3DNS,u'vertical-segments'), + (DRAWNS,u'auto-grow-height'), + (DRAWNS,u'auto-grow-width'), + (DRAWNS,u'blue'), + (DRAWNS,u'caption-angle'), + (DRAWNS,u'caption-angle-type'), + (DRAWNS,u'caption-escape'), + (DRAWNS,u'caption-escape-direction'), + (DRAWNS,u'caption-fit-line-length'), + (DRAWNS,u'caption-gap'), + (DRAWNS,u'caption-line-length'), + (DRAWNS,u'caption-type'), + (DRAWNS,u'color-inversion'), + (DRAWNS,u'color-mode'), + (DRAWNS,u'contrast'), + (DRAWNS,u'decimal-places'), + (DRAWNS,u'end-guide'), + (DRAWNS,u'end-line-spacing-horizontal'), + (DRAWNS,u'end-line-spacing-vertical'), + (DRAWNS,u'fill'), + (DRAWNS,u'fill-color'), + (DRAWNS,u'fill-gradient-name'), + (DRAWNS,u'fill-hatch-name'), + (DRAWNS,u'fill-hatch-solid'), + (DRAWNS,u'fill-image-height'), + (DRAWNS,u'fill-image-name'), + (DRAWNS,u'fill-image-ref-point'), + (DRAWNS,u'fill-image-ref-point-x'), + (DRAWNS,u'fill-image-ref-point-y'), + (DRAWNS,u'fill-image-width'), +# allowed_attributes + (DRAWNS,u'fit-to-contour'), + (DRAWNS,u'fit-to-size'), + (DRAWNS,u'frame-display-border'), + (DRAWNS,u'frame-display-scrollbar'), + (DRAWNS,u'frame-margin-horizontal'), + (DRAWNS,u'frame-margin-vertical'), + (DRAWNS,u'gamma'), + (DRAWNS,u'gradient-step-count'), + (DRAWNS,u'green'), + (DRAWNS,u'guide-distance'), + (DRAWNS,u'guide-overhang'), + (DRAWNS,u'image-opacity'), + (DRAWNS,u'line-distance'), + (DRAWNS,u'luminance'), + (DRAWNS,u'marker-end'), + (DRAWNS,u'marker-end-center'), + (DRAWNS,u'marker-end-width'), + (DRAWNS,u'marker-start'), + (DRAWNS,u'marker-start-center'), + (DRAWNS,u'marker-start-width'), + (DRAWNS,u'measure-align'), + (DRAWNS,u'measure-vertical-align'), + (DRAWNS,u'ole-draw-aspect'), + (DRAWNS,u'opacity'), + (DRAWNS,u'opacity-name'), + (DRAWNS,u'parallel'), + (DRAWNS,u'placing'), + (DRAWNS,u'red'), + (DRAWNS,u'secondary-fill-color'), + (DRAWNS,u'shadow'), + (DRAWNS,u'shadow-color'), + (DRAWNS,u'shadow-offset-x'), + (DRAWNS,u'shadow-offset-y'), + (DRAWNS,u'shadow-opacity'), + (DRAWNS,u'show-unit'), + (DRAWNS,u'start-guide'), + (DRAWNS,u'start-line-spacing-horizontal'), + (DRAWNS,u'start-line-spacing-vertical'), + (DRAWNS,u'stroke'), + (DRAWNS,u'stroke-dash'), + (DRAWNS,u'stroke-dash-names'), + (DRAWNS,u'stroke-linejoin'), + (DRAWNS,u'symbol-color'), + (DRAWNS,u'textarea-horizontal-align'), + (DRAWNS,u'textarea-vertical-align'), + (DRAWNS,u'tile-repeat-offset'), + (DRAWNS,u'unit'), + (DRAWNS,u'visible-area-height'), + (DRAWNS,u'visible-area-left'), + (DRAWNS,u'visible-area-top'), + (DRAWNS,u'visible-area-width'), + (DRAWNS,u'wrap-influence-on-position'), +# allowed_attributes + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'clip'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (FONS,u'max-height'), + (FONS,u'max-width'), + (FONS,u'min-height'), + (FONS,u'min-width'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (FONS,u'wrap-option'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'editable'), + (STYLENS,u'flow-with-text'), + (STYLENS,u'horizontal-pos'), + (STYLENS,u'horizontal-rel'), + (STYLENS,u'mirror'), + (STYLENS,u'number-wrapped-paragraphs'), + (STYLENS,u'overflow-behavior'), + (STYLENS,u'print-content'), + (STYLENS,u'protect'), + (STYLENS,u'rel-height'), + (STYLENS,u'rel-width'), + (STYLENS,u'repeat'), + (STYLENS,u'run-through'), + (STYLENS,u'shadow'), + (STYLENS,u'vertical-pos'), + (STYLENS,u'vertical-rel'), + (STYLENS,u'wrap'), + (STYLENS,u'wrap-contour'), + (STYLENS,u'wrap-contour-mode'), + (STYLENS,u'wrap-dynamic-threshold'), + (STYLENS,u'writing-mode'), + (SVGNS,u'fill-rule'), + (SVGNS,u'height'), + (SVGNS,u'stroke-color'), + (SVGNS,u'stroke-opacity'), + (SVGNS,u'stroke-width'), + (SVGNS,u'width'), + (SVGNS,u'x'), + (SVGNS,u'y'), + (TEXTNS,u'anchor-page-number'), + (TEXTNS,u'anchor-type'), + (TEXTNS,u'animation'), + (TEXTNS,u'animation-delay'), + (TEXTNS,u'animation-direction'), + (TEXTNS,u'animation-repeat'), + (TEXTNS,u'animation-start-inside'), + (TEXTNS,u'animation-steps'), + (TEXTNS,u'animation-stop-inside'), + ), + (STYLENS,u'handout-master'):( + (PRESENTATIONNS,u'presentation-page-layout-name'), + (STYLENS,u'page-layout-name'), + (PRESENTATIONNS,u'use-footer-name'), + (DRAWNS,u'style-name'), + (PRESENTATIONNS,u'use-header-name'), + (PRESENTATIONNS,u'use-date-time-name'), + ), +# allowed_attributes + (STYLENS,u'header'):( + (STYLENS,u'display'), + ), + (STYLENS,u'header-footer-properties'): ( + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (FONS,u'min-height'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'dynamic-spacing'), + (STYLENS,u'shadow'), + (SVGNS,u'height'), + ), + (STYLENS,u'header-left'):( + (STYLENS,u'display'), + ), + (STYLENS,u'header-style'):( + ), +# allowed_attributes + (STYLENS,u'list-level-properties'): ( + (FONS,u'height'), + (FONS,u'text-align'), + (FONS,u'width'), + (STYLENS,u'font-name'), + (STYLENS,u'vertical-pos'), + (STYLENS,u'vertical-rel'), + (SVGNS,u'y'), + (TEXTNS,u'min-label-distance'), + (TEXTNS,u'min-label-width'), + (TEXTNS,u'space-before'), + ), + (STYLENS,u'map'):( + (STYLENS,u'apply-style-name'), + (STYLENS,u'base-cell-address'), + (STYLENS,u'condition'), + ), + (STYLENS,u'master-page'):( + (STYLENS,u'page-layout-name'), + (STYLENS,u'display-name'), + (DRAWNS,u'style-name'), + (STYLENS,u'name'), + (STYLENS,u'next-style-name'), + ), + (STYLENS,u'page-layout'):( + (STYLENS,u'name'), + (STYLENS,u'page-usage'), + ), +# allowed_attributes + (STYLENS,u'page-layout-properties'): ( + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (FONS,u'page-height'), + (FONS,u'page-width'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'first-page-number'), + (STYLENS,u'footnote-max-height'), + (STYLENS,u'layout-grid-base-height'), + (STYLENS,u'layout-grid-color'), + (STYLENS,u'layout-grid-display'), + (STYLENS,u'layout-grid-lines'), + (STYLENS,u'layout-grid-mode'), + (STYLENS,u'layout-grid-print'), + (STYLENS,u'layout-grid-ruby-below'), + (STYLENS,u'layout-grid-ruby-height'), + (STYLENS,u'num-format'), + (STYLENS,u'num-letter-sync'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-suffix'), + (STYLENS,u'paper-tray-name'), + (STYLENS,u'print'), + (STYLENS,u'print-orientation'), + (STYLENS,u'print-page-order'), + (STYLENS,u'register-truth-ref-style-name'), + (STYLENS,u'scale-to'), + (STYLENS,u'scale-to-pages'), + (STYLENS,u'shadow'), + (STYLENS,u'table-centering'), + (STYLENS,u'writing-mode'), + ), +# allowed_attributes + (STYLENS,u'paragraph-properties'): ( + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'break-after'), + (FONS,u'break-before'), + (FONS,u'hyphenation-keep'), + (FONS,u'hyphenation-ladder-count'), + (FONS,u'keep-together'), + (FONS,u'keep-with-next'), + (FONS,u'line-height'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (FONS,u'orphans'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (FONS,u'text-align'), + (FONS,u'text-align-last'), + (FONS,u'text-indent'), + (FONS,u'widows'), + (STYLENS,u'auto-text-indent'), + (STYLENS,u'background-transparency'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'font-independent-line-spacing'), + (STYLENS,u'justify-single-word'), + (STYLENS,u'line-break'), + (STYLENS,u'line-height-at-least'), + (STYLENS,u'line-spacing'), + (STYLENS,u'page-number'), + (STYLENS,u'punctuation-wrap'), + (STYLENS,u'register-true'), + (STYLENS,u'shadow'), + (STYLENS,u'snap-to-layout-grid'), + (STYLENS,u'tab-stop-distance'), + (STYLENS,u'text-autospace'), + (STYLENS,u'vertical-align'), + (STYLENS,u'writing-mode'), + (STYLENS,u'writing-mode-automatic'), + (TEXTNS,u'line-number'), + (TEXTNS,u'number-lines'), + ), + (STYLENS,u'presentation-page-layout'):( + (STYLENS,u'display-name'), + (STYLENS,u'name'), + ), +# allowed_attributes + (STYLENS,u'region-center'):( + ), + (STYLENS,u'region-left'):( + ), + (STYLENS,u'region-right'):( + ), + (STYLENS,u'ruby-properties'): ( + (STYLENS,u'ruby-position'), + (STYLENS,u'ruby-align'), + ), + (STYLENS,u'section-properties'): ( + (FONS,u'background-color'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (STYLENS,u'protect'), + (STYLENS,u'writing-mode'), + (TEXTNS,u'dont-balance-text-columns'), + ), + (STYLENS,u'style'):( + (STYLENS,u'family'), + (STYLENS,u'list-style-name'), + (STYLENS,u'name'), + (STYLENS,u'auto-update'), + (STYLENS,u'default-outline-level'), + (STYLENS,u'class'), + (STYLENS,u'next-style-name'), + (STYLENS,u'data-style-name'), + (STYLENS,u'master-page-name'), + (STYLENS,u'display-name'), + (STYLENS,u'parent-style-name'), + ), +# allowed_attributes + (STYLENS,u'tab-stop'):( + (STYLENS,u'leader-text-style'), + (STYLENS,u'leader-width'), + (STYLENS,u'leader-style'), + (STYLENS,u'char'), + (STYLENS,u'leader-color'), + (STYLENS,u'position'), + (STYLENS,u'leader-text'), + (STYLENS,u'type'), + (STYLENS,u'leader-type'), + ), + (STYLENS,u'tab-stops'):( + ), + (STYLENS,u'table-cell-properties'): ( + (FONS,u'background-color'), + (FONS,u'border'), + (FONS,u'border-bottom'), + (FONS,u'border-left'), + (FONS,u'border-right'), + (FONS,u'border-top'), + (FONS,u'padding'), + (FONS,u'padding-bottom'), + (FONS,u'padding-left'), + (FONS,u'padding-right'), + (FONS,u'padding-top'), + (FONS,u'wrap-option'), + (STYLENS,u'border-line-width'), + (STYLENS,u'border-line-width-bottom'), + (STYLENS,u'border-line-width-left'), + (STYLENS,u'border-line-width-right'), + (STYLENS,u'border-line-width-top'), + (STYLENS,u'cell-protect'), + (STYLENS,u'decimal-places'), + (STYLENS,u'diagonal-bl-tr'), + (STYLENS,u'diagonal-bl-tr-widths'), + (STYLENS,u'diagonal-tl-br'), + (STYLENS,u'diagonal-tl-br-widths'), + (STYLENS,u'direction'), + (STYLENS,u'glyph-orientation-vertical'), + (STYLENS,u'print-content'), + (STYLENS,u'repeat-content'), + (STYLENS,u'rotation-align'), + (STYLENS,u'rotation-angle'), + (STYLENS,u'shadow'), + (STYLENS,u'shrink-to-fit'), + (STYLENS,u'text-align-source'), + (STYLENS,u'vertical-align'), + ), +# allowed_attributes + (STYLENS,u'table-column-properties'): ( + (FONS,u'break-after'), + (FONS,u'break-before'), + (STYLENS,u'column-width'), + (STYLENS,u'rel-column-width'), + (STYLENS,u'use-optimal-column-width'), + ), + (STYLENS,u'table-properties'): ( + (FONS,u'background-color'), + (FONS,u'break-after'), + (FONS,u'break-before'), + (FONS,u'keep-with-next'), + (FONS,u'margin'), + (FONS,u'margin-bottom'), + (FONS,u'margin-left'), + (FONS,u'margin-right'), + (FONS,u'margin-top'), + (STYLENS,u'may-break-between-rows'), + (STYLENS,u'page-number'), + (STYLENS,u'rel-width'), + (STYLENS,u'shadow'), + (STYLENS,u'width'), + (STYLENS,u'writing-mode'), + (TABLENS,u'align'), + (TABLENS,u'border-model'), + (TABLENS,u'display'), + ), + (STYLENS,u'table-row-properties'): ( + (FONS,u'background-color'), + (FONS,u'break-after'), + (FONS,u'break-before'), + (FONS,u'keep-together'), + (STYLENS,u'min-row-height'), + (STYLENS,u'row-height'), + (STYLENS,u'use-optimal-row-height'), + ), +# allowed_attributes + (STYLENS,u'text-properties'): ( + (FONS,u'background-color'), + (FONS,u'color'), + (FONS,u'country'), + (FONS,u'font-family'), + (FONS,u'font-size'), + (FONS,u'font-style'), + (FONS,u'font-variant'), + (FONS,u'font-weight'), + (FONS,u'hyphenate'), + (FONS,u'hyphenation-push-char-count'), + (FONS,u'hyphenation-remain-char-count'), + (FONS,u'language'), + (FONS,u'letter-spacing'), + (FONS,u'text-shadow'), + (FONS,u'text-transform'), + (STYLENS,u'country-asian'), + (STYLENS,u'country-complex'), + (STYLENS,u'font-charset'), + (STYLENS,u'font-charset-asian'), + (STYLENS,u'font-charset-complex'), + (STYLENS,u'font-family-asian'), + (STYLENS,u'font-family-complex'), + (STYLENS,u'font-family-generic'), + (STYLENS,u'font-family-generic-asian'), + (STYLENS,u'font-family-generic-complex'), + (STYLENS,u'font-name'), + (STYLENS,u'font-name-asian'), + (STYLENS,u'font-name-complex'), + (STYLENS,u'font-pitch'), + (STYLENS,u'font-pitch-asian'), + (STYLENS,u'font-pitch-complex'), + (STYLENS,u'font-relief'), + (STYLENS,u'font-size-asian'), + (STYLENS,u'font-size-complex'), + (STYLENS,u'font-size-rel'), + (STYLENS,u'font-size-rel-asian'), + (STYLENS,u'font-size-rel-complex'), + (STYLENS,u'font-style-asian'), + (STYLENS,u'font-style-complex'), + (STYLENS,u'font-style-name'), + (STYLENS,u'font-style-name-asian'), + (STYLENS,u'font-style-name-complex'), + (STYLENS,u'font-weight-asian'), + (STYLENS,u'font-weight-complex'), + (STYLENS,u'language-asian'), + (STYLENS,u'language-complex'), + (STYLENS,u'letter-kerning'), + (STYLENS,u'script-type'), + (STYLENS,u'text-blinking'), + (STYLENS,u'text-combine'), + (STYLENS,u'text-combine-end-char'), + (STYLENS,u'text-combine-start-char'), + (STYLENS,u'text-emphasize'), + (STYLENS,u'text-line-through-color'), + (STYLENS,u'text-line-through-mode'), + (STYLENS,u'text-line-through-style'), + (STYLENS,u'text-line-through-text'), + (STYLENS,u'text-line-through-text-style'), + (STYLENS,u'text-line-through-type'), + (STYLENS,u'text-line-through-width'), + (STYLENS,u'text-outline'), + (STYLENS,u'text-position'), + (STYLENS,u'text-rotation-angle'), + (STYLENS,u'text-rotation-scale'), + (STYLENS,u'text-scale'), + (STYLENS,u'text-underline-color'), + (STYLENS,u'text-underline-mode'), + (STYLENS,u'text-underline-style'), + (STYLENS,u'text-underline-type'), + (STYLENS,u'text-underline-width'), + (STYLENS,u'use-window-font-color'), + (TEXTNS,u'condition'), + (TEXTNS,u'display'), + ), + (SVGNS,u'definition-src'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (SVGNS,u'desc'):( + ), + (SVGNS,u'font-face-format'):( + (SVGNS,u'string'), + ), +# allowed_attributes + (SVGNS,u'font-face-name'):( + (SVGNS,u'name'), + ), + (SVGNS,u'font-face-src'):( + ), + (SVGNS,u'font-face-uri'):( + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (SVGNS,u'linearGradient'):( + (SVGNS,u'y2'), + (DRAWNS,u'name'), + (SVGNS,u'spreadMethod'), + (SVGNS,u'gradientUnits'), + (SVGNS,u'x2'), + (SVGNS,u'gradientTransform'), + (SVGNS,u'y1'), + (DRAWNS,u'display-name'), + (SVGNS,u'x1'), + ), + (SVGNS,u'radialGradient'):( + (DRAWNS,u'name'), + (SVGNS,u'fx'), + (SVGNS,u'fy'), + (SVGNS,u'spreadMethod'), + (SVGNS,u'gradientUnits'), + (SVGNS,u'cy'), + (SVGNS,u'cx'), + (SVGNS,u'gradientTransform'), + (DRAWNS,u'display-name'), + (SVGNS,u'r'), + ), + (SVGNS,u'stop'):( + (SVGNS,u'stop-color'), + (SVGNS,u'stop-opacity'), + (SVGNS,u'offset'), + ), + (SVGNS,u'title'):( + ), +# allowed_attributes + (TABLENS,u'body'):( + (TEXTNS,u'paragraph-style-name'), + (TEXTNS,u'style-name'), + ), + (TABLENS,u'calculation-settings'):( + (TABLENS,u'automatic-find-labels'), + (TABLENS,u'case-sensitive'), + (TABLENS,u'search-criteria-must-apply-to-whole-cell'), + (TABLENS,u'precision-as-shown'), + (TABLENS,u'use-regular-expressions'), + (TABLENS,u'null-year'), + ), + (TABLENS,u'cell-address'):( + (TABLENS,u'column'), + (TABLENS,u'table'), + (TABLENS,u'row'), + ), + (TABLENS,u'cell-content-change'):( + (TABLENS,u'id'), + (TABLENS,u'rejecting-change-id'), + (TABLENS,u'acceptance-state'), + ), + (TABLENS,u'cell-content-deletion'):( + (TABLENS,u'id'), + ), + (TABLENS,u'cell-range-source'):( + (TABLENS,u'last-row-spanned'), + (TABLENS,u'last-column-spanned'), + (TABLENS,u'name'), + (TABLENS,u'filter-options'), + (XLINKNS,u'actuate'), + (TABLENS,u'filter-name'), + (XLINKNS,u'href'), + (TABLENS,u'refresh-delay'), + (XLINKNS,u'type'), + ), + (TABLENS,u'change-deletion'):( + (TABLENS,u'id'), + ), + (TABLENS,u'change-track-table-cell'):( + (OFFICENS,u'string-value'), + (TABLENS,u'cell-address'), + (TABLENS,u'number-matrix-columns-spanned'), + (TABLENS,u'number-matrix-rows-spanned'), + (TABLENS,u'matrix-covered'), + (OFFICENS,u'value-type'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (OFFICENS,u'value'), + (TABLENS,u'formula'), + (OFFICENS,u'time-value'), + ), + (TABLENS,u'consolidation'):( + (TABLENS,u'function'), + (TABLENS,u'source-cell-range-addresses'), + (TABLENS,u'target-cell-address'), + (TABLENS,u'link-to-source-data'), + (TABLENS,u'use-labels'), + ), + (TABLENS,u'content-validation'):( + (TABLENS,u'base-cell-address'), + (TABLENS,u'display-list'), + (TABLENS,u'allow-empty-cell'), + (TABLENS,u'name'), + (TABLENS,u'condition'), + ), + (TABLENS,u'content-validations'):( + ), +# allowed_attributes + (TABLENS,u'covered-table-cell'):( + (TABLENS,u'protect'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (TABLENS,u'style-name'), + (TABLENS,u'content-validation-name'), + (OFFICENS,u'value-type'), + (TABLENS,u'number-columns-repeated'), + (TABLENS,u'formula'), + (OFFICENS,u'time-value'), + ), + (TABLENS,u'cut-offs'):( + ), + (TABLENS,u'data-pilot-display-info'):( + (TABLENS,u'member-count'), + (TABLENS,u'data-field'), + (TABLENS,u'enabled'), + (TABLENS,u'display-member-mode'), + ), + (TABLENS,u'data-pilot-field'):( + (TABLENS,u'selected-page'), + (TABLENS,u'function'), + (TABLENS,u'orientation'), + (TABLENS,u'used-hierarchy'), + (TABLENS,u'is-data-layout-field'), + (TABLENS,u'source-field-name'), + ), + (TABLENS,u'data-pilot-field-reference'):( + (TABLENS,u'member-name'), + (TABLENS,u'field-name'), + (TABLENS,u'member-type'), + (TABLENS,u'type'), + ), +# allowed_attributes + (TABLENS,u'data-pilot-group'):( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-group-member'):( + (TABLENS,u'name'), + ), + (TABLENS,u'data-pilot-groups'):( + (TABLENS,u'date-end'), + (TABLENS,u'end'), + (TABLENS,u'start'), + (TABLENS,u'source-field-name'), + (TABLENS,u'step'), + (TABLENS,u'date-start'), + (TABLENS,u'grouped-by'), + ), + (TABLENS,u'data-pilot-layout-info'):( + (TABLENS,u'add-empty-lines'), + (TABLENS,u'layout-mode'), + ), + (TABLENS,u'data-pilot-level'):( + (TABLENS,u'show-empty'), + ), +# allowed_attributes + (TABLENS,u'data-pilot-member'):( + (TABLENS,u'show-details'), + (TABLENS,u'name'), + (TABLENS,u'display'), + ), + (TABLENS,u'data-pilot-members'):( + ), + (TABLENS,u'data-pilot-sort-info'):( + (TABLENS,u'data-field'), + (TABLENS,u'sort-mode'), + (TABLENS,u'order'), + ), + (TABLENS,u'data-pilot-subtotal'):( + (TABLENS,u'function'), + ), + (TABLENS,u'data-pilot-subtotals'):( + ), + (TABLENS,u'data-pilot-table'):( + (TABLENS,u'buttons'), + (TABLENS,u'application-data'), + (TABLENS,u'name'), + (TABLENS,u'drill-down-on-double-click'), + (TABLENS,u'target-range-address'), + (TABLENS,u'ignore-empty-rows'), + (TABLENS,u'identify-categories'), + (TABLENS,u'show-filter-button'), + (TABLENS,u'grand-total'), + ), +# allowed_attributes + (TABLENS,u'data-pilot-tables'):( + ), + (TABLENS,u'database-range'):( + (TABLENS,u'orientation'), + (TABLENS,u'target-range-address'), + (TABLENS,u'contains-header'), + (TABLENS,u'on-update-keep-size'), + (TABLENS,u'name'), + (TABLENS,u'is-selection'), + (TABLENS,u'refresh-delay'), + (TABLENS,u'display-filter-buttons'), + (TABLENS,u'has-persistent-data'), + (TABLENS,u'on-update-keep-styles'), + ), + (TABLENS,u'database-ranges'):( + ), + (TABLENS,u'database-source-query'):( + (TABLENS,u'query-name'), + (TABLENS,u'database-name'), + ), +# allowed_attributes + (TABLENS,u'database-source-sql'):( + (TABLENS,u'parse-sql-statement'), + (TABLENS,u'database-name'), + (TABLENS,u'sql-statement'), + ), + (TABLENS,u'database-source-table'):( + (TABLENS,u'database-table-name'), + (TABLENS,u'database-name'), + ), + (TABLENS,u'dde-link'):( + ), + (TABLENS,u'dde-links'):( + ), + (TABLENS,u'deletion'):( + (TABLENS,u'rejecting-change-id'), + (TABLENS,u'multi-deletion-spanned'), + (TABLENS,u'acceptance-state'), + (TABLENS,u'table'), + (TABLENS,u'position'), + (TABLENS,u'type'), + (TABLENS,u'id'), + ), +# allowed_attributes + (TABLENS,u'deletions'):( + ), + (TABLENS,u'dependencies'):( + ), + (TABLENS,u'dependency'):( + (TABLENS,u'id'), + ), + (TABLENS,u'detective'):( + ), + (TABLENS,u'error-macro'):( + (TABLENS,u'execute'), + ), + (TABLENS,u'error-message'):( + (TABLENS,u'display'), + (TABLENS,u'message-type'), + (TABLENS,u'title'), + ), + (TABLENS,u'even-columns'):( + (TEXTNS,u'paragraph-style-name'), + (TEXTNS,u'style-name'), + ), + (TABLENS,u'even-rows'):( + (TEXTNS,u'paragraph-style-name'), + (TEXTNS,u'style-name'), + ), +# allowed_attributes + (TABLENS,u'filter'):( + (TABLENS,u'target-range-address'), + (TABLENS,u'display-duplicates'), + (TABLENS,u'condition-source-range-address'), + (TABLENS,u'condition-source'), + ), + (TABLENS,u'filter-and'):( + ), + (TABLENS,u'filter-condition'):( + (TABLENS,u'operator'), + (TABLENS,u'field-number'), + (TABLENS,u'data-type'), + (TABLENS,u'case-sensitive'), + (TABLENS,u'value'), + ), + (TABLENS,u'filter-or'):( + ), + (TABLENS,u'first-column'):( + (TEXTNS,u'paragraph-style-name'), + (TEXTNS,u'style-name'), + ), + (TABLENS,u'first-row'):( + (TEXTNS,u'paragraph-style-name'), + (TEXTNS,u'style-name'), + ), +# allowed_attributes + (TABLENS,u'help-message'):( + (TABLENS,u'display'), + (TABLENS,u'title'), + ), + (TABLENS,u'highlighted-range'):( + (TABLENS,u'contains-error'), + (TABLENS,u'direction'), + (TABLENS,u'marked-invalid'), + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'insertion'):( + (TABLENS,u'count'), + (TABLENS,u'rejecting-change-id'), + (TABLENS,u'acceptance-state'), + (TABLENS,u'table'), + (TABLENS,u'position'), + (TABLENS,u'type'), + (TABLENS,u'id'), + ), + (TABLENS,u'insertion-cut-off'):( + (TABLENS,u'position'), + (TABLENS,u'id'), + ), + (TABLENS,u'iteration'):( + (TABLENS,u'status'), + (TABLENS,u'maximum-difference'), + (TABLENS,u'steps'), + ), +# allowed_attributes + (TABLENS,u'label-range'):( + (TABLENS,u'label-cell-range-address'), + (TABLENS,u'data-cell-range-address'), + (TABLENS,u'orientation'), + ), + (TABLENS,u'label-ranges'):( + ), + (TABLENS,u'last-column'):( + (TEXTNS,u'paragraph-style-name'), + (TEXTNS,u'style-name'), + ), + (TABLENS,u'last-row'):( + (TEXTNS,u'paragraph-style-name'), + (TEXTNS,u'style-name'), + ), + (TABLENS,u'movement'):( + (TABLENS,u'id'), + (TABLENS,u'rejecting-change-id'), + (TABLENS,u'acceptance-state'), + ), + (TABLENS,u'movement-cut-off'):( + (TABLENS,u'position'), + (TABLENS,u'end-position'), + (TABLENS,u'start-position'), + ), + (TABLENS,u'named-expression'):( + (TABLENS,u'base-cell-address'), + (TABLENS,u'expression'), + (TABLENS,u'name'), + ), + (TABLENS,u'named-expressions'):( + ), + (TABLENS,u'named-range'):( + (TABLENS,u'range-usable-as'), + (TABLENS,u'base-cell-address'), + (TABLENS,u'name'), + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'null-date'):( + (TABLENS,u'date-value'), + (TABLENS,u'value-type'), + ), + (TABLENS,u'odd-columns'):( + (TEXTNS,u'paragraph-style-name'), + (TEXTNS,u'style-name'), + ), + (TABLENS,u'odd-rows'):( + (TEXTNS,u'paragraph-style-name'), + (TEXTNS,u'style-name'), + ), + (TABLENS,u'operation'):( + (TABLENS,u'index'), + (TABLENS,u'name'), + ), + (TABLENS,u'previous'):( + (TABLENS,u'id'), + ), + (TABLENS,u'scenario'):( + (TABLENS,u'comment'), + (TABLENS,u'border-color'), + (TABLENS,u'copy-back'), + (TABLENS,u'is-active'), + (TABLENS,u'protected'), + (TABLENS,u'copy-formulas'), + (TABLENS,u'copy-styles'), + (TABLENS,u'scenario-ranges'), + (TABLENS,u'display-border'), + ), + (TABLENS,u'shapes'):( + ), + (TABLENS,u'sort'):( + (TABLENS,u'case-sensitive'), + (TABLENS,u'algorithm'), + (TABLENS,u'target-range-address'), + (TABLENS,u'country'), + (TABLENS,u'language'), + (TABLENS,u'bind-styles-to-content'), + ), + (TABLENS,u'sort-by'):( + (TABLENS,u'field-number'), + (TABLENS,u'data-type'), + (TABLENS,u'order'), + ), + (TABLENS,u'sort-groups'):( + (TABLENS,u'data-type'), + (TABLENS,u'order'), + ), + (TABLENS,u'source-cell-range'):( + (TABLENS,u'cell-range-address'), + ), + (TABLENS,u'source-range-address'):( + (TABLENS,u'column'), + (TABLENS,u'end-column'), + (TABLENS,u'start-table'), + (TABLENS,u'end-row'), + (TABLENS,u'table'), + (TABLENS,u'start-row'), + (TABLENS,u'row'), + (TABLENS,u'end-table'), + (TABLENS,u'start-column'), + ), +# allowed_attributes + (TABLENS,u'source-service'):( + (TABLENS,u'user-name'), + (TABLENS,u'source-name'), + (TABLENS,u'password'), + (TABLENS,u'object-name'), + (TABLENS,u'name'), + ), + (TABLENS,u'subtotal-field'):( + (TABLENS,u'function'), + (TABLENS,u'field-number'), + ), + (TABLENS,u'subtotal-rule'):( + (TABLENS,u'group-by-field-number'), + ), + (TABLENS,u'subtotal-rules'):( + (TABLENS,u'bind-styles-to-content'), + (TABLENS,u'page-breaks-on-group-change'), + (TABLENS,u'case-sensitive'), + ), + (TABLENS,u'table'):( + (TABLENS,u'name'), + (TABLENS,u'is-sub-table'), + (TABLENS,u'style-name'), + (TABLENS,u'protected'), + (TABLENS,u'print-ranges'), + (TABLENS,u'print'), + (TABLENS,u'protection-key'), + ), + (TABLENS,u'table-cell'):( + (TABLENS,u'protect'), + (TABLENS,u'number-matrix-rows-spanned'), + (TABLENS,u'number-matrix-columns-spanned'), + (OFFICENS,u'string-value'), + (TABLENS,u'number-columns-spanned'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (TABLENS,u'style-name'), + (TABLENS,u'content-validation-name'), + (OFFICENS,u'value-type'), + (TABLENS,u'number-rows-spanned'), + (TABLENS,u'number-columns-repeated'), + (TABLENS,u'formula'), + (OFFICENS,u'time-value'), + ), +# allowed_attributes + (TABLENS,u'table-column'):( + (TABLENS,u'style-name'), + (TABLENS,u'default-cell-style-name'), + (TABLENS,u'visibility'), + (TABLENS,u'number-columns-repeated'), + ), + (TABLENS,u'table-column-group'):( + (TABLENS,u'display'), + ), + (TABLENS,u'table-columns'):( + ), + (TABLENS,u'table-header-columns'):( + ), + (TABLENS,u'table-header-rows'):( + ), + (TABLENS,u'table-row'):( + (TABLENS,u'number-rows-repeated'), + (TABLENS,u'style-name'), + (TABLENS,u'visibility'), + (TABLENS,u'default-cell-style-name'), + ), + (TABLENS,u'table-row-group'):( + (TABLENS,u'display'), + ), + (TABLENS,u'table-rows'):( + ), + (TABLENS,u'table-source'):( + (TABLENS,u'filter-options'), + (XLINKNS,u'actuate'), + (TABLENS,u'filter-name'), + (XLINKNS,u'href'), + (TABLENS,u'mode'), + (TABLENS,u'table-name'), + (XLINKNS,u'type'), + (TABLENS,u'refresh-delay'), + ), + (TABLENS,u'table-template'):( + (TEXTNS,u'last-row-end-column'), + (TEXTNS,u'first-row-end-column'), + (TEXTNS,u'name'), + (TEXTNS,u'last-row-start-column'), + (TEXTNS,u'first-row-start-column'), + ), + (TABLENS,u'target-range-address'):( + (TABLENS,u'column'), + (TABLENS,u'end-column'), + (TABLENS,u'start-table'), + (TABLENS,u'end-row'), + (TABLENS,u'table'), + (TABLENS,u'start-row'), + (TABLENS,u'row'), + (TABLENS,u'end-table'), + (TABLENS,u'start-column'), + ), + (TABLENS,u'tracked-changes'):( + (TABLENS,u'track-changes'), + ), +# allowed_attributes + (TEXTNS,u'a'):( + (TEXTNS,u'visited-style-name'), + (OFFICENS,u'name'), + (OFFICENS,u'title'), + (XLINKNS,u'show'), + (OFFICENS,u'target-frame-name'), + (XLINKNS,u'actuate'), + (TEXTNS,u'style-name'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (TEXTNS,u'alphabetical-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'alphabetical-index-auto-mark-file'):( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + ), + (TEXTNS,u'alphabetical-index-entry-template'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'alphabetical-index-mark'):( + (TEXTNS,u'main-entry'), + (TEXTNS,u'key1-phonetic'), + (TEXTNS,u'key2'), + (TEXTNS,u'key1'), + (TEXTNS,u'string-value'), + (TEXTNS,u'key2-phonetic'), + (TEXTNS,u'string-value-phonetic'), + ), +# allowed_attributes + (TEXTNS,u'alphabetical-index-mark-end'):( + (TEXTNS,u'id'), + ), + (TEXTNS,u'alphabetical-index-mark-start'):( + (TEXTNS,u'main-entry'), + (TEXTNS,u'key1-phonetic'), + (TEXTNS,u'key2'), + (TEXTNS,u'key1'), + (TEXTNS,u'string-value-phonetic'), + (TEXTNS,u'key2-phonetic'), + (TEXTNS,u'id'), + ), + (TEXTNS,u'alphabetical-index-source'):( + (TEXTNS,u'capitalize-entries'), + (FONS,u'language'), + (TEXTNS,u'relative-tab-stop-position'), + (TEXTNS,u'alphabetical-separators'), + (TEXTNS,u'combine-entries-with-pp'), + (TEXTNS,u'combine-entries-with-dash'), + (TEXTNS,u'sort-algorithm'), + (TEXTNS,u'ignore-case'), + (TEXTNS,u'combine-entries'), + (TEXTNS,u'comma-separated'), + (FONS,u'country'), + (TEXTNS,u'index-scope'), + (TEXTNS,u'main-entry-style-name'), + (TEXTNS,u'use-keys-as-entries'), + ), +# allowed_attributes + (TEXTNS,u'author-initials'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'author-name'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'bibliography'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'bibliography-configuration'):( + (TEXTNS,u'suffix'), + (FONS,u'language'), + (TEXTNS,u'numbered-entries'), + (FONS,u'country'), + (TEXTNS,u'sort-by-position'), + (TEXTNS,u'sort-algorithm'), + (TEXTNS,u'prefix'), + ), + (TEXTNS,u'bibliography-entry-template'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'bibliography-type'), + ), +# allowed_attributes + (TEXTNS,u'bibliography-mark'):( + (TEXTNS,u'address'), + (TEXTNS,u'annote'), + (TEXTNS,u'author'), + (TEXTNS,u'bibliography-type'), + (TEXTNS,u'booktitle'), + (TEXTNS,u'chapter'), + (TEXTNS,u'custom1'), + (TEXTNS,u'custom2'), + (TEXTNS,u'custom3'), + (TEXTNS,u'custom4'), + (TEXTNS,u'custom5'), + (TEXTNS,u'edition'), + (TEXTNS,u'editor'), + (TEXTNS,u'howpublished'), + (TEXTNS,u'identifier'), + (TEXTNS,u'institution'), + (TEXTNS,u'isbn'), + (TEXTNS,u'issn'), + (TEXTNS,u'journal'), + (TEXTNS,u'month'), + (TEXTNS,u'note'), + (TEXTNS,u'number'), + (TEXTNS,u'organizations'), + (TEXTNS,u'pages'), + (TEXTNS,u'publisher'), + (TEXTNS,u'report-type'), + (TEXTNS,u'school'), + (TEXTNS,u'series'), + (TEXTNS,u'title'), + (TEXTNS,u'url'), + (TEXTNS,u'volume'), + (TEXTNS,u'year'), + ), + (TEXTNS,u'bibliography-source'):( + ), + (TEXTNS,u'bookmark'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'bookmark-end'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'bookmark-ref'):( + (TEXTNS,u'ref-name'), + (TEXTNS,u'reference-format'), + ), + (TEXTNS,u'bookmark-start'):( + (TEXTNS,u'name'), + ), +# allowed_attributes + (TEXTNS,u'change'):( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'change-end'):( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'change-start'):( + (TEXTNS,u'change-id'), + ), + (TEXTNS,u'changed-region'):( + (TEXTNS,u'id'), + ), + (TEXTNS,u'chapter'):( + (TEXTNS,u'display'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'conditional-text'):( + (TEXTNS,u'string-value-if-true'), + (TEXTNS,u'current-value'), + (TEXTNS,u'string-value-if-false'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'creation-date'):( + (TEXTNS,u'date-value'), + (TEXTNS,u'fixed'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'creation-time'):( + (TEXTNS,u'fixed'), + (TEXTNS,u'time-value'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'creator'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'database-display'):( + (TEXTNS,u'column-name'), + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + (TEXTNS,u'database-name'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'database-name'):( + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + (TEXTNS,u'database-name'), + ), + (TEXTNS,u'database-next'):( + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + (TEXTNS,u'database-name'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'database-row-number'):( + (STYLENS,u'num-format'), + (TEXTNS,u'database-name'), + (TEXTNS,u'value'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + ), + (TEXTNS,u'database-row-select'):( + (TEXTNS,u'row-number'), + (TEXTNS,u'table-name'), + (TEXTNS,u'table-type'), + (TEXTNS,u'database-name'), + (TEXTNS,u'condition'), + ), +# allowed_attributes + (TEXTNS,u'date'):( + (TEXTNS,u'date-value'), + (TEXTNS,u'fixed'), + (TEXTNS,u'date-adjust'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'dde-connection'):( + (TEXTNS,u'connection-name'), + ), + (TEXTNS,u'dde-connection-decl'):( + (OFFICENS,u'automatic-update'), + (OFFICENS,u'dde-topic'), + (OFFICENS,u'dde-application'), + (OFFICENS,u'name'), + (OFFICENS,u'dde-item'), + ), + (TEXTNS,u'dde-connection-decls'):( + ), + (TEXTNS,u'deletion'):( + ), + (TEXTNS,u'description'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'editing-cycles'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'editing-duration'):( + (TEXTNS,u'duration'), + (TEXTNS,u'fixed'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'execute-macro'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'expression'):( + (TEXTNS,u'display'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (STYLENS,u'data-style-name'), + (OFFICENS,u'value-type'), + (TEXTNS,u'formula'), + (OFFICENS,u'time-value'), + ), + (TEXTNS,u'file-name'):( + (TEXTNS,u'fixed'), + (TEXTNS,u'display'), + ), +# allowed_attributes + (TEXTNS,u'format-change'):( + ), + (TEXTNS,u'h'):( + (TEXTNS,u'restart-numbering'), + (TEXTNS,u'cond-style-name'), + (TEXTNS,u'is-list-header'), + (TEXTNS,u'style-name'), + (TEXTNS,u'class-names'), + (TEXTNS,u'start-value'), + (TEXTNS,u'id'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'hidden-paragraph'):( + (TEXTNS,u'is-hidden'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'hidden-text'):( + (TEXTNS,u'string-value'), + (TEXTNS,u'is-hidden'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'illustration-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'illustration-index-entry-template'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'illustration-index-source'):( + (TEXTNS,u'index-scope'), + (TEXTNS,u'caption-sequence-name'), + (TEXTNS,u'use-caption'), + (TEXTNS,u'caption-sequence-format'), + (TEXTNS,u'relative-tab-stop-position'), + ), + (TEXTNS,u'index-body'):( + ), + (TEXTNS,u'index-entry-bibliography'):( + (TEXTNS,u'bibliography-data-field'), + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-chapter'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'display'), + ), +# allowed_attributes + (TEXTNS,u'index-entry-link-end'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-link-start'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-page-number'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-span'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-entry-tab-stop'):( + (STYLENS,u'position'), + (TEXTNS,u'style-name'), + (STYLENS,u'type'), + (STYLENS,u'leader-char'), + ), + (TEXTNS,u'index-entry-text'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-source-style'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'index-source-styles'):( + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'index-title'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'index-title-template'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'initial-creator'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'insertion'):( + ), +# allowed_attributes + (TEXTNS,u'keywords'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'line-break'):( + ), + (TEXTNS,u'linenumbering-configuration'):( + (TEXTNS,u'number-position'), + (TEXTNS,u'number-lines'), + (STYLENS,u'num-format'), + (TEXTNS,u'count-empty-lines'), + (TEXTNS,u'count-in-text-boxes'), + (TEXTNS,u'style-name'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'increment'), + (TEXTNS,u'offset'), + (TEXTNS,u'restart-on-page'), + ), + (TEXTNS,u'linenumbering-separator'):( + (TEXTNS,u'increment'), + ), + (TEXTNS,u'list'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'continue-numbering'), + ), + (TEXTNS,u'list-header'):( + ), + (TEXTNS,u'list-item'):( + (TEXTNS,u'start-value'), + ), + (TEXTNS,u'list-level-style-bullet'):( + (TEXTNS,u'level'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-suffix'), + (TEXTNS,u'bullet-relative-size'), + (TEXTNS,u'style-name'), + (TEXTNS,u'bullet-char'), + ), + (TEXTNS,u'list-level-style-image'):( + (XLINKNS,u'show'), + (XLINKNS,u'actuate'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (TEXTNS,u'level'), + ), + (TEXTNS,u'list-level-style-number'):( + (TEXTNS,u'level'), + (TEXTNS,u'display-levels'), + (STYLENS,u'num-format'), + (STYLENS,u'num-suffix'), + (TEXTNS,u'style-name'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'start-value'), + ), +# allowed_attributes + (TEXTNS,u'list-style'):( + (TEXTNS,u'consecutive-numbering'), + (STYLENS,u'display-name'), + (STYLENS,u'name'), + ), + (TEXTNS,u'measure'):( + (TEXTNS,u'kind'), + ), + (TEXTNS,u'modification-date'):( + (TEXTNS,u'date-value'), + (TEXTNS,u'fixed'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'modification-time'):( + (TEXTNS,u'fixed'), + (TEXTNS,u'time-value'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'note'):( + (TEXTNS,u'note-class'), + (TEXTNS,u'id'), + ), + (TEXTNS,u'note-body'):( + ), + (TEXTNS,u'note-citation'):( + (TEXTNS,u'label'), + ), + (TEXTNS,u'note-continuation-notice-backward'):( + ), + (TEXTNS,u'note-continuation-notice-forward'):( + ), + (TEXTNS,u'note-ref'):( + (TEXTNS,u'ref-name'), + (TEXTNS,u'note-class'), + (TEXTNS,u'reference-format'), + ), + (TEXTNS,u'notes-configuration'):( + (TEXTNS,u'citation-body-style-name'), + (STYLENS,u'num-format'), + (TEXTNS,u'default-style-name'), + (STYLENS,u'num-suffix'), + (TEXTNS,u'start-numbering-at'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'citation-style-name'), + (TEXTNS,u'footnotes-position'), + (TEXTNS,u'master-page-name'), + (TEXTNS,u'start-value'), + (TEXTNS,u'note-class'), + ), + (TEXTNS,u'number'):( + ), + (TEXTNS,u'numbered-paragraph'):( + (TEXTNS,u'continue-numbering'), + (TEXTNS,u'style-name'), + (TEXTNS,u'start-value'), + (TEXTNS,u'level'), + ), + (TEXTNS,u'object-count'):( + (STYLENS,u'num-format'), + (STYLENS,u'num-letter-sync'), + ), + (TEXTNS,u'object-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), +# allowed_attributes + (TEXTNS,u'object-index-entry-template'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'object-index-source'):( + (TEXTNS,u'use-draw-objects'), + (TEXTNS,u'use-math-objects'), + (TEXTNS,u'relative-tab-stop-position'), + (TEXTNS,u'use-chart-objects'), + (TEXTNS,u'index-scope'), + (TEXTNS,u'use-spreadsheet-objects'), + (TEXTNS,u'use-other-objects'), + ), + (TEXTNS,u'outline-level-style'):( + (TEXTNS,u'level'), + (TEXTNS,u'display-levels'), + (STYLENS,u'num-format'), + (STYLENS,u'num-suffix'), + (TEXTNS,u'style-name'), + (STYLENS,u'num-prefix'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'start-value'), + ), + (TEXTNS,u'outline-style'):( + ), + (TEXTNS,u'p'):( + (TEXTNS,u'cond-style-name'), + (TEXTNS,u'style-name'), + (TEXTNS,u'class-names'), + (TEXTNS,u'id'), + ), + (TEXTNS,u'page'):( + (TEXTNS,u'master-page-name'), + ), + (TEXTNS,u'page-continuation'):( + (TEXTNS,u'string-value'), + (TEXTNS,u'select-page'), + ), + (TEXTNS,u'page-number'):( + (TEXTNS,u'page-adjust'), + (STYLENS,u'num-format'), + (TEXTNS,u'fixed'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'select-page'), + ), + (TEXTNS,u'page-sequence'):( + ), + (TEXTNS,u'page-variable-get'):( + (STYLENS,u'num-format'), + (STYLENS,u'num-letter-sync'), + ), + (TEXTNS,u'page-variable-set'):( + (TEXTNS,u'active'), + (TEXTNS,u'page-adjust'), + ), + (TEXTNS,u'placeholder'):( + (TEXTNS,u'placeholder-type'), + (TEXTNS,u'description'), + ), + (TEXTNS,u'print-date'):( + (TEXTNS,u'date-value'), + (TEXTNS,u'fixed'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'print-time'):( + (TEXTNS,u'fixed'), + (TEXTNS,u'time-value'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'printed-by'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'reference-mark'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'reference-mark-end'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'reference-mark-start'):( + (TEXTNS,u'name'), + ), + (TEXTNS,u'ruby'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'ruby-base'):( + ), + (TEXTNS,u'ruby-text'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u's'):( + (TEXTNS,u'c'), + ), + (TEXTNS,u'script'):( + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (SCRIPTNS,u'language'), + ), + (TEXTNS,u'section'):( + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + (TEXTNS,u'style-name'), + (TEXTNS,u'protected'), + (TEXTNS,u'display'), + (TEXTNS,u'condition'), + ), + (TEXTNS,u'section-source'):( + (TEXTNS,u'filter-name'), + (XLINKNS,u'href'), + (XLINKNS,u'type'), + (TEXTNS,u'section-name'), + (XLINKNS,u'show'), + ), + (TEXTNS,u'sender-city'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-company'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-country'):( + (TEXTNS,u'fixed'), + ), +# allowed_attributes + (TEXTNS,u'sender-email'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-fax'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-firstname'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-initials'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-lastname'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-phone-private'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-phone-work'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-position'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-postal-code'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-state-or-province'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-street'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sender-title'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'sequence'):( + (TEXTNS,u'formula'), + (STYLENS,u'num-format'), + (STYLENS,u'num-letter-sync'), + (TEXTNS,u'name'), + (TEXTNS,u'ref-name'), + ), + (TEXTNS,u'sequence-decl'):( + (TEXTNS,u'separation-character'), + (TEXTNS,u'display-outline-level'), + (TEXTNS,u'name'), + ), + (TEXTNS,u'sequence-decls'):( + ), + (TEXTNS,u'sequence-ref'):( + (TEXTNS,u'ref-name'), + (TEXTNS,u'reference-format'), + ), + (TEXTNS,u'sheet-name'):( + ), + (TEXTNS,u'soft-page-break'):( + ), + (TEXTNS,u'sort-key'):( + (TEXTNS,u'sort-ascending'), + (TEXTNS,u'key'), + ), +# allowed_attributes + (TEXTNS,u'span'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'class-names'), + ), + (TEXTNS,u'subject'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'tab'):( + (TEXTNS,u'tab-ref'), + ), + (TEXTNS,u'table-formula'):( + (TEXTNS,u'formula'), + (STYLENS,u'data-style-name'), + (TEXTNS,u'display'), + ), + (TEXTNS,u'table-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'table-index-entry-template'):( + (TEXTNS,u'style-name'), + ), + (TEXTNS,u'table-index-source'):( + (TEXTNS,u'index-scope'), + (TEXTNS,u'caption-sequence-name'), + (TEXTNS,u'use-caption'), + (TEXTNS,u'caption-sequence-format'), + (TEXTNS,u'relative-tab-stop-position'), + ), +# allowed_attributes + (TEXTNS,u'table-of-content'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'table-of-content-entry-template'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'table-of-content-source'):( + (TEXTNS,u'index-scope'), + (TEXTNS,u'outline-level'), + (TEXTNS,u'relative-tab-stop-position'), + (TEXTNS,u'use-index-marks'), + (TEXTNS,u'use-outline-level'), + (TEXTNS,u'use-index-source-styles'), + ), + (TEXTNS,u'template-name'):( + (TEXTNS,u'display'), + ), + (TEXTNS,u'text-input'):( + (TEXTNS,u'description'), + ), + (TEXTNS,u'time'):( + (TEXTNS,u'time-adjust'), + (TEXTNS,u'fixed'), + (TEXTNS,u'time-value'), + (STYLENS,u'data-style-name'), + ), + (TEXTNS,u'title'):( + (TEXTNS,u'fixed'), + ), + (TEXTNS,u'toc-mark'):( + (TEXTNS,u'string-value'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'toc-mark-end'):( + (TEXTNS,u'id'), + ), + (TEXTNS,u'toc-mark-start'):( + (TEXTNS,u'id'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'tracked-changes'):( + (TEXTNS,u'track-changes'), + ), + (TEXTNS,u'user-defined'):( + (TEXTNS,u'name'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'date-value'), + (STYLENS,u'data-style-name'), + (TEXTNS,u'fixed'), + (OFFICENS,u'time-value'), + ), + (TEXTNS,u'user-field-decl'):( + (TEXTNS,u'name'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (OFFICENS,u'value-type'), + (TEXTNS,u'formula'), + (OFFICENS,u'time-value'), + ), + (TEXTNS,u'user-field-decls'):( + ), + (TEXTNS,u'user-field-get'):( + (STYLENS,u'data-style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'display'), + ), +# allowed_attributes + (TEXTNS,u'user-field-input'):( + (STYLENS,u'data-style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'description'), + ), + (TEXTNS,u'user-index'):( + (TEXTNS,u'protected'), + (TEXTNS,u'style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'protection-key'), + ), + (TEXTNS,u'user-index-entry-template'):( + (TEXTNS,u'style-name'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'user-index-mark'):( + (TEXTNS,u'index-name'), + (TEXTNS,u'string-value'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'user-index-mark-end'):( + (TEXTNS,u'id'), + (TEXTNS,u'outline-level'), + ), + (TEXTNS,u'user-index-mark-start'):( + (TEXTNS,u'index-name'), + (TEXTNS,u'id'), + (TEXTNS,u'outline-level'), + ), +# allowed_attributes + (TEXTNS,u'user-index-source'):( + (TEXTNS,u'copy-outline-levels'), + (TEXTNS,u'index-name'), + (TEXTNS,u'index-scope'), + (TEXTNS,u'relative-tab-stop-position'), + (TEXTNS,u'use-floating-frames'), + (TEXTNS,u'use-graphics'), + (TEXTNS,u'use-index-marks'), + (TEXTNS,u'use-objects'), + (TEXTNS,u'use-tables'), + ), + (TEXTNS,u'variable-decl'):( + (TEXTNS,u'name'), + (OFFICENS,u'value-type'), + ), + (TEXTNS,u'variable-decls'):( + ), + (TEXTNS,u'variable-get'):( + (STYLENS,u'data-style-name'), + (TEXTNS,u'name'), + (TEXTNS,u'display'), + ), + (TEXTNS,u'variable-input'):( + (STYLENS,u'data-style-name'), + (TEXTNS,u'display'), + (TEXTNS,u'name'), + (OFFICENS,u'value-type'), + (TEXTNS,u'description'), + ), + (TEXTNS,u'variable-set'):( + (TEXTNS,u'name'), + (TEXTNS,u'display'), + (OFFICENS,u'string-value'), + (OFFICENS,u'value'), + (OFFICENS,u'boolean-value'), + (OFFICENS,u'currency'), + (OFFICENS,u'date-value'), + (STYLENS,u'data-style-name'), + (OFFICENS,u'value-type'), + (TEXTNS,u'formula'), + (OFFICENS,u'time-value'), + ), +# allowed_attributes +}
Property changes on: trunk/pywikipedia/odf/grammar.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/load.py =================================================================== --- trunk/pywikipedia/odf/load.py (rev 0) +++ trunk/pywikipedia/odf/load.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,112 @@ +#!/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
Property changes on: trunk/pywikipedia/odf/load.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/manifest.py =================================================================== --- trunk/pywikipedia/odf/manifest.py (rev 0) +++ trunk/pywikipedia/odf/manifest.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,41 @@ +#!/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) +
Property changes on: trunk/pywikipedia/odf/manifest.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/math.py =================================================================== --- trunk/pywikipedia/odf/math.py (rev 0) +++ trunk/pywikipedia/odf/math.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import MATHNS +from element import Element + +# ODF 1.0 section 12.5 +# Mathematical content is represented by MathML 2.0 + +# Autogenerated +def Math(**args): + return Element(qname = (MATHNS,'math'), **args) +
Property changes on: trunk/pywikipedia/odf/math.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/meta.py =================================================================== --- trunk/pywikipedia/odf/meta.py (rev 0) +++ trunk/pywikipedia/odf/meta.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,66 @@ +# -*- 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) +
Property changes on: trunk/pywikipedia/odf/meta.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/namespaces.py =================================================================== --- trunk/pywikipedia/odf/namespaces.py (rev 0) +++ trunk/pywikipedia/odf/namespaces.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,107 @@ +# -*- 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.4" + +ANIMNS = u"urn:oasis:names:tc:opendocument:xmlns:animation:1.0" +CHARTNS = u"urn:oasis:names:tc:opendocument:xmlns:chart:1.0" +CHARTOOONS = u"http://openoffice.org/2010/chart" +CONFIGNS = u"urn:oasis:names:tc:opendocument:xmlns:config:1.0" +CSS3TNS = u"http://www.w3.org/TR/css3-text/" +#DBNS = u"http://openoffice.org/2004/database" +DBNS = u"urn:oasis:names:tc:opendocument:xmlns:database:1.0" +DCNS = u"http://purl.org/dc/elements/1.1/" +DOMNS = u"http://www.w3.org/2001/xml-events" +DR3DNS = u"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" +DRAWNS = u"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" +FIELDNS = u"urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" +FONS = u"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" +FORMNS = u"urn:oasis:names:tc:opendocument:xmlns:form:1.0" +FORMXNS = u"urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" +GRDDLNS = u"http://www.w3.org/2003/g/data-view#" +KOFFICENS = u"http://www.koffice.org/2005/" +MANIFESTNS = u"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" +MATHNS = u"http://www.w3.org/1998/Math/MathML" +METANS = u"urn:oasis:names:tc:opendocument:xmlns:meta:1.0" +NUMBERNS = u"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" +OFFICENS = u"urn:oasis:names:tc:opendocument:xmlns:office:1.0" +OFNS = u"urn:oasis:names:tc:opendocument:xmlns:of:1.2" +OOOCNS = u"http://openoffice.org/2004/calc" +OOONS = u"http://openoffice.org/2004/office" +OOOWNS = u"http://openoffice.org/2004/writer" +PRESENTATIONNS = u"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" +RDFANS = u"http://docs.oasis-open.org/opendocument/meta/rdfa#" +RPTNS = u"http://openoffice.org/2005/report" +SCRIPTNS = u"urn:oasis:names:tc:opendocument:xmlns:script:1.0" +SMILNS = u"urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" +STYLENS = u"urn:oasis:names:tc:opendocument:xmlns:style:1.0" +SVGNS = u"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" +TABLENS = u"urn:oasis:names:tc:opendocument:xmlns:table:1.0" +TABLEOOONS = u"http://openoffice.org/2009/table" +TEXTNS = u"urn:oasis:names:tc:opendocument:xmlns:text:1.0" +XFORMSNS = u"http://www.w3.org/2002/xforms" +XHTMLNS = u"http://www.w3.org/1999/xhtml" +XLINKNS = u"http://www.w3.org/1999/xlink" +XMLNS = u"http://www.w3.org/XML/1998/namespace" +XSDNS = u"http://www.w3.org/2001/XMLSchema" +XSINS = u"http://www.w3.org/2001/XMLSchema-instance" + +nsdict = { + ANIMNS: u'anim', + CHARTNS: u'chart', + CHARTOOONS: u'chartooo', + CONFIGNS: u'config', + CSS3TNS: u'css3t', + DBNS: u'db', + DCNS: u'dc', + DOMNS: u'dom', + DR3DNS: u'dr3d', + DRAWNS: u'draw', + FIELDNS: u'field', + FONS: u'fo', + FORMNS: u'form', + FORMXNS: u'formx', + GRDDLNS: u'grddl', + KOFFICENS: u'koffice', + MANIFESTNS: u'manifest', + MATHNS: u'math', + METANS: u'meta', + NUMBERNS: u'number', + OFFICENS: u'office', + OFNS: u'of', + OOONS: u'ooo', + OOOWNS: u'ooow', + OOOCNS: u'oooc', + PRESENTATIONNS: u'presentation', + RDFANS: u'rdfa', + RPTNS: u'rpt', + SCRIPTNS: u'script', + SMILNS: u'smil', + STYLENS: u'style', + SVGNS: u'svg', + TABLENS: u'table', + TABLEOOONS: u'tableooo', + TEXTNS: u'text', + XFORMSNS: u'xforms', + XLINKNS: u'xlink', + XHTMLNS: u'xhtml', + XMLNS: u'xml', + XSDNS: u'xsd', + XSINS: u'xsi', +}
Property changes on: trunk/pywikipedia/odf/namespaces.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/number.py =================================================================== --- trunk/pywikipedia/odf/number.py (rev 0) +++ trunk/pywikipedia/odf/number.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import NUMBERNS +from element import Element +from style import StyleElement + + +# Autogenerated +def AmPm(**args): + return Element(qname = (NUMBERNS,'am-pm'), **args) + +def Boolean(**args): + return Element(qname = (NUMBERNS,'boolean'), **args) + +def BooleanStyle(**args): + return StyleElement(qname = (NUMBERNS,'boolean-style'), **args) + +def CurrencyStyle(**args): + return StyleElement(qname = (NUMBERNS,'currency-style'), **args) + +def CurrencySymbol(**args): + return Element(qname = (NUMBERNS,'currency-symbol'), **args) + +def DateStyle(**args): + return StyleElement(qname = (NUMBERNS,'date-style'), **args) + +def Day(**args): + return Element(qname = (NUMBERNS,'day'), **args) + +def DayOfWeek(**args): + return Element(qname = (NUMBERNS,'day-of-week'), **args) + +def EmbeddedText(**args): + return Element(qname = (NUMBERNS,'embedded-text'), **args) + +def Era(**args): + return Element(qname = (NUMBERNS,'era'), **args) + +def Fraction(**args): + return Element(qname = (NUMBERNS,'fraction'), **args) + +def Hours(**args): + return Element(qname = (NUMBERNS,'hours'), **args) + +def Minutes(**args): + return Element(qname = (NUMBERNS,'minutes'), **args) + +def Month(**args): + return Element(qname = (NUMBERNS,'month'), **args) + +def Number(**args): + return Element(qname = (NUMBERNS,'number'), **args) + +def NumberStyle(**args): + return StyleElement(qname = (NUMBERNS,'number-style'), **args) + +def PercentageStyle(**args): + return StyleElement(qname = (NUMBERNS,'percentage-style'), **args) + +def Quarter(**args): + return Element(qname = (NUMBERNS,'quarter'), **args) + +def ScientificNumber(**args): + return Element(qname = (NUMBERNS,'scientific-number'), **args) + +def Seconds(**args): + return Element(qname = (NUMBERNS,'seconds'), **args) + +def Text(**args): + return Element(qname = (NUMBERNS,'text'), **args) + +def TextContent(**args): + return Element(qname = (NUMBERNS,'text-content'), **args) + +def TextStyle(**args): + return StyleElement(qname = (NUMBERNS,'text-style'), **args) + +def TimeStyle(**args): + return StyleElement(qname = (NUMBERNS,'time-style'), **args) + +def WeekOfYear(**args): + return Element(qname = (NUMBERNS,'week-of-year'), **args) + +def Year(**args): + return Element(qname = (NUMBERNS,'year'), **args) +
Property changes on: trunk/pywikipedia/odf/number.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/odf2moinmoin.py =================================================================== --- trunk/pywikipedia/odf/odf2moinmoin.py (rev 0) +++ trunk/pywikipedia/odf/odf2moinmoin.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,579 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2008 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# See http://trac.edgewall.org/wiki/WikiFormatting +# +# Contributor(s): +# + +import sys, zipfile, xml.dom.minidom +from namespaces import nsdict +from elementtypes import * + +IGNORED_TAGS = [ + 'draw:a' + 'draw:g', + 'draw:line', + 'draw:object-ole', + 'office:annotation', + 'presentation:notes', + 'svg:desc', +] + [ nsdict[item[0]]+":"+item[1] for item in empty_elements] + +INLINE_TAGS = [ nsdict[item[0]]+":"+item[1] for item in inline_elements] + + +class TextProps: + """ Holds properties for a text style. """ + + def __init__(self): + + self.italic = False + self.bold = False + self.fixed = False + self.underlined = False + self.strikethrough = False + self.superscript = False + self.subscript = False + + def setItalic(self, value): + if value == "italic": + self.italic = True + elif value == "normal": + self.italic = False + + def setBold(self, value): + if value == "bold": + self.bold = True + elif value == "normal": + self.bold = False + + def setFixed(self, value): + self.fixed = value + + def setUnderlined(self, value): + if value and value != "none": + self.underlined = True + + def setStrikethrough(self, value): + if value and value != "none": + self.strikethrough = True + + def setPosition(self, value): + if value is None or value == '': + return + posisize = value.split(' ') + textpos = posisize[0] + if textpos.find('%') == -1: + if textpos == "sub": + self.superscript = False + self.subscript = True + elif textpos == "super": + self.superscript = True + self.subscript = False + else: + itextpos = int(textpos[:textpos.find('%')]) + if itextpos > 10: + self.superscript = False + self.subscript = True + elif itextpos < -10: + self.superscript = True + self.subscript = False + + def __str__(self): + + return "[italic=%s, bold=i%s, fixed=%s]" % (str(self.italic), + str(self.bold), + str(self.fixed)) + +class ParagraphProps: + """ Holds properties of a paragraph style. """ + + def __init__(self): + + self.blockquote = False + self.headingLevel = 0 + self.code = False + self.title = False + self.indented = 0 + + def setIndented(self, value): + self.indented = value + + def setHeading(self, level): + self.headingLevel = level + + def setTitle(self, value): + self.title = value + + def setCode(self, value): + self.code = value + + + def __str__(self): + + return "[bq=%s, h=%d, code=%s]" % (str(self.blockquote), + self.headingLevel, + str(self.code)) + + +class ListProperties: + """ Holds properties for a list style. """ + + def __init__(self): + self.ordered = False + + def setOrdered(self, value): + self.ordered = value + + + +class ODF2MoinMoin(object): + + + def __init__(self, filepath): + self.footnotes = [] + self.footnoteCounter = 0 + self.textStyles = {"Standard": TextProps()} + self.paragraphStyles = {"Standard": ParagraphProps()} + self.listStyles = {} + self.fixedFonts = [] + self.hasTitle = 0 + self.lastsegment = None + + # Tags + self.elements = { + 'draw:page': self.textToString, + 'draw:frame': self.textToString, + 'draw:image': self.draw_image, + 'draw:text-box': self.textToString, + 'text:a': self.text_a, + 'text:note': self.text_note, + } + for tag in IGNORED_TAGS: + self.elements[tag] = self.do_nothing + + for tag in INLINE_TAGS: + self.elements[tag] = self.inline_markup + self.elements['text:line-break'] = self.text_line_break + self.elements['text:s'] = self.text_s + self.elements['text:tab'] = self.text_tab + + self.load(filepath) + + def processFontDeclarations(self, fontDecl): + """ Extracts necessary font information from a font-declaration + element. + """ + for fontFace in fontDecl.getElementsByTagName("style:font-face"): + if fontFace.getAttribute("style:font-pitch") == "fixed": + self.fixedFonts.append(fontFace.getAttribute("style:name")) + + + + def extractTextProperties(self, style, parent=None): + """ Extracts text properties from a style element. """ + + textProps = TextProps() + + if parent: + parentProp = self.textStyles.get(parent, None) + if parentProp: + textProp = parentProp + + textPropEl = style.getElementsByTagName("style:text-properties") + if not textPropEl: return textProps + + textPropEl = textPropEl[0] + + textProps.setItalic(textPropEl.getAttribute("fo:font-style")) + textProps.setBold(textPropEl.getAttribute("fo:font-weight")) + textProps.setUnderlined(textPropEl.getAttribute("style:text-underline-style")) + textProps.setStrikethrough(textPropEl.getAttribute("style:text-line-through-style")) + textProps.setPosition(textPropEl.getAttribute("style:text-position")) + + if textPropEl.getAttribute("style:font-name") in self.fixedFonts: + textProps.setFixed(True) + + return textProps + + def extractParagraphProperties(self, style, parent=None): + """ Extracts paragraph properties from a style element. """ + + paraProps = ParagraphProps() + + name = style.getAttribute("style:name") + + if name.startswith("Heading_20_"): + level = name[11:] + try: + level = int(level) + paraProps.setHeading(level) + except: + level = 0 + + if name == "Title": + paraProps.setTitle(True) + + paraPropEl = style.getElementsByTagName("style:paragraph-properties") + if paraPropEl: + paraPropEl = paraPropEl[0] + leftMargin = paraPropEl.getAttribute("fo:margin-left") + if leftMargin: + try: + leftMargin = float(leftMargin[:-2]) + if leftMargin > 0.01: + paraProps.setIndented(True) + except: + pass + + textProps = self.extractTextProperties(style) + if textProps.fixed: + paraProps.setCode(True) + + return paraProps + + + def processStyles(self, styleElements): + """ Runs through "style" elements extracting necessary information. + """ + + for style in styleElements: + + name = style.getAttribute("style:name") + + if name == "Standard": continue + + family = style.getAttribute("style:family") + parent = style.getAttribute("style:parent-style-name") + + if family == "text": + self.textStyles[name] = self.extractTextProperties(style, parent) + + elif family == "paragraph": + self.paragraphStyles[name] = \ + self.extractParagraphProperties(style, parent) + self.textStyles[name] = self.extractTextProperties(style, parent) + + def processListStyles(self, listStyleElements): + + for style in listStyleElements: + name = style.getAttribute("style:name") + + prop = ListProperties() + if style.hasChildNodes(): + subitems = [el for el in style.childNodes + if el.nodeType == xml.dom.Node.ELEMENT_NODE + and el.tagName == "text:list-level-style-number"] + if len(subitems) > 0: + prop.setOrdered(True) + + self.listStyles[name] = prop + + + def load(self, filepath): + """ Loads an ODT file. """ + + zip = zipfile.ZipFile(filepath) + + styles_doc = xml.dom.minidom.parseString(zip.read("styles.xml")) + fontfacedecls = styles_doc.getElementsByTagName("office:font-face-decls") + if fontfacedecls: + self.processFontDeclarations(fontfacedecls[0]) + self.processStyles(styles_doc.getElementsByTagName("style:style")) + self.processListStyles(styles_doc.getElementsByTagName("text:list-style")) + + self.content = xml.dom.minidom.parseString(zip.read("content.xml")) + fontfacedecls = self.content.getElementsByTagName("office:font-face-decls") + if fontfacedecls: + self.processFontDeclarations(fontfacedecls[0]) + + self.processStyles(self.content.getElementsByTagName("style:style")) + self.processListStyles(self.content.getElementsByTagName("text:list-style")) + + def compressCodeBlocks(self, text): + """ Removes extra blank lines from code blocks. """ + + return text + lines = text.split("\n") + buffer = [] + numLines = len(lines) + for i in range(numLines): + + if (lines[i].strip() or i == numLines-1 or i == 0 or + not ( lines[i-1].startswith(" ") + and lines[i+1].startswith(" ") ) ): + buffer.append("\n" + lines[i]) + + return ''.join(buffer) + +#----------------------------------- + def do_nothing(self, node): + return '' + + def draw_image(self, node): + """ + """ + + link = node.getAttribute("xlink:href") + if link and link[:2] == './': # Indicates a sub-object, which isn't supported + return "%s\n" % link + if link and link[:9] == 'Pictures/': + link = link[9:] + return "[[Image(%s)]]\n" % link + + def text_a(self, node): + text = self.textToString(node) + link = node.getAttribute("xlink:href") + if link.strip() == text.strip(): + return "[%s] " % link.strip() + else: + return "[%s %s] " % (link.strip(), text.strip()) + + + def text_line_break(self, node): + return "[[BR]]" + + def text_note(self, node): + cite = (node.getElementsByTagName("text:note-citation")[0] + .childNodes[0].nodeValue) + body = (node.getElementsByTagName("text:note-body")[0] + .childNodes[0]) + self.footnotes.append((cite, self.textToString(body))) + return "^%s^" % cite + + def text_s(self, node): + try: + num = int(node.getAttribute("text:c")) + return " "*num + except: + return " " + + def text_tab(self, node): + return " " + + def inline_markup(self, node): + text = self.textToString(node) + + if not text.strip(): + return '' # don't apply styles to white space + + styleName = node.getAttribute("text:style-name") + style = self.textStyles.get(styleName, TextProps()) + + if style.fixed: + return "`" + text + "`" + + mark = [] + if style: + if style.italic: + mark.append("''") + if style.bold: + mark.append("'''") + if style.underlined: + mark.append("__") + if style.strikethrough: + mark.append("~~") + if style.superscript: + mark.append("^") + if style.subscript: + mark.append(",,") + revmark = mark[:] + revmark.reverse() + return "%s%s%s" % (''.join(mark), text, ''.join(revmark)) + +#----------------------------------- + def listToString(self, listElement, indent = 0): + + self.lastsegment = listElement.tagName + buffer = [] + + styleName = listElement.getAttribute("text:style-name") + props = self.listStyles.get(styleName, ListProperties()) + + i = 0 + for item in listElement.childNodes: + buffer.append(" "*indent) + i += 1 + if props.ordered: + number = str(i) + number = " " + number + ". " + buffer.append(" 1. ") + else: + buffer.append(" * ") + subitems = [el for el in item.childNodes + if el.tagName in ["text:p", "text:h", "text:list"]] + for subitem in subitems: + if subitem.tagName == "text:list": + buffer.append("\n") + buffer.append(self.listToString(subitem, indent+3)) + else: + buffer.append(self.paragraphToString(subitem, indent+3)) + self.lastsegment = subitem.tagName + self.lastsegment = item.tagName + buffer.append("\n") + + return ''.join(buffer) + + def tableToString(self, tableElement): + """ MoinMoin uses || to delimit table cells + """ + + self.lastsegment = tableElement.tagName + buffer = [] + + for item in tableElement.childNodes: + self.lastsegment = item.tagName + if item.tagName == "table:table-header-rows": + buffer.append(self.tableToString(item)) + if item.tagName == "table:table-row": + buffer.append("\n||") + for cell in item.childNodes: + buffer.append(self.inline_markup(cell)) + buffer.append("||") + self.lastsegment = cell.tagName + return ''.join(buffer) + + + def toString(self): + """ Converts the document to a string. + FIXME: Result from second call differs from first call + """ + body = self.content.getElementsByTagName("office:body")[0] + text = body.childNodes[0] + + buffer = [] + + paragraphs = [el for el in text.childNodes + if el.tagName in ["draw:page", "text:p", "text:h","text:section", + "text:list", "table:table"]] + + for paragraph in paragraphs: + if paragraph.tagName == "text:list": + text = self.listToString(paragraph) + elif paragraph.tagName == "text:section": + text = self.textToString(paragraph) + elif paragraph.tagName == "table:table": + text = self.tableToString(paragraph) + else: + text = self.paragraphToString(paragraph) + if text: + buffer.append(text) + + if self.footnotes: + + buffer.append("----") + for cite, body in self.footnotes: + buffer.append("%s: %s" % (cite, body)) + + + buffer.append("") + return self.compressCodeBlocks('\n'.join(buffer)) + + + def textToString(self, element): + + buffer = [] + + for node in element.childNodes: + + if node.nodeType == xml.dom.Node.TEXT_NODE: + buffer.append(node.nodeValue) + + elif node.nodeType == xml.dom.Node.ELEMENT_NODE: + tag = node.tagName + + if tag in ("draw:text-box", "draw:frame"): + buffer.append(self.textToString(node)) + + elif tag in ("text:p", "text:h"): + text = self.paragraphToString(node) + if text: + buffer.append(text) + elif tag == "text:list": + buffer.append(self.listToString(node)) + else: + method = self.elements.get(tag) + if method: + buffer.append(method(node)) + else: + buffer.append(" {" + tag + "} ") + + return ''.join(buffer) + + def paragraphToString(self, paragraph, indent = 0): + + dummyParaProps = ParagraphProps() + + style_name = paragraph.getAttribute("text:style-name") + paraProps = self.paragraphStyles.get(style_name, dummyParaProps) + text = self.inline_markup(paragraph) + + if paraProps and not paraProps.code: + text = text.strip() + + if paragraph.tagName == "text:p" and self.lastsegment == "text:p": + text = "\n" + text + + self.lastsegment = paragraph.tagName + + if paraProps.title: + self.hasTitle = 1 + return "= " + text + " =\n" + + outlinelevel = paragraph.getAttribute("text:outline-level") + if outlinelevel: + + level = int(outlinelevel) + if self.hasTitle: level += 1 + + if level >= 1: + return "=" * level + " " + text + " " + "=" * level + "\n" + + elif paraProps.code: + return "{{{\n" + text + "\n}}}\n" + + if paraProps.indented: + return self.wrapParagraph(text, indent = indent, blockquote = True) + + else: + return self.wrapParagraph(text, indent = indent) + + + def wrapParagraph(self, text, indent = 0, blockquote=False): + + counter = 0 + buffer = [] + LIMIT = 50 + + if blockquote: + buffer.append(" ") + + return ''.join(buffer) + text + # Unused from here + for token in text.split(): + + if counter > LIMIT - indent: + buffer.append("\n" + " "*indent) + if blockquote: + buffer.append(" ") + counter = 0 + + buffer.append(token + " ") + counter += len(token) + + return ''.join(buffer)
Property changes on: trunk/pywikipedia/odf/odf2moinmoin.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/odf2xhtml.py =================================================================== --- trunk/pywikipedia/odf/odf2xhtml.py (rev 0) +++ trunk/pywikipedia/odf/odf2xhtml.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,1582 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2010 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# +#import pdb +#pdb.set_trace() +from xml.sax import handler +from xml.sax.saxutils import escape, quoteattr +from xml.dom import Node + +from opendocument import load + +from namespaces import ANIMNS, CHARTNS, CONFIGNS, DCNS, DR3DNS, DRAWNS, FONS, \ + FORMNS, MATHNS, METANS, NUMBERNS, OFFICENS, PRESENTATIONNS, SCRIPTNS, \ + SMILNS, STYLENS, SVGNS, TABLENS, TEXTNS, XLINKNS + +# Handling of styles +# +# First there are font face declarations. These set up a font style that will be +# referenced from a text-property. The declaration describes the font making +# it possible for the application to find a similar font should the system not +# have that particular one. The StyleToCSS stores these attributes to be used +# for the CSS2 font declaration. +# +# Then there are default-styles. These set defaults for various style types: +# "text", "paragraph", "section", "ruby", "table", "table-column", "table-row", +# "table-cell", "graphic", "presentation", "drawing-page", "chart". +# Since CSS2 can't refer to another style, ODF2XHTML add these to all +# styles unless overridden. +# +# The real styles are declared in the style:style element. They have a +# family referring to the default-styles, and may have a parent style. +# +# Styles have scope. The same name can be used for both paragraph and +# character etc. styles Since CSS2 has no scope we use a prefix. (Not elegant) +# In ODF a style can have a parent, these parents can be chained. + +class StyleToCSS: + """ The purpose of the StyleToCSS class is to contain the rules to convert + ODF styles to CSS2. Since it needs the generic fonts, it would probably + make sense to also contain the Styles in a dict as well.. + """ + + def __init__(self): + # Font declarations + self.fontdict = {} + + # Fill-images from presentations for backgrounds + self.fillimages = {} + + self.ruleconversions = { + (DRAWNS,u'fill-image-name'): self.c_drawfillimage, + (FONS,u"background-color"): self.c_fo, + (FONS,u"border"): self.c_fo, + (FONS,u"border-bottom"): self.c_fo, + (FONS,u"border-left"): self.c_fo, + (FONS,u"border-right"): self.c_fo, + (FONS,u"border-top"): self.c_fo, + (FONS,u"color"): self.c_fo, + (FONS,u"font-family"): self.c_fo, + (FONS,u"font-size"): self.c_fo, + (FONS,u"font-style"): self.c_fo, + (FONS,u"font-variant"): self.c_fo, + (FONS,u"font-weight"): self.c_fo, + (FONS,u"line-height"): self.c_fo, + (FONS,u"margin"): self.c_fo, + (FONS,u"margin-bottom"): self.c_fo, + (FONS,u"margin-left"): self.c_fo, + (FONS,u"margin-right"): self.c_fo, + (FONS,u"margin-top"): self.c_fo, + (FONS,u"min-height"): self.c_fo, + (FONS,u"padding"): self.c_fo, + (FONS,u"padding-bottom"): self.c_fo, + (FONS,u"padding-left"): self.c_fo, + (FONS,u"padding-right"): self.c_fo, + (FONS,u"padding-top"): self.c_fo, + (FONS,u"page-width"): self.c_page_width, + (FONS,u"page-height"): self.c_page_height, + (FONS,u"text-align"): self.c_text_align, + (FONS,u"text-indent") :self.c_fo, + (TABLENS,u'border-model') :self.c_border_model, + (STYLENS,u'column-width') : self.c_width, + (STYLENS,u"font-name"): self.c_fn, + (STYLENS,u'horizontal-pos'): self.c_hp, + (STYLENS,u'text-position'): self.c_text_position, + (STYLENS,u'text-line-through-style'): self.c_text_line_through_style, + (STYLENS,u'text-underline-style'): self.c_text_underline_style, + (STYLENS,u'width') : self.c_width, + # FIXME Should do style:vertical-pos here + } + + def save_font(self, name, family, generic): + """ It is possible that the HTML browser doesn't know how to + show a particular font. Fortunately ODF provides generic fallbacks. + Unfortunately they are not the same as CSS2. + CSS2: serif, sans-serif, cursive, fantasy, monospace + ODF: roman, swiss, modern, decorative, script, system + This method put the font and fallback into a dictionary + """ + htmlgeneric = "sans-serif" + if generic == "roman": htmlgeneric = "serif" + elif generic == "swiss": htmlgeneric = "sans-serif" + elif generic == "modern": htmlgeneric = "monospace" + elif generic == "decorative": htmlgeneric = "sans-serif" + elif generic == "script": htmlgeneric = "monospace" + elif generic == "system": htmlgeneric = "serif" + self.fontdict[name] = (family, htmlgeneric) + + def c_drawfillimage(self, ruleset, sdict, rule, val): + """ Fill a figure with an image. Since CSS doesn't let you resize images + this should really be implemented as an absolutely position <img> + with a width and a height + """ + sdict['background-image'] = "url('%s')" % self.fillimages[val] + + def c_fo(self, ruleset, sdict, rule, val): + """ XSL formatting attributes """ + selector = rule[1] + sdict[selector] = val + + def c_border_model(self, ruleset, sdict, rule, val): + """ Convert to CSS2 border model """ + if val == 'collapsing': + sdict['border-collapse'] ='collapse' + else: + sdict['border-collapse'] ='separate' + + def c_width(self, ruleset, sdict, rule, val): + """ Set width of box """ + sdict['width'] = val + + def c_text_align(self, ruleset, sdict, rule, align): + """ Text align """ + if align == "start": align = "left" + if align == "end": align = "right" + sdict['text-align'] = align + + def c_fn(self, ruleset, sdict, rule, fontstyle): + """ Generate the CSS font family + A generic font can be found in two ways. In a style:font-face + element or as a font-family-generic attribute in text-properties. + """ + generic = ruleset.get((STYLENS,'font-family-generic') ) + if generic is not None: + self.save_font(fontstyle, fontstyle, generic) + family, htmlgeneric = self.fontdict.get(fontstyle, (fontstyle, 'serif')) + sdict['font-family'] = '%s, %s' % (family, htmlgeneric) + + def c_text_position(self, ruleset, sdict, rule, tp): + """ Text position. This is used e.g. to make superscript and subscript + This attribute can have one or two values. + + The first value must be present and specifies the vertical + text position as a percentage that relates to the current font + height or it takes one of the values sub or super. Negative + percentages or the sub value place the text below the + baseline. Positive percentages or the super value place + the text above the baseline. If sub or super is specified, + the application can choose an appropriate text position. + + The second value is optional and specifies the font height + as a percentage that relates to the current font-height. If + this value is not specified, an appropriate font height is + used. Although this value may change the font height that + is displayed, it never changes the current font height that + is used for additional calculations. + """ + textpos = tp.split(' ') + if len(textpos) == 2 and textpos[0] != "0%": + # Bug in OpenOffice. If vertical-align is 0% - ignore the text size. + sdict['font-size'] = textpos[1] + if textpos[0] == "super": + sdict['vertical-align'] = "33%" + elif textpos[0] == "sub": + sdict['vertical-align'] = "-33%" + else: + sdict['vertical-align'] = textpos[0] + + def c_hp(self, ruleset, sdict, rule, hpos): + #FIXME: Frames wrap-style defaults to 'parallel', graphics to 'none'. + # It is properly set in the parent-styles, but the program doesn't + # collect the information. + wrap = ruleset.get((STYLENS,'wrap'),'parallel') + # Can have: from-left, left, center, right, from-inside, inside, outside + if hpos == "center": + sdict['margin-left'] = "auto" + sdict['margin-right'] = "auto" +# else: +# # force it to be *something* then delete it +# sdict['margin-left'] = sdict['margin-right'] = '' +# del sdict['margin-left'], sdict['margin-right'] + + if hpos in ("right","outside"): + if wrap in ( "left", "parallel","dynamic"): + sdict['float'] = "right" + elif wrap == "run-through": + sdict['position'] = "absolute" # Simulate run-through + sdict['top'] = "0" + sdict['right'] = "0"; + else: # No wrapping + sdict['margin-left'] = "auto" + sdict['margin-right'] = "0px" + elif hpos in ("left", "inside"): + if wrap in ( "right", "parallel","dynamic"): + sdict['float'] = "left" + elif wrap == "run-through": + sdict['position'] = "absolute" # Simulate run-through + sdict['top'] = "0" + sdict['left'] = "0" + else: # No wrapping + sdict['margin-left'] = "0px" + sdict['margin-right'] = "auto" + elif hpos in ("from-left", "from-inside"): + if wrap in ( "right", "parallel"): + sdict['float'] = "left" + else: + sdict['position'] = "relative" # No wrapping + if ruleset.has_key( (SVGNS,'x') ): + sdict['left'] = ruleset[(SVGNS,'x')] + + def c_page_width(self, ruleset, sdict, rule, val): + """ Set width of box + HTML doesn't really have a page-width. It is always 100% of the browser width + """ + sdict['width'] = val + + def c_text_underline_style(self, ruleset, sdict, rule, val): + """ Set underline decoration + HTML doesn't really have a page-width. It is always 100% of the browser width + """ + if val and val != "none": + sdict['text-decoration'] = "underline" + + def c_text_line_through_style(self, ruleset, sdict, rule, val): + """ Set underline decoration + HTML doesn't really have a page-width. It is always 100% of the browser width + """ + if val and val != "none": + sdict['text-decoration'] = "line-through" + + def c_page_height(self, ruleset, sdict, rule, val): + """ Set height of box """ + sdict['height'] = val + + def convert_styles(self, ruleset): + """ Rule is a tuple of (namespace, name). If the namespace is '' then + it is already CSS2 + """ + sdict = {} + for rule,val in ruleset.items(): + if rule[0] == '': + sdict[rule[1]] = val + continue + method = self.ruleconversions.get(rule, None ) + if method: + method(ruleset, sdict, rule, val) + return sdict + + +class TagStack: + def __init__(self): + self.stack = [] + + def push(self, tag, attrs): + self.stack.append( (tag, attrs) ) + + def pop(self): + item = self.stack.pop() + return item + + def stackparent(self): + item = self.stack[-1] + return item[1] + + def rfindattr(self, attr): + """ Find a tag with the given attribute """ + for tag, attrs in self.stack: + if attrs.has_key(attr): + return attrs[attr] + return None + def count_tags(self, tag): + c = 0 + for ttag, tattrs in self.stack: + if ttag == tag: c = c + 1 + return c + +special_styles = { + 'S-Emphasis':'em', + 'S-Citation':'cite', + 'S-Strong_20_Emphasis':'strong', + 'S-Variable':'var', + 'S-Definition':'dfn', + 'S-Teletype':'tt', + 'P-Heading_20_1':'h1', + 'P-Heading_20_2':'h2', + 'P-Heading_20_3':'h3', + 'P-Heading_20_4':'h4', + 'P-Heading_20_5':'h5', + 'P-Heading_20_6':'h6', +# 'P-Caption':'caption', + 'P-Addressee':'address', +# 'P-List_20_Heading':'dt', +# 'P-List_20_Contents':'dd', + 'P-Preformatted_20_Text':'pre', +# 'P-Table_20_Heading':'th', +# 'P-Table_20_Contents':'td', +# 'P-Text_20_body':'p' +} + +#----------------------------------------------------------------------------- +# +# ODFCONTENTHANDLER +# +#----------------------------------------------------------------------------- +class ODF2XHTML(handler.ContentHandler): + """ The ODF2XHTML parses an ODF file and produces XHTML""" + + def __init__(self, generate_css=True, embedable=False): + # Tags + self.generate_css = generate_css + self.elements = { + (DCNS, 'title'): (self.s_processcont, self.e_dc_title), + (DCNS, 'language'): (self.s_processcont, self.e_dc_contentlanguage), + (DCNS, 'creator'): (self.s_processcont, self.e_dc_creator), + (DCNS, 'description'): (self.s_processcont, self.e_dc_metatag), + (DCNS, 'date'): (self.s_processcont, self.e_dc_metatag), + (DRAWNS, 'custom-shape'): (self.s_custom_shape, self.e_custom_shape), + (DRAWNS, 'frame'): (self.s_draw_frame, self.e_draw_frame), + (DRAWNS, 'image'): (self.s_draw_image, None), + (DRAWNS, 'fill-image'): (self.s_draw_fill_image, None), + (DRAWNS, "layer-set"):(self.s_ignorexml, None), + (DRAWNS, 'object'): (self.s_draw_object, None), + (DRAWNS, 'object-ole'): (self.s_draw_object_ole, None), + (DRAWNS, 'page'): (self.s_draw_page, self.e_draw_page), + (DRAWNS, 'text-box'): (self.s_draw_textbox, self.e_draw_textbox), + (METANS, 'creation-date'):(self.s_processcont, self.e_dc_metatag), + (METANS, 'generator'):(self.s_processcont, self.e_dc_metatag), + (METANS, 'initial-creator'): (self.s_processcont, self.e_dc_metatag), + (METANS, 'keyword'): (self.s_processcont, self.e_dc_metatag), + (NUMBERNS, "boolean-style"):(self.s_ignorexml, None), + (NUMBERNS, "currency-style"):(self.s_ignorexml, None), + (NUMBERNS, "date-style"):(self.s_ignorexml, None), + (NUMBERNS, "number-style"):(self.s_ignorexml, None), + (NUMBERNS, "text-style"):(self.s_ignorexml, None), + (OFFICENS, "annotation"):(self.s_ignorexml, None), + (OFFICENS, "automatic-styles"):(self.s_office_automatic_styles, None), + (OFFICENS, "document"):(self.s_office_document_content, self.e_office_document_content), + (OFFICENS, "document-content"):(self.s_office_document_content, self.e_office_document_content), + (OFFICENS, "forms"):(self.s_ignorexml, None), + (OFFICENS, "master-styles"):(self.s_office_master_styles, None), + (OFFICENS, "meta"):(self.s_ignorecont, None), + (OFFICENS, "presentation"):(self.s_office_presentation, self.e_office_presentation), + (OFFICENS, "spreadsheet"):(self.s_office_spreadsheet, self.e_office_spreadsheet), + (OFFICENS, "styles"):(self.s_office_styles, None), + (OFFICENS, "text"):(self.s_office_text, self.e_office_text), + (OFFICENS, "scripts"):(self.s_ignorexml, None), + (OFFICENS, "settings"):(self.s_ignorexml, None), + (PRESENTATIONNS, "notes"):(self.s_ignorexml, None), +# (STYLENS, "default-page-layout"):(self.s_style_default_page_layout, self.e_style_page_layout), + (STYLENS, "default-page-layout"):(self.s_ignorexml, None), + (STYLENS, "default-style"):(self.s_style_default_style, self.e_style_default_style), + (STYLENS, "drawing-page-properties"):(self.s_style_handle_properties, None), + (STYLENS, "font-face"):(self.s_style_font_face, None), +# (STYLENS, "footer"):(self.s_style_footer, self.e_style_footer), +# (STYLENS, "footer-style"):(self.s_style_footer_style, None), + (STYLENS, "graphic-properties"):(self.s_style_handle_properties, None), + (STYLENS, "handout-master"):(self.s_ignorexml, None), +# (STYLENS, "header"):(self.s_style_header, self.e_style_header), +# (STYLENS, "header-footer-properties"):(self.s_style_handle_properties, None), +# (STYLENS, "header-style"):(self.s_style_header_style, None), + (STYLENS, "master-page"):(self.s_style_master_page, None), + (STYLENS, "page-layout-properties"):(self.s_style_handle_properties, None), + (STYLENS, "page-layout"):(self.s_style_page_layout, self.e_style_page_layout), +# (STYLENS, "page-layout"):(self.s_ignorexml, None), + (STYLENS, "paragraph-properties"):(self.s_style_handle_properties, None), + (STYLENS, "style"):(self.s_style_style, self.e_style_style), + (STYLENS, "table-cell-properties"):(self.s_style_handle_properties, None), + (STYLENS, "table-column-properties"):(self.s_style_handle_properties, None), + (STYLENS, "table-properties"):(self.s_style_handle_properties, None), + (STYLENS, "text-properties"):(self.s_style_handle_properties, None), + (SVGNS, 'desc'): (self.s_ignorexml, None), + (TABLENS, 'covered-table-cell'): (self.s_ignorexml, None), + (TABLENS, 'table-cell'): (self.s_table_table_cell, self.e_table_table_cell), + (TABLENS, 'table-column'): (self.s_table_table_column, None), + (TABLENS, 'table-row'): (self.s_table_table_row, self.e_table_table_row), + (TABLENS, 'table'): (self.s_table_table, self.e_table_table), + (TEXTNS, 'a'): (self.s_text_a, self.e_text_a), + (TEXTNS, "alphabetical-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "bibliography-configuration"):(self.s_ignorexml, None), + (TEXTNS, "bibliography-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, 'bookmark'): (self.s_text_bookmark, None), + (TEXTNS, 'bookmark-start'): (self.s_text_bookmark, None), + (TEXTNS, 'bookmark-ref'): (self.s_text_bookmark_ref, self.e_text_a), + (TEXTNS, 'bookmark-ref-start'): (self.s_text_bookmark_ref, None), + (TEXTNS, 'h'): (self.s_text_h, self.e_text_h), + (TEXTNS, "illustration-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, 'line-break'):(self.s_text_line_break, None), + (TEXTNS, "linenumbering-configuration"):(self.s_ignorexml, None), + (TEXTNS, "list"):(self.s_text_list, self.e_text_list), + (TEXTNS, "list-item"):(self.s_text_list_item, self.e_text_list_item), + (TEXTNS, "list-level-style-bullet"):(self.s_text_list_level_style_bullet, self.e_text_list_level_style_bullet), + (TEXTNS, "list-level-style-number"):(self.s_text_list_level_style_number, self.e_text_list_level_style_number), + (TEXTNS, "list-style"):(None, None), + (TEXTNS, "note"):(self.s_text_note, None), + (TEXTNS, "note-body"):(self.s_text_note_body, self.e_text_note_body), + (TEXTNS, "note-citation"):(None, self.e_text_note_citation), + (TEXTNS, "notes-configuration"):(self.s_ignorexml, None), + (TEXTNS, "object-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, 'p'): (self.s_text_p, self.e_text_p), + (TEXTNS, 's'): (self.s_text_s, None), + (TEXTNS, 'span'): (self.s_text_span, self.e_text_span), + (TEXTNS, 'tab'): (self.s_text_tab, None), + (TEXTNS, "table-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "table-of-content-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "user-index-source"):(self.s_text_x_source, self.e_text_x_source), + } + if embedable: + self.make_embedable() + self._resetobject() + + def set_plain(self): + """ Tell the parser to not generate CSS """ + self.generate_css = False + + def set_embedable(self): + """ Tells the converter to only output the parts inside the <body>""" + self.elements[(OFFICENS, u"text")] = (None,None) + self.elements[(OFFICENS, u"spreadsheet")] = (None,None) + self.elements[(OFFICENS, u"presentation")] = (None,None) + self.elements[(OFFICENS, u"document-content")] = (None,None) + + + def add_style_file(self, stylefilename, media=None): + """ Add a link to an external style file. + Also turns of the embedding of styles in the HTML + """ + self.use_internal_css = False + self.stylefilename = stylefilename + if media: + self.metatags.append('<link rel="stylesheet" type="text/css" href="%s" media="%s"/>\n' % (stylefilename,media)) + else: + self.metatags.append('<link rel="stylesheet" type="text/css" href="%s"/>\n' % (stylefilename)) + + def _resetfootnotes(self): + # Footnotes and endnotes + self.notedict = {} + self.currentnote = 0 + self.notebody = '' + + def _resetobject(self): + self.lines = [] + self._wfunc = self._wlines + self.xmlfile = '' + self.title = '' + self.language = '' + self.creator = '' + self.data = [] + self.tagstack = TagStack() + self.htmlstack = [] + self.pstack = [] + self.processelem = True + self.processcont = True + self.listtypes = {} + self.headinglevels = [0, 0,0,0,0,0, 0,0,0,0,0] # level 0 to 10 + self.use_internal_css = True + self.cs = StyleToCSS() + self.anchors = {} + + # Style declarations + self.stylestack = [] + self.styledict = {} + self.currentstyle = None + + self._resetfootnotes() + + # Tags from meta.xml + self.metatags = [] + + + def writeout(self, s): + if s != '': + self._wfunc(s) + + def writedata(self): + d = ''.join(self.data) + if d != '': + self.writeout(escape(d)) + + def opentag(self, tag, attrs={}, block=False): + """ Create an open HTML tag """ + self.htmlstack.append((tag,attrs,block)) + a = [] + for key,val in attrs.items(): + a.append('''%s=%s''' % (key, quoteattr(val))) + if len(a) == 0: + self.writeout("<%s>" % tag) + else: + self.writeout("<%s %s>" % (tag, " ".join(a))) + if block == True: + self.writeout("\n") + + def closetag(self, tag, block=True): + """ Close an open HTML tag """ + self.htmlstack.pop() + self.writeout("</%s>" % tag) + if block == True: + self.writeout("\n") + + def emptytag(self, tag, attrs={}): + a = [] + for key,val in attrs.items(): + a.append('''%s=%s''' % (key, quoteattr(val))) + self.writeout("<%s %s/>\n" % (tag, " ".join(a))) + +#-------------------------------------------------- +# Interface to parser +#-------------------------------------------------- + def characters(self, data): + if self.processelem and self.processcont: + self.data.append(data) + + def startElementNS(self, tag, qname, attrs): + self.pstack.append( (self.processelem, self.processcont) ) + if self.processelem: + method = self.elements.get(tag, (None, None) )[0] + if method: + self.handle_starttag(tag, method, attrs) + else: + self.unknown_starttag(tag,attrs) + self.tagstack.push( tag, attrs ) + + def endElementNS(self, tag, qname): + stag, attrs = self.tagstack.pop() + if self.processelem: + method = self.elements.get(tag, (None, None) )[1] + if method: + self.handle_endtag(tag, attrs, method) + else: + self.unknown_endtag(tag, attrs) + self.processelem, self.processcont = self.pstack.pop() + +#-------------------------------------------------- + def handle_starttag(self, tag, method, attrs): + method(tag,attrs) + + def handle_endtag(self, tag, attrs, method): + method(tag, attrs) + + def unknown_starttag(self, tag, attrs): + pass + + def unknown_endtag(self, tag, attrs): + pass + + def s_ignorexml(self, tag, attrs): + """ Ignore this xml element and all children of it + It will automatically stop ignoring + """ + self.processelem = False + + def s_ignorecont(self, tag, attrs): + """ Stop processing the text nodes """ + self.processcont = False + + def s_processcont(self, tag, attrs): + """ Start processing the text nodes """ + self.processcont = True + + def classname(self, attrs): + """ Generate a class name from a style name """ + c = attrs.get((TEXTNS,'style-name'),'') + c = c.replace(".","_") + return c + + def get_anchor(self, name): + """ Create a unique anchor id for a href name """ + if not self.anchors.has_key(name): + self.anchors[name] = "anchor%03d" % (len(self.anchors) + 1) + return self.anchors.get(name) + + +#-------------------------------------------------- + + def purgedata(self): + self.data = [] + +#----------------------------------------------------------------------------- +# +# Handle meta data +# +#----------------------------------------------------------------------------- + def e_dc_title(self, tag, attrs): + """ Get the title from the meta data and create a HTML <title> + """ + self.title = ''.join(self.data) + #self.metatags.append('<title>%s</title>\n' % escape(self.title)) + self.data = [] + + def e_dc_metatag(self, tag, attrs): + """ Any other meta data is added as a <meta> element + """ + self.metatags.append('<meta name="%s" content=%s/>\n' % (tag[1], quoteattr(''.join(self.data)))) + self.data = [] + + def e_dc_contentlanguage(self, tag, attrs): + """ Set the content language. Identifies the targeted audience + """ + self.language = ''.join(self.data) + self.metatags.append('<meta http-equiv="content-language" content="%s"/>\n' % escape(self.language)) + self.data = [] + + def e_dc_creator(self, tag, attrs): + """ Set the content creator. Identifies the targeted audience + """ + self.creator = ''.join(self.data) + self.metatags.append('<meta http-equiv="creator" content="%s"/>\n' % escape(self.creator)) + self.data = [] + + def s_custom_shape(self, tag, attrs): + """ A draw:custom-shape is made into a <div> in HTML which is then styled + """ + anchor_type = attrs.get((TEXTNS,'anchor-type'),'notfound') + htmltag = 'div' + name = "G-" + attrs.get( (DRAWNS,'style-name'), "") + if name == 'G-': + name = "PR-" + attrs.get( (PRESENTATIONNS,'style-name'), "") + name = name.replace(".","_") + if anchor_type == "paragraph": + style = 'position:absolute;' + elif anchor_type == 'char': + style = "position:absolute;" + elif anchor_type == 'as-char': + htmltag = 'div' + style = '' + else: + style = "position: absolute;" + if attrs.has_key( (SVGNS,"width") ): + style = style + "width:" + attrs[(SVGNS,"width")] + ";" + if attrs.has_key( (SVGNS,"height") ): + style = style + "height:" + attrs[(SVGNS,"height")] + ";" + if attrs.has_key( (SVGNS,"x") ): + style = style + "left:" + attrs[(SVGNS,"x")] + ";" + if attrs.has_key( (SVGNS,"y") ): + style = style + "top:" + attrs[(SVGNS,"y")] + ";" + if self.generate_css: + self.opentag(htmltag, {'class': name, 'style': style}) + else: + self.opentag(htmltag) + + def e_custom_shape(self, tag, attrs): + """ End the draw:frame + """ + self.closetag('div') + + def s_draw_frame(self, tag, attrs): + """ A draw:frame is made into a <div> in HTML which is then styled + """ + anchor_type = attrs.get((TEXTNS,'anchor-type'),'notfound') + htmltag = 'div' + name = "G-" + attrs.get( (DRAWNS,'style-name'), "") + if name == 'G-': + name = "PR-" + attrs.get( (PRESENTATIONNS,'style-name'), "") + name = name.replace(".","_") + if anchor_type == "paragraph": + style = 'position:relative;' + elif anchor_type == 'char': + style = "position:relative;" + elif anchor_type == 'as-char': + htmltag = 'div' + style = '' + else: + style = "position:absolute;" + if attrs.has_key( (SVGNS,"width") ): + style = style + "width:" + attrs[(SVGNS,"width")] + ";" + if attrs.has_key( (SVGNS,"height") ): + style = style + "height:" + attrs[(SVGNS,"height")] + ";" + if attrs.has_key( (SVGNS,"x") ): + style = style + "left:" + attrs[(SVGNS,"x")] + ";" + if attrs.has_key( (SVGNS,"y") ): + style = style + "top:" + attrs[(SVGNS,"y")] + ";" + if self.generate_css: + self.opentag(htmltag, {'class': name, 'style': style}) + else: + self.opentag(htmltag) + + def e_draw_frame(self, tag, attrs): + """ End the draw:frame + """ + self.closetag('div') + + def s_draw_fill_image(self, tag, attrs): + name = attrs.get( (DRAWNS,'name'), "NoName") + imghref = attrs[(XLINKNS,"href")] + imghref = self.rewritelink(imghref) + self.cs.fillimages[name] = imghref + + def rewritelink(self, imghref): + """ Intended to be overloaded if you don't store your pictures + in a Pictures subfolder + """ + return imghref + + def s_draw_image(self, tag, attrs): + """ A draw:image becomes an <img/> element + """ + parent = self.tagstack.stackparent() + anchor_type = parent.get((TEXTNS,'anchor-type')) + imghref = attrs[(XLINKNS,"href")] + imghref = self.rewritelink(imghref) + htmlattrs = {'alt':"", 'src':imghref } + if self.generate_css: + if anchor_type != "char": + htmlattrs['style'] = "display: block;" + self.emptytag('img', htmlattrs) + + def s_draw_object(self, tag, attrs): + """ A draw:object is embedded object in the document (e.g. spreadsheet in presentation). + """ + objhref = attrs[(XLINKNS,"href")] + # Remove leading "./": from "./Object 1" to "Object 1" +# objhref = objhref [2:] + + # Not using os.path.join since it fails to find the file on Windows. +# objcontentpath = '/'.join([objhref, 'content.xml']) + + for c in self.document.childnodes: + if c.folder == objhref: + self._walknode(c.topnode) + + def s_draw_object_ole(self, tag, attrs): + """ A draw:object-ole is embedded OLE object in the document (e.g. MS Graph). + """ + class_id = attrs[(DRAWNS,"class-id")] + if class_id and class_id.lower() == "00020803-0000-0000-c000-000000000046": ## Microsoft Graph 97 Chart + tagattrs = { 'name':'object_ole_graph', 'class':'ole-graph' } + self.opentag('a', tagattrs) + self.closetag('a', tagattrs) + + def s_draw_page(self, tag, attrs): + """ A draw:page is a slide in a presentation. We use a <fieldset> element in HTML. + Therefore if you convert a ODP file, you get a series of <fieldset>s. + Override this for your own purpose. + """ + name = attrs.get( (DRAWNS,'name'), "NoName") + stylename = attrs.get( (DRAWNS,'style-name'), "") + stylename = stylename.replace(".","_") + masterpage = attrs.get( (DRAWNS,'master-page-name'),"") + masterpage = masterpage.replace(".","_") + if self.generate_css: + self.opentag('fieldset', {'class':"DP-%s MP-%s" % (stylename, masterpage) }) + else: + self.opentag('fieldset') + self.opentag('legend') + self.writeout(escape(name)) + self.closetag('legend') + + def e_draw_page(self, tag, attrs): + self.closetag('fieldset') + + def s_draw_textbox(self, tag, attrs): + style = '' + if attrs.has_key( (FONS,"min-height") ): + style = style + "min-height:" + attrs[(FONS,"min-height")] + ";" + self.opentag('div') +# self.opentag('div', {'style': style}) + + def e_draw_textbox(self, tag, attrs): + """ End the draw:text-box + """ + self.closetag('div') + + def html_body(self, tag, attrs): + self.writedata() + if self.generate_css and self.use_internal_css: + self.opentag('style', {'type':"text/css"}, True) + self.writeout('/*<![CDATA[*/\n') + self.generate_stylesheet() + self.writeout('/*]]>*/\n') + self.closetag('style') + self.purgedata() + self.closetag('head') + self.opentag('body', block=True) + + default_styles = """ +img { width: 100%; height: 100%; } +* { padding: 0; margin: 0; background-color:white; } +body { margin: 0 1em; } +ol, ul { padding-left: 2em; } +""" + + def generate_stylesheet(self): + for name in self.stylestack: + styles = self.styledict.get(name) + # Preload with the family's default style + if styles.has_key('__style-family') and self.styledict.has_key(styles['__style-family']): + familystyle = self.styledict[styles['__style-family']].copy() + del styles['__style-family'] + for style, val in styles.items(): + familystyle[style] = val + styles = familystyle + # Resolve the remaining parent styles + while styles.has_key('__parent-style-name') and self.styledict.has_key(styles['__parent-style-name']): + parentstyle = self.styledict[styles['__parent-style-name']].copy() + del styles['__parent-style-name'] + for style, val in styles.items(): + parentstyle[style] = val + styles = parentstyle + self.styledict[name] = styles + # Write the styles to HTML + self.writeout(self.default_styles) + for name in self.stylestack: + styles = self.styledict.get(name) + css2 = self.cs.convert_styles(styles) + self.writeout("%s {\n" % name) + for style, val in css2.items(): + self.writeout("\t%s: %s;\n" % (style, val) ) + self.writeout("}\n") + + def generate_footnotes(self): + if self.currentnote == 0: + return + if self.generate_css: + self.opentag('ol', {'style':'border-top: 1px solid black'}, True) + else: + self.opentag('ol') + for key in range(1,self.currentnote+1): + note = self.notedict[key] +# for key,note in self.notedict.items(): + self.opentag('li', { 'id':"footnote-%d" % key }) +# self.opentag('sup') +# self.writeout(escape(note['citation'])) +# self.closetag('sup', False) + self.writeout(note['body']) + self.closetag('li') + self.closetag('ol') + + def s_office_automatic_styles(self, tag, attrs): + if self.xmlfile == 'styles.xml': + self.autoprefix = "A" + else: + self.autoprefix = "" + + def s_office_document_content(self, tag, attrs): + """ First tag in the content.xml file""" + self.writeout('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" ') + self.writeout('"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n') + self.opentag('html', {'xmlns':"http://www.w3.org/1999/xhtml%22%7D, True) + self.opentag('head', block=True) + self.emptytag('meta', { 'http-equiv':"Content-Type", 'content':"text/html;charset=UTF-8"}) + for metaline in self.metatags: + self.writeout(metaline) + self.writeout('<title>%s</title>\n' % escape(self.title)) + + def e_office_document_content(self, tag, attrs): + """ Last tag """ + self.closetag('html') + + def s_office_master_styles(self, tag, attrs): + """ """ + + def s_office_presentation(self, tag, attrs): + """ For some odd reason, OpenOffice Impress doesn't define a default-style + for the 'paragraph'. We therefore force a standard when we see + it is a presentation + """ + self.styledict['p'] = {(FONS,u'font-size'): u"24pt" } + self.styledict['presentation'] = {(FONS,u'font-size'): u"24pt" } + self.html_body(tag, attrs) + + def e_office_presentation(self, tag, attrs): + self.generate_footnotes() + self.closetag('body') + + def s_office_spreadsheet(self, tag, attrs): + self.html_body(tag, attrs) + + def e_office_spreadsheet(self, tag, attrs): + self.generate_footnotes() + self.closetag('body') + + def s_office_styles(self, tag, attrs): + self.autoprefix = "" + + def s_office_text(self, tag, attrs): + """ OpenDocument text """ + self.styledict['frame'] = { (STYLENS,'wrap'): u'parallel'} + self.html_body(tag, attrs) + + def e_office_text(self, tag, attrs): + self.generate_footnotes() + self.closetag('body') + + def s_style_handle_properties(self, tag, attrs): + """ Copy all attributes to a struct. + We will later convert them to CSS2 + """ + for key,attr in attrs.items(): + self.styledict[self.currentstyle][key] = attr + + + familymap = {'frame':'frame', 'paragraph':'p', 'presentation':'presentation', + 'text':'span','section':'div', + 'table':'table','table-cell':'td','table-column':'col', + 'table-row':'tr','graphic':'graphic' } + + def s_style_default_style(self, tag, attrs): + """ A default style is like a style on an HTML tag + """ + family = attrs[(STYLENS,'family')] + htmlfamily = self.familymap.get(family,'unknown') + self.currentstyle = htmlfamily +# self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def e_style_default_style(self, tag, attrs): + self.currentstyle = None + + def s_style_font_face(self, tag, attrs): + """ It is possible that the HTML browser doesn't know how to + show a particular font. Luckily ODF provides generic fallbacks + Unfortunately they are not the same as CSS2. + CSS2: serif, sans-serif, cursive, fantasy, monospace + ODF: roman, swiss, modern, decorative, script, system + """ + name = attrs[(STYLENS,"name")] + family = attrs[(SVGNS,"font-family")] + generic = attrs.get( (STYLENS,'font-family-generic'),"" ) + self.cs.save_font(name, family, generic) + + def s_style_footer(self, tag, attrs): + self.opentag('div', { 'id':"footer" }) + self.purgedata() + + def e_style_footer(self, tag, attrs): + self.writedata() + self.closetag('div') + self.purgedata() + + def s_style_footer_style(self, tag, attrs): + self.currentstyle = "@print #footer" + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def s_style_header(self, tag, attrs): + self.opentag('div', { 'id':"header" }) + self.purgedata() + + def e_style_header(self, tag, attrs): + self.writedata() + self.closetag('div') + self.purgedata() + + def s_style_header_style(self, tag, attrs): + self.currentstyle = "@print #header" + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def s_style_default_page_layout(self, tag, attrs): + """ Collect the formatting for the default page layout style. + """ + self.currentstyle = "@page" + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def s_style_page_layout(self, tag, attrs): + """ Collect the formatting for the page layout style. + This won't work in CSS 2.1, as page identifiers are not allowed. + It is legal in CSS3, but the rest of the application doesn't specify when to use what page layout + """ + name = attrs[(STYLENS,'name')] + name = name.replace(".","_") + self.currentstyle = ".PL-" + name + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + def e_style_page_layout(self, tag, attrs): + """ End this style + """ + self.currentstyle = None + + def s_style_master_page(self, tag, attrs): + """ Collect the formatting for the page layout style. + """ + name = attrs[(STYLENS,'name')] + name = name.replace(".","_") + + self.currentstyle = ".MP-" + name + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {('','position'):'relative'} + # Then load the pagelayout style if we find it + pagelayout = attrs.get( (STYLENS,'page-layout-name'), None) + if pagelayout: + pagelayout = ".PL-" + pagelayout + if self.styledict.has_key( pagelayout ): + styles = self.styledict[pagelayout] + for style, val in styles.items(): + self.styledict[self.currentstyle][style] = val + else: + self.styledict[self.currentstyle]['__parent-style-name'] = pagelayout + self.s_ignorexml(tag, attrs) + + # Short prefixes for class selectors + _familyshort = {'drawing-page':'DP', 'paragraph':'P', 'presentation':'PR', + 'text':'S', 'section':'D', + 'table':'T', 'table-cell':'TD', 'table-column':'TC', + 'table-row':'TR', 'graphic':'G' } + + def s_style_style(self, tag, attrs): + """ Collect the formatting for the style. + Styles have scope. The same name can be used for both paragraph and + character styles Since CSS has no scope we use a prefix. (Not elegant) + In ODF a style can have a parent, these parents can be chained. + We may not have encountered the parent yet, but if we have, we resolve it. + """ + name = attrs[(STYLENS,'name')] + name = name.replace(".","_") + family = attrs[(STYLENS,'family')] + htmlfamily = self.familymap.get(family,'unknown') + sfamily = self._familyshort.get(family,'X') + name = "%s%s-%s" % (self.autoprefix, sfamily, name) + parent = attrs.get( (STYLENS,'parent-style-name') ) + self.currentstyle = special_styles.get(name,"."+name) + self.stylestack.append(self.currentstyle) + if not self.styledict.has_key(self.currentstyle): + self.styledict[self.currentstyle] = {} + + self.styledict[self.currentstyle]['__style-family'] = htmlfamily + + # Then load the parent style if we find it + if parent: + parent = "%s-%s" % (sfamily, parent) + parent = special_styles.get(parent, "."+parent) + if self.styledict.has_key( parent ): + styles = self.styledict[parent] + for style, val in styles.items(): + self.styledict[self.currentstyle][style] = val + else: + self.styledict[self.currentstyle]['__parent-style-name'] = parent + + def e_style_style(self, tag, attrs): + """ End this style + """ + self.currentstyle = None + + def s_table_table(self, tag, attrs): + """ Start a table + """ + c = attrs.get( (TABLENS,'style-name'), None) + if c and self.generate_css: + c = c.replace(".","_") + self.opentag('table',{ 'class': "T-%s" % c }) + else: + self.opentag('table') + self.purgedata() + + def e_table_table(self, tag, attrs): + """ End a table + """ + self.writedata() + self.closetag('table') + self.purgedata() + + def s_table_table_cell(self, tag, attrs): + """ Start a table cell """ + #FIXME: number-columns-repeated § 8.1.3 + #repeated = int(attrs.get( (TABLENS,'number-columns-repeated'), 1)) + htmlattrs = {} + rowspan = attrs.get( (TABLENS,'number-rows-spanned') ) + if rowspan: + htmlattrs['rowspan'] = rowspan + colspan = attrs.get( (TABLENS,'number-columns-spanned') ) + if colspan: + htmlattrs['colspan'] = colspan + + c = attrs.get( (TABLENS,'style-name') ) + if c: + htmlattrs['class'] = 'TD-%s' % c.replace(".","_") + self.opentag('td', htmlattrs) + self.purgedata() + + def e_table_table_cell(self, tag, attrs): + """ End a table cell """ + self.writedata() + self.closetag('td') + self.purgedata() + + def s_table_table_column(self, tag, attrs): + """ Start a table column """ + c = attrs.get( (TABLENS,'style-name'), None) + repeated = int(attrs.get( (TABLENS,'number-columns-repeated'), 1)) + htmlattrs = {} + if c: + htmlattrs['class'] = "TC-%s" % c.replace(".","_") + for x in xrange(repeated): + self.emptytag('col', htmlattrs) + self.purgedata() + + def s_table_table_row(self, tag, attrs): + """ Start a table row """ + #FIXME: table:number-rows-repeated + c = attrs.get( (TABLENS,'style-name'), None) + htmlattrs = {} + if c: + htmlattrs['class'] = "TR-%s" % c.replace(".","_") + self.opentag('tr', htmlattrs) + self.purgedata() + + def e_table_table_row(self, tag, attrs): + """ End a table row """ + self.writedata() + self.closetag('tr') + self.purgedata() + + def s_text_a(self, tag, attrs): + """ Anchors start """ + self.writedata() + href = attrs[(XLINKNS,"href")].split("|")[0] + if href[0] == "#": + href = "#" + self.get_anchor(href[1:]) + self.opentag('a', {'href':href}) + self.purgedata() + + def e_text_a(self, tag, attrs): + """ End an anchor or bookmark reference """ + self.writedata() + self.closetag('a', False) + self.purgedata() + + def s_text_bookmark(self, tag, attrs): + """ Bookmark definition """ + name = attrs[(TEXTNS,'name')] + html_id = self.get_anchor(name) + self.writedata() + self.opentag('span', {'id':html_id}) + self.closetag('span', False) + self.purgedata() + + def s_text_bookmark_ref(self, tag, attrs): + """ Bookmark reference """ + name = attrs[(TEXTNS,'ref-name')] + html_id = "#" + self.get_anchor(name) + self.writedata() + self.opentag('a', {'href':html_id}) + self.purgedata() + + def s_text_h(self, tag, attrs): + """ Headings start """ + level = int(attrs[(TEXTNS,'outline-level')]) + if level > 6: level = 6 # Heading levels go only to 6 in XHTML + if level < 1: level = 1 + self.headinglevels[level] = self.headinglevels[level] + 1 + name = self.classname(attrs) + for x in range(level + 1,10): + self.headinglevels[x] = 0 + special = special_styles.get("P-"+name) + if special or not self.generate_css: + self.opentag('h%s' % level) + else: + self.opentag('h%s' % level, {'class':"P-%s" % name }) + self.purgedata() + + def e_text_h(self, tag, attrs): + """ Headings end + Side-effect: If there is no title in the metadata, then it is taken + from the first heading of any level. + """ + self.writedata() + level = int(attrs[(TEXTNS,'outline-level')]) + if level > 6: level = 6 # Heading levels go only to 6 in XHTML + if level < 1: level = 1 + lev = self.headinglevels[1:level+1] + outline = '.'.join(map(str,lev) ) + heading = ''.join(self.data) + if self.title == '': self.title = heading + anchor = self.get_anchor("%s.%s" % ( outline, heading)) + self.opentag('a', {'id': anchor} ) + self.closetag('a', False) + self.closetag('h%s' % level) + self.purgedata() + + def s_text_line_break(self, tag, attrs): + """ Force a line break (<br/>) """ + self.writedata() + self.emptytag('br') + self.purgedata() + + def s_text_list(self, tag, attrs): + """ Start a list (<ul> or <ol>) + To know which level we're at, we have to count the number + of text:list elements on the tagstack. + """ + name = attrs.get( (TEXTNS,'style-name') ) + level = self.tagstack.count_tags(tag) + 1 + if name: + name = name.replace(".","_") + else: + # FIXME: If a list is contained in a table cell or text box, + # the list level must return to 1, even though the table or + # textbox itself may be nested within another list. + name = self.tagstack.rfindattr( (TEXTNS,'style-name') ) + list_class = "%s_%d" % (name, level) + if self.generate_css: + self.opentag('%s' % self.listtypes.get(list_class,'ul'), {'class': list_class }) + else: + self.opentag('%s' % self.listtypes.get(list_class,'ul')) + self.purgedata() + + def e_text_list(self, tag, attrs): + """ End a list """ + self.writedata() + name = attrs.get( (TEXTNS,'style-name') ) + level = self.tagstack.count_tags(tag) + 1 + if name: + name = name.replace(".","_") + else: + # FIXME: If a list is contained in a table cell or text box, + # the list level must return to 1, even though the table or + # textbox itself may be nested within another list. + name = self.tagstack.rfindattr( (TEXTNS,'style-name') ) + list_class = "%s_%d" % (name, level) + self.closetag(self.listtypes.get(list_class,'ul')) + self.purgedata() + + def s_text_list_item(self, tag, attrs): + """ Start list item """ + self.opentag('li') + self.purgedata() + + def e_text_list_item(self, tag, attrs): + """ End list item """ + self.writedata() + self.closetag('li') + self.purgedata() + + def s_text_list_level_style_bullet(self, tag, attrs): + """ CSS doesn't have the ability to set the glyph + to a particular character, so we just go through + the available glyphs + """ + name = self.tagstack.rfindattr( (STYLENS,'name') ) + level = attrs[(TEXTNS,'level')] + self.prevstyle = self.currentstyle + list_class = "%s_%s" % (name, level) + self.listtypes[list_class] = 'ul' + self.currentstyle = ".%s_%s" % ( name.replace(".","_"), level) + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + + level = int(level) + listtype = ("square", "disc", "circle")[level % 3] + self.styledict[self.currentstyle][('','list-style-type')] = listtype + + def e_text_list_level_style_bullet(self, tag, attrs): + self.currentstyle = self.prevstyle + del self.prevstyle + + def s_text_list_level_style_number(self, tag, attrs): + name = self.tagstack.stackparent()[(STYLENS,'name')] + level = attrs[(TEXTNS,'level')] + num_format = attrs.get( (STYLENS,'name'),"1") + list_class = "%s_%s" % (name, level) + self.prevstyle = self.currentstyle + self.currentstyle = ".%s_%s" % ( name.replace(".","_"), level) + self.listtypes[list_class] = 'ol' + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + if num_format == "1": listtype = "decimal" + elif num_format == "I": listtype = "upper-roman" + elif num_format == "i": listtype = "lower-roman" + elif num_format == "A": listtype = "upper-alpha" + elif num_format == "a": listtype = "lower-alpha" + else: listtype = "decimal" + self.styledict[self.currentstyle][('','list-style-type')] = listtype + + def e_text_list_level_style_number(self, tag, attrs): + self.currentstyle = self.prevstyle + del self.prevstyle + + def s_text_note(self, tag, attrs): + self.writedata() + self.purgedata() + self.currentnote = self.currentnote + 1 + self.notedict[self.currentnote] = {} + self.notebody = [] + + def e_text_note(self, tag, attrs): + pass + + def collectnote(self,s): + if s != '': + self.notebody.append(s) + + def s_text_note_body(self, tag, attrs): + self._orgwfunc = self._wfunc + self._wfunc = self.collectnote + + def e_text_note_body(self, tag, attrs): + self._wfunc = self._orgwfunc + self.notedict[self.currentnote]['body'] = ''.join(self.notebody) + self.notebody = '' + del self._orgwfunc + + def e_text_note_citation(self, tag, attrs): + mark = ''.join(self.data) + self.notedict[self.currentnote]['citation'] = mark + self.opentag('a',{ 'href': "#footnote-%s" % self.currentnote }) + self.opentag('sup') +# self.writeout( escape(mark) ) + # Since HTML only knows about endnotes, there is too much risk that the + # marker is reused in the source. Therefore we force numeric markers + self.writeout(unicode(self.currentnote)) + self.closetag('sup') + self.closetag('a') + + def s_text_p(self, tag, attrs): + """ Paragraph + """ + htmlattrs = {} + specialtag = "p" + c = attrs.get( (TEXTNS,'style-name'), None) + if c: + c = c.replace(".","_") + specialtag = special_styles.get("P-"+c) + if specialtag is None: + specialtag = 'p' + if self.generate_css: + htmlattrs['class'] = "P-%s" % c + self.opentag(specialtag, htmlattrs) + self.purgedata() + + def e_text_p(self, tag, attrs): + """ End Paragraph + """ + specialtag = "p" + c = attrs.get( (TEXTNS,'style-name'), None) + if c: + c = c.replace(".","_") + specialtag = special_styles.get("P-"+c) + if specialtag is None: + specialtag = 'p' + self.writedata() + self.closetag(specialtag) + self.purgedata() + + def s_text_s(self, tag, attrs): + """ Generate a number of spaces. ODF has an element; HTML uses + We use   so we can send the output through an XML parser if we desire to + """ + c = attrs.get( (TEXTNS,'c'),"1") + for x in xrange(int(c)): + self.writeout(' ') + + def s_text_span(self, tag, attrs): + """ The text:span element matches the <span> element in HTML. It is + typically used to properties of the text. + """ + self.writedata() + c = attrs.get( (TEXTNS,'style-name'), None) + htmlattrs = {} + if c: + c = c.replace(".","_") + special = special_styles.get("S-"+c) + if special is None and self.generate_css: + htmlattrs['class'] = "S-%s" % c + self.opentag('span', htmlattrs) + self.purgedata() + + def e_text_span(self, tag, attrs): + """ End the text:span """ + self.writedata() + self.closetag('span', False) + self.purgedata() + + def s_text_tab(self, tag, attrs): + """ Move to the next tabstop. We ignore this in HTML + """ + self.writedata() + self.writeout(' ') + self.purgedata() + + def s_text_x_source(self, tag, attrs): + """ Various indexes and tables of contents. We ignore those. + """ + self.writedata() + self.purgedata() + self.s_ignorexml(tag, attrs) + + def e_text_x_source(self, tag, attrs): + """ Various indexes and tables of contents. We ignore those. + """ + self.writedata() + self.purgedata() + + +#----------------------------------------------------------------------------- +# +# Reading the file +# +#----------------------------------------------------------------------------- + + def load(self, odffile): + """ Loads a document into the parser and parses it. + The argument can either be a filename or a document in memory. + """ + self.lines = [] + self._wfunc = self._wlines + if isinstance(odffile, basestring): + self.document = load(odffile) + else: + self.document = odffile + self._walknode(self.document.topnode) + + def _walknode(self, node): + if node.nodeType == Node.ELEMENT_NODE: + self.startElementNS(node.qname, node.tagName, node.attributes) + for c in node.childNodes: + self._walknode(c) + self.endElementNS(node.qname, node.tagName) + if node.nodeType == Node.TEXT_NODE or node.nodeType == Node.CDATA_SECTION_NODE: + self.characters(unicode(node)) + + + def odf2xhtml(self, odffile): + """ Load a file and return the XHTML + """ + self.load(odffile) + return self.xhtml() + + def _wlines(self,s): + if s != '': self.lines.append(s) + + def xhtml(self): + """ Returns the xhtml + """ + return ''.join(self.lines) + + def _writecss(self, s): + if s != '': self._csslines.append(s) + + def _writenothing(self, s): + pass + + def css(self): + """ Returns the CSS content """ + self._csslines = [] + self._wfunc = self._writecss + self.generate_stylesheet() + res = ''.join(self._csslines) + self._wfunc = self._wlines + del self._csslines + return res + + def save(self, outputfile, addsuffix=False): + """ Save the HTML under the filename. + If the filename is '-' then save to stdout + We have the last style filename in self.stylefilename + """ + if outputfile == '-': + outputfp = sys.stdout + else: + if addsuffix: + outputfile = outputfile + ".html" + outputfp = file(outputfile, "w") + outputfp.write(self.xhtml().encode('us-ascii','xmlcharrefreplace')) + outputfp.close() + + +class ODF2XHTMLembedded(ODF2XHTML): + """ The ODF2XHTML parses an ODF file and produces XHTML""" + + def __init__(self, lines, generate_css=True, embedable=False): + self._resetobject() + self.lines = lines + + # Tags + self.generate_css = generate_css + self.elements = { +# (DCNS, 'title'): (self.s_processcont, self.e_dc_title), +# (DCNS, 'language'): (self.s_processcont, self.e_dc_contentlanguage), +# (DCNS, 'creator'): (self.s_processcont, self.e_dc_metatag), +# (DCNS, 'description'): (self.s_processcont, self.e_dc_metatag), +# (DCNS, 'date'): (self.s_processcont, self.e_dc_metatag), + (DRAWNS, 'frame'): (self.s_draw_frame, self.e_draw_frame), + (DRAWNS, 'image'): (self.s_draw_image, None), + (DRAWNS, 'fill-image'): (self.s_draw_fill_image, None), + (DRAWNS, "layer-set"):(self.s_ignorexml, None), + (DRAWNS, 'page'): (self.s_draw_page, self.e_draw_page), + (DRAWNS, 'object'): (self.s_draw_object, None), + (DRAWNS, 'object-ole'): (self.s_draw_object_ole, None), + (DRAWNS, 'text-box'): (self.s_draw_textbox, self.e_draw_textbox), +# (METANS, 'creation-date'):(self.s_processcont, self.e_dc_metatag), +# (METANS, 'generator'):(self.s_processcont, self.e_dc_metatag), +# (METANS, 'initial-creator'): (self.s_processcont, self.e_dc_metatag), +# (METANS, 'keyword'): (self.s_processcont, self.e_dc_metatag), + (NUMBERNS, "boolean-style"):(self.s_ignorexml, None), + (NUMBERNS, "currency-style"):(self.s_ignorexml, None), + (NUMBERNS, "date-style"):(self.s_ignorexml, None), + (NUMBERNS, "number-style"):(self.s_ignorexml, None), + (NUMBERNS, "text-style"):(self.s_ignorexml, None), +# (OFFICENS, "automatic-styles"):(self.s_office_automatic_styles, None), +# (OFFICENS, "document-content"):(self.s_office_document_content, self.e_office_document_content), + (OFFICENS, "forms"):(self.s_ignorexml, None), +# (OFFICENS, "master-styles"):(self.s_office_master_styles, None), + (OFFICENS, "meta"):(self.s_ignorecont, None), +# (OFFICENS, "presentation"):(self.s_office_presentation, self.e_office_presentation), +# (OFFICENS, "spreadsheet"):(self.s_office_spreadsheet, self.e_office_spreadsheet), +# (OFFICENS, "styles"):(self.s_office_styles, None), +# (OFFICENS, "text"):(self.s_office_text, self.e_office_text), + (OFFICENS, "scripts"):(self.s_ignorexml, None), + (PRESENTATIONNS, "notes"):(self.s_ignorexml, None), +## (STYLENS, "default-page-layout"):(self.s_style_default_page_layout, self.e_style_page_layout), +# (STYLENS, "default-page-layout"):(self.s_ignorexml, None), +# (STYLENS, "default-style"):(self.s_style_default_style, self.e_style_default_style), +# (STYLENS, "drawing-page-properties"):(self.s_style_handle_properties, None), +# (STYLENS, "font-face"):(self.s_style_font_face, None), +## (STYLENS, "footer"):(self.s_style_footer, self.e_style_footer), +## (STYLENS, "footer-style"):(self.s_style_footer_style, None), +# (STYLENS, "graphic-properties"):(self.s_style_handle_properties, None), +# (STYLENS, "handout-master"):(self.s_ignorexml, None), +## (STYLENS, "header"):(self.s_style_header, self.e_style_header), +## (STYLENS, "header-footer-properties"):(self.s_style_handle_properties, None), +## (STYLENS, "header-style"):(self.s_style_header_style, None), +# (STYLENS, "master-page"):(self.s_style_master_page, None), +# (STYLENS, "page-layout-properties"):(self.s_style_handle_properties, None), +## (STYLENS, "page-layout"):(self.s_style_page_layout, self.e_style_page_layout), +# (STYLENS, "page-layout"):(self.s_ignorexml, None), +# (STYLENS, "paragraph-properties"):(self.s_style_handle_properties, None), +# (STYLENS, "style"):(self.s_style_style, self.e_style_style), +# (STYLENS, "table-cell-properties"):(self.s_style_handle_properties, None), +# (STYLENS, "table-column-properties"):(self.s_style_handle_properties, None), +# (STYLENS, "table-properties"):(self.s_style_handle_properties, None), +# (STYLENS, "text-properties"):(self.s_style_handle_properties, None), + (SVGNS, 'desc'): (self.s_ignorexml, None), + (TABLENS, 'covered-table-cell'): (self.s_ignorexml, None), + (TABLENS, 'table-cell'): (self.s_table_table_cell, self.e_table_table_cell), + (TABLENS, 'table-column'): (self.s_table_table_column, None), + (TABLENS, 'table-row'): (self.s_table_table_row, self.e_table_table_row), + (TABLENS, 'table'): (self.s_table_table, self.e_table_table), + (TEXTNS, 'a'): (self.s_text_a, self.e_text_a), + (TEXTNS, "alphabetical-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "bibliography-configuration"):(self.s_ignorexml, None), + (TEXTNS, "bibliography-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, 'h'): (self.s_text_h, self.e_text_h), + (TEXTNS, "illustration-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, 'line-break'):(self.s_text_line_break, None), + (TEXTNS, "linenumbering-configuration"):(self.s_ignorexml, None), + (TEXTNS, "list"):(self.s_text_list, self.e_text_list), + (TEXTNS, "list-item"):(self.s_text_list_item, self.e_text_list_item), + (TEXTNS, "list-level-style-bullet"):(self.s_text_list_level_style_bullet, self.e_text_list_level_style_bullet), + (TEXTNS, "list-level-style-number"):(self.s_text_list_level_style_number, self.e_text_list_level_style_number), + (TEXTNS, "list-style"):(None, None), + (TEXTNS, "note"):(self.s_text_note, None), + (TEXTNS, "note-body"):(self.s_text_note_body, self.e_text_note_body), + (TEXTNS, "note-citation"):(None, self.e_text_note_citation), + (TEXTNS, "notes-configuration"):(self.s_ignorexml, None), + (TEXTNS, "object-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, 'p'): (self.s_text_p, self.e_text_p), + (TEXTNS, 's'): (self.s_text_s, None), + (TEXTNS, 'span'): (self.s_text_span, self.e_text_span), + (TEXTNS, 'tab'): (self.s_text_tab, None), + (TEXTNS, "table-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "table-of-content-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "user-index-source"):(self.s_text_x_source, self.e_text_x_source), + (TEXTNS, "page-number"):(None, None), + } +
Property changes on: trunk/pywikipedia/odf/odf2xhtml.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/odfmanifest.py =================================================================== --- trunk/pywikipedia/odf/odfmanifest.py (rev 0) +++ trunk/pywikipedia/odf/odfmanifest.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,115 @@ +#!/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']) +
Property changes on: trunk/pywikipedia/odf/odfmanifest.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/office.py =================================================================== --- trunk/pywikipedia/odf/office.py (rev 0) +++ trunk/pywikipedia/odf/office.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import 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
Property changes on: trunk/pywikipedia/odf/office.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/opendocument.py =================================================================== --- trunk/pywikipedia/odf/opendocument.py (rev 0) +++ trunk/pywikipedia/odf/opendocument.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,656 @@ +# -*- 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 ( + (CHARTNS,u'style-name'), + (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 :
Property changes on: trunk/pywikipedia/odf/opendocument.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/presentation.py =================================================================== --- trunk/pywikipedia/odf/presentation.py (rev 0) +++ trunk/pywikipedia/odf/presentation.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,85 @@ +# -*- 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) +
Property changes on: trunk/pywikipedia/odf/presentation.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/script.py =================================================================== --- trunk/pywikipedia/odf/script.py (rev 0) +++ trunk/pywikipedia/odf/script.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2006-2007 Søren Roug, European Environment Agency +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Contributor(s): +# + +from namespaces import 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) +
Property changes on: trunk/pywikipedia/odf/script.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/style.py =================================================================== --- trunk/pywikipedia/odf/style.py (rev 0) +++ trunk/pywikipedia/odf/style.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,148 @@ +# -*- 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) +
Property changes on: trunk/pywikipedia/odf/style.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/svg.py =================================================================== --- trunk/pywikipedia/odf/svg.py (rev 0) +++ trunk/pywikipedia/odf/svg.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,54 @@ +# -*- 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)
Property changes on: trunk/pywikipedia/odf/svg.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/table.py =================================================================== --- trunk/pywikipedia/odf/table.py (rev 0) +++ trunk/pywikipedia/odf/table.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,307 @@ +# -*- 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) +
Property changes on: trunk/pywikipedia/odf/table.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/teletype.py =================================================================== --- trunk/pywikipedia/odf/teletype.py (rev 0) +++ trunk/pywikipedia/odf/teletype.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,137 @@ +# -*- 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)
Property changes on: trunk/pywikipedia/odf/teletype.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/text.py =================================================================== --- trunk/pywikipedia/odf/text.py (rev 0) +++ trunk/pywikipedia/odf/text.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,562 @@ +# -*- 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) +
Property changes on: trunk/pywikipedia/odf/text.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/thumbnail.py =================================================================== --- trunk/pywikipedia/odf/thumbnail.py (rev 0) +++ trunk/pywikipedia/odf/thumbnail.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,427 @@ +#!/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 = """\ +iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAAG0OVFdAAAABGdBTUEAANbY1E9YMgAAABl0RVh0 +U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAFoHSURBVHjaYvz//z8DJQAggFhu3LiBU1JI +SOiPmJgYM7IYUD0jMh8ggFhAhKamJuOHDx/+8fPz4zQsMTGRYf78+RjiAAHEBCJOnTr1HZvmN2/e +MDAyQiycOXMmw5MnTxhmzZoViqwGIIAYrl+/DqKM/6OBNWvWgOmvX7/+37Rp0/8jR478//fv3/+f +P3/+h+phPHHixH+AAIK75D8WMGnSpP8vXrz4//v37/9///6Fi4MMALruf3Bw8H+AAAJp5rQrOoeh +edmyZWAbgd77f/bsWTAbBoB6JOpbmkF0OkAAgcLgO8gUYCCCnSIlJQWmw8LCGA4cOAAOAyMjI3hY +gMDvP7+f3791+weQuQAggGBi7FPmrvnf3NwMtgnkt/Xr1//fuXMn2EaQ5TB89+nX/wUlJSDbPUFe +AQgguKleiY2/QIpBTv727TuKJhB+//nf/xtP/4ANrK6tBRnAATIAIICQEwUjUCHIoyjOBYGbz/8y +8HMwMXCzfmcoLC1kMDH3YNDU1mGQ4PvLCBBALEjq/t958Zfh0dt/DL/+MDD8BdkBNIeXnYFBhIeR +4efffwybNqxgEOEXZLjw25Xh2QMWhmi9BwwAAYRsAMO5268ZZMREGGSEGBmYgcEL1MMAcgwo3D9/ ++sIwf84cBhHLGoYAVVYGxi/3wDYABBCKU6dPn37s1vM//3/+/v//20+gn5/9+b/7yq//iw++/6+o +qAhy0zUg1gH5HYYBAgg99Srsvvzz//6Tt//beSf+V/doBGkqheaFL0CKF1kzCAMEECOWfAMSY3Yq +PvF7X68FKCcCPcLAA8QqQHwB3VaAAGKktDwACCCc5QETE5ODjIzMfi4uLoRtjIwiQBe8RVYHEEDg +WODh4dkBTMLuQE1YDdPR0WG4cuUKw6tXr968ffsWxdsAAQTWAbQJq+aenh5wogJpBpUNzMzMGGoA +AggckshZFRmA8sXz58/BeQKY2WA5kRmkp7Oz8z8vL+8WgAACG3Lv3j0Mze/fvwcpBuaLb/9//foF +FweG2U9dXV2RixcvguTNAAKIAVQWaPt2oGgGlT4gzSBDNm/e/P/jx48o8n/+/PlraWkJil5OgAAC +OUDEKvsgWOLdu3f/k5KSwOxPnz79nzt3LrgIQwY/fvz4X1FbDbIgAOQVgAACxcIbFnZesFcEBQXB +AbdhwwYGNjY2BmdnZzANSypffvxn4OFgY/j5+TvI9i0gMYAAgkUJI7Dc+/flyxeGly9fMaipqWEE +9m1gTv329RvDjAmVDE52dgx6enpgvQABBIu7//fvPwCmB14Mze+//geXBwKcTAwn9q9kEOIXYNC2 +8IfLAwQQcqIIOHPv9/o3X/4z/PkLzABAR7KyQMoCPi5Ghm9fvjJM7i5lUDbwYXjI4sIwK41LHBgG +rwACCLk82Pvq038GaQEmBi52iAEwK/4BDbx7cTeDEB8/w42/TgwhRt8ZzNeeeAHyAUAAoSTL15/+ +/f/++z+DrBATw/P3/xgeAkunt5//MSzYcpOhJYyNQUNDowGorA9o82eYHoAAQjFgw6kv/yV4/zLc +v3WRoaRxBoOEtj/D2cXhPECNAcAExAbUiFE5AgQQenkAis/PrkWH/u/us3MGsvdBxYOAeD3QAIy8 +DxBAjNiKJXIAqIZ//PjxYT4+PmtgHmEAJjiGhw8fMhLSBxBALIQUcHBw1AINbAIZCkqUuABywQZM +kwzAnMBw//79TcCy2A+f+QABBA4BoOuZHj169FdWVpYs3wPzKoOAgACKI0BsYCnDwMrKyg204xsu +vQABxAQtkv6FhISUEmuho6Mjw9OnT+F8UNsIWHQxAMsChtOnT4PaSwzAVglYDBgNX9H129raci8C +AhAbIICQkTCoACEWgAoVDw8PcKl17Nix/ydPnvx//vz5/9jMAKqRh9Vi9fX1YLHe3l6QuD1AAMEs +ZwUVi6s37CTK8t27d4MtBrW7QPj169f/79y58x+YCDFKP1jJCIruurq6VyC+t4/Pf2DUgAozSYAA +Atvu4Wm5D+QA47hVoLIWwwBQsVpaWgq2FIRVVVX/gxp427dv/79kyZL/Fy5cAIcIPrBh/QZwtZOS +mvoXmLDngDIOKEQAAgg5CmLsis7+v3XrFlgDyAJIWoIAkM+A8Q5ufYEqidmzZ4Md8PnzZxzVGQSD +wN79+8F0ekb6X2C92AyqRmFRAhBA6PnUVtuv99CVjUXwlAysicEKQZUuKJcAm/7AlM0GrmyBwYi9 +ogWa+hYY6m+AxeDPt9cY9PV0GSoqKxjef/jGMGvGZGmgec9gSgECCFtBofvu3ftLoJQNjFuwI0RF +RRlwNRkQbQ4Ghmfv/jF8BlZaoKDjAzYnb1w4wHDx+lWG98A66s27zwwVZUUM8vJyakAH3IbpAwgg +rCXVxo2bnvr5+Ur9+w+pFX78+s/w8w+kvQnyMCsQs7GAeIwM91//A6r5z8DLAQwRFmDVwwnUA1R6 +4uhBhl0H9jG8efacgZldgCE4Pp+BiUuc4fTNLwyVwUJMsGIZIIBwFZUam89+u84GrND+QZMeKQ04 +acYbDGs3bWR4B/T5kbtcDLouWQycvKLgqp0FGJBGghdu2mgLaoDUAgQQrqL4BjOw/augogGuXNnZ +GBn4OUG+Y2RgY4W2l7//Bwb3P2BpB2oGMjKwMDMy3ARW+5nRbgwB7hYMTk5ODIVdWxmiQp0Yvj5b +9qy1uHIn0NyroH4dyHxYDgAIIHyVhdvzd392vvj4nwGYdhi+AKOBGdpY//vvDwPr348MX94+BVed +fTPXMry4tm02qMbLzs7eBmynrwOWgsuA/G1Ai77jCy2AAMLnAM75S1a/SIwJ3QTqpoAEzFO3N7Nx +CTEwMrMycN8qvLB9y8FAoPADmFna2tp/rl69mglyCKh9QExNCxBAjCTWOxKg+h6Iv2KRAzXDxYD4 +ORD/ROoG4wUAAURx/4BSABBAeMcbSAHA4jUF2M2YDWo3sLOzM0ybNi0SmBBXENIHEEAkt4hALR9g +FTsX2PJJBFrIwMKCPSMB2xcMwI4BwSgGCCC8LSJgBSMtLi5+AGiRCsgyUPFLTJRt3bqVwdXVFRQS +oK7MX3xqAQII7gCgTyKBrZplIIuAwUlyFADbAwwWFhZgB3p7e8OEZYD4IT59AAEEGzKyBuVb9CEC +YsHy5csZysvLUUIH1Bq6du3aLdBACD69AAEEC4GXwHYAuHYjFqxevZph3bp1DCtWrACH2Pfv38EO +AHWQgFU0OLqEhYXZQM00fAAggGBV3DPYeA8hAEq0SkpKDKGhoWCfgywFWQ7shTLcvXuXAdjzBLeI +QVEpIiICCl1hdDMWLFiwCtirBdsNEEDwEQdgcBFsih08eBCFD2qOgTqloEYMaIwJmPjATTPkLvG2 +bds2IY9sAHt/6rDhNFAAAAQQ3FWtra1biW2Qgjrvly5dAteTwP422HJQo/TBgwcYTTpgg+Y/zHIX +FxdWYGj9P3fu3H9g6LwHNYQBAgil8kEel8NneXp6OthyUF8e1H8HNddAoYGtPQlSD+3LM2ZmZoLF +Nm7c+B86XMcLEEBgmw10JazMUrYSbFiC23VQy0EhABreACa6/8BCBxz0oEEFbJ4ANmiDgXoEQOyG +1tb/VlZWIDNAvWxGgABiSSqseXiHMUju359fDEADGCQkJHAmwJUrV4LbiKDEBeyxgjodDLdv3wY3 +19TV1Rm4ubkZsGXlnJycNdpa2vfAQwXAtAbsP2wEMu+AWkUAAQQSkwU1yUH4ypUrGK4HKQImJHiT +HIRBiezy5cvgJjko4b18+fI/vugDhdK/P//+VTfU/09ISACNliaCogWULgACCJQVHp+aYtQEToiz +9qK4fP/+/aBsBC5WQdkNVLiAshtoCBqU3Tg5ORmMjY3BjVZ8hdiZM2eBbQhGxhdPnv4DOrofZDSs +oQIQQOC8+OMXQw+IvvaSB16axcTEMJiYmID5oKY3KG/fvHmTAZjwwMUuyCGgQTRcloOMAeFPX34A ++4I2DKWVlUA9P38DE+oRoDS8YwkQQLCS8POhPiNfi/Rdm0H9ehUVFXjnE2QRsMvFAExkDF+/fgWX +lqAmu4KCArifAIp/XPXTm8//GW5dPs9gbW3JwAxUtGL5ik7ooOVvmBqAAEKuDXfwcLIwvH37Fm45 +MHuBfQ2MY3DilJSUZIDUikxgi5EHsVC668DAffcF2Ef4/BVseU5hAYMwjyBo3ABUN7xEVgsQQMi9 +jT97JjgZvHkDGc8E9e1BdfqPHz8Z9PUNGLS1QcEtBox3LnDZj2uw4hWwEfvyw1+G38B+BOsviEcE +efkYXgNzGLC/0Qn0/R9k9QABhN7duTRn/pyPIF/9/PkLWJ9zAC3WBscz1i4YUsPy0zfIAPuHb//A +vSRulh8MZ8+dY4iMjWX49/cfg6OjHYORiYU0ul6AAMKWdAP+/v23HpT4YAmQEHj05h/Dj9//wRYL +8zCBHXTs4DaG81cuM7x98YLh229mhqjEPAZpaRkGNSkWPuRhMoAAwtbhOwmKe2ZmYDwDLf8G7A98 ++g7qG/wHxi2w5gPy//6HWPYOmMhuPvsL7raJAC2WFmQGdlCAXTfGbwzPgenm0YMHQHNYGGxsHRg+ +M4kz3H71jyGlbGoOsmUAAYStSfbm3M3XDAIiUkAL/zF8+8nI8PM3pMMJshSMQcPGTJA+IiewCcEJ +7Dm9AAYzGzNktuHZrdMMt+7eYeAA9qKffGBmEPinx3DkNNDRTH8Yfoh4tAHzVjvMMoAAwhYCv6/f +f/Xv6XtgKgam5j/AugTUMQZZyMSImKwAWfQdmJnefQM1Jv6D50zuAH14/fFnBhU1VYY3r18y8PHx +M3zms2F4/EUEaDmk06ogKw4q3OAeBwggrI3SnprEqgnLz3aAesCgXi8fEIPLGuiEDIyJngVBFZ+l +jgLDbWCZIcgrwLDj4l8GbSdDBi52JgZ3/f8M74FZ/O2rZ7C2IrhHBRBAWB1w89rlAwrC0PAGdXlY +GRmE+BjBQQ0S+v7zP8MvoO+/AtPDDyAN6jPyczEyHLryHjyC9ub1awZhUQkGHVZRBnOJ2wzt5Zbb +Jj55AuqYngXlNOSSECCAcBXgou8/fnn16RcneGxAQpAJHBKgIASNmoMGgD8AE+QXYBR9A6aPP7// +MGw69prh8e1zDOZCFxiAjRSGkJCQbaD5JKilr9HzPwwABBAuBzBdu3n/LwuvLDCOgTng639wnP+D +TFcC8Q+Gv19fMnx5/5yhu386w9kDK0CWzAE269k3bdo0wc7ODlTkggai7mIbH0YGAAGEq2Py7/jl +J98klKW5+Dj+MvAxfWJ4+/opw707VxnaJq1g4BRUYOCT1GWQF3z9G2i5JdSXjOvXr/8HtXwZMZaD +AEAA4esIRLu7e+bu3Ln9JJB9xSh2+SwOPikG2AQHsPIKh3bDwRULsGiWB9aeB48dOxYH5B4FZRRi +un0AAYTPAWxQ+Z9Qvg2w0XIYaDGo6gb58g2aen0gVgXiXaCSmdjuOUAAkdIVAqlVBjWlcMhLgio0 +qMP+E+sAgACi2nwBLQGoRw7se7gCO7uJwHZnBLBNyobcpqAEAAQQy0B6DNjkUAR6KAnYvIgFpWFQ +EwM0tgEackBu5SH3eUHNlNOnT98GBgpovPMXpW4ACCAWWsQWsPUYB/RIPNBjjjBPgVqShAZ7iQGg +1omysrK8lpaWJpB7kVLzAAKI6CwA9IAlECcBPRMDxBwgj4EwrgEiagDQnHdRURHD4sWLGbq7uxlK +Skrgcvfv3weNEaA0rcgBAAEEDwBQzC1cuNDO39//AB8fHwO5QzUUZgmG3t5ehoqKCnCyB3UPQHMT +2ABoQGTt2rU9sbGxZcTUN7gAQACxII26/AcGwndQgIACgB4A5MEHwDbrt2/fGC5cuMCQl5cHbkb8 +g89aI8oAkBhoCAuEQWxQdrK1tQUlCVA38xm5bgAIIPRMeX/Xrl0HQQ6iNgD1Ljdu3Ahf2hQVFQVO +xvr6+iCPMOTm5oI9eunSJUgHDehR0Fjb8+fPwaMP165dA9MgPkgclFrExMRAXeRjwIhjJdddAAGE +UgYADQL1f1yBsbJdTk6OKtkAlH+zs7PBMY0rOYNiFIRBngIFFMiDoNQBKgNAM+CgIRfQcAxIP6hX +DCp7YAUqaDjHxsbGAJgdLuIrmC0tLa+tXLlSA2Tew4cP/8bFxXE9efLkH0AAYRSCQMWKBw8ePG9h +YcGPb5qeGIBtZRhsNh00/gByfG1tLcPSpUvBMd7f389gaGgIlgOpA2VF0HAAqFMMWo6Eq3967949 +UM2AtUD08vLiAeK7QHvEQOtjgCmcAeh50Ey/FjDQHwIEEDbzuCQlJVNB403UBKCRPNDYZEZGxn9g +coePc7W0tPwHDc6C1iEBYwS8aAlkN2jgFbT+CNuQIzoAqQOmtG5YioZGKouTk9NP0FgodNnR/zlz +5vzfsWPHf2Dq6QOldCAWAQggbM1NXv9Q/9OggTpcq6tIBaAx1Pz8/P8bNmyAexxkPmjFJmzBJciB +oOFR0BQ4aMUWSA/IYyB5YsZtQdPpoKk0qOfZHBwcnoNGob/+/P5/2owZ/1tbW/8fPXoUZn8CA2Rp +HStAADFCPS0UXTbt3uM/FuDi/8+PTwzavNcYeqqiKa4ROjo6wENtoDF9cHe7p4ehsLAQnMRBox+g +/A5aeAIa+wMlfVAyB+VzUHIF2Q0agCSmrQHKVsCa5AGwR6QBbKeI37x585S8vLz49bt3GKrLKxiE +geYBszaoIAWtGQCtKboIDKz3AAEEMhlUglrCPA9OOxy8DCfvsYCn7EFTb8QWhiALlixZAsqP4NId +BCorK1GW9IAKO1DeB40zg0p0EBvkeJA9oPwuLi4OXoUDaj0SMyaF3EJUVFRUAJZhFgcOHlwtBiw4 +rty6yVBXVc1gaW7+e+bMmX/v3r3bC+0qgpZ1fgTpAwggRqT2gI1D0en9/xgglv78/JIhy/kPQ5i/ +C96JM1DVBmrmIk2OMVhbWzP4+vqCqylQTIPqeGDeZ5CWlmZ49uwZeGAdFLigwACV7KAaB7QaGDTo +CjKLnNoHZA9oDJWNg51BSECQ4cLVqwz1wALWztr61+zZs/8CU0QtdLIe5Pn3oNVKIH0AAcSI1iYw +DClZfOLVP22Wf39/Mby7e4hh98xo+FJlGAAtS9q5cydDQkICQ1JSEsPcuXMxqjVQqQ6q0kDJHJS0 +QUkd5GlQAIDm0UClOmh0GTTKDKriQDFOnsch9j14cB8YgIJAs4QYTl04z9Bc38BgbWnxa+HCRb9u +3LhRCvU8qCv9GbnlCBBAjFgKQZXo9MwDj7lTpb69vccwr1gNPEkAyoegUAbFKmhcHjR5gJ4HQR4F +5WVQsgZNEILYoCYrKOmD5EGBAqveQLEOzKPgFIArqROaFgbJv//yl+E2MKmrK0sByw0BhqOnTjK0 +tbQymJub/dm6ecvXUydPlgGVnoZ6/gt6sxkggHAFuZStrfb0f/oz/ER/n2GY1x4PLpSAfQWG+Ph4 +lGQHimVQIQZqtIBiGDSHAAKgGAU1YEAxDcpCIE+CYhjUgIHI8eCt23EtDQItGP/4DTRI9h/o+X8M +j+9fY7AxVgWaxcmw/8gRhq72dgYfbx+GbVu3MWzbtiULmudB81NfsfUZAAIIX5oDNdviDCLm969s +tGJQVVVFSaIgj4Nmd0GFGSjGQYEBKshAMcrLCym9YV1gSlqUIK0/gb3+Lz//M4DWp3798R+ezR7e +vshgZ64N9vzOffsYJgA7UmGh4cDGzg4GNQ19hlUrFmfcuH51KS7PgwBAABFyGTdotqp76vIZWQl+ +DLDF4aA5E5CnQRjkEJDHQSU3SJ4a3WOQp0EDvp+BMf3l5z8wm4kRkez//vvL8PzueQZBXlaGA0eP +APM+L8OqlasZEmPjGLZs3sygq2/IYGRmy8DPx8NgYaIjBKrucNkFEEDERA1oPX7Z06fPakEzVKCY +BuVpUOEGHY2k2mDHT6BHQTMhn779g+yLgI3GM0JWwoGG6n//Bub5GxeAofCDYdf+feAIuHDmLIOn +pwfDWSCtpaPHYGRqzSAjr8bwl4GN4cal4/uC/ZxdYaU+OgAIIGKiC7SbYQ0wf9eCCkBQnoUNhmAL +TZiDiVmKBFL3DZi8P4Cm84Aeh818gD3MCfEwaECcA9hS4WJnZPj2/Q/DjZvnGVgY/zFs2buH4dfv +XwwXz55jcHJwZLh46QaDpJIeg4qOLYOEHNDzzFwMX4Fm/+RRd4LORTzC5gaAACI2c/L7+fnX9U+Z +W8TOLcjw4w+ou/of4mFGREiCVheCkuq//4jQ+AddrffnH2Q66ecfyLJDYIUAXob4H+pvUALi4WAE +eg6Y74CeZwZng/8MXGyM4MV77z7/YTh/9igDO8tfhv2HD4Gr1XvA7rGRgSHDk2cvGIRkdBgUtKwY +FJWUGV594WC49OgfUA/QTqb/DNy/b3+fmGcgCEwFP9E9BhBApJROVnM3Xz0qLq0CXiXIiJQn/xNZ +bRGq0hiQZp1AAQlis4Irib8MX5+cAmaDfwyHjh4GN3hePX/BoKWpxXDl9nMGRkEDBhZxCwZeEQUG +VnYuFHMFuBgZXr37yHB6frD1mmVzjqHbCxBApJRYd989vnRDSFRagxVY2KE7GBTTyEkfFOuw/QxM +0Lk1ZmhJxsQEmnAEBiJUzz/QfA+QAZoLBPFBMQ5SCp4P+veHYd/ayQyeThYMf5mYwY2mA3v3MTjY +2TOsP/yYQVDWhEFc0pyBT0SRgZmVA6wXZIacMCODtjwzMACAfY5ffAy2SvOOamqqg1IBysIkgAAi +JQWAAstj54n7m+VlpRkYgWkWFDl//6PGPCz1w1begqZsQetLQROczEAT/v+DrEVlBq3EBQYEKIBA ++kFiIDlQVmAH5oPfQPY3YPE/d/kOhsnNmQx1dXVg80FtClC12j5nP4OIgjmDsLwZg7aaNIOGFNCQ +318Yvnz9zPDtyycG1l8vv+/duvzaxg3rQas+QbUAaHpwKzAAUMoCgAAiJQWAZl1u/Pr8+g8zgySL +IBczMK8ygh0LCvHfwJAANVJAc9pfvjFA5rGheZyXG6IOtCKNm50RkufBSZwRHDi//oECCVHPP3r3 +n+HOiz8MB84+Z1hbG85QX18H7iGCWqCgwY/mrml/OX99eHp40XzwXOcGYOucAbJi9DFopQJ0dgg0 +PQVqlf3CN2gKEECkVtrPw/0ds05cuDdLUkiUgYMFMl0MSqqgCdsvPyHzp8CaiuEbkA2a0P/5F5Sk +/4HV/IUmedA8J0iM4T+wifz7BzDGvjB8+/aJ4dzNTwzs/94zPDm/+sW61YtBnvsI7G+EgjwOnnzT +198DigRo6w7UvH1M6eQIQACRGgBfv337eu78rZcMz77xAz3EBE7qoOQNbqBAS3w2pn/A0vwPA/P/ +XwzMwGT5++snhi/AfsGfH58ZDhw6yrB+x3Fgl5uPgZVTgIGVS5iB+/3Gu5cu3JwH9RhoNQson7J2 +dnbeBdXzISEhi4HtjtfQadhz0Jj+RslwOAwABBA5zbYH146t26wYmuoL9D445j59+szw68fn/6eO +7Hy6ceMG4R9cepwsQM+BVlqz80owsHELAz0rCB5nYGb1YNDx8WDY32cFmmXdDp2yfwdJF4iZ2ebm +5sfAzpNQbW1tFTAQQJ6/AO3QgJL2P2rNaQIEECOZekBp0hwaU8+hee49NM8JGBrId/E6rY9Cnbo9 +9mtlX04xkAlarXWbAfsKcGjjkq0F2NfwgY75g8y/Ah37/4U0j0GVAAAIIFpN/4A6UmG+gS6pm9fv +6YT2xZ/CJvMJuIcX2nKTgMb2I2gKQVljQa0AAAgg+s9/EZctWaBu+w1uBWHZQkKtAAAIoAHfPzDQ +ACCAqLZ/gZYA2PsUAbYDkoGNoOi/f/+elJWVTaNGDQACAAHEMtg8C+xtGgMLQdCiiRggzQcaPUKe +hn/06JEukCqE9lIpBgABNGABAJqvu3v3biDQcwlAT/rCutggjG+YDDTSxABZ8U6VAAAIILoEwMeP +H/nExMSSgZ6LA8asAciToAFUEE3qcBmoSbx48eIcYACWUSMbAAQQ1QOAiYlJFxijoJUksUAsDPIk +aGaIWitJQJ0hU1PTPCAT1Dv6Tql5AAHEQkkSvnPnjjfQk6AkHAwaFoPlV1JGeokFt27dAk+ogNbw +8/Lygoaj+KkRAAABxEJkEmYXFRVNAXouHpgHTSlJwqQA0CYl0KoRkB2ghROwgxdAg7DA7rEDkLmC +UjsAAgjbIil1oCfBSRjoQUlYrJKyu4oSAJo8aWxsZGhpaQHzQVsI0GemQJMs58+ffwjMCqqUrhcE +CCAWpCTNAUxi30GW0XLlFz6wY8cOhm3btjFMnjwZfMzSvHnzcFWVoBkqeSATNKH7lhI7AQII2aeg +c2zuiYuLKw1EAGzZsoVh1apV4CU1oO0xoAlW7GOHkAVToDkIYKTJUhoAAAGE7NPfu3fvPmphYaEE +Svb0SOqgPX+g6TRQeQKaaAWtCwJNnoLmH5ABbP0QSA+IBgFQluzs7GwGBkIgrsXoxACAAEJeJwjy +tT/QASvRHUBNcOLECXCBBtqLtGfPHlBehssdP34cvBcVOa8jzzCDAgB2lgGoOgTNUqurq/MD/fCJ +XPcABBByCgD1tV+AJjexLW6iFID6HKBtp9XV1eApcdBiSBCGrRwDeRQ22QKKcdDsE8gtoKl0EA3b +5gqbbAWxoatXBKHdZrIAQAAxIXUvQa2qt6CQhiUzagHQMlfQFDtkp9l/8PrA9PR0lGVzMM+D7AZN +qYNmm0H79EAYNgcJagaDWoKgQACpBwUAtFVIMLaAhWrUokWLDgL9aY4sDhBA6BN6H65evXoLFPrU +AqB1AKB1AiCPg2IcW6EGS+ogj4PUgiY+QB4H0aDkD/KwsLAwGIM8DZtuBwUItFWId+93dHS0eEBA +wJKmpiY7QUHBE8AI2QvN9kwAAYRe3H8BFoR73N3d1aCdDoqAoqIieAceNgAr1JDzOCibwM4mAk19 +gWIZ5GnQuiHQ8hlQ4Yw8CQvKpoRahaBNUubm5mdiY2MZQakIlJ02bNjgAKxiQWXeL4AAQk8B3+fO +nbsXtsiBEgDyFCipowOQI0ByoJjetGkTfAuqm5sbOGa/gIfIv4E9C5qMBRXIoKwCksM2Aw0KsNLS +UmtczfWqqqrslJQUGVD75syZM+B5BWCqew1tQzABBBC2ITJr0M5wYtbmkQpAawFBB/2ATjg0NDSE +rxlcunTpf2ANAN4MDtoUfvr0afDiSdCCSdAebXxuAZkJVP8AVDOiHebH6Ojo+AHoafiud9CJksAs +AFooCVrmAtrfww4QQOhZAFwQghYoApMoIzUbRKDkfvToUXBDB9S8BVV/oGwG2g8Mil3kTRWwKXhY +aY+vRsLWKgTFPDD7cTo5OfGDVp/DaiGQWba2tn+AKQ+U/ME9NoAAwubDj2fPnr2sqqqqR60AAOX3 +9vZ2sOdA+5FB63VBHZu9e/eCCzjYNhnYchpYNUxsVQzKBlpaWjJIrUIWYEx/Bq1MBwUkyP5jx46B +p9aAnmeBDuGDlsT/BQggJiztAuH1R1/pggoiaoH6+npwPgYGLNjzoCoRdAoYKO+DCjdQSgB5HpRK +QDUBqAyANXyIGbQFLcbq6ekBtQqZQbEvIiIiYGVlxQQKmMvA7NDX1wcuT0CbMYABAjpXCzR/CFpY +/RcggFiQ8j5/aknt6Rt//FTu3z8CdgRoZRilDSLQSnBQSQ7y2Pr168GrQUHJH5a6QJ4EeRbmaVBs +geRAKQPkMWJSISiWgS1CXwbI0To/gO0GXmDT+j+wgGW8AWxunwQWfpcvXwY3xIDgALTh9BPU9gEI +IJDp7EH+phFvlGcuuAk6ahQ0t8clzECNmgA2fg/q2Hh5eYH5oPodFKiw2AbVBqDVZqDSH9bYAaUK +UN6GLa0jNhtAW4VvJ06cuFNbWxs01cYMOnOEA5j3QRsugI2obUB73kHHE8GNHYAAAmUBaZDnUfIB +Bx94Cz65LULQ5ghQzIMKPNCZlTDPg8RBHgJVg6DWHSgwQNUSqK0AW2oHinVQYweUAkhZfAVqIQJb +ernAVMsbHh7OCyxAmUELpa8A+x3A5P8PtBwf6HnQ/CJoiu0jdMKFASCAQKb/lf4w4S5KALDzMGw/ +fBW+EozYer+hoQG8Ehy0aBpU74I6PKBDtkAAtBECtDQW1swFDW+B2gmgDg2oMQTyAKjBA8qroBQA +a+2RMlYITPJ5EydOOAEMBNAJUwwrli1nEOTn//fu3bs/wOy1kgFywM8TBshyWfBkLEAAgQLg+fJ5 +i3JR2sesHAz7zr5kILYgBK0g3b59O7hkB7YkwV1bkMeBTU+4GlAfH2QeqMsLqglAGLScFhTDoGUv +MjIy4PIBFPsUDLWxOTu78gMDjvEysNq7dOECg6aGxl9gO+EfMOBBjQNQRIMaQfCYBQggFmgv8Pyz +DS6zpAL2pIEDgJmd4c03SKsMVHrjcgwoX4GWvIPorq4usBjIE5mZmaATVcHJGORh0EgPKDZh/X1Q +OwBkNii/g2Ic5HlQjQDikzugCuq/fPzwkUFdQ1UAHPvAvC8iJPQPWPiBlsnPYoCsOwC1yz8hrxkE +CCBYEfv6zr13C1UY36d9+w8s+ZmYGVi5BOEnJWELAFCMgo75ADYzwckX1MgBVj1YOzqgAAGtJwZ1 +bkBJHtTFBeVvUMyDltCDaEo8D1sqr6yizMDMxMpw7vIlcOzb29r8mT17zl9g9gR5/h567IMAQADB +ShhQgXBtR69zFkyClYOf4cWrd+DSGh2A8jiwcwH2PGgrG8hDyJ6HrRwHeRoU6yBPg2IelFpAYqAA +BVWxoHY+yPOkLppG9Tyk/Ll29TqDsAjkAKmVK1YyiAMLvqtXroEKvwnQvA9aZ4CxZhgggJCLWFDJ +eEjm/x5w/cfMxg0sCG+ACyhkADpHy8HBgcHPzw8c8qBJD2SPg1INqFoDeRZ24hBoTB9U2oOGv0Dm +gTwMSvIgz4NKfWI9Dzsi5z/SyrT///8xXL/1kMHU3BQY+8wMJ4CNravAOl9ZSfnP8RPHvgMjELSc +5inUfxixCRBALGj9gPvL+ssS7YrOrQKtudt//jVDMbCBAkriIABqURUXF4M9BurnIydB2AgOyPOg +wg1UrYH4oNhB3vEJ8jyoXAF5HlR342vo4GsEgpfZAhPzu4/ArvOHVwyCupA5g1WrVgIbRSpANz74 +//DhoxkMkPVEoKSPdU0RQACh2w5qH58SfFh56p1cq9kPBl5wCw12YhrI8+hNU1CsgzwJ2zMASvKg +LAEbVIHtG4DV56DqChT7sH1BsPKFlGUKoMWQn779B680u3HrDoO5oQHYnIPA9v6N6zcYXBwdGRYt +XPgVmA3vI8U+1kYNQABhC/5nG9furLIrat8DWtgEC4CAgACsngfJg2IctG8AFPuwsT1QXQ7yOKhw +Q97pCRvXA22YAJ2LRIrHQWEFOlEEVCyBzlB59/E7gxDXX1grkGHdmjUMOsB+xof3HxiuXr26HFrn +g2L/O66JVIAAwnqUDRBfvrnYsg/UInzw+BU4NkE9N3TPg5I4bPcXyPOwOh20FQa0cww0IgTZECUN +LPCkwBh0JhPoiBtS6nrwThGgq95+hhwm9OYr6Iyfvwyvnt6GT5ftPngAWN7cAtqpwHDrzi2GiKhY +FwbIAspPuGIfBAACCFc78+3L1z9XiLC//rfj6C2MghCUl0GFHSjmQUkeVOKDyglQlQYa8QUdmwTy +KD+/ADimQakAlPRh/X70EyLwl3yQWActp38P9DhoPwFI56+fPxhkRDmA9nKDlW1Yt57B2MgE2MZ4 +wSAkLMVgaGyuDh0m+4FvGh0ggHAFACjEbm6bmph18OI7BuTd5LB9QqB8Dsr3oMAQEBAEexoUw4KC +QuCkT+kmCvDxLX8g55KB8vubL5DVprDU9+zBTQZFYGCDwLbdu8C1jaqyCrBtcoNBQU6KQUddEWYM +3g4NQADhcyGov3xY7P+5j7ByAGL5P/BpX9+//wB6kBnsYVC7H1SwgVIBufv+0D3/Hhjm7z//Y3gH +Su7Qw7pALgDvRfj7k4HpzzuGNevXMazZuJFhy6bNDJampuC+B6htISElx8AvJscwceLkIEJ2AQQQ +E/7Ex3Bvz+bV9aA9Qoj6F3LSGMijoJIc1JSFleiUbpuB7QoDndX0DohBB4jBAgTkcdDaZEHO/wwf +XtwB2ivOcA/Yuzx//hywN/kQmPUUge2N2wzSMrIMmmoKDGqKUgzWdk7VDJDzgHACgAAiNNoA6g2d +BvbZ/wGTHRMs78ImJUB8ap0jAj4DEJTXf/4H7xBjZEDsPwB5nIcTkqq+ASv/r5/fMVy78YiBA1i2 +3Lt7l0FPW5fhDpCWkBRnkJFVYmDlFmf4+IMDWKfzgsb2QX2Dl7jsBQggYqLs/smTJ27Beoaw4/xA ++RxUqFHqefAOMWAZ+/LTf4ZXwFj/CvU8eA8B0OMivEwM3KCTvEBVKPM/hif3L4PPtr4PbIx9/gRs +agNbl5Cjyd8x8AnLMnAKyDL8ZeEHNvmYGPh4eBk8fYK08dkPEEDEBMCn/Pz86aBSHzYZARutwZXk +GdFoXB4HD0EDC7kXH4DJHZjX/0G334D2FIE8DtpDBB7t4WIEn5cGKndAVfI9YJJnBAbC08dPGJSA +SR80qvSHkZNBXFoR2BsVB3qcA1hjABsBn9kZotPK5iGfIIcOAAKImOgD+fwmrCBkgm57+Qvd3QGq +n3/9hZQN4H4T1GNMDBB5kEdBu0ZA2yQgZ7RDxL8CExSogANtkGCEbuIHJSbQ9jiYGlDMgzZn/QTW +/Rxs/xju3boMNucBMPa/f//G8ArYyVIwNWN4+OQlg6qaJugweYb3f/gYPr1hAqaW/wxvvzAzHLsn +CBoyB7XlsZ7hCxBAxAQAKPW9ffv+CwMb31+G33+ZgB7+D94OA9shBk4I/xHbZUD7BpihGynAaqDi +0L0S4MBhYERsjgKZwcsJ2jEG2VnCycYAPikRZAc7KyPDb2DA3n/2DVzt3n94H7xd7svnTwyyMjIM +n4DVMTsnL8NvLjmGrwzAzhUjO8P5+8DAevGPQYyfkeHHf3A/RhRXAAAEELEZ+M2TVx++cQn/5mJi +YQNvZwPV0d9/gUptSEkN2hYHa9b+Q/IYOCCQdoGBNleAT2UESjAz/gemCkbwJguQmSAZkOf/ADWA +jg/8/x+y2eoHMIk9un0B3Oh5/voVw3dganz98jV4y9yFG48ZZJR1GfiE5BhOPeIBFn7/wZuyQJEC +akCxsnMzVE7YMQWYDTyxbZ4ECCBiA+Dz0SOHD//h1XTn5mFBKaFh9SUjUqZnxkHDCjdwfQ4MOFCb +G+Tx/9CtNKAN0UyMsJ0nEFNBSfnPr+8MrAy/GK5cv8vw9dtX8F0+wP4+OEX8ZRFkePhNjuHtMyEG +Lj52BuSeNShSmJhZGR59l3GDDpljrC4FCCBiK+5v3S2VS379/A452hLN88g0uTUBAyx1MEK23cBM +/fkb2Od4fpHByMiYQUpWhuHLx88Mn4D9DkkJKYaDl94xvPkry8DGK8PAzsUL7lyhjx0oSTAzaCmA +F1IIYLMbIICITQGgOvDZD2Do//uHKAj/w/sGiC2zIDbIIyAOEzCJs4L2D4JikhGRD0AeBJcTwFj+ +9x+0fxBC/2eA7CeEtDoh+wh/AmP/9+dnDEdPfAGP+LwGdr6kxCWA3fPPDP/YgP0NUXkGDl4RBmYW +drCHQQWyALD2V5dhYlARhxROHz9yMJRV1oFOjcG4wAgggIgNAJCL3v0COgYUAP8ZIHe2gU5VZQWm +bw5WUOEF3SzJAKEhSZ0RvgEStDHyP9QkRkbYRktGaEqCjQkwQrMSRBzY+mIwt5QDjzBPmTKFYc++ +fcBW3wMGG0trhgVbrjAIyZkw8AjJMDCy8ALtYGJQFmNk0JAB1h5sv4F9lW8Mz55+Ae8h/A10t6GJ +RRKwHFiKvssMIIBIacW85f7/7r2UwB9BLtDmRQZEgYdcXcCqSPDuT1BMQ/cQM0PTOQsrKFVAPAra +LAkrI0ClP6g8ZWOGlAkgvadvfQMPxIDmC0BrB0FrCDrbOhhWrFjJwM4rycAhoMDAySvAYKr8l0GY +8w2wlfiF4cndjwys/78xPL5x7OmCOdMuALvqL6HjgfuxNU0AAoiUAPhyeM/6rRra+jHAJiB0Hz8D +tIUGSQnswBTBww6p70H7i1mQCiRQbQHaHg9K6qCzekF7C0E0qBAE6f3C8B+8hZaXiwl8aPCdFz8Z +7jz4AG5xgqa4QR0t0PgC6Hqlg1d/MEgr8TIYyf1iEBG4B+z1v/uxevuq6+vWrgbt/ngHHQR5Bh0Q +gW2kfMuAtOkKBgACiJRuG3gZ3ZHzj1cqyUuBW2mgqgrkSVAqAHViQB4CbZz8Br0h5e8/SMBwcUCy +BUg9JysjvO0AKi/AbYr/kOYw6BDblx//MTz98B9YwH0BtvNvMTzfUwjOAqBRaNC9evWds4F5/O+X +OzcvX3v58uVd6JDXS6hnn0E9C5v/+0FoDSFAAJGSAsDL6MR5fgA9D7l35jWw7Q5L6qCmKg/QgxIC +TPCNlKBTtsG7SH9B1IPO/PgBPRIYVEWBYh+8dfYvpCT9++83w5X7Xxku3vkMLPheMDy/vpPBztaW +wcDAADys3tPT8/Lq6ROg1SCgbXTHGSC7SGFzfQS3yWIDAAFESgCAC8L7z78x8IkAW1kCLPDqCpS0 +wUNVn0FJ+h+4kQQ+9/gXxHOgghMUUKB2DbhQBLXy/oMkfjH8+Qls4X36zPD+/QeGs7c+Mwj/Pv/r +4vq512/evHFfVFTU0ts4Txw09L5ixYrXJ06cOMgA2T0K2gYP2gz9gdJNEwABRGpX7u339w8f//uj +Ivv8HSPDp++QZP/tNyQ2QdkA3A+AlvL/oS3Bf/+BFSEwdln+/2D49xtYlX7/zPDzG7Aa+/WJYee+ +wwxb95xm4AU2V+7dvAHaGwyawQUdjfddR0fHH3Sjwfnz5790dnZuZoDsMgXtGb4JneKieMcIQACR +GgDfZsyas/KfiEUJOw8rOPkyQmMV3BZghJzYwMr0D9xyY/jzneHXj08MX4F1NqiEfvboHsPaLfsZ +7j5+ywDeWsspyMDHy/b/9c1ds4Gl1mGg+WegJfYPAQEB5cbGRsZp06b9XwEq9iGevgid4PxI6C4Z +YgFAAJE6dgXaNOC9aNeD9YIiUuDSn53lHwMHy18Gpr+/QPuHgc1U6F5iYCwfPX6cYe3WowxMrDzg +uUZWLiFgo0WCgZVbBDz19mZ/4pb7D94vgObnl0jjd+zd3d1P//79K1xVVdX379+/N9CkfxVawv+i +1sZJgAAiNQWAmu+v+FiAeZX1HTAZfwG3yF4Ae2QfXj/4smTBrKe33/Gpg3eFg2KYR4xBTCcQHNMs +QA8zs3ExMLNyMsh8nf96+ezp5VCP30ebsGRUUFAIAhZ8wgsWLHgD9Pwz6MzuTWgJ/4uBigAggMgZ +znnH9Ovjr80r1jyfMqnv3OfPn99CHQaKwe9WNiZ5v1VTtUCHgIM8zMTMBll3AxrYYHr+f2uPPWi9 +LCi5X4OO2aPnYzbQjpXU1NR/Dx48aIZmidvQ+pyqngcBgAAiZ/gWtA7HEUrD5t3eQj0DSiGWDkWn +d8NOpYOB55vc1t6+82YBNCm/wjFcDXKPILD0f/r69esMaODcgKaAj8iBRa0sABBA5G6f54Y65gcW +j4iJi7KXq8ceB19kKP15Nr7kjg5AoQZa3qLHANmBDkpZ16EzPDTZPQ4QQORkgf8M+Hdtvnn5+udy +B6Yz2St70uoIJHdsgcsEbdR8g3r8HaHJDUoAQADRas8baPBBCuqRVyR4ABQhoJlOPqgeWAsPYySH +WikAIIBotTsKFHt3yND3F+rhn1D2b2yepyYACKAhcb/AUAdycnKijx49ej0Y3QYQQCyj0UM6AK3H +vnbtmjILC4sRKyurAZDWB2I9ZmZmGdicEQyDJtJfvXr1DKgHdO7MF2pdjEEtABBAoyUAUqSeO3dO +gIeHxwgYmYbAyDMAYm1QBKNHKjImtBAAlABAa+MuXLiw2MfHB3SI0FtcRzsOBAAIIJaRELG3bt0C +5VBDJiYmUMTqAyNVF0gLIkck7Exv0GwvNc4GhfedWVnBK7iA7ohNTExcNH/+/OMMuE+QojsACKAh +WQKAIvXSpUuyXFxcoAgF51ZQEQzEirANV6A1C8gRTOnRvpQA0AJR0EIy0GHv9vb2oEtAX1Cy2Zua +ACCABlUCePHiBbesrKwhMKJAOdYYGHF60IhlJbcIHiwAtJwSVBVs2rSpMD8/fwF0RG/AT/ACCCAW +euRWYMrXBOZAI2h9qg+NVDH03ApaV4pv0c1gBaDVkqB7aEFHzYNORgAtJAJdLADaJQUazIdt8QZV +BQ4ODqA1a6C77b8TGBWhCwAIILJKAFCkXr16VYyNjQ25waQHjGB1WKSiF8MDWQRTC4Dm60ERDTrk +ZNasWeBiHQRAuz7KysoYsrKy8N5FAlpODyoFzp8/v9TPzw90ENqbgS4FAAKIBUcEMwEdZgX0TBe0 +e8MNikBYhMIaTEOpCCYXgJbdgnbAga4HAR3tA9rjCA0j8C455CtFCAHYwlJtbe1oYINwwWBoEAIE +ELYLpkDlL9CdfPLHjh07JSEhwYZvx9xwBKAtD6CDbUA5HHTQzbRp08DioP0dkyZNYkhOTh42DUKA +AMJW2YKPcv/06RPfoUOHzoACA3mR/HAFoJ0HoLr88OHD4MifPXs2+EIgUOSD1qWAdiGAGnLERD7s +jCvk01FgJ6SAxEElgbS0tFlvb28YKLMRc/YNrQBAAGFUAdDbFkFj2R/WrFmzzc7OzgpU5JO6g3mw +AVAEgLamwzYtgiIHtp0FtMIatOcXtBES+bQX0EKkAwcOoOwLxBXZyPcEwjCIj5xxYGMMoHAEhSew +BADdvQVa7AAK7x8DES4AAYS1EQhdUg46zVl33bp1U42MjBRBy9PIvQFqIABoExeo/gZFOqjeBh2b +AzqlDrSkFgZg13rBLnSD7YkE7X4D7XoH3XyJL8Jhm0BBy/ZBCQzGhsnDIh3WIIadxQhiw+5ZAzYq +lwUEBBQMVIMQIICwNgJBdRIwEYDmPF/vBQIgO4Uep2ZSCkCbVUFHkoAiG3RoBbCnAt6Z6+PjwxAT +EwNeYAra0kRO6x+2+R1WpIPCA4ZBRTss4kEAFOGgiIZFOPJBnKDIh+02Apmpo6MTBWwQzqd2g3Dt +2rWcoqKi7MCq5hOwe41z6BkggHB2A6EnCkoDsdHRo0cXKCgocIP2gVJ68ygtAOhIBlCdDToXBrRV +s6CgAHwIJ7nXQ8KKbVgRDsvZoMgG9fFBbQFQuwjEhm0DRz7uCdTnh20PhR0JBetBwbrDsKNjqN0g +BCb2TBMTkwZgqSICtBvUXf8PLOm+ysvL7wOGU0p8fPwbpJ7eP4AAwjcQBFqAA1rF8BLYGzgOTE0u +oAClxk5IagFQfzw8PJwhKCgIfOwsMNWTnKtx1eEwNqx4hx1uBDvgCLYdHnacJag9AcPIEY9vDASU +KEDVDzCCzCZOnBgCGiEERgzJI4TQRiSzoaHhNFNT04S0tDRW0FlFoARpbm7OePnyZV5glegPbNR7 +Aruuuc+fP58DLf1/AQQQzgSA1Bh8O2/evA3u7u4uIM9TY28gpQCU86ZPnw66bIXo3glyRMOKcljO +BuVoUOMPVH2ADlkDHfEFakMA++vgfj6ozw/SB0oIsLOUQIEL6haCIhA0wgeikTeDEzvwRekIIbTb +zqaurj4TiKOAPRcW0PEloMQHWk8Nqg5B7gFWMaBRSmZgKQ6KPNCarp+ghAMQQIRcCFukpbts2bJ+ +S0tLLVBjEHa501AYuUPvjoGOKwIN6IAwMEdgRAao8RcREQGOQFgVgNyaB+Vo2CEYoEiHnQkBuxSX +nBFP2AghMLIWBAYGgq5DfUtMKVBYWOgKtHtzZGQkE7AtwSIpKckIa+OAGr6ghAyK/BkzZoCOdfoH +jLsZwEQB2iUEWqYFag1/AwggQlkZtkTpNbD+2KOvr68FKv4Ge28AuZUOammDLgIGHfQDO10I1LVD +BqCtF6BhXNg5+MjTwrD6GnY7Kqw1D8LI9TslQ92wEUI9Pb0EYNtlKTC3HoN2DXEW90B1icASaFZU +VBT4wCLkk59BpRdoAAvU4wF1e4Hs/8CcvwMY+aCl5YLQOAUfJQEQQMRuFH6/aNGi/cAGRAzQoUKw +Ix8Ha44H5XSge8FHRoIOMwDlVFBggA43gwFQ9w90tT3oiEnk1jm2xho6Rk4c1JjjAOmHHZYILIFa +gQkgGBjRv9AbhNDinhWY42uA3dUaUMIFlsrgHWQwAGpUgo7wApUooAEs2CAUMOH/grbrQBjUgAGZ +/Q8ggIhJAH+hgxTf9+7ddUdGRsYMdizOYCoFQJEPyu2gIzJBI3pKSkoMLi4u4HvPQUd2woCWlha4 +iwg63AU54tFzPKzIhyUqbA1HWDVBjURAqEEIOhoUSLED3T8Z2F5JAs2cnjt/Dlx9gA6rAw1agfwD +mo0ERT5oTxVo/gJ0zzuwRAB5AHTkD2j1PmiZ8WdonP4FCCAWPEPEoP4eb3SUY9J3ibjGx+/52bdc +uckQ/AXSBQLVewPdGEQexgWd3Adq9IC2E4HugwYV+6BzHGEAJgY6zgi5yIZFNnp7AUbDqhPIMQmI +kTzkrh1swIfSRICrQQiLfNCwMTBidUE7Bt3c3cEnBcDAnIXzGXZs28HwH+hufz8/8FZK0IWcoHMj +GSB3z7yGRv5HaPUCKmH+AQQQC1qDD3QcOV96VlTPE664yM//xBgfg5M+sJ/L/h6YJIQYdh+7wRDq +xQ926GCYDQSdXgg6px6UIzw9PcFFPbDHApcHRdTmzZvBp5gin0qMbSQPNl4P4sOuhocV0bC6H1T1 +wc7GofbQOMhMUCkgJCQksnr16srQ0NBKYOSDimvQriye6OjoBGAjUR7ov19AdfABmWWrVzKcPH6S +4Sewd8QDrEZAp7aCzssFRj6oNzEJ2p0HRfwXaKICVQPgYg0ggFighvNlFOVvvc0YZv77Pyd4LwbK +anRGoGdZOMA7nvaeeczg4/gd3BWDtXwHCoBOZATduGJrawsu0svLyxnOnTsHlwctygDleuSiHHly +BuQHGIaN6sFyP6zBB/Ij7MZ45HO/kBt/1FzrAGsQAtsmKcB23kpgewB0KSMjsHuXAaz704ENcR7U +yF/NsH/vfnDjVglYDYAOcAMd0yssLPwNKDaXAbK95hU093+CFf2wqgUggECuBu3ikOHnZfA0Sz00 +4ScDD/Y69t9fhl9f3zB8fX2LoTpWjcHKRAvc+KB1WwCUw0ErbUBHboP666ChXdAxvLBxfFBktbW1 +YbTsZ86cyZCamgofwkUfyYNhUHUGy/WwuhgUwbBGGQzDunrIgzu0WrkEGyEERtIpR0fH6IKCgqT4 +uPhYdQ01EU5OLvilEUtWrmQ4CAybN69egaq+v3///Pm7b98+UAJ4B9S/mgGycRx0bCjo0FjQLjvY +2el/YAkAIIBge5FAFzEoA7FVQMma/nf/lLD67M/Pzwzf3z9k0JP4xFCR6gzueoBSK7USACiiQBfK +gCIblENBkQ27OQPWvQEdQwqKbNDp+/hGCIODg+E3dIAiHnYvC2jmDzThA+LDjiyHHYIFq4NhGDni +kXM7PQDIraA2zbp168+7u7tJamioCXBxcXPAjnpYtGI5OPLfv3nLoK+n9xcEDh8+/P/OnTvPnjx5 +soEBcnrAIyh+AY3878iRDwIAAcQCLexBRwmBtiD+2tATkhhd2Dv9MaMjF0YdxcIO3uh66tZzhvcf +P4NP6oKd9E0uAKV0UGSCIgY0IwdrdIFGrkCRTSoA3UYGGhqG3U4CimyQ2aC2AYgGBSzsOFdQZMKG +cUERDvIPKMFRY3CH0owAsvPmzVsMAUGBhlISEr+Bkc8Ki/yFy5YwHNh/kOHDu7cMBnr6f4DhBY58 +YO/gLjDyQXUeaFMx7MzcV9D4/Y5c9MMAQAAxorFBZ8yBLunSi80unfaQPVIErSJg+P39A8O3t/cZ +fI2ZGeKDbMClACgRkBJAoFwJGnYF5UJQZIOOogZFHHK/GHTlA2gWz8PDA9yyB/XniRnbB0UsKIJB +RT0o0kELWkAYFPmg4h5U1IPMh43mgSIcNHoGinzki4oGIuKR7xXaC8zdoKFoSdDIKycHA/QQHYZ5 +wAbeoQP7GT4Au7z6unp/gHr+AqtIUORffvr0KSzynzIgbr3+jF7vIwOAAMLmO1B5CxpW0guNDmx9 +KV6Lcubevz/AxtLHpwxsP+4xzKzxArcDQDmXmC4hqH8KGmsHRcSaNWsY5syZAxYH5T7QGeOgG6ZA +/XdiBnuQu23I3TdY5INyPigBgDAo14NKA5A62A0VsIgHYViuJ3UcnxaR/+3bd4YdO7YzGBgaAds4 +kgzcnJDMBTqAYu7ChQwHgdXfZ2CC1tXR+QN0Jyjn/wOG6Vlg428zNOKfMiC2FYNa/T/xHSgBEEDY +Yu0H1JDfq5euL7K1vZXNaLrYD55imIG5g52X4dNnbobj5+8wuNnxEuwSglqooBwPKupB9yyAgLq6 +OngaF7nLhmtYFxY4sEiGdduQaeSLqWAte9iULayBB8rZoFwOyu2g9gUo8kFuh1VjtO7W4pq3giRm +0FHM34Fd1k0MVpaWDBKgkpWDE9xCA3Xk5wJ7O4cPHQAdl/bf0FD/79cv3/+ePHXiH7CRfOzli5c7 +oXH2BGmw5wu0r493azZAALHgmQoGpaLfhw9f7VN56vJcLnBb+p//bOAz2ZhZucAHX+w5+YjBxkQd +5xWroGIX1E0DXWUCatiBWu2gC7RA3TNiFl8gT8fC6nQYBkUsSAw5ASAP4sDEQGbBJnBgK39gkQ/i +w7p4lDbuSF0yCTtg8Nfv/wxff/xl+PDpK8Pxg9sYbGxswYcBgop9kPyP/38ZFsybD2z4HmT4A/Sz +vr7e35/ff4HOz/h/7+69Y69fvd6JVN/DGnuwyCe4BxEggPCV23+gdciVO/feLbjTa/HAu2Rr2+d/ +kozM4MYgH8OVR88ZHj97Db/2BXmxyNatW8F1OAjExcWBZ97wzR8gT+Ag52RYLobNw8O6bLAEAksw +yO0H5BE62KgdyH2g3I5c38OmtglFPrXWwzJCT46DHbf5+88/8JF4X4F+O3pgK4M1MOeLiokwwHp6 +34D+nD8fmPMPHgKfKWhhYQlqzzCev3D+77lz53a+efPmKDDMnqDl/K/ERj4IAAQQMbOBoBQFGhv6 +sbXH+1VYybwZLxj0WZnZeRjYuIUYth+5xaAoJwmOGNhiEdDRdqALkUGrdEDXbBAzXQuLdNiiC1gf +Hbb4AjYsCzu2F3ZgM6ENKOgDOrArOZHre1oteIY5A2T+j98Q/A96NvDPv/+A/vvD8PHLV4ZH148y +uLm6Aksnfngm+gRM9AsXLgBHPsggcxMTcHg9e/6c6ezZsweA7alj0JwPi3xYzv9Nyu5jgAAi9tRc +0AgS6MSLX6t6khKj8xqmPWRx42PhEGA4eOEWQ0IApM6FzQ+A7kjEt1ADFvGw4h15cAaW40HisEkY +WA6GDcXCpmOREwGs/sbMzYjZO8yJH9pEPiP0pEDQ6X/gIxL/wU4U/A8+Dfj3b9BheX8YfoCOPr53 +msHezoaBm4cbHvnvgI3WRYsWMhw5dJiBCajRzNKMgYWZheHalcsM33/8YRQRFfsKTABvGBAnBcJy +/m9St54DBBAjiWpB3UTQ2S96EQkx3Q/Y45S+vr3LEO8kwBDkYQ7uEYASAa6GFPJwLKyIB0U67BJN +kBhs/B2Wa2Fr7GBj8LBIhyysZMKYxcM35YpMUz3SGSCRDiraYQcBgxMBMMJB9Tz85GRw++YPwzeg +v5/dPgFs8JmDqyYODkj1+PrjB4bFixYzHDl8mIGTg43B3sYe3Ja6desOw2+gefwCggw83FzfWptq +QRsULkO7e2SdlAgCAAFE6kD+b6hln65cuHRGT/qpxncea6lXL54xOJrKwxdCYgtkWB8dlLNBkQ0b +lQPRoIQAu0QQ1B0D1dNCQqA7dEWQWut8SMuuQPdssqHM3eObv0fG1MzlsMOTwcdhgs4J/QmJfNDx +9yD8/Tfk7G+YeuTI//DkAoOdnS3QT6C1FZCc//ztG4ZFCxcxHAW2lziACd3F0QnYTvjDcOPmbWAY +/WQQl5BkkJGRZZCRlmI1MTFh3rdv7y5oO+0XuUvKAQKI3BABDf2BBol0NdQls1g0SvwbknQZzI00 +wddooDf2YPU8YnQOMQYPm09HXlGLXEcPto2lIGeAzjr9CT0zHcT+BT75Fpg7oPU7NqeCMwAw8n98 +/cLw7M4J0A13DLygYXQWZgZxYWGG+0+egIewjx45wsAJTNzOzi4Mf//8Zrhw8SIw4/xlkJaWZJCT +lWOQkQVmNB5+0DUmf50dLE1AVTMw8r+Q6x+AAKIkVEHtB9DyImNWFobQjPLJSbnx7sBqQAKcU5Ej +DP2CeORVtbCiHrmIH5SRDj/iGMKGHIH8H3zOMy5Xwq5QAB2qyQwsPH///MZw/tR+BiUlZXBiOHnm +NMNnYPX3BZgoPn74wPD502fwnLwtsCsICi/QzCbo2HQxcSnw5JeCvAKDvLw0g7CQAMOf3+CdTmfs +7OxAYzSvyD09FCCAKA1hkP9A65GsgUV34PHjJ6JAq1NAfW1YNwx5QwX6PDusBQ9q5MH64oPhbABY +d+3PP8hBwKCGHOj6hp/QRhz0VHeMiIcc9s3IwAY6RRVYqrMxQY6C//3rN7DE+8pw8exhYOQJgi8I +uH7zOsMXYCkIvnkNiEG3IbABw0JPVw9s+K1bN8CXFcnISDPIy8kDc74cg5gE6IYmEQbQOZzfgI4C +jazu2Lwqpam+cjUwAXwix68AAURpaP+DTjZcBjbmDt27dw982xLyTciwljlshwzyxAtsxo3Y/jit +Ix3cev8LOt6ageEtsFB99ekf+BToN5//MXz4/g/coEPv3oEii42ZEXz3hygvE4MwDyP4PHEWYOSD +unygYvzPr68Ml88fAUaeADjSL127DOwh/GJ49+EdeE3DV2A7iBNY8oEi/y+wSnzy5DG4lBERl2YQ +EpNn4BKWZ2DmkWL4xSLM8PEPN8OPf6wMP/8D21qsPAy2Tt49oOoYupGHZAAQQNQI8b/QRHBtxYoV +20GtetgdpMh9ceTtUrB5dXoMvxIzGgfK6V++Q+4rewmMdNDB7W8+/wXfXQYq6hlhuR0pwvk4IXcb +ifBAIh90ODxIEYgGXfYkxM0ATAh/GP79/sJw6vgh8GAZqLdz4/ZNYCn4h+Hp86cMTx48YvgFDCte +8FpAefC8BehiiJfvvjFwC0oyCIorALE8A+hsZm5+YciFdMCeAeSKIdDN19wMn/7xCkyau6YWNKVC +zi5jgACiVsiDmrGgBWpmwGpgAbC+YgdtI8M1TYwS3/8xXfEfS0MKXQybGhSz/iNu80DhQ5WBDrMH +Fe+gbhuoLod11ZBzN0w9GyvkFi9WFkYUp4IOx2cHi0PYoIQEOigfVMT/Bub8Xz++MFw8f5aBm4sL +XNdfv3mTgRGoEDQ3Arr27BuwMcwPLAVBRTzILlDv4MXbb8CiXhKcIBTk5RkkJaUZePgEGX4zcTF8 +/8PK8OUXpDriZmcEJs5/DN+/fmT48uHt31gvTV3Q4g9gVfCNlIgDCCBqreoEzR2A1pw9OXXq5Glh +YSEbXl4eBhZW0C5YRshFGv8gl+OAijbQlSiw2wL+/oXcRAKuLf8zgtWAAuM/9H4qBuigCuwseiZo +1wt2NRMT9Daif9A7msB3VcEqcQZIfQyrWVjAF/NArmT59RvSgkdOM7Dj30GRycHGBG28QYo4UAYH +JQA26A0p4ET0B2QeyC+QhAG+RAAo/wvYL/z44QvDpfPHwLkbVMzffvCAgR2Ye9++e8vwCHT7GTC3 +CwG7t7LAbh24ewy6DhpY9ygBG3kikgoM3MKyDF9YJBmefONnYP/PCUyELODBpE/A7ubrj0D8CZT4 +/jPcf8HO8P0LO3P5xP2LOvMd/YClwE9SGoQAAVg7gx6CYSiO/4sEkxEjNjvgS/gwvpOvIOLuzNXd +wVEiMTcO2AxLNMO0fR2uEocemiZNmn/z3vu/NP39M/bKByQdMbrT2WJYqdrMrFgiCuTeQLBUlu/u +mxQ6TiEk4oRSR+WmnsTXUUIn9B8/vsRn+kIkTC8yEovIbNLzE7tDYqrImol5hr2RFkponfdTpld6 +UdT+6v//D/JK4nFojaGQT1DSeKv4Qc6AikUiTF6jC/beXNU3fhBguV7BKBrwjz48b43zKUTTbijw +Ib9xYSljbLYhypaLmtOG7bZg1R1kClWE3MDulBUpSdOg2AeyZIpaQ/Yf7jwCjw7gy0FvPOpPfikI +XwKImuu6f0CHJJ8+fXz/wR8mXsXfTDwMzMBQ/AfNdX//IW6bQekv/0esQWVEaoVjqMNeY0DrA9S6 +AFFF/IcnOlAigJUW/xkQF7/Brv+B3W32FzpCxsyMsBtUt7Mywdo0kMTBBG0cgC6KAJU8v4Fds2/A +Bt2rB8DI5+ECXwVy/fYt8DD250+fQBc8M7wHJgJxUVFonf8JPMDz8M0vBmExaQZOIXmGL8wyDC9f +iTP8fsMPbO1zgOt6ZmgpxobWYgNFvpQgE8PTd5wMzL+B7QiTyBkMC3sMgaXAD/Q7knABgACidusL +tB9bxcTcxj+pdEqdsKgEsKUvAGzhM2EclI5SCqDX4wyUXUdG+8UbiITxF5q6/v35BayPPzNwfzkP +vujuNbBrd+XGVWDk84AHve7fuwe+8lBESBi8FgI0FvL563eG07eB+YZTioFdQI6BV1iOgUdAnIGD +W5CBhY0TGOks2EeVkNzBDE0UX779YPj77Q2DEtOJvtbyuDZQZiRmdBAggKi9swO8m/jMySNnU/+8 +//zzBz8vByc3+GozYiP/PzHTskh9cNj9NOCSA6k9ALu2EXZzIUwvuJ6H5nKG/6hdQORr4KCFA+SW +M6g5DFA1sO4TI/RGwN+gCa2v7xj4v19lUFJWAq9aBk3u+P8PYti0eRP4mufHjx8ySAH78ZqaWuD7 +L998/MFw5NoPBl4haQZeEXkGHiFZBi4+cWDDHphhQHdtMDJjRD6sBAUJg25aFONnAnY9GRjkREGT +WtwM/37+ZvjxxSQfqHQWNC6+E4owgACiRf8LdNWDenZhdam+fWSgELAU4OLmBde/yJEIrsuRingm +eEQwQu/Y/A9udIEaVsyMSA0+RsiVdCxMsMiFVAqM0DodcicXpEEJa9QxIl1kBBcDLXj4zwC92Q0S +o///wa61Q5q4+Q9xNxO0OgG1ARABB7rf7yfDlJ46hucPb4BXItvZ2QEjn5fh+YvnDAcOHWI4euwo +w7PHTxjkgInCxNgEvD7x8cuPDOcf/AdffccL7ONzC8owcPGLM7BzCTAwA3M+sKUCbNZArtAD9UD4 +gd1KcX5GBlEg5mUHNUb/gy9j+gdeDgdZ/AIab/j1E9ie+PGNgf3Hw21x4V5JoLklQrODAAFEi71d +4FJgan/r6lk2gX6/fnxn5uHmAqZYFgZ2ZkhLmgXauobVoUxMiEiBRdR/2DJIRuyLMuANSgZGlJQM +0/sfaaQKXM//Q5QU/5mQruWGDdn+Q1IPbRWC3McCvdIT3EYA8llZGaFtDFDk/2J4/uwlw7wZ/eB6 +HtSaBxX3sDGOH8Cu3/tXrxnMTM3AmzZA3b+bD14z3H7NgYh8YGufi1eMgY2THzwgJsjDxCAh8B+Y +s/8BI/sv+D61nz9+gRuKvz78ZHjx+yewxIFgJoY/DOwM3/68f/Xg04M7116fP3v6PrAXBrqUBrQ7 +hgfaM8N7+BRAANEiAYC2I4GWIT///ebqVTEpPj0R3j9Az7GCh0n//8cs6sGlwX9E5CNyHFoxzAQd +V4eWAuAWMTP0qkKkRASyB3SRLKjUgVxmCb30khF+gxHYnj/QIogZGMvg3shfyAW2sCvPwJdc/4a0 +vkFXG4ISL0ju3ee/DE/e/GR49e4Tw5YV88Dmgep10A4l0CAYqNsH2phqb2/P4O/vD96rD9qxu33/ +GYY/PGoMXAKSwFwvxSAiIswgLcHBICX2i0GQ6y3QDX/AufjHO6DZb/8wfGT88ffTm8ef79+58vrC +udMvjh879hwaod+hGe0bdHb2CzSyQYtC3kIH5t4yoF20gw0ABBCthuBAqU9JRlbOccbCLRNExMQZ +eICNQSZQbP1H3C0NijjYXZOgVjUogEFKQGxYVwdl3Pk/JIJAd9SBIu8ftA/+9z9kfAHUJYPdZghK +JGB5aGMAfMcltBvIAG0rgIZrQXdeguz/D78Z9T+YD6vz/0LNff3pP8ODN//ALe+Pn38y3Hn6heHW +/dcMW3pcGfh52MF7EUBL5EEJABT5IDbotLGHwD4/GxsHQ3nbPAYuYNUgJirCICslBox0gX/MwM7b +8yf33ty4dvn5yRMnnv38+fM7lsj9zIDY2/eZAXGhEEztD+g0PQz/IWVqGCAAbWewgjAMg+EyC3pS +BnrydXw194bzsOMUEaZDRTdmm9YkbezAq556Lfz52yYh/f413ksbaw/7ulL9qcln89V6ucBcOHX4 +nA+FFOJnykrERRFRHluTLKRgGu89zc5Wn2CZor11pr4iRWoF3oWikyCuYYS0JGGfjKxMxNcBAgzd +R6Kzxfv+ZRwH3QVdXx0tOt+oDo922595PsKZDp2/4TY4tbZpQJXKvvT5FnX0tkVx25XlFQAe8WQk +ZzYqQU3b6Nz7SHQReIiiykw//Bo28RZAtEoAf6HF0ps1q1esj0stSvv69yuwMQhausUEabAxQe4Q +B12UDrqLmA+YOFiYGbBGJCRRMIJzPijyQJH47wcoIv+Bb7IHzdD9/c8AH0kEJag/0NwPHkz6C6GR +hh3ACewvtG5hBDakgOUFuEH1B6j5/79fwAbWL4bHr38x3H7yneH1+x/gbh4z4y8GEa4f/7m/P/j5 +8uGFj7dP7Gc2MTERAZ0IDlrHACryQQ0yUOSvWrXqxYoVKx5CI/0FdPkWiA+76BW2hu87tKj+MxA3 +iQAEEC1nYWDHzBmePHlqmaysDBtsfgA0/PsbWrT+/ou4ffcndFEFePj4P0IOrB46nAzr4kE7Coiu +IAN6V/A/9Cpx8NgiOJKB2RW0swUoB4xgYGPq31/QTN1Pho9ffjB8+fETfOPnr69vwcX2nVs3GW5c +2PPx/r1H95Dq1jfQnAqKtP/Aer/Cx8eHE5QATE1NYUezvC8pKTkC1QO72Re2OfMlA2J//u/BcHUM +QADR8oQH2PzAqz37Dx0xsfF24nnPycDGzg0dj4dE7p9//+GLJv/C+/T/4d035L4+A3w+ADpDB6KB +EczE+JeB6T+o7Aa12H6B8e8/wJbyT9A28J/gSGYElqCf3r9luHv/IcOVG/cYrt1+zPDl22/wfkcQ +Bu114Gd+8efx9f1XP378Cbql9DE04p5Bi+wP0OIZ5BJuYMRnAxt4nKCt2KAEA8z5PwsKCtYDq4Ef +0ITyHJrrnzEgVu1+hYbL38FwWQQIAAQQredhwfMDHJyc5v2Lj8zjFRBn4BUQAq9wRYlc2OwadPiV +BdSCByUCYN+MmfEfPOf+h0bsH3A36DfDDyANajUzAiP/88d3DPfuP2C4fus+MHKfMLz/9B18cSkT +KwcwgjmBEcwBub2VjZuBhY0HTLMBO9kiP3a/37VxLWg3Leh2x3vQiH/JgNhQ+QdpvIqFiYmJz8/P +b0JKSko0sMvHdOzYsX9AfP4UsP8FVf8GKeJhW7Q+Q+vzP4Ml4mEAIIBofcYLeH7gx/fvj3+9v3vn +Hw+vCjsTDwMX9KZ5pv9/wZH3Dxi5oCVOf0B93O8/wf1r0PIxEP7/H7SO7hP4HL9rN+8zXL35iOHt +x2+QLWosHOAIBl3JC8agyGWXYmCVVmWQVOCCyEHVMDEDczow4fGyvv3PcHvipZ3rD69ggNxlirF3 +HsdINDM3N7coMNfPiYmJ8fj48SPTyZMn/+7cuXMjMFIvI0U+LOJfQyMeloj+MQxCABBAtE4A/6DF +3tvVi6YsLavrq//74TvDuz+/oQtCgXXw98+/nzy6/f761cuvTp449uzmzZvvYMUkdJ2BhIZdotNf +NklgnIsxsEgqMkjIQSMcnLs5IMU4Myuw/geWLEwgmhmImeAFnCTDsV/nNjVsvn3nzQEg9wEDYjMF +/MQMAqUkyDBOaWnpCmAR73rgwAGmT58+/QFG/hxgwrwJa/BCzYSVHt8YEDd/DtqpDYAAYqRTIgOd +PK4FxAbQhiEb2iAGbCADdo4NrBsECnhRINYMzp3Y85LRnA09crFaCGyti39aCLq1eCG0aH8IzZmw +7dKkXMkKPqBJSkoqRFhYuB/Y0BN8+vTpdGBVcBOYGH5CzXsNjfg3aIkKI+IH2y1tAAFEr7VY7NCZ +QtAqYg5o4MPOyP8JzfF/YH1dpICDHWEDOrBfPyavevojlmCsx32DLif/d6Pr4vYtB5dDc/ljIot2 +fIAJ6nbQhcZmQJwKxCsZIMviGdByPnJdjzNxDbYEABBAQ+Hwf0ZoogHvSIpMiut+KlCgDCnaTwCL +9jpyi3ZiSy/QbijQETrC0ATMA3XTD6SBnY9ILXy8JctgSwAAATSULgIC5UTQZhR5aJXCBA3852QW +7cSEDTM0AYBKIW4oZmVAHJ4Ji/gfxJYwgy0BAATQULo69ic0sl9DI+Y/NND/0qiR9R+amGAN0p/Q +CGeAjdwhVVv/GQb3GhacACCAWIbY1bGwCKEL0NTU/A+1jxGaABiRIvs/NEcP6du0AAIMANtMxR3x +N38FAAAAAElFTkSuQmCC\ +""" + +def thumbnail(): + icon = base64.decodestring(iconstr) + return icon + +if __name__ == "__main__": + icon = thumbnail() + f = file("thumbnail.png","wb") + f.write(icon) + f.close()
Property changes on: trunk/pywikipedia/odf/thumbnail.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/userfield.py =================================================================== --- trunk/pywikipedia/odf/userfield.py (rev 0) +++ trunk/pywikipedia/odf/userfield.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,169 @@ +#!/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() +
Property changes on: trunk/pywikipedia/odf/userfield.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/odf/xforms.py =================================================================== --- trunk/pywikipedia/odf/xforms.py (rev 0) +++ trunk/pywikipedia/odf/xforms.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,34 @@ +# -*- 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)
Property changes on: trunk/pywikipedia/odf/xforms.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/INFO =================================================================== --- trunk/pywikipedia/openpyxl/INFO (rev 0) +++ trunk/pywikipedia/openpyxl/INFO 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,3 @@ +https://bitbucket.org/ericgazoni/openpyxl/downloads +https://bitbucket.org/ericgazoni/openpyxl/get/1.5.6.tar.gz +ericgazoni-openpyxl-e5934500ffac.tar.gz
Added: trunk/pywikipedia/openpyxl/LICENCE =================================================================== --- trunk/pywikipedia/openpyxl/LICENCE (rev 0) +++ trunk/pywikipedia/openpyxl/LICENCE 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,34 @@ +This software is under the MIT Licence +====================================== + +Copyright (c) 2010 openpyxl + +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. + +Odict implementation in openpyxl/writer/odict.py uses the following licence: + +Copyright (c) 2001-2011 Python Software Foundation + 2011 Raymond Hettinger +License: PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 + See http://www.opensource.org/licenses/Python-2.0 for full terms +Note: backport changes by Raymond were originally distributed under MIT + license, but since the original license for Python is more + restrictive than MIT, code cannot be released under its terms and + still adheres to the limitations of Python license.
Added: trunk/pywikipedia/openpyxl/README =================================================================== --- trunk/pywikipedia/openpyxl/README (rev 0) +++ trunk/pywikipedia/openpyxl/README 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,108 @@ +OpenPyxl is a Python library to read/write Excel 2007 xlsx/xlsm files. + +It was born from lack of existing library to read/write natively from Python the new Open Office XML format. + +All kudos to the PHPExcel team as openpyxl is a Python port of PHPExcel http://www.phpexcel.net/ + +== User List == +Official user list can be found on http://groups.google.com/group/openpyxl-users + +== Contribute == +Any help will be greatly appreciated, there are just a few requirements to get your code checked in the public repository: +* Mercurial bundles are the preferred way of contributing code, compared to diffs written in a text file. Forks are encouraged, but don't forget to make a pull request if you want your code to be included :) +* long diffs posted in the body of a tracker request will not be looked at (more than 30 rows of non-syntax highlighted code is simply unreadable). Please attach your bundle files to the issue instead. +* every non-trivial change must come with at least a unit test (that tests the new behavior, obviously :p). There are plenty of examples in the /test directory if you lack know-how or inspiration. + +== Easy Install == +Releases are also packaged on PyPi, so all you have to type to get the latest version is: + + $ easy_install openpyxl + +== Features == + +** Supported data types ** + * String (shared, Inline not currently supported) + * Integer + * Float + * Date + +** Supported Excel features ** + * Names ranges + * Number formats (built-in and custom formats) + +** Handy features ** + * Implicit conversion between Python types and Excel types: + * Dates + * Floats + * Percentages + * Optimized modes to read and write extremely large files + +== Python 3.x support == + +Openpyxl supports python (even if some tests can fail on 2.4) from 2.4 to 2.6. If you use a more recent version of python, please use the hjunes fork you can find here : https://bitbucket.org/hjunes/openpyxl/. + +== Full documentation== +With tutorial, examples, API documentation: http://packages.python.org/openpyxl/ + +== Quick Examples == + +=== Write a workbook === + + #!python + from openpyxl.workbook import Workbook + from openpyxl.writer.excel import ExcelWriter + + from openpyxl.cell import get_column_letter + + wb = Workbook() + + dest_filename = r'empty_book.xlsx' + + ws = wb.worksheets[0] + + ws.title = "range names" + + for col_idx in xrange(1, 40): + col = get_column_letter(col_idx) + for row in xrange(1, 600): + ws.cell('%s%s'%(col, row)).value = '%s%s' % (col, row) + + ws = wb.create_sheet() + + ws.title = 'Pi' + + ws.cell('F5').value = 3.14 + + wb.save(filename = dest_filename) + +=== Read an existing workbook === + + #!python + from openpyxl.reader.excel import load_workbook + + wb = load_workbook(filename = r'empty_book.xlsx') + + sheet_ranges = wb.get_sheet_by_name(name = 'range names') + + print sheet_ranges.cell('D18').value # D18 + +=== Number Formats === + + #!python + import datetime + from openpyxl.workbook import Workbook + + wb = Workbook() + ws = wb.worksheets[0] + + # set date using a Python datetime + ws.cell('A1').value = datetime.datetime(2010, 7, 21) + + print ws.cell('A1').style.number_format.format_code # returns 'yyyy-mm-dd' + + # set percentage using a string followed by the percent sign + ws.cell('B1').value = '3.14%' + + print ws.cell('B1').value # returns 0.031400000000000004 + + print ws.cell('B1').style.number_format.format_code # returns '0%'
Added: trunk/pywikipedia/openpyxl/__init__.py =================================================================== --- trunk/pywikipedia/openpyxl/__init__.py (rev 0) +++ trunk/pywikipedia/openpyxl/__init__.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,53 @@ +# file openpyxl/__init__.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Imports for the openpyxl package.""" + +# package imports +from openpyxl import cell +from openpyxl import namedrange +from openpyxl import style +from openpyxl import workbook +from openpyxl import worksheet +from openpyxl import reader +from openpyxl import shared +from openpyxl import writer + +# constants + +__major__ = 1 # for major interface/format changes +__minor__ = 5 # for minor interface/format changes +__release__ = 6 # for tweaks, bug-fixes, or development + +__version__ = '%d.%d.%d' % (__major__, __minor__, __release__) + +__author__ = 'Eric Gazoni' +__license__ = 'MIT/Expat' +__author_email__ = 'eric.gazoni@gmail.com' +__maintainer_email__ = 'openpyxl-users@googlegroups.com' +__url__ = 'http://bitbucket.org/ericgazoni/openpyxl/wiki/Home' +__downloadUrl__ = "http://bitbucket.org/ericgazoni/openpyxl/downloads" + +__all__ = ('reader', 'shared', 'writer',)
Property changes on: trunk/pywikipedia/openpyxl/__init__.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/cell.py =================================================================== --- trunk/pywikipedia/openpyxl/cell.py (rev 0) +++ trunk/pywikipedia/openpyxl/cell.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,397 @@ +# file openpyxl/cell.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Manage individual cells in a spreadsheet. + +The Cell class is required to know its value and type, display options, +and any other features of an Excel cell. Utilities for referencing +cells using Excel's 'A1' column/row nomenclature are also provided. + +""" + +__docformat__ = "restructuredtext en" + +# Python stdlib imports +import datetime +import re + +# package imports +from openpyxl.shared.compat import all +from openpyxl.shared.date_time import SharedDate +from openpyxl.shared.exc import CellCoordinatesException, \ + ColumnStringIndexException, DataTypeException +from openpyxl.style import NumberFormat +from openpyxl.shared import NUMERIC_TYPES + +# constants +COORD_RE = re.compile('^[$]?([A-Z]+)[$]?(\d+)$') + +ABSOLUTE_RE = re.compile('^[$]?([A-Z]+)[$]?(\d+)(:[$]?([A-Z]+)[$]?(\d+))?$') + +def coordinate_from_string(coord_string): + """Convert a coordinate string like 'B12' to a tuple ('B', 12)""" + match = COORD_RE.match(coord_string.upper()) + if not match: + msg = 'Invalid cell coordinates (%s)' % coord_string + raise CellCoordinatesException(msg) + column, row = match.groups() + row = int(row) + if not row: + msg = "There is no row 0 (%s)" % coord_string + raise CellCoordinatesException(msg) + return (column, row) + + +def absolute_coordinate(coord_string): + """Convert a coordinate to an absolute coordinate string (B12 -> $B$12)""" + parts = ABSOLUTE_RE.match(coord_string).groups() + + if all(parts[-2:]): + return '$%s$%s:$%s$%s' % (parts[0], parts[1], parts[3], parts[4]) + else: + return '$%s$%s' % (parts[0], parts[1]) + + +def column_index_from_string(column, fast=False): + """Convert a column letter into a column number (e.g. B -> 2) + + Excel only supports 1-3 letter column names from A -> ZZZ, so we + restrict our column names to 1-3 characters, each in the range A-Z. + + .. note:: + + Fast mode is faster but does not check that all letters are capitals between A and Z + + """ + column = column.upper() + + clen = len(column) + + if not fast and not all('A' <= char <= 'Z' for char in column): + msg = 'Column string must contain only characters A-Z: got %s' % column + raise ColumnStringIndexException(msg) + + if clen == 1: + return ord(column[0]) - 64 + elif clen == 2: + return ((1 + (ord(column[0]) - 65)) * 26) + (ord(column[1]) - 64) + elif clen == 3: + return ((1 + (ord(column[0]) - 65)) * 676) + ((1 + (ord(column[1]) - 65)) * 26) + (ord(column[2]) - 64) + elif clen > 3: + raise ColumnStringIndexException('Column string index can not be longer than 3 characters') + else: + raise ColumnStringIndexException('Column string index can not be empty') + + +def get_column_letter(col_idx): + """Convert a column number into a column letter (3 -> 'C') + + Right shift the column col_idx by 26 to find column letters in reverse + order. These numbers are 1-based, and can be converted to ASCII + ordinals by adding 64. + + """ + # these indicies corrospond to A -> ZZZ and include all allowed + # columns + if not 1 <= col_idx <= 18278: + msg = 'Column index out of bounds: %s' % col_idx + raise ColumnStringIndexException(msg) + ordinals = [] + temp = col_idx + while temp: + quotient, remainder = divmod(temp, 26) + # check for exact division and borrow if needed + if remainder == 0: + quotient -= 1 + remainder = 26 + ordinals.append(remainder + 64) + temp = quotient + ordinals.reverse() + return ''.join([chr(ordinal) for ordinal in ordinals]) + + +class Cell(object): + """Describes cell associated properties. + + Properties of interest include style, type, value, and address. + + """ + __slots__ = ('column', + 'row', + '_value', + '_data_type', + 'parent', + 'xf_index', + '_hyperlink_rel') + + ERROR_CODES = {'#NULL!': 0, + '#DIV/0!': 1, + '#VALUE!': 2, + '#REF!': 3, + '#NAME?': 4, + '#NUM!': 5, + '#N/A': 6} + + TYPE_STRING = 's' + TYPE_FORMULA = 'f' + TYPE_NUMERIC = 'n' + TYPE_BOOL = 'b' + TYPE_NULL = 's' + TYPE_INLINE = 'inlineStr' + TYPE_ERROR = 'e' + TYPE_FORMULA_CACHE_STRING = 'str' + + VALID_TYPES = [TYPE_STRING, TYPE_FORMULA, TYPE_NUMERIC, TYPE_BOOL, + TYPE_NULL, TYPE_INLINE, TYPE_ERROR, TYPE_FORMULA_CACHE_STRING] + + RE_PATTERNS = { + 'percentage': re.compile(r'^-?[0-9]*.?[0-9]*\s?%$'), + 'time': re.compile(r'^(\d|[0-1]\d|2[0-3]):[0-5]\d(:[0-5]\d)?$'), + 'numeric': re.compile(r'^-?([\d]|[\d]+.[\d]*|.[\d]+|[1-9][\d]+.?[\d]*)((E|e)-?[\d]+)?$'), + } + + def __init__(self, worksheet, column, row, value=None): + self.column = column.upper() + self.row = row + # _value is the stored value, while value is the displayed value + self._value = None + self._hyperlink_rel = None + self._data_type = self.TYPE_NULL + if value: + self.value = value + self.parent = worksheet + self.xf_index = 0 + + @property + def encoding(self): + return self.parent.encoding + + def __repr__(self): + return u"<Cell %s.%s>" % (self.parent.title, self.get_coordinate()) + + def check_string(self, value): + """Check string coding, length, and line break character""" + # convert to unicode string + if not isinstance(value, unicode): + value = unicode(value, self.encoding) + # string must never be longer than 32,767 characters + # truncate if necessary + value = value[:32767] + # we require that newline is represented as "\n" in core, + # not as "\r\n" or "\r" + value = value.replace('\r\n', '\n') + return value + + def check_numeric(self, value): + """Cast value to int or float if necessary""" + if not isinstance(value, NUMERIC_TYPES): + try: + value = int(value) + except ValueError: + value = float(value) + return value + + def set_value_explicit(self, value=None, data_type=TYPE_STRING): + """Coerce values according to their explicit type""" + type_coercion_map = { + self.TYPE_INLINE: self.check_string, + self.TYPE_STRING: self.check_string, + self.TYPE_FORMULA: self.check_string, + self.TYPE_NUMERIC: self.check_numeric, + self.TYPE_BOOL: bool, } + try: + self._value = type_coercion_map[data_type](value) + except KeyError: + if data_type not in self.VALID_TYPES: + msg = 'Invalid data type: %s' % data_type + raise DataTypeException(msg) + self._data_type = data_type + + def data_type_for_value(self, value): + """Given a value, infer the correct data type""" + if value is None: + data_type = self.TYPE_NULL + elif value is True or value is False: + data_type = self.TYPE_BOOL + elif isinstance(value, NUMERIC_TYPES): + data_type = self.TYPE_NUMERIC + elif not value: + data_type = self.TYPE_STRING + elif isinstance(value, (datetime.datetime, datetime.date)): + data_type = self.TYPE_NUMERIC + elif isinstance(value, basestring) and value[0] == '=': + data_type = self.TYPE_FORMULA + elif self.RE_PATTERNS['numeric'].match(value): + data_type = self.TYPE_NUMERIC + elif value.strip() in self.ERROR_CODES: + data_type = self.TYPE_ERROR + else: + data_type = self.TYPE_STRING + return data_type + + def bind_value(self, value): + """Given a value, infer type and display options.""" + self._data_type = self.data_type_for_value(value) + if value is None: + self.set_value_explicit('', self.TYPE_NULL) + return True + elif self._data_type == self.TYPE_STRING: + # percentage detection + percentage_search = self.RE_PATTERNS['percentage'].match(value) + if percentage_search and value.strip() != '%': + value = float(value.replace('%', '')) / 100.0 + self.set_value_explicit(value, self.TYPE_NUMERIC) + self._set_number_format(NumberFormat.FORMAT_PERCENTAGE) + return True + # time detection + time_search = self.RE_PATTERNS['time'].match(value) + if time_search: + sep_count = value.count(':') #pylint: disable=E1103 + if sep_count == 1: + hours, minutes = [int(bit) for bit in value.split(':')] #pylint: disable=E1103 + seconds = 0 + elif sep_count == 2: + hours, minutes, seconds = \ + [int(bit) for bit in value.split(':')] #pylint: disable=E1103 + days = (hours / 24.0) + (minutes / 1440.0) + \ + (seconds / 86400.0) + self.set_value_explicit(days, self.TYPE_NUMERIC) + self._set_number_format(NumberFormat.FORMAT_DATE_TIME3) + return True + if self._data_type == self.TYPE_NUMERIC: + # date detection + # if the value is a date, but not a date time, make it a + # datetime, and set the time part to 0 + if isinstance(value, datetime.date) and not \ + isinstance(value, datetime.datetime): + value = datetime.datetime.combine(value, datetime.time()) + if isinstance(value, datetime.datetime): + value = SharedDate().datetime_to_julian(date=value) + self.set_value_explicit(value, self.TYPE_NUMERIC) + self._set_number_format(NumberFormat.FORMAT_DATE_YYYYMMDD2) + return True + self.set_value_explicit(value, self._data_type) + + def _get_value(self): + """Return the value, formatted as a date if needed""" + value = self._value + if self.is_date(): + value = SharedDate().from_julian(value) + return value + + def _set_value(self, value): + """Set the value and infer type and display options.""" + self.bind_value(value) + + value = property(_get_value, _set_value, + doc='Get or set the value held in the cell.\n\n' + ':rtype: depends on the value (string, float, int or ' + ':class:`datetime.datetime`)') + + def _set_hyperlink(self, val): + """Set value and display for hyperlinks in a cell""" + if self._hyperlink_rel is None: + self._hyperlink_rel = self.parent.create_relationship("hyperlink") + self._hyperlink_rel.target = val + self._hyperlink_rel.target_mode = "External" + if self._value is None: + self.value = val + + def _get_hyperlink(self): + """Return the hyperlink target or an empty string""" + return self._hyperlink_rel is not None and \ + self._hyperlink_rel.target or '' + + hyperlink = property(_get_hyperlink, _set_hyperlink, + doc='Get or set the hyperlink held in the cell. ' + 'Automatically sets the `value` of the cell with link text, ' + 'but you can modify it afterwards by setting the ' + '`value` property, and the hyperlink will remain.\n\n' + ':rtype: string') + + @property + def hyperlink_rel_id(self): + """Return the id pointed to by the hyperlink, or None""" + return self._hyperlink_rel is not None and \ + self._hyperlink_rel.id or None + + def _set_number_format(self, format_code): + """Set a new formatting code for numeric values""" + self.style.number_format.format_code = format_code + + @property + def has_style(self): + """Check if the parent worksheet has a style for this cell""" + return self.get_coordinate() in self.parent._styles #pylint: disable=W0212 + + @property + def style(self): + """Returns the :class:`openpyxl.style.Style` object for this cell""" + return self.parent.get_style(self.get_coordinate()) + + @property + def data_type(self): + """Return the data type represented by this cell""" + return self._data_type + + def get_coordinate(self): + """Return the coordinate string for this cell (e.g. 'B12') + + :rtype: string + """ + return '%s%s' % (self.column, self.row) + + @property + def address(self): + """Return the coordinate string for this cell (e.g. 'B12') + + :rtype: string + """ + return self.get_coordinate() + + def offset(self, row=0, column=0): + """Returns a cell location relative to this cell. + + :param row: number of rows to offset + :type row: int + + :param column: number of columns to offset + :type column: int + + :rtype: :class:`openpyxl.cell.Cell` + """ + offset_column = get_column_letter(column_index_from_string( + column=self.column) + column) + offset_row = self.row + row + return self.parent.cell('%s%s' % (offset_column, offset_row)) + + def is_date(self): + """Returns whether the value is *probably* a date or not + + :rtype: bool + """ + return (self.has_style + and self.style.number_format.is_date_format() + and isinstance(self._value, NUMERIC_TYPES))
Property changes on: trunk/pywikipedia/openpyxl/cell.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/chart.py =================================================================== --- trunk/pywikipedia/openpyxl/chart.py (rev 0) +++ trunk/pywikipedia/openpyxl/chart.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,339 @@ +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +import math + +from openpyxl.style import NumberFormat +from openpyxl.drawing import Drawing, Shape +from openpyxl.shared.units import pixels_to_EMU, short_color +from openpyxl.cell import get_column_letter + +class Axis(object): + + POSITION_BOTTOM = 'b' + POSITION_LEFT = 'l' + + ORIENTATION_MIN_MAX = "minMax" + + def __init__(self): + + self.orientation = self.ORIENTATION_MIN_MAX + self.number_format = NumberFormat() + for attr in ('position', 'tick_label_position', 'crosses', + 'auto', 'label_align', 'label_offset', 'cross_between'): + setattr(self, attr, None) + self.min = 0 + self.max = None + self.unit = None + self.title = '' + + @classmethod + def default_category(cls): + """ default values for category axes """ + + ax = Axis() + ax.id = 60871424 + ax.cross = 60873344 + ax.position = Axis.POSITION_BOTTOM + ax.tick_label_position = 'nextTo' + ax.crosses = "autoZero" + ax.auto = True + ax.label_align = 'ctr' + ax.label_offset = 100 + return ax + + @classmethod + def default_value(cls): + """ default values for value axes """ + + ax = Axis() + ax.id = 60873344 + ax.cross = 60871424 + ax.position = Axis.POSITION_LEFT + ax.major_gridlines = None + ax.tick_label_position = 'nextTo' + ax.crosses = 'autoZero' + ax.auto = False + ax.cross_between = 'between' + return ax + +class Reference(object): + """ a simple wrapper around a serie of reference data """ + + def __init__(self, sheet, pos1, pos2=None): + + self.sheet = sheet + self.pos1 = pos1 + self.pos2 = pos2 + + def get_type(self): + + if isinstance(self.cache[0], basestring): + return 'str' + else: + return 'num' + + def _get_ref(self): + """ format excel reference notation """ + + if self.pos2: + return '%s!$%s$%s:$%s$%s' % (self.sheet.title, + get_column_letter(self.pos1[1] + 1), self.pos1[0] + 1, + get_column_letter(self.pos2[1] + 1), self.pos2[0] + 1) + else: + return '%s!$%s$%s' % (self.sheet.title, + get_column_letter(self.pos1[1] + 1), self.pos1[0] + 1) + + + def _get_cache(self): + """ read data in sheet - to be used at writing time """ + + cache = [] + if self.pos2: + for row in range(self.pos1[0], self.pos2[0] + 1): + for col in range(self.pos1[1], self.pos2[1] + 1): + cache.append(self.sheet.cell(row=row, column=col).value) + else: + cell = self.sheet.cell(row=self.pos1[0], column=self.pos1[1]) + cache.append(cell.value) + return cache + + +class Serie(object): + """ a serie of data and possibly associated labels """ + + MARKER_NONE = 'none' + + def __init__(self, values, labels=None, legend=None, color=None, xvalues=None): + + self.marker = Serie.MARKER_NONE + self.values = values + self.xvalues = xvalues + self.labels = labels + self.legend = legend + self.error_bar = None + self._color = color + + def _get_color(self): + return self._color + + def _set_color(self, color): + self._color = short_color(color) + + color = property(_get_color, _set_color) + + def get_min_max(self): + + if self.error_bar: + err_cache = self.error_bar.values._get_cache() + vals = [v + err_cache[i] \ + for i, v in enumerate(self.values._get_cache())] + else: + vals = self.values._get_cache() + return min(vals), max(vals) + + def __len__(self): + + return len(self.values.cache) + +class Legend(object): + + def __init__(self): + + self.position = 'r' + self.layout = None + +class ErrorBar(object): + + PLUS = 1 + MINUS = 2 + PLUS_MINUS = 3 + + def __init__(self, _type, values): + + self.type = _type + self.values = values + +class Chart(object): + """ raw chart class """ + + GROUPING_CLUSTERED = 'clustered' + GROUPING_STANDARD = 'standard' + + BAR_CHART = 1 + LINE_CHART = 2 + SCATTER_CHART = 3 + + def __init__(self, _type, grouping): + + self._series = [] + + # public api + self.type = _type + self.grouping = grouping + self.x_axis = Axis.default_category() + self.y_axis = Axis.default_value() + self.legend = Legend() + self.lang = 'fr-FR' + self.title = '' + self.print_margins = dict(b=.75, l=.7, r=.7, t=.75, header=0.3, footer=.3) + + # the containing drawing + self.drawing = Drawing() + + # the offset for the plot part in percentage of the drawing size + self.width = .6 + self.height = .6 + self.margin_top = self._get_max_margin_top() + self.margin_left = 0 + + # the user defined shapes + self._shapes = [] + + def add_serie(self, serie): + + serie.id = len(self._series) + self._series.append(serie) + self._compute_min_max() + if not None in [s.xvalues for s in self._series]: + self._compute_xmin_xmax() + + def add_shape(self, shape): + + shape._chart = self + self._shapes.append(shape) + + def get_x_units(self): + """ calculate one unit for x axis in EMU """ + + return max([len(s.values._get_cache()) for s in self._series]) + + def get_y_units(self): + """ calculate one unit for y axis in EMU """ + + dh = pixels_to_EMU(self.drawing.height) + return (dh * self.height) / self.y_axis.max + + def get_y_chars(self): + """ estimate nb of chars for y axis """ + + _max = max([max(s.values._get_cache()) for s in self._series]) + return len(str(int(_max))) + + def _compute_min_max(self): + """ compute y axis limits and units """ + + maxi = max([max(s.values._get_cache()) for s in self._series]) + + mul = None + if maxi < 1: + s = str(maxi).split('.')[1] + mul = 10 + for x in s: + if x == '0': + mul *= 10 + else: + break + maxi = maxi * mul + + maxi = math.ceil(maxi * 1.1) + sz = len(str(int(maxi))) - 1 + unit = math.ceil(math.ceil(maxi / pow(10, sz)) * pow(10, sz - 1)) + maxi = math.ceil(maxi / unit) * unit + + if mul is not None: + maxi = maxi / mul + unit = unit / mul + + if maxi / unit > 9: + # no more that 10 ticks + unit *= 2 + + self.y_axis.max = maxi + self.y_axis.unit = unit + + def _compute_xmin_xmax(self): + """ compute x axis limits and units """ + + maxi = max([max(s.xvalues._get_cache()) for s in self._series]) + + mul = None + if maxi < 1: + s = str(maxi).split('.')[1] + mul = 10 + for x in s: + if x == '0': + mul *= 10 + else: + break + maxi = maxi * mul + + maxi = math.ceil(maxi * 1.1) + sz = len(str(int(maxi))) - 1 + unit = math.ceil(math.ceil(maxi / pow(10, sz)) * pow(10, sz - 1)) + maxi = math.ceil(maxi / unit) * unit + + if mul is not None: + maxi = maxi / mul + unit = unit / mul + + if maxi / unit > 9: + # no more that 10 ticks + unit *= 2 + + self.x_axis.max = maxi + self.x_axis.unit = unit + + def _get_max_margin_top(self): + + mb = Shape.FONT_HEIGHT + Shape.MARGIN_BOTTOM + plot_height = self.drawing.height * self.height + return float(self.drawing.height - plot_height - mb) / self.drawing.height + + def _get_min_margin_left(self): + + ml = (self.get_y_chars() * Shape.FONT_WIDTH) + Shape.MARGIN_LEFT + return float(ml) / self.drawing.width + + def _get_margin_top(self): + """ get margin in percent """ + + return min(self.margin_top, self._get_max_margin_top()) + + def _get_margin_left(self): + + return max(self._get_min_margin_left(), self.margin_left) + +class BarChart(Chart): + def __init__(self): + super(BarChart, self).__init__(Chart.BAR_CHART, Chart.GROUPING_CLUSTERED) + +class LineChart(Chart): + def __init__(self): + super(LineChart, self).__init__(Chart.LINE_CHART, Chart.GROUPING_STANDARD) + +class ScatterChart(Chart): + def __init__(self): + super(ScatterChart, self).__init__(Chart.SCATTER_CHART, Chart.GROUPING_STANDARD) + +
Property changes on: trunk/pywikipedia/openpyxl/chart.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/drawing.py =================================================================== --- trunk/pywikipedia/openpyxl/drawing.py (rev 0) +++ trunk/pywikipedia/openpyxl/drawing.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,399 @@ +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +import math +from openpyxl.style import Color +from openpyxl.shared.units import pixels_to_EMU, EMU_to_pixels, short_color + +class Shadow(object): + + SHADOW_BOTTOM = 'b' + SHADOW_BOTTOM_LEFT = 'bl' + SHADOW_BOTTOM_RIGHT = 'br' + SHADOW_CENTER = 'ctr' + SHADOW_LEFT = 'l' + SHADOW_TOP = 't' + SHADOW_TOP_LEFT = 'tl' + SHADOW_TOP_RIGHT = 'tr' + + def __init__(self): + self.visible = False + self.blurRadius = 6 + self.distance = 2 + self.direction = 0 + self.alignment = self.SHADOW_BOTTOM_RIGHT + self.color = Color(Color.BLACK) + self.alpha = 50 + +class Drawing(object): + """ a drawing object - eg container for shapes or charts + we assume user specifies dimensions in pixels; units are + converted to EMU in the drawing part + """ + + count = 0 + + def __init__(self): + + self.name = '' + self.description = '' + self.coordinates = ((1, 2), (16, 8)) + self.left = 0 + self.top = 0 + self._width = EMU_to_pixels(200000) + self._height = EMU_to_pixels(1828800) + self.resize_proportional = False + self.rotation = 0 +# self.shadow = Shadow() + + def _set_width(self, w): + + if self.resize_proportional and w: + ratio = self._height / self._width + self._height = round(ratio * w) + self._width = w + + def _get_width(self): + + return self._width + + width = property(_get_width, _set_width) + + def _set_height(self, h): + + if self.resize_proportional and h: + ratio = self._width / self._height + self._width = round(ratio * h) + self._height = h + + def _get_height(self): + + return self._height + + height = property(_get_height, _set_height) + + def set_dimension(self, w=0, h=0): + + xratio = w / self._width + yratio = h / self._height + + if self.resize_proportional and w and h: + if (xratio * self._height) < h: + self._height = math.ceil(xratio * self._height) + self._width = width + else: + self._width = math.ceil(yratio * self._width) + self._height = height + + def get_emu_dimensions(self): + """ return (x, y, w, h) in EMU """ + + return (pixels_to_EMU(self.left), pixels_to_EMU(self.top), + pixels_to_EMU(self._width), pixels_to_EMU(self._height)) + + +class Shape(object): + """ a drawing inside a chart + coordiantes are specified by the user in the axis units + """ + + MARGIN_LEFT = 6 + 13 + 1 + MARGIN_BOTTOM = 17 + 11 + + FONT_WIDTH = 7 + FONT_HEIGHT = 8 + + ROUND_RECT = 'roundRect' + RECT = 'rect' + + # other shapes to define : + ''' + "line" + "lineInv" + "triangle" + "rtTriangle" + "diamond" + "parallelogram" + "trapezoid" + "nonIsoscelesTrapezoid" + "pentagon" + "hexagon" + "heptagon" + "octagon" + "decagon" + "dodecagon" + "star4" + "star5" + "star6" + "star7" + "star8" + "star10" + "star12" + "star16" + "star24" + "star32" + "roundRect" + "round1Rect" + "round2SameRect" + "round2DiagRect" + "snipRoundRect" + "snip1Rect" + "snip2SameRect" + "snip2DiagRect" + "plaque" + "ellipse" + "teardrop" + "homePlate" + "chevron" + "pieWedge" + "pie" + "blockArc" + "donut" + "noSmoking" + "rightArrow" + "leftArrow" + "upArrow" + "downArrow" + "stripedRightArrow" + "notchedRightArrow" + "bentUpArrow" + "leftRightArrow" + "upDownArrow" + "leftUpArrow" + "leftRightUpArrow" + "quadArrow" + "leftArrowCallout" + "rightArrowCallout" + "upArrowCallout" + "downArrowCallout" + "leftRightArrowCallout" + "upDownArrowCallout" + "quadArrowCallout" + "bentArrow" + "uturnArrow" + "circularArrow" + "leftCircularArrow" + "leftRightCircularArrow" + "curvedRightArrow" + "curvedLeftArrow" + "curvedUpArrow" + "curvedDownArrow" + "swooshArrow" + "cube" + "can" + "lightningBolt" + "heart" + "sun" + "moon" + "smileyFace" + "irregularSeal1" + "irregularSeal2" + "foldedCorner" + "bevel" + "frame" + "halfFrame" + "corner" + "diagStripe" + "chord" + "arc" + "leftBracket" + "rightBracket" + "leftBrace" + "rightBrace" + "bracketPair" + "bracePair" + "straightConnector1" + "bentConnector2" + "bentConnector3" + "bentConnector4" + "bentConnector5" + "curvedConnector2" + "curvedConnector3" + "curvedConnector4" + "curvedConnector5" + "callout1" + "callout2" + "callout3" + "accentCallout1" + "accentCallout2" + "accentCallout3" + "borderCallout1" + "borderCallout2" + "borderCallout3" + "accentBorderCallout1" + "accentBorderCallout2" + "accentBorderCallout3" + "wedgeRectCallout" + "wedgeRoundRectCallout" + "wedgeEllipseCallout" + "cloudCallout" + "cloud" + "ribbon" + "ribbon2" + "ellipseRibbon" + "ellipseRibbon2" + "leftRightRibbon" + "verticalScroll" + "horizontalScroll" + "wave" + "doubleWave" + "plus" + "flowChartProcess" + "flowChartDecision" + "flowChartInputOutput" + "flowChartPredefinedProcess" + "flowChartInternalStorage" + "flowChartDocument" + "flowChartMultidocument" + "flowChartTerminator" + "flowChartPreparation" + "flowChartManualInput" + "flowChartManualOperation" + "flowChartConnector" + "flowChartPunchedCard" + "flowChartPunchedTape" + "flowChartSummingJunction" + "flowChartOr" + "flowChartCollate" + "flowChartSort" + "flowChartExtract" + "flowChartMerge" + "flowChartOfflineStorage" + "flowChartOnlineStorage" + "flowChartMagneticTape" + "flowChartMagneticDisk" + "flowChartMagneticDrum" + "flowChartDisplay" + "flowChartDelay" + "flowChartAlternateProcess" + "flowChartOffpageConnector" + "actionButtonBlank" + "actionButtonHome" + "actionButtonHelp" + "actionButtonInformation" + "actionButtonForwardNext" + "actionButtonBackPrevious" + "actionButtonEnd" + "actionButtonBeginning" + "actionButtonReturn" + "actionButtonDocument" + "actionButtonSound" + "actionButtonMovie" + "gear6" + "gear9" + "funnel" + "mathPlus" + "mathMinus" + "mathMultiply" + "mathDivide" + "mathEqual" + "mathNotEqual" + "cornerTabs" + "squareTabs" + "plaqueTabs" + "chartX" + "chartStar" + "chartPlus" + ''' + + def __init__(self, coordinates=((0, 0), (1, 1)), text=None, scheme="accent1"): + + self.coordinates = coordinates # in axis unit + self.text = text + self.scheme = scheme + self.style = Shape.RECT + self._border_width = 3175 # in EMU + self._border_color = Color.BLACK[2:] #"F3B3C5" + self._color = Color.WHITE[2:] + self._text_color = Color.BLACK[2:] + + def _get_border_color(self): + return self._border_color + + def _set_border_color(self, color): + self._border_color = short_color(color) + + border_color = property(_get_border_color, _set_border_color) + + def _get_color(self): + return self._color + + def _set_color(self, color): + self._color = short_color(color) + + color = property(_get_color, _set_color) + + def _get_text_color(self): + return self._text_color + + def _set_text_color(self, color): + self._text_color = short_color(color) + + text_color = property(_get_text_color, _set_text_color) + + def _get_border_width(self): + + return EMU_to_pixels(self._border_width) + + def _set_border_width(self, w): + + self._border_width = pixels_to_EMU(w) + print self._border_width + + border_width = property(_get_border_width, _set_border_width) + + def get_coordinates(self): + """ return shape coordinates in percentages (left, top, right, bottom) """ + + (x1, y1), (x2, y2) = self.coordinates + + drawing_width = pixels_to_EMU(self._chart.drawing.width) + drawing_height = pixels_to_EMU(self._chart.drawing.height) + plot_width = drawing_width * self._chart.width + plot_height = drawing_height * self._chart.height + + margin_left = self._chart._get_margin_left() * drawing_width + xunit = plot_width / self._chart.get_x_units() + + margin_top = self._chart._get_margin_top() * drawing_height + yunit = self._chart.get_y_units() + + x_start = (margin_left + (float(x1) * xunit)) / drawing_width + y_start = (margin_top + plot_height - (float(y1) * yunit)) / drawing_height + + x_end = (margin_left + (float(x2) * xunit)) / drawing_width + y_end = (margin_top + plot_height - (float(y2) * yunit)) / drawing_height + + def _norm_pct(pct): + """ force shapes to appear by truncating too large sizes """ + if pct > 1: pct = 1 + elif pct < 0: pct = 0 + return pct + + # allow user to specify y's in whatever order + # excel expect y_end to be lower + if y_end < y_start: + y_end, y_start = y_start, y_end + + return (_norm_pct(x_start), _norm_pct(y_start), + _norm_pct(x_end), _norm_pct(y_end))
Property changes on: trunk/pywikipedia/openpyxl/drawing.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/namedrange.py =================================================================== --- trunk/pywikipedia/openpyxl/namedrange.py (rev 0) +++ trunk/pywikipedia/openpyxl/namedrange.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,83 @@ +# file openpyxl/namedrange.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Track named groups of cells in a worksheet""" + +# Python stdlib imports +import re + +# package imports +from openpyxl.shared.exc import NamedRangeException + +# constants +NAMED_RANGE_RE = re.compile("'?([^']*)'?!(($([A-Za-z]+))?$([0-9]+)(:($([A-Za-z]+))?($([0-9]+)))?)$") + +class NamedRange(object): + """A named group of cells + + Scope is a worksheet object or None for workbook scope names (the default) + """ + __slots__ = ('name', 'destinations', 'scope') + + def __init__(self, name, destinations): + self.name = name + self.destinations = destinations + self.scope = None + + def __str__(self): + return ','.join([u'%s!%s' % (sheet, name) for sheet, name in self.destinations]) + + def __repr__(self): + + return '<%s "%s">' % (self.__class__.__name__, str(self)) + +class NamedRangeContainingValue(object): + """A named value""" + __slots__ = ('name', 'value', 'scope') + + def __init__(self, name, value): + self.name = name + self.value = value + self.scope = None + + +def split_named_range(range_string): + """Separate a named range into its component parts""" + + destinations = [] + + for range_string in range_string.split(','): + + match = NAMED_RANGE_RE.match(range_string) + if not match: + raise NamedRangeException('Invalid named range string: "%s"' % range_string) + else: + sheet_name, xlrange = match.groups()[:2] + destinations.append((sheet_name, xlrange)) + + return destinations + +def refers_to_range(range_string): + return bool(NAMED_RANGE_RE.match(range_string))
Property changes on: trunk/pywikipedia/openpyxl/namedrange.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/reader/__init__.py =================================================================== --- trunk/pywikipedia/openpyxl/reader/__init__.py (rev 0) +++ trunk/pywikipedia/openpyxl/reader/__init__.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,33 @@ +# file openpyxl/reader/__init__.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Imports for the openpyxl.reader namespace.""" + +# package imports +from openpyxl.reader import excel +from openpyxl.reader import strings +from openpyxl.reader import style +from openpyxl.reader import workbook +from openpyxl.reader import worksheet
Property changes on: trunk/pywikipedia/openpyxl/reader/__init__.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/reader/excel.py =================================================================== --- trunk/pywikipedia/openpyxl/reader/excel.py (rev 0) +++ trunk/pywikipedia/openpyxl/reader/excel.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,118 @@ +# file openpyxl/reader/excel.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Read an xlsx file into Python""" + +# Python stdlib imports +from zipfile import ZipFile, ZIP_DEFLATED, BadZipfile + +# package imports +from openpyxl.shared.exc import OpenModeError, InvalidFileException +from openpyxl.shared.ooxml import ARC_SHARED_STRINGS, ARC_CORE, ARC_APP, \ + ARC_WORKBOOK, PACKAGE_WORKSHEETS, ARC_STYLE +from openpyxl.workbook import Workbook, DocumentProperties +from openpyxl.reader.strings import read_string_table +from openpyxl.reader.style import read_style_table +from openpyxl.reader.workbook import read_sheets_titles, read_named_ranges, \ + read_properties_core, get_sheet_ids +from openpyxl.reader.worksheet import read_worksheet +from openpyxl.reader.iter_worksheet import unpack_worksheet + +def load_workbook(filename, use_iterators=False): + """Open the given filename and return the workbook + + :param filename: the path to open + :type filename: string + + :param use_iterators: use lazy load for cells + :type use_iterators: bool + + :rtype: :class:`openpyxl.workbook.Workbook` + + .. note:: + + When using lazy load, all worksheets will be :class:`openpyxl.reader.iter_worksheet.IterableWorksheet` + and the returned workbook will be read-only. + + """ + + if isinstance(filename, file): + # fileobject must have been opened with 'rb' flag + # it is required by zipfile + if 'b' not in filename.mode: + raise OpenModeError("File-object must be opened in binary mode") + + try: + archive = ZipFile(filename, 'r', ZIP_DEFLATED) + except (BadZipfile, RuntimeError, IOError, ValueError), e: + raise InvalidFileException(unicode(e)) + wb = Workbook() + + if use_iterators: + wb._set_optimized_read() + + try: + _load_workbook(wb, archive, filename, use_iterators) + except KeyError, e: + raise InvalidFileException(unicode(e)) + + archive.close() + return wb + +def _load_workbook(wb, archive, filename, use_iterators): + + valid_files = archive.namelist() + + # get workbook-level information + try: + wb.properties = read_properties_core(archive.read(ARC_CORE)) + except KeyError: + wb.properties = DocumentProperties() + + try: + string_table = read_string_table(archive.read(ARC_SHARED_STRINGS)) + except KeyError: + string_table = {} + style_table = read_style_table(archive.read(ARC_STYLE)) + + # get worksheets + wb.worksheets = [] # remove preset worksheet + sheet_names = read_sheets_titles(archive.read(ARC_WORKBOOK)) + for i, sheet_name in enumerate(sheet_names): + + sheet_codename = 'sheet%d.xml' % (i + 1) + worksheet_path = '%s/%s' % (PACKAGE_WORKSHEETS, sheet_codename) + + if not worksheet_path in valid_files: + continue + + if not use_iterators: + new_ws = read_worksheet(archive.read(worksheet_path), wb, sheet_name, string_table, style_table) + else: + xml_source = unpack_worksheet(archive, worksheet_path) + new_ws = read_worksheet(xml_source, wb, sheet_name, string_table, style_table, filename, sheet_codename) + wb.add_sheet(new_ws, index=i) + + wb._named_ranges = read_named_ranges(archive.read(ARC_WORKBOOK), wb)
Property changes on: trunk/pywikipedia/openpyxl/reader/excel.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/reader/iter_worksheet.py =================================================================== --- trunk/pywikipedia/openpyxl/reader/iter_worksheet.py (rev 0) +++ trunk/pywikipedia/openpyxl/reader/iter_worksheet.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,358 @@ +# file openpyxl/reader/iter_worksheet.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +""" Iterators-based worksheet reader +*Still very raw* +""" + +from StringIO import StringIO +import warnings +import operator +from itertools import ifilter, groupby +from openpyxl.worksheet import Worksheet +from openpyxl.cell import coordinate_from_string, get_column_letter, Cell +from openpyxl.reader.excel import get_sheet_ids +from openpyxl.reader.strings import read_string_table +from openpyxl.reader.style import read_style_table, NumberFormat +from openpyxl.shared.date_time import SharedDate +from openpyxl.reader.worksheet import read_dimension +from openpyxl.shared.ooxml import (MIN_COLUMN, MAX_COLUMN, PACKAGE_WORKSHEETS, + MAX_ROW, MIN_ROW, ARC_SHARED_STRINGS, ARC_APP, ARC_STYLE) +from openpyxl.shared.compat import iterparse +from zipfile import ZipFile +import openpyxl.cell +import re +import tempfile +import zlib +import zipfile +import struct + +TYPE_NULL = Cell.TYPE_NULL +MISSING_VALUE = None + +RE_COORDINATE = re.compile('^([A-Z]+)([0-9]+)$') + +SHARED_DATE = SharedDate() + +_COL_CONVERSION_CACHE = dict((get_column_letter(i), i) for i in xrange(1, 18279)) +def column_index_from_string(str_col, _col_conversion_cache=_COL_CONVERSION_CACHE): + # we use a function argument to get indexed name lookup + return _col_conversion_cache[str_col] +del _COL_CONVERSION_CACHE + +RAW_ATTRIBUTES = ['row', 'column', 'coordinate', 'internal_value', 'data_type', 'style_id', 'number_format'] + +try: + from collections import namedtuple + BaseRawCell = namedtuple('RawCell', RAW_ATTRIBUTES) +except ImportError: + + warnings.warn("""Unable to import 'namedtuple' module, this may cause memory issues when using optimized reader. Please upgrade your Python installation to 2.6+""") + + class BaseRawCell(object): + + def __init__(self, *args): + assert len(args) == len(RAW_ATTRIBUTES) + + for attr, val in zip(RAW_ATTRIBUTES, args): + setattr(self, attr, val) + + def _replace(self, **kwargs): + + self.__dict__.update(kwargs) + + return self + + +class RawCell(BaseRawCell): + """Optimized version of the :class:`openpyxl.cell.Cell`, using named tuples. + + Useful attributes are: + + * row + * column + * coordinate + * internal_value + + You can also access if needed: + + * data_type + * number_format + + """ + + @property + def is_date(self): + res = (self.data_type == Cell.TYPE_NUMERIC + and self.number_format is not None + and ('d' in self.number_format + or 'm' in self.number_format + or 'y' in self.number_format + or 'h' in self.number_format + or 's' in self.number_format + )) + + return res + +def iter_rows(workbook_name, sheet_name, xml_source, range_string='', row_offset=0, column_offset=0): + + archive = get_archive_file(workbook_name) + + source = xml_source + + if range_string: + min_col, min_row, max_col, max_row = get_range_boundaries(range_string, row_offset, column_offset) + else: + min_col, min_row, max_col, max_row = read_dimension(xml_source=source) + min_col = column_index_from_string(min_col) + max_col = column_index_from_string(max_col) + 1 + max_row += 6 + + try: + string_table = read_string_table(archive.read(ARC_SHARED_STRINGS)) + except KeyError: + string_table = {} + + style_table = read_style_table(archive.read(ARC_STYLE)) + + source.seek(0) + p = iterparse(source) + + return get_squared_range(p, min_col, min_row, max_col, max_row, string_table, style_table) + + +def get_rows(p, min_column=MIN_COLUMN, min_row=MIN_ROW, max_column=MAX_COLUMN, max_row=MAX_ROW): + + return groupby(get_cells(p, min_row, min_column, max_row, max_column), operator.attrgetter('row')) + +def get_cells(p, min_row, min_col, max_row, max_col, _re_coordinate=RE_COORDINATE): + + for _event, element in p: + + if element.tag == '{http://schemas.openxmlformats.org/spreadsheetml/2006/main%7Dc': + coord = element.get('r') + column_str, row = _re_coordinate.match(coord).groups() + + row = int(row) + column = column_index_from_string(column_str) + + if min_col <= column <= max_col and min_row <= row <= max_row: + data_type = element.get('t', 'n') + style_id = element.get('s') + value = element.findtext('{http://schemas.openxmlformats.org/spreadsheetml/2006/main%7Dv') + yield RawCell(row, column_str, coord, value, data_type, style_id, None) + + if element.tag == '{http://schemas.openxmlformats.org/spreadsheetml/2006/main%7Dv': + continue + element.clear() + + + +def get_range_boundaries(range_string, row=0, column=0): + + if ':' in range_string: + min_range, max_range = range_string.split(':') + min_col, min_row = coordinate_from_string(min_range) + max_col, max_row = coordinate_from_string(max_range) + + min_col = column_index_from_string(min_col) + column + max_col = column_index_from_string(max_col) + column + min_row += row + max_row += row + + else: + min_col, min_row = coordinate_from_string(range_string) + min_col = column_index_from_string(min_col) + max_col = min_col + 1 + max_row = min_row + + return (min_col, min_row, max_col, max_row) + +def get_archive_file(archive_name): + + return ZipFile(archive_name, 'r') + +def get_xml_source(archive_file, sheet_name): + + return archive_file.read('%s/%s' % (PACKAGE_WORKSHEETS, sheet_name)) + +def get_missing_cells(row, columns): + + return dict([(column, RawCell(row, column, '%s%s' % (column, row), MISSING_VALUE, TYPE_NULL, None, None)) for column in columns]) + +def get_squared_range(p, min_col, min_row, max_col, max_row, string_table, style_table): + + expected_columns = [get_column_letter(ci) for ci in xrange(min_col, max_col)] + + current_row = min_row + for row, cells in get_rows(p, min_row=min_row, max_row=max_row, min_column=min_col, max_column=max_col): + full_row = [] + if current_row < row: + + for gap_row in xrange(current_row, row): + + dummy_cells = get_missing_cells(gap_row, expected_columns) + + yield tuple([dummy_cells[column] for column in expected_columns]) + + current_row = row + + temp_cells = list(cells) + + retrieved_columns = dict([(c.column, c) for c in temp_cells]) + + missing_columns = list(set(expected_columns) - set(retrieved_columns.keys())) + + replacement_columns = get_missing_cells(row, missing_columns) + + for column in expected_columns: + + if column in retrieved_columns: + cell = retrieved_columns[column] + + if cell.style_id is not None: + style = style_table[int(cell.style_id)] + cell = cell._replace(number_format=style.number_format.format_code) #pylint: disable-msg=W0212 + if cell.internal_value is not None: + if cell.data_type in Cell.TYPE_STRING: + cell = cell._replace(internal_value=unicode(string_table[int(cell.internal_value)])) #pylint: disable-msg=W0212 + elif cell.data_type == Cell.TYPE_BOOL: + cell = cell._replace(internal_value=cell.internal_value == '1') + elif cell.is_date: + cell = cell._replace(internal_value=SHARED_DATE.from_julian(float(cell.internal_value))) + elif cell.data_type == Cell.TYPE_NUMERIC: + cell = cell._replace(internal_value=float(cell.internal_value)) + elif cell.data_type in(Cell.TYPE_INLINE, Cell.TYPE_FORMULA_CACHE_STRING): + cell = cell._replace(internal_value=unicode(cell.internal_value)) + full_row.append(cell) + + else: + full_row.append(replacement_columns[column]) + + current_row = row + 1 + + yield tuple(full_row) + +#------------------------------------------------------------------------------ + +class IterableWorksheet(Worksheet): + + def __init__(self, parent_workbook, title, workbook_name, + sheet_codename, xml_source): + + Worksheet.__init__(self, parent_workbook, title) + self._workbook_name = workbook_name + self._sheet_codename = sheet_codename + self._xml_source = xml_source + + min_col, min_row, max_col, max_row = read_dimension(xml_source=xml_source) + + self._max_row = max_row + self._max_column = max_col + self._dimensions = '%s%s:%s%s' % (min_col, min_row, max_col, max_row) + + + def iter_rows(self, range_string='', row_offset=0, column_offset=0): + """ Returns a squared range based on the `range_string` parameter, + using generators. + + :param range_string: range of cells (e.g. 'A1:C4') + :type range_string: string + + :param row: row index of the cell (e.g. 4) + :type row: int + + :param column: column index of the cell (e.g. 3) + :type column: int + + :rtype: generator + + """ + + return iter_rows(workbook_name=self._workbook_name, + sheet_name=self._sheet_codename, + xml_source=self._xml_source, + range_string=range_string, + row_offset=row_offset, + column_offset=column_offset) + + def cell(self, *args, **kwargs): + raise NotImplementedError("use 'iter_rows()' instead") + + def range(self, *args, **kwargs): + raise NotImplementedError("use 'iter_rows()' instead") + + def calculate_dimension(self): + return self._dimensions + + def get_highest_column(self): + return self._max_column + + def get_highest_row(self): + return self._max_row + +def unpack_worksheet(archive, filename): + + temp_file = tempfile.TemporaryFile(mode='r+', prefix='openpyxl.', suffix='.unpack.temp') + + zinfo = archive.getinfo(filename) + + if zinfo.compress_type == zipfile.ZIP_STORED: + decoder = None + elif zinfo.compress_type == zipfile.ZIP_DEFLATED: + decoder = zlib.decompressobj(-zlib.MAX_WBITS) + else: + raise zipfile.BadZipFile("Unrecognized compression method") + + archive.fp.seek(_get_file_offset(archive, zinfo)) + bytes_to_read = zinfo.compress_size + + while True: + buff = archive.fp.read(min(bytes_to_read, 102400)) + if not buff: + break + bytes_to_read -= len(buff) + if decoder: + buff = decoder.decompress(buff) + temp_file.write(buff) + + if decoder: + temp_file.write(decoder.decompress('Z')) + + return temp_file + +def _get_file_offset(archive, zinfo): + + try: + return zinfo.file_offset + except AttributeError: + # From http://stackoverflow.com/questions/3781261/how-to-simulate-zipfile-open-in-p... + + # Seek over the fixed size fields to the "file name length" field in + # the file header (26 bytes). Unpack this and the "extra field length" + # field ourselves as info.extra doesn't seem to be the correct length. + archive.fp.seek(zinfo.header_offset + 26) + file_name_len, extra_len = struct.unpack("<HH", archive.fp.read(4)) + return zinfo.header_offset + 30 + file_name_len + extra_len
Property changes on: trunk/pywikipedia/openpyxl/reader/iter_worksheet.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/reader/strings.py =================================================================== --- trunk/pywikipedia/openpyxl/reader/strings.py (rev 0) +++ trunk/pywikipedia/openpyxl/reader/strings.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,71 @@ +# file openpyxl/reader/strings.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Read the shared strings table.""" + +# package imports +from openpyxl.shared.xmltools import fromstring, QName +from openpyxl.shared.ooxml import NAMESPACES + + +def read_string_table(xml_source): + """Read in all shared strings in the table""" + table = {} + xmlns = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main' + root = fromstring(text=xml_source) + string_index_nodes = root.findall(QName(xmlns, 'si').text) + for index, string_index_node in enumerate(string_index_nodes): + + string = get_string(xmlns, string_index_node) + + # fix XML escaping sequence for '_x' + string = string.replace('x005F_', '') + + table[index] = string + + return table + + +def get_string(xmlns, string_index_node): + """Read the contents of a specific string index""" + rich_nodes = string_index_node.findall(QName(xmlns, 'r').text) + if rich_nodes: + reconstructed_text = [] + for rich_node in rich_nodes: + partial_text = get_text(xmlns, rich_node) + reconstructed_text.append(partial_text) + return u''.join(reconstructed_text) + else: + return get_text(xmlns, string_index_node) + + +def get_text(xmlns, rich_node): + """Read rich text, discarding formatting if not disallowed""" + text_node = rich_node.find(QName(xmlns, 't').text) + partial_text = text_node.text or u'' + + if text_node.get(QName(NAMESPACES['xml'], 'space').text) != 'preserve': + partial_text = partial_text.strip() + return unicode(partial_text)
Property changes on: trunk/pywikipedia/openpyxl/reader/strings.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/reader/style.py =================================================================== --- trunk/pywikipedia/openpyxl/reader/style.py (rev 0) +++ trunk/pywikipedia/openpyxl/reader/style.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,69 @@ +# file openpyxl/reader/style.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Read shared style definitions""" + +# package imports +from openpyxl.shared.xmltools import fromstring, QName +from openpyxl.shared.exc import MissingNumberFormat +from openpyxl.style import Style, NumberFormat + + +def read_style_table(xml_source): + """Read styles from the shared style table""" + table = {} + xmlns = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main' + root = fromstring(xml_source) + custom_num_formats = parse_custom_num_formats(root, xmlns) + builtin_formats = NumberFormat._BUILTIN_FORMATS + cell_xfs = root.find(QName(xmlns, 'cellXfs').text) + cell_xfs_nodes = cell_xfs.findall(QName(xmlns, 'xf').text) + for index, cell_xfs_node in enumerate(cell_xfs_nodes): + new_style = Style() + number_format_id = int(cell_xfs_node.get('numFmtId')) + if number_format_id < 164: + new_style.number_format.format_code = \ + builtin_formats.get(number_format_id, 'General') + else: + + if number_format_id in custom_num_formats: + new_style.number_format.format_code = \ + custom_num_formats[number_format_id] + else: + raise MissingNumberFormat('%s' % number_format_id) + table[index] = new_style + return table + + +def parse_custom_num_formats(root, xmlns): + """Read in custom numeric formatting rules from the shared style table""" + custom_formats = {} + num_fmts = root.find(QName(xmlns, 'numFmts').text) + if num_fmts is not None: + num_fmt_nodes = num_fmts.findall(QName(xmlns, 'numFmt').text) + for num_fmt_node in num_fmt_nodes: + custom_formats[int(num_fmt_node.get('numFmtId'))] = \ + num_fmt_node.get('formatCode').lower() + return custom_formats
Property changes on: trunk/pywikipedia/openpyxl/reader/style.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/reader/workbook.py =================================================================== --- trunk/pywikipedia/openpyxl/reader/workbook.py (rev 0) +++ trunk/pywikipedia/openpyxl/reader/workbook.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,136 @@ +# file openpyxl/reader/workbook.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Read in global settings to be maintained by the workbook object.""" + +# package imports +from openpyxl.shared.xmltools import fromstring, QName +from openpyxl.shared.ooxml import NAMESPACES +from openpyxl.workbook import DocumentProperties +from openpyxl.shared.date_time import W3CDTF_to_datetime +from openpyxl.namedrange import NamedRange, NamedRangeContainingValue, split_named_range, refers_to_range + +import datetime + +# constants +BUGGY_NAMED_RANGES = ['NA()', '#REF!'] +DISCARDED_RANGES = ['Excel_BuiltIn', 'Print_Area'] + +def get_sheet_ids(xml_source): + + sheet_names = read_sheets_titles(xml_source) + + return dict((sheet, 'sheet%d.xml' % (i + 1)) for i, sheet in enumerate(sheet_names)) + + +def read_properties_core(xml_source): + """Read assorted file properties.""" + properties = DocumentProperties() + root = fromstring(xml_source) + creator_node = root.find(QName(NAMESPACES['dc'], 'creator').text) + if creator_node is not None: + properties.creator = creator_node.text + else: + properties.creator = '' + last_modified_by_node = root.find( + QName(NAMESPACES['cp'], 'lastModifiedBy').text) + if last_modified_by_node is not None: + properties.last_modified_by = last_modified_by_node.text + else: + properties.last_modified_by = '' + + created_node = root.find(QName(NAMESPACES['dcterms'], 'created').text) + if created_node is not None: + properties.created = W3CDTF_to_datetime(created_node.text) + else: + properties.created = datetime.datetime.now() + + modified_node = root.find(QName(NAMESPACES['dcterms'], 'modified').text) + if modified_node is not None: + properties.modified = W3CDTF_to_datetime(modified_node.text) + else: + properties.modified = properties.created + + return properties + + +def read_sheets_titles(xml_source): + """Read titles for all sheets.""" + root = fromstring(xml_source) + titles_root = root.find(QName('http://schemas.openxmlformats.org/spreadsheetml/2006/main', + 'sheets').text) + + return [sheet.get('name') for sheet in titles_root.getchildren()] + +def read_named_ranges(xml_source, workbook): + """Read named ranges, excluding poorly defined ranges.""" + named_ranges = [] + root = fromstring(xml_source) + names_root = root.find(QName('http://schemas.openxmlformats.org/spreadsheetml/2006/main', + 'definedNames').text) + if names_root is not None: + + for name_node in names_root.getchildren(): + range_name = name_node.get('name') + + if name_node.get("hidden", '0') == '1': + continue + + valid = True + + for discarded_range in DISCARDED_RANGES: + if discarded_range in range_name: + valid = False + + for bad_range in BUGGY_NAMED_RANGES: + if bad_range in name_node.text: + valid = False + + if valid: + if refers_to_range(name_node.text): + destinations = split_named_range(name_node.text) + + new_destinations = [] + for worksheet, cells_range in destinations: + # it can happen that a valid named range references + # a missing worksheet, when Excel didn't properly maintain + # the named range list + # + # we just ignore them here + worksheet = workbook.get_sheet_by_name(worksheet) + if worksheet: + new_destinations.append((worksheet, cells_range)) + + named_range = NamedRange(range_name, new_destinations) + else: + named_range = NamedRangeContainingValue(range_name, name_node.text) + + location_id = name_node.get("localSheetId") + if location_id: + named_range.scope = workbook.worksheets[int(location_id)] + + named_ranges.append(named_range) + + return named_ranges
Property changes on: trunk/pywikipedia/openpyxl/reader/workbook.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/reader/worksheet.py =================================================================== --- trunk/pywikipedia/openpyxl/reader/worksheet.py (rev 0) +++ trunk/pywikipedia/openpyxl/reader/worksheet.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,116 @@ +# file openpyxl/reader/worksheet.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Reader for a single worksheet.""" + +# Python stdlib imports +try: + from openpyxl.shared.compat import iterparse +except ImportError: + from xml.etree.ElementTree import iterparse +from itertools import ifilter +from StringIO import StringIO + +# package imports +from openpyxl.cell import Cell, coordinate_from_string +from openpyxl.worksheet import Worksheet + +def _get_xml_iter(xml_source): + + if not hasattr(xml_source, 'name'): + return StringIO(xml_source) + else: + xml_source.seek(0) + return xml_source + +def read_dimension(xml_source): + + source = _get_xml_iter(xml_source) + + it = iterparse(source) + + for event, element in it: + + if element.tag == '{http://schemas.openxmlformats.org/spreadsheetml/2006/main%7Ddimension': + ref = element.get('ref') + + if ':' in ref: + min_range, max_range = ref.split(':') + else: + min_range = max_range = ref + + min_col, min_row = coordinate_from_string(min_range) + max_col, max_row = coordinate_from_string(max_range) + + return min_col, min_row, max_col, max_row + + else: + element.clear() + + return None + +def filter_cells((event, element)): + + return element.tag == '{http://schemas.openxmlformats.org/spreadsheetml/2006/main%7Dc' + +def fast_parse(ws, xml_source, string_table, style_table): + + source = _get_xml_iter(xml_source) + + it = iterparse(source) + + for event, element in ifilter(filter_cells, it): + + value = element.findtext('{http://schemas.openxmlformats.org/spreadsheetml/2006/main%7Dv') + + if value is not None: + + coordinate = element.get('r') + data_type = element.get('t', 'n') + style_id = element.get('s') + + if data_type == Cell.TYPE_STRING: + value = string_table.get(int(value)) + + ws.cell(coordinate).value = value + + if style_id is not None: + ws._styles[coordinate] = style_table.get(int(style_id)) + + # to avoid memory exhaustion, clear the item after use + element.clear() + +from openpyxl.reader.iter_worksheet import IterableWorksheet + +def read_worksheet(xml_source, parent, preset_title, string_table, + style_table, workbook_name = None, sheet_codename = None): + """Read an xml worksheet""" + if workbook_name and sheet_codename: + ws = IterableWorksheet(parent, preset_title, workbook_name, + sheet_codename, xml_source) + else: + ws = Worksheet(parent, preset_title) + fast_parse(ws, xml_source, string_table, style_table) + return ws
Property changes on: trunk/pywikipedia/openpyxl/reader/worksheet.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/shared/__init__.py =================================================================== --- trunk/pywikipedia/openpyxl/shared/__init__.py (rev 0) +++ trunk/pywikipedia/openpyxl/shared/__init__.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,37 @@ +# file openpyxl/shared/__init__.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Imports for the openpyxl.shared namespace.""" + +# package imports +from openpyxl.shared import date_time +from openpyxl.shared import exc +from openpyxl.shared import ooxml +from openpyxl.shared import password_hasher +from openpyxl.shared import xmltools +import decimal + +NUMERIC_TYPES = (int, float, long, decimal.Decimal) +
Property changes on: trunk/pywikipedia/openpyxl/shared/__init__.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/shared/compat/__init__.py =================================================================== --- trunk/pywikipedia/openpyxl/shared/compat/__init__.py (rev 0) +++ trunk/pywikipedia/openpyxl/shared/compat/__init__.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,27 @@ +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file +import sys + +from openpyxl.shared.compat.elementtree import iterparse +from openpyxl.shared.compat.tempnamedfile import NamedTemporaryFile +from openpyxl.shared.compat.allany import all, any
Property changes on: trunk/pywikipedia/openpyxl/shared/compat/__init__.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/shared/compat/allany.py =================================================================== --- trunk/pywikipedia/openpyxl/shared/compat/allany.py (rev 0) +++ trunk/pywikipedia/openpyxl/shared/compat/allany.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,24 @@ +# Copyright (c) 2001-2011 Python Software Foundation +# +# License: PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +# See http://www.opensource.org/licenses/Python-2.0 for full terms + +import sys + +if sys.version_info < (2, 5): + def all(iterable): + for element in iterable: + if not element: + return False + return True + + def any(iterable): + for element in iterable: + if element: + return True + return False +else: + all = all + any = any + +del sys
Property changes on: trunk/pywikipedia/openpyxl/shared/compat/allany.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/shared/compat/elementtree.py =================================================================== --- trunk/pywikipedia/openpyxl/shared/compat/elementtree.py (rev 0) +++ trunk/pywikipedia/openpyxl/shared/compat/elementtree.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,27 @@ +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +try: + from xml.etree.ElementTree import iterparse +except ImportError: + from cElementTree import iterparse
Property changes on: trunk/pywikipedia/openpyxl/shared/compat/elementtree.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/shared/compat/sax.py =================================================================== --- trunk/pywikipedia/openpyxl/shared/compat/sax.py (rev 0) +++ trunk/pywikipedia/openpyxl/shared/compat/sax.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,42 @@ +# Copyright (c) 2001-2011 Python Software Foundation +# +# License: PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +# See http://www.opensource.org/licenses/Python-2.0 for full terms + +import sys +from xml.sax.saxutils import XMLGenerator as _XMLGenerator, quoteattr + +if sys.version_info < (2, 5): + + class XMLGenerator(_XMLGenerator): + + def _qname(self, name): + """Builds a qualified name from a (ns_url, localname) pair""" + if name[0]: + # The name is in a non-empty namespace + prefix = self._current_context[name[0]] + if prefix: + # If it is not the default namespace, prepend the prefix + return prefix + ":" + name[1] + # Return the unqualified name + return name[1] + + def startElementNS(self, name, qname, attrs): + self._write('<' + self._qname(name)) + + for prefix, uri in self._undeclared_ns_maps: + if prefix: + self._out.write(' xmlns:%s="%s"' % (prefix, uri)) + else: + self._out.write(' xmlns="%s"' % uri) + self._undeclared_ns_maps = [] + + for (name, value) in attrs.items(): + self._write(' %s=%s' % (self._qname(name), quoteattr(value))) + self._write('>') + + def endElementNS(self, name, qname): + self._write('</%s>' % self._qname(name)) + +else: + XMLGenerator = _XMLGenerator
Property changes on: trunk/pywikipedia/openpyxl/shared/compat/sax.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/shared/compat/tempnamedfile.py =================================================================== --- trunk/pywikipedia/openpyxl/shared/compat/tempnamedfile.py (rev 0) +++ trunk/pywikipedia/openpyxl/shared/compat/tempnamedfile.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,13 @@ +import tempfile +import os + +def NamedTemporaryFile(mode, suffix, prefix, delete=False): + + try: + return tempfile.NamedTemporaryFile(mode=mode, suffix=suffix, prefix=prefix, delete=delete) + except TypeError: + handle, filename = tempfile.mkstemp(suffix=suffix, prefix=prefix) + os.close(handle) + fobj = open(filename, mode) + + return fobj
Property changes on: trunk/pywikipedia/openpyxl/shared/compat/tempnamedfile.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/shared/date_time.py =================================================================== --- trunk/pywikipedia/openpyxl/shared/date_time.py (rev 0) +++ trunk/pywikipedia/openpyxl/shared/date_time.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,155 @@ +# file openpyxl/shared/date_time.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Manage Excel date weirdness.""" + +# Python stdlib imports +from __future__ import division +from math import floor +import calendar +import datetime +import time +import re + +# constants +W3CDTF_FORMAT = '%Y-%m-%dT%H:%M:%SZ' + +RE_W3CDTF = '(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.(\d{2}))?Z?' + +EPOCH = datetime.datetime.utcfromtimestamp(0) + +def datetime_to_W3CDTF(dt): + """Convert from a datetime to a timestamp string.""" + return datetime.datetime.strftime(dt, W3CDTF_FORMAT) + + +def W3CDTF_to_datetime(formatted_string): + """Convert from a timestamp string to a datetime object.""" + match = re.match(RE_W3CDTF,formatted_string) + digits = map(int, match.groups()[:6]) + return datetime.datetime(*digits) + + +class SharedDate(object): + """Date formatting utilities for Excel with shared state. + + Excel has a two primary date tracking schemes: + Windows - Day 1 == 1900-01-01 + Mac - Day 1 == 1904-01-01 + + SharedDate stores which system we are using and converts dates between + Python and Excel accordingly. + + """ + CALENDAR_WINDOWS_1900 = 1900 + CALENDAR_MAC_1904 = 1904 + datetime_object_type = 'DateTime' + + def __init__(self): + self.excel_base_date = self.CALENDAR_WINDOWS_1900 + + def datetime_to_julian(self, date): + """Convert from python datetime to excel julian date representation.""" + + if isinstance(date, datetime.datetime): + return self.to_julian(date.year, date.month, date.day, \ + hours=date.hour, minutes=date.minute, + seconds=date.second + date.microsecond * 1.0e-6) + elif isinstance(date, datetime.date): + return self.to_julian(date.year, date.month, date.day) + + def to_julian(self, year, month, day, hours=0, minutes=0, seconds=0): + """Convert from Python date to Excel JD.""" + # explicitly disallow bad years + # Excel 2000 treats JD=0 as 1/0/1900 (buggy, disallow) + # Excel 2000 treats JD=2958466 as a bad date (Y10K bug!) + if year < 1900 or year > 10000: + msg = 'Year not supported by Excel: %s' % year + raise ValueError(msg) + if self.excel_base_date == self.CALENDAR_WINDOWS_1900: + # Fudge factor for the erroneous fact that the year 1900 is + # treated as a Leap Year in MS Excel. This affects every date + # following 28th February 1900 + if year == 1900 and month <= 2: + excel_1900_leap_year = False + else: + excel_1900_leap_year = True + excel_base_date = 2415020 + else: + raise NotImplementedError('Mac dates are not yet supported.') + #excel_base_date = 2416481 + #excel_1900_leap_year = False + + # Julian base date adjustment + if month > 2: + month = month - 3 + else: + month = month + 9 + year -= 1 + + # Calculate the Julian Date, then subtract the Excel base date + # JD 2415020 = 31 - Dec - 1899 -> Excel Date of 0 + century, decade = int(str(year)[:2]), int(str(year)[2:]) + excel_date = floor(146097 * century / 4) + \ + floor((1461 * decade) / 4) + floor((153 * month + 2) / 5) + \ + day + 1721119 - excel_base_date + if excel_1900_leap_year: + excel_date += 1 + + # check to ensure that we exclude 2/29/1900 as a possible value + if self.excel_base_date == self.CALENDAR_WINDOWS_1900 \ + and excel_date == 60: + msg = 'Error: Excel believes 1900 was a leap year' + raise ValueError(msg) + excel_time = ((hours * 3600) + (minutes * 60) + seconds) / 86400 + return excel_date + excel_time + + def from_julian(self, value=0): + """Convert from the Excel JD back to a date""" + if self.excel_base_date == self.CALENDAR_WINDOWS_1900: + excel_base_date = 25569 + if value < 60: + excel_base_date -= 1 + elif value == 60: + msg = 'Error: Excel believes 1900 was a leap year' + raise ValueError(msg) + else: + raise NotImplementedError('Mac dates are not yet supported.') + #excel_base_date = 24107 + + if value >= 1: + utc_days = value - excel_base_date + + return EPOCH + datetime.timedelta(days=utc_days) + + elif value >= 0: + hours = floor(value * 24) + mins = floor(value * 24 * 60) - floor(hours * 60) + secs = floor(value * 24 * 60 * 60) - floor(hours * 60 * 60) - \ + floor(mins * 60) + return datetime.time(int(hours), int(mins), int(secs)) + else: + msg = 'Negative dates (%s) are not supported' % value + raise ValueError(msg)
Property changes on: trunk/pywikipedia/openpyxl/shared/date_time.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/shared/exc.py =================================================================== --- trunk/pywikipedia/openpyxl/shared/exc.py (rev 0) +++ trunk/pywikipedia/openpyxl/shared/exc.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,59 @@ +# file openpyxl/shared/exc.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Definitions for openpyxl shared exception classes.""" + + +class CellCoordinatesException(Exception): + """Error for converting between numeric and A1-style cell references.""" + +class ColumnStringIndexException(Exception): + """Error for bad column names in A1-style cell references.""" + +class DataTypeException(Exception): + """Error for any data type inconsistencies.""" + +class NamedRangeException(Exception): + """Error for badly formatted named ranges.""" + +class SheetTitleException(Exception): + """Error for bad sheet names.""" + +class InsufficientCoordinatesException(Exception): + """Error for partially specified cell coordinates.""" + +class OpenModeError(Exception): + """Error for fileobj opened in non-binary mode.""" + +class InvalidFileException(Exception): + """Error for trying to open a non-ooxml file.""" + +class ReadOnlyWorkbookException(Exception): + """Error for trying to modify a read-only workbook""" + +class MissingNumberFormat(Exception): + """Error when a referenced number format is not in the stylesheet""" + +
Property changes on: trunk/pywikipedia/openpyxl/shared/exc.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/shared/ooxml.py =================================================================== --- trunk/pywikipedia/openpyxl/shared/ooxml.py (rev 0) +++ trunk/pywikipedia/openpyxl/shared/ooxml.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,60 @@ +# file openpyxl/shared/ooxml.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Constants for fixed paths in a file and xml namespace urls.""" + +MIN_ROW = 0 +MIN_COLUMN = 0 +MAX_COLUMN = 16384 +MAX_ROW = 1048576 + +# constants +PACKAGE_PROPS = 'docProps' +PACKAGE_XL = 'xl' +PACKAGE_RELS = '_rels' +PACKAGE_THEME = PACKAGE_XL + '/' + 'theme' +PACKAGE_WORKSHEETS = PACKAGE_XL + '/' + 'worksheets' +PACKAGE_DRAWINGS = PACKAGE_XL + '/' + 'drawings' +PACKAGE_CHARTS = PACKAGE_XL + '/' + 'charts' + +ARC_CONTENT_TYPES = '[Content_Types].xml' +ARC_ROOT_RELS = PACKAGE_RELS + '/.rels' +ARC_WORKBOOK_RELS = PACKAGE_XL + '/' + PACKAGE_RELS + '/workbook.xml.rels' +ARC_CORE = PACKAGE_PROPS + '/core.xml' +ARC_APP = PACKAGE_PROPS + '/app.xml' +ARC_WORKBOOK = PACKAGE_XL + '/workbook.xml' +ARC_STYLE = PACKAGE_XL + '/styles.xml' +ARC_THEME = PACKAGE_THEME + '/theme1.xml' +ARC_SHARED_STRINGS = PACKAGE_XL + '/sharedStrings.xml' + +NAMESPACES = { + 'cp': 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties', + 'dc': 'http://purl.org/dc/elements/1.1/', + 'dcterms': 'http://purl.org/dc/terms/', + 'dcmitype': 'http://purl.org/dc/dcmitype/', + 'xsi': 'http://www.w3.org/2001/XMLSchema-instance', + 'vt': 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes', + 'xml': 'http://www.w3.org/XML/1998/namespace' +}
Property changes on: trunk/pywikipedia/openpyxl/shared/ooxml.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/shared/password_hasher.py =================================================================== --- trunk/pywikipedia/openpyxl/shared/password_hasher.py (rev 0) +++ trunk/pywikipedia/openpyxl/shared/password_hasher.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,47 @@ +# file openpyxl/shared/password_hasher.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Basic password hashing.""" + + +def hash_password(plaintext_password=''): + """Create a password hash from a given string. + + This method is based on the algorithm provided by + Daniel Rentz of OpenOffice and the PEAR package + Spreadsheet_Excel_Writer by Xavier Noguer xnoguer@rezebra.com. + + """ + password = 0x0000 + i = 1 + for char in plaintext_password: + value = ord(char) << i + rotated_bits = value >> 15 + value &= 0x7fff + password ^= (value | rotated_bits) + i += 1 + password ^= len(plaintext_password) + password ^= 0xCE4B + return str(hex(password)).upper()[2:]
Property changes on: trunk/pywikipedia/openpyxl/shared/password_hasher.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/shared/units.py =================================================================== --- trunk/pywikipedia/openpyxl/shared/units.py (rev 0) +++ trunk/pywikipedia/openpyxl/shared/units.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,67 @@ +# file openpyxl/shared/units.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +import math + +def pixels_to_EMU(value): + return int(round(value * 9525)) + +def EMU_to_pixels(value): + if not value: + return 0 + else: + return round(value / 9525.) + +def EMU_to_cm(value): + if not value: + return 0 + else: + return (EMU_to_pixels(value) * 2.57 / 96) + +def pixels_to_points(value): + return value * 0.67777777 + +def points_to_pixels(value): + if not value: + return 0 + else: + return int(math.ceil(value * 1.333333333)) + +def degrees_to_angle(value): + return int(round(value * 60000)) + +def angle_to_degrees(value): + if not value: + return 0 + else: + return round(value / 60000.) + +def short_color(color): + """ format a color to its short size """ + + if len(color) > 6: + return color[2:] + else: + return color
Property changes on: trunk/pywikipedia/openpyxl/shared/units.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/shared/xmltools.py =================================================================== --- trunk/pywikipedia/openpyxl/shared/xmltools.py (rev 0) +++ trunk/pywikipedia/openpyxl/shared/xmltools.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,97 @@ +# file openpyxl/shared/xmltools.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Shared xml tools. + +Shortcut functions taken from: + http://lethain.com/entry/2009/jan/22/handling-very-large-csv-and-xml-files-i... + +""" + +# Python stdlib imports +from xml.sax.xmlreader import AttributesNSImpl +from openpyxl.shared.compat.sax import XMLGenerator +try: + from xml.etree.ElementTree import ElementTree, Element, SubElement, \ + QName, fromstring, tostring +except ImportError: + from cElementTree import ElementTree, Element, SubElement, \ + QName, fromstring, tostring + +# package imports +from openpyxl import __name__ as prefix + + +def get_document_content(xml_node): + """Print nicely formatted xml to a string.""" + pretty_indent(xml_node) + return tostring(xml_node, 'utf-8') + + +def pretty_indent(elem, level=0): + """Format xml with nice indents and line breaks.""" + i = "\n" + level * " " + if len(elem): + if not elem.text or not elem.text.strip(): + elem.text = i + " " + if not elem.tail or not elem.tail.strip(): + elem.tail = i + for elem in elem: + pretty_indent(elem, level + 1) + if not elem.tail or not elem.tail.strip(): + elem.tail = i + else: + if level and (not elem.tail or not elem.tail.strip()): + elem.tail = i + + +def start_tag(doc, name, attr=None, body=None, namespace=None): + """Wrapper to start an xml tag.""" + if attr is None: + attr = {} + + attr_vals = {} + attr_keys = {} + for key, val in attr.iteritems(): + key_tuple = (namespace, key) + attr_vals[key_tuple] = val + attr_keys[key_tuple] = key + attr2 = AttributesNSImpl(attr_vals, attr_keys) + doc.startElementNS((namespace, name), name, attr2) + if body: + doc.characters(body) + + +def end_tag(doc, name, namespace=None): + """Wrapper to close an xml tag.""" + doc.endElementNS((namespace, name), name) + + +def tag(doc, name, attr=None, body=None, namespace=None): + """Wrapper to print xml tags and comments.""" + if attr is None: + attr = {} + start_tag(doc, name, attr, body, namespace) + end_tag(doc, name, namespace)
Property changes on: trunk/pywikipedia/openpyxl/shared/xmltools.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/style.py =================================================================== --- trunk/pywikipedia/openpyxl/style.py (rev 0) +++ trunk/pywikipedia/openpyxl/style.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,398 @@ +# file openpyxl/style.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Style and formatting option tracking.""" + +# Python stdlib imports +import re +try: + from hashlib import md5 +except ImportError: + from md5 import md5 + +from openpyxl.shared.compat import any + +class HashableObject(object): + """Define how to hash property classes.""" + __fields__ = None + __leaf__ = False + + def __repr__(self): + + return ':'.join([repr(getattr(self, x)) for x in self.__fields__]) + + def __hash__(self): + +# return int(md5(repr(self)).hexdigest(), 16) + return hash(repr(self)) + +class Color(HashableObject): + """Named colors for use in styles.""" + BLACK = 'FF000000' + WHITE = 'FFFFFFFF' + RED = 'FFFF0000' + DARKRED = 'FF800000' + BLUE = 'FF0000FF' + DARKBLUE = 'FF000080' + GREEN = 'FF00FF00' + DARKGREEN = 'FF008000' + YELLOW = 'FFFFFF00' + DARKYELLOW = 'FF808000' + + __fields__ = ('index',) + __slots__ = __fields__ + __leaf__ = True + + def __init__(self, index): + super(Color, self).__init__() + self.index = index + + +class Font(HashableObject): + """Font options used in styles.""" + UNDERLINE_NONE = 'none' + UNDERLINE_DOUBLE = 'double' + UNDERLINE_DOUBLE_ACCOUNTING = 'doubleAccounting' + UNDERLINE_SINGLE = 'single' + UNDERLINE_SINGLE_ACCOUNTING = 'singleAccounting' + + __fields__ = ('name', + 'size', + 'bold', + 'italic', + 'superscript', + 'subscript', + 'underline', + 'strikethrough', + 'color') + __slots__ = __fields__ + + def __init__(self): + super(Font, self).__init__() + self.name = 'Calibri' + self.size = 11 + self.bold = False + self.italic = False + self.superscript = False + self.subscript = False + self.underline = self.UNDERLINE_NONE + self.strikethrough = False + self.color = Color(Color.BLACK) + + +class Fill(HashableObject): + """Area fill patterns for use in styles.""" + FILL_NONE = 'none' + FILL_SOLID = 'solid' + FILL_GRADIENT_LINEAR = 'linear' + FILL_GRADIENT_PATH = 'path' + FILL_PATTERN_DARKDOWN = 'darkDown' + FILL_PATTERN_DARKGRAY = 'darkGray' + FILL_PATTERN_DARKGRID = 'darkGrid' + FILL_PATTERN_DARKHORIZONTAL = 'darkHorizontal' + FILL_PATTERN_DARKTRELLIS = 'darkTrellis' + FILL_PATTERN_DARKUP = 'darkUp' + FILL_PATTERN_DARKVERTICAL = 'darkVertical' + FILL_PATTERN_GRAY0625 = 'gray0625' + FILL_PATTERN_GRAY125 = 'gray125' + FILL_PATTERN_LIGHTDOWN = 'lightDown' + FILL_PATTERN_LIGHTGRAY = 'lightGray' + FILL_PATTERN_LIGHTGRID = 'lightGrid' + FILL_PATTERN_LIGHTHORIZONTAL = 'lightHorizontal' + FILL_PATTERN_LIGHTTRELLIS = 'lightTrellis' + FILL_PATTERN_LIGHTUP = 'lightUp' + FILL_PATTERN_LIGHTVERTICAL = 'lightVertical' + FILL_PATTERN_MEDIUMGRAY = 'mediumGray' + + __fields__ = ('fill_type', + 'rotation', + 'start_color', + 'end_color') + __slots__ = __fields__ + + def __init__(self): + super(Fill, self).__init__() + self.fill_type = self.FILL_NONE + self.rotation = 0 + self.start_color = Color(Color.WHITE) + self.end_color = Color(Color.BLACK) + + +class Border(HashableObject): + """Border options for use in styles.""" + BORDER_NONE = 'none' + BORDER_DASHDOT = 'dashDot' + BORDER_DASHDOTDOT = 'dashDotDot' + BORDER_DASHED = 'dashed' + BORDER_DOTTED = 'dotted' + BORDER_DOUBLE = 'double' + BORDER_HAIR = 'hair' + BORDER_MEDIUM = 'medium' + BORDER_MEDIUMDASHDOT = 'mediumDashDot' + BORDER_MEDIUMDASHDOTDOT = 'mediumDashDotDot' + BORDER_MEDIUMDASHED = 'mediumDashed' + BORDER_SLANTDASHDOT = 'slantDashDot' + BORDER_THICK = 'thick' + BORDER_THIN = 'thin' + + __fields__ = ('border_style', + 'color') + __slots__ = __fields__ + + def __init__(self): + super(Border, self).__init__() + self.border_style = self.BORDER_NONE + self.color = Color(Color.BLACK) + + +class Borders(HashableObject): + """Border positioning for use in styles.""" + DIAGONAL_NONE = 0 + DIAGONAL_UP = 1 + DIAGONAL_DOWN = 2 + DIAGONAL_BOTH = 3 + + __fields__ = ('left', + 'right', + 'top', + 'bottom', + 'diagonal', + 'diagonal_direction', + 'all_borders', + 'outline', + 'inside', + 'vertical', + 'horizontal') + __slots__ = __fields__ + + def __init__(self): + super(Borders, self).__init__() + self.left = Border() + self.right = Border() + self.top = Border() + self.bottom = Border() + self.diagonal = Border() + self.diagonal_direction = self.DIAGONAL_NONE + + self.all_borders = Border() + self.outline = Border() + self.inside = Border() + self.vertical = Border() + self.horizontal = Border() + + +class Alignment(HashableObject): + """Alignment options for use in styles.""" + HORIZONTAL_GENERAL = 'general' + HORIZONTAL_LEFT = 'left' + HORIZONTAL_RIGHT = 'right' + HORIZONTAL_CENTER = 'center' + HORIZONTAL_CENTER_CONTINUOUS = 'centerContinuous' + HORIZONTAL_JUSTIFY = 'justify' + VERTICAL_BOTTOM = 'bottom' + VERTICAL_TOP = 'top' + VERTICAL_CENTER = 'center' + VERTICAL_JUSTIFY = 'justify' + + __fields__ = ('horizontal', + 'vertical', + 'text_rotation', + 'wrap_text', + 'shrink_to_fit', + 'indent') + __slots__ = __fields__ + __leaf__ = True + + def __init__(self): + super(Alignment, self).__init__() + self.horizontal = self.HORIZONTAL_GENERAL + self.vertical = self.VERTICAL_BOTTOM + self.text_rotation = 0 + self.wrap_text = False + self.shrink_to_fit = False + self.indent = 0 + + +class NumberFormat(HashableObject): + """Numer formatting for use in styles.""" + FORMAT_GENERAL = 'General' + FORMAT_TEXT = '@' + FORMAT_NUMBER = '0' + FORMAT_NUMBER_00 = '0.00' + FORMAT_NUMBER_COMMA_SEPARATED1 = '#,##0.00' + FORMAT_NUMBER_COMMA_SEPARATED2 = '#,##0.00_-' + FORMAT_PERCENTAGE = '0%' + FORMAT_PERCENTAGE_00 = '0.00%' + FORMAT_DATE_YYYYMMDD2 = 'yyyy-mm-dd' + FORMAT_DATE_YYYYMMDD = 'yy-mm-dd' + FORMAT_DATE_DDMMYYYY = 'dd/mm/yy' + FORMAT_DATE_DMYSLASH = 'd/m/y' + FORMAT_DATE_DMYMINUS = 'd-m-y' + FORMAT_DATE_DMMINUS = 'd-m' + FORMAT_DATE_MYMINUS = 'm-y' + FORMAT_DATE_XLSX14 = 'mm-dd-yy' + FORMAT_DATE_XLSX15 = 'd-mmm-yy' + FORMAT_DATE_XLSX16 = 'd-mmm' + FORMAT_DATE_XLSX17 = 'mmm-yy' + FORMAT_DATE_XLSX22 = 'm/d/yy h:mm' + FORMAT_DATE_DATETIME = 'd/m/y h:mm' + FORMAT_DATE_TIME1 = 'h:mm AM/PM' + FORMAT_DATE_TIME2 = 'h:mm:ss AM/PM' + FORMAT_DATE_TIME3 = 'h:mm' + FORMAT_DATE_TIME4 = 'h:mm:ss' + FORMAT_DATE_TIME5 = 'mm:ss' + FORMAT_DATE_TIME6 = 'h:mm:ss' + FORMAT_DATE_TIME7 = 'i:s.S' + FORMAT_DATE_TIME8 = 'h:mm:ss@' + FORMAT_DATE_YYYYMMDDSLASH = 'yy/mm/dd@' + FORMAT_CURRENCY_USD_SIMPLE = '"$"#,##0.00_-' + FORMAT_CURRENCY_USD = '$#,##0_-' + FORMAT_CURRENCY_EUR_SIMPLE = '[$EUR ]#,##0.00_-' + _BUILTIN_FORMATS = { + 0: 'General', + 1: '0', + 2: '0.00', + 3: '#,##0', + 4: '#,##0.00', + + 9: '0%', + 10: '0.00%', + 11: '0.00E+00', + 12: '# ?/?', + 13: '# ??/??', + 14: 'mm-dd-yy', + 15: 'd-mmm-yy', + 16: 'd-mmm', + 17: 'mmm-yy', + 18: 'h:mm AM/PM', + 19: 'h:mm:ss AM/PM', + 20: 'h:mm', + 21: 'h:mm:ss', + 22: 'm/d/yy h:mm', + + 37: '#,##0 (#,##0)', + 38: '#,##0 [Red](#,##0)', + 39: '#,##0.00(#,##0.00)', + 40: '#,##0.00[Red](#,##0.00)', + + 41: '_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)', + 42: '_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)', + 43: '_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)', + + 44: '_("$"* #,##0.00_)_("$"* (#,##0.00)_("$"* "-"??_)_(@_)', + 45: 'mm:ss', + 46: '[h]:mm:ss', + 47: 'mmss.0', + 48: '##0.0E+0', + 49: '@', } + _BUILTIN_FORMATS_REVERSE = dict( + [(value, key) for key, value in _BUILTIN_FORMATS.iteritems()]) + + __fields__ = ('_format_code', + '_format_index') + __slots__ = __fields__ + __leaf__ = True + + DATE_INDICATORS = 'dmyhs' + BAD_DATE_RE = re.compile(r'([|").*[dmhys].*(]|")') + + def __init__(self): + super(NumberFormat, self).__init__() + self._format_code = self.FORMAT_GENERAL + self._format_index = 0 + + def _set_format_code(self, format_code = FORMAT_GENERAL): + """Setter for the format_code property.""" + self._format_code = format_code + self._format_index = self.builtin_format_id(format = format_code) + + def _get_format_code(self): + """Getter for the format_code property.""" + return self._format_code + + format_code = property(_get_format_code, _set_format_code) + + def builtin_format_code(self, index): + """Return one of the standard format codes by index.""" + return self._BUILTIN_FORMATS[index] + + def is_builtin(self, format = None): + """Check if a format code is a standard format code.""" + if format is None: + format = self._format_code + return format in self._BUILTIN_FORMATS.values() + + def builtin_format_id(self, format): + """Return the id of a standard style.""" + return self._BUILTIN_FORMATS_REVERSE.get(format, None) + + def is_date_format(self, format = None): + """Check if the number format is actually representing a date.""" + if format is None: + format = self._format_code + + if any([x in format for x in self.DATE_INDICATORS]): + if self.BAD_DATE_RE.search(format) is None: + return True + + return False + +class Protection(HashableObject): + """Protection options for use in styles.""" + PROTECTION_INHERIT = 'inherit' + PROTECTION_PROTECTED = 'protected' + PROTECTION_UNPROTECTED = 'unprotected' + + __fields__ = ('locked', + 'hidden') + __slots__ = __fields__ + __leaf__ = True + + def __init__(self): + super(Protection, self).__init__() + self.locked = self.PROTECTION_INHERIT + self.hidden = self.PROTECTION_INHERIT + + +class Style(HashableObject): + """Style object containing all formatting details.""" + __fields__ = ('font', + 'fill', + 'borders', + 'alignment', + 'number_format', + 'protection') + __slots__ = __fields__ + + def __init__(self): + super(Style, self).__init__() + self.font = Font() + self.fill = Fill() + self.borders = Borders() + self.alignment = Alignment() + self.number_format = NumberFormat() + self.protection = Protection() + +DEFAULTS = Style()
Property changes on: trunk/pywikipedia/openpyxl/style.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/workbook.py =================================================================== --- trunk/pywikipedia/openpyxl/workbook.py (rev 0) +++ trunk/pywikipedia/openpyxl/workbook.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,191 @@ +# file openpyxl/workbook.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Workbook is the top-level container for all document information.""" + +__docformat__ = "restructuredtext en" + +# Python stdlib imports +import datetime +import os + +# package imports +from openpyxl.worksheet import Worksheet +from openpyxl.writer.dump_worksheet import DumpWorksheet, save_dump +from openpyxl.writer.strings import StringTableBuilder +from openpyxl.namedrange import NamedRange +from openpyxl.style import Style +from openpyxl.writer.excel import save_workbook +from openpyxl.shared.exc import ReadOnlyWorkbookException + + +class DocumentProperties(object): + """High-level properties of the document.""" + + def __init__(self): + self.creator = 'Unknown' + self.last_modified_by = self.creator + self.created = datetime.datetime.now() + self.modified = datetime.datetime.now() + self.title = 'Untitled' + self.subject = '' + self.description = '' + self.keywords = '' + self.category = '' + self.company = 'Microsoft Corporation' + + +class DocumentSecurity(object): + """Security information about the document.""" + + def __init__(self): + self.lock_revision = False + self.lock_structure = False + self.lock_windows = False + self.revision_password = '' + self.workbook_password = '' + + +class Workbook(object): + """Workbook is the container for all other parts of the document.""" + + def __init__(self, optimized_write=False, encoding='utf-8'): + self.worksheets = [] + self._active_sheet_index = 0 + self._named_ranges = [] + self.properties = DocumentProperties() + self.style = Style() + self.security = DocumentSecurity() + self.__optimized_write = optimized_write + self.__optimized_read = False + self.strings_table_builder = StringTableBuilder() + + self.encoding = encoding + + if not optimized_write: + self.worksheets.append(Worksheet(self)) + + def _set_optimized_read(self): + self.__optimized_read = True + + def get_active_sheet(self): + """Returns the current active sheet.""" + return self.worksheets[self._active_sheet_index] + + def create_sheet(self, index=None): + """Create a worksheet (at an optional index). + + :param index: optional position at which the sheet will be inserted + :type index: int + + """ + + if self.__optimized_read: + raise ReadOnlyWorkbookException('Cannot create new sheet in a read-only workbook') + + if self.__optimized_write : + new_ws = DumpWorksheet(parent_workbook=self) + else: + new_ws = Worksheet(parent_workbook=self) + + self.add_sheet(worksheet=new_ws, index=index) + return new_ws + + def add_sheet(self, worksheet, index=None): + """Add an existing worksheet (at an optional index).""" + + assert isinstance(worksheet, Worksheet), "The parameter you have given is not of the type 'Worksheet'" + + if index is None: + index = len(self.worksheets) + self.worksheets.insert(index, worksheet) + + def remove_sheet(self, worksheet): + """Remove a worksheet from this workbook.""" + self.worksheets.remove(worksheet) + + def get_sheet_by_name(self, name): + """Returns a worksheet by its name. + + Returns None if no worksheet has the name specified. + + :param name: the name of the worksheet to look for + :type name: string + + """ + requested_sheet = None + for sheet in self.worksheets: + if sheet.title == name: + requested_sheet = sheet + break + return requested_sheet + + def get_index(self, worksheet): + """Return the index of the worksheet.""" + return self.worksheets.index(worksheet) + + def get_sheet_names(self): + """Returns the list of the names of worksheets in the workbook. + + Names are returned in the worksheets order. + + :rtype: list of strings + + """ + return [s.title for s in self.worksheets] + + def create_named_range(self, name, worksheet, range): + """Create a new named_range on a worksheet""" + assert isinstance(worksheet, Worksheet) + named_range = NamedRange(name, [(worksheet, range)]) + self.add_named_range(named_range) + + def get_named_ranges(self): + """Return all named ranges""" + return self._named_ranges + + def add_named_range(self, named_range): + """Add an existing named_range to the list of named_ranges.""" + self._named_ranges.append(named_range) + + def get_named_range(self, name): + """Return the range specified by name.""" + requested_range = None + for named_range in self._named_ranges: + if named_range.name == name: + requested_range = named_range + break + return requested_range + + def remove_named_range(self, named_range): + """Remove a named_range from this workbook.""" + self._named_ranges.remove(named_range) + + def save(self, filename): + """ shortcut """ + if self.__optimized_write: + save_dump(self, filename) + else: + save_workbook(self, filename)
Property changes on: trunk/pywikipedia/openpyxl/workbook.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/worksheet.py =================================================================== --- trunk/pywikipedia/openpyxl/worksheet.py (rev 0) +++ trunk/pywikipedia/openpyxl/worksheet.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,542 @@ +# file openpyxl/worksheet.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Worksheet is the 2nd-level container in Excel.""" + +# Python stdlib imports +import re + +# package imports +import openpyxl.cell +from openpyxl.cell import coordinate_from_string, \ + column_index_from_string, get_column_letter +from openpyxl.shared.exc import SheetTitleException, \ + InsufficientCoordinatesException, CellCoordinatesException, \ + NamedRangeException +from openpyxl.shared.password_hasher import hash_password +from openpyxl.style import Style, DEFAULTS as DEFAULTS_STYLE +from openpyxl.drawing import Drawing +from openpyxl.namedrange import NamedRangeContainingValue + +_DEFAULTS_STYLE_HASH = hash(DEFAULTS_STYLE) + +def flatten(results): + + rows = [] + + for row in results: + + cells = [] + + for cell in row: + + cells.append(cell.value) + + rows.append(tuple(cells)) + + return tuple(rows) + + +class Relationship(object): + """Represents many kinds of relationships.""" + # TODO: Use this object for workbook relationships as well as + # worksheet relationships + TYPES = { + 'hyperlink': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlin...', + 'drawing':'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', + #'worksheet': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/workshee...', + #'sharedStrings': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedSt...', + #'styles': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles', + #'theme': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme', + } + + def __init__(self, rel_type): + if rel_type not in self.TYPES: + raise ValueError("Invalid relationship type %s" % rel_type) + self.type = self.TYPES[rel_type] + self.target = "" + self.target_mode = "" + self.id = "" + + +class PageSetup(object): + """Information about page layout for this sheet""" + pass + + +class HeaderFooter(object): + """Information about the header/footer for this sheet.""" + pass + + +class SheetView(object): + """Information about the visible portions of this sheet.""" + pass + + +class RowDimension(object): + """Information about the display properties of a row.""" + __slots__ = ('row_index', + 'height', + 'visible', + 'outline_level', + 'collapsed', + 'style_index',) + + def __init__(self, index=0): + self.row_index = index + self.height = -1 + self.visible = True + self.outline_level = 0 + self.collapsed = False + self.style_index = None + + +class ColumnDimension(object): + """Information about the display properties of a column.""" + __slots__ = ('column_index', + 'width', + 'auto_size', + 'visible', + 'outline_level', + 'collapsed', + 'style_index',) + + def __init__(self, index='A'): + self.column_index = index + self.width = -1 + self.auto_size = False + self.visible = True + self.outline_level = 0 + self.collapsed = False + self.style_index = 0 + + +class PageMargins(object): + """Information about page margins for view/print layouts.""" + + def __init__(self): + self.left = self.right = 0.7 + self.top = self.bottom = 0.75 + self.header = self.footer = 0.3 + + +class SheetProtection(object): + """Information about protection of various aspects of a sheet.""" + + def __init__(self): + self.sheet = False + self.objects = False + self.scenarios = False + self.format_cells = False + self.format_columns = False + self.format_rows = False + self.insert_columns = False + self.insert_rows = False + self.insert_hyperlinks = False + self.delete_columns = False + self.delete_rows = False + self.select_locked_cells = False + self.sort = False + self.auto_filter = False + self.pivot_tables = False + self.select_unlocked_cells = False + self._password = '' + + def set_password(self, value='', already_hashed=False): + """Set a password on this sheet.""" + if not already_hashed: + value = hash_password(value) + self._password = value + + def _set_raw_password(self, value): + """Set a password directly, forcing a hash step.""" + self.set_password(value, already_hashed=False) + + def _get_raw_password(self): + """Return the password value, regardless of hash.""" + return self._password + + password = property(_get_raw_password, _set_raw_password, + 'get/set the password (if already hashed, ' + 'use set_password() instead)') + + +class Worksheet(object): + """Represents a worksheet. + + Do not create worksheets yourself, + use :func:`openpyxl.workbook.Workbook.create_sheet` instead + + """ + BREAK_NONE = 0 + BREAK_ROW = 1 + BREAK_COLUMN = 2 + + SHEETSTATE_VISIBLE = 'visible' + SHEETSTATE_HIDDEN = 'hidden' + SHEETSTATE_VERYHIDDEN = 'veryHidden' + + def __init__(self, parent_workbook, title='Sheet'): + self._parent = parent_workbook + self._title = '' + if not title: + self.title = 'Sheet%d' % (1 + len(self._parent.worksheets)) + else: + self.title = title + self.row_dimensions = {} + self.column_dimensions = {} + self._cells = {} + self._styles = {} + self._charts = [] + self.relationships = [] + self.selected_cell = 'A1' + self.active_cell = 'A1' + self.sheet_state = self.SHEETSTATE_VISIBLE + self.page_setup = PageSetup() + self.page_margins = PageMargins() + self.header_footer = HeaderFooter() + self.sheet_view = SheetView() + self.protection = SheetProtection() + self.show_gridlines = True + self.print_gridlines = False + self.show_summary_below = True + self.show_summary_right = True + self.default_row_dimension = RowDimension() + self.default_column_dimension = ColumnDimension() + self._auto_filter = None + self._freeze_panes = None + + def __repr__(self): + return u'<Worksheet "%s">' % self.title + + @property + def encoding(self): + return self._parent.encoding + + def garbage_collect(self): + """Delete cells that are not storing a value.""" + delete_list = [coordinate for coordinate, cell in \ + self._cells.iteritems() if (cell.value in ('', None) and \ + hash(cell.style) == _DEFAULTS_STYLE_HASH)] + for coordinate in delete_list: + del self._cells[coordinate] + + def get_cell_collection(self): + """Return an unordered list of the cells in this worksheet.""" + return self._cells.values() + + def _set_title(self, value): + """Set a sheet title, ensuring it is valid.""" + bad_title_char_re = re.compile(r'[\*?:/[]]') + if bad_title_char_re.search(value): + msg = 'Invalid character found in sheet title' + raise SheetTitleException(msg) + + # check if sheet_name already exists + # do this *before* length check + if self._parent.get_sheet_by_name(value): + # use name, but append with lowest possible integer + i = 1 + while self._parent.get_sheet_by_name('%s%d' % (value, i)): + i += 1 + value = '%s%d' % (value, i) + if len(value) > 31: + msg = 'Maximum 31 characters allowed in sheet title' + raise SheetTitleException(msg) + self._title = value + + def _get_title(self): + """Return the title for this sheet.""" + return self._title + + title = property(_get_title, _set_title, doc= + 'Get or set the title of the worksheet. ' + 'Limited to 31 characters, no special characters.') + + def _set_auto_filter(self, range): + # Normalize range to a str or None + if not range: + range = None + elif isinstance(range, str): + range = range.upper() + else: # Assume a range + range = range[0][0].address + ':' + range[-1][-1].address + self._auto_filter = range + + def _get_auto_filter(self): + return self._auto_filter + + auto_filter = property(_get_auto_filter, _set_auto_filter, doc= + 'get or set auto filtering on columns') + def _set_freeze_panes(self, topLeftCell): + if not topLeftCell: + topLeftCell = None + elif isinstance(topLeftCell, str): + topLeftCell = topLeftCell.upper() + else: # Assume a cell + topLeftCell = topLeftCell.address + if topLeftCell == 'A1': + topLeftCell = None + self._freeze_panes = topLeftCell + + def _get_freeze_panes(self): + return self._freeze_panes + + freeze_panes = property(_get_freeze_panes, _set_freeze_panes, doc= + "Get or set frozen panes") + + def cell(self, coordinate=None, row=None, column=None): + """Returns a cell object based on the given coordinates. + + Usage: cell(coodinate='A15') **or** cell(row=15, column=1) + + If `coordinates` are not given, then row *and* column must be given. + + Cells are kept in a dictionary which is empty at the worksheet + creation. Calling `cell` creates the cell in memory when they + are first accessed, to reduce memory usage. + + :param coordinate: coordinates of the cell (e.g. 'B12') + :type coordinate: string + + :param row: row index of the cell (e.g. 4) + :type row: int + + :param column: column index of the cell (e.g. 3) + :type column: int + + :raise: InsufficientCoordinatesException when coordinate or (row and column) are not given + + :rtype: :class:`openpyxl.cell.Cell` + + """ + if not coordinate: + if (row is None or column is None): + msg = "You have to provide a value either for " \ + "'coordinate' or for 'row' *and* 'column'" + raise InsufficientCoordinatesException(msg) + else: + coordinate = '%s%s' % (get_column_letter(column + 1), row + 1) + else: + coordinate = coordinate.replace('$', '') + + return self._get_cell(coordinate) + + def _get_cell(self, coordinate): + + if not coordinate in self._cells: + column, row = coordinate_from_string(coordinate) + new_cell = openpyxl.cell.Cell(self, column, row) + self._cells[coordinate] = new_cell + if column not in self.column_dimensions: + self.column_dimensions[column] = ColumnDimension(column) + if row not in self.row_dimensions: + self.row_dimensions[row] = RowDimension(row) + return self._cells[coordinate] + + def get_highest_row(self): + """Returns the maximum row index containing data + + :rtype: int + """ + if self.row_dimensions: + return max(self.row_dimensions.keys()) + else: + return 1 + + def get_highest_column(self): + """Get the largest value for column currently stored. + + :rtype: int + """ + if self.column_dimensions: + return max([column_index_from_string(column_index) + for column_index in self.column_dimensions]) + else: + return 1 + + def calculate_dimension(self): + """Return the minimum bounding range for all cells containing data.""" + return 'A1:%s%d' % (get_column_letter(self.get_highest_column()), + self.get_highest_row()) + + def range(self, range_string, row=0, column=0): + """Returns a 2D array of cells, with optional row and column offsets. + + :param range_string: cell range string or `named range` name + :type range_string: string + + :param row: number of rows to offset + :type row: int + + :param column: number of columns to offset + :type column: int + + :rtype: tuples of tuples of :class:`openpyxl.cell.Cell` + + """ + if ':' in range_string: + # R1C1 range + result = [] + min_range, max_range = range_string.split(':') + min_col, min_row = coordinate_from_string(min_range) + max_col, max_row = coordinate_from_string(max_range) + if column: + min_col = get_column_letter( + column_index_from_string(min_col) + column) + max_col = get_column_letter( + column_index_from_string(max_col) + column) + min_col = column_index_from_string(min_col) + max_col = column_index_from_string(max_col) + cache_cols = {} + for col in xrange(min_col, max_col + 1): + cache_cols[col] = get_column_letter(col) + rows = xrange(min_row + row, max_row + row + 1) + cols = xrange(min_col, max_col + 1) + for row in rows: + new_row = [] + for col in cols: + new_row.append(self.cell('%s%s' % (cache_cols[col], row))) + result.append(tuple(new_row)) + return tuple(result) + else: + try: + return self.cell(coordinate=range_string, row=row, + column=column) + except CellCoordinatesException: + pass + + # named range + named_range = self._parent.get_named_range(range_string) + if named_range is None: + msg = '%s is not a valid range name' % range_string + raise NamedRangeException(msg) + if isinstance(named_range, NamedRangeContainingValue): + msg = '%s refers to a value, not a range' % range_string + raise NamedRangeException(msg) + + result = [] + for destination in named_range.destinations: + + worksheet, cells_range = destination + + if worksheet is not self: + msg = 'Range %s is not defined on worksheet %s' % \ + (cells_range, self.title) + raise NamedRangeException(msg) + + content = self.range(cells_range) + + if isinstance(content, tuple): + for cells in content: + result.extend(cells) + else: + result.append(content) + + if len(result) == 1: + return result[0] + else: + return tuple(result) + + def get_style(self, coordinate): + """Return the style object for the specified cell.""" + if not coordinate in self._styles: + self._styles[coordinate] = Style() + return self._styles[coordinate] + + def create_relationship(self, rel_type): + """Add a relationship for this sheet.""" + rel = Relationship(rel_type) + self.relationships.append(rel) + rel_id = self.relationships.index(rel) + rel.id = 'rId' + str(rel_id + 1) + return self.relationships[rel_id] + + def add_chart(self, chart): + """ Add a chart to the sheet """ + + chart._sheet = self + self._charts.append(chart) + + def append(self, list_or_dict): + """Appends a group of values at the bottom of the current sheet. + + * If it's a list: all values are added in order, starting from the first column + * If it's a dict: values are assigned to the columns indicated by the keys (numbers or letters) + + :param list_or_dict: list or dict containing values to append + :type list_or_dict: list/tuple or dict + + Usage: + + * append(['This is A1', 'This is B1', 'This is C1']) + * **or** append({'A' : 'This is A1', 'C' : 'This is C1'}) + * **or** append({0 : 'This is A1', 2 : 'This is C1'}) + + :raise: TypeError when list_or_dict is neither a list/tuple nor a dict + + """ + + row_idx = len(self.row_dimensions) + + if isinstance(list_or_dict, (list, tuple)): + + for col_idx, content in enumerate(list_or_dict): + + self.cell(row=row_idx, column=col_idx).value = content + + elif isinstance(list_or_dict, dict): + + for col_idx, content in list_or_dict.iteritems(): + + if isinstance(col_idx, basestring): + col_idx = column_index_from_string(col_idx) - 1 + + self.cell(row=row_idx, column=col_idx).value = content + + else: + raise TypeError('list_or_dict must be a list or a dict') + + @property + def rows(self): + + return self.range(self.calculate_dimension()) + + @property + def columns(self): + + max_row = self.get_highest_row() + + cols = [] + + for col_idx in range(self.get_highest_column()): + col = get_column_letter(col_idx + 1) + res = self.range('%s1:%s%d' % (col, col, max_row)) + cols.append(tuple([x[0] for x in res])) + + + return tuple(cols) +
Property changes on: trunk/pywikipedia/openpyxl/worksheet.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/writer/__init__.py =================================================================== --- trunk/pywikipedia/openpyxl/writer/__init__.py (rev 0) +++ trunk/pywikipedia/openpyxl/writer/__init__.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,34 @@ +# file openpyxl/writer/__init__.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Imports for the openpyxl.writer namespace.""" + +# package imports +from openpyxl.writer import excel +from openpyxl.writer import strings +from openpyxl.writer import styles +from openpyxl.writer import theme +from openpyxl.writer import workbook +from openpyxl.writer import worksheet
Property changes on: trunk/pywikipedia/openpyxl/writer/__init__.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/writer/charts.py =================================================================== --- trunk/pywikipedia/openpyxl/writer/charts.py (rev 0) +++ trunk/pywikipedia/openpyxl/writer/charts.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,272 @@ +# coding=UTF-8 +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +from openpyxl.shared.xmltools import Element, SubElement, get_document_content +from openpyxl.chart import Chart, ErrorBar + +class ChartWriter(object): + + def __init__(self, chart): + self.chart = chart + + def write(self): + """ write a chart """ + + root = Element('c:chartSpace', + {'xmlns:c':"http://schemas.openxmlformats.org/drawingml/2006/chart", + 'xmlns:a':"http://schemas.openxmlformats.org/drawingml/2006/main", + 'xmlns:r':"http://schemas.openxmlformats.org/officeDocument/2006/relationships%22%7D) + + SubElement(root, 'c:lang', {'val':self.chart.lang}) + self._write_chart(root) + self._write_print_settings(root) + self._write_shapes(root) + + return get_document_content(root) + + def _write_chart(self, root): + + chart = self.chart + + ch = SubElement(root, 'c:chart') + self._write_title(ch) + plot_area = SubElement(ch, 'c:plotArea') + layout = SubElement(plot_area, 'c:layout') + mlayout = SubElement(layout, 'c:manualLayout') + SubElement(mlayout, 'c:layoutTarget', {'val':'inner'}) + SubElement(mlayout, 'c:xMode', {'val':'edge'}) + SubElement(mlayout, 'c:yMode', {'val':'edge'}) + SubElement(mlayout, 'c:x', {'val':str(chart._get_margin_left())}) + SubElement(mlayout, 'c:y', {'val':str(chart._get_margin_top())}) + SubElement(mlayout, 'c:w', {'val':str(chart.width)}) + SubElement(mlayout, 'c:h', {'val':str(chart.height)}) + + if chart.type == Chart.SCATTER_CHART: + subchart = SubElement(plot_area, 'c:scatterChart') + SubElement(subchart, 'c:scatterStyle', {'val':str('lineMarker')}) + else: + if chart.type == Chart.BAR_CHART: + subchart = SubElement(plot_area, 'c:barChart') + SubElement(subchart, 'c:barDir', {'val':'col'}) + else: + subchart = SubElement(plot_area, 'c:lineChart') + + SubElement(subchart, 'c:grouping', {'val':chart.grouping}) + + self._write_series(subchart) + + SubElement(subchart, 'c:marker', {'val':'1'}) + SubElement(subchart, 'c:axId', {'val':str(chart.x_axis.id)}) + SubElement(subchart, 'c:axId', {'val':str(chart.y_axis.id)}) + + if chart.type == Chart.SCATTER_CHART: + self._write_axis(plot_area, chart.x_axis, 'c:valAx') + else: + self._write_axis(plot_area, chart.x_axis, 'c:catAx') + self._write_axis(plot_area, chart.y_axis, 'c:valAx') + + self._write_legend(ch) + + SubElement(ch, 'c:plotVisOnly', {'val':'1'}) + + def _write_title(self, chart): + if self.chart.title != '': + title = SubElement(chart, 'c:title') + tx = SubElement(title, 'c:tx') + rich = SubElement(tx, 'c:rich') + SubElement(rich, 'a:bodyPr') + SubElement(rich, 'a:lstStyle') + p = SubElement(rich, 'a:p') + pPr = SubElement(p, 'a:pPr') + SubElement(pPr, 'a:defRPr') + r = SubElement(p, 'a:r') + SubElement(r, 'a:rPr', {'lang':self.chart.lang}) + t = SubElement(r, 'a:t').text = self.chart.title + SubElement(title, 'c:layout') + + def _write_axis(self, plot_area, axis, label): + + ax = SubElement(plot_area, label) + SubElement(ax, 'c:axId', {'val':str(axis.id)}) + + scaling = SubElement(ax, 'c:scaling') + SubElement(scaling, 'c:orientation', {'val':axis.orientation}) + if label == 'c:valAx': + SubElement(scaling, 'c:max', {'val':str(axis.max)}) + SubElement(scaling, 'c:min', {'val':str(axis.min)}) + + SubElement(ax, 'c:axPos', {'val':axis.position}) + if label == 'c:valAx': + SubElement(ax, 'c:majorGridlines') + SubElement(ax, 'c:numFmt', {'formatCode':"General", 'sourceLinked':'1'}) + if axis.title != '': + title = SubElement(ax, 'c:title') + tx = SubElement(title, 'c:tx') + rich = SubElement(tx, 'c:rich') + SubElement(rich, 'a:bodyPr') + SubElement(rich, 'a:lstStyle') + p = SubElement(rich, 'a:p') + pPr = SubElement(p, 'a:pPr') + SubElement(pPr, 'a:defRPr') + r = SubElement(p, 'a:r') + SubElement(r, 'a:rPr', {'lang':self.chart.lang}) + t = SubElement(r, 'a:t').text = axis.title + SubElement(title, 'c:layout') + SubElement(ax, 'c:tickLblPos', {'val':axis.tick_label_position}) + SubElement(ax, 'c:crossAx', {'val':str(axis.cross)}) + SubElement(ax, 'c:crosses', {'val':axis.crosses}) + if axis.auto: + SubElement(ax, 'c:auto', {'val':'1'}) + if axis.label_align: + SubElement(ax, 'c:lblAlgn', {'val':axis.label_align}) + if axis.label_offset: + SubElement(ax, 'c:lblOffset', {'val':str(axis.label_offset)}) + if label == 'c:valAx': + if self.chart.type == Chart.SCATTER_CHART: + SubElement(ax, 'c:crossBetween', {'val':'midCat'}) + else: + SubElement(ax, 'c:crossBetween', {'val':'between'}) + SubElement(ax, 'c:majorUnit', {'val':str(axis.unit)}) + + def _write_series(self, subchart): + + for i, serie in enumerate(self.chart._series): + ser = SubElement(subchart, 'c:ser') + SubElement(ser, 'c:idx', {'val':str(i)}) + SubElement(ser, 'c:order', {'val':str(i)}) + + if serie.legend: + tx = SubElement(ser, 'c:tx') + self._write_serial(tx, serie.legend) + + if serie.color: + sppr = SubElement(ser, 'c:spPr') + if self.chart.type == Chart.BAR_CHART: + # fill color + fillc = SubElement(sppr, 'a:solidFill') + SubElement(fillc, 'a:srgbClr', {'val':serie.color}) + # edge color + ln = SubElement(sppr, 'a:ln') + fill = SubElement(ln, 'a:solidFill') + SubElement(fill, 'a:srgbClr', {'val':serie.color}) + + if serie.error_bar: + self._write_error_bar(ser, serie) + + marker = SubElement(ser, 'c:marker') + SubElement(marker, 'c:symbol', {'val':serie.marker}) + + if serie.labels: + cat = SubElement(ser, 'c:cat') + self._write_serial(cat, serie.labels) + + if self.chart.type == Chart.SCATTER_CHART: + if serie.xvalues: + xval = SubElement(ser, 'c:xVal') + self._write_serial(xval, serie.xvalues) + + yval = SubElement(ser, 'c:yVal') + self._write_serial(yval, serie.values) + else: + val = SubElement(ser, 'c:val') + self._write_serial(val, serie.values) + + def _write_serial(self, node, serie, literal=False): + + cache = serie._get_cache() + if isinstance(cache[0], basestring): + typ = 'str' + else: + typ = 'num' + + if not literal: + if typ == 'num': + ref = SubElement(node, 'c:numRef') + else: + ref = SubElement(node, 'c:strRef') + SubElement(ref, 'c:f').text = serie._get_ref() + if typ == 'num': + data = SubElement(ref, 'c:numCache') + else: + data = SubElement(ref, 'c:strCache') + else: + data = SubElement(node, 'c:numLit') + + if typ == 'num': + SubElement(data, 'c:formatCode').text = 'General' + if literal: + values = (1,) + else: + values = cache + + SubElement(data, 'c:ptCount', {'val':str(len(values))}) + for j, val in enumerate(values): + point = SubElement(data, 'c:pt', {'idx':str(j)}) + SubElement(point, 'c:v').text = str(val) + + def _write_error_bar(self, node, serie): + + flag = {ErrorBar.PLUS_MINUS:'both', + ErrorBar.PLUS:'plus', + ErrorBar.MINUS:'minus'} + + eb = SubElement(node, 'c:errBars') + SubElement(eb, 'c:errBarType', {'val':flag[serie.error_bar.type]}) + SubElement(eb, 'c:errValType', {'val':'cust'}) + + plus = SubElement(eb, 'c:plus') + self._write_serial(plus, serie.error_bar.values, + literal=(serie.error_bar.type == ErrorBar.MINUS)) + + minus = SubElement(eb, 'c:minus') + self._write_serial(minus, serie.error_bar.values, + literal=(serie.error_bar.type == ErrorBar.PLUS)) + + def _write_legend(self, chart): + + legend = SubElement(chart, 'c:legend') + SubElement(legend, 'c:legendPos', {'val':self.chart.legend.position}) + SubElement(legend, 'c:layout') + + def _write_print_settings(self, root): + + settings = SubElement(root, 'c:printSettings') + SubElement(settings, 'c:headerFooter') + margins = dict([(k, str(v)) for (k, v) in self.chart.print_margins.iteritems()]) + SubElement(settings, 'c:pageMargins', margins) + SubElement(settings, 'c:pageSetup') + + def _write_shapes(self, root): + + if self.chart._shapes: + SubElement(root, 'c:userShapes', {'r:id':'rId1'}) + + def write_rels(self, drawing_id): + + root = Element('Relationships', {'xmlns' : 'http://schemas.openxmlformats.org/package/2006/relationships%27%7D) + attrs = {'Id' : 'rId1', + 'Type' : 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartUse...', + 'Target' : '../drawings/drawing%s.xml' % drawing_id } + SubElement(root, 'Relationship', attrs) + return get_document_content(root)
Property changes on: trunk/pywikipedia/openpyxl/writer/charts.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/writer/drawings.py =================================================================== --- trunk/pywikipedia/openpyxl/writer/drawings.py (rev 0) +++ trunk/pywikipedia/openpyxl/writer/drawings.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,191 @@ +# coding=UTF-8 + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +from openpyxl.shared.xmltools import Element, SubElement, get_document_content + + +class DrawingWriter(object): + """ one main drawing file per sheet """ + + def __init__(self, sheet): + self._sheet = sheet + + def write(self): + """ write drawings for one sheet in one file """ + + root = Element('xdr:wsDr', + {'xmlns:xdr' : "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing", + 'xmlns:a' : "http://schemas.openxmlformats.org/drawingml/2006/main%22%7D) + + for i, chart in enumerate(self._sheet._charts): + + drawing = chart.drawing + +# anchor = SubElement(root, 'xdr:twoCellAnchor') +# (start_row, start_col), (end_row, end_col) = drawing.coordinates +# # anchor coordinates +# _from = SubElement(anchor, 'xdr:from') +# x = SubElement(_from, 'xdr:col').text = str(start_col) +# x = SubElement(_from, 'xdr:colOff').text = '0' +# x = SubElement(_from, 'xdr:row').text = str(start_row) +# x = SubElement(_from, 'xdr:rowOff').text = '0' + +# _to = SubElement(anchor, 'xdr:to') +# x = SubElement(_to, 'xdr:col').text = str(end_col) +# x = SubElement(_to, 'xdr:colOff').text = '0' +# x = SubElement(_to, 'xdr:row').text = str(end_row) +# x = SubElement(_to, 'xdr:rowOff').text = '0' + + # we only support absolute anchor atm (TODO: oneCellAnchor, twoCellAnchor + x, y, w, h = drawing.get_emu_dimensions() + anchor = SubElement(root, 'xdr:absoluteAnchor') + SubElement(anchor, 'xdr:pos', {'x':str(x), 'y':str(y)}) + SubElement(anchor, 'xdr:ext', {'cx':str(w), 'cy':str(h)}) + + # graph frame + frame = SubElement(anchor, 'xdr:graphicFrame', {'macro':''}) + + name = SubElement(frame, 'xdr:nvGraphicFramePr') + SubElement(name, 'xdr:cNvPr', {'id':'%s' % i, 'name':'Graphique %s' % i}) + SubElement(name, 'xdr:cNvGraphicFramePr') + + frm = SubElement(frame, 'xdr:xfrm') + # no transformation + SubElement(frm, 'a:off', {'x':'0', 'y':'0'}) + SubElement(frm, 'a:ext', {'cx':'0', 'cy':'0'}) + + graph = SubElement(frame, 'a:graphic') + data = SubElement(graph, 'a:graphicData', + {'uri':'http://schemas.openxmlformats.org/drawingml/2006/chart%27%7D) + SubElement(data, 'c:chart', + { 'xmlns:c':'http://schemas.openxmlformats.org/drawingml/2006/chart', + 'xmlns:r':'http://schemas.openxmlformats.org/officeDocument/2006/relationships', + 'r:id':'rId%s' % (i + 1)}) + + SubElement(anchor, 'xdr:clientData') + + return get_document_content(root) + + def write_rels(self, chart_id): + + root = Element('Relationships', + {'xmlns' : 'http://schemas.openxmlformats.org/package/2006/relationships%27%7D) + for i, chart in enumerate(self._sheet._charts): + attrs = {'Id' : 'rId%s' % (i + 1), + 'Type' : 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', + 'Target' : '../charts/chart%s.xml' % (chart_id + i) } + SubElement(root, 'Relationship', attrs) + return get_document_content(root) + +class ShapeWriter(object): + """ one file per shape """ + + schema = "http://schemas.openxmlformats.org/drawingml/2006/main" + + def __init__(self, shapes): + + self._shapes = shapes + + def write(self, shape_id): + + root = Element('c:userShapes', {'xmlns:c' : 'http://schemas.openxmlformats.org/drawingml/2006/chart%27%7D) + + for shape in self._shapes: + anchor = SubElement(root, 'cdr:relSizeAnchor', + {'xmlns:cdr' : "http://schemas.openxmlformats.org/drawingml/2006/chartDrawing%22%7D) + + xstart, ystart, xend, yend = shape.get_coordinates() + + _from = SubElement(anchor, 'cdr:from') + SubElement(_from, 'cdr:x').text = str(xstart) + SubElement(_from, 'cdr:y').text = str(ystart) + + _to = SubElement(anchor, 'cdr:to') + SubElement(_to, 'cdr:x').text = str(xend) + SubElement(_to, 'cdr:y').text = str(yend) + + sp = SubElement(anchor, 'cdr:sp', {'macro':'', 'textlink':''}) + nvspr = SubElement(sp, 'cdr:nvSpPr') + SubElement(nvspr, 'cdr:cNvPr', {'id':str(shape_id), 'name':'shape %s' % shape_id}) + SubElement(nvspr, 'cdr:cNvSpPr') + + sppr = SubElement(sp, 'cdr:spPr') + frm = SubElement(sppr, 'a:xfrm', {'xmlns:a':self.schema}) + # no transformation + SubElement(frm, 'a:off', {'x':'0', 'y':'0'}) + SubElement(frm, 'a:ext', {'cx':'0', 'cy':'0'}) + + prstgeom = SubElement(sppr, 'a:prstGeom', {'xmlns:a':self.schema, 'prst':str(shape.style)}) + SubElement(prstgeom, 'a:avLst') + + fill = SubElement(sppr, 'a:solidFill', {'xmlns:a':self.schema}) + SubElement(fill, 'a:srgbClr', {'val':shape.color}) + + border = SubElement(sppr, 'a:ln', {'xmlns:a':self.schema, 'w':str(shape._border_width)}) + sf = SubElement(border, 'a:solidFill') + SubElement(sf, 'a:srgbClr', {'val':shape.border_color}) + + self._write_style(sp) + self._write_text(sp, shape) + + shape_id += 1 + + return get_document_content(root) + + def _write_text(self, node, shape): + """ write text in the shape """ + + tx_body = SubElement(node, 'cdr:txBody') + SubElement(tx_body, 'a:bodyPr', {'xmlns:a':self.schema, 'vertOverflow':'clip'}) + SubElement(tx_body, 'a:lstStyle', + {'xmlns:a':self.schema}) + p = SubElement(tx_body, 'a:p', {'xmlns:a':self.schema}) + if shape.text: + r = SubElement(p, 'a:r') + rpr = SubElement(r, 'a:rPr', {'lang':'en-US'}) + fill = SubElement(rpr, 'a:solidFill') + SubElement(fill, 'a:srgbClr', {'val':shape.text_color}) + + SubElement(r, 'a:t').text = shape.text + else: + SubElement(p, 'a:endParaRPr', {'lang':'en-US'}) + + def _write_style(self, node): + """ write style theme """ + + style = SubElement(node, 'cdr:style') + + ln_ref = SubElement(style, 'a:lnRef', {'xmlns:a':self.schema, 'idx':'2'}) + scheme_clr = SubElement(ln_ref, 'a:schemeClr', {'val':'accent1'}) + SubElement(scheme_clr, 'a:shade', {'val':'50000'}) + + fill_ref = SubElement(style, 'a:fillRef', {'xmlns:a':self.schema, 'idx':'1'}) + SubElement(fill_ref, 'a:schemeClr', {'val':'accent1'}) + + effect_ref = SubElement(style, 'a:effectRef', {'xmlns:a':self.schema, 'idx':'0'}) + SubElement(effect_ref, 'a:schemeClr', {'val':'accent1'}) + + font_ref = SubElement(style, 'a:fontRef', {'xmlns:a':self.schema, 'idx':'minor'}) + SubElement(font_ref, 'a:schemeClr', {'val':'lt1'})
Property changes on: trunk/pywikipedia/openpyxl/writer/drawings.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/writer/dump_worksheet.py =================================================================== --- trunk/pywikipedia/openpyxl/writer/dump_worksheet.py (rev 0) +++ trunk/pywikipedia/openpyxl/writer/dump_worksheet.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,315 @@ +# file openpyxl/writer/straight_worksheet.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Write worksheets to xml representations in an optimized way""" + +import datetime +import os + +try: + from collections import OrderedDict +except ImportError: + from openpyxl.writer.odict import OrderedDict + +from openpyxl.cell import column_index_from_string, get_column_letter, Cell +from openpyxl.worksheet import Worksheet +from openpyxl.shared.xmltools import (XMLGenerator, get_document_content, + start_tag, end_tag, tag) +from openpyxl.shared.date_time import SharedDate +from openpyxl.shared.ooxml import MAX_COLUMN, MAX_ROW +from openpyxl.shared import NUMERIC_TYPES +from openpyxl.shared.compat import NamedTemporaryFile +from openpyxl.writer.excel import ExcelWriter +from openpyxl.writer.strings import write_string_table +from openpyxl.writer.styles import StyleWriter +from openpyxl.style import Style, NumberFormat + +from openpyxl.shared.ooxml import (ARC_SHARED_STRINGS, ARC_CONTENT_TYPES, + ARC_ROOT_RELS, ARC_WORKBOOK_RELS, ARC_APP, ARC_CORE, ARC_THEME, + ARC_STYLE, ARC_WORKBOOK, + PACKAGE_WORKSHEETS, PACKAGE_DRAWINGS, PACKAGE_CHARTS) + +STYLES = {'datetime' : {'type':Cell.TYPE_NUMERIC, + 'style':'1'}, + 'string':{'type':Cell.TYPE_STRING, + 'style':'0'}, + 'numeric':{'type':Cell.TYPE_NUMERIC, + 'style':'0'}, + 'formula':{'type':Cell.TYPE_FORMULA, + 'style':'0'}, + 'boolean':{'type':Cell.TYPE_BOOL, + 'style':'0'}, + } + +DESCRIPTORS_CACHE_SIZE = 50 +DESCRIPTORS_CACHE = OrderedDict() + +DATETIME_STYLE = Style() +DATETIME_STYLE.number_format.format_code = NumberFormat.FORMAT_DATE_YYYYMMDD2 +BOUNDING_BOX_PLACEHOLDER = 'A1:%s%d' % (get_column_letter(MAX_COLUMN), MAX_ROW) + +def create_temporary_file(suffix=''): + + fobj = NamedTemporaryFile(mode='w+', suffix=suffix, prefix='openpyxl.', delete=False) + filename = fobj.name + + return filename + +def get_temporary_file(filename): + + if filename in DESCRIPTORS_CACHE: + + fobj = DESCRIPTORS_CACHE[filename] + + # re-insert the value so it does not get evicted + # from cache soon + del DESCRIPTORS_CACHE[filename] + DESCRIPTORS_CACHE[filename] = fobj + + return fobj + else: + fobj = open(filename, 'r+') + DESCRIPTORS_CACHE[filename] = fobj + + if len(DESCRIPTORS_CACHE) > DESCRIPTORS_CACHE_SIZE: + filename, fileobj = DESCRIPTORS_CACHE.popitem(last=False) + fileobj.close() + + return fobj + +class DumpWorksheet(Worksheet): + + """ + .. warning:: + + You shouldn't initialize this yourself, use :class:`openpyxl.workbook.Workbook` constructor instead, + with `optimized_write = True`. + """ + + def __init__(self, parent_workbook): + + Worksheet.__init__(self, parent_workbook) + + self._max_col = 0 + self._max_row = 0 + self._parent = parent_workbook + + self._fileobj_header_name = create_temporary_file(suffix='.header') + self._fileobj_content_name = create_temporary_file(suffix='.content') + self._fileobj_name = create_temporary_file() + + self.title = 'Sheet' + + self._shared_date = SharedDate() + self._string_builder = self._parent.strings_table_builder + + @property + def filename(self): + return self._fileobj_name + + @property + def _temp_files(self): + + return (self._fileobj_content_name, + self._fileobj_header_name, + self._fileobj_name) + + def write_header(self): + + fobj = get_temporary_file(filename=self._fileobj_header_name) + doc = XMLGenerator(fobj, 'utf-8') + + start_tag(doc, 'worksheet', + {'xml:space': 'preserve', + 'xmlns': 'http://schemas.openxmlformats.org/spreadsheetml/2006/main', + 'xmlns:r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships%27%7D) + start_tag(doc, 'sheetPr') + tag(doc, 'outlinePr', + {'summaryBelow': '1', + 'summaryRight': '1'}) + end_tag(doc, 'sheetPr') + tag(doc, 'dimension', {'ref': 'A1:%s' % (self.get_dimensions())}) + start_tag(doc, 'sheetViews') + start_tag(doc, 'sheetView', {'workbookViewId': '0'}) + tag(doc, 'selection', {'activeCell': 'A1', + 'sqref': 'A1'}) + end_tag(doc, 'sheetView') + end_tag(doc, 'sheetViews') + tag(doc, 'sheetFormatPr', {'defaultRowHeight': '15'}) + start_tag(doc, 'sheetData') + + def close(self): + + self._close_content() + + self._fileobj = get_temporary_file(filename=self._fileobj_name) + + self._write_fileobj(self._fileobj_header_name) + self._write_fileobj(self._fileobj_content_name) + + self._fileobj.close() + + def _write_fileobj(self, fobj_name): + + fobj = get_temporary_file(filename=fobj_name) + + fobj.flush() + fobj.seek(0) + + while True: + chunk = fobj.read(4096) + if not chunk: + break + self._fileobj.write(chunk) + + fobj.close() + + self._fileobj.flush() + + def _close_content(self): + + doc = self._get_content_generator() + end_tag(doc, 'sheetData') + + end_tag(doc, 'worksheet') + + def get_dimensions(self): + + if not self._max_col or not self._max_row: + return 'A1' + else: + return '%s%d' % (get_column_letter(self._max_col), (self._max_row)) + + def _get_content_generator(self): + """ XXX: this is ugly, but it allows to resume writing the file + even after the handle is closed""" + + # when I'll recreate the XMLGenerator, it will start writing at the + # begining of the file, erasing previously entered rows, so we have + # to move to the end of the file before adding new tags + handle = get_temporary_file(filename=self._fileobj_content_name) + handle.seek(0, 2) + + doc = XMLGenerator(out=handle) + + return doc + + def append(self, row): + + """ + :param row: iterable containing values to append + :type row: iterable + """ + + doc = self._get_content_generator() + + self._max_row += 1 + span = len(row) + self._max_col = max(self._max_col, span) + + row_idx = self._max_row + + attrs = {'r': '%d' % row_idx, + 'spans': '1:%d' % span} + + start_tag(doc, 'row', attrs) + + for col_idx, cell in enumerate(row): + + if cell is None: + continue + + coordinate = '%s%d' % (get_column_letter(col_idx + 1), row_idx) + attributes = {'r': coordinate} + + if isinstance(cell, bool): + dtype = 'boolean' + elif isinstance(cell, NUMERIC_TYPES): + dtype = 'numeric' + elif isinstance(cell, (datetime.datetime, datetime.date)): + dtype = 'datetime' + cell = self._shared_date.datetime_to_julian(cell) + attributes['s'] = STYLES[dtype]['style'] + elif cell and cell[0] == '=': + dtype = 'formula' + else: + dtype = 'string' + cell = self._string_builder.add(cell) + + attributes['t'] = STYLES[dtype]['type'] + + start_tag(doc, 'c', attributes) + + if dtype == 'formula': + tag(doc, 'f', body='%s' % cell[1:]) + tag(doc, 'v') + elif dtype == 'boolean': + tag(doc, 'v', body='%d' % cell) + else: + tag(doc, 'v', body='%s' % cell) + + end_tag(doc, 'c') + + + end_tag(doc, 'row') + + +def save_dump(workbook, filename): + + writer = ExcelDumpWriter(workbook) + writer.save(filename) + return True + +class ExcelDumpWriter(ExcelWriter): + + def __init__(self, workbook): + + self.workbook = workbook + self.style_writer = StyleDumpWriter(workbook) + self.style_writer._style_list.append(DATETIME_STYLE) + + def _write_string_table(self, archive): + + shared_string_table = self.workbook.strings_table_builder.get_table() + archive.writestr(ARC_SHARED_STRINGS, + write_string_table(shared_string_table)) + + return shared_string_table + + def _write_worksheets(self, archive, shared_string_table, style_writer): + + for i, sheet in enumerate(self.workbook.worksheets): + sheet.write_header() + sheet.close() + archive.write(sheet.filename, PACKAGE_WORKSHEETS + '/sheet%d.xml' % (i + 1)) + for filename in sheet._temp_files: + os.remove(filename) + + +class StyleDumpWriter(StyleWriter): + + def _get_style_list(self, workbook): + return [] +
Property changes on: trunk/pywikipedia/openpyxl/writer/dump_worksheet.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/writer/excel.py =================================================================== --- trunk/pywikipedia/openpyxl/writer/excel.py (rev 0) +++ trunk/pywikipedia/openpyxl/writer/excel.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,156 @@ +# file openpyxl/writer/excel.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Write a .xlsx file.""" + +# Python stdlib imports +from zipfile import ZipFile, ZIP_DEFLATED +from StringIO import StringIO + +# package imports +from openpyxl.shared.ooxml import ARC_SHARED_STRINGS, ARC_CONTENT_TYPES, \ + ARC_ROOT_RELS, ARC_WORKBOOK_RELS, ARC_APP, ARC_CORE, ARC_THEME, \ + ARC_STYLE, ARC_WORKBOOK, \ + PACKAGE_WORKSHEETS, PACKAGE_DRAWINGS, PACKAGE_CHARTS +from openpyxl.writer.strings import create_string_table, write_string_table +from openpyxl.writer.workbook import write_content_types, write_root_rels, \ + write_workbook_rels, write_properties_app, write_properties_core, \ + write_workbook +from openpyxl.writer.theme import write_theme +from openpyxl.writer.styles import StyleWriter +from openpyxl.writer.drawings import DrawingWriter, ShapeWriter +from openpyxl.writer.charts import ChartWriter +from openpyxl.writer.worksheet import write_worksheet, write_worksheet_rels + + +class ExcelWriter(object): + """Write a workbook object to an Excel file.""" + + def __init__(self, workbook): + self.workbook = workbook + self.style_writer = StyleWriter(self.workbook) + + def write_data(self, archive): + """Write the various xml files into the zip archive.""" + # cleanup all worksheets + shared_string_table = self._write_string_table(archive) + + archive.writestr(ARC_CONTENT_TYPES, write_content_types(self.workbook)) + archive.writestr(ARC_ROOT_RELS, write_root_rels(self.workbook)) + archive.writestr(ARC_WORKBOOK_RELS, write_workbook_rels(self.workbook)) + archive.writestr(ARC_APP, write_properties_app(self.workbook)) + archive.writestr(ARC_CORE, + write_properties_core(self.workbook.properties)) + archive.writestr(ARC_THEME, write_theme()) + archive.writestr(ARC_STYLE, self.style_writer.write_table()) + archive.writestr(ARC_WORKBOOK, write_workbook(self.workbook)) + + self._write_worksheets(archive, shared_string_table, self.style_writer) + + def _write_string_table(self, archive): + + for ws in self.workbook.worksheets: + ws.garbage_collect() + shared_string_table = create_string_table(self.workbook) + archive.writestr(ARC_SHARED_STRINGS, + write_string_table(shared_string_table)) + + return shared_string_table + + def _write_worksheets(self, archive, shared_string_table, style_writer): + + drawing_id = 1 + chart_id = 1 + shape_id = 1 + + for i, sheet in enumerate(self.workbook.worksheets): + archive.writestr(PACKAGE_WORKSHEETS + '/sheet%d.xml' % (i + 1), + write_worksheet(sheet, shared_string_table, + style_writer.get_style_by_hash())) + if sheet._charts or sheet.relationships: + archive.writestr(PACKAGE_WORKSHEETS + + '/_rels/sheet%d.xml.rels' % (i + 1), + write_worksheet_rels(sheet, drawing_id)) + if sheet._charts: + dw = DrawingWriter(sheet) + archive.writestr(PACKAGE_DRAWINGS + '/drawing%d.xml' % drawing_id, + dw.write()) + archive.writestr(PACKAGE_DRAWINGS + '/_rels/drawing%d.xml.rels' % drawing_id, + dw.write_rels(chart_id)) + drawing_id += 1 + + for chart in sheet._charts: + cw = ChartWriter(chart) + archive.writestr(PACKAGE_CHARTS + '/chart%d.xml' % chart_id, + cw.write()) + + if chart._shapes: + archive.writestr(PACKAGE_CHARTS + '/_rels/chart%d.xml.rels' % chart_id, + cw.write_rels(drawing_id)) + sw = ShapeWriter(chart._shapes) + archive.writestr(PACKAGE_DRAWINGS + '/drawing%d.xml' % drawing_id, + sw.write(shape_id)) + shape_id += len(chart._shapes) + drawing_id += 1 + + chart_id += 1 + + + def save(self, filename): + """Write data into the archive.""" + archive = ZipFile(filename, 'w', ZIP_DEFLATED) + self.write_data(archive) + archive.close() + + +def save_workbook(workbook, filename): + """Save the given workbook on the filesystem under the name filename. + + :param workbook: the workbook to save + :type workbook: :class:`openpyxl.workbook.Workbook` + + :param filename: the path to which save the workbook + :type filename: string + + :rtype: bool + + """ + writer = ExcelWriter(workbook) + writer.save(filename) + return True + + +def save_virtual_workbook(workbook): + """Return an in-memory workbook, suitable for a Django response.""" + writer = ExcelWriter(workbook) + temp_buffer = StringIO() + try: + archive = ZipFile(temp_buffer, 'w', ZIP_DEFLATED) + writer.write_data(archive) + finally: + archive.close() + virtual_workbook = temp_buffer.getvalue() + temp_buffer.close() + return virtual_workbook
Property changes on: trunk/pywikipedia/openpyxl/writer/excel.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/writer/odict.py =================================================================== --- trunk/pywikipedia/openpyxl/writer/odict.py (rev 0) +++ trunk/pywikipedia/openpyxl/writer/odict.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,269 @@ +# Copyright (c) 2001-2011 Python Software Foundation +# 2011 Raymond Hettinger +# License: PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +# See http://www.opensource.org/licenses/Python-2.0 for full terms +# Note: backport changes by Raymond were originally distributed under MIT +# license, but since the original license for Python is more +# restrictive than MIT, code cannot be released under its terms and +# still adheres to the limitations of Python license. + +## {{{ http://code.activestate.com/recipes/576693/ (r9) +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. + +try: + from thread import get_ident as _get_ident +except ImportError: + from dummy_thread import get_ident as _get_ident + +try: + from _abcoll import KeysView, ValuesView, ItemsView +except ImportError: + pass + + +class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running={}): + 'od.__repr__() <==> repr(od)' + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self) == len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) +## end of http://code.activestate.com/recipes/576693/ }}}
Property changes on: trunk/pywikipedia/openpyxl/writer/odict.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/writer/strings.py =================================================================== --- trunk/pywikipedia/openpyxl/writer/strings.py (rev 0) +++ trunk/pywikipedia/openpyxl/writer/strings.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,86 @@ +# file openpyxl/writer/strings.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Write the shared string table.""" + +# Python stdlib imports +from StringIO import StringIO + +# package imports +from openpyxl.shared.xmltools import start_tag, end_tag, tag, XMLGenerator + + +def create_string_table(workbook): + """Compile the string table for a workbook.""" + strings = set() + for sheet in workbook.worksheets: + for cell in sheet.get_cell_collection(): + if cell.data_type == cell.TYPE_STRING and cell._value is not None: + strings.add(cell.value) + return dict((key, i) for i, key in enumerate(strings)) + + +def write_string_table(string_table): + """Write the string table xml.""" + temp_buffer = StringIO() + doc = XMLGenerator(temp_buffer, 'utf-8') + start_tag(doc, 'sst', {'xmlns': + 'http://schemas.openxmlformats.org/spreadsheetml/2006/main', + 'uniqueCount': '%d' % len(string_table)}) + strings_to_write = sorted(string_table.iteritems(), + key=lambda pair: pair[1]) + for key in [pair[0] for pair in strings_to_write]: + start_tag(doc, 'si') + if key.strip() != key: + attr = {'xml:space': 'preserve'} + else: + attr = {} + tag(doc, 't', attr, key) + end_tag(doc, 'si') + end_tag(doc, 'sst') + string_table_xml = temp_buffer.getvalue() + temp_buffer.close() + return string_table_xml + +class StringTableBuilder(object): + + def __init__(self): + + self.counter = 0 + self.dct = {} + + def add(self, key): + + key = key.strip() + try: + return self.dct[key] + except KeyError: + res = self.dct[key] = self.counter + self.counter += 1 + return res + + def get_table(self): + + return self.dct
Property changes on: trunk/pywikipedia/openpyxl/writer/strings.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/writer/styles.py =================================================================== --- trunk/pywikipedia/openpyxl/writer/styles.py (rev 0) +++ trunk/pywikipedia/openpyxl/writer/styles.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,261 @@ +# file openpyxl/writer/styles.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Write the shared style table.""" + +# package imports +from openpyxl.shared.xmltools import Element, SubElement +from openpyxl.shared.xmltools import get_document_content +from openpyxl import style + +class StyleWriter(object): + + def __init__(self, workbook): + self._style_list = self._get_style_list(workbook) + self._root = Element('styleSheet', + {'xmlns':'http://schemas.openxmlformats.org/spreadsheetml/2006/main%27%7D) + + def _get_style_list(self, workbook): + crc = {} + for worksheet in workbook.worksheets: + for style in worksheet._styles.values(): + crc[hash(style)] = style + self.style_table = dict([(style, i + 1) \ + for i, style in enumerate(crc.values())]) + sorted_styles = sorted(self.style_table.iteritems(), \ + key=lambda pair:pair[1]) + return [s[0] for s in sorted_styles] + + def get_style_by_hash(self): + return dict([(hash(style), id) \ + for style, id in self.style_table.iteritems()]) + + def write_table(self): + number_format_table = self._write_number_formats() + fonts_table = self._write_fonts() + fills_table = self._write_fills() + borders_table = self._write_borders() + self._write_cell_style_xfs() + self._write_cell_xfs(number_format_table, fonts_table, fills_table, borders_table) + self._write_cell_style() + self._write_dxfs() + self._write_table_styles() + + return get_document_content(xml_node=self._root) + + def _write_fonts(self): + """ add fonts part to root + return {font.crc => index} + """ + + fonts = SubElement(self._root, 'fonts') + + # default + font_node = SubElement(fonts, 'font') + SubElement(font_node, 'sz', {'val':'11'}) + SubElement(font_node, 'color', {'theme':'1'}) + SubElement(font_node, 'name', {'val':'Calibri'}) + SubElement(font_node, 'family', {'val':'2'}) + SubElement(font_node, 'scheme', {'val':'minor'}) + + # others + table = {} + index = 1 + for st in self._style_list: + if hash(st.font) != hash(style.DEFAULTS.font) and hash(st.font) not in table: + table[hash(st.font)] = str(index) + font_node = SubElement(fonts, 'font') + SubElement(font_node, 'sz', {'val':str(st.font.size)}) + SubElement(font_node, 'color', {'rgb':str(st.font.color.index)}) + SubElement(font_node, 'name', {'val':st.font.name}) + SubElement(font_node, 'family', {'val':'2'}) + # Don't write the 'scheme' element because it appears to prevent + # the font name from being applied in Excel. + #SubElement(font_node, 'scheme', {'val':'minor'}) + if st.font.bold: + SubElement(font_node, 'b') + if st.font.italic: + SubElement(font_node, 'i') + index += 1 + + fonts.attrib["count"] = str(index) + return table + + def _write_fills(self): + fills = SubElement(self._root, 'fills', {'count':'2'}) + fill = SubElement(fills, 'fill') + SubElement(fill, 'patternFill', {'patternType':'none'}) + fill = SubElement(fills, 'fill') + SubElement(fill, 'patternFill', {'patternType':'gray125'}) + + table = {} + index = 2 + for st in self._style_list: + if hash(st.fill) != hash(style.DEFAULTS.fill) and hash(st.fill) not in table: + table[hash(st.fill)] = str(index) + fill = SubElement(fills, 'fill') + if hash(st.fill.fill_type) != hash(style.DEFAULTS.fill.fill_type): + node = SubElement(fill, 'patternFill', {'patternType':st.fill.fill_type}) + if hash(st.fill.start_color) != hash(style.DEFAULTS.fill.start_color): + + SubElement(node, 'fgColor', {'rgb':str(st.fill.start_color.index)}) + if hash(st.fill.end_color) != hash(style.DEFAULTS.fill.end_color): + SubElement(node, 'bgColor', {'rgb':str(st.fill.start_color.index)}) + index += 1 + + fills.attrib["count"] = str(index) + return table + + def _write_borders(self): + borders = SubElement(self._root, 'borders') + + # default + border = SubElement(borders, 'border') + SubElement(border, 'left') + SubElement(border, 'right') + SubElement(border, 'top') + SubElement(border, 'bottom') + SubElement(border, 'diagonal') + + # others + table = {} + index = 1 + for st in self._style_list: + if hash(st.borders) != hash(style.DEFAULTS.borders) and hash(st.borders) not in table: + table[hash(st.borders)] = str(index) + border = SubElement(borders, 'border') + # caution: respect this order + for side in ('left', 'right', 'top', 'bottom', 'diagonal'): + obj = getattr(st.borders, side) + node = SubElement(border, side, {'style':obj.border_style}) + SubElement(node, 'color', {'rgb':str(obj.color.index)}) + index += 1 + + borders.attrib["count"] = str(index) + return table + + def _write_cell_style_xfs(self): + cell_style_xfs = SubElement(self._root, 'cellStyleXfs', {'count':'1'}) + xf = SubElement(cell_style_xfs, 'xf', + {'numFmtId':"0", 'fontId':"0", 'fillId':"0", 'borderId':"0"}) + + def _write_cell_xfs(self, number_format_table, fonts_table, fills_table, borders_table): + """ write styles combinations based on ids found in tables """ + + # writing the cellXfs + cell_xfs = SubElement(self._root, 'cellXfs', + {'count':'%d' % (len(self._style_list) + 1)}) + + # default + def _get_default_vals(): + return dict(numFmtId='0', fontId='0', fillId='0', + xfId='0', borderId='0') + + SubElement(cell_xfs, 'xf', _get_default_vals()) + + for st in self._style_list: + vals = _get_default_vals() + + if hash(st.font) != hash(style.DEFAULTS.font): + vals['fontId'] = fonts_table[hash(st.font)] + vals['applyFont'] = '1' + + if hash(st.borders) != hash(style.DEFAULTS.borders): + vals['borderId'] = borders_table[hash(st.borders)] + vals['applyBorder'] = '1' + + if hash(st.fill) != hash(style.DEFAULTS.fill): + vals['fillId'] = fills_table[hash(st.fill)] + vals['applyFillId'] = '1' + + if st.number_format != style.DEFAULTS.number_format: + vals['numFmtId'] = '%d' % number_format_table[st.number_format] + vals['applyNumberFormat'] = '1' + + if hash(st.alignment) != hash(style.DEFAULTS.alignment): + vals['applyAlignment'] = '1' + + node = SubElement(cell_xfs, 'xf', vals) + + if hash(st.alignment) != hash(style.DEFAULTS.alignment): + alignments = {} + + for align_attr in ['horizontal', 'vertical']: + if hash(getattr(st.alignment, align_attr)) != hash(getattr(style.DEFAULTS.alignment, align_attr)): + alignments[align_attr] = getattr(st.alignment, align_attr) + + if hash(st.alignment.wrap_text) != hash(style.DEFAULTS.alignment.wrap_text): + alignments['wrapText'] = '1' + + SubElement(node, 'alignment', alignments) + + + def _write_cell_style(self): + cell_styles = SubElement(self._root, 'cellStyles', {'count':'1'}) + cell_style = SubElement(cell_styles, 'cellStyle', + {'name':"Normal", 'xfId':"0", 'builtinId':"0"}) + + def _write_dxfs(self): + dxfs = SubElement(self._root, 'dxfs', {'count':'0'}) + + def _write_table_styles(self): + + table_styles = SubElement(self._root, 'tableStyles', + {'count':'0', 'defaultTableStyle':'TableStyleMedium9', + 'defaultPivotStyle':'PivotStyleLight16'}) + + def _write_number_formats(self): + + number_format_table = {} + + number_format_list = [] + exceptions_list = [] + num_fmt_id = 165 # start at a greatly higher value as any builtin can go + num_fmt_offset = 0 + + for style in self._style_list: + + if not style.number_format in number_format_list : + number_format_list.append(style.number_format) + + for number_format in number_format_list: + + if number_format.is_builtin(): + btin = number_format.builtin_format_id(number_format.format_code) + number_format_table[number_format] = btin + else: + number_format_table[number_format] = num_fmt_id + num_fmt_offset + num_fmt_offset += 1 + exceptions_list.append(number_format) + + num_fmts = SubElement(self._root, 'numFmts', + {'count':'%d' % len(exceptions_list)}) + + for number_format in exceptions_list : + SubElement(num_fmts, 'numFmt', + {'numFmtId':'%d' % number_format_table[number_format], + 'formatCode':'%s' % number_format.format_code}) + + return number_format_table
Property changes on: trunk/pywikipedia/openpyxl/writer/styles.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/writer/theme.py =================================================================== --- trunk/pywikipedia/openpyxl/writer/theme.py (rev 0) +++ trunk/pywikipedia/openpyxl/writer/theme.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,202 @@ +# -*- coding: utf-8 -*- +# file openpyxl/writer/theme.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Write the theme xml based on a fixed string.""" + +# package imports +from openpyxl.shared.xmltools import fromstring, get_document_content + + +def write_theme(): + """Write the theme xml.""" + xml_node = fromstring( + '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' + + '<a:theme xmlns:a="http://schemas.openxmlformats.org/' + 'drawingml/2006/main" name="Office Theme">' + '<a:themeElements>' + + '<a:clrScheme name="Office">' + '<a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1>' + '<a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1>' + '<a:dk2><a:srgbClr val="1F497D"/></a:dk2>' + '<a:lt2><a:srgbClr val="EEECE1"/></a:lt2>' + '<a:accent1><a:srgbClr val="4F81BD"/></a:accent1>' + '<a:accent2><a:srgbClr val="C0504D"/></a:accent2>' + '<a:accent3><a:srgbClr val="9BBB59"/></a:accent3>' + '<a:accent4><a:srgbClr val="8064A2"/></a:accent4>' + '<a:accent5><a:srgbClr val="4BACC6"/></a:accent5>' + '<a:accent6><a:srgbClr val="F79646"/></a:accent6>' + '<a:hlink><a:srgbClr val="0000FF"/></a:hlink>' + '<a:folHlink><a:srgbClr val="800080"/></a:folHlink>' + '</a:clrScheme>' + + '<a:fontScheme name="Office">' + '<a:majorFont>' + '<a:latin typeface="Cambria"/>' + '<a:ea typeface=""/>' + '<a:cs typeface=""/>' + '<a:font script="Jpan" typeface="MS Pゴシック"/>' + '<a:font script="Hang" typeface="맑은 고딕"/>' + '<a:font script="Hans" typeface="宋体"/>' + '<a:font script="Hant" typeface="新細明體"/>' + '<a:font script="Arab" typeface="Times New Roman"/>' + '<a:font script="Hebr" typeface="Times New Roman"/>' + '<a:font script="Thai" typeface="Tahoma"/>' + '<a:font script="Ethi" typeface="Nyala"/>' + '<a:font script="Beng" typeface="Vrinda"/>' + '<a:font script="Gujr" typeface="Shruti"/>' + '<a:font script="Khmr" typeface="MoolBoran"/>' + '<a:font script="Knda" typeface="Tunga"/>' + '<a:font script="Guru" typeface="Raavi"/>' + '<a:font script="Cans" typeface="Euphemia"/>' + '<a:font script="Cher" typeface="Plantagenet Cherokee"/>' + '<a:font script="Yiii" typeface="Microsoft Yi Baiti"/>' + '<a:font script="Tibt" typeface="Microsoft Himalaya"/>' + '<a:font script="Thaa" typeface="MV Boli"/>' + '<a:font script="Deva" typeface="Mangal"/>' + '<a:font script="Telu" typeface="Gautami"/>' + '<a:font script="Taml" typeface="Latha"/>' + '<a:font script="Syrc" typeface="Estrangelo Edessa"/>' + '<a:font script="Orya" typeface="Kalinga"/>' + '<a:font script="Mlym" typeface="Kartika"/>' + '<a:font script="Laoo" typeface="DokChampa"/>' + '<a:font script="Sinh" typeface="Iskoola Pota"/>' + '<a:font script="Mong" typeface="Mongolian Baiti"/>' + '<a:font script="Viet" typeface="Times New Roman"/>' + '<a:font script="Uigh" typeface="Microsoft Uighur"/>' + '</a:majorFont>' + '<a:minorFont>' + '<a:latin typeface="Calibri"/>' + '<a:ea typeface=""/>' + '<a:cs typeface=""/>' + '<a:font script="Jpan" typeface="MS Pゴシック"/>' + '<a:font script="Hang" typeface="맑은 고딕"/>' + '<a:font script="Hans" typeface="宋体"/>' + '<a:font script="Hant" typeface="新細明體"/>' + '<a:font script="Arab" typeface="Arial"/>' + '<a:font script="Hebr" typeface="Arial"/>' + '<a:font script="Thai" typeface="Tahoma"/>' + '<a:font script="Ethi" typeface="Nyala"/>' + '<a:font script="Beng" typeface="Vrinda"/>' + '<a:font script="Gujr" typeface="Shruti"/>' + '<a:font script="Khmr" typeface="DaunPenh"/>' + '<a:font script="Knda" typeface="Tunga"/>' + '<a:font script="Guru" typeface="Raavi"/>' + '<a:font script="Cans" typeface="Euphemia"/>' + '<a:font script="Cher" typeface="Plantagenet Cherokee"/>' + '<a:font script="Yiii" typeface="Microsoft Yi Baiti"/>' + '<a:font script="Tibt" typeface="Microsoft Himalaya"/>' + '<a:font script="Thaa" typeface="MV Boli"/>' + '<a:font script="Deva" typeface="Mangal"/>' + '<a:font script="Telu" typeface="Gautami"/>' + '<a:font script="Taml" typeface="Latha"/>' + '<a:font script="Syrc" typeface="Estrangelo Edessa"/>' + '<a:font script="Orya" typeface="Kalinga"/>' + '<a:font script="Mlym" typeface="Kartika"/>' + '<a:font script="Laoo" typeface="DokChampa"/>' + '<a:font script="Sinh" typeface="Iskoola Pota"/>' + '<a:font script="Mong" typeface="Mongolian Baiti"/>' + '<a:font script="Viet" typeface="Arial"/>' + '<a:font script="Uigh" typeface="Microsoft Uighur"/>' + '</a:minorFont>' + '</a:fontScheme>' + + '<a:fmtScheme name="Office">' + '<a:fillStyleLst>' + '<a:solidFill><a:schemeClr val="phClr"/></a:solidFill>' + '<a:gradFill rotWithShape="1"><a:gsLst>' + '<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="50000"/>' + '<a:satMod val="300000"/></a:schemeClr></a:gs>' + '<a:gs pos="35000"><a:schemeClr val="phClr"><a:tint val="37000"/>' + '<a:satMod val="300000"/></a:schemeClr></a:gs>' + '<a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="15000"/>' + '<a:satMod val="350000"/></a:schemeClr></a:gs></a:gsLst>' + '<a:lin ang="16200000" scaled="1"/></a:gradFill>' + '<a:gradFill rotWithShape="1"><a:gsLst>' + '<a:gs pos="0"><a:schemeClr val="phClr"><a:shade val="51000"/>' + '<a:satMod val="130000"/></a:schemeClr></a:gs>' + '<a:gs pos="80000"><a:schemeClr val="phClr"><a:shade val="93000"/>' + '<a:satMod val="130000"/></a:schemeClr></a:gs>' + '<a:gs pos="100000"><a:schemeClr val="phClr">' + '<a:shade val="94000"/>' + '<a:satMod val="135000"/></a:schemeClr></a:gs></a:gsLst>' + '<a:lin ang="16200000" scaled="0"/></a:gradFill></a:fillStyleLst>' + '<a:lnStyleLst>' + '<a:ln w="9525" cap="flat" cmpd="sng" algn="ctr">' + '<a:solidFill><a:schemeClr val="phClr"><a:shade val="95000"/>' + '<a:satMod val="105000"/></a:schemeClr></a:solidFill>' + '<a:prstDash val="solid"/></a:ln>' + '<a:ln w="25400" cap="flat" cmpd="sng" algn="ctr"><a:solidFill>' + '<a:schemeClr val="phClr"/></a:solidFill>' + '<a:prstDash val="solid"/></a:ln>' + '<a:ln w="38100" cap="flat" cmpd="sng" algn="ctr"><a:solidFill>' + '<a:schemeClr val="phClr"/></a:solidFill>' + '<a:prstDash val="solid"/></a:ln></a:lnStyleLst>' + '<a:effectStyleLst><a:effectStyle><a:effectLst>' + '<a:outerShdw blurRad="40000" dist="20000" dir="5400000" ' + 'rotWithShape="0"><a:srgbClr val="000000">' + '<a:alpha val="38000"/></a:srgbClr></a:outerShdw></a:effectLst>' + '</a:effectStyle><a:effectStyle><a:effectLst>' + '<a:outerShdw blurRad="40000" dist="23000" dir="5400000" ' + 'rotWithShape="0"><a:srgbClr val="000000">' + '<a:alpha val="35000"/></a:srgbClr></a:outerShdw></a:effectLst>' + '</a:effectStyle><a:effectStyle><a:effectLst>' + '<a:outerShdw blurRad="40000" dist="23000" dir="5400000" ' + 'rotWithShape="0"><a:srgbClr val="000000">' + '<a:alpha val="35000"/></a:srgbClr></a:outerShdw></a:effectLst>' + '<a:scene3d><a:camera prst="orthographicFront">' + '<a:rot lat="0" lon="0" rev="0"/></a:camera>' + '<a:lightRig rig="threePt" dir="t">' + '<a:rot lat="0" lon="0" rev="1200000"/></a:lightRig>' + '</a:scene3d><a:sp3d><a:bevelT w="63500" h="25400"/>' + '</a:sp3d></a:effectStyle></a:effectStyleLst>' + '<a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/>' + '</a:solidFill><a:gradFill rotWithShape="1"><a:gsLst>' + '<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="40000"/>' + '<a:satMod val="350000"/></a:schemeClr></a:gs>' + '<a:gs pos="40000"><a:schemeClr val="phClr"><a:tint val="45000"/>' + '<a:shade val="99000"/><a:satMod val="350000"/>' + '</a:schemeClr></a:gs>' + '<a:gs pos="100000"><a:schemeClr val="phClr">' + '<a:shade val="20000"/><a:satMod val="255000"/>' + '</a:schemeClr></a:gs></a:gsLst>' + '<a:path path="circle">' + '<a:fillToRect l="50000" t="-80000" r="50000" b="180000"/>' + '</a:path>' + '</a:gradFill><a:gradFill rotWithShape="1"><a:gsLst>' + '<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="80000"/>' + '<a:satMod val="300000"/></a:schemeClr></a:gs>' + '<a:gs pos="100000"><a:schemeClr val="phClr">' + '<a:shade val="30000"/><a:satMod val="200000"/>' + '</a:schemeClr></a:gs></a:gsLst>' + '<a:path path="circle">' + '<a:fillToRect l="50000" t="50000" r="50000" b="50000"/></a:path>' + '</a:gradFill></a:bgFillStyleLst></a:fmtScheme>' + '</a:themeElements>' + '<a:objectDefaults/><a:extraClrSchemeLst/>' + '</a:theme>') + return get_document_content(xml_node)
Property changes on: trunk/pywikipedia/openpyxl/writer/theme.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/writer/workbook.py =================================================================== --- trunk/pywikipedia/openpyxl/writer/workbook.py (rev 0) +++ trunk/pywikipedia/openpyxl/writer/workbook.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,219 @@ +# file openpyxl/writer/workbook.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Write the workbook global settings to the archive.""" + +# package imports +from openpyxl.shared.xmltools import Element, SubElement +from openpyxl.cell import absolute_coordinate +from openpyxl.shared.xmltools import get_document_content +from openpyxl.shared.ooxml import NAMESPACES, ARC_CORE, ARC_WORKBOOK, \ + ARC_APP, ARC_THEME, ARC_STYLE, ARC_SHARED_STRINGS +from openpyxl.shared.date_time import datetime_to_W3CDTF +from openpyxl.namedrange import NamedRange, NamedRangeContainingValue + + +def write_properties_core(properties): + """Write the core properties to xml.""" + root = Element('cp:coreProperties', {'xmlns:cp': NAMESPACES['cp'], + 'xmlns:xsi': NAMESPACES['xsi'], 'xmlns:dc': NAMESPACES['dc'], + 'xmlns:dcterms': NAMESPACES['dcterms'], + 'xmlns:dcmitype': NAMESPACES['dcmitype'], }) + SubElement(root, 'dc:creator').text = properties.creator + SubElement(root, 'cp:lastModifiedBy').text = properties.last_modified_by + SubElement(root, 'dcterms:created', \ + {'xsi:type': 'dcterms:W3CDTF'}).text = \ + datetime_to_W3CDTF(properties.created) + SubElement(root, 'dcterms:modified', + {'xsi:type': 'dcterms:W3CDTF'}).text = \ + datetime_to_W3CDTF(properties.modified) + return get_document_content(root) + + +def write_content_types(workbook): + """Write the content-types xml.""" + root = Element('Types', {'xmlns': 'http://schemas.openxmlformats.org/package/2006/content-types%27%7D) + SubElement(root, 'Override', {'PartName': '/' + ARC_THEME, 'ContentType': 'application/vnd.openxmlformats-officedocument.theme+xml'}) + SubElement(root, 'Override', {'PartName': '/' + ARC_STYLE, 'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'}) + SubElement(root, 'Default', {'Extension': 'rels', 'ContentType': 'application/vnd.openxmlformats-package.relationships+xml'}) + SubElement(root, 'Default', {'Extension': 'xml', 'ContentType': 'application/xml'}) + SubElement(root, 'Override', {'PartName': '/' + ARC_WORKBOOK, 'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml'}) + SubElement(root, 'Override', {'PartName': '/' + ARC_APP, 'ContentType': 'application/vnd.openxmlformats-officedocument.extended-properties+xml'}) + SubElement(root, 'Override', {'PartName': '/' + ARC_CORE, 'ContentType': 'application/vnd.openxmlformats-package.core-properties+xml'}) + SubElement(root, 'Override', {'PartName': '/' + ARC_SHARED_STRINGS, 'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml'}) + + drawing_id = 1 + chart_id = 1 + + for sheet_id, sheet in enumerate(workbook.worksheets): + SubElement(root, 'Override', + {'PartName': '/xl/worksheets/sheet%d.xml' % (sheet_id + 1), + 'ContentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'}) + if sheet._charts: + SubElement(root, 'Override', + {'PartName' : '/xl/drawings/drawing%d.xml' % drawing_id, + 'ContentType' : 'application/vnd.openxmlformats-officedocument.drawing+xml'}) + drawing_id += 1 + + for chart in sheet._charts: + SubElement(root, 'Override', + {'PartName' : '/xl/charts/chart%d.xml' % chart_id, + 'ContentType' : 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'}) + chart_id += 1 + if chart._shapes: + SubElement(root, 'Override', + {'PartName' : '/xl/drawings/drawing%d.xml' % drawing_id, + 'ContentType' : 'application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml'}) + drawing_id += 1 + + return get_document_content(root) + + +def write_properties_app(workbook): + """Write the properties xml.""" + worksheets_count = len(workbook.worksheets) + root = Element('Properties', {'xmlns': 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties', + 'xmlns:vt': 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes%27%7D) + SubElement(root, 'Application').text = 'Microsoft Excel' + SubElement(root, 'DocSecurity').text = '0' + SubElement(root, 'ScaleCrop').text = 'false' + SubElement(root, 'Company') + SubElement(root, 'LinksUpToDate').text = 'false' + SubElement(root, 'SharedDoc').text = 'false' + SubElement(root, 'HyperlinksChanged').text = 'false' + SubElement(root, 'AppVersion').text = '12.0000' + + # heading pairs part + heading_pairs = SubElement(root, 'HeadingPairs') + vector = SubElement(heading_pairs, 'vt:vector', + {'size': '2', 'baseType': 'variant'}) + variant = SubElement(vector, 'vt:variant') + SubElement(variant, 'vt:lpstr').text = 'Worksheets' + variant = SubElement(vector, 'vt:variant') + SubElement(variant, 'vt:i4').text = '%d' % worksheets_count + + # title of parts + title_of_parts = SubElement(root, 'TitlesOfParts') + vector = SubElement(title_of_parts, 'vt:vector', + {'size': '%d' % worksheets_count, 'baseType': 'lpstr'}) + for ws in workbook.worksheets: + SubElement(vector, 'vt:lpstr').text = '%s' % ws.title + return get_document_content(root) + + +def write_root_rels(workbook): + """Write the relationships xml.""" + root = Element('Relationships', {'xmlns': + 'http://schemas.openxmlformats.org/package/2006/relationships%27%7D) + SubElement(root, 'Relationship', {'Id': 'rId1', 'Target': ARC_WORKBOOK, + 'Type': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDo...) + SubElement(root, 'Relationship', {'Id': 'rId2', 'Target': ARC_CORE, + 'Type': 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-p...) + SubElement(root, 'Relationship', {'Id': 'rId3', 'Target': ARC_APP, + 'Type': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended...) + return get_document_content(root) + + +def write_workbook(workbook): + """Write the core workbook xml.""" + root = Element('workbook', {'xmlns': 'http://schemas.openxmlformats.org/spreadsheetml/2006/main', + 'xml:space': 'preserve', 'xmlns:r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships%27%7D) + SubElement(root, 'fileVersion', {'appName': 'xl', 'lastEdited': '4', + 'lowestEdited': '4', 'rupBuild': '4505'}) + SubElement(root, 'workbookPr', {'defaultThemeVersion': '124226', + 'codeName': 'ThisWorkbook'}) + book_views = SubElement(root, 'bookViews') + SubElement(book_views, 'workbookView', {'activeTab': '%d' % workbook.get_index(workbook.get_active_sheet()), + 'autoFilterDateGrouping': '1', 'firstSheet': '0', 'minimized': '0', + 'showHorizontalScroll': '1', 'showSheetTabs': '1', + 'showVerticalScroll': '1', 'tabRatio': '600', + 'visibility': 'visible'}) + # worksheets + sheets = SubElement(root, 'sheets') + for i, sheet in enumerate(workbook.worksheets): + sheet_node = SubElement(sheets, 'sheet', {'name': sheet.title, + 'sheetId': '%d' % (i + 1), 'r:id': 'rId%d' % (i + 1)}) + if not sheet.sheet_state == sheet.SHEETSTATE_VISIBLE: + sheet_node.set('state', sheet.sheet_state) + + # Defined names + defined_names = SubElement(root, 'definedNames') + # named ranges + for named_range in workbook.get_named_ranges(): + name = SubElement(defined_names, 'definedName', + {'name': named_range.name}) + if named_range.scope: + name.set('localSheetId', '%s' % workbook.get_index(named_range.scope)) + + if isinstance(named_range, NamedRange): + # as there can be many cells in one range, generate the list of ranges + dest_cells = [] + for worksheet, range_name in named_range.destinations: + dest_cells.append("'%s'!%s" % (worksheet.title.replace("'", "''"), + absolute_coordinate(range_name))) + + # finally write the cells list + name.text = ','.join(dest_cells) + else: + assert isinstance(named_range, NamedRangeContainingValue) + name.text = named_range.value + + # autoFilter + for i, sheet in enumerate(workbook.worksheets): + #continue + auto_filter = sheet.auto_filter + if not auto_filter: + continue + name = SubElement(defined_names, 'definedName', + dict(name='_xlnm._FilterDatabase', + localSheetId=str(i), + hidden='1')) + name.text = "'%s'!%s" % (sheet.title.replace("'", "''"), + absolute_coordinate(auto_filter)) + + SubElement(root, 'calcPr', {'calcId': '124519', 'calcMode': 'auto', + 'fullCalcOnLoad': '1'}) + return get_document_content(root) + + +def write_workbook_rels(workbook): + """Write the workbook relationships xml.""" + root = Element('Relationships', {'xmlns': + 'http://schemas.openxmlformats.org/package/2006/relationships%27%7D) + for i in range(len(workbook.worksheets)): + SubElement(root, 'Relationship', {'Id': 'rId%d' % (i + 1), + 'Type': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/workshee...', + 'Target': 'worksheets/sheet%s.xml' % (i + 1)}) + rid = len(workbook.worksheets) + 1 + SubElement(root, 'Relationship', + {'Id': 'rId%d' % rid, 'Target': 'sharedStrings.xml', + 'Type': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedSt...) + SubElement(root, 'Relationship', + {'Id': 'rId%d' % (rid + 1), 'Target': 'styles.xml', + 'Type': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles%2...) + SubElement(root, 'Relationship', + {'Id': 'rId%d' % (rid + 2), 'Target': 'theme/theme1.xml', + 'Type': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme%27...) + return get_document_content(root)
Property changes on: trunk/pywikipedia/openpyxl/writer/workbook.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/openpyxl/writer/worksheet.py =================================================================== --- trunk/pywikipedia/openpyxl/writer/worksheet.py (rev 0) +++ trunk/pywikipedia/openpyxl/writer/worksheet.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,215 @@ +# file openpyxl/writer/worksheet.py + +# Copyright (c) 2010-2011 openpyxl +# +# 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. +# +# @license: http://www.opensource.org/licenses/mit-license.php +# @author: see AUTHORS file + +"""Write worksheets to xml representations.""" + +# Python stdlib imports +from StringIO import StringIO # cStringIO doesn't handle unicode + +# package imports +from openpyxl.cell import coordinate_from_string, column_index_from_string +from openpyxl.shared.xmltools import Element, SubElement, XMLGenerator, \ + get_document_content, start_tag, end_tag, tag + + +def row_sort(cell): + """Translate column names for sorting.""" + return column_index_from_string(cell.column) + + +def write_worksheet(worksheet, string_table, style_table): + """Write a worksheet to an xml file.""" + xml_file = StringIO() + doc = XMLGenerator(xml_file, 'utf-8') + start_tag(doc, 'worksheet', + {'xml:space': 'preserve', + 'xmlns': 'http://schemas.openxmlformats.org/spreadsheetml/2006/main', + 'xmlns:r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships%27%7D) + start_tag(doc, 'sheetPr') + tag(doc, 'outlinePr', + {'summaryBelow': '%d' % (worksheet.show_summary_below), + 'summaryRight': '%d' % (worksheet.show_summary_right)}) + end_tag(doc, 'sheetPr') + tag(doc, 'dimension', {'ref': '%s' % worksheet.calculate_dimension()}) + write_worksheet_sheetviews(doc, worksheet) + tag(doc, 'sheetFormatPr', {'defaultRowHeight': '15'}) + write_worksheet_cols(doc, worksheet) + write_worksheet_data(doc, worksheet, string_table, style_table) + if worksheet.auto_filter: + tag(doc, 'autoFilter', {'ref': worksheet.auto_filter}) + write_worksheet_hyperlinks(doc, worksheet) + if worksheet._charts: + tag(doc, 'drawing', {'r:id':'rId1'}) + end_tag(doc, 'worksheet') + doc.endDocument() + xml_string = xml_file.getvalue() + xml_file.close() + return xml_string + +def write_worksheet_sheetviews(doc, worksheet): + start_tag(doc, 'sheetViews') + start_tag(doc, 'sheetView', {'workbookViewId': '0'}) + selectionAttrs = {} + topLeftCell = worksheet.freeze_panes + if topLeftCell: + colName, row = coordinate_from_string(topLeftCell) + column = column_index_from_string(colName) + pane = 'topRight' + paneAttrs = {} + if column > 1: + paneAttrs['xSplit'] = str(column - 1) + if row > 1: + paneAttrs['ySplit'] = str(row - 1) + pane = 'bottomLeft' + if column > 1: + pane = 'bottomRight' + paneAttrs.update(dict(topLeftCell=topLeftCell, + activePane=pane, + state='frozen')) + tag(doc, 'pane', paneAttrs) + selectionAttrs['pane'] = pane + if row > 1 and column > 1: + tag(doc, 'selection', {'pane': 'topRight'}) + tag(doc, 'selection', {'pane': 'bottomLeft'}) + + selectionAttrs.update({'activeCell': worksheet.active_cell, + 'sqref': worksheet.selected_cell}) + + tag(doc, 'selection', selectionAttrs) + end_tag(doc, 'sheetView') + end_tag(doc, 'sheetViews') + + +def write_worksheet_cols(doc, worksheet): + """Write worksheet columns to xml.""" + if worksheet.column_dimensions: + start_tag(doc, 'cols') + for column_string, columndimension in \ + worksheet.column_dimensions.iteritems(): + col_index = column_index_from_string(column_string) + col_def = {} + col_def['collapsed'] = str(columndimension.style_index) + col_def['min'] = str(col_index) + col_def['max'] = str(col_index) + if columndimension.width != \ + worksheet.default_column_dimension.width: + col_def['customWidth'] = 'true' + if not columndimension.visible: + col_def['hidden'] = 'true' + if columndimension.outline_level > 0: + col_def['outlineLevel'] = str(columndimension.outline_level) + if columndimension.collapsed: + col_def['collapsed'] = 'true' + if columndimension.auto_size: + col_def['bestFit'] = 'true' + if columndimension.width > 0: + col_def['width'] = str(columndimension.width) + else: + col_def['width'] = '9.10' + tag(doc, 'col', col_def) + end_tag(doc, 'cols') + + +def write_worksheet_data(doc, worksheet, string_table, style_table): + """Write worksheet data to xml.""" + start_tag(doc, 'sheetData') + max_column = worksheet.get_highest_column() + style_id_by_hash = style_table + cells_by_row = {} + for cell in worksheet.get_cell_collection(): + cells_by_row.setdefault(cell.row, []).append(cell) + for row_idx in sorted(cells_by_row): + row_dimension = worksheet.row_dimensions[row_idx] + attrs = {'r': '%d' % row_idx, + 'spans': '1:%d' % max_column} + if row_dimension.height > 0: + attrs['ht'] = str(row_dimension.height) + attrs['customHeight'] = '1' + start_tag(doc, 'row', attrs) + row_cells = cells_by_row[row_idx] + sorted_cells = sorted(row_cells, key = row_sort) + for cell in sorted_cells: + value = cell._value + coordinate = cell.get_coordinate() + attributes = {'r': coordinate} + attributes['t'] = cell.data_type + if coordinate in worksheet._styles: + attributes['s'] = '%d' % style_id_by_hash[ + hash(worksheet._styles[coordinate])] + start_tag(doc, 'c', attributes) + if value is None: + tag(doc, 'v', body='') + elif cell.data_type == cell.TYPE_STRING: + tag(doc, 'v', body = '%s' % string_table[value]) + elif cell.data_type == cell.TYPE_FORMULA: + tag(doc, 'f', body = '%s' % value[1:]) + tag(doc, 'v') + elif cell.data_type == cell.TYPE_NUMERIC: + if isinstance(value, long): + func=str + else: + func=repr + tag(doc, 'v', body = func(value)) + elif cell.data_type == cell.TYPE_BOOL: + tag(doc, 'v', body = '%d' % value) + else: + tag(doc, 'v', body = '%s' % value) + end_tag(doc, 'c') + end_tag(doc, 'row') + end_tag(doc, 'sheetData') + + +def write_worksheet_hyperlinks(doc, worksheet): + """Write worksheet hyperlinks to xml.""" + write_hyperlinks = False + for cell in worksheet.get_cell_collection(): + if cell.hyperlink_rel_id is not None: + write_hyperlinks = True + break + if write_hyperlinks: + start_tag(doc, 'hyperlinks') + for cell in worksheet.get_cell_collection(): + if cell.hyperlink_rel_id is not None: + attrs = {'display': cell.hyperlink, + 'ref': cell.get_coordinate(), + 'r:id': cell.hyperlink_rel_id} + tag(doc, 'hyperlink', attrs) + end_tag(doc, 'hyperlinks') + + +def write_worksheet_rels(worksheet, idx): + """Write relationships for the worksheet to xml.""" + root = Element('Relationships', {'xmlns': 'http://schemas.openxmlformats.org/package/2006/relationships%27%7D) + for rel in worksheet.relationships: + attrs = {'Id': rel.id, 'Type': rel.type, 'Target': rel.target} + if rel.target_mode: + attrs['TargetMode'] = rel.target_mode + SubElement(root, 'Relationship', attrs) + if worksheet._charts: + attrs = {'Id' : 'rId1', + 'Type' : 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', + 'Target' : '../drawings/drawing%s.xml' % idx } + SubElement(root, 'Relationship', attrs) + return get_document_content(root)
Property changes on: trunk/pywikipedia/openpyxl/writer/worksheet.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/subster.py =================================================================== --- trunk/pywikipedia/subster.py (rev 0) +++ trunk/pywikipedia/subster.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,646 @@ +# -*- coding: utf-8 -*- +""" +Robot which will does substitutions of tags within wiki page content with external or +other wiki text data. Like dynamic text updating. + +Look at http://de.wikipedia.org/wiki/Benutzer:DrTrigon/Benutzer:DrTrigonBot/config.c... +for 'postproc' example code. + +Look at https://wiki.toolserver.org/view/Mail how to setup mail handling. The +following code was used in file '$HOME/.forward+subster': +--- --- --- --- --- --- --- --- --- --- +> ~/data/subster/mail_inbox +--- --- --- --- --- --- --- --- --- --- +in order to enable mail (mbox style) storage in given file for address: +drtrigon+subster@toolserver.org + +Other scripts and tools related to this bot are: +- subster_irc.py IRC Robot +- substersim.py Subster simulation panel +- subster_mail_queue.py Subster mail queue +""" +## @package subster +# @brief Dynamic Text Substitutions Robot +# +# @copyright Dr. Trigon, 2009-2012 +# +# @section FRAMEWORK +# +# Python wikipedia robot framework, DrTrigonBot. +# @see http://pywikipediabot.sourceforge.net/ +# @see http://de.wikipedia.org/wiki/Benutzer:DrTrigonBot +# +# External code / other modules used are listed here. +# @see https://bitbucket.org/ericgazoni/openpyxl/wiki/Home +# @see http://pypi.python.org/pypi/crontab/.11 +# +# @section LICENSE +# +# Distributed under the terms of the MIT license. +# @see http://de.wikipedia.org/wiki/MIT-Lizenz +# +__version__ = '$Id: subster.py 418 2012-10-19 17:41:45Z drtrigon $' +# + + +import re, sys, os, string, time +import difflib +import BeautifulSoup +import StringIO, zipfile, csv, urllib +import mailbox, mimetypes, datetime, email.utils +import openpyxl.reader.excel +import crontab +import logging +import copy +import ast + +import pagegenerators, basic +import dtbext +# Splitting the bot into library parts +import wikipedia as pywikibot +from pywikibot import i18n +from pywikibot.comms import http + + +bot_config = { # unicode values + 'TemplateName': u'User:DrTrigonBot/Subster', # or 'template' for 'Flagged Revisions' + 'ErrorTemplate': u'----\n<b>SubsterBot Exception in "%s" (%s)</b>\n%s', + + # important to use a '.css' page here, since it HAS TO BE protected to + # prevent malicious code injection ! + 'ConfCSSpostproc': u'User:DrTrigon/DrTrigonBot/subster-postproc.css', + 'ConfCSSconfig': u'User:DrTrigon/DrTrigonBot/subster-config.css', + + 'CodeTemplate': u'\n%s(DATA, *args)\n', + 'CRONMaxDelay': 1*24*60*60, # bot runs daily + + # regex values + 'var_regex_str': u'<!--SUBSTER-%(var1)s-->%(cont)s<!--SUBSTER-%(var2)s-->', + + 'mbox_file': 'mail_inbox', # "drtrigon+subster@toolserver.org" + 'data_path': '../data/subster', + + # bot paramater/options + 'param_default': { + 'url': '', + 'regex': '', + 'value': '', + 'count': '0', + #'postproc': '("","")', + 'postproc': '('', '')', + 'wiki': 'False', # may be change to url='wiki://' + 'magicwords_only': 'False', + 'beautifulsoup': 'False', # DRTRIGON-88 + 'expandtemplates': 'False', # DRTRIGON-93 (only with 'wiki') + 'simple': '', # DRTRIGON-85 + 'zip': 'False', + 'xlsx': '', # + 'ods': '', # + # may be 'hours' have to be added too (e.g. for 'ar') + 'cron': '', # DRTRIGON-102 + 'error': repr('<noinclude>\n%(error)s\n</noinclude>'), # DRTRIGON-116 + #'djvu': ... u"djvused -e 'n' "%s"" ... djvutext.py + #'pdf': ... u"pdftotext" or python module + #'imageocr', 'swfocr', ... + }, + + # this is a system parameter and should not be changed! (copy.deepcopy) + 'EditFlags': {'minorEdit': True, 'botflag': True}, +} + +## used/defined magic words, look also at bot_control +# use, for example: '<!--SUBSTER-BOTerror--><!--SUBSTER-BOTerror-->' +magic_words = {} # no magic word substitution (for empty dict) + +# debug tools +# (look at 'bot_control.py' for more info) +debug = [] +#debug.append( 'code' ) # code debugging + + +class SubsterBot(basic.AutoBasicBot): + ''' + Robot which will does substitutions of tags within wiki page content with external or + other wiki text data. Like dynamic text updating. + ''' + + _param_default = bot_config['param_default'] + + _var_regex_str = bot_config['var_regex_str']%{'var1':'%(var)s','var2':'%(var)s','cont':'%(cont)s'} + _BS_regex_str = bot_config['var_regex_str']%{'var1':'%(var1)s','var2':'%(var2)sBS:/','cont':'%(cont)s'} + + # -template and subst-tag handling taken from MerlBot + # -this bot could also be runned on my local wiki with an anacron-job + + def __init__(self): + '''Constructor of SubsterBot(), initialize needed vars.''' + + pywikibot.output(u'\03{lightgreen}* Initialization of bot:\03{default}') + + logging.basicConfig(level=logging.DEBUG if ('code' in debug) else logging.INFO) + + basic.AutoBasicBot.__init__(self) + + # modification of timezone to be in sync with wiki + os.environ['TZ'] = 'Europe/Amsterdam' + time.tzset() + pywikibot.output(u'Setting process TimeZone (TZ): %s' % str(time.tzname)) # ('CET', 'CEST') + + # init constants + self._bot_config = bot_config + # convert e.g. namespaces to corret language + self._bot_config['TemplateName'] = pywikibot.Page(self.site, self._bot_config['TemplateName']).title() + self._template_regex = re.compile('{{' + self._bot_config['TemplateName'] + '(.*?)}}', re.S) + + self._debug = debug + + + # init constants + self._userListPage = pywikibot.Page(self.site, bot_config['TemplateName']) + self._ConfCSSpostprocPage = pywikibot.Page(self.site, bot_config['ConfCSSpostproc']) + self._ConfCSSconfigPage = pywikibot.Page(self.site, bot_config['ConfCSSconfig']) + self.pagegen = pagegenerators.ReferringPageGenerator(self._userListPage, onlyTemplateInclusion=True) + self._code = self._ConfCSSpostprocPage.get() + pywikibot.output(u'Imported postproc %s rev %s from %s' % \ + ((self._ConfCSSpostprocPage.title(asLink=True),) + self._ConfCSSpostprocPage.getVersionHistory(revCount=1)[0][:2]) ) + self._flagenable = {} + if self._ConfCSSconfigPage.exists(): + exec(self._ConfCSSconfigPage.get()) # with variable: bot_config_wiki + self._flagenable = bot_config_wiki['flagenable'] + pywikibot.output(u'Imported config %s rev %s from %s' % \ + ((self._ConfCSSconfigPage.title(asLink=True),) + self._ConfCSSconfigPage.getVersionHistory(revCount=1)[0][:2]) ) + + def run(self, sim=False, msg=None, EditFlags=bot_config['EditFlags']): + '''Run SubsterBot().''' + + pywikibot.output(u'\03{lightgreen}* Processing Template Backlink List:\03{default}') + + if sim: self.pagegen = ['dummy'] + + for page in self.pagegen: + # setup source to get data from + if sim: + content = sim['content'] + params = [ sim ] + else: + pywikibot.output(u'Getting page "%s" via API from %s...' + % (page.title(asLink=True), self.site)) + + # get page content and operating mode + content = self.load(page) + params = self.loadTemplates(page, self._bot_config['TemplateName'], + default=self._param_default) + + if not params: continue + + (substed_content, substed_tags) = self.subContent(content, params) + + # output result to page or return directly + if sim: + return substed_content + else: + # if changed, write! + if (substed_content != content): + #if substed_tags: + self.outputContentDiff(content, substed_content) + + head = i18n.twtranslate(self.site.lang, + 'thirdparty-drtrigonbot-sum_disc-summary-head') + if msg is None: + msg = i18n.twtranslate(self.site.lang, + 'thirdparty-drtrigonbot-subster-summary-mod') + flags = copy.deepcopy(EditFlags) + if page.title() in self._flagenable: + flags.update( self._flagenable[page.title()] ) + pywikibot.output(u'Flags used for writing: %s' % flags) + self.save( page, substed_content, + (head + u' ' + msg) % {'tags':", ".join(substed_tags)}, + **flags ) + else: + pywikibot.output(u'NOTHING TO DO!') + + def subContent(self, content, params): + """Substitute the tags in content according to params. + + @param content: Content with tags to substitute. + @type content: string + @param params: Params with data how to substitute tags. + @type params: dict + + Returns a tuple containig the new content with tags + substituted and a list of those tags. + """ + + substed_content = content + substed_tags = [] # DRTRIGON-73 + + # 0.) subst (internal) magic words + try: + (substed_content, tags) = self.subBotMagicWords(substed_content) + substed_tags += tags + except: + exc_info = sys.exc_info() + (exception_only, result) = dtbext.pywikibot.gettraceback(exc_info) + substed_content += ast.literal_eval(self._param_default['error']) %\ + {'error': bot_config['ErrorTemplate'] %\ + ( pywikibot.Timestamp.now().isoformat(' '), + u' ' + result.replace(u'\n', u'\n ').rstrip() ) } + substed_tags.append( u'>error:BotMagicWords<' ) + + if (len(params) == 1) and ast.literal_eval(params[0]['magicwords_only']): + return (substed_content, substed_tags) + + for item in params: + # 1.) - 5.) subst templates + try: + (substed_content, tags) = self.subTemplate(substed_content, item) + substed_tags += tags + except: + exc_info = sys.exc_info() + (exception_only, result) = dtbext.pywikibot.gettraceback(exc_info) + substed_content += ast.literal_eval(item['error']) %\ + {'error': bot_config['ErrorTemplate'] %\ + ( item['value'], + pywikibot.Timestamp.now().isoformat(' '), + u' ' + result.replace(u'\n', u'\n ').rstrip() ) } + substed_tags.append( u'>error:%s<' % item['value'] ) + + return (substed_content, substed_tags) + + def subBotMagicWords(self, content): + """Substitute the DrTrigonBot Magic Word (tag)s in content. + + @param content: Content with tags to substitute. + @type content: string + + Returns a tuple containig the new content with tags + substituted and a list of those tags. + """ + + substed_tags = [] # DRTRIGON-73 + + # 0.) subst (internal) magic words + for subitem in magic_words.keys(): + prev_content = content + content = self.get_var_regex(subitem).sub( (self._var_regex_str%{'var':subitem,'cont':magic_words[subitem]}), + content, 1) # subst. once + if (content != prev_content): + substed_tags.append(subitem) + + return (content, substed_tags) + + def subTemplate(self, content, param): + """Substitute the template tags in content according to param. + + @param content: Content with tags to substitute. + @type content: string + @param param: Param with data how to substitute tags. + @type param: dict + + Returns a tuple containig the new content with tags + substituted and a list of those tags. + """ + + substed_tags = [] # DRTRIGON-73 + prev_content = content + + # 0.2.) check for 'simple' mode and get additional params + if param['simple']: + p = self.site.getExpandedString(param['simple']) + param.update( pywikibot.extract_templates_and_params(p)[0][1] ) + + # 0.5.) check cron/date + if param['cron']: + # [min] [hour] [day of month] [month] [day of week] + # (date supported only, thus [min] and [hour] dropped) + if not (param['cron'][0] == '@'): + param['cron'] = '* * ' + param['cron'] + entry = crontab.CronTab(param['cron']) + # find the delay from midnight (does not return 0.0 - but next) + delay = entry.next(datetime.datetime.now().replace(hour=0,minute=0,second=0,microsecond=0)-datetime.timedelta(microseconds=1)) + + pywikibot.output(u'CRON delay for execution: %.3f (<= %i)' % (delay, bot_config['CRONMaxDelay'])) + + if not (delay <= bot_config['CRONMaxDelay']): + return (content, substed_tags) + + # 1.) getUrl or wiki text + # (security: check url not to point to a local file on the server, + # e.g. 'file://' - same as used in xsalt.py) + secure = False + for item in [u'http://', u'https://', u'mail://']: + secure = secure or (param['url'][:len(item)] == item) + param['wiki'] = ast.literal_eval(param['wiki']) + param['zip'] = ast.literal_eval(param['zip']) + if (not secure) and (not param['wiki']): + return (content, substed_tags) + if param['wiki']: + if ast.literal_eval(param['expandtemplates']): # DRTRIGON-93 (only with 'wiki') + external_buffer = dtbext.pywikibot.Page(self.site, param['url']).get(expandtemplates=True) + else: + external_buffer = self.load( dtbext.pywikibot.Page(self.site, param['url']) ) + elif (param['url'][:7] == u'mail://'): # DRTRIGON-101 + param['url'] = param['url'].replace(u'{{@}}', u'@') # e.g. nlwiki + mbox = SubsterMailbox(pywikibot.config.datafilepath(bot_config['data_path'], bot_config['mbox_file'], '')) + external_buffer = mbox.find_data(param['url']) + mbox.close() + elif param['zip']: + external_buffer = urllib.urlopen(param['url']).read() + # issue with r355: http://de.wikipedia.org/w/index.php?title=Vorlage:Infobox_Kreditinstitut/Dat... + #f_url, external_buffer = http.request(self.site, param['url'], no_hostname=True, back_response=True) + #external_buffer = f_url.read() + #del f_url # free some memory (no need to keep a copy...) + else: + external_buffer = http.request(self.site, param['url'], no_hostname = True) + + # some intermediate processing (unzip, xlsx2csv, ...) + if param['zip']: + fileno = 0 if (param['zip'] == True) else (param['zip']-1) + external_buffer = self.unzip(external_buffer, fileno) + if param['xlsx']: + external_buffer = self.xlsx2csv(external_buffer, param['xlsx']) + if param['ods']: + external_buffer = self.ods2csv(external_buffer, param['ods']) + + if not ast.literal_eval(param['beautifulsoup']): # DRTRIGON-88 + # 2.) regexp + #for subitem in param['regex']: + subitem = param['regex'] + regex = re.compile(subitem, re.S | re.I) + + # 3.) subst in content + external_data = regex.search(external_buffer) + + external_data_dict = {} + if external_data: # not None + external_data = external_data.groups() + + pywikibot.output(u'Groups found by regex: %i' % len(external_data)) + + # DRTRIGON-114: Support for named groups in regexs + if regex.groupindex: + for item in regex.groupindex: + external_data_dict[u'%s-%s' % (param['value'], item)] = external_data[regex.groupindex[item]-1] + elif (len(external_data) == 1): + external_data_dict = {param['value']: external_data[0]} + else: + external_data_dict = {param['value']: str(external_data)} + logging.getLogger('subster').debug( str(external_data_dict) ) + + param['postproc'] = eval(param['postproc']) + # should be secured as given below, but needs code changes in wiki too + #param['postproc'] = ast.literal_eval(param['postproc']) + for value in external_data_dict: + external_data = external_data_dict[value] + + # 4.) postprocessing + func = param['postproc'][0] # needed by exec call of self._code + DATA = [ external_data ] # + args = param['postproc'][1:] # + scope = {} # (scope to run in) + scope.update( locals() ) # (add DATA, *args, ...) + scope.update( globals() ) # (add imports and else) + if func: + exec(self._code + (bot_config['CodeTemplate'] % func), scope, scope) + external_data = DATA[0] + logging.getLogger('subster').debug( external_data ) + + # 5.) subst content + var_regex = self.get_var_regex(value) + content = var_regex.sub((self._var_regex_str%{'var':value,'cont':external_data}), content, int(param['count'])) + if (content != prev_content): + substed_tags.append(value) + else: + # DRTRIGON-105: Support for multiple BS template configurations + value = param['value'] + if value: + value += u'-' + + # DRTRIGON-88: Enable Beautiful Soup power for Subster + BS_tags = self.get_BS_regex(value).findall(content) + + pywikibot.output(u'BeautifulSoup tags found by regex: %i' % len(BS_tags)) + + BS = BeautifulSoup.BeautifulSoup(external_buffer) + for item in BS_tags: + external_data = eval('BS.%s' % item[1]) + external_data = self._BS_regex_str%{'var1':value+'BS:'+item[1],'var2':value,'cont':external_data} + content = content.replace(item[0], external_data, 1) + + if (content != prev_content): + substed_tags.append(value+'BS') + + return (content, substed_tags) + + def outputContentDiff(self, content, substed_content): + """Outputs the diff between the original and the new content. + + @param content: Original content. + @type content: string + @param substed_content: New content. + @type substed_content: string + + Returns nothing, but outputs/prints the diff. + """ + diff = difflib.Differ().compare(content.splitlines(1), substed_content.splitlines(1)) + diff = [ line for line in diff if line[0].strip() ] + pywikibot.output(u'Diff:') + pywikibot.output(u'--- ' * 15) + pywikibot.output(u''.join(diff)) + pywikibot.output(u'--- ' * 15) + + def get_var_regex(self, var, cont='.*?'): + """Get regex used/needed to find the tags to replace. + + @param var: The tag/variable name. + @type var: string + @param cont: The content/value of the variable. + @type cont: string + + Return the according (and compiled) regex object. + """ + return re.compile((self._var_regex_str%{'var':var,'cont':cont}), re.S | re.I) + + def get_BS_regex(self, var, cont='(.*?)'): + """Get regex used/needed to find the BS tags to replace. + + @param var: The tag/variable name. + @type var: string + @param cont: The content/value of the variable. + @type cont: string + + Return the according (and compiled) regex object. + """ + return re.compile(u'(' + self._BS_regex_str%{'var1':var+'BS:(.*?)','var2':var,'cont':cont} + u')') + + def unzip(self, external_buffer, i): + """Convert zip data to plain format. + """ + + zip_buffer = zipfile.ZipFile(StringIO.StringIO(external_buffer)) + data_file = zip_buffer.namelist()[i] + external_buffer = zip_buffer.open(data_file).read().decode('latin-1') + + return external_buffer + + def xlsx2csv(self, external_buffer, sheet): + """Convert xlsx (EXCEL) data to csv format. + """ + + wb = openpyxl.reader.excel.load_workbook(StringIO.StringIO(external_buffer), use_iterators = True) + + sheet_ranges = wb.get_sheet_by_name(name = sheet) + + output = StringIO.StringIO() + spamWriter = csv.writer(output) + + for row in sheet_ranges.iter_rows(): # it brings a new method: iter_rows() + spamWriter.writerow([ cell.internal_value for cell in row ]) + + external_buffer = output.getvalue() + output.close() + + return external_buffer + + def ods2csv(self, external_buffer, sheet): + """Convert ods (Open/Libre Office) data to csv format. + """ + # http://www.mail-archive.com/python-list@python.org/msg209447.html + + import odf + from odf import opendocument, table, teletype + + doc = odf.opendocument.load(StringIO.StringIO(external_buffer)) + + output = StringIO.StringIO() + spamWriter = csv.writer(output) + + for sheet in doc.getElementsByType(odf.table.Table): + if not (sheet.getAttribute('name') == sheet): + continue + for row in sheet.getElementsByType(odf.table.TableRow): + spamWriter.writerow([ odf.teletype.extractText(cell).encode('utf-8') + for cell in row.getElementsByType(odf.table.TableCell) ]) + + external_buffer = output.getvalue() + output.close() + + return external_buffer + + +class SubsterMailbox(mailbox.mbox): + def __init__(self, mbox_file): + mailbox.mbox.__init__(self, mbox_file) + self.lock() + + self.remove_duplicates() + + def remove_duplicates(self): + """Find mails with same 'From' (sender) and remove all + except the most recent one. + """ + + unique = {} + remove = [] + for i, message in enumerate(self): + sender = message['from'] # Could possibly be None. + timestmp = message['date'] # Could possibly be None. + + timestmp = time.mktime( email.utils.parsedate(timestmp) ) + timestmp = datetime.datetime.fromtimestamp( timestmp ) + + if sender in unique: + (j, timestmp_j) = unique[sender] + + if (timestmp >= timestmp_j): + remove.append( j ) + else: + remove.append( i ) + else: + unique[sender] = (i, timestmp) + + remove.reverse() + for i in remove: + self.remove(i) + + self.flush() + #self.close() + + if remove: + pywikibot.output('Removed %i depreciated email data source(s).' % len(remove)) + + def find_data(self, url): + """Find mail according to given 'From' (sender). + """ + + url = (url[:7], ) + tuple(url[7:].split('/')) + content = [] + + for i, message in enumerate(self): + sender = message['from'] # Could possibly be None. + subject = message['subject'] # Could possibly be None. + timestmp = message['date'] # Could possibly be None. + + if sender and url[1] in sender: + # data found + pywikibot.output('Found email data source:') + pywikibot.output('%i / %s / %s / %s' % (i, sender, subject, timestmp)) + + full = (url[2] == 'attachment-full') + ind = 0 # default; ignore attachement index + if (url[2] == 'all'): + content = [ message.as_string(True) ] + elif (url[2] == 'attachment') or full: + if len(url) > 3: + ind = int(url[3]) # combine 'ind' with 'full=True'...? + counter = 1 + content = [] + for part in message.walk(): + # multipart/* are just containers + if part.get_content_maintype() == 'multipart': + continue + # Applications should really sanitize the given filename so that an + # email message can't be used to overwrite important files + filename = part.get_filename() + if filename or full: + if not filename: + ext = mimetypes.guess_extension(part.get_content_type()) + if not ext: + # Use a generic bag-of-bits extension + ext = '.bin' + filename = 'part-%03d%s' % (counter, ext) + + content += [ part.get_payload(decode=True) ] + pywikibot.output('Found attachment # %i: "%s"' % (counter, filename)) + + if counter == ind: + return content[-1] + + counter += 1 + + if (not full) and (not ind): + break + + break + + return string.join(content) + + +def main(): + args = pywikibot.handleArgs() + bot = SubsterBot() # for several user's, but what about complete automation (continous running...) + if len(args) > 0: + for arg in args: + pywikibot.showHelp() + return + try: + bot.run() + except KeyboardInterrupt: + pywikibot.output('\nQuitting program...') + +if __name__ == "__main__": + try: + main() + finally: + pywikibot.stopme() +
Property changes on: trunk/pywikipedia/subster.py ___________________________________________________________________ Added: svn:eol-style + native
Added: trunk/pywikipedia/subster_irc.py =================================================================== --- trunk/pywikipedia/subster_irc.py (rev 0) +++ trunk/pywikipedia/subster_irc.py 2012-12-02 19:17:58 UTC (rev 10761) @@ -0,0 +1,163 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +""" +Robot which connects to Recent Changes channel and runs "SubsterBot" whenever +needed. Alternative to test panel 'substersim.py' but no need of external +toolserver tool and web server to test correctness anymore - everything can be +done within wiki. + +Note: the script requires the Python IRC library +http://python-irclib.sourceforge.net/ +""" +## @package subster_irc +# @brief Dynamic Text Substitutions IRC surveillance Robot +# +# @copyright Dr. Trigon, 2011 +# @copyright Balasyum +# +# @section FRAMEWORK +# +# Python wikipedia robot framework, DrTrigonBot. +# @see http://pywikipediabot.sourceforge.net/ +# @see http://de.wikipedia.org/wiki/Benutzer:DrTrigonBot +# +# @section LICENSE +# +# Distributed under the terms of the LGPL license. +# +__version__ = '$Id: subster_irc.py 332 2012-06-13 12:37:40Z drtrigon $' +# + +import wikipedia as pywikibot + +import articlenos +import subster +#import botlist +from collections import deque +import time +import thread + +bot_config = { 'BotName': pywikibot.config.usernames[pywikibot.config.family][pywikibot.config.mylang], + + 'ConfCSSconfig': u'User:DrTrigon/DrTrigonBot/subster-config.css', +} + +## used/defined magic words, look also at bot_control +# use, for example: '<!--SUBSTER-BOTerror--><!--SUBSTER-BOTerror-->' +magic_words = {} # no magic word substitution (for empty dict) + +# debug tools +# (look at 'bot_control.py' and 'subster.py' for more info) +debug = [] + + +class SubsterTagModifiedBot(articlenos.ArtNoDisp): +# def __init__(self, site, channel, nickname, server, port=6667): +# SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname) +# self.channel = channel +# self.site = site +# self.other_ns = re.compile( +# u'14[[07(' + u'|'.join(site.namespaces()) + u')') +# self.api_url = self.site.api_address() +# self.api_url += 'action=query&meta=siteinfo&siprop=statistics&format=xml' +# self.api_found = re.compile(r'articles="(.*?)"') +# self.re_edit = re.compile( +# r'^C14[[^C07(?P<page>.+?)^C14]]^C4 (?P<flags>.*?)^C10 ^C02(?P<url>.+?)^C ^C5*^C ^C03(?P<user>.+?)^C ^C5*^C (?^B?(?P<bytes>[+-]?\d+?)^B?) ^C10(?P<summary>.*)^C'.replace('^B', '\002').replace('^C', '\003').replace('^U', '\037')) +# + def __init__(self, *arg): + articlenos.ArtNoDisp.__init__(self, *arg) + + self.refs = {} + self.time = 0. + self.queue = deque([]) + + self.templ = pywikibot.Page(self.site, subster.bot_config['TemplateName']) + self.do_refresh_References() + + # init constants + self._ConfCSSconfigPage = pywikibot.Page(self.site, bot_config['ConfCSSconfig']) + self._difflink = [] + if self._ConfCSSconfigPage.exists(): + exec(self._ConfCSSconfigPage.get()) # with variable: bot_config_wiki + self._difflink = bot_config_wiki['difflink'] + + def on_pubmsg(self, c, e): + match = self.re_edit.match(e.arguments()[0]) + if not match: + return +# print match.groups(), match.group('page'), match.group('user') + user = match.group('user').decode(self.site.encoding()) + if user == bot_config['BotName']: + return + #if botlist.isBot(user): + # return + # test actual page against (template incl.) list + page = match.group('page').decode(self.site.encoding()) + if page in self.refs: + self.do_check(page) + else: + if page not in self.queue: + self.queue.append( page ) # check later + # refresh list and test (queued) old pages against new list + (size, age) = ( len(self.queue), (time.time()-self.time) ) + if (size > 1000) or (age > 300): + pywikibot.output(u'QUEUE: size=%i, age=%f' % (size, age)) + self.do_refresh_References() + while self.queue: + pop = self.queue.popleft() + if pop in self.refs: + self.do_check(pop) + # test actual page against 'difflink' list ("HACKY") + p = page + for (target, source, params) in self._difflink: + if params['subpages']: + p = p.split('/') + else: + p = [p] + if (source == p[0]): + pywikibot.output(u'DIFFLINK: target=%s, source=%s, params=%s' % (target, source, params)) + text = u'[[%s]] / [[User:%s]] / %s' % ( page, + user, + match.group('summary').decode(self.site.encoding()) ) + self.do_check(target, params=(text, params['flags'])) + + def do_refresh_References(self): +# print "refresh" + self.refs = {} + self.time = time.time() + for page in self.templ.getReferences(follow_redirects=False, + onlyTemplateInclusion=True): + self.refs[page.title()] = page + + def do_check(self, page_title, params=None): + # Create two threads as follows + # (simple 'thread' for more sophisticated code use 'threading') + pywikibot.output(u"CHECK: %s" % page_title) + try: + thread.start_new_thread( main_subster, (self.refs[page_title], params) ) + except: + pywikibot.output(u"WARNING: unable to start thread") + +# Define a function for the thread +def main_subster(page, params=None): + bot = subster.SubsterBot() + page.get(force=True) # refresh page content + bot.silent = True + bot.pagegen = [ page ] # single page, according to pagegenerators.py + if params: + bot.run(msg = params[0], EditFlags = params[1]) + else: + bot.run() + del bot + +def main(): + subster.magic_words = magic_words + subster.debug = debug + site = pywikibot.getSite() + site.forceLogin() + chan = '#' + site.language() + '.' + site.family.name + bot = SubsterTagModifiedBot(site, chan, site.loggedInAs(), "irc.wikimedia.org") + bot.start() + +if __name__ == "__main__": + main()
Property changes on: trunk/pywikipedia/subster_irc.py ___________________________________________________________________ Added: svn:eol-style + native
pywikipedia-svn@lists.wikimedia.org