odfoutline 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #!/usr/bin/python3
  2. # -*- coding: utf-8 -*-
  3. # Copyright (C) 2006 Søren Roug, European Environment Agency
  4. #
  5. # This is free software. You may redistribute it under the terms
  6. # of the Apache license and the GNU General Public License Version
  7. # 2 or at your option any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public
  15. # License along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. #
  18. # Contributor(s):
  19. #
  20. from __future__ import print_function
  21. import zipfile
  22. from xml.sax import make_parser,handler
  23. from xml.sax.xmlreader import InputSource
  24. import xml.sax.saxutils
  25. import sys
  26. from odf.namespaces import TEXTNS, TABLENS, DRAWNS
  27. try:
  28. from cStringIO import StringIO
  29. except ImportError:
  30. from io import StringIO
  31. def getxmlpart(odffile, xmlfile):
  32. """ Get the content out of the ODT file"""
  33. z = zipfile.ZipFile(odffile)
  34. content = z.read(xmlfile)
  35. z.close()
  36. return content
  37. #
  38. # Extract headings from content.xml
  39. #
  40. class ODTHeadingHandler(handler.ContentHandler):
  41. """ Extract headings from content.xml of an ODT file """
  42. def __init__(self, eater):
  43. self.r = eater
  44. self.data = []
  45. self.level = 0
  46. def characters(self, data):
  47. self.data.append(data)
  48. def startElementNS(self, tag, qname, attrs):
  49. if tag == (TEXTNS, 'h'):
  50. self.level = 0
  51. for (att,value) in attrs.items():
  52. if att == (TEXTNS, 'outline-level'):
  53. self.level = int(value)
  54. self.data = []
  55. def endElementNS(self, tag, qname):
  56. if tag == (TEXTNS, 'h'):
  57. str = ''.join(self.data)
  58. self.data = []
  59. self.r.append("%d%*s%s" % (self.level, self.level, '', str))
  60. class ODTSheetHandler(handler.ContentHandler):
  61. """ Extract sheet names from content.xml of an ODS file """
  62. def __init__(self, eater):
  63. self.r = eater
  64. def startElementNS(self, tag, qname, attrs):
  65. if tag == (TABLENS, 'table'):
  66. sheetname = attrs.get((TABLENS, 'name'))
  67. if sheetname:
  68. self.r.append(sheetname)
  69. class ODTSlideHandler(handler.ContentHandler):
  70. """ Extract headings from content.xml of an ODT file """
  71. def __init__(self, eater):
  72. self.r = eater
  73. self.data = []
  74. self.pagenum = 0
  75. def characters(self, data):
  76. self.data.append(data)
  77. def startElementNS(self, tag, qname, attrs):
  78. if tag == (DRAWNS, 'page'):
  79. self.pagenum = self.pagenum + 1
  80. self.r.append("SLIDE %d: %s" % ( self.pagenum, attrs.get((DRAWNS, 'name'),'')))
  81. if tag == (TEXTNS, 'p'):
  82. self.data = []
  83. def endElementNS(self, tag, qname):
  84. if tag == (TEXTNS, 'p'):
  85. str = ''.join(self.data)
  86. self.data = []
  87. if len(str) > 0:
  88. self.r.append(" " + str)
  89. def odtheadings(odtfile):
  90. mimetype = getxmlpart(odtfile,'mimetype')
  91. content = getxmlpart(odtfile,'content.xml')
  92. lines = []
  93. parser = make_parser()
  94. parser.setFeature(handler.feature_namespaces, 1)
  95. if not isinstance(mimetype, str):
  96. mimetype=mimetype.decode("utf-8")
  97. if mimetype in ('application/vnd.oasis.opendocument.text',
  98. 'application/vnd.oasis.opendocument.text-template'):
  99. parser.setContentHandler(ODTHeadingHandler(lines))
  100. elif mimetype in ('application/vnd.oasis.opendocument.spreadsheet',
  101. 'application/vnd.oasis.opendocument.spreadsheet-template'):
  102. parser.setContentHandler(ODTSheetHandler(lines))
  103. elif mimetype in ('application/vnd.oasis.opendocument.presentation'
  104. 'application/vnd.oasis.opendocument.presentation-template'):
  105. parser.setContentHandler(ODTSlideHandler(lines))
  106. else:
  107. print ("Unsupported fileformat")
  108. sys.exit(2)
  109. parser.setErrorHandler(handler.ErrorHandler())
  110. inpsrc = InputSource()
  111. if not isinstance(content, str):
  112. content=content.decode("utf-8")
  113. inpsrc.setByteStream(StringIO(content))
  114. parser.parse(inpsrc)
  115. return lines
  116. if __name__ == "__main__":
  117. filler = " "
  118. for heading in odtheadings(sys.argv[1]):
  119. print (heading)
  120. # Local Variables: ***
  121. # mode: python ***
  122. # End: ***