1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
#!/usr/bin/env python
from __future__ import print_function
import xml.dom.minidom
from xml.parsers.expat import ExpatError
import argparse
import sys
import re
description = """
This script converts the default Release Notes from JIRA to a ITK's wiki format.
Specifically input such as:
<h2> Epic
</h2>
<ul>
<li>[<a href='https://issues.itk.org/jira/browse/SIMPLEITK-1'>SIMPLEITK-1</a>] - Develop registration framework for ITKv4 Framework
</li>
<li>[<a href='https://issues.itk.org/jira/browse/SIMPLEITK-571'>SIMPLEITK-571</a>] - Add More Registration Examples
</li>
</ul>
is converted to:
==Epic==
*[[[https://issues.itk.org/jira/browse/SIMPLEITK-1SIMPLEITK-1]]] - Develop registration framework for ITKv4 Framework
*[[[https://issues.itk.org/jira/browse/SIMPLEITK-571SIMPLEITK-571]]] - Add More Registration Examples
"""
def do_text(node,strip=False):
"""Render a text node, with some while space cleanup"""
text = node.data.encode('ascii', 'replace');
text = re.sub(' +', ' ', text)
if strip:
text = text.strip()
return text;
def do_li(node):
"""Render a li element into a wiki bullet-ed list"""
return ("*"+parse(node)).rstrip('\n')
def do_a(node):
"""Render a hyperlink node, into a wiki link"""
if node.hasAttribute("href"):
return "[["+node.attributes["href"].value+' '+parse(node)+"]]"
def do_h(node, level=1):
"""Render a header title"""
s="="*level
if len(node.childNodes)==1 and node.firstChild.nodeType == xml.dom.Node.TEXT_NODE:
s+=do_text(node.firstChild, strip=True)
else:
s+=parse(node)
s +="="*level
return s
def parse_Element(node):
"""Dispatch to correct handling do method"""
if node.tagName == "li":
return do_li(node)
elif node.tagName == "a":
return do_a(node)
elif node.tagName == "h1":
return do_h(node,1)
elif node.tagName == "h2":
return do_h(node,2)
else:
return parse(node)
def parse_Document(node):
"""Dispatch for root document element"""
return parse(node.documentElement)
def parse(node):
"""Core reclusive method for depth-first traversal without state"""
s=""
for child in node.childNodes:
if child.nodeType == xml.dom.Node.TEXT_NODE:
s+=do_text(child)
elif child.nodeType == xml.dom.Node.DOCUMENT_TYPE_NODE:
s+=parse_Document(child)
elif child.nodeType == xml.dom.Node.ELEMENT_NODE:
s+=parse_Element(child)
return s
def html_fragment_to_wiki(html_fragment):
dom = xml.dom.minidom.parseString("<html>"+html_fragment+"</html>")
return parse(dom)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=description)
parser.add_argument("inputHTMLNotes", help="Input file name containing the HTML fragment of release notes generated by JIRA.")
args = parser.parse_args()
with open(args.inputHTMLNotes, "r") as myfile:
data=myfile.read()
try:
print(html_fragment_to_wiki(data))
except ExpatError as e:
print(e, file=sys.stderr)
# 1 based line index in error
print( " \"{0}\"".format(data.splitlines()[e.lineno-1]), file=sys.stderr)
|