1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
\LeadsheetsExplLibrary{transposing}{2014/08/10 transposing of chord symbols}
\prop_new:N \l__leadsheets_pitches_prop
\prop_new:N \l__leadsheets_prefer_key_prop
\seq_new:N \l__leadsheets_sharps_seq
\seq_new:N \l__leadsheets_flats_seq
\cs_new_protected:Npn \leadsheets_define_key:nnn #1#2#3
{
\seq_new:c {g__leadsheets_key_#1_#2_seq}
\prop_new:c {g__leadsheets_key_#1_#2_prop}
\seq_gset_from_clist:cn {g__leadsheets_key_#1_#2_seq} {#3}
}
% pitches:
\prop_put:Nnn \l__leadsheets_pitches_prop {C} {0}
\prop_put:Nnn \l__leadsheets_pitches_prop {Cma} {0}
\prop_put:Nnn \l__leadsheets_pitches_prop {Ami} {0}
\prop_put:Nnn \l__leadsheets_pitches_prop {C#} {1}
\prop_put:Nnn \l__leadsheets_pitches_prop {C#ma} {1}
\prop_put:Nnn \l__leadsheets_pitches_prop {A#mi} {1}
\prop_put:Nnn \l__leadsheets_pitches_prop {Db} {1}
\prop_put:Nnn \l__leadsheets_pitches_prop {Dbma} {1}
\prop_put:Nnn \l__leadsheets_pitches_prop {Bbmi} {1}
\prop_put:Nnn \l__leadsheets_pitches_prop {D} {2}
\prop_put:Nnn \l__leadsheets_pitches_prop {Dma} {2}
\prop_put:Nnn \l__leadsheets_pitches_prop {Bmi} {2}
\prop_put:Nnn \l__leadsheets_pitches_prop {D#} {3}
\prop_put:Nnn \l__leadsheets_pitches_prop {D#ma} {3}
\prop_put:Nnn \l__leadsheets_pitches_prop {F#mi} {3}
\prop_put:Nnn \l__leadsheets_pitches_prop {Eb} {3}
\prop_put:Nnn \l__leadsheets_pitches_prop {Ebma} {3}
\prop_put:Nnn \l__leadsheets_pitches_prop {Cmi} {3}
\prop_put:Nnn \l__leadsheets_pitches_prop {E} {4}
\prop_put:Nnn \l__leadsheets_pitches_prop {Ema} {4}
\prop_put:Nnn \l__leadsheets_pitches_prop {C#mi} {4}
\prop_put:Nnn \l__leadsheets_pitches_prop {Fb} {4}
\prop_put:Nnn \l__leadsheets_pitches_prop {Fbma} {4}
\prop_put:Nnn \l__leadsheets_pitches_prop {Dbmi} {4}
\prop_put:Nnn \l__leadsheets_pitches_prop {F} {5}
\prop_put:Nnn \l__leadsheets_pitches_prop {Fma} {5}
\prop_put:Nnn \l__leadsheets_pitches_prop {Dmi} {5}
\prop_put:Nnn \l__leadsheets_pitches_prop {F#} {6}
\prop_put:Nnn \l__leadsheets_pitches_prop {F#ma} {6}
\prop_put:Nnn \l__leadsheets_pitches_prop {D#mi} {6}
\prop_put:Nnn \l__leadsheets_pitches_prop {Gb} {6}
\prop_put:Nnn \l__leadsheets_pitches_prop {Gbma} {6}
\prop_put:Nnn \l__leadsheets_pitches_prop {Ebmi} {6}
\prop_put:Nnn \l__leadsheets_pitches_prop {G} {7}
\prop_put:Nnn \l__leadsheets_pitches_prop {Gma} {7}
\prop_put:Nnn \l__leadsheets_pitches_prop {Emi} {7}
\prop_put:Nnn \l__leadsheets_pitches_prop {G#} {8}
\prop_put:Nnn \l__leadsheets_pitches_prop {G#ma} {8}
\prop_put:Nnn \l__leadsheets_pitches_prop {E#mi} {8}
\prop_put:Nnn \l__leadsheets_pitches_prop {Ab} {8}
\prop_put:Nnn \l__leadsheets_pitches_prop {Abma} {8}
\prop_put:Nnn \l__leadsheets_pitches_prop {Fmi} {8}
\prop_put:Nnn \l__leadsheets_pitches_prop {A} {9}
\prop_put:Nnn \l__leadsheets_pitches_prop {Ama} {9}
\prop_put:Nnn \l__leadsheets_pitches_prop {F#mi} {9}
\prop_put:Nnn \l__leadsheets_pitches_prop {A#} {10}
\prop_put:Nnn \l__leadsheets_pitches_prop {A#ma} {10}
\prop_put:Nnn \l__leadsheets_pitches_prop {F##mi} {10}
\prop_put:Nnn \l__leadsheets_pitches_prop {Bb} {10}
\prop_put:Nnn \l__leadsheets_pitches_prop {Bbma} {10}
\prop_put:Nnn \l__leadsheets_pitches_prop {Gmi} {10}
\prop_put:Nnn \l__leadsheets_pitches_prop {B} {11}
\prop_put:Nnn \l__leadsheets_pitches_prop {Bma} {11}
\prop_put:Nnn \l__leadsheets_pitches_prop {G#mi} {11}
\seq_set_from_clist:Nn \l__leadsheets_sharps_seq
{C,Ami,G,Emi,D,Bmi,A,F#mi,E,C#mi,B,G#mi,F#,D#mi}
\seq_set_from_clist:Nn \l__leadsheets_flats_seq
{C,Ami,F,Dmi,Bb,Gmi,Eb,Cmi,Ab,Fmi,Db,Bbmi,Gb,Ebmi}
\prop_put:Nnn \l__leadsheets_prefer_key_prop {0} {sharp} % C
\prop_put:Nnn \l__leadsheets_prefer_key_prop {1} {flat} % Db
\prop_put:Nnn \l__leadsheets_prefer_key_prop {2} {sharp} % D
\prop_put:Nnn \l__leadsheets_prefer_key_prop {3} {flat} % Eb
\prop_put:Nnn \l__leadsheets_prefer_key_prop {4} {sharp} % E
\prop_put:Nnn \l__leadsheets_prefer_key_prop {5} {flat} % F
\prop_put:Nnn \l__leadsheets_prefer_key_prop {6} {sharp} % F#
\prop_put:Nnn \l__leadsheets_prefer_key_prop {7} {sharp} % G
\prop_put:Nnn \l__leadsheets_prefer_key_prop {8} {flat} % Ab
\prop_put:Nnn \l__leadsheets_prefer_key_prop {9} {sharp} % A
\prop_put:Nnn \l__leadsheets_prefer_key_prop {10} {flat} % Bb
\prop_put:Nnn \l__leadsheets_prefer_key_prop {11} {sharp} % B
\group_begin:
\char_set_catcode_other:N \#
\leadsheets_define_key:nnn {sharp} {0} {C, D, E, F, G, A, B} % C
\leadsheets_define_key:nnn {flat} {0} {C, D, E, F, G, A, B} % C
\leadsheets_define_key:nnn {sharp} {1} {C#, D#, E#, F#, G#, A#, B#} % C#
\leadsheets_define_key:nnn {flat} {1} {Db, Eb, F, Gb, Ab, Bb, C} % Db
\leadsheets_define_key:nnn {sharp} {2} {D, E, F#, G, A, B, C#} % D
\leadsheets_define_key:nnn {flat} {2} {Ebb,Fb, Gb, Abb,Bbb,Cb, Db} % Ebb
\leadsheets_define_key:nnn {sharp} {3} {D#, E#, F##,G#, A#, B#, C##}% Eb
\leadsheets_define_key:nnn {flat} {3} {Eb, F, G, Ab, Bb, C, D} % Eb
\leadsheets_define_key:nnn {sharp} {4} {E, F#, G#, A, B, C#, D#} % E
\leadsheets_define_key:nnn {flat} {4} {Fb, Gb, Ab, Bbb,Cb, Db, Eb} % Fb
\leadsheets_define_key:nnn {sharp} {5} {E#, F##,G##,A#, B#, C##,D##}% E#
\leadsheets_define_key:nnn {flat} {5} {F, G, A, Bb, C, D, E} % F
\leadsheets_define_key:nnn {sharp} {6} {F#, G#, A#, B, C#, D#, E#} % F#
\leadsheets_define_key:nnn {flat} {6} {Gb, Ab, Bb, Cb, Db, Eb, F} % Gb
\leadsheets_define_key:nnn {sharp} {7} {G, A, B, C, D, E, F#} % G
\leadsheets_define_key:nnn {flat} {7} {Abb,Bbb,Cb, Dbb,Ebb,Fb, Gb} % Abb
\leadsheets_define_key:nnn {sharp} {8} {G#, A#, B#, C#, D#, E#, F##}% G#
\leadsheets_define_key:nnn {flat} {8} {Ab, Bb, C, Db, Eb, F, G} % Ab
\leadsheets_define_key:nnn {sharp} {9} {A, B, C#, D, E, F#, G#} % A
\leadsheets_define_key:nnn {flat} {9} {Bbb,Cb, Db, Ebb,Fb, Gb, Ab} % Bbb
\leadsheets_define_key:nnn {sharp} {10} {A#, B#, C##,D#, E#, F##,G##}% A#
\leadsheets_define_key:nnn {flat} {10} {Bb, C, D, Eb, F, G, A} % Bb
\leadsheets_define_key:nnn {sharp} {11} {B, C#, D#, E, F#, G#, A#} % B
\leadsheets_define_key:nnn {flat} {11} {Cb, Db, Eb, Fb, Gb, Ab, Bb} % Cb
\group_end:
% #1: key
% #2: semitone steps
% #3: chord
\cs_new_protected:Npn \leadsheets_transpose:nnN #1#2#3
{
\int_set:Nn \l__leadsheets_tmpa_int {0}
% \l__leadsheets_tmpa_int holds the C pitch
\seq_if_in:NnTF \l__leadsheets_sharps_seq {#1}
{ \tl_set:Nn \l__leadsheets_tmpa_tl {sharp} }
{ \tl_set:Nn \l__leadsheets_tmpa_tl {flat} }
% \l__leadsheets_tmpa_tl holds the `sharp' or `flat' preference
\int_set:Nn \l__leadsheets_tmpb_int {#2}
\int_while_do:nNnn { \l__leadsheets_tmpb_int } < { 0 }
{ \int_set:Nn \l__leadsheets_tmpb_int { \l__leadsheets_tmpb_int + 12 } }
% \l__leadsheets_tmpb_int holds the new pitch number relatice to C
\bool_if:NTF \l__leadsheets_enharmonic_bool
{ \tl_set_eq:NN \l__leadsheets_tmpb_tl \l__leadsheets_enharmonic_tl }
{
\tl_set:Nx \l__leadsheets_tmpb_tl
{
\prop_item:NV
\l__leadsheets_prefer_key_prop
\l__leadsheets_tmpb_int
}
}
% \l__leadsheets_tmpb_tl holds the `sharp' or `flat' preference
% of the new key
\seq_set_split:NnV \l__leadsheets_tmpa_seq {/} #3
\tl_clear:N #3
\seq_clear:N \l__leadsheets_tmpb_seq
\seq_map_inline:Nn \l__leadsheets_tmpa_seq
{
\tl_set:Nn \l__leadsheets_tmpc_tl {##1} % the chord
\int_zero:N \l__leadsheets_tmpc_int
\int_zero:N \l__leadsheets_tmpc_int
\seq_map_inline:cn
{
g__leadsheets_key_
\l__leadsheets_tmpb_tl _
\int_to_arabic:V \l__leadsheets_tmpa_int
_seq
}
{
\int_incr:N \l__leadsheets_tmpc_int
\tl_if_in:NnT \l__leadsheets_tmpc_tl {####1}
{
\tl_set:Nx \l__leadsheets_tmpd_tl
{
\seq_item:cV
{
g__leadsheets_key_
\l__leadsheets_tmpb_tl _
\int_to_arabic:V \l__leadsheets_tmpb_int
_seq
}
\l__leadsheets_tmpc_int
}
\tl_replace_once:NnV \l__leadsheets_tmpc_tl
{####1}
\l__leadsheets_tmpd_tl
\seq_map_break:
}
}
\seq_put_right:NV \l__leadsheets_tmpb_seq \l__leadsheets_tmpc_tl
}
\tl_set:Nx #3 { \seq_use:Nn \l__leadsheets_tmpb_seq {/} }
}
\cs_generate_variant:Nn \leadsheets_transpose:nnN { xV }
\keys_define:nn {leadsheets}
{
transpose .code:n =
\bool_set_true:N \l__leadsheets_transpose_bool
\int_set:Nn \l__leadsheets_transpose_steps_int {#1} ,
transpose-capo .bool_set:N = \l__leadsheets_transpose_capo_bool ,
enharmonic .choices:nn =
{ sharp , flat }
{
\tl_set_eq:NN \l__leadsheets_enharmonic_tl \l_keys_choice_tl
\bool_set_true:N \l__leadsheets_enharmonic_bool
}
}
\endinput
|