diff options
Diffstat (limited to 'Master/texmf-dist/scripts/pmxchords/ChordsTr.lua')
-rw-r--r-- | Master/texmf-dist/scripts/pmxchords/ChordsTr.lua | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/Master/texmf-dist/scripts/pmxchords/ChordsTr.lua b/Master/texmf-dist/scripts/pmxchords/ChordsTr.lua new file mode 100644 index 00000000000..e58ff11424a --- /dev/null +++ b/Master/texmf-dist/scripts/pmxchords/ChordsTr.lua @@ -0,0 +1,124 @@ +--[[ + (c) Copyright 2013 Ondrej Fafejta <fafejtao@gmail.com> + https://github.com/fafejtao/pmxChords +]]-- +-- +-- Chords transposition class +-- +ChordsTr = {} -- the table representing the class, which will double as the metatable for the instances +ChordsTr.__index = ChordsTr -- failed table lookups on the instances should fallback to the class table, to get methods +setmetatable( + ChordsTr, + { + __call = function (cls, ...) + return cls.new(...) + end, + }) + +-- +-- global constants +-- +ChordsTr.CHORDS_BEGIN="\\ch." +ChordsTr.CHORDS_END=".\\" +ChordsTr.BASE_CHORDS_ARR= { -- lua is indexing from 1 I need from 0 ... + [0] = "C", + [1] = "Cs", + [2] = "D", + [3] = "Ef", + [4] = "E", + [5] = "F", + [6] = "Fs", + [7] = "G", + [8] = "Af", + [9] = "A", + [10] = "Bf", + [11] = "B" +} + +-- +-- Create instance of chords transposition class +-- params iSig input signature e.g. -1 - F major +-- oSig output signature e.g. 2 - D major +-- +function ChordsTr.new(iSig, oSig) + local self = setmetatable({}, ChordsTr) + self.trMap = ChordsTr.__createTransposeMap(oSig - iSig) + return self +end + +-- +-- Core of transposition. +-- Prepare map of transposed chords. +-- Key is input base chord and value is output base chord. +-- +function ChordsTr.__createTransposeMap(sigDiff) + local size = 12 + local halfTones = (sigDiff * 7) % size + if (halfTones < 0 ) then + halfTones = halfTones + size + end + + -- generate transpose map of base chords ... + local res = {} + local i + for i = 0, size - 1, 1 do + local key = ChordsTr.BASE_CHORDS_ARR[i] + local trIdx = (i + halfTones) % size; + res[key] = ChordsTr.BASE_CHORDS_ARR[trIdx] + end + return res +end + +-- +-- transpose one line. +-- Find each chords in line and transpose it into output signature. +-- return transposed line. +-- +function ChordsTr:lineTranspose(line) + local pos = 0; + local trLine = "" -- transposed line (result) + while true do + local i = string.find(line, ChordsTr.CHORDS_BEGIN, pos) + if i == nil then + trLine = trLine .. string.sub(line, pos) + break + end + i = i + 3 -- move after \ch. + trLine = trLine .. string.sub(line, pos, i) -- append non chord string into result + pos = string.find(line, ChordsTr.CHORDS_END, i) + if pos == nil then -- TODO check correctly end of chords ... e.g. check wrong line (first chord is not finished correctly): \ch.C. c \ch.G7.\ b + io.stderr:write("End of chords was not found!\n") + os.exit(-1) + end + chord = string.sub(line, i + 1, pos - 1) + trLine=trLine .. self:doTranspose(chord) + end + return trLine +end + +-- +-- do transpose of one chord. +-- +function ChordsTr:doTranspose(chord) + local base, alt = ChordsTr.splitChord(chord) + return self.trMap[base]..alt +end + +-- +-- Split chord into two part: base chord and chord alteration. +-- e.g. Fsm7 - base chord is Fs, alteration is m7 +-- +function ChordsTr.splitChord(chord) + if(chord.len == 1) then + return chord, "" + end + local secondChar = string.sub(chord, 2, 2) + if (secondChar == 's' or secondChar == 'f' ) then + return chord.sub(chord, 1, 2), chord.sub(chord, 3) + else + return chord.sub(chord, 1, 1), chord.sub(chord, 2) + end +end +-- +-- end of ChordsTr class +-- |