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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
|
%\iffalse
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% musixcrd - typsetting chord symbols with %%
%% musixtex %%
%% main source file contains code, doc, and examples %%
%% $Id$ %%
%% copyright 2004 , Robert Hennig %%
%% this code is licensed in terms of the %%
%% GNU Public License %%
%% %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\fi
\ifx\makeatletter\undefined\def\makeatletter{\catcode`\@=11\relax}\fi
\ifx\makeatother\undefined\def\makeatother{\catcode`\@=12\relax}\fi
\makeatletter% ^^A allows to use @ as ordinary letter
%
% \def\backslash{\tt\char'134}
% \def\musixtex{MusiX\TeX}
% \def\musixcrd{MusixCrd}
% \def\crdexample#1{{\tt\backslash c #1 }$\rightarrow$ \c #1 \medskip}
% \def\pmx{PMX}
% \title{
% {\bf \musixcrd} \\
% --- Typesetting Chord Symbols with \musixtex --- \\
% Version 1.1 \\
% {\large $Revision$}}
%
% \author{Robert Hennig\thanks{robert.hennig@freylax.de}}
% \maketitle
% \tableofcontents
%
% \section{Usage}
% This package was written to ease the typesetting of chord symbols
% for music scores.
% One point of focus was that the user should have not to much to type
% if placing the cord. So one macro will be used which takes characters
% as argument which describe the chord to type. \par
% Thought the syntax of the chord description could easily be altered they
% should become somewhat stable whereas the output format can be adapted to
% individual needs.
% Further the notenames can be transposed, so transposing a music piece
% with chord symbols can be done easily. \par
% The package can be used with \musixtex\ and \pmx\
% -- which also gave the idea for the usage of an short chord--description
% `language'.
% \footnote{If the default output functions are changed the package could
% also be used with \TeX{} and \LaTeX{} alone.}
% \par
%
% \DescribeMacro{\c}
% The main macro which the package defines is
% \verb*|\c |\synt{chord-list}\verb*| |. The argument is an space
% terminated \synt{chord-list}
% \footnote{This form of argument was choosen because it leads to a
% short notation inside \pmx\ e.g.: \\
% {\tt \backslash c AfM \backslash\ e8 f g4 \backslash c Gm7 \backslash\ b4 g}
% }.
% \begin{demo}[w]{\musixtex}
% \nobarnumbers
% \startextract
% \NOtes\c CM7 \hu e\c Dm7 \hu f\en\bar
% \NOTEs\c Ch/E \hu g\c F6/A \hu h\en\bar
% \NOtes\c 0-1E7/G \hl i\c Fd/Af \hl j\en
% \endextract
% \end{demo}
%
% \subsection{Syntax}
% \begin{grammar}
% <empty> ::= `'
%
% <digit> ::= `0' | `1' | `2' | `3' | `4' | `5' | `6' | `7' | `8' | `9'
%
% <number> ::= <digit> | `-' <digit>
%
% <vertical-shift> ::= <number> | <empty>
%
% <horizontal-shift> ::= <number> | <empty>
%
% <note-base-name> ::= `C' | `D' | `E' | `F' | `G' | `A' | `B'
%
% <accidental> ::= `s' | `f' | `ds' | `df'
%
% <note-name> ::= <empty> | <note-base-name>
% | <note-base-name> <accidental>
%
% <chord-qualifier> ::=
% `m' | `d' | `h' | `M' | `4' | `+5' | `-5' | `6' | `7' | `-9' | `+9'
%
% <chord-qualifier-list> ::= <empty>
% | <chord-qualifier> <chord-qualifier-list>
%
% <begin-bass-note> ::= <empty> | `/'
%
% <chord> ::= <vertical-shift> <horizontal-shift> \\
% <note-name> <chord-qualifier-list> \\
% <begin-bass-note> <note-name> <chord-qualifier-list>
%
% <chord-list> ::= <chord-list> `,' <chord-list> | <chord> | <empty>
% \end{grammar}
%
%
% \subsection{Semantics}
% \paragraph{\synt{vertical-shift}}
% \DescribeMacro{\crddefaultheight}
% Adjustment of the vertical chord position in internotes,
% relative to the default value defined with
% \verb*|\crddefaultheight|. You may change this default within
% your sheet.
% \begin{macrocode}
\def\crddefaultheight{10}
% \end{macrocode}
% \paragraph{\synt{horizontal-shift}}
% Horizontal adjustment in multiples of \verb*|\elemskip|.
%
% \paragraph{\synt{accidental}}
% Allowed accidentals are: sharp, flat, double-sharp, double-flat.
%
% \paragraph{\synt{note-name}}
% \DescribeMacro{\crdtranspose}
% The given note names are transposed by the number of quint steps
% given in \verb*|\crdtranspose|. You may change this value within
% your sheet.
% \begin{macrocode}
\def\crdtranspose{0}
% \end{macrocode}
% \paragraph{\synt{chord-qualifier}}
% Currently known qualifiers are:
% \begin{description}
% \item[m] minor
% \item[d] diminished
% \item[h] half-diminished
% \item[M] major
% \item[4] suspended fourth
% \item[+5] augmented fifth
% \item[-5] diminished fifth
% \item[6] 6th
% \item[7] 7th
% \item[9] 9th
% \item[-9] diminished 9th
% \item[+9] augmented 9th
% \end{description}
% Note that the syntax is independent of the visualization
% of the qualifier so different chord styles could be applied.
%
% \paragraph{\synt{begin-bass-note}}
% Use the `/' symbol to skip the \synt{note-name} and
% \synt{chord-qualifier-list} to allow the notation of
% bass-notes without chord-notes.
%
% \paragraph{\synt{chord-list}}
% With `,' separated chords are spread evenly
% within one bar. Use this notation if the horizontal positions
% of the chords do not line up with the notes.
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Implementation}
% \subsection{Input Guard}
% To prevent repeated defenition of the main macros
% we end the inclusion of this file if we already now
% about our macros.
% \begin{macrocode}
\ifx\crd@parser\undefined\else\makeatother\endinput\fi%
% \end{macrocode}
% \subsection{List Macros}
% For the parsing of the chord description some macros are needed which
% can do simple string operations. \medskip \\
% \DescribeMacro{\crd@append}
% \syntax{"\\crd@append"<tokens-a>"\\to"<tokens-b>}\\
% Append \synt{tokens-a} to \synt{tokens-b}.
% \begin{macrocode}
\def\crd@append#1\to#2{%
\toks0=\expandafter{#1}\toks2=\expandafter{#2}%
\edef#2{\the\toks2 \the\toks0}}
% \end{macrocode}
% \DescribeMacro{\crd@prepend}
% \syntax{"\\crd@prepend"<tokens-a>"\\by"<tokens-b>}\\
% Prepend \synt{tokens-a} by \synt{tokens-b}.
% \begin{macrocode}
\def\crd@prepend#1\by#2{%
\toks0=\expandafter{#1}\toks2=\expandafter{#2}%
\edef#1{\the\toks2 \the\toks0}}
% \end{macrocode}
% \DescribeMacro{\crd@movetoken}
% \syntax{"\\crd@movetoken"<tokens-a>"\\to"<tokens-b>}\\
% Move the first token of \synt{tokens-a} to the front of
% \synt{tokens-b}.
% \begin{macrocode}
\def\crd@movetoken#1\to#2{%
\ifx#1\empty\else\expandafter\crd@moveoff#1\crd@moveoff#1#2\fi}%
\def\crd@moveoff#1#2\crd@moveoff#3#4{\def#3{#2}\crd@prepend#4\by#1}
% \end{macrocode}
% \begin{demo}[w]{test}
% \makeatletter
% \def\l{oo} (\l) %
% \crd@append{ns}\to\l append:(\l) %
% \crd@prepend\l\by{sp} prepend:(\l)\\%
% \def\swap#1#2{(#1,#2) %
% \ifx#1\empty\else\crd@movetoken#1\to#2\swap#1#2\fi}
% \def\r{} movetoken:\\ \swap\l\r
% \makeatother
% \end{demo}
%
% \subsection{Parsing}
% To describe the syntatic items which exists for a distinct semantic
% a \synt{syntax-table} is used.
% For each item exists a coresponding macro which will be executed
% if it name matches. The name of the item consists of the
% \synt{syntax-table} name and the \emph{reverse} syntax of this item. \par
%
% \DescribeMacro{\crd@parse}
% The \syntax{"\\crd@parse"<tokens>"\\for"<syntax-table>} macro is used
% to test if the first part of \synt{tokens} has matches for the longest
% possible item described in \synt{syntax-table}.
% If an item matched its macro will be expanded and
% and the tokens of the item are cut of from the given \synt{tokens}.
% \DescribeMacro{\crd@parsematched}
% The conditional \verb|\crd@parsematched| is true if an item matched and
% false otherwise.
%
% \begin{macrocode}
\newif\ifcrd@parsematched% true if parse matched
\newcount\crd@parsedepth% internal register
\def\crd@parse#1\for#2{% parse tokens #1 for occurence of items of table #2
\crd@parsedepth=1 % default if not defined
\expandafter\ifx\csname#2depth\endcsname\relax\else%
\crd@parsedepth=\csname#2depth\endcsname%
\fi%
\def\stack{}%\def\crd@parseresult{}
\crd@parsematchedfalse% initialisation
\crd@parser#1\for#2% call the recursive part
}
\def\crd@parser#1\for#2{% recursive part of parser
\ifx#1\empty\else% is list filled ?
\ifnum\crd@parsedepth>0 % and do we have to read more chars into stack
\advance\crd@parsedepth by-1 %
\crd@movetoken#1\to\stack%
\crd@parser#1\for#2% recursive call
\ifcrd@parsematched\else% if still not matched
\expandafter\ifx\csname#2\stack\endcsname\relax% does item match
\crd@movetoken\stack\to#1% no match, put char back to source
\else% match
\csname#2\stack\endcsname%
\crd@parsematchedtrue% signal success
\fi%
\fi%
\fi%
\fi%
}
% \end{macrocode}
% For an example suppose that we want to express the
% semantic \synt{bool} by the following grammar:
% \begin{grammar}
% <bool> ::= `y' | `n' | `yes' | `no'
% \end{grammar}
%
% \begin{demo}[w]{bool}
% \def\bool{bool} % syntax-table with name `bool'
% \def\booldepth{3} % max length of text to looking for is 3
% \def\booly{true}
% \def\booln{false}
% \def\boolsey{true*} % reverse syntax !!!
% \def\boolon{false*} % reverse syntax !!!
% \makeatletter
% \def\p#1{ (#1) \crd@parse#1\for\bool : (#1)\\}
% \makeatother
% \def\l{nonyyestest} \p\l\p\l\p\l\p\l\p\l
% \end{demo}
%
%
% \subsection{Chord parsing}
% \subsubsection{Vertical and Horizontal shifting}
% \begin{macrocode}
\newcount\crd@vshift%
\newcount\crd@hshift%
\def\crd@number{crd@number}%
\def\crd@numberdepth{2}%
\expandafter\def\csname\crd@number0\endcsname{\crd@numberval=0 }%
\expandafter\def\csname\crd@number1\endcsname{\crd@numberval=1 }%
\expandafter\def\csname\crd@number2\endcsname{\crd@numberval=2 }%
\expandafter\def\csname\crd@number3\endcsname{\crd@numberval=3 }%
\expandafter\def\csname\crd@number4\endcsname{\crd@numberval=4 }%
\expandafter\def\csname\crd@number5\endcsname{\crd@numberval=5 }%
\expandafter\def\csname\crd@number6\endcsname{\crd@numberval=6 }%
\expandafter\def\csname\crd@number7\endcsname{\crd@numberval=7 }%
\expandafter\def\csname\crd@number8\endcsname{\crd@numberval=8 }%
\expandafter\def\csname\crd@number9\endcsname{\crd@numberval=9 }%
\expandafter\def\csname\crd@number1-\endcsname{\crd@numberval=-1 }%
\expandafter\def\csname\crd@number2-\endcsname{\crd@numberval=-2 }%
\expandafter\def\csname\crd@number3-\endcsname{\crd@numberval=-3 }%
\expandafter\def\csname\crd@number4-\endcsname{\crd@numberval=-4 }%
\expandafter\def\csname\crd@number5-\endcsname{\crd@numberval=-5 }%
\expandafter\def\csname\crd@number6-\endcsname{\crd@numberval=-6 }%
\expandafter\def\csname\crd@number7-\endcsname{\crd@numberval=-7 }%
\expandafter\def\csname\crd@number8-\endcsname{\crd@numberval=-8 }%
\expandafter\def\csname\crd@number9-\endcsname{\crd@numberval=-9 }%
\def\crd@bracketinit{%
\def\crd@bracketopen{}%
\def\crd@bracketclose{}%
}
\def\crd@bracket{crd@bracket}%
\def\crd@bracketdepth{1}%
\expandafter\def\csname\crd@bracket(\endcsname{%
\crd@append(\to\crd@bracketopen}%
\expandafter\def\csname\crd@bracket)\endcsname{%
\crd@append)\to\crd@bracketclose}%
% \end{macrocode}
% \subsubsection{Notes and Accidentals}
% \paragraph{Syntax}
% In order to allow transposition of notes we use the circle of fifth
% for representing notes.
% \DescribeMacro{\crd@quintval}
% The syntax table \verb|\crd@quintval| contains the mapping from note
% names to the note position in the circle of fifth. \\
% \DescribeMacro{\crd@quint}
% The count register \verb|\crd@quint| is used to receive the result.
% \begin{macrocode}
\newcount\crd@quint% register used to represent notes in the circle of
\def\crd@quintval{crd@quintval}%
\def\crd@quintvalA{\crd@quint=3 }% A
\def\crd@quintvalB{\crd@quint=5 }% B
\def\crd@quintvalC{\crd@quint=0 }% C
\def\crd@quintvalD{\crd@quint=2 }% D
\def\crd@quintvalE{\crd@quint=4 }% E
\def\crd@quintvalF{\crd@quint=-1 }% F
\def\crd@quintvalG{\crd@quint=1 }% G
% \end{macrocode}
% \DescribeMacro{\crd@quintmod}
% The modification of the note position in the circle of fifth
% which is caused by the accidentals is coded in the
% \verb|\crd@quintmod| syntax table.
% \begin{macrocode}
\def\crd@quintmod{crd@quintmod}
\def\crd@quintmoddepth{2}
\def\crd@quintmods{\advance\crd@quint by7 }% sharp
\def\crd@quintmodf{\advance\crd@quint by-7 }% flat
\def\crd@quintmodsd{\advance\crd@quint by14 }% double sharp
\def\crd@quintmodfd{\advance\crd@quint by-14 }% double flat
% \end{macrocode}
% \paragraph{Notenames and accidental symbols}
% After transpositon and enharmonic adaption an reverse mapping
% from the circle of fifth to notenames and accidentals is needed.
% \DescribeMacro{\crd@note}
% The mapping from circle of fifth to notenames without accidentals
% is specified in the \verb|\crd@note| table.
% \DescribeMacro{\crd@notelow}\DescribeMacro{\crd@notehigh}
% In addition we need to now where the notes without accidentals
% start and end which is defined in \verb|\crd@notelow| and
% \verb|crd@notehigh|.
% \begin{macrocode}
\def\crd@note{crd@note}
\expandafter\def\csname\crd@note3\endcsname{A}
\expandafter\def\csname\crd@note5\endcsname{B}
\expandafter\def\csname\crd@note0\endcsname{C}
\expandafter\def\csname\crd@note2\endcsname{D}
\expandafter\def\csname\crd@note4\endcsname{E}
\expandafter\def\csname\crd@note-1\endcsname{F}
\expandafter\def\csname\crd@note1\endcsname{G}
\def\crd@notelow{-1} % lowest quint without accidental
\def\crd@notehigh{5} % highest quint without accidental
% \end{macrocode}
%
% \DescribeMacro{\crd@sharp}\DescribeMacro{\crd@flat}
% \DescribeMacro{\crd@doublesharp}\DescribeMacro{\crd@doubleflat}
% The following macros define the representation of the
% (default) accidentals.
% \begin{macrocode}
\def\crd@sharp{\sharp}
\def\crd@flat{\flat}
\def\crd@doublesharp{\sharp\sharp}
\def\crd@doubleflat{\flat\flat}
% \end{macrocode}
% \paragraph{Parsing}
% \DescribeMacro{\crd@input}
% The following functions read their input from \verb|\crd@input|.\\
% \DescribeMacro{\crd@parsenote}
% The \syntax{"\\crd@parsenote"<note><accidental>}
% macro parses the input \verb|\crd@input| and if note and
% accidental could be detected the transposed note position
% in the circle of fifth will be calculated, transposed and
% adapted using the \verb|\crd@enharmonic| macro.
% Then the position in the circle of fifth is calculated back
% to the \synt{note} and \synt{accidental} representation which
% is stored in the arguments.
% \begin{macrocode}
\def\crd@parsenote#1#2{% parse input results: #1
\def#1{}\def#2{}%
\crd@parse\crd@input\for\crd@quintval%
\ifcrd@parsematched% we got an valid note
\crd@parse\crd@input\for\crd@quintmod%
\advance\crd@quint by\crdtranspose \relax% transposition, space is needed!
\crd@enharmonic%
\ifnum\crd@quint>\crd@notehigh % sharps ?
\advance\crd@quint by-7 %
\ifnum\crd@quint>\crd@notehigh % double sharp ?
\advance\crd@quint by-7 %
\ifnum\crd@quint>\crd@notehigh % too much sharps !
\relax ERROR:too much sharps%
\else\edef#2{\crd@doublesharp}\fi%
\else\edef#2{\crd@sharp}\fi%
\fi%
\ifnum\crd@quint<\crd@notelow % flats ?
\advance\crd@quint by7 %
\ifnum\crd@quint<\crd@notelow % double flat ?
\advance\crd@quint by7 %
\ifnum\crd@quint<\crd@notelow % too much flats !
\relax ERROR:too much flats%
\else\edef#2{\crd@doubleflat}\fi%
\else\edef#2{\crd@flat}\fi%
\fi%
\expandafter\ifx\csname\crd@note\number\crd@quint\endcsname\relax%
ERROR:notename for (\number\crd@quint) is not defined.
\fi%
\edef#1{\csname\crd@note\number\crd@quint\endcsname}% set note
\fi%
}
% \end{macrocode}
%
%
% \DescribeMacro{\crd@enharmonic}
% To allow different enharmonic adaptions the \verb|\crd@enharmonic|
% macro is provided which default behaviour is to do nothing.
% \begin{macrocode}
\def\crd@enharmonic{}%
% \end{macrocode}
%
% \begin{demo}[w]{noteparsing}
% \makeatletter
% \def\parsenoter{\crd@parsenote\n\a%
% \ifx\n\empty\else{\crd@notetype\n\a}\parsenoter\fi}%
% \def\parsenotes#1{%
% \let\crd@flat=\crd@noteflat%
% \let\crd@sharp=\crd@notesharp%
% \def\crd@input{#1}\parsenoter}
% \makeatother
%
% \parsenotes{CDfDEfEFFsGAfAsB}
% \end{demo}
%
%
% \subsubsection{Chord Qualifiers}
% To cover a broad range of different styles for setting chord qualifiers
% the design is open for extensions. For the sake of demonstration and
% simple usability an default implementation is provided and discussed
% furtherwards. \\
% Suppose we want to distinguish 3 different kinds of qualifiers,
% some go down, some go up and alterations are put in brackets.
% \DescribeMacro{\crd@qualinit}
% We choose to use 3 lists (macros) to hold the parsing results.
% For initialisation of these lists the \verb|\crd@qualinit| macro
% has to be implemented.
% \begin{macrocode}
\def\crd@qualinit{%
\def\crd@lo{}% lower extensions
\def\crd@up{}% upper extensioins
\def\crd@alt{}% alterations
}
% \end{macrocode}
% \DescribeMacro{\crd@qual}
% Now the syntax table \verb|\crd@qual| has to be defined which fills
% the lists appropriatly.
% \begin{macrocode}
\def\crd@qual{crd@qual}%
\def\crd@qualdepth{2}
\def\crd@qualm{\crd@append{\crd@smalltype m}\to\crd@lo}% minor
\def\crd@qualM{\crd@append{\crd@capitaltype M}\to\crd@up}% major7
\expandafter\def\csname\crd@qual4\endcsname% 4
{\crd@append{\crd@numbertype4}\to\crd@lo}
\expandafter\def\csname\crd@qual5+\endcsname% aug. 5
{\crd@append{\crd@numbertype\crd@numbersharp5}\to\crd@alt}
\expandafter\def\csname\crd@qual5-\endcsname% dim. 5
{\crd@append{\crd@numbertype\crd@numberflat5}\to\crd@alt}
\expandafter\def\csname\crd@qual6\endcsname% 6
{\crd@append{\crd@numbertype6}\to\crd@up}
\expandafter\def\csname\crd@qual7\endcsname% dominant 7
{\crd@append{\crd@numbertype7}\to\crd@up}
\def\crd@quald{\crd@append{\crd@dim}\to\crd@up}% diminished
\def\crd@qualh{\crd@append{\crd@hdim}\to\crd@up}% half diminished
\expandafter\def\csname\crd@qual9-\endcsname% -9
{\crd@append{\crd@numbertype\crd@numberflat9}\to\crd@alt}
\expandafter\def\csname\crd@qual9+\endcsname% +9
{\crd@append{\crd@numbertype\crd@numbersharp9}\to\crd@alt}
% \end{macrocode}
%
% \begin{demo}[w]{qualparsing}
% \makeatletter
% \def\parsequal#1{\def\crd@input{#1}%
% \crd@qualinit%
% \loop\crd@parse\crd@input\for\crd@qual%
% \ifcrd@parsematched\repeat%
% (\crd@lo,\crd@up,\crd@alt)%
% }%
% \makeatother
%
% \parsequal{mMdh4+5-567-9+9}
% \end{demo}
%
% \subsubsection{Parsing the whole chord}
% We are now ready to parse the whole chord, consisting
% of chordnote, qualifiers and bassnote. However
% if one likes to set only a bassnote one needs to tell
% that there is no chord note to set. For this purpose
% the \DescribeMacro{\crd@skipcrdnote} \verb|\crd@skipcrdnote|
% syntax table defines the `/' item which does this skip.
% \begin{macrocode}
\def\crd@skipcrdnote{crd@skipcrdnote}
\expandafter\def\csname\crd@skipcrdnote/\endcsname{}
% \end{macrocode}
% \DescribeMacro{\crd@parsecrd}
%
% \begin{macrocode}
\def\crd@parsecrd{%
\crd@vshift=0 %
\let\crd@numberval=\crd@vshift%
\crd@parse\crd@input\for\crd@number%
\crd@hshift=0 %
\let\crd@numberval=\crd@hshift%
\crd@parse\crd@input\for\crd@number%
\crd@bracketinit%
\crd@parse\crd@input\for\crd@bracket%
\def\crd@crdnote{}% chord note
\def\crd@crdacc{}% chord note accidental
\def\crd@bassnote{}% bass note
\def\crd@bassacc{}% bass note accidental
\crd@qualinit% initialize qualifiers
\let\crd@flat=\crd@noteflat%
\let\crd@doubleflat=\crd@notedoubleflat%
\let\crd@sharp=\crd@notesharp%
\let\crd@doublesharp=\crd@notedoublesharp%
\crd@parsenote\crd@crdnote\crd@crdacc% read chord note
\loop\crd@parse\crd@input\for\crd@qual% read qualifiers
\ifcrd@parsematched\repeat%
\crd@parse\crd@input\for\crd@skipcrdnote% skip eventually
\let\crd@flat=\crd@bassflat%
\let\crd@doubleflat=\crd@bassdoubleflat%
\let\crd@sharp=\crd@basssharp%
\let\crd@doublesharp=\crd@bassdoublesharp%
\crd@parsenote\crd@bassnote\crd@bassacc% read bass note
\crd@parse\crd@input\for\crd@bracket%
\crd@formatcrd\hfil% call rendering
}
% \end{macrocode}
% \subsubsection{ Multiple chords}
% \DescribeMacro{\crd@parsecrds}
% The \verb|\crd@parsecrds| macro is used to read more then one
% chord. This can be usefull if no corresponding note over which
% one can put the note exist.
% \DescribeMacro{\crd@crddelim}
% The syntax table \verb|\crd@crddelim| is used.
% \begin{macrocode}
\def\crd@crddelim{crd@crddelim}%
\expandafter\def\csname\crd@crddelim,\endcsname{}%
\def\crd@parsecrds{%
\crd@parsecrd%
\crd@parse\crd@input\for\crd@crddelim%
\ifcrd@parsematched\crd@parsecrds\fi%
}
% \end{macrocode}
% \begin{demo}[w]{multiple chords}
% \c (Cm),2CM,Cm7
% \end{demo}
% \DescribeMacro{\c}
% The main entry point for the user is the
% \verb*|\c |\synt{chord-list}\verb*| | macro which calls the
% \verb|\crd@output| routine with the formatted chords.
% \begin{macrocode}
\def\crd#1 {\def\crd@input{#1}\crd@output\crd@parsecrds}
\let\cedilla=\c
\let\c=\crd
% \end{macrocode}
%
% \subsection{Formatting}
% To allow the use of different fonts the
% notion of fontstyles is introduced.
% The initialisation of fontstyles is done in different macros.
% \DescribeMacro{\crd@fontstylea}
% \begin{macrocode}
\def\crd@fontstylea{%
\font\crd@eightrm=cmr8
\font\crd@eightit=cmmi8
\font\crd@seventeenrm=cmr17
\font\crd@fourteenrm=cmr14
\font\crd@twelverm=cmr12
\font\crd@ninerm=cmr9
\font\crd@smallninerm=cmr9 scaled 900
\font\crd@bigninerm=cmr9 scaled 1100
\let\crd@notetype=\crd@seventeenrm
\def\crd@noteflat{\raise0.6ex\hbox{\kern-0.085em\musictwenty2}}
\def\crd@notedoubleflat{\raise0.6ex\hbox{\kern-0.085em\musictwenty3}}
\def\crd@notesharp{\raise0.8ex\hbox{\musictwenty4}}
\def\crd@notedoublesharp{\raise0.8ex\hbox{\musictwenty5}}
\let\crd@basstype=\crd@fourteenrm
\def\crd@bassflat{\raise.5ex\hbox{\musicsixteen2}}
\def\crd@bassdoubleflat{\raise0.6ex\hbox{\kern-0.085em\musicsixteen3}}
\def\crd@basssharp{\raise1ex\hbox{\musicsixteen4}}
\def\crd@bassdoublesharp{\raise0.8ex\hbox{\musicsixteen5}}
\let\crd@numbertype=\crd@ninerm
\def\crd@numberflat{\raise.5ex\hbox{\musiceleven2}}
\def\crd@numbersharp{\raise1ex\hbox{\musiceleven4}}
\def\crd@numberminus{\crd@ninerm-}
\def\crd@numberplus{\crd@ninerm+}
\let\crd@capitaltype=\crd@smallninerm % capitals
\let\crd@smalltype=\crd@bigninerm % small
\def\crd@hdim{\crd@eightit$\circ$\kern-4.4pt\raise.9pt\hbox{\crd@eightrm/}}
\def\crd@dim{\crd@eightit$\circ$}
}
% \end{macrocode}
% The formating of the chords is done in the
% \DescribeMacro{\crd@formatcrd}
% \verb|\crd@formatcrd| macro. The parse results are
% stored in the following macros:
% \verb|\crd@crdnote| -- chord note,
% \verb|\crd@crdacc| -- chord note accidental,
% \verb|\crd@bassnote| -- bass note and
% \verb|\crd@bassacc| -- bass note accidental.
%
%
%\iffalse % dont include this, just experimental code
%<*gobble>
\def\mymatrix#1{\null\,\vcenter{\normalbaselines\m@th
\ialign{\hfil$##$\hfil&&\quad\hfil$##$\hfil\crcr
\mathstrut\crcr\noalign{\kern-\baselineskip}
#1\crcr\mathstrut\crcr\noalign{\kern-\baselineskip}}}\,}
\def\crd@formatcrdb{%
${\rm \crd@crdnote}\crd@crdacc%
^{\crd@up}_{\raise0pt\hbox{{\rm \crd@lo}}}
\ifx\crd@alt\empty\else\left(\mymatrix\crd@alt\right)\fi%
\ifx\crd@bassnote\empty\else% do we have an bass note set ?
/{\rm \crd@bassnote}\crd@bassacc%
\fi$%
}
%</gobble>
%\fi
% \begin{macrocode}
\def\crd@formatcrda{%
\hbox{\kern\crd@hshift\elemskip\raise\crd@vshift\internote\hbox{%
{\crd@notetype\crd@bracketopen}%
{\crd@notetype\crd@crdnote\crd@crdacc}%
\vbox{%
\hbox{%
\crd@up%
\ifx\crd@alt\empty\else\crd@numbertype(\crd@alt\crd@numbertype)\fi%
}%
\nointerlineskip\vskip1pt%
\hbox{\vphantom{\crd@capitaltype M}\crd@lo}}%
\ifx\crd@bassnote\empty\else%
{\crd@basstype/%
\lower0.5ex\hbox{\kern-0.17em \crd@bassnote\crd@bassacc}}%
\fi%\
{\crd@notetype\crd@bracketclose}%
}}
}
% \end{macrocode}
% \begin{macrocode}
\let\crd@formatcrd=\crd@formatcrda
\crd@fontstylea
% \end{macrocode}
%
% \begin{demo}[w]{formatting}
% \generalsignature{0}\generalmeter{\meterfrac44}
% \nobarnumbers
% \startextract
% \NOtes\c Cm,CM,Dm7 \hu f\en\bar
% \endextract
% \end{demo}
%
%
% \DescribeMacro{\crd@output}
% The output function puts the formatted chords on their place.
%
% \begin{macrocode}
\def\crd@musixOutput#1{\hbox{\zchar{\crddefaultheight}{\hbox to\elemskip{#1\hss}}}}
\let\crd@output=\crd@musixOutput
% \end{macrocode}
%
%
\makeatother
%
% \section{Customization}
% If the default implementation does not suite the needs
% some tips of how to change the default behaviour will be
% given.
% \subsection{Changing the extensions}
% \begin{description}
% \item[Q:] How do I get the symbol $Dm^{M7}$ ?
% \item[A:] The M has to be put to the upper extensions list, so we
% have to change the definition in the \verb|\crd@qual| table:
% \def\crddefaultheight{0}
% \begin{demo}[w]{$Dm^{M7}$}
% \makeatletter%
% \def\crd@qualM{\crd@append{\crd@capitaltype M}\to\crd@up}% major7
% \makeatother%
% \c DmM7 %
% \end{demo}
% \item[Q:] How do I get the symbol $Dm^{7-5}$ ?
% \item[A:]
% \begin{itemize}
% \renewcommand{\labelitemi}{-}
% \item
% The predefined symbol can be found by using `h' -- for
% half dimineshed.
% \begin{demo}[w]{h}
% \c Dh %
% \end{demo}
% \item
% to ge the diminished fifth explicit to the upper extensions one could
% either change the definition of the `h' to:
% \begin{demo}[w]{Dmh : $Dm^{7-5}$}
% \makeatletter%
% \def\crd@qualh%
% {\crd@append{\crd@numbertype 7-5}\to\crd@up}% half diminished
% \makeatother%
% \c Dmh %
% \end{demo}
% \item
% or may introduce an mapping for the -5 and has to write: D7-5
% \begin{demo}[w]{Dm7-5 : $Dm^{7-5}$}
% \makeatletter%
% \expandafter\def\csname\crd@qual5-\endcsname% dimin. 5
% {\crd@append{\crd@numberminus\crd@numbertype5}\to\crd@up}%
% \makeatother%
% \c Dm7-5 %
% \end{demo}
% \end{itemize}
% \end{description}
%
% \subsection{change fonts}
% \begin{description}
% \item[Q:] How do I change the font?
% \item[A:] One has to create his own fontstyle definition
% with a suitable formatting like for example:
% \begin{demo}[w]{change fonts}
% \makeatletter%
% \def\crd@fontstyleb{%
% \font\crd@newfont=cmssbx10%
% \let\crd@notetype=\crd@newfont%
% \def\crd@noteflat{\raise2pt\hbox{\musixchar90}}%
% \def\crd@notedoubleflat{\crd@noteflat\crd@noteflat}%
% \def\crd@notesharp{\raise3.5pt\hbox{\musixchar92}}%
% \def\crd@notedoublesharp{\crd@notesharp\crd@notesharp}%
% \let\crd@basstype=\crd@newfont%
% \def\crd@bassflat{\crd@noteflat}%
% \def\crd@bassdoubleflat{\crd@notedoubleflat}%
% \def\crd@basssharp{\crd@notesharp}%
% \def\crd@bassdoublesharp{\crd@notedoublesharp}%
% \let\crd@numbertype=\crd@newfont%
% \def\crd@numberflat{\crd@noteflat}%
% \def\crd@numbersharp{\crd@notesharp}%
% \def\crd@numberminus{\crd@newfont-}%
% \def\crd@numberplus{\crd@newfont+}%
% \let\crd@capitaltype=\crd@newfont % capitals in extension
% \let\crd@smalltype=\crd@newfont % small letters in extension
% \def\crd@hdim%
% {\crd@newfont$\circ$\kern-4.4pt\raise.9pt\hbox{\crd@newfont/}}%
% \def\crd@dim{\crd@newfont$\circ$}%
% }%
% \def\crd@formatcrdb{%
% \hbox{\kern\crd@hshift\elemskip\raise\crd@vshift\internote\hbox{%
% {\crd@notetype\crd@crdnote\crd@crdacc}%
% \crd@lo%
% \raise4pt%
% \hbox{%
% \crd@up%
% \ifx\crd@alt\empty\else\crd@numbertype(\crd@alt\crd@numbertype)\fi%
% }%
% \ifx\crd@bassnote\empty\else%
% {\crd@basstype/\crd@bassnote\crd@bassacc}%
% \fi%\
% }}
% }
% \crd@fontstyleb%
% \let\crd@formatcrd=\crd@formatcrdb
% \makeatother%
% \nobarnumbers%
% \startextract\NOtes\c D7,AfM7 \hu f\en\bar\endextract%
% \end{demo}
% \end{description}
% Contributions for improving either the current fontstyle
% or the definition of new ones are welcome.
%
% \section{Todo}
%
% The actual implementation is not really open for changing
% the input format and the way the chords are displayed.
% One should implement an middle layer which is fixed and
% offer various implementations either for the input format
% and the output format which are written using this layer.
%
% \section{Change Log}
%
% \begin{description}
% \item[Version 1.0] (2.11.2004) \par Initial version.
% \item[Version 1.1] (1.7.2005) \par
% Added input guard and resetting of parameters
% if file is included more than once.
% \end{description}
%
% \Finale \PrintIndex
%
%\iffalse
%<*gobble>
%%% Local Variables:
%%% mode: plain-tex
%%% TeX-master: t
%%% End:
%</gobble>
%\fi
|