Skip to main content
Topic: Python NWCTXT parser (Read 14034 times) previous topic - next topic

Python NWCTXT parser

This is a basic parser for the .nwctxt file format in the scripting language python.
Code: [Select · Download]
#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.

Re: Python NWCTXT parser

Reply #1
Here's an update that allows you to change the semi-tree format back into NWCTXT:
Code: [Select · Download]
#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

Re: Python NWCTXT parser

Reply #2
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
Thanks for your good work. I find I am much more productive in Python. Here is the code, which is mostly yours. Thanks again.

Code: [Select · Download]
#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
Love and peace,
Joe