~ubuntu-branches/ubuntu/utopic/texlive-bin/utopic

« back to all changes in this revision

Viewing changes to utils/mtx/mtx-0.60d/lyrics.c

  • Committer: Package Import Robot
  • Author(s): Norbert Preining
  • Date: 2012-05-07 10:47:49 UTC
  • mfrom: (1.2.4)
  • Revision ID: package-import@ubuntu.com-20120507104749-p00ot5sajjbkp1hp
Tags: 2011.20120507-1
* new upstream checkout: uptex 1.10
* drop patches for config file inclusion in (x)dvipdfmx, included upstream
* add man page for etex
* include pmpost patches and build it
* adapt/unfuzzify patches for current sources
* disable mtx building, we have prepmx package in Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Output from p2c 1.21alpha-07.Dec.93, the Pascal-to-C translator */
 
2
/* From input file "lyrics.pas" */
 
3
 
 
4
 
 
5
#include "p2c.h"
 
6
 
 
7
 
 
8
#define LYRICS_G
 
9
#include "lyrics.h"
 
10
 
 
11
 
 
12
#ifndef CONTROL_H
 
13
#include "control.h"
 
14
#endif
 
15
 
 
16
#ifndef STRINGS_H
 
17
#include "strings.h"
 
18
#endif
 
19
 
 
20
#ifndef MTXLINE_H
 
21
#include "mtxline.h"
 
22
#endif
 
23
 
 
24
#ifndef STATUS_H
 
25
#include "status.h"
 
26
#endif
 
27
 
 
28
#ifndef MULTFILE_H
 
29
#include "multfile.h"
 
30
#endif
 
31
 
 
32
#ifndef FILES_H
 
33
#include "files.h"
 
34
#endif
 
35
 
 
36
#ifndef UTILITY_H
 
37
#include "utility.h"
 
38
#endif
 
39
 
 
40
 
 
41
/* Symbols used in strings of melismatype */
 
42
 
 
43
#define beam_melisma    '['
 
44
#define inhibit_beam_melisma  '<'
 
45
#define slur_melisma    '('
 
46
#define inhibit_slur_melisma  '{'
 
47
 
 
48
 
 
49
typedef char other_index;
 
50
 
 
51
typedef char other_index0;
 
52
 
 
53
typedef Char melismatype[256];
 
54
 
 
55
typedef enum {
 
56
  nolyr, haslyr
 
57
} haslyrtype;
 
58
typedef enum {
 
59
  normal, aux
 
60
} auxtype;
 
61
typedef enum {
 
62
  asbefore, newassign
 
63
} assigntype;
 
64
typedef enum {
 
65
  virgin, active
 
66
} inittype;
 
67
 
 
68
typedef struct lyrinfotype {
 
69
  short lyr_adjust, slur_level, slur_change, beam_level, beam_change;
 
70
  melismatype melisma;
 
71
  boolean numbered;
 
72
} lyrinfotype;
 
73
 
 
74
typedef enum {
 
75
  none_given, global_lyrics, local_lyrics
 
76
} lyrlinetype;
 
77
 
 
78
typedef struct lyrtagtype {
 
79
  lyrlinetype lyrsource;
 
80
  haslyrtype has_lyrics;
 
81
  auxtype auxiliary;
 
82
  assigntype new_assign;
 
83
  inittype initialized;
 
84
  short linecount;
 
85
  Char tags[256];
 
86
} lyrtagtype;
 
87
 
 
88
 
 
89
#define maxLyrNums      64
 
90
#define lyrtaglength    40
 
91
 
 
92
 
 
93
#define lyr_adjust_undef  (-12345)
 
94
#define interstave      24
 
95
 
 
96
 
 
97
Static short LyrNum = 0;
 
98
 
 
99
Static boolean lyrmodealter[maxstaves], oldlyrmodealter[maxstaves];
 
100
Static lyrtagtype tag[maxvoices], oldtag[maxvoices];
 
101
Static lyrinfotype lyrinfo[maxvoices];
 
102
Static Char numberedParagraph[maxLyrNums][lyrtaglength + 1];
 
103
 
 
104
 
 
105
/* Information flow for verse numbers: at the SetLyrics stage, the first
 
106
line of each lyrics paragraph is checked for a verse number, and if
 
107
found, the paragraph tag is remembered.  At the AssignLyrics stage,
 
108
the first time that paragraph is encountered, the particular voice
 
109
is marked in lyrinfo as being numbered.  When that voice is later processed,
 
110
the mark in lyrinfo is interrogated and turned off: if it was on, the
 
111
mtxVerse pre-TeX string is put into the output. */
 
