2 (c) 2004-2005: Jelmer Vernooij <jelmer@samba.org>
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 2 of the License, or
7 (at your option) any later version.
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.
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.
24 #include <libxml/xmlmemory.h>
25 #include <libxml/parser.h>
27 #define DTD_URL "http://jelmer.vernstok.nl/oss/ptabtools/svn/trunk/ptbxml.dtd"
40 # include <libxslt/xslt.h>
41 # include <libxslt/transform.h>
44 #define SMART_ADD_PROP_INT(parent, name, contents) { \
46 snprintf(tmpc, 100, "%d", contents); \
47 xmlSetProp(parent, name, tmpc); \
51 #define SMART_ADD_CHILD_STRING(parent, name, contents) xmlNewTextChild(parent, NULL, name, contents)
52 #define SMART_ADD_CHILD_INT(parent, name, contents) { \
54 xmlNodePtr tmp = xmlNewNode(NULL, name); \
55 snprintf(tmpc, 100, "%d", contents); \
56 xmlNodeSetContent(tmp, tmpc); \
57 xmlAddChild(parent, tmp); \
60 #define SMART_ADD_CHILD_XINT(parent, name, contents) { \
62 xmlNodePtr tmp = xmlNewNode(NULL, name); \
63 snprintf(tmpc, 100, "%x", contents); \
64 xmlNodeSetContent(tmp, tmpc); \
65 xmlAddChild(parent, tmp); \
68 xmlNodePtr xml_write_font(const char *name, struct ptb_font *font)
70 xmlNodePtr xfont = xmlNewNode(NULL, "font");
71 xmlSetProp(xfont, "function", name);
72 SMART_ADD_PROP_INT(xfont, "size", font->size);
73 SMART_ADD_PROP_INT(xfont, "thickness", font->thickness);
74 SMART_ADD_PROP_INT(xfont, "underlined", font->underlined);
75 SMART_ADD_PROP_INT(xfont, "italic", font->italic);
76 xmlSetProp(xfont, "family", font->family);
80 xmlNodePtr xml_write_directions(struct ptb_direction *directions)
82 xmlNodePtr xdirections = xmlNewNode(NULL, "directions");
83 struct ptb_direction *direction = directions;
86 xmlNodePtr xdirection = xmlNewNode(NULL, "direction");
87 xmlAddChild(xdirections, xdirection);
89 direction = direction->next;
94 xmlNodePtr xml_write_rhythmslashes(struct ptb_rhythmslash *rhythmslashs)
96 xmlNodePtr xrhythmslashs = xmlNewNode(NULL, "rhythmslashs");
97 struct ptb_rhythmslash *rhythmslash = rhythmslashs;
100 xmlNodePtr xrhythmslash = xmlNewNode(NULL, "rhythmslash");
101 xmlAddChild(xrhythmslashs, xrhythmslash);
102 SMART_ADD_CHILD_INT(xrhythmslash, "properties", rhythmslash->properties);
103 SMART_ADD_PROP_INT(xrhythmslash, "offset", rhythmslash->offset);
104 SMART_ADD_CHILD_INT(xrhythmslash, "dotted", rhythmslash->dotted);
105 SMART_ADD_CHILD_INT(xrhythmslash, "length", rhythmslash->length);
107 rhythmslash = rhythmslash->next;
110 return xrhythmslashs;
113 xmlNodePtr xml_write_chordtexts(struct ptb_chordtext *chordtexts)
115 xmlNodePtr xchordtexts = xmlNewNode(NULL, "chordtexts");
116 struct ptb_chordtext *chordtext = chordtexts;
119 xmlNodePtr xchordtext = xmlNewNode(NULL, "chordtext");
120 xmlAddChild(xchordtexts, xchordtext);
122 SMART_ADD_CHILD_STRING(xchordtext, "note1", ptb_get_tone(chordtext->name[0]));
123 SMART_ADD_CHILD_STRING(xchordtext, "note2", ptb_get_tone(chordtext->name[1]));
124 SMART_ADD_PROP_INT(xchordtext, "offset", chordtext->offset);
125 SMART_ADD_CHILD_INT(xchordtext, "additions", chordtext->additions);
126 SMART_ADD_CHILD_INT(xchordtext, "alterations", chordtext->alterations);
127 SMART_ADD_CHILD_INT(xchordtext, "properties", chordtext->properties);
128 SMART_ADD_CHILD_INT(xchordtext, "VII", chordtext->VII);
130 chordtext = chordtext->next;
135 xmlNodePtr xml_write_musicbars(struct ptb_musicbar *musicbars)
137 xmlNodePtr xmusicbars = xmlNewNode(NULL, "musicbars");
138 struct ptb_musicbar *musicbar = musicbars;
141 xmlNodePtr xmusicbar = SMART_ADD_CHILD_STRING(xmusicbars, "musicbar", musicbar->description);
143 if(musicbar->letter != 0x7f) {
145 snprintf(tmp, 100, "%c", musicbar->letter);
146 xmlSetProp(xmusicbar, "letter", tmp);
149 musicbar = musicbar->next;
154 xmlNodePtr xml_write_linedatas(struct ptb_linedata *linedatas)
156 xmlNodePtr xlinedatas = xmlNewNode(NULL, "linedatas");
157 struct ptb_linedata *linedata = linedatas;
160 xmlNodePtr xlinedata = xmlNewNode(NULL, "linedata");
161 xmlAddChild(xlinedatas, xlinedata);
163 SMART_ADD_CHILD_INT(xlinedata, "string", linedata->detailed.string);
164 SMART_ADD_CHILD_INT(xlinedata, "fret", linedata->detailed.fret);
165 SMART_ADD_CHILD_INT(xlinedata, "properties", linedata->properties);
166 SMART_ADD_CHILD_INT(xlinedata, "transcribe", linedata->transcribe);
167 SMART_ADD_CHILD_INT(xlinedata, "conn_to_next", linedata->conn_to_next);
169 linedata = linedata->next;
174 xmlNodePtr xml_write_positions(struct ptb_position *positions)
176 xmlNodePtr xpositions = xmlNewNode(NULL, "positions");
177 struct ptb_position *position = positions;
180 xmlNodePtr xposition = xmlNewNode(NULL, "position");
181 xmlAddChild(xpositions, xposition);
183 SMART_ADD_PROP_INT(xposition, "offset", position->offset);
184 SMART_ADD_CHILD_INT(xposition, "dots", position->dots);
185 SMART_ADD_CHILD_INT(xposition, "length", position->length);
186 SMART_ADD_CHILD_INT(xposition, "properties", position->properties);
187 SMART_ADD_CHILD_INT(xposition, "fermenta", position->fermenta);
189 xmlAddChild(xposition, xml_write_linedatas(position->linedatas));
191 position = position->next;
196 xmlNodePtr xml_write_staffs(struct ptb_staff *staffs)
198 xmlNodePtr xstaffs = xmlNewNode(NULL, "staffs");
199 struct ptb_staff *staff = staffs;
203 xmlNodePtr xstaff = xmlNewNode(NULL, "staff");
204 xmlAddChild(xstaffs, xstaff);
206 SMART_ADD_CHILD_INT(xstaff, "highest_note", staff->highest_note);
207 SMART_ADD_CHILD_INT(xstaff, "lowest_note", staff->lowest_note);
208 SMART_ADD_CHILD_INT(xstaff, "properties", staff->properties);
210 for(i = 0; i < 2; i++)
211 xmlAddChild(xstaff, xml_write_positions(staff->positions[i]));
218 xmlNodePtr xml_write_sections(struct ptb_section *sections)
220 xmlNodePtr sctns = xmlNewNode(NULL, "sections");
221 struct ptb_section *section = sections;
224 xmlNodePtr meter_type;
225 xmlNodePtr xsection = xmlNewNode(NULL, "section");
227 xmlAddChild(sctns, xsection);
229 if(section->letter != 0x7f) {
231 snprintf(tmp, 100, "%c", section->letter);
232 xmlSetProp(xsection, "letter", tmp);
235 switch(section->end_mark) {
236 case END_MARK_TYPE_NORMAL:
237 SMART_ADD_CHILD_STRING(xsection, "end-mark", "normal");
239 case END_MARK_TYPE_REPEAT:
240 SMART_ADD_CHILD_STRING(xsection, "end-mark", "repeat");
244 meter_type = xmlNewNode(NULL, "meter-type");
245 xmlAddChild(xsection, meter_type);
247 if(section->meter_type & METER_TYPE_BEAM_2) SMART_ADD_CHILD_STRING(meter_type, "beam_2", "");
248 if(section->meter_type & METER_TYPE_BEAM_3) SMART_ADD_CHILD_STRING(meter_type, "beam_3", "");
249 if(section->meter_type & METER_TYPE_BEAM_4) SMART_ADD_CHILD_STRING(meter_type, "beam_4", "");
250 if(section->meter_type & METER_TYPE_BEAM_5) SMART_ADD_CHILD_STRING(meter_type, "beam_5", "");
251 if(section->meter_type & METER_TYPE_BEAM_6) SMART_ADD_CHILD_STRING(meter_type, "beam_6", "");
252 if(section->meter_type & METER_TYPE_COMMON) SMART_ADD_CHILD_STRING(meter_type, "common", "");
253 if(section->meter_type & METER_TYPE_CUT) SMART_ADD_CHILD_STRING(meter_type, "cut", "");
254 if(section->meter_type & METER_TYPE_SHOW) SMART_ADD_CHILD_STRING(meter_type, "show", "");
256 SMART_ADD_CHILD_INT(xsection, "beat", section->detailed.beat);
257 SMART_ADD_CHILD_INT(xsection, "beat-value", section->detailed.beat_value);
258 SMART_ADD_CHILD_INT(xsection, "metronome-pulses-per-measure", section->metronome_pulses_per_measure);
259 SMART_ADD_CHILD_INT(xsection, "properties", section->properties);
260 SMART_ADD_CHILD_INT(xsection, "key-extra", section->key_extra);
261 SMART_ADD_CHILD_INT(xsection, "position-width", section->position_width);
262 SMART_ADD_CHILD_STRING(xsection, "description", section->description);
264 xmlAddChild(xsection, xml_write_chordtexts(section->chordtexts));
265 xmlAddChild(xsection, xml_write_rhythmslashes(section->rhythmslashes));
266 xmlAddChild(xsection, xml_write_directions(section->directions));
267 xmlAddChild(xsection, xml_write_staffs(section->staffs));
269 xmlAddChild(xsection, xml_write_musicbars(section->musicbars));
271 section = section->next;
277 xmlNodePtr xml_write_guitars(struct ptb_guitar *guitars, int instr)
279 xmlNodePtr gtrs = xmlNewNode(NULL, "guitars");
280 struct ptb_guitar *gtr = guitars;
285 xmlNodePtr xgtr = xmlNewNode(NULL, "guitar");
287 xmlAddChild(gtrs, xgtr);
289 snprintf(tmp, 100, "gtr-%d-%d", instr, gtr->index);
290 xmlSetProp(xgtr, "id", tmp);
292 strings = xmlNewNode(NULL, "tuning");
293 xmlAddChild(xgtr, strings);
295 for(i = 0; i < gtr->nr_strings; i++) {
296 const char *notenames[] = { "c", "cis", "d", "dis", "e", "f", "fis", "g", "gis", "a", "ais", "b" };
297 xmlNodePtr string = xmlNewNode(NULL, "stringtuning");
298 SMART_ADD_PROP_INT(string, "octave", gtr->strings[i]/12);
299 xmlSetProp(string, "note", notenames[gtr->strings[i]%12]);
300 xmlAddChild(strings, string);
303 SMART_ADD_CHILD_STRING(xgtr, "title", gtr->title);
304 SMART_ADD_CHILD_STRING(xgtr, "type", gtr->type);
305 SMART_ADD_CHILD_INT(xgtr, "reverb", gtr->reverb);
306 SMART_ADD_CHILD_INT(xgtr, "chorus", gtr->chorus);
307 SMART_ADD_CHILD_INT(xgtr, "tremolo", gtr->tremolo);
308 SMART_ADD_CHILD_INT(xgtr, "pan", gtr->pan);
309 SMART_ADD_CHILD_INT(xgtr, "capo", gtr->capo);
310 SMART_ADD_CHILD_INT(xgtr, "initial_volume", gtr->initial_volume);
311 SMART_ADD_CHILD_INT(xgtr, "midi_instrument", gtr->midi_instrument);
312 SMART_ADD_CHILD_INT(xgtr, "half_up", gtr->half_up);
313 SMART_ADD_CHILD_INT(xgtr, "simulate", gtr->simulate);
321 xmlNodePtr xml_write_guitarins(struct ptb_guitarin *guitarins)
323 struct ptb_guitarin *guitarin = guitarins;
324 xmlNodePtr xguitarins = xmlNewNode(NULL, "guitarins");
327 xmlNodePtr xguitarin = xmlNewNode(NULL, "guitarin");
328 xmlAddChild(xguitarins, xguitarin);
330 SMART_ADD_PROP_INT(xguitarin, "offset", guitarin->offset);
331 SMART_ADD_PROP_INT(xguitarin, "section", guitarin->section);
332 SMART_ADD_PROP_INT(xguitarin, "staff", guitarin->staff);
333 SMART_ADD_CHILD_INT(xguitarin, "rhythm_slash", guitarin->rhythm_slash);
334 SMART_ADD_CHILD_INT(xguitarin, "staff_in", guitarin->staff_in);
336 guitarin = guitarin->next;
342 xmlNodePtr xml_write_tempomarkers(struct ptb_tempomarker *tempomarkers)
344 struct ptb_tempomarker *tempomarker = tempomarkers;
345 xmlNodePtr xtempomarkers = xmlNewNode(NULL, "tempomarkers");
348 xmlNodePtr xtempomarker = SMART_ADD_CHILD_STRING(xtempomarkers, "tempomarker", tempomarker->description);
350 SMART_ADD_CHILD_INT(xtempomarker, "type", tempomarker->type);
351 SMART_ADD_PROP_INT(xtempomarker, "section", tempomarker->section);
352 SMART_ADD_PROP_INT(xtempomarker, "offset", tempomarker->offset);
353 SMART_ADD_CHILD_INT(xtempomarker, "bpm", tempomarker->bpm);
355 tempomarker = tempomarker->next;
358 return xtempomarkers;
361 xmlNodePtr xml_write_dynamics(struct ptb_dynamic *dynamics)
363 struct ptb_dynamic *dynamic = dynamics;
364 xmlNodePtr xdynamics = xmlNewNode(NULL, "dynamics");
367 xmlNodePtr xdynamic = xmlNewNode(NULL, "dynamic");
368 xmlAddChild(xdynamics, xdynamic);
370 SMART_ADD_PROP_INT(xdynamic, "offset", dynamic->offset);
372 dynamic = dynamic->next;
378 xmlNodePtr xml_write_chorddiagrams(struct ptb_chorddiagram *chorddiagrams)
380 struct ptb_chorddiagram *chorddiagram = chorddiagrams;
381 xmlNodePtr xchorddiagrams = xmlNewNode(NULL, "chorddiagrams");
383 while(chorddiagram) {
385 xmlNodePtr xchorddiagram = xmlNewNode(NULL, "chorddiagram");
386 xmlNodePtr strings = xmlNewNode(NULL, "strings");
387 xmlAddChild(xchorddiagrams, xchorddiagram);
388 xmlAddChild(xchorddiagram, strings);
390 SMART_ADD_CHILD_STRING(xchorddiagram, "note1", ptb_get_tone(chorddiagram->name[0]));
391 SMART_ADD_CHILD_STRING(xchorddiagram, "note2", ptb_get_tone(chorddiagram->name[1]));
392 SMART_ADD_CHILD_INT(xchorddiagram, "frets", chorddiagram->frets);
393 SMART_ADD_CHILD_INT(xchorddiagram, "type", chorddiagram->type);
395 for(i = 0; i < chorddiagram->nr_strings; i++) {
396 SMART_ADD_CHILD_INT(strings, "string", chorddiagram->tones[i]);
399 chorddiagram = chorddiagram->next;
402 return xchorddiagrams;
405 xmlNodePtr xml_write_sectionsymbols(struct ptb_sectionsymbol *sectionsymbols)
407 struct ptb_sectionsymbol *sectionsymbol = sectionsymbols;
408 xmlNodePtr xsectionsymbols = xmlNewNode(NULL, "sectionsymbols");
410 while(sectionsymbol) {
411 xmlNodePtr xsectionsymbol = xmlNewNode(NULL, "sectionsymbol");
412 xmlAddChild(xsectionsymbols, xsectionsymbol);
414 SMART_ADD_CHILD_INT(xsectionsymbol, "repeat-ending", sectionsymbol->repeat_ending);
416 sectionsymbol = sectionsymbol->next;
419 return xsectionsymbols;
422 xmlNodePtr xml_write_floatingtexts(struct ptb_floatingtext *floatingtexts)
424 struct ptb_floatingtext *floatingtext = floatingtexts;
425 xmlNodePtr xfloatingtexts = xmlNewNode(NULL, "floatingtexts");
427 while(floatingtext) {
428 xmlNodePtr xfloatingtext = SMART_ADD_CHILD_STRING(xfloatingtexts, "floatingtext", floatingtext->text);
430 SMART_ADD_PROP_INT(xfloatingtext, "offset", floatingtext->offset);
432 switch(floatingtext->alignment) {
434 SMART_ADD_CHILD_STRING(xfloatingtext, "alignment", "left");
437 SMART_ADD_CHILD_STRING(xfloatingtext, "alignment", "right");
440 SMART_ADD_CHILD_STRING(xfloatingtext, "alignment", "center");
444 xmlAddChild(xfloatingtext, xml_write_font("font", &floatingtext->font));
446 floatingtext = floatingtext->next;
449 return xfloatingtexts;
452 xmlNodePtr xml_write_instrument(struct ptbf *bf, int i)
455 xmlNodePtr instrument = xmlNewNode(NULL, "instrument");
456 snprintf(tmp, 100, "instr-%d", i);
457 xmlSetProp(instrument, "id", tmp);
459 xmlAddChild(instrument, xml_write_guitars(bf->instrument[i].guitars, i));
460 xmlAddChild(instrument, xml_write_sections(bf->instrument[i].sections));
461 xmlAddChild(instrument, xml_write_guitarins(bf->instrument[i].guitarins));
462 xmlAddChild(instrument, xml_write_chorddiagrams(bf->instrument[i].chorddiagrams));
463 xmlAddChild(instrument, xml_write_tempomarkers(bf->instrument[i].tempomarkers));
464 xmlAddChild(instrument, xml_write_dynamics(bf->instrument[i].dynamics));
465 xmlAddChild(instrument, xml_write_floatingtexts(bf->instrument[i].floatingtexts));
466 xmlAddChild(instrument, xml_write_sectionsymbols(bf->instrument[i].sectionsymbols));
470 xmlNodePtr xml_write_song_header(struct ptb_hdr *hdr)
472 xmlNodePtr song = xmlNewNode(NULL, "song");
474 SMART_ADD_CHILD_STRING(song, "title", hdr->class_info.song.title);
475 SMART_ADD_CHILD_STRING(song, "artist", hdr->class_info.song.artist);
476 SMART_ADD_CHILD_STRING(song, "words-by", hdr->class_info.song.words_by);
477 SMART_ADD_CHILD_STRING(song, "music-by", hdr->class_info.song.music_by);
478 SMART_ADD_CHILD_STRING(song, "arranged-by", hdr->class_info.song.arranged_by);
479 SMART_ADD_CHILD_STRING(song, "guitar-transcribed-by", hdr->class_info.song.guitar_transcribed_by);
480 SMART_ADD_CHILD_STRING(song, "bass-transcribed-by", hdr->class_info.song.bass_transcribed_by);
481 SMART_ADD_CHILD_STRING(song, "lyrics", hdr->class_info.song.lyrics);
482 SMART_ADD_CHILD_STRING(song, "copyright", hdr->class_info.song.copyright);
484 /* FIXME: Sub stuff */
489 xmlNodePtr xml_write_lesson_header(struct ptb_hdr *hdr)
491 xmlNodePtr lesson = xmlNewNode(NULL, "lesson");
493 SMART_ADD_CHILD_STRING(lesson, "title", hdr->class_info.lesson.title);
494 SMART_ADD_CHILD_STRING(lesson, "artist", hdr->class_info.lesson.artist);
495 SMART_ADD_CHILD_STRING(lesson, "author", hdr->class_info.lesson.author);
496 SMART_ADD_CHILD_STRING(lesson, "copyright", hdr->class_info.lesson.copyright);
498 switch(hdr->class_info.lesson.level) {
499 case LEVEL_BEGINNER: xmlSetProp(lesson, "level", "beginner"); break;
500 case LEVEL_INTERMEDIATE: xmlSetProp(lesson, "level", "intermediate"); break;
501 case LEVEL_ADVANCED: xmlSetProp(lesson, "level", "advanced"); break;
509 xmlNodePtr xml_write_header(struct ptb_hdr *hdr)
511 xmlNodePtr header = xmlNewNode(NULL, "header");
512 switch(hdr->classification) {
513 case CLASSIFICATION_SONG:
514 xmlSetProp(header, "classification", "song");
515 xmlAddChild(header, xml_write_song_header(hdr));
517 case CLASSIFICATION_LESSON:
518 xmlSetProp(header, "classification", "lesson");
519 xmlAddChild(header, xml_write_lesson_header(hdr));
525 int main(int argc, const char **argv)
529 xmlNodePtr root_node;
534 int c, i, musicxml = 0;
536 const char *input = NULL;
540 int format_output = 1;
541 struct poptOption options[] = {
543 {"debug", 'd', POPT_ARG_NONE, &debugging, 0, "Turn on debugging output" },
544 {"outputfile", 'o', POPT_ARG_STRING, &output, 0, "Write to specified file", "FILE" },
545 {"musicxml", 'm', POPT_ARG_NONE, &musicxml, 'm', "Output MusicXML" },
546 {"no-format", 'f', POPT_ARG_NONE, &format_output, 0, "Don't format output" },
547 {"quiet", 'q', POPT_ARG_NONE, &quiet, 1, "Be quiet (no output to stderr)" },
548 {"version", 'v', POPT_ARG_NONE, &version, 'v', "Show version information" },
552 pc = poptGetContext(argv[0], argc, argv, options, 0);
553 poptSetOtherOptionHelp(pc, "file.ptb");
554 while((c = poptGetNextOpt(pc)) >= 0) {
557 printf("ptb2xml Version "PACKAGE_VERSION"\n");
558 printf("(C) 2004-2005 Jelmer Vernooij <jelmer@samba.org>\n");
564 ptb_set_debug(debugging);
566 if(!poptPeekArg(pc)) {
567 poptPrintUsage(pc, stderr, 0);
571 input = poptGetArg(pc);
572 if (!quiet) fprintf(stderr, "Parsing %s...\n", input);
573 ret = ptb_read_file(input);
576 perror("Read error: ");
581 int baselength = strlen(input);
582 if (!strcmp(input + strlen(input) - 4, ".ptb")) {
585 output = malloc(baselength + 6);
586 strncpy(output, input, baselength);
587 strcpy(output + baselength, ".xml");
590 if (!quiet) fprintf(stderr, "Building DOM tree...\n");
592 doc = xmlNewDoc(BAD_CAST "1.0");
593 root_node = xmlNewNode(NULL, BAD_CAST "powertab");
594 dtd = xmlCreateIntSubset(doc, "powertab", NULL, DTD_URL);
595 xmlDocSetRootElement(doc, root_node);
597 comment = xmlNewComment("\nGenerated by ptb2xml, part of ptabtools. \n"
598 "(C) 2004-2005 by Jelmer Vernooij <jelmer@samba.org>\n"
599 "See http://jelmer.vernstok.nl/oss/ptabtools/ for details\n");
600 xmlAddChild(root_node, comment);
602 xmlAddChild(root_node, xml_write_header(&ret->hdr));
604 for(i = 0; i < 2; i++) {
605 xmlAddChild(root_node, xml_write_instrument(ret, i));
608 fonts = xmlNewNode( NULL, "fonts"); xmlAddChild(root_node, fonts);
610 xmlAddChild(fonts, xml_write_font("default_font", &ret->default_font));
611 xmlAddChild(fonts, xml_write_font("chord_name_font", &ret->chord_name_font));
612 xmlAddChild(fonts, xml_write_font("tablature_font", &ret->tablature_font));
616 if (!quiet) fprintf(stderr, "Converting to MusicXML...\n");
618 xsltStylesheetPtr stylesheet = xsltParseStylesheetFile(MUSICXMLSTYLESHEET);
619 doc = xsltApplyStylesheet(stylesheet, doc, NULL);
620 xsltFreeStylesheet(stylesheet);
622 fprintf(stderr, "Conversion to MusicXML not possible in this version: libxslt not compiled in\n");
627 if (!quiet) fprintf(stderr, "Writing output to %s...\n", output);
629 if (xmlSaveFormatFile(output, doc, format_output) < 0) {