Path: sparky!uunet!dtix!darwin.sura.net!zaphod.mps.ohio-state.edu!pacific.mps.ohio-state.edu!linac!att!cbnewsm!cbnewsl!att-out!rutgers!sun-barr!west.West.Sun.COM!cronkite.Central.Sun.COM!sixgun.East.Sun.COM!newscan!verdelait!martin
From: mar...@sun.com (Martin Leclerc SE Sun Montreal)
Newsgroups: alt.sources
Subject: chord v1.2 - part 1/2
Message-ID: <1992Sep3.183528.6863@newscan.canada.sun.com>
Date: 3 Sep 92 18:35:28 GMT
Sender: n...@newscan.canada.sun.com
Reply-To: mar...@sun.com
Organization: Sun Microsystems du Canada
Lines: 2218
Nntp-Posting-Host: verdelait.canada.sun.com
Archive-Name: chord v1.2 - part 1/2

This is a description of a utility called 'chord'.

It's purpose is to provide guitar players with a tool to produce good
looking, self-descriptive music sheet from a text file.

'chord' read a text file containing the lyrics of a song, the chords to
be played, their description and some other optional data to produce a
PostScript document that includes:

	Centered titles Chord names above the words Graphical
	representation of the chords at the end of the songs

'chord' also provides support for 

	Multiple logical pages per physical pages ( 1, 2 or 4)
	Configurable fonts for the lyrics and the chord names
	Multiple songs inside one file
	The complete ISO 8859-1 character set
and
	Chorus marking

NEW IN VERSION 1.2

o More flexible Page Numbering
  o Left/right
  o always-present
  o an option for simgle spacing on lines with no chords
o Distinction between an unplayed string and a buffed one
o TOC generation
o Some bug fixes

Thanks to contributor Steve Putz !

NEW IN VERSION 1.1

o 'chord' supports transposition. See the man page.
o miscellanious bug fixes, including dubious coding that kept IBM and
  SGI from executing chord properly
o the grids now indicate string played open
o Error messages noe correctly report the name of the file and
  the line number where the error was found

PLANNED

o Support for tablature
o Alternate marking for the chorus


'chord' has been developped on SPARCStations running SunOS 4.1.2 and
OpenWindows 3. The PostScript previewer (PageView), SparcPrinters and
LaserWriter II have had no problem with the output. Please report any
changes your system requires.

===== COMPILING =====

chord is written in fairly portable C and should work on most UNIX
systems with little or no change. Let us know of your problems.

Simply edit the Makefile to meet your environment and 'make'

===== Amiga =====

Chord was successfully compled on an amiga system using a PD getopts


===== VMS =====

VMS port was done by  Jim Gerland (GERL...@ubvms.cc.buffalo.edu)
	chord.rnh
	makefile.vms
	argproc.c

===== ARCHIVES =====

James B. from the University of Nevada (nevada.edu) has
graciously open the doors of their ftp site for archiving
songs in chord format. Look for files with the '.chordpro' 
extension.


Martin Leclerc (Martin.Lecl...@canada.sun.com)
Mario Dorion   (Mario.Dor...@canada.sun.com)	



#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 09/03/1992 18:16 UTC by martin@verdelait
# Source directory /tmp_mnt/disk2/martin/wrk/chord
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   1900 -rw-r--r-- transpose.c
#   8336 -rw-rw-rw- iso.c
#  21084 -rw-rw-rw- chord.c
#  15970 -rw-rw-rw- grid.c
#   5646 -rw-rw-rw- chord.man
#    730 -rw-rw-rw- Makefile
#   1046 -rw-rw-rw- chord.h
#   1158 -rw-rw-rw- songs/heaven
#   1161 -rw-rw-rw- songs/you_ve_got_a_friend
#    351 -rw-r--r-- makefile.vms
#   4262 -rw-r--r-- chord.rnh
#  13622 -rw-r--r-- argproc.c
#   2345 -rw-r--r-- README
#
# ============= transpose.c ==============
if test -f 'transpose.c' -a X"$1" != X"-c"; then
	echo 'x - skipping transpose.c (File already exists)'
else
echo 'x - extracting transpose.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'transpose.c' &&
X#include "chord.h"
X
Xextern int grid_size;
Xextern int transpose;
X
Xextern char *notes[];
Xextern char mesg[];
X
Xint do_transpose ( chord )
Xchar *chord;
X{
X
X/*
X
Xattempting parsing
X
X1) look for a known note name at start of name
X2) copy literally until delimiter found 
X3) repeat
X
X*/
Xint i,j;
Xint p_chord, p_new_chord;
Xint sharp, flat, new_i;
Xunsigned char new_chord[MAXTOKEN];
X
Xp_chord = 0;
Xp_new_chord = 0;
X
Xwhile (TRUE)
X	{
X	/* Find basic note */
X	i=0;
X	while ( (i < 7) && (strncmp ( chord + p_chord, notes[i], strlen (notes[i]))) )
X		i++;
X	
X	if (i >= 7) 
X		return(1);
X	
X	/* Look for sharp or flat */
X	p_chord += strlen(notes[i]);
X	flat = ( chord[p_chord] == 'b');
X	sharp = ( chord[p_chord] == '#');
X	if (sharp || flat) p_chord++;
X	
X	
X	/*compute new chord name */
X	
X	new_i = i;
X
X
X	/* moving upscale ... */
X	if (transpose > 0) 
X		for (j=0; j < transpose; j++)
X			if (sharp)
X				{
X				sharp = 0;
X				new_i = (new_i + 1) % 7;
X				}
X			else
X				if (flat)
X					flat = 0;
X				else 
X					if ((new_i == 2) || (new_i == 6))
X						new_i = (new_i + 1) % 7;
X					else 
X						sharp++;
X	
X
X	/* moving downscale ... */
X	else
X		for (j=0; j > transpose; j--)
X			if (flat)
X				{
X				flat = 0;
X				new_i = (new_i + 6) % 7;
X				}
X			else
X				if (sharp)
X					sharp = 0;
X				else 
X					if ((new_i == 3) || (new_i == 0))
X						new_i = (new_i + 6) % 7;
X					else 
X						flat++;
X	
X	
X	sprintf (new_chord+p_new_chord, "%s", notes[new_i]);
X	p_new_chord += strlen(notes[new_i]);
X	
X	if (sharp) sprintf( new_chord + p_new_chord++, "#");
X	if (flat) sprintf( new_chord + p_new_chord++, "b");
X	
X	while ((chord[p_chord] != '/') && (chord[p_chord] != '\0'))
X		new_chord[p_new_chord++] = chord[p_chord++];
X	
X	if (chord[p_chord] == '\0')
X		{
X		new_chord[p_new_chord] = '\0';
X		sprintf (mesg, "[%s] becomes [%s]", chord, new_chord);
X		debug (mesg);
X		strcpy(chord, new_chord);
X		return(0);
X		}
X
X	p_chord++;
X	new_chord[p_new_chord++] = '/';
X	}
X}
SHAR_EOF
chmod 0644 transpose.c ||
echo 'restore of transpose.c failed'
Wc_c="`wc -c < 'transpose.c'`"
test 1900 -eq "$Wc_c" ||
	echo 'transpose.c: original size 1900, current size' "$Wc_c"
fi
# ============= iso.c ==============
if test -f 'iso.c' -a X"$1" != X"-c"; then
	echo 'x - skipping iso.c (File already exists)'