112
 
 
113
boolean hasVerseNumber(voice)
 
114
voice_index voice;
 
115
{
 
116
  boolean Result;
 
117
 
 
118
  Result = lyrinfo[voice-1].numbered;
 
119
  lyrinfo[voice-1].numbered = false;
 
120
  return Result;
 
121
}
 
122
 
 
123
 
 
124
Static boolean isNumberedLyricsParagraph(tag)
 
125
Char *tag;
 
126
{
 
127
  short i, FORLIM;
 
128
 
 
129
  FORLIM = LyrNum;
 
130
  for (i = 0; i <= FORLIM - 1; i++) {
 
131
    if (!strcmp(tag, numberedParagraph[i]))
 
132
      return true;
 
133
  }
 
134
  return false;
 
135
}
 
136
 
 
137
 
 
138
Static boolean anyTagNumbered(tags_)
 
139
Char *tags_;
 
140
{
 
141
  boolean Result;
 
142
  Char tags[256];
 
143
  Char s[256];
 
144
 
 
145
  strcpy(tags, tags_);
 
146
/* p2c: lyrics.pas: Note: Eliminated unused assignment statement [338] */
 
147
  if (curtail(tags, '}') > 0)
 
148
    delete1(tags, 1);
 
149
  do {
 
150
    GetNextWord(s, tags, ',', dummy);
 
151
    if (*s == '\0')
 
152
      return false;
 
153
    if (isNumberedLyricsParagraph(s))
 
154
      return true;
 
155
  } while (true);
 
156
  return false;
 
157
}
 
158
 
 
159
 
 
160
/* Save the tag in the numberedParagraph list, stripping off braces if any */
 
161
Static Void markNumbered(tag_)
 
162
Char *tag_;
 
163
{
 
164
  Char tag[256];
 
165
 
 
166
  strcpy(tag, tag_);
 
167
  if (LyrNum >= maxLyrNums) {
 
168
    error("Too many numbered lines in the lyrics", !print);
 
169
    return;
 
170
  }
 
171
  LyrNum++;
 
172
  if (curtail(tag, '}') > 0)
 
173
    delete1(tag, 1);
 
174
  strcpy(numberedParagraph[LyrNum-1], tag);
 
175
/* p2c: lyrics.pas, line 104:
 
176
 * Note: Possible string truncation in assignment [145] */
 
177
}
 
178
 
 
179
 
 
180
/* --- end of procedures to keep track of verse numbering --- */
 
181
 
 
182
Void lyricsParagraph()
 
183
{
 
184
  Char first[256], w[256];
 
185
  paragraph_index0 l, line;
 
186
  other_index0 i;
 
187
  other_index0 nother = 0;
 
188
  Char other_[10][lyrtaglength + 1];
 
189
  boolean numbered;
 
190
  Char STR1[256], STR3[256];
 
191
  paragraph_index0 FORLIM;
 
192
  Char STR4[256];
 
193
  Char STR5[256];
 
194
 
 
195
  if (!doLyrics())
 
196
    return;
 
197
  NextWord(w, P[0], blank, dummy);
 
198
  l = strlen(w);
 
199
  line_no = orig_line_no[0];
 
200
  if (w[l-1] != '}')
 
201
    strcat(w, "}");
 
202
  GetNextWord(first, w, dummy, '}');
 
203
  while (*w != '\0') {
 
204
    if (w[0] == '=')
 
205
      predelete(w, 1);
 
206
    if (w[0] != '{')
 
207
      sprintf(w, "{%s", strcpy(STR1, w));
 
208
    nother++;
 
209
    GetNextWord(other_[nother-1], w, dummy, '}');
 
210
/* p2c: lyrics.pas, line 122:
 
211
 * Note: Possible string truncation in assignment [145] */
 
212
  }
 
213
  if (beVerbose()) {
 
214
    printf("---- Paragraph %d starting at line %d has lyrics headed %s",
 
215
           paragraph_no, line_no, first);
 
216
    for (i = 0; i <= nother - 1; i++)
 
217
      printf("=%s", other_[i]);
 
218
    putchar('\n');
 
219
  }
 
220
  sprintf(STR5, "%c Paragraph %s line %s bar %s",
 
221
          comment, toString(STR1, paragraph_no), toString(STR3, line_no),
 
222
          toString(STR4, bar_no));
 
223
  tex3(STR5);
 
224
  sprintf(STR3, "\\mtxSetLyrics%s{%%", first);
 
225
  tex3(STR3);
 
226
  FORLIM = para_len;
 
227
  for (line = 2; line <= FORLIM; line++) {
 
228
    lyrTranslate(P[line-1], &numbered);
 
229
    if (numbered) {
 
230
      if (line > 2)
 
231
        warning("Verse number not in first line of paragraph treated as lyrics",
 
232
                print);
 
233
      else {
 
234
        markNumbered(first);
 
235
        for (i = 0; i <= nother - 1; i++)
 
236
          markNumbered(other_[i]);
 
237
      }
 
238
    }
 
239
    line_no = orig_line_no[line-1];
 
240
    if (strlen(P[line-1]) > max_lyrics_line_length && pmx_preamble_done)
 
241
      error("Lyrics line too long", print);
 
242
    if (pmx_preamble_done) {
 
243
      if (line == 2) {
 
244
        sprintf(STR3, "\\\\\\:%s", P[line-1]);
 
245
        put(STR3, putspace);
 
246
      } else {
 
247
        sprintf(STR3, "\\\\\\ %s", P[line-1]);
 
248
        put(STR3, putspace);
 
249
      }
 
250
    } else
 
251
      put(P[line-1], putspace);
 
252
    if (line < para_len) {
 
253
      if (pmx_preamble_done)
 
254
        putLine(" %\\");
 
255
      else
 
256
        putLine(" %");
 
257
    } else if (pmx_preamble_done)
 
258
      putLine("}\\");
 
259
    else
 
260
      putLine("}");
 
261
  }
 
262
  for (i = 0; i <= nother - 1; i++) {
 
263
    sprintf(STR1, "\\mtxCopyLyrics%s%s", first, other_[i]);
 
264
    tex3(STR1);
 
265
  }
 
266
}
 
