Here is a Python script I wrote after reading NWC Virtuoso, kahman's post:
Python NWCTXT parser - https://forum.noteworthycomposer.com/?topic=6097.0
My script converts kahman's Python List/Dictionary output to XML. I did it so that I could study the structure of an nwctxt file using a data folding text editor. The XML structure is my own home grown version based on what I inferred from kahman's Python Data Structure. I have done minimal testing so use it with caution. Please let me know what you think. Please post any additions here. You can use this script as you like. Here is the code:
"""
nwcPy2nwcXml.py Translates
FROM: nwcPythonListDictFormat (kahman's nwctxt to python converter pyNWC-a output)
TO: jdorocak's homegrown xml (So I can use data folding in a text editor.) :)
Usage: nwcPy2nwcXml.py infileName outfileName
Example: nwcPy2nwcXml.py mySong.py mySong.xml
Author: Joe Dorocak
License: Use this as you please. :)
Use with caution - I have done minimal testing. No warranty is implied. :)
"""
class ConvertToXML():
"""
Converts
FROM: nwcPythonListDictFormat (NWC Virtuoso kahman's nwctxt to python converter pyNWC-a output)
TO: jdorocak's homegrown xml (So I can use data folding in a text editor.) :)
rs == resultString; il == indentationLevel; aprs(il,str) == appendToResultString(indentationLevel,strToAppend)
data == string output of kahman's nwctxt to python converter
ix == index of current pythonListDict item;
joe's xml syntax for nwctxtPy files inferred from analysis of data (i added elements named j*):
<jNwctxtPy>
<SongInfo count=1></SongInfo>
<PgSetup count=1></PgSetup>
<jFonts><Font count=12></Font></jFonts>
<PgMargins count=1></PgMargins>
<jStaves>
<jStaff>
<AddStaff count=1></AddStaff>
<StaffProperties count=2></StaffProperties>
<StaffInstrument count=1></StaffInstrument>
<Clef count=n></Clef>
<Key count=n></Key>
<Tempo count=n></Tempo>
<Note count=n></Note>
<Chord count=n></Chord>
<Bar count=n></Bar>
</jStaff>
</jStaves>
</jNwctxtPy>
"""
def __init__(self, indata):
"""
data == data to be converted. FROM: nwcPythonListDictFormat (kahman's nwctxt to python converter pyNWC-a output)
rs == resultString; converted data jdorocak's homegrown xml (So I can use data folding in a text editor.) :)
"""
self.data = eval(indata)
self.data.append(['End', {'Joe': 'End', 'Pos': 'Whatever'}])
self.rs = ''
def toxml(self):
self.aprs(0,'<jNwctxtPy>')
#SongInfo
self.aprs(1,'<SongInfo count=1>')
ix = 0
print len(self.data)
for k,v in self.data[ix][1].iteritems():
self.aprs (2,'<' + k + '>' + str(v) + '</' + k + '>')
self.aprs (1,'</SongInfo>')
#PgSetup
self.aprs (1,'<PgSetup count=1>')
ix = 1
for k,v in self.data[ix][1].iteritems():
self.aprs (2,'<' + k + '>' + str(v) + '</' + k + '>' )
self.aprs (1,'</PgSetup>')
#Fonts
self.aprs (1,'<jFonts>')
for ix in range(2,14):
self.aprs (2,'<Font count=12>')
for k,v in self.data[ix][1].iteritems():
self.aprs (3,'<' + k + '>' + str(v) + '</' + k + '>' )
self.aprs (2,'</Font>')
self.aprs (1,'</jFonts>')
#PgMargins
self.aprs (1,'<PgSetup count=1>')
ix = 15
for k,v in self.data[ix][1].iteritems():
self.aprs (2,'<' + k + '>' + str(v) + '</' + k + '>' )
self.aprs (1,'</PgSetup>')
self.aprs (1,'<jStaves>')
self.aprs (2,'<jStaff>')
#AddStaff
ix = 16
for ix in range(ix,len(self.data)-1):
#if self.data[ix+1][0] == 'AddStaff': self.aprs (2,'<jStaff>') #ix+1 needed to add ['End',{'Joe':'whatever'}]
self.aprs (3,'<'+ self.data[ix][0] +'>')
for k,v in self.data[ix][1].iteritems():
self.aprs (4,'<' + k + '>' + str(v) + '</' + k + '>' )
self.aprs (3,'</'+ self.data[ix][0] +'>')
if self.data[ix+1][0] == 'AddStaff': #ix+1 needed to add ['End',{'Joe':'whatever'}]
self.aprs (2,'</jStaff>')
self.aprs (2,'<jStaff>')
self.aprs (2,'</jStaff>')
self.aprs (1,'</jStaves>')
self.aprs(0,'</jNwctxtPy>')
return self.rs
def aprs(self, il, strToAppend):
"""aprs(il,str) == appendToResultString(indentationLevel,strToAppend)"""
self.rs = ''.join([self.rs, il*2*' '+strToAppend+'\n'])
#print il*2*' '+strToAppend
import sys
N_ARGS = 2
def main(argv=None):
if argv == None: argv=sys.argv
args = argv[1:] #NOTE: args[0] != argv[0] == <full path to example.py>
if len(args) != N_ARGS or "-h" in args or "--help" in args:
print __doc__
sys.exit(2)
f = open(args[0], 'r'); s = f.read(); f.close() # get the input file into s
cx = ConvertToXML(s) # make a new converter for s
sXml = cx.toxml() # translate s into sXml
f = open(args[1], 'w'); f.write(sXml); f.close() # write str(s2) into the output file
print 'Translated ' + str(args[0]) + ' yielding ' + str(args[1])
if __name__ == '__main__':
sys.exit(main())
I have posted the addition I did to kahman's code to save his output in a file, at his post: https://forum.noteworthycomposer.com/?topic=6097.0
All the best.
Joe