else
echo 'x - extracting iso.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'iso.c' &&
X#include <stdio.h>
X
Xprint_re_encode ()
X{
X	printf("%%  iso.ps  reencodeing of ISO 8859-1 8-bit french characters\n");
X	printf("%%\n");
X	printf("/reencodedict 5 dict def\n");
X	printf("/ReEncode\n");
X	printf("  { reencodedict begin\n");
X	printf("      /newencoding exch def\n");
X	printf("      /newfontname exch def\n");
X	printf("      /basefontname exch def\n");
X	printf("\n");
X	printf("      /basefontdict basefontname findfont def\n");
X	printf("\n");
X	printf("      /newfont basefontdict maxlength dict def\n");
X	printf("\n");
X	printf("      basefontdict\n");
X	printf("      {  exch dup dup /FID ne exch /Encoding ne and\n");
X	printf("	{ exch newfont 3 1 roll put }\n");
X	printf("	{ pop pop }\n");
X	printf("	ifelse\n");
X	printf("      } forall\n");
X	printf("      newfont /FontName newfontname put\n");
X	printf("      newfont /Encoding newencoding put\n");
X	printf("      newfontname newfont definefont pop\n");
X	printf("      end\n");
X	printf("   } def\n");
X	printf("\n");
X	printf("/ISO 256 array def\n");
X	printf("\n");
X	printf("0 1 255 { ISO exch /.notdef put } for\n");
X	printf("ISO\n");
X	printf("\n");
X	printf("  dup 8#040 /space put\n");
X	printf("  dup 8#041 /exclam put\n");
X	printf("  dup 8#042 /quotedbl put\n");
X	printf("  dup 8#043 /numbersign put\n");
X	printf("  dup 8#044 /dollar put\n");
X	printf("  dup 8#045 /percent put\n");
X	printf("  dup 8#046 /ampersand put\n");
X	printf("  dup 8#047 /quotesingle put\n");
X	printf("  dup 8#050 /parenleft put\n");
X	printf("  dup 8#051 /parenright put\n");
X	printf("  dup 8#052 /asterisk put\n");
X	printf("  dup 8#053 /plus put\n");
X	printf("  dup 8#054 /comma put\n");
X	printf("  dup 8#055 /hyphen put\n");
X	printf("  dup 8#056 /period put\n");
X	printf("  dup 8#057 /slash put\n");
X	printf("  dup 8#060 /zero put\n");
X	printf("  dup 8#061 /one put\n");
X	printf("  dup 8#062 /two put\n");
X	printf("  dup 8#063 /three put\n");
X	printf("  dup 8#064 /four put\n");
X	printf("  dup 8#065 /five put\n");
X	printf("  dup 8#066 /six put\n");
X	printf("  dup 8#067 /seven put\n");
X	printf("  dup 8#070 /eight put\n");
X	printf("  dup 8#071 /nine put\n");
X	printf("  dup 8#072 /colon put\n");
X	printf("  dup 8#073 /semicolon put\n");
X	printf("  dup 8#074 /less put\n");
X	printf("  dup 8#075 /equal put\n");
X	printf("  dup 8#076 /greater put\n");
X	printf("  dup 8#077 /question put\n");
X	printf("  dup 8#100 /at put\n");
X	printf("  dup 8#101 /A put\n");
X	printf("  dup 8#102 /B put\n");
X	printf("  dup 8#103 /C put\n");
X	printf("  dup 8#104 /D put\n");
X	printf("  dup 8#105 /E put\n");
X	printf("  dup 8#106 /F put\n");
X	printf("  dup 8#107 /G put\n");
X	printf("  dup 8#110 /H put\n");
X	printf("  dup 8#111 /I put\n");
X	printf("  dup 8#112 /J put\n");
X	printf("  dup 8#113 /K put\n");
X	printf("  dup 8#114 /L put\n");
X	printf("  dup 8#115 /M put\n");
X	printf("  dup 8#116 /N put\n");
X	printf("  dup 8#117 /O put\n");
X	printf("  dup 8#120 /P put\n");
X	printf("  dup 8#121 /Q put\n");
X	printf("  dup 8#122 /R put\n");
X	printf("  dup 8#123 /S put\n");
X	printf("  dup 8#124 /T put\n");
X	printf("  dup 8#125 /U put\n");
X	printf("  dup 8#126 /V put\n");
X	printf("  dup 8#127 /W put\n");
X	printf("  dup 8#130 /X put\n");
X	printf("  dup 8#131 /Y put\n");
X	printf("  dup 8#132 /Z put\n");
X	printf("  dup 8#133 /bracketleft put\n");
X	printf("  dup 8#134 /backslash put\n");
X	printf("  dup 8#135 /bracketright put\n");
X	printf("  dup 8#136 /asciicircum put\n");
X	printf("  dup 8#137 /underscore put\n");
X	printf("  dup 8#140 /grave put\n");
X	printf("  dup 8#141 /a put\n");
X	printf("  dup 8#142 /b put\n");
X	printf("  dup 8#143 /c put\n");
X	printf("  dup 8#144 /d put\n");
X	printf("  dup 8#145 /e put\n");
X	printf("  dup 8#146 /f put\n");
X	printf("  dup 8#147 /g put\n");
X	printf("  dup 8#150 /h put\n");
X	printf("  dup 8#151 /i put\n");
X	printf("  dup 8#152 /j put\n");
X	printf("  dup 8#153 /k put\n");
X	printf("  dup 8#154 /l put\n");
X	printf("  dup 8#155 /m put\n");
X	printf("  dup 8#156 /n put\n");
X	printf("  dup 8#157 /o put\n");
X	printf("  dup 8#160 /p put\n");
X	printf("  dup 8#161 /q put\n");
X	printf("  dup 8#162 /r put\n");
X	printf("  dup 8#163 /s put\n");
X	printf("  dup 8#164 /t put\n");
X	printf("  dup 8#165 /u put\n");
X	printf("  dup 8#166 /v put\n");
X	printf("  dup 8#167 /w put\n");
X	printf("  dup 8#170 /x put\n");
X	printf("  dup 8#171 /y put\n");
X	printf("  dup 8#172 /z put\n");
X	printf("  dup 8#173 /braceleft put\n");
X	printf("  dup 8#174 /bar put\n");
X	printf("  dup 8#175 /braceright put\n");
X	printf("  dup 8#176 /asciitilde put\n");
X	printf("  dup 8#241 /exclamdown put\n");
X	printf("  dup 8#242 /cent put\n");
X	printf("  dup 8#243 /sterling put\n");
X	printf("  dup 8#244 /currency put\n");
X	printf("  dup 8#245 /yen put\n");
X	printf("  dup 8#246 /bar put\n");
X	printf("  dup 8#247 /section put\n");
X	printf("  dup 8#250 /dieresis put\n");
X	printf("  dup 8#251 /copyright put\n");
X	printf("  dup 8#252 /ordfeminine put\n");
X	printf("  dup 8#253 /guillemotleft put\n");
X	printf("  dup 8#254 /.notdef put\n");
X	printf("  dup 8#255 /endash put\n");
X	printf("  dup 8#256 /registered put\n");
X	printf("  dup 8#257 /tilde put\n");
X	printf("  dup 8#260 /ring put\n");
X	printf("  dup 8#261 /.notdef put\n");
X	printf("  dup 8#262 /.notdef put\n");
X	printf("  dup 8#263 /.notdef put\n");
X	printf("  dup 8#264 /acute put\n");
X	printf("  dup 8#265 /.notdef put\n");
X	printf("  dup 8#266 /paragraph put\n");
X	printf("  dup 8#267 /.notdef put\n");
X	printf("  dup 8#270 /cedilla put\n");
X	printf("  dup 8#271 /.notdef put\n");
X	printf("  dup 8#272 /ordmasculine put\n");
X	printf("  dup 8#273 /guillemotright put\n");
X	printf("  dup 8#274 /.notdef put\n");
X	printf("  dup 8#275 /circumflex put\n");
X	printf("  dup 8#276 /dotlessi put\n");
X	printf("  dup 8#277 /questiondown put\n");
X	printf("  dup 8#300 /Agrave put\n");
X	printf("  dup 8#301 /Aacute put\n");
X	printf("  dup 8#302 /Acircumflex put\n");
X	printf("  dup 8#303 /Atilde put\n");
X	printf("  dup 8#304 /Adieresis put\n");
X	printf("  dup 8#305 /Aring put\n");
X	printf("  dup 8#306 /AE put\n");
X	printf("  dup 8#307 /Ccedilla put\n");
X	printf("  dup 8#310 /Egrave put\n");
X	printf("  dup 8#311 /Eacute put\n");
X	printf("  dup 8#312 /Ecircumflex put\n");
X	printf("  dup 8#313 /Edieresis put\n");
X	printf("  dup 8#314 /Igrave put\n");
X	printf("  dup 8#315 /Iacute put\n");
X	printf("  dup 8#316 /Icircumflex put\n");
X	printf("  dup 8#317 /Idieresis put\n");
X	printf("  dup 8#320 /.notdef put\n");
X	printf("  dup 8#321 /Ntilde put\n");
X	printf("  dup 8#322 /Ograve put\n");
X	printf("  dup 8#323 /Oacute put\n");
X	printf("  dup 8#324 /Ocircumflex put\n");
X	printf("  dup 8#325 /Otilde put\n");
X	printf("  dup 8#326 /Odieresis put\n");
X	printf("  dup 8#327 /.notdef put\n");
X	printf("  dup 8#330 /Oslash put\n");
X	printf("  dup 8#331 /Ugrave put\n");
X	printf("  dup 8#332 /Uacute put\n");
X	printf("  dup 8#333 /Ucircumflex put\n");
X	printf("  dup 8#334 /Udieresis put\n");
X	printf("  dup 8#335 /.notdef put\n");
X	printf("  dup 8#336 /.notdef put\n");
X	printf("  dup 8#337 /germandbls put\n");
X	printf("  dup 8#340 /agrave put\n");
X	printf("  dup 8#341 /aacute put\n");
X	printf("  dup 8#342 /acircumflex put\n");
X	printf("  dup 8#343 /atilde put\n");
X	printf("  dup 8#344 /adieresis put\n");
X	printf("  dup 8#345 /aring put\n");
X	printf("  dup 8#346 /ae put\n");
X	printf("  dup 8#347 /ccedilla put\n");
X	printf("  dup 8#350 /egrave put\n");
X	printf("  dup 8#351 /eacute put\n");
X	printf("  dup 8#352 /ecircumflex put\n");
X	printf("  dup 8#353 /edieresis put\n");
X	printf("  dup 8#354 /igrave put\n");
X	printf("  dup 8#355 /iacute put\n");
X	printf("  dup 8#356 /icircumflex put\n");
X	printf("  dup 8#357 /idieresis put\n");
X	printf("  dup 8#360 /.notdef put\n");
X	printf("  dup 8#361 /ntilde put\n");
X	printf("  dup 8#362 /agrave put\n");
X	printf("  dup 8#363 /oacute put\n");
X	printf("  dup 8#364 /ocircumflex put\n");
X	printf("  dup 8#365 /otilde put\n");
X	printf("  dup 8#366 /odieresis put\n");
X	printf("  dup 8#367 /.notdef put\n");
X	printf("  dup 8#370 /oslash put\n");
X	printf("  dup 8#371 /ugrave put\n");
X	printf("  dup 8#372 /uacute put\n");
X	printf("  dup 8#373 /ucircumflex put\n");
X	printf("  dup 8#374 /udieresis put\n");
X	printf("  dup 8#375 /ydieresis put\n");
X	printf("  dup 8#376 /.notdef put\n");
X	printf("  pop\n");
X	printf("\n");
X	printf("\n");
X}
X
Xre_encode (font)
Xchar *font;
X	{
X	printf("/%s /%s ISO ReEncode\n", font, font); 
X	}
SHAR_EOF
chmod 0666 iso.c ||
echo 'restore of iso.c failed'
Wc_c="`wc -c < 'iso.c'`"
test 8336 -eq "$Wc_c" ||
	echo 'iso.c: original size 8336, current size' "$Wc_c"
fi
# ============= chord.c ==============
if test -f 'chord.c' -a X"$1" != X"-c"; then
	echo 'x - skipping chord.c (File already exists)'
