This is a basic parser for the .nwctxt file format in the scripting language python.
#pyNWC-a .nwctxt syntax parser in python
#Created by forum user kahman.
#Use it however you please. Feel free to modify it, but please return all modifications to the forum.
#Known bugs:
# *Cannot import lyrics that have line-breaks in them.
def parsefile(_file):
"parse one file"""
_file=_file.split('\n') #split the file by line
for x in range(len(_file)): #for each remaining line,
_file[x]=parseline(_file[x]) #parse it seperately
while 1: #until error occurs
try:
_file.remove(None) #remove a None from the list
except ValueError: #if there is no None,
break #break
return _file
def parseline(line):
output=[]
if line=='': #if line is blank,
return None #destroy it
elif line[0]=='#': #or if it's a comment,
return None #destroy it
elif line[0]=='!': #or if it's start/end marker,
return None #destroy it
line=line.split('|') #split the line by |
output.append(line[1]) #set what object it is
output.append({})
for x in line[2:]: #then for each property/value
y=(x.split(':')) #split it into property and value
output[1][y[0]]=y[1] #and add these to the dictionary
return output
See the code for known bugs.
If you want to "translate" it into another computer language, feel free to do so. If you want to modify it, feel free to do so.
Basically, what it does is you can give it a line of code and it will process it by | and :, so
|Note|Dur:4th|Pos:0 becomes the line of code
['Note', {'Dur': '4th', 'Pos': '0'}]If anyone makes any modifications, post them here.
At some point, someone should write a converter to/from MXML...sigh.
Oh, and at some point, I'll work on a program to convert from this back to NWCTXT.
If you find a bug, please post it here.
Here's an update that allows you to change the semi-tree format back into NWCTXT:
#pyNWC-a .nwctxt syntax parser (I/O) in python
#Created by forum user kahman.
#Use it however you please. Feel free to modify it, but please return all modifications to the forum.
#Known bugs:
# *Cannot import lyrics that have line-breaks in them.
def parsefile(_file):
"parse one file"
_file=_file.split('\n') #split the file by line
for x in range(len(_file)): #for each remaining line,
_file[x]=parseline(_file[x]) #parse it seperately
while 1: #until error occurs
try:
_file.remove(None) #remove a None from the list
except ValueError: #if there is no None,
break #break
return _file
def parseline(line):
"parse one line"
output=[]
if line=='': #if line is blank,
return None #destroy it
elif line[0]=='#': #or if it's a comment,
return None #destroy it
elif line[0]=='!': #or if it's start/end marker,
return None #destroy it
line=line.split('|') #split the line by |
output.append(line[1]) #set what object it is
output.append({})
for x in line[2:]: #then for each property/value
y=(x.split(':')) #split it into property and value
output[1][y[0]]=y[1] #and add these to the dictionary
return output
def writefile(tree):
"write a file"
output='!NoteWorthyComposer(2.0)\n' #start empty output
for x in tree: #for each line
output=output+writeline(x)+'\n' #process it seperately
output=output+'!NoteWorthyComposer-End'
return output
def writeline(line):
"write a line"
output='|' #start empty output
output=output+line[0]
for x in line[1].keys():
output=output+'|%s:%s' %(x, line[1][x])
return output
Here is a wrapper script I wrote so that I could save your output as a file. I have used your output in a file as input to a Python script that converts it to XML. The converter is posted under:
"nwcPythonTxt to xml converter" https://forum.noteworthycomposer.com/?topic=6860.0 (https://forum.noteworthycomposer.com/?topic=6860.0)
Thanks for your good work. I find I am much more productive in Python. Here is the code, which is mostly yours. Thanks again.
#Joe Dorocak's small additions to kahman's :
#pyNWC-a .nwctxt syntax parser (I/O) in python
#Created by NWC forum user kahman.
#Use it however you please. Feel free to modify it, but please return all modifications to the forum.
#See below for known bugs.
#If you want to "translate" it into another computer language, feel free to do so. If you want to modify it, feel free to do so.
#Basically, what it does is you can give it a line of code and it will process it by | and :, so |Note|Dur:4th|Pos:0 becomes the line of code ['Note', {'Dur': '4th', 'Pos': '0'}]
#If anyone makes any modifications, post them here.
#At some point, someone should write a converter to/from MXML...sigh.
#Oh, and at some point, I'll work on a program to convert from this back to NWCTXT.
#If you find a bug, please post it here.
#Known bugs:
# *Cannot import lyrics that have line-breaks in them.
"""
nwcTxtParse.py Translates NWCTextFormat to PythonListDictFormat
Usage: nwcTxtParse.py infileName outfileName
Example: nwcTxtParse.py mySong.nwctxt mySong.py
"""
def parsefile(_file):
"parse one file"
_file=_file.split('\n') #split the file by line
for x in range(len(_file)): #for each remaining line,
_file[x]=parseline(_file[x]) #parse it seperately
while 1: #until error occurs
try:
_file.remove(None) #remove a None from the list
except ValueError: #if there is no None,
break #break
return _file
def parseline(line):
"parse one line"
output=[]
if line=='': #if line is blank,
return None #destroy it
elif line[0]=='#': #or if it's a comment,
return None #destroy it
elif line[0]=='!': #or if it's start/end marker,
return None #destroy it
line=line.split('|') #split the line by |
output.append(line[1]) #set what object it is
output.append({})
for x in line[2:]: #then for each property/value
y=(x.split(':')) #split it into property and value
output[1][y[0]]=y[1] #and add these to the dictionary
return output
def writefile(tree):
"write a file"
output='!NoteWorthyComposer(2.0)\n' #start empty output
for x in tree: #for each line
output=output+writeline(x)+'\n' #process it seperately
output=output+'!NoteWorthyComposer-End'
return output
def writeline(line):
"write a line"
output='|' #start empty output
output=output+line[0]
for x in line[1].keys():
output=output+'|%s:%s' %(x, line[1][x])
return output
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
s2 = parsefile(s) # translate s into s2
f = open(args[1], 'w'); f.write(str(s2)); f.close() # write str(s2) into the output file
print 'Translated ' + str(args[0]) + ' yielding ' + str(args[1])
if __name__ == '__main__':
sys.exit(main())
Thanks again.
All the best :)
Joe