summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/pmxchords
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2013-12-13 22:20:40 +0000
committerKarl Berry <karl@freefriends.org>2013-12-13 22:20:40 +0000
commit2e18ec49471b5109220bcdbda439fb3461b42f61 (patch)
treea150c763a8eae02cfbe09b10a4af5fec533f9871 /Master/texmf-dist/scripts/pmxchords
parentbb69c6ad45c96b1cf0b5fa79318c64e26b1c9bcd (diff)
pmxchords (12dec13)
git-svn-id: svn://tug.org/texlive/trunk@32405 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts/pmxchords')
-rw-r--r--Master/texmf-dist/scripts/pmxchords/ChordsTr.lua124
-rwxr-xr-xMaster/texmf-dist/scripts/pmxchords/pmxchords.lua194
2 files changed, 318 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
+--
diff --git a/Master/texmf-dist/scripts/pmxchords/pmxchords.lua b/Master/texmf-dist/scripts/pmxchords/pmxchords.lua
new file mode 100755
index 00000000000..13da5178d5b
--- /dev/null
+++ b/Master/texmf-dist/scripts/pmxchords/pmxchords.lua
@@ -0,0 +1,194 @@
+#!/usr/bin/env texlua
+--
+-- global constants
+--
+VERSION = "0.9.1"
+FILE_SUFFIX="_chtr"
+PMX_CMD="pmxab"
+
+--[[
+ pmxchords.lua: transposes chord macros (e,g., \ch.C.\) and calls pmxab
+
+ (c) Copyright 2013 Ondrej Fafejta <fafejtao@gmail.com>
+ https://github.com/fafejtao/pmxChords
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+--]]
+
+--[[
+ ChangeLog:
+
+ version 0.9.1 2013-12-09 - added some options. Improved processing.
+
+ version 0.9 2013-12-05 - rewrite code from perl to lua...
+--]]
+
+function usage()
+ print("Usage: [texlua] pmxchords.lua basename[.pmx] ")
+ print(" 1. transpose chords into new file basename"..FILE_SUFFIX..".pmx")
+ print(" 2. call pmxab on transposed file basename"..FILE_SUFFIX..".pmx")
+ print(" 3. rename basename"..FILE_SUFFIX..".tex to basename.tex")
+ print("options: -v version")
+ print(" -h help")
+ print(" -s stop after first step. e.g. generate only transposed basename"..FILE_SUFFIX..".pmx file")
+end
+
+function whoami ()
+ print("This is pmxchords.lua version ".. VERSION)
+end
+
+whoami()
+if #arg == 0 then
+ usage()
+ os.exit(0)
+end
+
+kpse.set_program_name("luatex") -- allows ChordsTr.lua to be installed in a texmf tree
+require "ChordsTr"
+
+function parseInputSignature(line)
+ -- parse input signature from pmx digits line. Only one line digits format is supported!
+ -- e.g.
+ -- 1 1 2 4 2 4 0 -1
+ -- signature is -1 : F major
+ local res = string.match(line, "^%s*[0-9]+%s+[0-9]+%s+[0-9]+%s+[0-9]+%s+[0-9]+%s+[0-9]+%s+[0-9]+%s+([%+%-]?[0-9]+)%s*$")
+ return tonumber(res)
+end
+
+function parseOutputSignature(line)
+ -- parse output signature from pmx
+ -- e.g.
+ -- K-2+2
+ -- output signature is +2 : D major
+ local res = string.match(line, "^K[%+%-]?[0-9]+([%+%-]?[0-9]+)")
+ return tonumber(res)
+end
+
+function handleErr(msg)
+ io.stderr:write(msg.."\n")
+ os.exit(2)
+end
+
+--
+-- get file name without .pmx suffix
+--
+function getBaseFileName(fileName)
+ if fileName ~= "" and string.sub(fileName, -4, -1) == ".pmx" then
+ return string.sub(fileName, 1, -5)
+ else
+ return fileName
+ end
+end
+
+--
+-- Make chords transposition. Generates new pmx file with transposed chords.
+--
+-- param baseName input file name without .pmx suffix
+-- return outputBaseName transposed pmx file name without .pmx suffix
+--
+function makeChordsTransposition(baseName)
+ local inputFileName = baseName..".pmx"
+ local inputFile = io.open(inputFileName, "r")
+ if(inputFile == nil) then
+ handleErr("File does not exist: "..inputFileName)
+ end
+
+ local outputBaseName = baseName..FILE_SUFFIX -- output base name without suffix. Used for renaming generated .tex file ...
+ local outputFileName = outputBaseName..".pmx"
+ local outputFile = io.open(outputFileName, "w")
+ if(outputFile == nil) then
+ handleErr("Can not create temporary file: ".. outputFileName)
+ end
+
+ --
+ -- transpose chords from inputFile into outputFile
+ --
+ -- input and output signature will be parsed from input pmx file
+ --
+ local iSig = nil -- input signature
+ local chTr = nil -- chords transposition class
+
+ for line in inputFile:lines() do
+ if(chTr ~= nil) then
+ outputFile:write(chTr:lineTranspose(line).."\n")
+ else
+ outputFile:write(line.."\n")
+ end
+ if(iSig == nil) then
+ iSig = parseInputSignature(line)
+ if(iSig ~= nil) then
+ io.stderr:write("Chords: input signature detected: "..iSig .."\n")
+ end
+ elseif(chTr == nil) then
+ local oSig = parseOutputSignature(line)
+ if(oSig ~= nil) then
+ io.stderr:write("Chords: output signature detected: "..oSig .."\n")
+ chTr = ChordsTr(iSig, oSig)
+ end
+ end
+ end
+ inputFile:close()
+ outputFile:close()
+
+ return outputBaseName
+end
+
+--
+-- Make pmxab process.
+-- param baseName input file name without .pmx suffix
+-- param outputBaseName transposed pmx file name without .pmx suffix
+--
+function pmxabProcess(baseName, outputBaseName)
+ --
+ -- call pmxab to generate .tex file
+ --
+ local pmxResCode = os.execute(PMX_CMD .. " " .. outputBaseName )
+ if (pmxResCode ~= 0 ) then
+ io.stderr:write("PMX process fail! "..outputBaseName .."\n")
+ os.exit(pmxResCode)
+ end
+
+ os.rename(outputBaseName..".tex", baseName..".tex")
+
+ -- remove temporary files
+ os.remove(outputBaseName..".pmx")
+ os.remove(outputBaseName..".pml")
+ os.remove("pmxaerr.dat")
+end
+
+narg = 1
+onlyTranspose = false
+
+repeat
+ this_arg = arg[narg]
+ if this_arg == "-v" then
+ os.exit(0)
+ elseif this_arg == "-h" then
+ usage()
+ os.exit(0)
+ elseif this_arg == "-s" then
+ onlyTranspose = true
+ else
+ local baseName = getBaseFileName(this_arg)
+ local outputBaseName = makeChordsTransposition(baseName)
+
+ if (not onlyTranspose) then
+ pmxabProcess(baseName, outputBaseName)
+ end
+ end
+
+ narg = narg + 1
+until narg > #arg