我想写一个脚本,接收来自剪贴板的文本输入,它将来自带有和弦的歌曲抒情片。该函数的目标是在将和弦名称上下移动半步后,将文本返回到剪贴板。如果解决方案是使用shell命令,我仍然可以将其包装在AppleScript中。我很难对转置函数本身概念化一个好的、可靠的方法。
转换下来,任何"C“和弦都会变成"B”和弦。一个"F#“将变成和"F”。一个"Ab“会变成"G”等等。如果函数只转下来或向上转,会很好,因为它可以循环,但如果它能走任何一条路,那就太好了。下面是一个文本的示例,其中包含了我能想到的尽可能多的变体:
C F G
La la is a line of lyrics with simple chords
C B7 Ab F#
La la some chords have flats and sharps
C Abm Fm
La la other lines have minor chords
F#sus Fmj7 B5 Gsus2 Gm7
La la but chords can can't kinda funky
Cdim Daug F+ G2
Doo wop with many short suffixed annotations
C/F Am/G B7/G
and any can have a slash followed by a bass note.关于和弦表格式的注释:
和弦的名字是在歌词线上给出的。*诗句等由一个额外的断线隔开。
当然,其中一个问题与顺序更改有关,而不是更改已经更改的和弦名称。
我们只需看一行三个空格的线,就可以用和弦来隔离这些线。在这些行中,只需要查看大写字母(和b& #)。
我发现这里有人在做chord (PHP弦转置器),但是它使用的是内联chord表示法,而且我也不会说PHP。
下面是我现在正在工作的代码。它有很多重复,所以不是很有效。还有比这更好的方法吗?
property chordList : {"A#", "Bb", "C#", "Db", "D#", "Eb", "F#", "Gb", "G#", "Ab", "A", "B", "C", "D", "E", "F", "G"}
property codeList : {"©12", "©13", "©16", "©17", "©19", "©20", "©23", "©24", "©26", "©27", "©11", "©14", "©15", "©18", "©21", "©22", "©25"}
property loweredList : {"A", "A", "C", "C", "D", "D", "F", "F", "G", "G", "Ab", "Bb", "B", "Db", "Eb", "E", "Gb"}
property raisedList : {"B", "B", "D", "D", "E", "E", "G", "G", "A", "A", "A#", "C", "C#", "D#", "F", "F#", "G#"}
set theString to the clipboard
set transposeUp to false -- true transposes up, false shifts down
set newString to transposeChords(theString, transposeUp)
set the clipboard to newString
on transposeChords(musicString, shiftUp)
if shiftUp then
set changeList to raisedList
else
set changeList to loweredList
end if
set otid to AppleScript's text item delimiters
considering case
set transposedString to ""
repeat with p from 1 to (count paragraphs in musicString)
set thisLine to paragraph p of musicString
if (thisLine contains " ") and (thisLine does not contain "t") then
-- change all chord names to a ©11, ©12, etc. code
repeat with c from 1 to (count chordList)
set thisLine to replaceString((item c of chordList), (item c of codeList), thisLine)
end repeat
-- change all codes to the shifted counterpart
repeat with c from 1 to (count codeList)
set thisLine to replaceString((item c of codeList), (item c of changeList), thisLine)
end repeat
set newLine to thisLine
else
set newLine to thisLine
end if
set transposedString to transposedString & newLine & return
end repeat
return transposedString
end considering
set AppleScript's text item delimiters to otid
end transposeChords
on replaceString(toFind, replaceWith, aString)
set AppleScript's text item delimiters to toFind
set aString to text items of aString
set AppleScript's text item delimiters to replaceWith
set aString to aString as string
end replaceString发布于 2019-08-20 15:19:47
在工作了几天之后,我想出了一些可以工作的代码。它循环遍历匹配三个空格的段落,然后查找/替换每个chord名称,每次一次,首先将它们更改为代码,然后再更改为移位的chord。它不是超级健壮,因为它使用数组和重复循环通过它们来改变和弦。这是很好的想法,因为歌曲单张不是很大。不过,如果可能的话,正则表达式的变化会更加强劲。
property chordList : {"A#", "Bb", "C#", "Db", "D#", "Eb", "F#", "Gb", "G#", "Ab", "A", "B", "C", "D", "E", "F", "G"}
property codeList : {"©12", "©13", "©16", "©17", "©19", "©20", "©23", "©24", "©26", "©27", "©11", "©14", "©15", "©18", "©21", "©22", "©25"}
property loweredList : {"A", "A", "C", "C", "D", "D", "F", "F", "G", "G", "Ab", "Bb", "B", "Db", "Eb", "E", "Gb"}
property raisedList : {"B", "B", "D", "D", "E", "E", "G", "G", "A", "A", "A#", "C", "C#", "D#", "F", "F#", "G#"}
set theString to the clipboard
set transposeUp to false -- true transposes up, false shifts down
set newString to transposeChords(theString, transposeUp)
set the clipboard to newString
on transposeChords(musicString, shiftUp)
if shiftUp then
set changeList to raisedList
else
set changeList to loweredList
end if
set otid to AppleScript's text item delimiters
considering case
set transposedString to ""
repeat with p from 1 to (count paragraphs in musicString)
set thisLine to paragraph p of musicString
if (thisLine contains " ") and (thisLine does not contain "t") then
-- change all chord names to a ©11, ©12, etc. code
repeat with c from 1 to (count chordList)
set thisLine to replaceString((item c of chordList), (item c of codeList), thisLine)
end repeat
-- change all codes to the shifted counterpart
repeat with c from 1 to (count codeList)
set thisLine to replaceString((item c of codeList), (item c of changeList), thisLine)
end repeat
set newLine to thisLine
else
set newLine to thisLine
end if
set transposedString to transposedString & newLine & return
end repeat
return transposedString
end considering
set AppleScript's text item delimiters to otid
end transposeChords
on replaceString(toFind, replaceWith, aString)
set AppleScript's text item delimiters to toFind
set aString to text items of aString
set AppleScript's text item delimiters to replaceWith
set aString to aString as string
end replaceStringhttps://codereview.stackexchange.com/questions/226562
复制相似问题