#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 */ {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; V3 "%s: Called at <%s>\n",F,P V; if (*P != '!') {V5 "%s: No annotation\n",F V; return 0;} if (!P[1]) {V5 "%s: Trailing '!'\n",F 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; 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; l = ann->l; /* Length of annotation so far */ if (l > 0) { /* Only one allowed at present */ syntax("Overwrite earlier annotation", q); TextInit(&ann,64); } while ((c = *P) && (c != '!') && (c != ' ')) { ann->t[l++] = c; ann->t[l] = 0; ann->l ++; 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; } P++; } if (c != '!') { 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 */ V3 "%s: Continue at <%3.3s>\n",F,P V; return 0; /* Ignore it; it's an abc2win ! */ } P++; V3 " parsed annotation <%s>\n",TextStr(ann) 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; dtype[decos] = annname[i].type; V5 "%s: Deco dtype[%d] is %d \"%s\"\n",F,decos,dtype[decos],TextStr(ann) V; decos++; ++n; // Number of decos found break; } } V3 "%s: %d decos found, %d total.\n",F,n,decos V; V3 "%s: Return 1 for ann !%s!\n",F,TextStr(ann) V; return 1; }