import std/[logging, options, os, strutils]
import zero_functional
import ./ast
type
FormatContext = ref object
chart: ChordChart
currentKey: ChordChartPitch
sourceKey: ChordChartPitch
currentSection: ChordChartNode
numberChart: bool
transposeSteps: int
const DEFAULT_STYLESHEET* = """
"""
func scaleDegree(root: ChordChartPitch, p: ChordChartPitch): string =
let distance = p - root
case distance:
of 0: "1"
of 1: "♭2"
of 2: "2"
of 3: "♭3"
of 4: "3"
of 5: "4"
of 6: "♭5"
of 7: "5"
of 8: "♭6"
of 9: "6"
of 10: "♭7"
of 11: "7"
else: raise newException(Exception, "Impossible")
func format(ctx: FormatContext, chord: ChordChartChord, useNumber = false): string =
if not useNumber and chord.original.isSome: return chord.original.get
elif useNumber:
result = "" &
ctx.currentKey.scaleDegree(chord.rootPitch) & ""
if chord.flavor.isSome:
result &= "" & chord.flavor.get & ""
if chord.bassPitch.isSome:
result &= "/" &
ctx.currentKey.scaleDegree(chord.bassPitch.get) & ""
else:
result = $chord.rootPitch
if chord.flavor.isSome: result &= chord.flavor.get
if chord.bassPitch.isSome: result &= "/" & $chord.bassPitch.get
#debug "transposed " & $ctx.sourceKey & " -> " & $ctx.currentKey &
# " (distance " & $distance & ")\p\tchord: " & $chord & " to " & result
proc transpose(ctx: FormatContext, chord: ChordChartChord): ChordChartChord =
result = chord
let distance = ctx.currentKey - ctx.sourceKey
if distance != 0:
result = ChordChartChord(
original: none[string](),
rootPitch: chord.rootPitch + distance,
flavor:
if chord.flavor.isSome: some(chord.flavor.get)
else: none[string](),
bassPitch:
if chord.bassPitch.isSome: some(chord.bassPitch.get + distance)
else: none[ChordChartPitch]())
func makeSongOrder(songOrder, indent: string): string =
result = indent & "Song Order
\p" &
indent & " \p"
result &= join(songOrder.split(",") -->
map(indent & "
\p" & indent & "" & node.sectionName
if ctx.currentSection.remainingSectionLine.isSome:
result &= "" &
ctx.currentSection.remainingSectionLine.get & ""
result &= "
\p"
var contents = newSeq[string]()
for contentNode in node.sectionContents:
contents.add(ctx.toHtml(contentNode, indent & " "))
result &= contents.join("\p")
result &= indent & "