else
echo 'x - extracting chord.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'chord.c' &&
Xstatic char rcsid[] = "$Id: chord.c,v 1.12 1992/08/25 03:35:33 putz Exp $";
X/*	@(#)chord.c 1.0 91/07/01 */
X
X#include "chord.h"
X
XFILE *source_fd;
XFILE *toc_file = NULL;		/* optional table of contents file */
X
Xunsigned char
X	text_line[MAXLINE],	/* Lyrics Buffer */
X	chord[MAXTOKEN],	/* Buffer for the name of the chord */
X	title1[MAXLINE];	/* Holds the first title line */
X
Xchar
X	source[MAXTOKEN],
X	directive[MAXTOKEN],	/* Buffer for the directive */
X	mesg[MAXTOKEN];
X
Xchar
X	i_input;		/* Input line pointer */
Xchar
X	*text_font = DEF_TEXT_FONT,	/* Default font for text */
X	*chord_font = DEF_CHORD_FONT,	/* Default font for chord */
X	*used_fonts[MAXFONTS][MAXLINE],
X	*current_file,
X	*chord_line[MAXLINE];
X
Xchar *notes[7] =  { "C", "D", "E", "F", "G", "A", "B" };
X
Xint
X	c,			/* Current character in input file */
X	i_chord,		/* Index to 'chord' */
X	i_directive,		/* Index to 'directive' */
X	i_text, 		/* Index to 'text_line' */
X	in_chord,		/* Booleans indicating parsing status */
X	lyrics_only = FALSE,
X	auto_space = FALSE,	/* applies lyrics_only when no chords */
X	left_foot_odd = -1,	/* -1 for all page numbers on the right */
X				/* 0 for odd page numbers on the right */
X				/* 1 for odd page numbers on the left */
X	number_all = FALSE,	/* number the first page (set with -p 1) */
X	page_label = 1,		/* page number for footers and index */
X	i_chord_ov,		/* Overflow Booleans */
X	i_directive_ov = FALSE,
X	i_text_ov = FALSE,
X	in_directive = FALSE,
X	in_chordrc = FALSE,
X	in_chorus = FALSE,
X	has_directive = FALSE,
X	has_chord = FALSE,
X	title1_found = FALSE,
X	debug_mode = FALSE,
X	need_soc = FALSE,
X	pagination = 1,		/* virtual pages per physical pages */
X	transpose = 0,		/* transposition value */
X	vpos,			/* Current PostScript position, in points */
X	hpos,
X	start_of_chorus,	/* Vertical positions of the chorus */
X	end_of_chorus,
X	chord_size = DEF_CHORD_SIZE, 	/* Default font size for 'chord_font' */
X	text_size = DEF_TEXT_SIZE, 	/* Default font size for 'text_font' */
X	grid_size = DEF_GRID_SIZE,
X	n_pages = 1,		/* total page counter */
X	v_pages = 1,		/* virtual pages */
X	n_lines = 1,		/* line number in input file */
X	song_pages = 1,		/* song page counter */
X	blank_space = 0;	/* consecutive blank line counter */
X
Xfloat
X	chord_inc,
X	scale = 1.0,		/* Current scale factor */
X	rotation = 0.0;		/* Current rotation */
X
Xextern int nb_chord, first_ptr;
Xextern struct chord_struct chordtab[MAX_CHORD];
X
Xextern char *optarg;
Xextern int optind, opterr;
X
X/* --------------------------------------------------------------------------------*/
Xuse_chord_font()
X	{
X	printf ("CHORD_FONT setfont\n");
X	}
X
X/* --------------------------------------------------------------------------------*/
Xset_chord_font()
X	{
X	printf ("/CHORD_FONT { /%s findfont %d scalefont } def\n", chord_font, chord_size);
X	re_encode (chord_font);
X	}
X
X/* --------------------------------------------------------------------------------*/
Xuse_text_font()
X	{
X	printf ("TEXT_FONT setfont\n");
X	}
X/* --------------------------------------------------------------------------------*/
Xset_text_font(size)
Xint size;
X	{
X	printf ("/TEXT_FONT { /%s findfont %d scalefont } def\n", text_font, size);
X	re_encode (text_font);
X	}
X
X/* --------------------------------------------------------------------------------*/
Xdo_help (command) 
Xchar *command;
X	{
X	fprintf (stderr, "Usage: %s [options] file\n", command);
X	fprintf (stderr, "Options:\n");
X	fprintf (stderr, "	-c n               : set chord size [9]\n");
X	fprintf (stderr, "	-C postsctipt_font : Set chord font\n");
X	fprintf (stderr, "	-t n               : set text size [12]\n");
X	fprintf (stderr, "	-T postsctipt_font : set text font\n");
X	fprintf (stderr, "	-g n               : set chord grid size [30]\n");
X	fprintf (stderr, "	-l                 : only print lyrics\n");
X	fprintf (stderr, "	-h                 : This message\n");
X	fprintf (stderr, "	-2                 : 2 pages per sheet\n");
X	fprintf (stderr, "	-4                 : 4 pages per sheet\n");
X	fprintf (stderr, "	-d                 : dumps default chords definitions\n");
X	fprintf (stderr, "	-i file            : write table of contents to file\n");
X	fprintf (stderr, "	-a                 : automatic single space lines without chords\n");
X	fprintf (stderr, "	-p n               : starting page number [1]\n");
X	fprintf (stderr, "	-R                 : odd pages numbers on right\n");
X	fprintf (stderr, "	-L                 : odd pages numbers on left\n");
X	}
X
X/* --------------------------------------------------------------------------------*/
Xdo_chord (i_text, chord)
Xint i_text;
Xchar *chord;
X	{
X	if (transpose != 0)
X		if (do_transpose (chord) != 0)
X			{
X			sprintf (mesg, "Don't know how to transpose [%s]", chord);
X			error (mesg);
X			}
X
X	if (i_text < MAXLINE)
X		chord_line[i_text] = chordtab[add_to_chordtab(chord)].chord_name;
X	}
X
X/* --------------------------------------------------------------------------------*/
Xprint_chord_line ()
X	{
X	int i, j;		/* Counter */
X	
X	for (j=0; j<MAXLINE; j++)
X		{
X		if (chord_line[j] != NULL )
X			{
X			use_text_font();
X			printf ("(");
X			for (i=0; i < j; printf ("%c",text_line[i++]));
X				printf (") stringwidth  pop %d add %d moveto\n", hpos, vpos);
X
X			use_chord_font();
X			printf ("(%s) show\n", chord_line[j]);
X	
X			chord_line[j]=NULL;
X			}
X		}
X	}
X
X/* --------------------------------------------------------------------------------*/
Xdo_directive(directive)
Xchar *directive;
X	{
X	int   i;
X	char  *command, *comment;
X
X	command=(char *)strtok(directive, ": ");
X
X	if (!strcmp(command, "start_of_chorus") || !strcmp(command,"soc"))
X		{
X		/* start_of_chorus = vpos - blank_space; */
X		need_soc = TRUE;
X		in_chorus = TRUE;
X		}
X	else if (!strcmp (command, "end_of_chorus") || !strcmp(command, "eoc"))
X		{
X		if ( in_chorus )
X			{
X			end_of_chorus = vpos;
X			do_chorus_line();
X			in_chorus = FALSE;
X			}
X		else
X			error ("Not in a chorus.");
X		}
X	else if (!strcmp (command, "textfont") || !strcmp (command, "tf"))
X		{
X		text_font = (char *)strtok(NULL, ": ");
X		}
X	else if (!strcmp (command, "chordfont") || !strcmp (command, "cf"))
X		{
X		chord_font = (char *)strtok(NULL, ": ");
X		set_chord_font();
X		}
X	else if (!strcmp (command, "chordsize") || !strcmp (command, "cs"))
X		{
X		i = atoi((char *)strtok(NULL, ": "));
X		if ( i == 0 )
X			error ("invalid value for chord_size");
X		else
X			chord_size = i;
X		set_chord_font();
X		}
X	else if (!strcmp (command, "textsize") || !strcmp (command, "ts"))
X		{
X		i = atoi((char *)strtok(NULL, ": "));
X		if ( i == 0 )
X			error ("invalid value for text_size");
X		else
X			text_size = i;
X		}
X	else if (!strcmp (command, "comment") || !strcmp (command, "c"))
X		{
X		comment = (char *)strtok(NULL, "\0");
X		advance(blank_space);
X		blank_space = 0;
X		advance(text_size);
X		text_line[i_text] = '\0';
X		use_text_font();
X		printf (".9  setgray\n");
X		printf ("%d  setlinewidth\n", text_size);
X		printf ("newpath\n");
X		printf ("%d %d moveto\n", hpos, vpos + text_size/2 - 2);
X		printf ("(%s) stringwidth rlineto\n", comment);
X		printf ("stroke\n");
X		printf ("%d %d moveto\n", hpos, vpos);
X		printf ("0  setgray\n");
X		printf ("1 setlinewidth\n");
X		printf ("(%s) show\n", comment);
X		i_text = 0;
X		}
X	else if (!strcmp(command, "new_song") || !strcmp(command,"ns"))
X		{
X		do_new_song();
X		}
X	else if (!strcmp(command, "title") || !strcmp(command,"t"))
X		{
X		do_title();
X		}  
X	else if (!strcmp(command, "subtitle") || !strcmp(command,"st"))
X		{
X		do_subtitle();
X		}  
X	else if (!strcmp(command, "define") || !strcmp(command,"d"))
X		{
X		do_define_chord();
X		}  
X	else
X		{
X		sprintf (mesg, "Invalid Directive : [%s]", command);
X		error(mesg);
X		has_directive = FALSE;
X		}
X	}
X
X/* --------------------------------------------------------------------------------*/
Xdo_chorus_line()
X	{
X	printf ("1  setlinewidth\n");
X	printf ("newpath\n");
X	printf ("%d %d moveto\n", L_MARGIN - 10, start_of_chorus);
X	printf ("0 %d rlineto\n", -(start_of_chorus - end_of_chorus));
X	printf ("closepath\n");
X	printf ("stroke\n");
X	}
X/* --------------------------------------------------------------------------------*/
Xdo_translate(vert, horiz)
X	float vert, horiz;
X	{
X	printf ("%f %f translate\n", vert , horiz );
X	debug ("changing translation");
X	}
X/* --------------------------------------------------------------------------------*/
Xdo_new_song()
X	{
X	do_end_of_song();
X	nb_chord=first_ptr=0;
X	song_pages = 0;
X	do_start_of_page();
X	init_known_chords();
X	read_chordrc();
X	}
X/* --------------------------------------------------------------------------------*/
Xinit_ps()
X	{
X	printf ("%%!PS-Adobe-1.0\n");
X	printf ("%%%%Title: A song\n");
X	printf ("%%%%Creator: Martin Leclerc & Mario Dorion\n");
X	printf ("%%%%Pages: (atend)\n");
X	printf ("%%%%BoundingBox: 5 5 605 787\n");
X	printf ("%%%%EndComments\n");
X	printf ("/inch {72 mul } def\n");
X
X	print_re_encode();
X	set_chord_font();
X	set_text_font(text_size);
X	do_init_grid_ps();
X	init_known_chords();
X
X	printf ("%%%%EndProlog\n");
X
X	printf ("%%%%Page: \"%d\" %d\n",n_pages, n_pages);
X	printf ("%%%%BeginPageSetup\n");
X	printf ("/pgsave save def\n");
X	printf ("%f %f scale\n", scale, scale);
X	printf ("%f rotate\n", rotation);
X	printf ("%%%%EndPageSetup\n");
X
X	vpos = TOP;
X	hpos  = L_MARGIN;
X	if (pagination==4)
X		do_translate (0.0,   800.0);
X	else if (pagination==2)
X		do_translate (-40.0, -800.0);
X
X	}
X
X/* --------------------------------------------------------------------------------*/
Xdo_end_of_song()
X{
X	draw_chords();
X	do_end_of_page();
X}
X		 
X
X/* --------------------------------------------------------------------------------*/
Xdo_end_of_phys_page()
X/* physical */
X	{
X	debug ("end_of_phys_page");
X	printf ("pgsave restore\n");
X	printf ("showpage\n");
X	printf ("%%%%EndPage: \"%d\" %d\n",n_pages, n_pages);
X	}
X
X/* --------------------------------------------------------------------------------*/
Xdo_end_of_page()
X/* Logical */
X	{
X	printf ("1  setlinewidth\n");
X	printf ("0  setgray\n");
X	printf ("newpath\n");
X	printf ("%d %d 10 sub moveto\n", L_MARGIN, BOTTOM); 
X	printf ("%d 0 rlineto\n", WIDTH - L_MARGIN * 2);
X	printf ("stroke\n");
X	if (number_all || song_pages>1)
X		{
X		int pnum = (number_all ? page_label : song_pages);
X		set_text_font(text_size - 2);
X		use_text_font();
X		if (page_label % 2 == left_foot_odd) {  /* left side */
X			printf ("1 inch %d 3 div moveto\n", BOTTOM); 
X			printf ("(Page %d) show\n", pnum);
X		} else {                                /* right side */
X			printf ("(Page %d) dup stringwidth pop\n", pnum);
X			printf ("%d exch sub 1 inch sub %d 3 div moveto\n",
X				WIDTH, BOTTOM); 
X			printf ("show\n");
X		}
X
X		if (title1_found )
X			{
X			printf ("(%s) dup stringwidth pop 2 div\n", title1);
X			printf ("%d 2 div exch sub %d 3 div moveto\n",
X				WIDTH, BOTTOM);
X			printf ("show\n");
X			}
X		set_text_font(text_size);
X		}
X	if ( in_chorus )
X		{
X		end_of_chorus = vpos;
X		do_chorus_line();
X		}
X
X	if (v_pages == pagination) 
X		{
X		do_end_of_phys_page();
X		v_pages = 0;
X		}
X	}
X
X/* --------------------------------------------------------------------------------*/
Xdo_start_of_page()
X/*logical page ! */
X	{
X	v_pages++;
X	page_label++;
X
X	if (v_pages == 1)
X		{
X		n_pages++;
X		printf ("%%%%Page: \"%d\" %d\n",n_pages, n_pages);
X		printf ("%%%%BeginPageSetup\n");
X		printf ("/pgsave save def\n");
X		printf ("%f %f scale\n", scale, scale);
X		printf ("%f rotate\n",rotation);
X		printf ("%%%%EndPageSetup\n");
X		}
X
X	if (pagination==4) {
X		if (v_pages==1) 
X			do_translate(0.0, 800.0);
X		else if (v_pages==2)
X			do_translate(600.0, 0.0);
X		else if (v_pages==3)
X			do_translate(-600.0, -800.0);
X		else if (v_pages==4)
X			do_translate(600.0, 0.0);
X	}
X
X	if (pagination==2) {
X		if (v_pages==1) 
X			do_translate(-40.0, -800.0);
X		else if (v_pages==2)
X			do_translate(500.0, 0.0);
X	}
X
X	vpos = TOP;
X	hpos=L_MARGIN;
X	song_pages++;
X	if ( in_chorus )
X		{
X		start_of_chorus = vpos;
X		}
X	}
X
X/* --------------------------------------------------------------------------------*/
Xadvance(amount)
Xint amount;
X	{
X	vpos = vpos - amount;     /* Affect text positionning ! */
X	if (vpos < BOTTOM )
X		{
X		do_end_of_page();
X		do_start_of_page();
X		}
X	}
X
X/* --------------------------------------------------------------------------------*/
Xprint_text_line()
X	{
X	int i;
X
X	text_line[i_text] = '\0';
X
X	for (i=0; text_line[i] == ' '; i++);
X
X	if (!(lyrics_only || auto_space && !has_chord))
X		{
X		advance(blank_space);
X		blank_space = 0;
X		advance (chord_size + 1);
X
X		if ( ( text_line[i] != '\0' )
X		  && ( vpos - text_size <= BOTTOM))
X			advance (text_size);
X
X		if (need_soc)
X			{
X			start_of_chorus = vpos + chord_size;
X			need_soc = FALSE;
X			}
X		print_chord_line();
X		}
X
X	if ( text_line[i] == '\0')
X		{
X		blank_space += text_size - 2;
X		debug ("blank line found ");
X		}
X	else
X		{
X		advance (blank_space);
X		blank_space = 0;
X		advance (text_size - 1);
X		if (need_soc)
X			{
X			start_of_chorus = vpos + text_size;
X			need_soc = FALSE;
X			}
X		use_text_font();
X		printf ("%d %d moveto\n", hpos, vpos);
X		printf ("(%s) show\n", text_line);
X		}
X
X	i_text = 0;
X	i_text_ov = FALSE;
X	hpos = L_MARGIN;
X	has_chord = FALSE;
X	}
X
X/* --------------------------------------------------------------------------------*/
Xdo_title()
X	{
X	char *buf;
X	buf = (char *)strtok(NULL, "\0");
X	set_text_font (text_size+5);
X	use_text_font();
X	printf ("(%s) dup stringwidth pop 2 div\n", buf);
X	printf ("%d 2 div exch sub %d moveto\n", WIDTH, vpos);
X	printf ("show\n");
X	vpos = vpos - text_size - 5;
X	strcpy (title1, buf);
X	title1_found = TRUE;
X	set_text_font (text_size);
X	if (toc_file && song_pages == 1)	/* generate index entry */
X		{ /* careful to ignore any \ which may have been inserted */
X		char *bp;
X		for (bp = buf; *bp; bp++) if (*bp != '\\') putc(*bp, toc_file);
X		fprintf(toc_file, " ... %d\n", page_label);
X		}
X	}
X/* --------------------------------------------------------------------------------*/
Xdo_subtitle()
X	{
X	char *buf;
X	buf = (char *)strtok(NULL, "\0");
X	use_text_font();
X	printf ("(%s) dup stringwidth pop 2 div\n", buf);
X	printf ("%d 2 div exch sub %d moveto\n", WIDTH , vpos);
X	printf ("show\n");
X	vpos = vpos - text_size ;
X	}
X
X/* --------------------------------------------------------------------------------*/
Xput_in_string(array, p_index, c, max_index, p_ov_flag)
Xunsigned char array[MAXLINE];
Xint *p_index;
Xunsigned char c;
Xint max_index;
Xint *p_ov_flag;
X	{
X	if (*p_index < max_index)
X		{
X		if ( (int) c < 128 )
X			{
X			array[(*p_index)++] = c;
X			}
X		else
X			{
X			array[(*p_index)++] = '\\';
X			sprintf( &array[*p_index], "%o", c);
X			(*p_index) += 3;
X			}
X		}
X	else
X		{
X		if (!*p_ov_flag)
X			{
X			error ("Buffer Overflow");
X			*p_ov_flag = TRUE;
X			}
X		}
X	}
X/* --------------------------------------------------------------------------------*/
Xprocess_file(source_fd)
XFILE *source_fd;
X	{
X	debug("start of process_file");
X
X	n_lines = 0;
X
X	while ( (c=getc(source_fd)) != EOF )
X		{
X		i_input++;
X		switch ((char)c) {
X
X		case '[':
X			if ( in_chord )
X				error("Opening a chord within a chord!");
X			else
X				in_chord = TRUE;
X			i_chord = 0;
X			break;
X		
X		case ']':
X			if ( in_chord )
X				{
X				in_chord = FALSE;
X				chord[i_chord]='\0';
X				do_chord(i_text, chord);
X				has_chord = TRUE; 
X				i_chord = 0;
X				i_chord_ov = FALSE;
X				}
X			else
X				error("']' found with no matching '['");
X			break;
X		
X		case '{':
X			in_directive = TRUE;
X			i_directive = 0;
X			has_directive = TRUE;
X			break;
X
X		case '}':
X			if ( in_directive)
X				{
X				in_directive = FALSE;
X				directive[i_directive]='\0';
X				for (; (c=getc(source_fd)) != '\n'; );
X				i_input = 0;
X				do_directive(directive);
X				has_directive = FALSE;
X				n_lines++;
X				i_directive = 0;
X				i_directive_ov = FALSE;
X				}
X			else
X				error("'}' found with no matching '{'");
X			break;
X
X		case '\n':
X			if ( in_directive )
X				error ("Line ends while in a directive !"); 
X			if ( in_chord )
X				error ("Line ends while in a chord !"); 
X			if (has_directive == FALSE)
X				{
X				if (in_chordrc)
X					error("line is NOT a directive");
X				else
X					{
X					print_text_line();
X					}
X				}
X			else
X				has_directive = FALSE;
X			n_lines++;
X			i_input = 0;
X			in_directive = FALSE;
X			in_chord = FALSE;
X			break;
X
X		case '(':
X		case ')':
X			if (in_directive)
X				{
X				put_in_string(directive, &i_directive, '\\', MAXTOKEN, &i_directive_ov);
X				put_in_string(directive, &i_directive, c, MAXTOKEN, &i_directive_ov);
X				break;
X				}
X			else if (in_chord) /* allow parens in chord names */
X				{
X				put_in_string (chord, &i_chord, '\\', MAXLINE, &i_text_ov);
X				put_in_string (chord, &i_chord, c, MAXLINE, &i_text_ov);
X				break;
X				}
X			else
X				{
X				put_in_string (text_line, &i_text, '\\', MAXLINE, &i_text_ov);
X				put_in_string (text_line, &i_text, c, MAXLINE, &i_text_ov);
X				break;
X				}
X	
X	/* This case HAS to be the last before the default statement !!! */
X
X		case '#':
X			if (i_input == 1)
X				{
X				for (; (c=getc(source_fd)) != '\n'; );
X				n_lines++;
X				i_input = 0;
X				break;
X				}
X
X		default :
X			if (in_chord )
X				{
X				if ( c != ' ' )
X					put_in_string(chord, &i_chord, c, MAXTOKEN, &i_text_ov);
X				}
X			else if (in_directive)
X				{
X				put_in_string(directive, &i_directive, c, MAXTOKEN, &i_directive_ov);
X				}
X			else
X				{
X				put_in_string(text_line, &i_text, c, MAXLINE, &i_text_ov);
X				}
X			break;
X			}
X		}
X	print_text_line();
X	}
X
X/* --------------------------------------------------------------------------------*/
X/* read the file passed as argument */
Xread_input_file()
X	{
X	current_file = source;
X	source_fd = fopen (source, "r");
X	if (source_fd == NULL)
X		{
X		fprintf(stderr, "Unable to open [%s]\n", source);
X		exit (1);
X		}
X
X	process_file(source_fd);
X	fclose(source_fd);
X	}
X
X/* --------------------------------------------------------------------------------*/
X/* read the file $HOME/.chordrc as a set of directive */
Xread_chordrc()
X	{
X	char chordrc[MAXTOKEN];
X	FILE *chordrc_fd;
X	int n_lines_save;
X
X	strcpy (chordrc, getenv ("HOME"));
X	strcat (chordrc,"/.chordrc\0");
X	current_file = chordrc;
X	chordrc_fd = fopen (chordrc, "r");
X	if (chordrc_fd != NULL)
X		{
X		n_lines_save=n_lines;
X		n_lines=1;
X		in_chordrc = TRUE;
X		process_file(chordrc_fd);
X		in_chordrc = FALSE;
X		n_lines=n_lines_save;
X		fclose(chordrc_fd);
X		}
X	current_file = source;
X	}
X
X/* --------------------------------------------------------------------------------*/
Xdebug(dbg_str)
Xchar *dbg_str;
X{
X	if ( debug_mode )
X		fprintf (stderr, "Debug: %s\n", dbg_str);
X}
X
X/* --------------------------------------------------------------------------------*/
Xprint_version()
X{
X	char *version = VERSION;
X	char *patch_level = PATCH_LEVEL;
X	
X	printf ("chord version %s, patchlevel %s\n", version, patch_level);
X}
X/* --------------------------------------------------------------------------------*/
Xerror(err_str)
Xchar *err_str;
X{
X	fprintf(stderr, "WARNING: %s\n",err_str);
X	fprintf(stderr, "         in file %s, line %d\n", current_file,n_lines);
X}
X
X/* --------------------------------------------------------------------------------*/
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X	{
X	int c,i;
X/* Option Parsing */
X
X	while ((c = getopt(argc, argv, "hlDd24Vc:t:g:C:T:x:aLRp:i:")) != -1)
X		switch (c) {
X
X		case 'h':
X			do_help(argv[0]);
X			exit(1);
X			break;
X
X		case 'D':
X			debug_mode = TRUE;
X			break;
X
X		case 'd':
X			init_known_chords();
X			dump_chords();
X			exit(0);
X
X		case 'c':
X			i = atoi (optarg);
X			if ( i == 0 )
X				error ("invalid value for chord_size");
X			else
X				chord_size = i;
X			break;
X
X		case 't':
X			i = atoi (optarg);
X			if ( i == 0 )
X				error ("invalid value for text_size");
X			else
X				text_size = i;
X			break;
X
X		case 'x':
X			i = atoi (optarg);
X			if ( i == 0 )
X				error ("invalid value for transposition");
X			else
X				transpose = i;
X			break;
X
X		case 'T':
X			text_font = optarg;
X			break;
X
X		case 'C':
X			chord_font = optarg;
X			break;
X
X		case 'g':
X			i = atoi (optarg);
X			if ( i == 0 )
X				error ("invalid value for grid_size");
X			else
X				grid_size = i;
X			break;
X
X		case 'l':
X			lyrics_only=TRUE;
X			break;
X
X		case 'V':
X			print_version();
X			exit(0);
X
X		case '2':
X			pagination=2;
X			scale=scale2;
X			rotation=90.0;
X			break;
X
X		case '4':
X			pagination=4;
X			scale=scale4;
X			break;
X
X		case 'i':
X			if (!strcmp(optarg, "-")) toc_file = stderr;
X			else toc_file = fopen(optarg, "w");
X			if (toc_file == NULL) {
X				perror (optarg);
X				error ("unable to create index file");
X			}
X			break;
X
X		case 'a':
X			auto_space=TRUE;
X			break;
X
X		case 'p':
X			page_label = atoi(optarg);
X			number_all = TRUE;
X			break;
X
X		case 'L':
X			left_foot_odd = 1;
X			break;
X
X		case 'R':
X			left_foot_odd = 0;
X			break;
X
X		case '?':
X			do_help(argv[0]);
X			break;
X		}
X
X
X/* File Processing */
X
X	init_ps();
X
X	read_chordrc();
X
X	chord_inc = chord_size * 1.5;
X
X	if (optind  == argc)
X		{
X		debug ("Reading stdin");
X		strcpy(source, "stdin");
X		process_file (stdin);
X		}
X	else
X		{
X		for ( ; optind < argc; optind++ )
X			{
X			debug ("Processing a file");
X			strcpy(source, argv[optind]);
X			read_input_file();
X			if (optind < argc - 1)
X				do_new_song();
X			}
X		}
X
X
X	do_end_of_song();
X	if (v_pages != 0)
X		{
X		do_end_of_phys_page();
X		}
X
X	printf ("%%%%Trailer\n");
X	printf ("%%%%Pages: %d 1\n", n_pages);
X	printf ("%%%%EOF\n");
X	if (toc_file) fclose(toc_file);
X	exit (0);	
X	return(0);
X	}
X
SHAR_EOF
chmod 0666 chord.c ||
echo 'restore of chord.c failed'
Wc_c="`wc -c < 'chord.c'`"
test 21084 -eq "$Wc_c" ||
	echo 'chord.c: original size 21084, current size' "$Wc_c"
