Source

nwc2ly / nwc2ly.py

#! /usr/bin/env python
# -*- coding: utf8 -*-
#
# Noteworthy Composer Text Format Converter
# (Korean version)
import sys

position_bases = {
    'Treble': 67,  # 가온 다 오른쪽 첫번째 B(시)음
    'Bass': 49,    # 가온 다 왼쪽 첫번째 D(레)음
}
# We cannot distinguish major and minor keys currently.
keysig_map = {
    '0': 'c \major',
    '#1': 'g \major',
    '#2': 'd \major',
    '#3': 'a \major',
    '#4': 'e \major',
    '#5': 'b \major',
    '#6': 'fis \major',
    '#7': 'cis \major',
    'b1': 'f \major',
    'b2': 'bes \major',
    'b3': 'ees \major',
    'b4': 'aes \major',
    'b5': 'des \major',
    'b6': 'ges \major',
    'b7': 'ces \major',
}
accidental_map = {
    '#': 'is',
    'x': 'isis',
    'b': 'es',
    'v': 'eses',
}
barline_map = {
    'Single': '|',
    'Double': '||',
    'SectionOpen': '.|',
    'SecionClose': '|.',
    'MasterRepeatOpen': '|:',
    'MasterRepeatClose': ':|',
    'CloseRepeatOpen': '|:',
    'CloseRepeatClose': ':|',
}

# Assumptions:
# - All staves have the same time signature and the same key signature.
#   (including intermediate changes)
#   Exceptions may apply for percussion staves.
# - All staves share a single global tempo.
# - 

def usage():
    print 'blah blah'

def parse_parts(parts):
    data = {}
    for item in parts:
        k, v = item.split(':')
        if v == 'Y':
            v = True
        elif v == 'N':
            v = False
        if v.startswith('"') and v.endswith('"'):
            v = v[1:-1].replace('\\r\\n', '\r\n').decode('cp949')
        data[k] = v
    return data

def parse_opts(value):
    data = {}
    for item in data.split(','):
        try:
            k, v = item.split('=')
        except ValueError:
            k = item
            v = True
        data[k] = v
    return data

def absolute_pos(relative_pos, clef='Treble'):
    return position_bases[clef] + relative_pos

def normalize_name(name):
    # TODO
    return name.replace(' ', '_')

def convert_key(keysig):
    sharps = keysig.count('#')
    flats = keysig.count('b')
    if sharps == 0 and flats == 0:
        return keysig_map['0']
    if sharps > 0 and flats == 0:
        return keysig_map['#' + str(sharps)]
    if sharps == 0 and flats > 0:
        return keysig_map['b' + str(flats)]
    else:
        print 'WARNING: unsupported keysignature (%s)' % keysig
    return None

def convert(input_file, output_file):
    staff_began = False
    layered = False
    for line in input_file:
        if line.startswith('!'):  # comment lines
            continue
        parts = line.strip().split('|')
        object_type = parts[1]
        data = parse_parts(parts[2:])
        print object_type, data
        if object_type == 'SongInfo':
            pass
        if object_type == 'PgSetup':
            pass
        if object_type == 'Font':
            pass
        if object_type == 'PgMargins':
            pass
        if object_type == 'AddStaff':
            data['Style']
            data['Layer']
            if staff_began:
                pass
            else:
                pass
        if object_type == 'StaffProperties':
            pass
        if object_type == 'StaffInstrument':
            pass
        if object_type == 'Lyrics':
            pass
        if object_type.startswith('Lyric'):
            pass
        if object_type == 'Clef':
            pass
        if object_type == 'TimeSig':
            pass
        if object_type == 'Key':
            pass
        if object_type == 'Tempo':
            data.get('Text', '')
            pass
        if object_type == 'Rest':
            pass
        if object_type == 'Bar':
            pass
        if object_type == 'Text':
            pass
        if object_type == 'Note':
            dur = data['Dur'].split(',')
            dur_opts = parse_opts(dur[1:])
            pass
        if object_type == 'Chord':
            pass
        if object_type == 'Dynamic':
            data['Style']
            pass
        if object_type == 'SustainPedal':
            pass
        if object_type == 'PerformanceStyle':
            pass
        if object_type == 'Flow':
            pass

if __name__ == '__main__':
    if len(sys.argv) == 1:
        usage()
    else:
        input_file = open(sys.argv[1], 'r')
        try:
            output_file = open(sys.argv[2], 'w')
        except IndexError:
            output_file = sys.stdout

    convert(input_file, output_file)
    input_file.close()
    if output_file != sys.stdout:
        output_file.close()
    print 'Conversion complete!'