6 Commits

7 changed files with 82 additions and 7 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
pco_chords pco_chords
src/pco_chordspkg/notation
.*.sw? .*.sw?

View File

@@ -1,6 +1,6 @@
# Package # Package
version = "0.6.1" version = "0.6.2"
author = "Jonathan Bernard" author = "Jonathan Bernard"
description = "Chord chart formatter compatible with Planning Center Online" description = "Chord chart formatter compatible with Planning Center Online"
license = "MIT" license = "MIT"

View File

@@ -186,12 +186,12 @@ proc parseChord*(
let bass = let bass =
if m.get.captures.contains(4) and m.get.captures[4].len > 0: if m.get.captures.contains(4) and m.get.captures[4].len > 0:
some(toScaleDegree(ctx.curKey, parseSpelledPitch(m.get.captures[4]))) some(parseSpelledPitchOrScaleDegree(ctx.curKey, m.get.captures[4]))
else: none[ScaleDegree]() else: none[ScaleDegree]()
return some(ChordChartChord( return some(ChordChartChord(
original: some(chordValue), original: some(chordValue),
root: toScaleDegree(ctx.curKey, parseSpelledPitch(m.get.captures[0])), root: parseSpelledPitchOrScaleDegree(ctx.curKey, m.get.captures[0]),
flavor: flavor, flavor: flavor,
bass: bass)) bass: bass))

View File

@@ -1,4 +1,4 @@
const PCO_CHORDS_VERSION* = "0.6.1" const PCO_CHORDS_VERSION* = "0.6.2"
const USAGE* = """Usage: const USAGE* = """Usage:
pco_chords [options] pco_chords [options]

View File

@@ -312,8 +312,8 @@ proc toHtml*(
numberChart: numberChart, numberChart: numberChart,
transposeSteps: transpose) transposeSteps: transpose)
debug "Formatting:\p\tsource key: " & $ctx.sourceKey & "\p\ttransposing: " & debug "Formatting:\p\tsource key: $#\p\ttransposing: $#\p\ttarget key: $#" %
$transpose & "\p\ttarget key: " & $ctx.currentKey [$ctx.sourceKey, $transpose, $ctx.currentKey]
result = """<!doctype html> result = """<!doctype html>
<html> <html>

Binary file not shown.

View File

@@ -207,7 +207,7 @@ func toNote*(p: Pitch): Note =
of Df, D: Note.D of Df, D: Note.D
of Ef, E: Note.E of Ef, E: Note.E
of F: Note.F of F: Note.F
of Gf, G: Note.D of Gf, G: Note.G
func toSpelledPitch*(p: Pitch): SpelledPitch = func toSpelledPitch*(p: Pitch): SpelledPitch =
@@ -314,8 +314,22 @@ func toScaleDegree*(k: Key, sp: SpelledPitch): ScaleDegree =
]# ]#
func parseSpelledPitchOrScaleDegree*(key: Key, str: string): ScaleDegree =
try:
let pitch =parseSpelledPitch(str)
return toScaleDegree(key, pitch)
except:
try: return parseScaleDegree(str)
except:
raise newException(ValueError,
str & " is not a recognized pitch or scale degree")
func transpose*(k: Key, steps: int): Key = func transpose*(k: Key, steps: int): Key =
#[
debugEcho "transpose: $# by $# steps, resulting in $# ($#)" %
[$k, $steps, $(k.tonic.toPitch + steps), $toSpelledPitch(k.tonic.toPitch + steps)]
]#
Key( Key(
tonic: toSpelledPitch(k.tonic.toPitch + steps), tonic: toSpelledPitch(k.tonic.toPitch + steps),
mode: k.mode) mode: k.mode)
@@ -373,3 +387,63 @@ when isMainModule:
assert "#5" == $toScaleDegree( assert "#5" == $toScaleDegree(
Key(tonic: parseSpelledPitch("Eb"), mode: Ionian), Key(tonic: parseSpelledPitch("Eb"), mode: Ionian),
parseSpelledPitch("B")) parseSpelledPitch("B"))
assert toSpelledPitch(Pitch.F + 2) ==
SpelledPitch(note: Note.G, alteration: naNatural)
let pitchCases = [
(Pitch.Af, SpelledPitch(note: Note.A, alteration: naFlat)),
(Pitch.A, SpelledPitch(note: Note.A, alteration: naNatural)),
(Pitch.Bf, SpelledPitch(note: Note.B, alteration: naFlat)),
(Pitch.B, SpelledPitch(note: Note.B, alteration: naNatural)),
(Pitch.C, SpelledPitch(note: Note.C, alteration: naNatural)),
(Pitch.Df, SpelledPitch(note: Note.D, alteration: naFlat)),
(Pitch.D, SpelledPitch(note: Note.D, alteration: naNatural)),
(Pitch.Ef, SpelledPitch(note: Note.E, alteration: naFlat)),
(Pitch.E, SpelledPitch(note: Note.E, alteration: naNatural)),
(Pitch.F, SpelledPitch(note: Note.F, alteration: naNatural)),
(Pitch.Gf, SpelledPitch(note: Note.G, alteration: naFlat)),
(Pitch.G, SpelledPitch(note: Note.G, alteration: naNatural)),
]
for (pitch, expected) in pitchCases:
assert toSpelledPitch(pitch) == expected
let spelledPitchCases = [
("Ab", Pitch.Af),
("G#", Pitch.Af),
("A", Pitch.A),
("G##", Pitch.A),
("Bbb", Pitch.A),
("Bb", Pitch.Bf),
("A#", Pitch.Bf),
("Cbb", Pitch.Bf),
("B", Pitch.B),
("Cb", Pitch.B),
("A##", Pitch.B),
("C", Pitch.C),
("B#", Pitch.C),
("Dbb", Pitch.C),
("Db", Pitch.Df),
("C#", Pitch.Df),
("B##", Pitch.Df),
("D", Pitch.D),
("C##", Pitch.D),
("Ebb", Pitch.D),
("Eb", Pitch.Ef),
("D#", Pitch.Ef),
("Fbb", Pitch.Ef),
("E", Pitch.E),
("Fb", Pitch.E),
("D##", Pitch.E),
("F", Pitch.F),
("E#", Pitch.F),
("Gbb", Pitch.F),
("Gb", Pitch.Gf),
("F#", Pitch.Gf),
("E##", Pitch.Gf),
("G", Pitch.G),
("F##", Pitch.G),
("Abb", Pitch.G),
]
for (spelled, expected) in spelledPitchCases:
assert parseSpelledPitch(spelled).toPitch == expected