summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/pmxchords
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2015-12-31 22:39:54 +0000
committerKarl Berry <karl@freefriends.org>2015-12-31 22:39:54 +0000
commit36b38c720ee0922b0bb81f4e094978a899bcf0ca (patch)
tree6f9da1d0204a17be08b011098204b065eb5c6572 /Master/texmf-dist/scripts/pmxchords
parent6d1d56a11a1ad5479f3b834f00d94693b8aaeb6e (diff)
pmxchords (31dec15)
git-svn-id: svn://tug.org/texlive/trunk@39249 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts/pmxchords')
-rw-r--r--Master/texmf-dist/scripts/pmxchords/ChordsTr.lua148
-rwxr-xr-xMaster/texmf-dist/scripts/pmxchords/pmxchords.lua279
2 files changed, 233 insertions, 194 deletions
diff --git a/Master/texmf-dist/scripts/pmxchords/ChordsTr.lua b/Master/texmf-dist/scripts/pmxchords/ChordsTr.lua
index e58ff11424a..737c9ce6422 100644
--- a/Master/texmf-dist/scripts/pmxchords/ChordsTr.lua
+++ b/Master/texmf-dist/scripts/pmxchords/ChordsTr.lua
@@ -1,38 +1,38 @@
--[[
(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 = {} -- 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,
- })
+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"
+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"
}
--
@@ -41,9 +41,9 @@ ChordsTr.BASE_CHORDS_ARR= { -- lua is indexing from 1 I need from 0 ...
-- 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
+ local self = setmetatable({}, ChordsTr)
+ self.trMap = ChordsTr.__createTransposeMap(oSig - iSig)
+ return self
end
--
@@ -52,21 +52,21 @@ end
-- 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
+ 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
--
@@ -74,50 +74,50 @@ end
-- 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
+function ChordsTr:lineTranspose(line)
+ local pos = 0;
+ local trLine = "" -- transposed line (result)
+ while true do
+ local i = line:find(ChordsTr.CHORDS_BEGIN, pos)
+ if i == nil then
+ trLine = trLine .. line:sub(pos)
+ break
+ end
+ i = i + 3 -- move after \ch.
+ trLine = trLine .. line:sub(pos, i) -- append non chord string into result
+ pos = line:find(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
+ local chord = line:sub(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
+ 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
+ if (chord.len == 1) then
+ return chord, ""
+ end
+ local secondChar = chord:sub(2, 2)
+ if (secondChar == 's' or secondChar == 'f') then
+ return chord:sub(1, 2), chord:sub(3)
+ else
+ return chord:sub(1, 1), chord:sub(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
index 1539e90a48a..58179a355a9 100755
--- a/Master/texmf-dist/scripts/pmxchords/pmxchords.lua
+++ b/Master/texmf-dist/scripts/pmxchords/pmxchords.lua
@@ -1,10 +1,10 @@
-#!/usr/bin/env texlua
+#! /usr/bin/env texlua
--
-- global constants
--
-VERSION = "0.9.2"
-FILE_SUFFIX="_chtr"
-PMX_CMD="pmxab"
+VERSION = "0.9.3"
+FILE_SUFFIX = "_chtr"
+PMX_CMD = "pmxab"
--[[
pmxchords.lua: transpose chords (\ch.C.\) and process pmxab
@@ -30,9 +30,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
--[[
ChangeLog:
+ version 0.9.3 2014-04-21 - fixed transposition problem:
+ If song began in E-minor and signature is changed in half of song to A-minor
+ transposition must be omitted.
version 0.9.2 2013-12-13 - fixed: stop processing when pmxab fail.
- - Do not remove file pmxaerr.dat.
+ - When pmxab is called generated file pmxaerr.dat is not removed.
version 0.9.1 2013-12-09 - added some options. Improved processing.
@@ -40,60 +43,89 @@ with this program; if not, write to the Free Software Foundation, Inc.,
--]]
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 fist step. e.g. generate only transposed basename"..FILE_SUFFIX..".pmx file")
+ 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 fist step. e.g. generate only transposed basename" .. FILE_SUFFIX .. ".pmx file")
end
-function whoami ()
- print("This is pmxchords.lua version ".. VERSION)
+function whoami()
+ print("This is pmxchords.lua version " .. VERSION)
end
whoami()
if #arg == 0 then
- usage()
- os.exit(0)
+ usage()
+ os.exit(0)
end
kpse.set_program_name("luatex")
-require "ChordsTr"
+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)
+ -- 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)
+ -- 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
+
+--
+-- Strip comments from line
+-- Comments begin with % character
+--
+function lineWithoutComment(line)
+ local i = string.find(line, "%%")
+ if (i == nil) then
+ return line
+ end
+ return line:sub(0, i - 1)
+end
+
+--
+-- Function checks only if the line contains \ch. string.
+-- It does not check correctly if notes already started. It checks only if chords started..
+-- Scenario bellow will fail!
+-- d44 f a r / % first line does not contain chords symbol
+-- % signature is changed
+-- K+0+0
+-- \ch.C.\ c44 e g r4 /
+--
+function checkChordsAlreadyStarted(line)
+ local i = string.find(lineWithoutComment(line), ChordsTr.CHORDS_BEGIN)
+ if (i ~= nil) then
+ return true
+ end
+ return false;
end
function handleErr(msg)
- io.stderr:write(msg.."\n")
- os.exit(2)
+ 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
+ if fileName ~= "" and string.sub(fileName, -4, -1) == ".pmx" then
+ return string.sub(fileName, 1, -5)
+ else
+ return fileName
+ end
end
--
@@ -103,50 +135,57 @@ end
-- 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
+ 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
+
+ -- If song began in E-minor and signature is changed in half of song to A-minor
+ -- transposition must be omitted.
+ local chordsAlreadyStarted = false;
+
+ 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 and not chordsAlreadyStarted) then
+ local oSig = parseOutputSignature(line)
+ if (oSig ~= nil) then
+ io.stderr:write("Chords: output signature detected: " .. oSig .. "\n")
+ chTr = ChordsTr(iSig, oSig)
+ elseif (checkChordsAlreadyStarted(line)) then
+ io.stderr:write("Chords: notes already started. Chords transposition is omitted.\n")
+ chordsAlreadyStarted = true;
+ end
+ end
+ end
+ inputFile:close()
+ outputFile:close()
+
+ return outputBaseName
end
--
@@ -155,51 +194,51 @@ end
-- param outputBaseName transposed pmx file name without .pmx suffix
--
function pmxabProcess(baseName, outputBaseName)
- --
- -- call pmxab to generate .tex file
- --
- os.execute(PMX_CMD .. " " .. outputBaseName )
- -- check error
- local pmxaerr = io.open("pmxaerr.dat", "r")
- if (not pmxaerr) then
- handleErr("No log file.")
- end
- linebuf = pmxaerr:read()
- err = tonumber(linebuf)
- pmxaerr:close()
- if (err ~= 0 ) then
- handleErr("PMX process fail! "..outputBaseName..".pmx")
- end
-
- os.rename(outputBaseName..".tex", baseName..".tex")
-
- -- remove temporary files
- os.remove(outputBaseName..".pmx")
- os.remove(outputBaseName..".pml")
+ --
+ -- call pmxab to generate .tex file
+ --
+ os.execute(PMX_CMD .. " " .. outputBaseName)
+ -- check error
+ local pmxaerr = io.open("pmxaerr.dat", "r")
+ if (not pmxaerr) then
+ handleErr("No log file.")
+ end
+ local linebuf = pmxaerr:read()
+ local err = tonumber(linebuf)
+ pmxaerr:close()
+ if (err ~= 0) then
+ handleErr("PMX process fail! " .. outputBaseName .. ".pmx")
+ end
+
+ os.rename(outputBaseName .. ".tex", baseName .. ".tex")
+
+ -- remove temporary files
+ os.remove(outputBaseName .. ".pmx")
+ os.remove(outputBaseName .. ".pml")
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 (onlyTranspose) then
- os.exit(0)
- end
- pmxabProcess(baseName, outputBaseName)
- end
-
- narg = narg + 1
+ local 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 (onlyTranspose) then
+ os.exit(0)
+ end
+ pmxabProcess(baseName, outputBaseName)
+ end
+
+ narg = narg + 1
until narg > #arg