#include "jcabc2ps.h" #include "parse.h" #include "prsAnn.h" Ann annname[] = { {D_GRACE, "GRACE"}, /* 1 */ {D_STACC, "STACC"}, /* 2 */ {D_SLIDE, "SLIDE"}, /* 3 */ {D_EMBAR, "EMBAR"}, /* 4 */ {D_HOLD, "HOLD"}, /* 5 */ {D_HOLD, "fermata"}, /* 5 */ {D_UPBOW, "UPBOW"}, /* 6 */ {D_UPBOW, "up"}, /* 6 */ {D_DOWNBOW, "DOWNBOW"}, /* 7 */ {D_DOWNBOW, "down"}, /* 7 */ {D_ROLL, "ROLL"}, /* 8 */ {D_TRILL, "TRILL"}, /* 9 */ {D_HAT, "HAT"}, /* 10 */ {D_ATT, "ATT"}, /* 11 */ {D_SEGNO, "segno"}, /* 12 */ {D_CODA, "coda"}, /* 13 */ {0}, }; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Parse an annotation. This has the syntax !text!, where the text is any of a * list of official musical symbols. This is a "preliminary" implementation; * there is still work to be done on this topic. */ int prsAnn() { char *F = "prsAnn"; char *q; int c, i, l; int n=0; // Annotation count float yy; char ann_t[200]; double ann_x, ann_y; int ann_p = 0; char marker; V3 "%s: Called at <%s>\n",F,P V; marker = *P; if (*P != '!' && *P != '+') { V5 "%s: No annotation\n",F V; return 0; } if (!P[1]) {V5 "%s: Trailing '%c'\n",F,marker V; return 0;} if (!ann) { V5 "%s: No current annotation\n",F V; TextInit(&ann,32); } q = P; /* Note position of opening quote */ P++; /* Skip to first char of string */ ann_p = 0; ann_x = ann_y = 0.0; l = 0; switch (c = *P) { /* Check for position char */ case '^': /* Above staff */ V3 " Annotation position '%c' above staff.\n",c V; P++; ann_p = P_ABOVE; ann_y = 38; break; case '<': /* Left of note */ V3 " Annotation position '%c' left of note.\n",c V; P++; ann_p = P_LEFT; break; case '=': /* Next to note */ V3 " Annotation position '%c' next to note.\n",c V; P++; ann_p = P_NEXT; break; case '>': /* Right of note */ V3 " Annotation position '%c' right of note.\n",c V; P++; ann_p = P_RIGHT; break; case '_': /* Below staff */ V3 " Annotation position '%c' below staff.\n",c V; P++; ann_p = P_BELOW; ann_y = -12; break; } V3 "%s: Position is %d ann_y=%.3f\n",F,ann_p,ann_y V; while ((c = *P) && (c != marker) && (c != ' ')) { ann_t[l++] = c; ann_t[l] = 0; if (c == '@') { if (sscanf(P+1,"%f",&yy) > 0) { ann_y = yy; V5 "%s: Matched ann_y=%6.3f\n",F,yy V; } } V7 "%s: ann=\"%s\"\n",F,ann_t V; if (l >= 200) { syntax("String for annotation too long", q); return 1; // this behavior strikes me as questionable } P++; } if (c != marker) { if (!c) V3 "%s: EOL reached while parsing annotation.\n",F V; if ( c) V3 "%s: '%c' found while parsing annotation.\n",F,c V; P = q + 1; /* Reposition just after the ! */ while ((c = *P) && isspace(c)) P++; // TextInit(&ann,64); /* Discard accumulated chars */ -- no longer needed V3 "%s: Continue at <%3.3s>\n",F,P V; return 0; /* Ignore it; it's an abc2win ! */ } P++; // skip trailing whitespaces while ((c = *P) && (c == ' ') || (c == '\t')) { P++; } V3 " parsed annotation <%s>\n",ann_t V; for (i=0; annname[i].value; i++) { if (!strcasecmp(ann_t,annname[i].value)) { V5 "%s: Matched annotation name %d.\n",F,i V; addDeco (annname[i].type); // V5 "%s: Deco dtype[%d] is %d \"%s\"\n",F,decos,dtype[decos],TextStr(ann) V; ++n; // Number of decos found break; } } if (n == 0) // if no decoration found, treat as annotation { if (ann->l > 0) { /* Only one allowed at present */ syntax("Overwrite earlier annotation", q); TextInit(&ann,64); } strcpy (ann->t, ann_t); ann->l = l; ann->x = ann_x; ann->y = ann_y; ann->p = ann_p; } // V3 "%s: %d decos found, %d total.\n",F,n,decos V; V3 "%s: Return 1 for ann %c%s%c\n",F,marker,TextStr(ann),marker V; return 1; }