Fix compatibility with newer versions of lilypond.
[jelmer/ptabtools.git] / ptb2ascii.c
1 /*
2         (c) 2004: Jelmer Vernooij <jelmer@samba.org>
3
4         This program is free software; you can redistribute it and/or modify
5         it under the terms of the GNU General Public License as published by
6         the Free Software Foundation; either version 3 of the License, or
7         (at your option) any later version.
8
9         This program is distributed in the hope that it will be useful,
10         but WITHOUT ANY WARRANTY; without even the implied warranty of
11         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12         GNU General Public License for more details.
13
14         You should have received a copy of the GNU General Public License
15         along with this program; if not, write to the Free Software
16         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include <stdio.h>
20 #include <errno.h>
21 #include <popt.h>
22 #include <string.h>
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27
28 #ifdef HAVE_STDINT_H
29 #  include <stdint.h>
30 #endif
31
32 #include "ptb.h"
33
34
35 void ascii_write_header(FILE *out, struct ptbf *ret) 
36 {
37         if(ret->hdr.classification == CLASSIFICATION_SONG) {
38                 if(ret->hdr.class_info.song.title)      fprintf(out, "  Title: %s\n", ret->hdr.class_info.song.title);
39                 if(ret->hdr.class_info.song.music_by) fprintf(out, "  Music By: %s\n", ret->hdr.class_info.song.music_by);
40                 if(ret->hdr.class_info.song.words_by) fprintf(out, "  Words By: %s\n", ret->hdr.class_info.song.words_by);
41                 if(ret->hdr.class_info.song.copyright) fprintf(out, "  Copyright: %s\n", ret->hdr.class_info.song.copyright);
42                 if(ret->hdr.class_info.song.guitar_transcribed_by) fprintf(out, "  Transcribed By: %s\n", ret->hdr.class_info.song.guitar_transcribed_by);
43                 if(ret->hdr.class_info.song.release_type == RELEASE_TYPE_PR_AUDIO &&
44                    ret->hdr.class_info.song.release_info.pr_audio.album_title) fprintf(out, "  Album Title: %s\n", ret->hdr.class_info.song.release_info.pr_audio.album_title);
45         } else if(ret->hdr.classification == CLASSIFICATION_LESSON) {
46                 if(ret->hdr.class_info.lesson.title)    fprintf(out, "  Title: %s\n", ret->hdr.class_info.lesson.title);
47                 if(ret->hdr.class_info.lesson.artist) fprintf(out, "  Artist: %s\n", ret->hdr.class_info.lesson.artist);
48                 if(ret->hdr.class_info.lesson.author) fprintf(out, "  Transcribed By: %s\n", ret->hdr.class_info.lesson.author);
49                 if(ret->hdr.class_info.lesson.copyright) fprintf(out, "  Copyright: %s\n", ret->hdr.class_info.lesson.copyright);
50         }
51         fprintf(out, "\n");
52 }
53
54 int ascii_write_position(FILE *out, struct ptb_position *pos, int string)
55 {
56         struct ptb_linedata *d = pos->linedatas;
57
58         while(d) {
59                 if(string == (int)d->detailed.string) {
60                         return fprintf(out, "%d", d->detailed.fret);
61                 } 
62
63                 d = d->next;
64         }
65
66         return 0;
67 }
68
69
70 void ascii_write_chordtext(FILE *out, struct ptb_chordtext *name) {
71         if(name->properties & CHORDTEXT_PROPERTY_NOCHORD) {
72                 fprintf(out, "N.C.");
73         }
74
75         if(name->properties & CHORDTEXT_PROPERTY_PARENTHESES) {
76                 fprintf(out, "(");
77         }
78
79         if(!(name->properties & CHORDTEXT_PROPERTY_NOCHORD) | 
80            (name->properties & CHORDTEXT_PROPERTY_PARENTHESES)) {
81                 if(name->name[0] == name->name[1]) {
82                         fprintf(out, "%s", ptb_get_tone(name->name[0]));
83                 } else { 
84                         fprintf(out, "%s/%s", ptb_get_tone(name->name[0]),
85                                                 ptb_get_tone(name->name[1]));
86                 }
87         }
88
89         if(name->properties & CHORDTEXT_PROPERTY_PARENTHESES) {
90                 fprintf(out, ")");
91         }
92
93         fprintf(out, " ");
94 }
95
96 void ascii_write_staff(FILE *out, struct ptb_staff *s) 
97 {
98         int i;
99
100         for(i = 0; i < 6; i++) {
101                 int j;
102                 for(j = 0; j < 2; j++) {
103                         struct ptb_position *p = s->positions[j];
104                         while(p) {
105                                 int ret = ascii_write_position(out, p, i);
106                                 for(; ret < 4; ret++) fprintf(out, "-");
107                                 p = p->next;
108                         }
109                 }
110
111                 fprintf(out, "\n");
112         }
113 }
114
115 void ascii_write_section(FILE *out, struct ptb_section *s) 
116 {
117         struct ptb_chordtext *ct = s->chordtexts;
118         struct ptb_staff *st = s->staffs;
119
120         if(s->letter != 0x7f) {
121                 fprintf(out, "%c. %s\n", s->letter, s->description);
122         }
123
124         while(ct) {
125                 ascii_write_chordtext(out, ct);
126                 ct = ct->next;
127         }
128         fprintf(out, "\n");
129         
130         while(st) {
131                 ascii_write_staff(out, st);
132                 st = st->next;
133                 if(st)fprintf(out, "|\n");
134         }
135 }
136
137 int ascii_write_lyrics(FILE *out, struct ptbf *ret)
138 {
139         if(ret->hdr.classification != CLASSIFICATION_SONG || !ret->hdr.class_info.song.lyrics) return 0;
140         fprintf(out, "\nLyrics:\n");
141         fprintf(out, "%s\n\n", ret->hdr.class_info.song.lyrics);
142         return 1;
143 }
144
145 int ascii_write_chords(FILE *out, struct ptbf *ret)
146 {
147         /* FIXME:
148          * acc =  \chords {
149     % why don't \skip, s4 work?
150         c2 c f c
151         f c g:7 c
152     g f c  g:7 % urg, bug!
153         g f c  g:7
154     % copy 1-8
155         c2 c f c
156         f c g:7 c
157 }
158 */
159
160         return 0;
161 }
162
163 int main(int argc, const char **argv) 
164 {
165         FILE *out;
166         struct ptbf *ret;
167         int debugging = 0;
168         struct ptb_section *section;
169         int instrument = 0;
170         int c;
171         int version = 0;
172         const char *input;
173         char *output = NULL;
174         poptContext pc;
175         struct poptOption options[] = {
176                 POPT_AUTOHELP
177                 {"debug", 'd', POPT_ARG_NONE, &debugging, 0, "Turn on debugging output" },
178                 {"outputfile", 'o', POPT_ARG_STRING, &output, 0, "Write to specified file", "FILE" },
179                 {"regular", 'r', POPT_ARG_NONE, &instrument, 0, "Write tabs for regular guitar" },
180                 {"bass", 'b', POPT_ARG_NONE, &instrument, 1, "Write tabs for bass guitar"},
181                 {"version", 'v', POPT_ARG_NONE, &version, 'v', "Show version information" },
182                 POPT_TABLEEND
183         };
184
185         pc = poptGetContext(argv[0], argc, argv, options, 0);
186         poptSetOtherOptionHelp(pc, "file.ptb");
187         while((c = poptGetNextOpt(pc)) >= 0) {
188                 switch(c) {
189                 case 'v':
190                         printf("ptb2ascii Version "PACKAGE_VERSION"\n");
191                         printf("(C) 2004 Jelmer Vernooij <jelmer@samba.org>\n");
192                         exit(0);
193                         break;
194                 }
195         }
196                         
197         ptb_set_debug(debugging);
198         
199         if(!poptPeekArg(pc)) {
200                 poptPrintUsage(pc, stderr, 0);
201                 return -1;
202         }
203         input = poptGetArg(pc);
204         ret = ptb_read_file(input);
205         
206         if(!ret) {
207                 perror("Read error: ");
208                 return -1;
209         } 
210
211         if(!output) {
212                 int baselength = strlen(input);
213                 if (!strcmp(input + strlen(input) - 4, ".ptb")) {
214                         baselength -= 4;
215                 }
216                 output = malloc(baselength + 6);
217                 strncpy(output, input, baselength);
218                 strcpy(output + baselength, ".txt");
219         }
220
221         if(!strcmp(output, "-")) {
222                 out = stdout;
223         } else {
224                 out = fopen(output, "w+");
225                 if(!out) {
226                         perror("open");
227                         return -1;
228                 }
229         } 
230         
231         fprintf(out, "Generated by ptb2ascii (C) 2004 Jelmer Vernooij <jelmer@samba.org>\n");
232         fprintf(out, "See http://jelmer.vernstok.nl/oss/ptabtools/ for more info\n\n");
233                 
234         ascii_write_header(out, ret);
235         ascii_write_lyrics(out, ret);
236
237         section = ret->instrument[instrument].sections;
238         while(section) {
239                 ascii_write_section(out, section);
240                 fprintf(out, "\n\n");
241                 section = section->next;
242         }
243
244         if(output)fclose(out);
245         
246         return (ret?0:1);
247 }
248
249