267
 
 
268
 
 
269
Static Char *songraise(Result, voice)
 
270
Char *Result;
 
271
voice_index voice;
 
272
{
 
273
  Char s[256];
 
274
  lyrtagtype *WITH;
 
275
  lyrinfotype *WITH1;
 
276
  Char STR1[256], STR3[256];
 
277
 
 
278
  WITH = &tag[voice-1];
 
279
  WITH1 = &lyrinfo[voice-1];
 
280
  if (WITH->initialized == virgin && WITH1->lyr_adjust == 0)
 
281
    return strcpy(Result, "");
 
282
  else {
 
283
    if (WITH->auxiliary == aux)
 
284
      strcpy(s, "Aux");
 
285
    else
 
286
      *s = '\0';
 
287
    sprintf(Result, "\\mtx%sLyricsAdjust{%s}{%s}",
 
288
            s, toString(STR1, PMXinstr(voiceStave(voice))),
 
289
            toString(STR3, WITH1->lyr_adjust));
 
290
    return Result;
 
291
  }
 
292
}
 
293
 
 
294
 
 
295
Char *lyricsReport(Result, voice)
 
296
Char *Result;
 
297
voice_index voice;
 
298
{
 
299
  Char l[256];
 
300
  lyrtagtype *WITH;
 
301
 
 
302
  WITH = &tag[voice-1];
 
303
  if (WITH->has_lyrics == nolyr ||
 
304
      WITH->lyrsource == none_given && *WITH->tags == '\0')
 
305
    return strcpy(Result, " but has no own lyrics");
 
306
  else {
 
307
    strcpy(l, " with ");
 
308
    if (WITH->auxiliary == aux)
 
309
      strcat(l, "auxiliary ");
 
310
    strcat(l, "lyrics ");
 
311
    if (WITH->lyrsource == local_lyrics)
 
312
      strcat(l, "locally defined as \"");
 
313
    else
 
314
      strcat(l, "labelled \"");
 
315
    sprintf(l + strlen(l), "%s\"", WITH->tags);
 
316
    if (anyTagNumbered(WITH->tags))
 
317
      strcat(l, " with verse numbers");
 
318
    return strcpy(Result, l);
 
319
  }
 
320
}
 
321
 
 
322
 
 
323
Void initLyrics()
 
