abcpp is a simple yet powerful preprocessor designed for, but not limited to, ABC music files (http://staffweb.cms.gre.ac.uk/~c.walshaw/abc/). It provides conditional output, macros, symbol renaming, and file inclusion. I wrote it for two reasons: first, I wanted to overcome incompatibilities between ABC packages; secondly, I wanted to be able to write portable and more readable ABC files.
Inspired by the C and S-Lang (http://www.s-lang.org) preprocessor, abcpp supports a few directives that allow you to play a few tricks. You write your ABC music files with directives lines like #define or #ifdef, defining macros or excluding portions of text according to specific conditions. Then you preprocess your file with abcpp, producing an output file suitable for each ABC application or voice. In a nutshell, have your ABC cake and eat it too!
The home page for abcpp and other tools is http://abcplus.sourceforge.net.
Normally, if you write for one specific ABC application you can use extensions that other ABC applications may not support. For example, I mainly write ABC choral music files, which I convert to PostScript using abcm2ps (http://moinejf.free.fr). abcm2ps supports this type of Q: field:
Q: "Allegro" 1/4 = 100
which I want to use as it's standard in printed music. Unfortunately, abc2midi (http://abc.sourceforge.net/abcMIDI) doesn't like it, and will only accept this:
Q: 1/4 = 100
Several such incompatibilities exist. So, if I wanted to proof-listen to a tune I should manually modify the ABC source! No way...
The key is using conditional directives, like #ifdef... #else... #endif, to exclude parts that some applications don't support:
#ifndef MIDI Q: "Allegro" 1/4 = 100 #else Q: 1/4 = 100 #endif
Conditional output makes it also possible to extract parts from a score:
#ifdef SOPRANO ALL V: 1 ... #endif #ifdef ALTO ALL V: 2 ... #endif #ifdef TENOR ALL V: 3 ... #endif #ifdef BASS ALL V: 1 ... #endif
I always found that some decorations like !crescendo(! or !diminuendo(! are just too verbose. I'd much prefer a shorter form like, say, !<(! or !>(!, but no ABC application I'm aware of supports macros of this kind.
The solution is to use macros to redefine the decorations. Moreover, using macros one could change the syntax of ABC fields:
#define !<(! !crescendo(! #define !<)! !crescendo)! #define Title: T: #define Composer: C: #define System: %%staves #ifdef MIDI #define !x! z #else #define !x! x #endif
You don't want to clutter your ABC sources with macro definitions. It's simpler to write definitions once and for all in external files, which you can include in your ABC files:
#include <fancyheader.abp> #include "my own macros.abp"
Unpack the archive, type 'make', and move abcpp to a directory in the $PATH. Suggested destinations are /usr/local/bin for Unix systems, C:\WINDOWS for Windows 9x/ME.
In the following, <something> denotes a required argument, while [something] denotes an optional argument.
Directives lines must begin in column 1, and will not appear in the output file. The current version supports the following directives:
#define GU Guido #define GG GU_Gonzato
#define \"C \"^Do
#define GG Guido~Gonzato #define AIC "abcpp is cool"
#define !lph! !longphrase! ... #define !lph!
#define EMPTY ""
#define do c #define re d #define mi e C: Gui\do, il \re dei \mi\mi
abcpp is a command line tool. Typical usage is:
$ abcpp [-s] [-c] [-h] [-def1 -def2 ...] [inputfile] [outputfile]
The following ABC tune contains directives for making different headers, depending whether the symbol MIDI is defined. Some symbols and decorations are redefined to give the tune a M-Tx-ish look:
% my_music.abp % #define Index: X: #define Title: T: #define Meter: M: #define Length: L: #define Tempo: Q: #define Voice: V: #define Key: K: #define Style: %%staves #define Duet [1~2] #define !<(! !crescendo(! #define !<)! !crescendo)! #define !>(! !diminuendo(! #define !>)! !diminuendo)! #define !H! !fermata! Index: 1 Title: %abcpp% test Meter: 4/4 Length: 1/4 #ifdef MIDI Tempo: 1/4 = 80 #else Tempo: "Allegro" Voice: 1 clef=treble name="Flute" Voice: 2 clef=treble name="Violin" Style: Duet #endif Key: C % Voice: 1 cdef|!<(!cde!<)!f|!>(!CDE!>)!F|!H!G4| Voice: 2 ccee|ccgg |g f e d |!H!C4| % % End of file my_music.abp
That's nice, but there's a better approach. Let's write a file, called my_defines.abp, that reads:
# my_defines.abp # #define Index: X: #define Title: T: #define Meter: M: #define Length: L: #define Tempo: Q: #define Voice: V: #define Key: K: #define Style: %%staves #define Duet [1~2] #define !<(! !crescendo(! #define !<)! !crescendo)! #define !>(! !diminuendo(! #define !>)! !diminuendo)! #define !H! !fermata!
Now, let's rewrite my_music.abp:
% my_music.abp % # #include my_defines.abp # Index: 1 Title: %abcpp% test Meter: 4/4 Length: 1/4 #ifdef MIDI Tempo: 1/4 = 80 #else Tempo: "Allegro" Voice: 1 clef=treble name="Flute" Voice: 2 clef=treble name="Violin" Style: Duet #endif Key: C % Voice: 1 cdef|!<(!cde!<)!f|!>(!CDE!>)!F|!H!G4| Voice: 2 ccee|ccgg |g f e d |!H!C4| % % End of file my_music.abp
Do you like it like this? I find it much more readable. We're ready to run my_music.abp through abcpp:
$ abcpp my_music.abp my_music_nomidi.abc $ abcpp -MIDI my_music.abp my_music_midi.abc
The first line doesn't define any symbol, while the second line defines the symbol MIDI. This is used to produce an alternative header. We now have two ABC files: one for typesetting and one for making a MIDI file.
In case you didn't notice: I suggest that you use the .abp extension for ABC files with abcpp directives, .abc for plain ABC files.
In Italy, France, and in general in Latin countries, notes are written using Guido d'Arezzo's notation: do re mi fa sol la si -> c d e f g a b. Using built-in macros and a bit of care, you can write ABC tunes using do re mi... instead of normal notes. You don't want this replacement to occur in lyrics lines, though.
Let's write a sample tune:
% doremi.abp #doremi X: 1 T: Do \re \mi -> c d e C: Gui\do M: 4/4 L: 1/4 Q: 1/4 = 100 K: C % #define !tieni! !fermata! DO RE MI FA|SOL LA SI !tieni!do|do SI LA SOL|FA MI RE DO| #abc w: do re mi fa sol la si do, do si la sol fa mi re do. #doremi DO RE MI FA|SOL LA SI !tieni!do|do SI LA SOL|FA MI RE DO| #abc w: do re mi fa sol la si do, do si la sol fa mi re do. % % End of file doremi.abp
How about it? This trick makes it possible to write ABC music even to people who have no confidence with Anglo-Saxon notation - namely, young Italian students... Note that some syllables in the header start with '\': this prevents them from being replaced by their macro definition.
The following ABC file is written for SATB. Let's see how to output four different ABC files, one for each voice:
X: 1 T: Part extraction C: Guido Gonzato M: 4/4 L: 1/4 Q: 1/4 = 60 %%staves [S A T B] V: S clef=treble name="Soprano" sname="S" V: A clef=treble name="Alto" sname="A" V: T clef=treble name="Tenor" sname="T" V: B clef=bass name="Bass" sname="B" K: C % #ifdef SOPRANO ALL [V: S] cccc|eeee|gggg|c'c'c'c'| #endif #ifdef ALTO ALL [V: A] cccc|GGGG|cccc|eeee| #endif #ifdef TENOR ALL [V: T] CCCC|EEEE|GGGG|cccc| #endif #ifdef BASS ALL [V: B] CCCC|G,G,G,G,|CCCC|EEEE| #endif %
Make the four files with these command lines:
$ abcpp -SOPRANO parts-soprano.abc $ abcpp -ALTO parts-alto.abc $ abcpp -TENOR parts-tenor.abc $ abcpp -BASS parts-bass.abc
and the four-parts score with:
$ abcpp -ALL parts.abc parts-all.abc
Normally, to do part extraction you'll want to use abc2prt - see the home page.
Guitar chords are only defined if they start in A-G. But some users may want to print the chord names using Latin notes. Here's how it's done:
% doremi.abp #ifndef MIDI #define \"C\" \"^Do\" #define \"G\" \"^Sol\" #endif X: 1 T: do re mi M: 4/4 L: 1/4 K: C % "C"CDEF|"G"GABc|"C"C2"G"G2|"C"C2z2|
'-s': this option (strip) removes w: lines and all decorations from input. This can be useful for fussy ABC applications that follow old ABC standards.
'-c': this option removes all chords. In many ABC files, "chords" are actually textual annotations. abc2midi will dutifully play them, obviously with unexpected results. Better strip them out.
'-h': shows usage.
Macro definitions can interfere with each other. To prevent macro replacement in specific spots, use the '\' character. For example, if the syllable 'do' is #defined as 'c', the word 'Guido' will become 'Guic', while 'Gui\do' will be converted as 'Guido'.
Sooner or later I'll replace all static structures in abcpp.c with dynamic ones.
abcpp is copyright by Guido Gonzato <guido . gonzato at univr . it> 2001-2003, and released under the General Public Licence. If you find this small program useful, or have bug reports, suggestions, or criticism, please drop me a line. abcpp is very useful to me; I hope I've done something useful for other people too.
Enjoy,
Guido =8-)
This document was generated using AFT v5.095