TidyTools.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #
  2. # ElementTree
  3. # $Id: TidyTools.py 1862 2004-06-18 07:31:02Z Fredrik $
  4. #
  5. # tools to run the "tidy" command on an HTML or XHTML file, and return
  6. # the contents as an XHTML element tree.
  7. #
  8. # history:
  9. # 2002-10-19 fl added to ElementTree library; added getzonebody function
  10. #
  11. # Copyright (c) 1999-2004 by Fredrik Lundh. All rights reserved.
  12. #
  13. # fredrik@pythonware.com
  14. # http://www.pythonware.com
  15. #
  16. ##
  17. # Tools to build element trees from HTML, using the external <b>tidy</b>
  18. # utility.
  19. ##
  20. import glob, string, os, sys
  21. from ElementTree import ElementTree, Element
  22. NS_XHTML = "{http://www.w3.org/1999/xhtml}"
  23. ##
  24. # Convert an HTML or HTML-like file to XHTML, using the <b>tidy</b>
  25. # command line utility.
  26. #
  27. # @param file Filename.
  28. # @param new_inline_tags An optional list of valid but non-standard
  29. # inline tags.
  30. # @return An element tree, or None if not successful.
  31. def tidy(file, new_inline_tags=None):
  32. command = ["tidy", "-qn", "-asxml"]
  33. if new_inline_tags:
  34. command.append("--new-inline-tags")
  35. command.append(string.join(new_inline_tags, ","))
  36. # FIXME: support more tidy options!
  37. # convert
  38. os.system(
  39. "%s %s >%s.out 2>%s.err" % (string.join(command), file, file, file)
  40. )
  41. # check that the result is valid XML
  42. try:
  43. tree = ElementTree()
  44. tree.parse(file + ".out")
  45. except:
  46. print "*** %s:%s" % sys.exc_info()[:2]
  47. print ("*** %s is not valid XML "
  48. "(check %s.err for info)" % (file, file))
  49. tree = None
  50. else:
  51. if os.path.isfile(file + ".out"):
  52. os.remove(file + ".out")
  53. if os.path.isfile(file + ".err"):
  54. os.remove(file + ".err")
  55. return tree
  56. ##
  57. # Get document body from a an HTML or HTML-like file. This function
  58. # uses the <b>tidy</b> function to convert HTML to XHTML, and cleans
  59. # up the resulting XML tree.
  60. #
  61. # @param file Filename.
  62. # @return A <b>body</b> element, or None if not successful.
  63. def getbody(file, **options):
  64. # get clean body from text file
  65. # get xhtml tree
  66. try:
  67. tree = apply(tidy, (file,), options)
  68. if tree is None:
  69. return
  70. except IOError, v:
  71. print "***", v
  72. return None
  73. NS = NS_XHTML
  74. # remove namespace uris
  75. for node in tree.getiterator():
  76. if node.tag.startswith(NS):
  77. node.tag = node.tag[len(NS):]
  78. body = tree.getroot().find("body")
  79. return body
  80. ##
  81. # Same as <b>getbody</b>, but turns plain text at the start of the
  82. # document into an H1 tag. This function can be used to parse zone
  83. # documents.
  84. #
  85. # @param file Filename.
  86. # @return A <b>body</b> element, or None if not successful.
  87. def getzonebody(file, **options):
  88. body = getbody(file, **options)
  89. if body is None:
  90. return
  91. if body.text and string.strip(body.text):
  92. title = Element("h1")
  93. title.text = string.strip(body.text)
  94. title.tail = "\n\n"
  95. body.insert(0, title)
  96. body.text = None
  97. return body
  98. if __name__ == "__main__":
  99. import sys
  100. for arg in sys.argv[1:]:
  101. for file in glob.glob(arg):
  102. print file, "...", tidy(file)