324
{
 
325
  /* at the start only */
 
326
  stave_index stave;
 
327
  voice_index voice, FORLIM;
 
328
  lyrinfotype *WITH;
 
329
  lyrtagtype *WITH1;
 
330
  stave_index FORLIM1;
 
331
 
 
332
  FORLIM = nvoices;
 
333
  for (voice = 0; voice <= FORLIM - 1; voice++) {
 
334
    WITH = &lyrinfo[voice];
 
335
    WITH1 = &tag[voice];
 
336
    WITH1->has_lyrics = nolyr;
 
337
    WITH->lyr_adjust = lyr_adjust_undef;
 
338
    *WITH->melisma = '\0';
 
339
    WITH->slur_level = 0;
 
340
    WITH->beam_level = 0;
 
341
    WITH1->auxiliary = aux;
 
342
    WITH1->lyrsource = none_given;
 
343
    WITH1->new_assign = asbefore;
 
344
    WITH1->initialized = virgin;
 
345
  }
 
346
  FORLIM1 = nstaves;
 
347
  for (stave = 0; stave <= FORLIM1 - 1; stave++)
 
348
    oldlyrmodealter[stave] = false;
 
349
}
 
350
 
 
351
 
 
352
Static Void registerLyrics(voice, w)
 
353
voice_index voice;
 
354
Char *w;
 
355
{
 
356
  lyrtagtype *WITH;
 
357
 
 
358
  WITH = &tag[voice-1];
 
359
  strcpy(oldtag[voice-1].tags, WITH->tags);
 
360
  oldtag[voice-1].lyrsource = WITH->lyrsource;
 
361
  WITH->lyrsource = global_lyrics;
 
362
  switch (strlen(w)) {
 
363
 
 
364
  case 0:
 
365
    *WITH->tags = '\0';
 
366
    break;
 
367
 
 
368
  case 1:
 
369
    fatalerror("M-Tx system error in registerLyrics");
 
370
    break;
 
371
 
 
372
  default:
 
373
    strcpy(WITH->tags, w);
 
374
    break;
 
375
  }
 
376
}
 
377
 
 
378
 
 
379
Void extractLyrtag(voice, note)
 
380
voice_index voice;
 
381
Char *note;
 
382
{
 
383
  /* inline lyrics change */
 
384
  lyrtagtype *WITH;
 
385
  Char STR1[256], STR2[256];
 
386
 
 
387
  WITH = &tag[voice-1];
 
388
  if (WITH->has_lyrics == nolyr) {
 
389
    error3(voice, "Inline lyrics change on no-lyrics line");
 
390
    return;
 
391
  }
 
392
  registerLyrics(voice, note);   /* was: ''); */
 
393
  sprintf(note, "\\mtxAssignLyrics{%s}%s",
 
394
          toString(STR1, PMXinstr(voiceStave(voice))), strcpy(STR2, note));
 
395
  if (WITH->auxiliary == aux)
 
396
    sprintf(note, "\\mtxAuxLyr{%s}\\", strcpy(STR2, note));
 
397
  else
 
398
    strcat(note, "\\");
 
399
}
 
400
 
 
401
 
 
402
Void clearTags()
 
403
{
 
404
  /* at start of paragraph analyis */
 
405
  voice_index voice, FORLIM;
 
406
  lyrtagtype *WITH;
 
407
 
 
408
  memcpy(oldtag, tag, maxvoices * sizeof(lyrtagtype));
 
409
  FORLIM = nvoices;
 
410
  for (voice = 0; voice <= FORLIM - 1; voice++) {
 
411
    WITH = &tag[voice];
 
412
    WITH->lyrsource = none_given;
 
413
    *WITH->tags = '\0';
 
414
    WITH->linecount = 0;
 
415
  }
 
416
}
 
417
 
 
418
 
 
419
#define maxlyrlen       (PMXlinelength - 15)
 
420
 
 
421
 
 
422
Local Void convertlyrics(lyn, voice, mx)
 
423
Char *lyn;
 
424
voice_index voice;
 
425
auxtype mx;
 