fi
# ============= grid.c ==============
if test -f 'grid.c' -a X"$1" != X"-c"; then
	echo 'x - skipping grid.c (File already exists)'
else
echo 'x - extracting grid.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'grid.c' &&
Xstatic char rcsid[] = "$Id: grid.c,v 2.2 1992/08/27 18:24:53 putz Exp $";
X
X#include "chord.h"
X
Xstruct chord_struct chordtab[MAX_CHORD];
Xint    nb_chord;
Xint	first_ptr = 0;
X
X/* char	known_chords[256][CHORD_NAME_SZ]; */
Xstruct kcs {
X	char	chord_name[CHORD_NAME_SZ];
X	int	displ;
X	int	s1,s2,s3,s4,s5,s6;
X} known_chords[MAX_CHORD];
X
X
Xint	nb_known_chord = 0;
X
Xextern int hpos,vpos;
Xextern int grid_size;
Xextern char mesg[MAXTOKEN];
X
Xdo_init_grid_ps()
X{
X	printf("%% routines for the drawing of the chords\n");
X	printf("/grid { \n");
X	printf("	gsave currentpoint\n");
X	printf("	6 { 0 cagesizeX rlineto incr cagesize neg incr add rmoveto } repeat\n");
X	printf("	moveto\n");
X	printf("	5 { cagesize 0 rlineto 0 cagesize sub incr rmoveto } repeat\n");
X	printf("	1 setlinewidth stroke grestore\n");
X	printf("	gsave\n");
X	printf("	0 cagesizeX rmoveto cagesize 0 rlineto\n");
X	printf("	cagesize 30 div setlinewidth stroke\n");
X	printf("	grestore	\n");
X	printf("} def\n");
X	printf("\n");
X	printf("/dot {\n");
X	printf("	gsave\n");
X	printf("	/fret exch def /str exch def\n");
X	printf("	/x 5  fret abs sub incr mul half-incr sub def\n");
X	printf("	/y 6 str sub incr mul def\n");
X	printf("	y x rmoveto\n");
X	printf("	0 setgray\n");
X	printf("	fret -1 eq\n");
X	printf("	  {\n");
X	printf("	  0 incr rmoveto\n");
X	printf("	  check neg  check neg rmoveto\n");
X	printf("	  check check rlineto check check rlineto\n");
X	printf("	  check neg check neg rmoveto check neg check rmoveto\n");
X	printf("  	  check check neg rlineto check check neg rlineto\n");
X	printf("	  cagesize 50 div setlinewidth stroke\n");
X	printf("	  }\n");
X	printf("	  {  fret 0 ne\n");
X	printf("	    { currentpoint dot-size 0 360 arc fill}\n");
X	printf("	    { currentpoint\n");
X	printf("	      check 0 360 newpath arc\n");
X	printf("	      cagesize 50 div setlinewidth\n");
X	printf("	    }\n");
X	printf("	    ifelse \n");
X	printf("	    stroke \n");
X	printf("	  }\n");
X	printf("	  ifelse\n");
X	printf("	grestore\n");
X	printf("} def	\n");
X	printf("\n");
X	printf("/dots {\n");
X	printf("	grid\n");
X	printf("	/fret-displ exch def\n");
X	printf("	  1 1 6\n");
X	printf("	  {\n");
X	printf("	    /str exch def\n");
X	printf("	    /fret exch def\n");
X	printf("	    fret %d ne {str fret dot} if\n", FRET_NONE);
X	printf("	  } for\n");
X	printf("\n");
X	printf("	fret-displ 1 ne\n");
X	printf("	{\n");
X	printf("    	  gsave\n");
X	printf("    	  0 cagesize 3 div sub cagesizeX incr sub rmoveto\n");
X	printf("    	  /char 1 string def fret-displ char cvs show grestore \n");
X	printf("	} if\n");
X	printf("\n");
X	printf("	/chord-name exch def\n");
X	printf("	gsave displ-font setfont\n");
X	printf("	0 cagesizeX cagesizeX 15 div add dot-size 3 mul add rmoveto\n");
X	printf("	chord-name stringwidth pop 2 div cagesize 2 div exch sub 0 rmoveto\n");
X	printf("	chord-name show	chord-font setfont grestore\n");
X	printf("} def\n");
X	printf("\n");
X	printf("/cagesize %d def\n",grid_size);
X	printf("/incr cagesize 5 div def\n");
X	printf("/cagesizeX incr 4 mul def\n");
X	printf("/half-incr incr 2 div def\n");
X	printf("/dot-size cagesize 15 div def\n");
X	printf("/check cagesize 20 div def\n");
X	printf("\n");
X	printf("/chord-font /Times-Roman findfont cagesize 5 div scalefont def\n");
X	printf("/displ-font /Times-Roman findfont cagesize 3 div scalefont def\n");
X	printf("%% end of the routines for the drawing of the chords\n");
X	printf("\n");
X}
X
X
Xint add_to_chordtab(chord)
Xchar *chord;
X{
X	int i, prev_i;
X	int n;
X
X/*  	fprintf(stderr, "attempting to add (%s)\n",chord); */
X	i=first_ptr; prev_i = -1;
X	while (1)
X	{
X/*		fprintf (stderr, "comparing with %d (%s)\n", i, chordtab[i].chord_name);  */
X		if (nb_chord>0 && i != -1) {
X			n=strcmp(chord, chordtab[i].chord_name);
X			if (n==0)
X				return(i);
X			else if (n>0) {
X				prev_i=i;
X				i=chordtab[i].next_ptr;
X				continue;
X				}
X			}
X/* 		fprintf(stderr, "inserting between %d and %d\n",prev_i,i);  */
X
X		strcpy(chordtab[nb_chord].chord_name,      chord);
X		if (nb_chord!=0)
X			chordtab[nb_chord].next_ptr=i;
X		else
X			chordtab[nb_chord].next_ptr = -1;
X		if (prev_i != -1)
X			chordtab[prev_i].next_ptr=nb_chord;
X		if (i==first_ptr)
X			first_ptr=nb_chord;
X                if (nb_chord >= MAX_CHORD-1) {
X		    fprintf(stderr, "too many chords, bumping %s\n",
X			chordtab[nb_chord-1].chord_name);
X		    return(nb_chord - 1);
X		}
X		nb_chord++;
X
X/*
X		fprintf(stderr, "dumping chordtab (start is %d)\n",first_ptr);
X		for (i=0; i<nb_chord;i++) 
X			fprintf(stderr, "	%d:	%10s -> %d\n",
X				i,chordtab[i].chord_name,chordtab[i].next_ptr);
X*/
X		return(nb_chord - 1);
X	}
X}
X
Xmoveto(new_hpos,new_vpos)
Xint	new_hpos,new_vpos;
X{
X	if (new_hpos + grid_size + L_MARGIN > WIDTH)
X		{
X		new_hpos = L_MARGIN;
X		new_vpos -= 2*grid_size;
X		}
X
X	if (new_vpos < BOTTOM)
X		{
X		do_end_of_page();
X		do_start_of_page();
X		new_vpos=TOP-2*grid_size;
X		}
X
X	printf ("%d %d moveto\n", new_hpos, new_vpos);
X	hpos=new_hpos;vpos = new_vpos;
X}
X
Xdraw_chords()
X	{
X	int ptr;
X	int idx;
X
X	moveto(WIDTH - grid_size - grid_size - L_MARGIN, vpos); 
X
X	ptr=first_ptr;
X	if (nb_chord != 0)
X		{
X		while (ptr != -1)
X			{
X			moveto(hpos + 2 * grid_size, vpos);
X
X			if ((idx=is_chord_known(chordtab[ptr].chord_name))==-1)
X				{
X				sprintf (mesg, "chord \'%s\' has never been defined",
X					chordtab[ptr].chord_name);
X				error(mesg);
X
X				printf("(%s) 0 0 0 0 0 0 1 dots\n",
X					 chordtab[ptr].chord_name);
X				}
X			else
X				printf("(%s) %d %d %d %d %d %d %d dots\n",
X					known_chords[idx].chord_name,
X					known_chords[idx].s1,
X					known_chords[idx].s2,
X					known_chords[idx].s3,
X					known_chords[idx].s4,
X					known_chords[idx].s5,
X					known_chords[idx].s6,
X					known_chords[idx].displ);
X			ptr = chordtab[ptr].next_ptr;
X	        	}
X		}
X	}
X
Xdo_define_chord()
X{
X	int dot_array[6];
X	char *chord_name;
X	char *temp_str;
X	int fret_displ;
X	int n;
X	int hardtoplay = 0;
X
X	for ( n=0; n<6; n++)
X		dot_array[n] = 0;
X
X	chord_name=(char *)strtok(NULL, DELIM_STR);
X	if (chord_name==NULL) {
X		error("syntax error in chord definition: no chord name");
X		return(0);
X	}
X
X	temp_str=(char *)strtok(NULL, DELIM_STR);
X	if (temp_str==NULL) {
X		error("syntax error in chord definition: no base fret position");
X		return(0);
X	}
X	fret_displ=atoi(temp_str);
X
X#ifdef DEBUGON
X	fprintf(stderr, "fret_displ = %d\n", fret_displ);
X#endif
X
X	for (n=5; n>=0; n--)
X		{
X		temp_str=(char *)strtok(NULL, DELIM_STR);
X
X#ifdef DEBUGON
X		fprintf(stderr, "n = %d and temp_str = [%s]\n", n, temp_str);
X#endif
X
X		if (temp_str!=NULL) {
X			if (!strcmp(temp_str, FRET_NONE_STR))
X				dot_array[n]=FRET_NONE;
X			else if (!strcasecmp(temp_str, FRET_X_STR))
X				dot_array[n]=FRET_X;
X			else {
X				dot_array[n]=atoi(temp_str);
X				if (dot_array[n] < 0) dot_array[n]=FRET_NONE;
X			}
X			hardtoplay=hardtoplay||(dot_array[n]>LONG_FINGERS);
X			}
X		else 
X			{
X			error("syntax error in chord definition : too few arguments");
X			return(0);
X			}
X		}
X
X	if (hardtoplay)
X		{
X		sprintf(mesg,
X		  "Warning: You'll need long fingers to play \"%s\" this way!", chord_name);
X		error (mesg);
X		}
X
X	learn_chord(chord_name,
X			dot_array[0],dot_array[1],dot_array[2],
X			dot_array[3],dot_array[4],dot_array[5],
X			fret_displ);
X}
X
Xlearn_chord(chord, s1, s2, s3, s4, s5, s6, displ)
Xchar 	*chord;
Xint	displ;
Xint	s1,s2,s3,s4,s5,s6;
X{
X        int i,not_found;
X
X        not_found=TRUE;
X        for (i=0;i < nb_known_chord && not_found; i++) {
X                not_found=strcmp(chord,known_chords[i].chord_name);
X        };
X
X        if (not_found) {
X                if (nb_known_chord >= MAX_CHORD-1) {
X		    fprintf(stderr, "too many chords, can't learn %s\n", chord);
X		    return(0);
X		}
X                nb_known_chord++;
X		} else {
X		i--;
X		} 
X
X        strcpy(known_chords[i].chord_name,chord);
X	known_chords[i].displ=displ;
X	known_chords[i].s1=s1;
X	known_chords[i].s2=s2;
X	known_chords[i].s3=s3;
X	known_chords[i].s4=s4;
X	known_chords[i].s5=s5;
X	known_chords[i].s6=s6;
X
X}
X
Xinit_known_chords()
X{
X	nb_known_chord=0;
X
X#define N FRET_NONE
X#define X FRET_X
X        learn_chord("Ab",     1,3,3,2,1,1,4);
X        learn_chord("Abm",    1,3,3,1,1,1,4);	/* G#m is preferred */
X        learn_chord("Ab7",    N,N,1,1,1,2,1);
X        learn_chord("Abm7",   N,N,1,1,1,1,4);	/* G#m7 is preferred */
X        learn_chord("Absus",  N,N,1,1,2,4,1);
X        learn_chord("Ab+",    N,N,2,1,1,0,1);
X        learn_chord("Abdim",  N,N,0,1,0,1,1);	/* G#dim is preferred */
X        learn_chord("Abmaj7", N,N,1,1,1,3,1);
X
X
X        learn_chord("A",      N,0,2,2,2,0,1);
X        learn_chord("Am",     N,0,2,2,1,0,1);
X        learn_chord("A7",     N,0,2,0,2,0,1);
X        learn_chord("Am7",    N,0,2,2,1,3,1);
X        learn_chord("Asus",   N,N,2,2,3,0,1);
X        learn_chord("A+",     N,0,3,2,2,1,1);
X        learn_chord("Adim",   N,N,1,2,1,2,1);
X        learn_chord("Amaj7",  N,0,2,1,2,0,1);
X
X        learn_chord("A#",     N,1,3,3,3,1,1);	/* Bb is preferred */
X        learn_chord("A#m",    N,1,3,3,2,1,1);	/* Bbm is preferred */
X        learn_chord("A#7",    N,N,1,1,1,2,3);	/* Bb7 is preferred */
X        learn_chord("A#m7",   N,1,3,1,2,1,1);	/* Bbm7 is preferred */
X        learn_chord("A#sus",  N,N,3,3,4,1,1);	/* Bbsus is preferred */
X        learn_chord("A#+",    N,N,0,3,3,2,1);	/* Bb+ is preferred */
X        learn_chord("A#dim",  N,N,2,3,2,3,1);	/* Bbdim is preferred */
X        learn_chord("A#maj7", N,1,3,2,3,N,1);	/* Bbmaj7 is preferred */
X
X        learn_chord("Bb",     N,1,3,3,3,1,1);
X        learn_chord("Bbm",    N,1,3,3,2,1,1);
X        learn_chord("Bb7",    N,N,1,1,1,2,3);
X        learn_chord("Bbm7",   N,1,3,1,2,1,1);
X        learn_chord("Bbsus",  N,N,3,3,4,1,1);
X        learn_chord("Bb+",    N,N,0,3,3,2,1);
X        learn_chord("Bbdim",  N,N,2,3,2,3,1);
X        learn_chord("Bbmaj7", N,1,3,2,3,N,1);
X
X        learn_chord("B",      N,2,4,4,4,2,1);
X        learn_chord("Bm",     N,2,4,4,3,2,1);
X        learn_chord("B7",     0,2,1,2,0,2,1);
X        learn_chord("Bm7",    N,1,3,1,2,1,2);
X        learn_chord("Bsus",   N,N,3,3,4,1,2);
X        learn_chord("B+",     N,N,1,0,0,4,1);
X        learn_chord("Bdim",   N,N,0,1,0,1,1);
X        learn_chord("Bmaj7",  N,2,4,3,4,N,1);
X
X        learn_chord("C",      N,3,2,0,1,0,1);
X        learn_chord("Cm",     N,1,3,3,2,1,3);
X        learn_chord("C7",     0,3,2,3,1,0,1);
X        learn_chord("Cm7",    N,1,3,1,2,1,3);
X        learn_chord("Csus",   N,N,3,0,1,3,1);
X        learn_chord("C+",     N,N,2,1,1,0,1);
X        learn_chord("Cdim",   N,N,1,2,1,2,1);
X        learn_chord("Cmaj7",  N,3,2,0,0,0,1);
X
X        learn_chord("C#",      N,N,3,1,2,1,1);	/* Db is preferred */
X        learn_chord("C#m",     N,N,2,1,2,0,1);
X        learn_chord("C#7",     N,N,3,4,2,4,1);	/* Db7 is preferred */
X        learn_chord("C#m7",    N,N,2,4,2,4,1);
X        learn_chord("C#sus",   N,N,3,3,4,1,4);	/* Dbsus is preferred */
X        learn_chord("C#+",     N,N,3,2,2,1,1);	/* Db+ is preferred */
X        learn_chord("C#dim",   N,N,2,3,2,3,1);
X        learn_chord("C#maj7",  N,4,3,1,1,1,1);	/* Dbmaj7 is preferred */
X
X        learn_chord("Db",      N,N,3,1,2,1,1);
X        learn_chord("Dbm",     N,N,2,1,2,0,1);	/* C#m is preferred */
X        learn_chord("Db7",     N,N,3,4,2,4,1);
X        learn_chord("Dbm7",    N,N,2,4,2,4,1);	/* C#m7 is prefered */
X        learn_chord("Dbsus",   N,N,3,3,4,1,4);
X        learn_chord("Db+",     N,N,3,2,2,1,1);	/* Db+ is preferred */
X        learn_chord("Dbdim",   N,N,2,3,2,3,1);
X        learn_chord("Dbmaj7",  N,4,3,1,1,1,1);
X
X        learn_chord("D",      N,N,0,2,3,2,1);
X        learn_chord("Dm",     N,N,0,2,3,1,1);
X        learn_chord("D7",     N,N,0,2,1,2,1);
X        learn_chord("Dm7",    N,N,0,2,1,1,1);
X        learn_chord("Dsus",   N,N,0,2,3,3,1);
X        learn_chord("D+",     N,N,0,3,3,2,1);
X        learn_chord("Ddim",   N,N,0,1,0,1,1);
X        learn_chord("Dmaj7",  N,N,0,2,2,2,1);
X
X        learn_chord("D#",      N,N,3,1,2,1,3);	/* Eb is preferred */
X        learn_chord("D#m",     N,N,4,3,4,2,1);	/* Ebm is preferred */
X        learn_chord("D#7",     N,N,1,3,2,3,1);	/* Eb7 is preferred */
X        learn_chord("D#m7",    N,N,1,3,2,2,1);	/* Ebm7 is preferred */
X        learn_chord("D#sus",   N,N,1,3,4,4,1);	/* Ebsus is preferred */
X        learn_chord("D#+",     N,N,1,0,0,4,1);	/* Eb+ is preferred */
X        learn_chord("D#dim",   N,N,1,2,1,2,1);
X        learn_chord("D#maj7",  N,N,1,3,3,3,1);	/* Ebmaj7 is preferred */
X
X        learn_chord("Eb",      N,N,3,1,2,1,3);
X        learn_chord("Ebm",     N,N,4,3,4,2,1);
X        learn_chord("Eb7",     N,N,1,3,2,3,1);
X        learn_chord("Ebm7",    N,N,1,3,2,2,1);
X        learn_chord("Ebsus",   N,N,1,3,4,4,1);
X        learn_chord("Eb+",     N,N,1,0,0,4,1);
X        learn_chord("Ebdim",   N,N,1,2,1,2,1);	/* D#dim is preferred */
X        learn_chord("Ebmaj7",  N,N,1,3,3,3,1);
X
X        learn_chord("E",      0,2,2,1,0,0,1);
X        learn_chord("Em",     0,2,2,0,0,0,1);
X        learn_chord("E7",     0,2,2,1,3,0,1);
X        learn_chord("Em7",    0,2,2,0,3,0,1);
X        learn_chord("Esus",   0,2,2,2,0,0,1);
X        learn_chord("E+",     N,N,2,1,1,0,1);
X        learn_chord("Edim",   N,N,2,3,2,3,1);
X        learn_chord("Emaj7",  0,2,1,1,0,N,1);
X
X        learn_chord("F",      1,3,3,2,1,1,1);
X        learn_chord("Fm",     1,3,3,1,1,1,1);
X        learn_chord("F7",     1,3,1,2,1,1,1);
X        learn_chord("Fm7",    1,3,1,1,1,1,1);
X        learn_chord("Fsus",   N,N,3,3,1,1,1);
X        learn_chord("F+",     N,N,3,2,2,1,1);
X        learn_chord("Fdim",   N,N,0,1,0,1,1);
X        learn_chord("Fmaj7",  N,3,3,2,1,0,1);
X
X        learn_chord("F#",     2,4,4,3,2,2,1);	/* or Gb */
X        learn_chord("F#m",    2,4,4,2,2,2,1);	/* or Gbm */
X        learn_chord("F#7",    N,N,4,3,2,0,1);	/* or Gb7 */
X        learn_chord("F#m7",   N,N,2,2,2,2,1);	/* or Gbm7 */
X        learn_chord("F#sus",  N,N,4,4,2,2,1);	/* or Gbsus */
X        learn_chord("F#+",    N,N,4,3,3,2,1);	/* or Gb+ */
X        learn_chord("F#dim",  N,N,1,2,1,2,1);	/* or Gbdim */
X        learn_chord("F#maj7", N,N,4,3,2,1,1);	/* Gbdim is preferred */
X
X        learn_chord("Gb",     2,4,4,3,2,2,1);	/* or F# */
X        learn_chord("Gbm",    2,4,4,2,2,2,1);	/* or F#m */
X        learn_chord("Gb7",    N,N,4,3,2,0,1);	/* or F#7 */
X        learn_chord("Gbm7",   N,N,2,2,2,2,1);	/* or F#m7 */
X        learn_chord("Gbsus",  N,N,4,4,2,2,1);	/* or F#sus */
X        learn_chord("Gb+",    N,N,4,3,3,2,1);	/* or F#+ */
X        learn_chord("Gbdim",  N,N,1,2,1,2,1);	/* or F#dim */
X        learn_chord("Gbmaj7", N,N,4,3,2,1,1);
X
X        learn_chord("G",      3,2,0,0,0,3,1);
X        learn_chord("Gm",     1,3,3,1,1,1,3);
X        learn_chord("G7",     3,2,0,0,0,1,1);
X        learn_chord("Gm7",    1,3,1,1,1,1,3);
X        learn_chord("Gsus",   N,N,0,0,1,3,1);
X        learn_chord("G+",     N,N,1,0,0,4,1);
X        learn_chord("Gdim",   N,N,2,3,2,3,1);
X        learn_chord("Gmaj7",  N,N,1,2,3,4,2);
X
X        learn_chord("G#",     1,3,3,2,1,1,4);	/* Ab is preferred */
X        learn_chord("G#m",    1,3,3,1,1,1,4);
X        learn_chord("G#7",    N,N,1,1,1,2,1);	/* Ab7 is preferred */
X        learn_chord("G#m7",   N,N,1,1,1,1,4);
X        learn_chord("G#sus",  N,N,1,1,2,4,1);	/* Absus is preferred */
X        learn_chord("G#+",    N,N,2,1,1,0,1);	/* Ab+ is preferred */
X        learn_chord("G#dim",  N,N,0,1,0,1,1);
X        learn_chord("G#maj7", N,N,1,1,1,3,1);	/* Abmaj7 is preferred */
X#undef N
X#undef X
X}
X
Xis_chord_known(chord)
Xchar *chord;
X{
X        int i;
X
X        for (i=0;i < nb_known_chord;i++)
X                if (!strcmp(chord,known_chords[i].chord_name))
X			return (i);
X	return(-1);
X}
X
Xdump_fret(fretnum)
X{
X	if (fretnum == FRET_NONE) printf("  %2s", FRET_NONE_STR);
X	else if (fretnum == FRET_X) printf("  %2s", FRET_X_STR);
X	else printf("  %2d", fretnum);
X}
X
Xdump_chords()
X{
X	int i;
X
X	printf ("#Chord		pos 1st 2nd 3rd 4th 5th 6th\n");
X	for (i=0;i < nb_known_chord;i++) {
X		printf("{define %s	%2d",
X			known_chords[i].chord_name, known_chords[i].displ);
X		dump_fret(known_chords[i].s6);
X		dump_fret(known_chords[i].s5);
X		dump_fret(known_chords[i].s4);
X		dump_fret(known_chords[i].s3);
X		dump_fret(known_chords[i].s2);
X		dump_fret(known_chords[i].s1);
X		printf("}\n");
X	}
X}
SHAR_EOF
chmod 0666 grid.c ||
echo 'restore of grid.c failed'
Wc_c="`wc -c < 'grid.c'`"
test 15970 -eq "$Wc_c" ||
	echo 'grid.c: original size 15970, current size' "$Wc_c"
