/*
- (c) 2004: Jelmer Vernooij <jelmer@samba.org>
+ (c) 2004-2005: Jelmer Vernooij <jelmer@samba.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <stdio.h>
#include <errno.h>
+#include <string.h>
#include <popt.h>
-#include <sys/time.h>
#include <time.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
#include "ptb.h"
-#define SMART_ADD_CHILD_STRING(parent, name, contents) if(contents) { xmlNodePtr tmp = xmlNewNode(NULL, name); xmlNodeSetContent(tmp, contents); xmlAddChild(parent, tmp); }
-#define SMART_ADD_CHILD_INT(parent, name, contents) { char tmpc[100]; xmlNodePtr tmp = xmlNewNode(NULL, name); g_snprintf(tmpc, 100, "%d", contents); xmlNodeSetContent(tmp, tmpc); xmlAddChild(parent, tmp); }
-#define SMART_ADD_CHILD_XINT(parent, name, contents) { char tmpc[100]; xmlNodePtr tmp = xmlNewNode(NULL, name); g_snprintf(tmpc, 100, "%x", contents); xmlNodeSetContent(tmp, tmpc); xmlAddChild(parent, tmp); }
+#ifdef HAVE_XSLT
+# include <libxslt/xslt.h>
+# include <libxslt/transform.h>
+#endif
+
+#define SMART_ADD_CHILD_STRING(parent, name, contents) xmlNewTextChild(parent, NULL, name, contents)
+#define SMART_ADD_CHILD_INT(parent, name, contents) { \
+ char tmpc[100]; \
+ xmlNodePtr tmp = xmlNewNode(NULL, name); \
+ snprintf(tmpc, 100, "%d", contents); \
+ xmlNodeSetContent(tmp, tmpc); \
+ xmlAddChild(parent, tmp); \
+}
+
+#define SMART_ADD_CHILD_XINT(parent, name, contents) { \
+ char tmpc[100]; \
+ xmlNodePtr tmp = xmlNewNode(NULL, name); \
+ snprintf(tmpc, 100, "%x", contents); \
+ xmlNodeSetContent(tmp, tmpc); \
+ xmlAddChild(parent, tmp); \
+}
-xmlNodePtr xml_write_font(struct ptb_font *font)
+xmlNodePtr xml_write_font(const char *name, struct ptb_font *font)
{
- xmlNodePtr xfont = xmlNewNode(NULL, "font");
+ xmlNodePtr xfont = xmlNewNode(NULL, name);
char tmp[100];
- g_snprintf(tmp, 100, "%d", font->size); xmlSetProp(xfont, "size", tmp);
- g_snprintf(tmp, 100, "%d", font->thickness); xmlSetProp(xfont, "thickness", tmp);
- g_snprintf(tmp, 100, "%d", font->underlined); xmlSetProp(xfont, "underlined", tmp);
- g_snprintf(tmp, 100, "%d", font->italic); xmlSetProp(xfont, "italic", tmp);
+ snprintf(tmp, 100, "%d", font->size); xmlSetProp(xfont, "size", tmp);
+ snprintf(tmp, 100, "%d", font->thickness); xmlSetProp(xfont, "thickness", tmp);
+ snprintf(tmp, 100, "%d", font->underlined); xmlSetProp(xfont, "underlined", tmp);
+ snprintf(tmp, 100, "%d", font->italic); xmlSetProp(xfont, "italic", tmp);
xmlSetProp(xfont, "family", font->family);
return xfont;
}
-xmlNodePtr xml_write_directions(GList *directions)
+xmlNodePtr xml_write_directions(struct ptb_direction *directions)
{
xmlNodePtr xdirections = xmlNewNode(NULL, "directions");
- GList *gl = directions;
+ struct ptb_direction *direction = directions;
- while(gl) {
- struct ptb_direction *direction = gl->data;
+ while(direction) {
xmlNodePtr xdirection = xmlNewNode(NULL, "direction");
xmlAddChild(xdirections, xdirection);
- gl = gl->next;
+ direction = direction->next;
}
return xdirections;
}
-xmlNodePtr xml_write_rhythmslashes(GList *rhythmslashs)
+xmlNodePtr xml_write_rhythmslashes(struct ptb_rhythmslash *rhythmslashs)
{
xmlNodePtr xrhythmslashs = xmlNewNode(NULL, "rhythmslashs");
- GList *gl = rhythmslashs;
+ struct ptb_rhythmslash *rhythmslash = rhythmslashs;
- while(gl) {
- struct ptb_rhythmslash *rhythmslash = gl->data;
+ while(rhythmslash) {
xmlNodePtr xrhythmslash = xmlNewNode(NULL, "rhythmslash");
xmlAddChild(xrhythmslashs, xrhythmslash);
+ SMART_ADD_CHILD_INT(xrhythmslash, "properties", rhythmslash->properties);
+ SMART_ADD_CHILD_INT(xrhythmslash, "offset", rhythmslash->offset);
+ SMART_ADD_CHILD_INT(xrhythmslash, "dotted", rhythmslash->dotted);
+ SMART_ADD_CHILD_INT(xrhythmslash, "length", rhythmslash->length);
- gl = gl->next;
+ rhythmslash = rhythmslash->next;
}
return xrhythmslashs;
}
-xmlNodePtr xml_write_chordtexts(GList *chordtexts)
+xmlNodePtr xml_write_chordtexts(struct ptb_chordtext *chordtexts)
{
xmlNodePtr xchordtexts = xmlNewNode(NULL, "chordtexts");
- GList *gl = chordtexts;
+ struct ptb_chordtext *chordtext = chordtexts;
- while(gl) {
- struct ptb_chordtext *chordtext = gl->data;
+ while(chordtext) {
xmlNodePtr xchordtext = xmlNewNode(NULL, "chordtext");
xmlAddChild(xchordtexts, xchordtext);
SMART_ADD_CHILD_INT(xchordtext, "additions", chordtext->additions);
SMART_ADD_CHILD_INT(xchordtext, "alterations", chordtext->alterations);
SMART_ADD_CHILD_INT(xchordtext, "properties", chordtext->properties);
+ SMART_ADD_CHILD_INT(xchordtext, "VII", chordtext->VII);
- gl = gl->next;
+ chordtext = chordtext->next;
}
return xchordtexts;
}
-xmlNodePtr xml_write_musicbars(GList *musicbars)
+xmlNodePtr xml_write_musicbars(struct ptb_musicbar *musicbars)
{
xmlNodePtr xmusicbars = xmlNewNode(NULL, "musicbars");
- GList *gl = musicbars;
+ struct ptb_musicbar *musicbar = musicbars;
- while(gl) {
- struct ptb_musicbar *musicbar = gl->data;
- xmlNodePtr xmusicbar = xmlNewNode(NULL, "musicbar");
- xmlAddChild(xmusicbars, xmusicbar);
+ while(musicbar) {
+ xmlNodePtr xmusicbar = SMART_ADD_CHILD_STRING(xmusicbars, "musicbar", musicbar->description);
if(musicbar->letter != 0x7f) {
char tmp[100];
- g_snprintf(tmp, 100, "%c", musicbar->letter);
+ snprintf(tmp, 100, "%c", musicbar->letter);
xmlSetProp(xmusicbar, "letter", tmp);
}
- xmlNodeSetContent(xmusicbar, musicbar->description);
-
- gl = gl->next;
+ musicbar = musicbar->next;
}
return xmusicbars;
}
-xmlNodePtr xml_write_linedatas(GList *linedatas)
+xmlNodePtr xml_write_linedatas(struct ptb_linedata *linedatas)
{
xmlNodePtr xlinedatas = xmlNewNode(NULL, "linedatas");
- GList *gl = linedatas;
+ struct ptb_linedata *linedata = linedatas;
- while(gl) {
- struct ptb_linedata *linedata = gl->data;
+ while(linedata) {
xmlNodePtr xlinedata = xmlNewNode(NULL, "linedata");
xmlAddChild(xlinedatas, xlinedata);
- SMART_ADD_CHILD_INT(xlinedata, "tone", linedata->tone);
+ SMART_ADD_CHILD_INT(xlinedata, "string", linedata->detailed.string);
+ SMART_ADD_CHILD_INT(xlinedata, "fret", linedata->detailed.fret);
SMART_ADD_CHILD_INT(xlinedata, "properties", linedata->properties);
SMART_ADD_CHILD_INT(xlinedata, "transcribe", linedata->transcribe);
SMART_ADD_CHILD_INT(xlinedata, "conn_to_next", linedata->conn_to_next);
- gl = gl->next;
+ linedata = linedata->next;
}
return xlinedatas;
}
-xmlNodePtr xml_write_positions(GList *positions)
+xmlNodePtr xml_write_positions(struct ptb_position *positions)
{
xmlNodePtr xpositions = xmlNewNode(NULL, "positions");
- GList *gl = positions;
+ struct ptb_position *position = positions;
- while(gl) {
- struct ptb_position *position = gl->data;
+ while(position) {
xmlNodePtr xposition = xmlNewNode(NULL, "position");
xmlAddChild(xpositions, xposition);
xmlAddChild(xposition, xml_write_linedatas(position->linedatas));
- gl = gl->next;
+ position = position->next;
}
return xpositions;
}
-xmlNodePtr xml_write_staffs(GList *staffs)
+xmlNodePtr xml_write_staffs(struct ptb_staff *staffs)
{
xmlNodePtr xstaffs = xmlNewNode(NULL, "staffs");
- GList *gl = staffs;
+ struct ptb_staff *staff = staffs;
- while(gl) {
- struct ptb_staff *staff = gl->data;
+ while(staff) {
+ int i;
xmlNodePtr xstaff = xmlNewNode(NULL, "staff");
xmlAddChild(xstaffs, xstaff);
SMART_ADD_CHILD_INT(xstaff, "lowest_note", staff->lowest_note);
SMART_ADD_CHILD_INT(xstaff, "properties", staff->properties);
- xmlAddChild(xstaff, xml_write_positions(staff->positions1));
- xmlAddChild(xstaff, xml_write_musicbars(staff->musicbars));
+ for(i = 0; i < 2; i++)
+ xmlAddChild(xstaff, xml_write_positions(staff->positions[i]));
- gl = gl->next;
+ staff = staff->next;
}
return xstaffs;
}
-xmlNodePtr xml_write_sections(GList *sections)
+xmlNodePtr xml_write_sections(struct ptb_section *sections)
{
xmlNodePtr sctns = xmlNewNode(NULL, "sections");
- GList *gl = sections;
+ struct ptb_section *section = sections;
- while(gl) {
- struct ptb_section *section = gl->data;
+ while(section) {
xmlNodePtr meter_type;
xmlNodePtr xsection = xmlNewNode(NULL, "section");
if(section->letter != 0x7f) {
char tmp[100];
- g_snprintf(tmp, 100, "%c", section->letter);
+ snprintf(tmp, 100, "%c", section->letter);
xmlSetProp(xsection, "letter", tmp);
}
if(section->meter_type & METER_TYPE_CUT) SMART_ADD_CHILD_STRING(meter_type, "cut", "");
if(section->meter_type & METER_TYPE_SHOW) SMART_ADD_CHILD_STRING(meter_type, "show", "");
- SMART_ADD_CHILD_INT(xsection, "beat", section->beat_value);
+ SMART_ADD_CHILD_INT(xsection, "beat", section->detailed.beat);
+ SMART_ADD_CHILD_INT(xsection, "beat-value", section->detailed.beat_value);
SMART_ADD_CHILD_INT(xsection, "metronome-pulses-per-measure", section->metronome_pulses_per_measure);
SMART_ADD_CHILD_INT(xsection, "properties", section->properties);
SMART_ADD_CHILD_INT(xsection, "key-extra", section->key_extra);
xmlAddChild(xsection, xml_write_directions(section->directions));
xmlAddChild(xsection, xml_write_staffs(section->staffs));
- gl = gl->next;
+ xmlAddChild(xsection, xml_write_musicbars(section->musicbars));
+
+ section = section->next;
}
return sctns;
}
-xmlNodePtr xml_write_guitars(GList *guitars)
+xmlNodePtr xml_write_guitars(struct ptb_guitar *guitars)
{
xmlNodePtr gtrs = xmlNewNode(NULL, "guitars");
- GList *gl = guitars;
+ struct ptb_guitar *gtr = guitars;
- while(gl) {
+ while(gtr) {
char tmp[100];
int i;
- struct ptb_guitar *gtr = gl->data;
xmlNodePtr xgtr = xmlNewNode(NULL, "guitar");
xmlNodePtr strings;
xmlAddChild(gtrs, xgtr);
- g_snprintf(tmp, 100, "%d", gtr->index);
+ snprintf(tmp, 100, "%d", gtr->index);
xmlSetProp(xgtr, "id", tmp);
strings = xmlNewNode(NULL, "strings");
SMART_ADD_CHILD_INT(strings, "string", gtr->strings[i]);
}
+ SMART_ADD_CHILD_STRING(xgtr, "title", gtr->title);
+ SMART_ADD_CHILD_STRING(xgtr, "type", gtr->type);
SMART_ADD_CHILD_INT(xgtr, "reverb", gtr->reverb);
SMART_ADD_CHILD_INT(xgtr, "chorus", gtr->chorus);
SMART_ADD_CHILD_INT(xgtr, "tremolo", gtr->tremolo);
SMART_ADD_CHILD_INT(xgtr, "half_up", gtr->half_up);
SMART_ADD_CHILD_INT(xgtr, "simulate", gtr->simulate);
- gl = gl->next;
+ gtr = gtr->next;
}
return gtrs;
}
-xmlNodePtr xml_write_guitarins(GList *guitarins)
+xmlNodePtr xml_write_guitarins(struct ptb_guitarin *guitarins)
{
- GList *gl = guitarins;
+ struct ptb_guitarin *guitarin = guitarins;
xmlNodePtr xguitarins = xmlNewNode(NULL, "guitarins");
- while(gl) {
- struct ptb_guitarin *guitarin = gl->data;
+ while(guitarin) {
xmlNodePtr xguitarin = xmlNewNode(NULL, "guitarin");
xmlAddChild(xguitarins, xguitarin);
SMART_ADD_CHILD_INT(xguitarin, "rhythm_slash", guitarin->rhythm_slash);
SMART_ADD_CHILD_INT(xguitarin, "staff_in", guitarin->staff_in);
- gl = gl->next;
+ guitarin = guitarin->next;
}
return xguitarins;
}
-xmlNodePtr xml_write_tempomarkers(GList *tempomarkers)
+xmlNodePtr xml_write_tempomarkers(struct ptb_tempomarker *tempomarkers)
{
- GList *gl = tempomarkers;
+ struct ptb_tempomarker *tempomarker = tempomarkers;
xmlNodePtr xtempomarkers = xmlNewNode(NULL, "tempomarkers");
- while(gl) {
- struct ptb_tempomarker *tempomarker = gl->data;
- xmlNodePtr xtempomarker = xmlNewNode(NULL, "tempomarker");
- xmlAddChild(xtempomarkers, xtempomarker);
+ while(tempomarker) {
+ xmlNodePtr xtempomarker = SMART_ADD_CHILD_STRING(xtempomarkers, "tempomarker", tempomarker->description);
SMART_ADD_CHILD_INT(xtempomarker, "type", tempomarker->type);
SMART_ADD_CHILD_INT(xtempomarker, "section", tempomarker->section);
SMART_ADD_CHILD_INT(xtempomarker, "offset", tempomarker->offset);
SMART_ADD_CHILD_INT(xtempomarker, "bpm", tempomarker->bpm);
- xmlNodeSetContent(xtempomarker, tempomarker->description);
- gl = gl->next;
+ tempomarker = tempomarker->next;
}
return xtempomarkers;
}
-xmlNodePtr xml_write_dynamics(GList *dynamics)
+xmlNodePtr xml_write_dynamics(struct ptb_dynamic *dynamics)
{
- GList *gl = dynamics;
+ struct ptb_dynamic *dynamic = dynamics;
xmlNodePtr xdynamics = xmlNewNode(NULL, "dynamics");
- while(gl) {
- struct ptb_dynamic *dynamic = gl->data;
+ while(dynamic) {
xmlNodePtr xdynamic = xmlNewNode(NULL, "dynamic");
xmlAddChild(xdynamics, xdynamic);
SMART_ADD_CHILD_INT(xdynamic, "offset", dynamic->offset);
- gl = gl->next;
+ dynamic = dynamic->next;
}
return xdynamics;
}
-xmlNodePtr xml_write_chorddiagrams(GList *chorddiagrams)
+xmlNodePtr xml_write_chorddiagrams(struct ptb_chorddiagram *chorddiagrams)
{
- GList *gl = chorddiagrams;
+ struct ptb_chorddiagram *chorddiagram = chorddiagrams;
xmlNodePtr xchorddiagrams = xmlNewNode(NULL, "chorddiagrams");
- while(gl) {
- struct ptb_chorddiagram *chorddiagram = gl->data;
+ while(chorddiagram) {
int i;
xmlNodePtr xchorddiagram = xmlNewNode(NULL, "chorddiagram");
xmlNodePtr strings = xmlNewNode(NULL, "strings");
SMART_ADD_CHILD_INT(strings, "string", chorddiagram->tones[i]);
}
- gl = gl->next;
+ chorddiagram = chorddiagram->next;
}
return xchorddiagrams;
}
-xmlNodePtr xml_write_sectionsymbols(GList *sectionsymbols)
+xmlNodePtr xml_write_sectionsymbols(struct ptb_sectionsymbol *sectionsymbols)
{
- GList *gl = sectionsymbols;
+ struct ptb_sectionsymbol *sectionsymbol = sectionsymbols;
xmlNodePtr xsectionsymbols = xmlNewNode(NULL, "sectionsymbols");
- while(gl) {
- struct ptb_sectionsymbol *sectionsymbol = gl->data;
+ while(sectionsymbol) {
xmlNodePtr xsectionsymbol = xmlNewNode(NULL, "sectionsymbol");
xmlAddChild(xsectionsymbols, xsectionsymbol);
SMART_ADD_CHILD_INT(xsectionsymbol, "repeat-ending", sectionsymbol->repeat_ending);
- gl = gl->next;
+ sectionsymbol = sectionsymbol->next;
}
return xsectionsymbols;
}
-xmlNodePtr xml_write_floatingtexts(GList *floatingtexts)
+xmlNodePtr xml_write_floatingtexts(struct ptb_floatingtext *floatingtexts)
{
- GList *gl = floatingtexts;
+ struct ptb_floatingtext *floatingtext = floatingtexts;
xmlNodePtr xfloatingtexts = xmlNewNode(NULL, "floatingtexts");
- while(gl) {
- struct ptb_floatingtext *floatingtext = gl->data;
- xmlNodePtr xfloatingtext = xmlNewNode(NULL, "floatingtext");
- xmlAddChild(xfloatingtexts, xfloatingtext);
+ while(floatingtext) {
+ xmlNodePtr xfloatingtext = SMART_ADD_CHILD_STRING(xfloatingtexts, "floatingtext", floatingtext->text);
SMART_ADD_CHILD_INT(xfloatingtext, "beginpos", floatingtext->beginpos);
SMART_ADD_CHILD_STRING(xfloatingtext, "alignment", "center");
break;
}
- xmlNodeSetContent(xfloatingtext, floatingtext->text);
- xmlAddChild(xfloatingtext, xml_write_font(&floatingtext->font));
+ xmlAddChild(xfloatingtext, xml_write_font("font", &floatingtext->font));
- gl = gl->next;
+ floatingtext = floatingtext->next;
}
return xfloatingtexts;
{
char tmp[100];
xmlNodePtr instrument = xmlNewNode(NULL, "instrument");
- g_snprintf(tmp, 100, "%d", i);
+ snprintf(tmp, 100, "%d", i);
xmlSetProp(instrument, "id", tmp);
xmlAddChild(instrument, xml_write_guitars(bf->instrument[i].guitars));
xmlNodePtr root_node;
xmlDocPtr doc;
xmlNodePtr comment;
- int c, i;
+ xmlNodePtr fonts;
+ int c, i, musicxml = 0;
int version = 0;
+ const char *input = NULL;
char *output = NULL;
poptContext pc;
+ int quiet = 0;
+ int format_output = 0;
struct poptOption options[] = {
POPT_AUTOHELP
{"debug", 'd', POPT_ARG_NONE, &debugging, 0, "Turn on debugging output" },
{"outputfile", 'o', POPT_ARG_STRING, &output, 0, "Write to specified file", "FILE" },
+ {"musicxml", 'm', POPT_ARG_NONE, &musicxml, 'm', "Output MusicXML" },
+ {"format", 'f', POPT_ARG_NONE, &format_output, 1, "Format output" },
+ {"quiet", 'q', POPT_ARG_NONE, &quiet, 1, "Be quiet (no output to stderr)" },
{"version", 'v', POPT_ARG_NONE, &version, 'v', "Show version information" },
POPT_TABLEEND
};
while((c = poptGetNextOpt(pc)) >= 0) {
switch(c) {
case 'v':
- printf("ptb2ascii Version "PTB_VERSION"\n");
- printf("(C) 2004 Jelmer Vernooij <jelmer@samba.org>\n");
+ printf("ptb2xml Version "PACKAGE_VERSION"\n");
+ printf("(C) 2004-2005 Jelmer Vernooij <jelmer@samba.org>\n");
exit(0);
break;
}
poptPrintUsage(pc, stderr, 0);
return -1;
}
- ret = ptb_read_file(poptGetArg(pc));
+
+ input = poptGetArg(pc);
+ if (!quiet) fprintf(stderr, "Parsing %s...\n", input);
+ ret = ptb_read_file(input);
if(!ret) {
perror("Read error: ");
return -1;
}
+ if(!output) {
+ int baselength = strlen(input);
+ if (!strcmp(input + strlen(input) - 4, ".ptb")) {
+ baselength -= 4;
+ }
+ output = malloc(baselength + 6);
+ strncpy(output, input, baselength);
+ strcpy(output + baselength, ".xml");
+ }
+
+ if (!quiet) fprintf(stderr, "Building DOM tree...\n");
+
doc = xmlNewDoc(BAD_CAST "1.0");
root_node = xmlNewNode(NULL, BAD_CAST "powertab");
xmlDocSetRootElement(doc, root_node);
comment = xmlNewComment("\nGenerated by ptb2xml, part of ptabtools. \n"
- "(C) 2004 by Jelmer Vernooij <jelmer@samba.org>\n"
+ "(C) 2004-2005 by Jelmer Vernooij <jelmer@samba.org>\n"
"See http://jelmer.vernstok.nl/oss/ptabtools/ for details\n");
xmlAddChild(root_node, comment);
xmlAddChild(root_node, xml_write_instrument(ret, i));
}
- xmlSaveFormatFileEnc(output?output:"-", doc, "UTF-8", 1);
+ fonts = xmlNewNode( NULL, "fonts"); xmlAddChild(root_node, fonts);
+
+ xmlAddChild(fonts, xml_write_font("default_font", &ret->default_font));
+ xmlAddChild(fonts, xml_write_font("chord_name_font", &ret->chord_name_font));
+ xmlAddChild(fonts, xml_write_font("tablature_font", &ret->tablature_font));
+
+ if (musicxml)
+ {
+ if (!quiet) fprintf(stderr, "Converting to MusicXML...\n");
+#ifdef HAVE_XSLT
+ xsltStylesheetPtr stylesheet = xsltParseStylesheetFile(MUSICXMLSTYLESHEET);
+ doc = xsltApplyStylesheet(stylesheet, doc, NULL);
+ xsltFreeStylesheet(stylesheet);
+#else
+ fprintf(stderr, "Conversion to MusicXML not possible in this version: libxslt not compiled in\n");
+ return -1;
+#endif
+ }
+
+ if (!quiet) fprintf(stderr, "Writing output to %s...\n", output);
+
+ if (xmlSaveFormatFile(output, doc, format_output) < 0) {
+ return -1;
+ }
xmlFreeDoc(doc);