426
{
 
427
  static Char setlyr[256] = "%%\\\\\\mtxSetLyrics";
 
428
  Char btag[256], thistag[256], w[256];
 
429
  boolean numbered;
 
430
  Char STR1[256];
 
431
  lyrtagtype *WITH;
 
432
  Char STR2[256];
 
433
 
 
434
  NextWord(w, lyn, blank, dummy);
 
435
  WITH = &tag[voice-1];
 
436
  if (*w == '\0') {
 
437
    *WITH->tags = '\0';
 
438
    return;
 
439
  }
 
440
  WITH->has_lyrics = haslyr;
 
441
  WITH->auxiliary = mx;
 
442
  if (w[0] == '{') {
 
443
    registerLyrics(voice, w);
 
444
    return;
 
445
  }
 
446
  WITH->lyrsource = local_lyrics;
 
447
  WITH->linecount++;
 
448
  toString(thistag, voice * 10 + WITH->linecount);
 
449
  sprintf(btag, "{%s}", thistag);
 
450
  if (*WITH->tags == '\0')
 
451
    strcpy(WITH->tags, btag);
 
452
  else {
 
453
    WITH->tags[strlen(WITH->tags) - 1] = ',';
 
454
    sprintf(WITH->tags + strlen(WITH->tags), "%s}", thistag);
 
455
  }
 
456
  trim(lyn);
 
457
  lyrTranslate(lyn, &numbered);
 
458
  if (numbered)
 
459
    markNumbered(thistag);
 
460
  if (strlen(lyn) + strlen(btag) > maxlyrlen)
 
461
    sprintf(lyn, "%s%s{\\\n\\\\\\:%s}\\", setlyr, btag, strcpy(STR2, lyn));
 
462
  else
 
463
    sprintf(lyn, "%s%s{%s}\\", setlyr, btag, strcpy(STR1, lyn));
 
464
}
 
465
 
 
466
#undef maxlyrlen
 
467
 
 
468
 
 
469
Void maybeLyrics(voice, parline, w_)
 
470
voice_index voice;
 
471
paragraph_index parline;
 
472
Char *w_;
 
473
{
 
474
  /* during paragraph analysis, parline had L:, already stripped */
 
475
  Char w[256];
 
476
  voice_index0 k;
 
477
 
 
478
  /**  Labelled lyrics line -- */
 
479
  strcpy(w, w_);
 
480
  if (!doLyrics())
 
481
    return;
 
482
  if (strlen(w) == 1 && voice == 0)
 
483
    warning("Lyrics line above top voice should be labelled", print);
 
484
  if (strlen(w) == 1) {   /**  Standard lyrics line -------- */
 
485
    k = voice;
 
486
    if (k == 0)
 
487
      k = 1;
 
488
    convertlyrics(P[parline-1], k, normal);
 
489
    return;
 
490
  }
 
491
  predelete(w, 1);
 
492
  k = findVoice(w);
 
493
  if (k == 0)
 
494
    error("Lyrics line belongs to unknown voice", print);
 
495
  else
 
496
    convertlyrics(P[parline-1], k, aux);
 
497
}
 
498
 
 
499
 
 
500
Void reviseLyrics()
 
501
{
 
502
  /* after paragraph analysis */
 
503
  voice_index voice;
 
504
  stave_index stave;
 
505
  voice_index FORLIM;
 
506
  lyrtagtype *WITH;
 
507
  stave_index FORLIM1;
 
508
 
 
509
  FORLIM = nvoices;
 
510
  for (voice = 0; voice <= FORLIM - 1; voice++) {
 
511
    WITH = &tag[voice];
 
512
    if (oldtag[voice].lyrsource == global_lyrics &&
 
513
        WITH->lyrsource == none_given) {
 
514
      strcpy(WITH->tags, oldtag[voice].tags);
 
515
      WITH->lyrsource = global_lyrics;
 
516
    }
 
517
    WITH->new_assign = (assigntype)(WITH->has_lyrics == haslyr &&
 
518
                                    strcmp(WITH->tags, oldtag[voice].tags));
 
519
    if (*WITH->tags == '\0')
 
520
      WITH->has_lyrics = nolyr;
 
521
    strcpy(oldtag[voice].tags, WITH->tags);
 
522
    oldtag[voice].lyrsource = WITH->lyrsource;
 
523
  }
 
524
  FORLIM1 = nstaves;
 
525
  for (stave = 1; stave <= FORLIM1; stave++) {
 
526
    WITH = &tag[first_on_stave[stave-1] - 1];
 
527
    lyrmodealter[stave-1] = (!aloneOnStave(stave) &&
 
528
                             WITH->has_lyrics == haslyr &&
 
529
                             WITH->auxiliary == normal);
 
530
  }
 
531
}
 
532
 
 
533
 
 
534
Void assignLyrics(stave, lyrassign)
 
535
stave_index stave;
 
536
Char *lyrassign;
 