fi
# ============= chord.man ==============
if test -f 'chord.man' -a X"$1" != X"-c"; then
	echo 'x - skipping chord.man (File already exists)'
else
echo 'x - extracting chord.man (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'chord.man' &&
X.TH chord l "27 August 1992" "Utilities"
X.SH NAME
Xchord \- format lyrics and chord file
X.SH SYNOPSIS
X.B chord
X[-option ...] [ filename... ]
X.SH DESCRIPTION
X.I chord
Xproduces a postscript document from a lyrics file containing chord
Xindications and chorus delimiters. If no file name is supplied, 
X.I chord
Xreads from the standard input.
XThe document produced contains the lyrics of a song, with the guitar chords
Xappearing above the right words. A representation of all chords used in the
Xsong is printed at the bottom of the last page.
X
X.SH OPTIONS
X.TP 8
X.B \-c \fIchord_font size\fB
XSets the size, in points, of the font used to display chords to the specified
Xinteger value.
X.TP 8
X.B \-C \fIChord_font\fB
XSets the font used to print chords to the specified name. That name must be
Xknown to your PostScript Interpreter.
X.TP 8
X.B \-d
XDumps the list and description of all internally known chords.
X.TP 8
X.B \-D
XPrints debugging information. For programmers only.
X.TP 8
X.B \-g \fIgrid_size\fB
XSets the size of the chord grids.
X.TP 8
X.B \-h
XPrints a short options summary.
X.TP 8
X.B \-l
XPrints only the lyrics of the song.
X.TP 8
X.B \-t \fItext_font size\fB
XSets the size, in points, of the font used to display the lyrics to the
Xspecified integer value. The title
Xline is displayed using that point size + 5. The sub-tiltle is displayed
Xusing that point size -2.
X.TP 8
X.B \-T \fIText_font\fB
XSets the font used to print text to the specified name. That name must be
Xknown to your PostScript Interpreter.
X.TP 8
X.B \-V
XPrints version and patch level
X.TP 8
X.B \-x \fIhalf-tones\fB
XSets up transposition to that number of half-tones. Can not be zero. All
Xchord names must be build in the following way in order to be recognized:
X
X{note-name}[#|b][^/]* [ '/' {note-name}[#|b][^/]* ]
X
XThat is, a valid note name, possibly followed by '#' or 'b', followed by
Xother modifier ('7', 'm', etc...). Many such construct can make up a chord
Xname, as long as they are separated by '/'.
X
X{note-name} must appear in the list 'A','B','C','D','E','F','G'.
X.TP 8
X.B \-2
XPrints two logical pages per physical page.
X.TP 8
X.B \-4
XPrints four logical pages per physical page.
X.TP
X.BI \-i " file"
XGenerates a table of contents with the song titles and page numbers.  If \fIfile\fR is "-" the table of contents is written to stderr.
X.TP
X.B \-a 
XAutomatically single spaces lines that have no chords.
X.TP
X.BI \-p " first_page" 
XNumbers the pages consecutively starting with \fIfirst_page\fR (e.g. 1).
XWithout this option, each song restarts the page numbering at 1, and page
Xnumbers are only put on subsequent pages of multiple page songs.
X.TP
X.B \-R 
XPlaces the odd and even page numbers in the lower right and left corners respectively (for two-sided output).  The default is all page numbers on the right.
X.TP
X.B \-L 
XPlaces the odd page numbers on the left.
X
X.SH KEYWORDS
XA line starting with a '#' is interpreted as a comment, and generates no output.
X(although all your comments are automatically mailed to the authors, and we read them
Xat parties...)
X
XDirectives that  appear between french brackets ('{' and '}') have a
Xspecial meaning. They must be alone on a line. Blanks before the
Xopening bracket and after the closing bracket are not significant.
X
XBlanks inside a directive are significant.
X
XKnown directives are:
X.TP 8
X.B \fBstart_of_chorus\fR or \fBsoc\fR
Xwhich indicates the start of a chorus (yep). The complete chorus will
Xbe highlighted by a change bar, to be easily located by the player.
X.TP 8
X.B \fBend_of_chorus\fR or \fBeoc\fR
Xmarks the end of the chorus
X.TP 8
X.B \fBcomment:\fR or \fBc:\fR
Xwill call the printing of the rest of the line, highlighted by a grey box
X(Useful to call a chorus, for example)
X.TP 8
X.B \fBnew_song\fR or \fBns\fR
Xmarks the beginning of a new song. It enables you to put multiple songs
Xin one file. It is not required at the beginning of the file.
X.TP 8
X.B \fBtitle:\fR or \fBt:\fR
Xspecifies the title of the song. It will appear centered at the top of the first
Xpage, and at the bottom of every other page, accompanied there by the
Xpage number, within the current song.
X.TP 8
X.B \fBsubtitle:\fR or \fBst:\fR
Xspecifies a string to be printed right below the title. Many subtitles can be
Xspecified
X.TP 8
X.B \fBdefine: name offset str1 ... str6\fB
Xdefines a new chord called "name", starting at fret "offset".
XThe following numbers
Xare the fret number [ 1 to n ] for each string [str1 to str6]
Xand are RELATIVE to the offset.  A value of "-" as 
Xthe fret number on a string means that string is not played.
XOpen strings indicated with a fret value of 0 are represented by a small open circle above the string.
XA value of "x" or "X" as the fret number means that string is to be buffed,
Xor silenced. This will be represented by an "x" appearing above the string.
XThe strings are numbered in descending order of tonality, starting on the
Xhigh E (the bottom string).
X
XAt the beginning of every song, the default chords are loaded and the ~/.chordrc
Xfile is re-read. Definition of new chords are preserved for the remainder of the
Xexecution, or until redefined by the user.
X.TP 8
X.B textfont: postscript_font
Xsame as -T command option
X.TP 8
X.B textsize: n
Xsame as -t command option
X.TP 8
X.B chordfont: postscript_font
Xsame as -C command option
X.TP 8
X.B chordsize: n
Xsame as -c command option
X.SH FILES
X.TP 8
X.B $HOME/.chordrc
XInitial directives re-read after each song.
X.SH COPYRIGHT
XCopyright 1992 by Martin Leclerc and Mario Dorion
X.SH AUTHORS
XMartin Leclerc
X(martin.lecl...@canada.sun.com)
X
XMario Dorion
X(mario.dor...@canada.sun.com)
X
X
X.SH CONTRIBUTORS
XSteve Putz (p...@parc.xerox.com)
XJim Gerland (GERL...@ubvms.cc.buffalo.edu)
SHAR_EOF
chmod 0666 chord.man ||
echo 'restore of chord.man failed'
Wc_c="`wc -c < 'chord.man'`"
test 5646 -eq "$Wc_c" ||
	echo 'chord.man: original size 5646, current size' "$Wc_c"
fi
# ============= Makefile ==============
if test -f 'Makefile' -a X"$1" != X"-c"; then
	echo 'x - skipping Makefile (File already exists)'
else
echo 'x - extracting Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
X# add -DDEBUG if needed.. ml
XCC = cc 
XCFLAGS = -g 
XBINDIR = /disk2/martin/bin/elf
XMANDIR = /usr/man
XMANEXT = l
X
XSRC = transpose.c iso.c chord.c grid.c chord.man Makefile
XVMSSTUFF = makefile.vms chord.rnh argproc.c
XINCL = chord.h
XOBJ = grid.o iso.o chord.o transpose.o
XSONGS = songs/heaven songs/you_ve_got_a_friend
X
Xall: chord
X
Xchord : $(OBJ) $(INCL)
X	$(CC) $(CFLAGS) -o chord $(OBJ)
X
Xinstall : all
X	cp chord $(BINDIR)
X	rm -f $(MANDIR)/cat$(MANEXT)/chord.$(MANEXT)
X	cp chord.man $(MANDIR)/man$(MANEXT)/chord.$(MANEXT)
X	chmod 666 $(MANDIR)/man$(MANEXT)/chord.$(MANEXT)
X	
Xshar : $(SRC)
X	shar -F -l 60 -o chord.part $(SRC) $(INCL) $(SONGS) $(VMSSTUFF) README
X
Xlint : $(SRC)
X	lint iso.c chord.c grid.c 
X
Xclean:
X	rm -f core *.o chord 
SHAR_EOF
chmod 0666 Makefile ||
echo 'restore of Makefile failed'
Wc_c="`wc -c < 'Makefile'`"
test 730 -eq "$Wc_c" ||
	echo 'Makefile: original size 730, current size' "$Wc_c"
fi
# ============= chord.h ==============
if test -f 'chord.h' -a X"$1" != X"-c"; then
	echo 'x - skipping chord.h (File already exists)'
else
echo 'x - extracting chord.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'chord.h' &&
X#include <stdio.h>
X
X#define VERSION "1.2"
X#define PATCH_LEVEL "0"
X
X#define TRUE 1
X#define FALSE 0
X
X#define MAXLINE 256
X#define MAXFONTS 16   /* Maximum number of different fonts in one execution */
X#define MAXTOKEN 256
X#define MAX_CHORD 256
X#define CHORD_NAME_SZ   32
X#define MAXNOTE 8
X
X#define LONG_FINGERS	4
X#define FRET_NONE_STR	"-"		/* fret value for unplayed strings */
X#define FRET_NONE	-2		/* internal numeric value */
X#define FRET_X_STR	"x"		/* fret value for muted strings */
X#define FRET_X		-1		/* internal value (must be -1) */
X
X#define TOP 756         /* 10.5 inches in points */
X#define BOTTOM 36        /* 0.5 inch in points */
X#define L_MARGIN 72      /* 1 inch in points */
X#define WIDTH 612        /* 8.5 inches in points */
X
X#define DELIM_STR       ": \t"
X
X#define DEF_TEXT_SIZE 12
X#define DEF_CHORD_SIZE 9
X#define DEF_GRID_SIZE 30
X#define DEF_TEXT_FONT "Times-Roman"
X#define DEF_CHORD_FONT "Helvetica-Oblique"
X
X#define scale2 .75
X#define scale4 .475
X
Xstruct chord_struct {
X	int  next_ptr;
X	char chord_name[CHORD_NAME_SZ];
X	};
X
SHAR_EOF
chmod 0666 chord.h ||
echo 'restore of chord.h failed'
Wc_c="`wc -c < 'chord.h'`"
test 1046 -eq "$Wc_c" ||
	echo 'chord.h: original size 1046, current size' "$Wc_c"
fi
true || echo 'restore of songs/heaven failed'
echo End of part 1, continue with part 2
exit 0