537
{
 
538
  /* at start of new block */
 
539
  Char atag[256], instr[256], l[256];
 
540
  voice_index v1, v2, voice;
 
541
  lyrtagtype *WITH;
 
542
  Char STR2[256];
 
543
  lyrinfotype *WITH1;
 
544
 
 
545
  *lyrassign = '\0';
 
546
  toString(instr, PMXinstr(stave));
 
547
  v1 = first_on_stave[stave-1];
 
548
  v2 = v1 + number_on_stave[stave-1] - 1;
 
549
  /* don't reassign if other voice takes over */
 
550
  if (tag[v1-1].auxiliary == tag[v2-1].auxiliary &&
 
551
      tag[v1-1].has_lyrics != tag[v2-1].has_lyrics) {
 
552
    for (voice = v1 - 1; voice <= v2 - 1; voice++) {
 
553
      WITH = &tag[voice];
 
554
      if (WITH->new_assign == newassign)
 
555
        WITH->new_assign = (assigntype)WITH->has_lyrics;
 
556
    }
 
557
  }
 
558
  for (voice = v1 - 1; voice <= v2 - 1; voice++)
 
559
    lyrinfo[voice].numbered = false;
 
560
  for (voice = v1; voice <= v2; voice++) {
 
561
    WITH = &tag[voice-1];
 
562
    if (WITH->new_assign == newassign) {
 
563
      strcpy(atag, WITH->tags);
 
564
      if (*atag == '\0')
 
565
        strcpy(atag, "{}");
 
566
      sprintf(l, "\\mtxAssignLyrics{%s}%s", instr, atag);
 
567
      if (WITH->auxiliary == aux)
 
568
        sprintf(l, "\\mtxAuxLyr{%s}", strcpy(STR2, l));
 
569
      strcat(lyrassign, l);
 
570
      if (*WITH->tags == '\0')
 
571
        WITH->has_lyrics = nolyr;
 
572
      if (WITH->has_lyrics == haslyr && WITH->initialized == virgin) {
 
573
        WITH1 = &lyrinfo[voice-1];
 
574
        if (WITH->auxiliary == aux && upper(voice))
 
575
          WITH1->lyr_adjust = interstave;
 
576
        else
 
577
          WITH1->lyr_adjust = 0;
 
578
        strcat(lyrassign, songraise(STR2, voice));
 
579
        WITH->initialized = active;
 
580
      }
 
581
      if (anyTagNumbered(atag))
 
582
        lyrinfo[voice-1].numbered = true;
 
583
    }
 
584
  }
 
585
  if (lyrmodealter[stave-1] == oldlyrmodealter[stave-1])
 
586
    return;
 
587
  if (lyrmodealter[stave-1])
 
588
    sprintf(lyrassign + strlen(lyrassign), "\\mtxLyrModeAlter{%s}", instr);
 
589
  else
 
590
    sprintf(lyrassign + strlen(lyrassign), "\\mtxLyrModeNormal{%s}", instr);
 
591
  oldlyrmodealter[stave-1] = lyrmodealter[stave-1];
 
592
}
 
593
 
 
594
 
 
595
Void lyricsAdjust(voice, note)
 
596
voice_index voice;
 
597
Char *note;
 
598
{
 
599
  /* inline at-word */
 
600
  short adj;
 
601
  boolean force, put_above, put_below;
 
602
  lyrinfotype *WITH;
 
603
  lyrtagtype *WITH1;
 
604
  Char STR2[256];
 
605
 
 
606
  WITH = &lyrinfo[voice-1];
 
607
  WITH1 = &tag[voice-1];
 
608
  predelete(note, 1);
 
609
  force = (note[0] == '=');
 
610
  if (force)
 
611
    predelete(note, 1);
 
612
  put_above = (note[0] == '^');
 
613
  if (put_above)
 
614
    predelete(note, 1);
 
615
  put_below = (note[0] == 'v');
 
616
  if (put_below)
 
617
    predelete(note, 1);
 
618
  if (*note != '\0')
 
619
    getNum(note, &adj);
 
620
  else
 
621
    adj = 0;
 
622
  if (WITH1->has_lyrics == nolyr) {
 
623
    *note = '\0';
 
624
    return;
 
625
  }
 
626
  if (put_above)
 
627
    WITH->lyr_adjust = interstave;
 
628
  else if (put_below)
 
629
    WITH->lyr_adjust = 0;
 
630
  if (force)
 
631
    WITH->lyr_adjust = adj;
 
632
  else
 
633
    WITH->lyr_adjust += adj;
 
634
  songraise(note, voice);
 
635
  if (*note != '\0')
 
636
    sprintf(note, "\\\\%s\\", strcpy(STR2, note));
 
637
}
 
638
 
 
639
 
 
640
Void lyrTranslate(P, numbered)
 
641
Char *P;
 
642
boolean *numbered;
 
643
{   /* Test for starting number */
 
644
  short k, l, number;
 
645
  Char Q[256], w[256];
 
646
 
 
647
  NextWord(w, P, blank, dummy);
 
648
  *numbered = false;
 
649
  if (endsWith(w, ".")) {
 
650
    getNum(w, &number);
 
651
    *numbered = (number != 0);
 
652
  }
 
653
  /*Translate lyrics link */
 
654
  *Q = '\0';
 
655
  l = strlen(P);
 
656
  for (k = 1; k <= l - 1; k++) {
 
657
    if (P[k-1] != '_' || P[k] == '_' || P[k] == ' ' || pos1(P[k], digits) > 0)
 
658
      sprintf(Q + strlen(Q), "%c", P[k-1]);
 
659
    else if (k > 1 && P[k-2] == '\\')
 
660
      strcat(Q, "mtxLowLyrlink ");
 
661
    else
 
662
      strcat(Q, "\\mtxLyrlink ");
 
663
  }
 
664
  sprintf(Q + strlen(Q), "%c", P[l-1]);
 
665
  strcpy(P, Q);
 
666
}
 
667
 
 
668
 
 
669
typedef enum {
 
670
  beam, slur
 
671
} melismaEnd;
 
672
 
 
673
 
 
674
Static Char removeLast(s, t)
 
675
Char *s;
 
676
Char *t;
 
677
{
 
678
  Char Result;
 
679
  short i, l;
 
680
 
 
681
  l = strlen(s);
 
682
  for (i = l; i >= 1; i--) {
 
683
    if (pos1(s[i-1], t) > 0) {
 
684
      Result = s[i-1];
 
685
      delete1(s, i);
 
686
      return Result;
 
687
    }
 
688
  }
 
689
  return dummy;
 
690
}
 
691
 
 
692
 
 
693
Static boolean OpenMelisma(s)
 
694
Char *s;
 
695
{
 
696
  return (pos1(slur_melisma, s) > 0 || pos1(beam_melisma, s) > 0);
 
697
}
 
698
 
 
699
 
 
700
/* Local variables for getSyllable: */
 
701
struct LOC_getSyllable {
 
702
  voice_index voice;
 
703
  boolean BM, EM;
 
704
} ;
 
705
 
 
706
Local Void startMelismas(t, LINK)
 
707
Char *t;
 
708
struct LOC_getSyllable *LINK;
 
709
{
 
710
  boolean open_before, open_now;
 
711
  short i, k;
 
712
  lyrinfotype *WITH;
 
713
 
 
714
  k = strlen(t);
 
715
  for (i = 0; i <= k - 1; i++) {
 
716
    WITH = &lyrinfo[LINK->voice-1];
 
717
    open_before = OpenMelisma(WITH->melisma);
 
718
    sprintf(WITH->melisma + strlen(WITH->melisma), "%c", t[i]);
 
719
    open_now = OpenMelisma(WITH->melisma);
 
720
    LINK->BM = (LINK->BM || open_now && !open_before);
 
721
  }
 
722
}
 
723
 
 
724
Local boolean endMelisma(voice, LINK)
 
725
short voice;
 
726
struct LOC_getSyllable *LINK;
 
727
{
 
728
  Char found;
 
729
  short i;
 
730
  short count[2];
 
731
  melismaEnd t;
 
732
  short FORLIM1;
 
733
  lyrinfotype *WITH;
 
734
  Char STR1[4];
 
735
 
 
736
  LINK->EM = false;
 
737
  count[(long)slur] = -lyrinfo[voice-1].slur_change;
 
738
  count[(long)beam] = -lyrinfo[voice-1].beam_change;
 
739
  for (t = beam; (long)t <= (long)slur; t = (melismaEnd)((long)t + 1)) {
 
740
    FORLIM1 = count[(long)t];
 
741
    for (i = 1; i <= FORLIM1; i++) {
 
742
      WITH = &lyrinfo[voice-1];
 
743
      switch (t) {
 
744
 
 
745
      case slur:
 
746
        sprintf(STR1, "%c%c", slur_melisma, inhibit_slur_melisma);
 
747
        found = removeLast(WITH->melisma, STR1);
 
748
        break;
 
749
 
 
750
      case beam:
 
751
        sprintf(STR1, "%c%c", beam_melisma, inhibit_beam_melisma);
 
752
        found = removeLast(WITH->melisma, STR1);
 
753
        break;
 
754
      }
 
755
      if (found == dummy)
 
756
        error3(voice, "Ending a melisma that was never started");
 
757
      LINK->EM = (LINK->EM ||
 
758
          (!OpenMelisma(WITH->melisma) &&
 
759
           pos1(found, (sprintf(STR1, "%c%c", slur_melisma, beam_melisma),
 
760
                        STR1)) > 0));
 
761
    }
 
762
  }
 
763
  return LINK->EM;
 
764
}
 
765
 
 
766
Local Void startSlurMelisma(voice, LINK)
 
767
voice_index voice;
 
768
struct LOC_getSyllable *LINK;
 
769
{
 
770
  static Char start[2] = {
 
771
    slur_melisma, inhibit_slur_melisma
 
772
  };
 
773
 
 
774
  Char slurs[256];
 
775
  short k, FORLIM;
 
776
  Char STR1[256];
 
777
 
 
778
  *slurs = '\0';
 
779
  FORLIM = lyrinfo[voice-1].slur_change;
 
780
  for (k = 1; k <= FORLIM; k++)
 
781
    sprintf(slurs, "%c%s",
 
782
            start[noSlurMelisma(voice, 1 - k)], strcpy(STR1, slurs));
 
783
  startMelismas(slurs, LINK);
 
784
}
 
785
 
 
786
Local Void startBeamMelisma(voice, LINK)
 
787
voice_index voice;
 
788
struct LOC_getSyllable *LINK;
 
789
{
 
790
  static Char start[2] = {
 
791
    beam_melisma, inhibit_beam_melisma
 
792
  };
 
793
 
 
794
  Char beams[256];
 
795
  short k, FORLIM;
 
796
  Char STR1[256];
 
797
 
 
798
  *beams = '\0';
 
799
  FORLIM = lyrinfo[voice-1].beam_change;
 
800
  for (k = 1; k <= FORLIM; k++)
 
801
    sprintf(beams, "%c%s", start[noBeamMelisma(voice)], strcpy(STR1, beams));
 
802
  startMelismas(beams, LINK);
 
803
}
 
804
 
 
805
Local boolean startMelisma(voice, LINK)
 
806
short voice;
 
807
struct LOC_getSyllable *LINK;
 
808
{
 
809
  LINK->BM = false;
 
810
  startSlurMelisma(voice, LINK);
 
811
  startBeamMelisma(voice, LINK);
 
812
  return LINK->BM;
 
813
}
 
814
 
 
815
 
 
816
/* Append mtxBM or mtxEM to pretex when appropriate */
 
817
Void getSyllable(voice_, pretex)
 
818
voice_index voice_;
 
819
Char *pretex;
 
820
{
 
821
  struct LOC_getSyllable V;
 
822
  short t;
 
823
  lyrtagtype *WITH;
 
824
  lyrinfotype *WITH1;
 
825
 
 
826
  V.voice = voice_;
 
827
  WITH = &tag[V.voice-1];
 
828
  WITH1 = &lyrinfo[V.voice-1];
 
829
  if (WITH->has_lyrics != haslyr)
 
830
    return;
 
831
  t = WITH1->slur_level;
 
832
  WITH1->slur_level = slurLevel(V.voice);
 
833
  WITH1->slur_change = WITH1->slur_level - t;
 
834
  t = WITH1->beam_level;
 
835
  WITH1->beam_level = beamLevel(V.voice);
 
836
  WITH1->beam_change = WITH1->beam_level - t;
 
837
  if (startMelisma(V.voice, &V)) {
 
838
    if (WITH->auxiliary == aux)
 
839
      strcat(pretex, "\\mtxAuxBM");
 
840
    else
 
841
      strcat(pretex, "\\mtxBM");
 
842
  }
 
843
  if (!endMelisma(V.voice, &V))
 
844
    return;
 
845
  if (WITH->auxiliary == aux)
 
846
    strcat(pretex, "\\mtxAuxEM");
 
847
  else
 
848
    strcat(pretex, "\\mtxEM");
 
849
}
 
850
 
 
851
 
 
852
Static Void getSyllable1(voice, pretex)
 
853
voice_index voice;
 
854
Char *pretex;
 
855
{
 
856
  lyrinfotype *WITH;
 
857
 
 
858
  WITH = &lyrinfo[voice-1];
 
859
  printf("voice=%d, slurchange=%d, melisma=%s, beamchange=%d\n",
 
860
         voice, WITH->slur_change, WITH->melisma, WITH->beam_change);
 
861
  getSyllable1(voice, pretex);
 
862
  if (*pretex != '\0')
 
863
    printf("pretex = %s\n", pretex);
 
864
}
 
865
 
 
866
 
 
867
 
 
868
 
 
869
/* End. */