commit a4b139b6ed79b49ff242c3b4bdd30605446708f8
parent 4f825dd807715e457bfccdb30870d6e81db1588b
Author: nibo <nibo@relim.de>
Date: Tue, 6 Aug 2024 16:24:26 +0200
WIP
Diffstat:
| M | chordpro.c | | | 99 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- |
| M | chordpro.h | | | 2 | +- |
2 files changed, 82 insertions(+), 19 deletions(-)
diff --git a/chordpro.c b/chordpro.c
@@ -1799,7 +1799,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
char tag_end[6];
char annotation[512];
enum State state = STATE_LYRICS;
- enum State return_to_state;
+ enum State prev_state;
unsigned int line_number = 1;
int dn = 0;
int dv = 0;
@@ -1862,7 +1862,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
}
songs[so]->sections[se]->lines[li]->lyrics = realloc(songs[so]->sections[se]->lines[li]->lyrics, (ly+1) * sizeof(struct ChoLineItem *));
songs[so]->sections[se]->lines[li]->lyrics[ly] = cho_line_item_new();
- return_to_state = STATE_LYRICS;
+ prev_state = STATE_LYRICS;
state = STATE_MARKUP_TAG;
break;
}
@@ -2187,12 +2187,33 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
ch = 0;
g_prev_ftype = g_current_ftype;
g_current_ftype = SF_CHORD;
- songs[so]->sections[se]->lines[li]->text_above = realloc(songs[so]->sections[se]->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
- songs[so]->sections[se]->lines[li]->text_above[c] = malloc(sizeof(struct ChoLineItemAbove));
- songs[so]->sections[se]->lines[li]->text_above[c]->is_chord = true;
- chord_pos = cho_line_compute_chord_position(songs[so]->sections[se]->lines[li], ly, te);
- songs[so]->sections[se]->lines[li]->text_above[c]->position = chord_pos;
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord = cho_chord_parse(chord);
+ if (
+ prev_state == STATE_MARKUP_TAG_BEGIN ||
+ prev_state == STATE_MARKUP_ATTR_NAME ||
+ prev_state == STATE_MARKUP_ATTR_VALUE
+ ) {
+ chord_pos = cho_line_compute_chord_position(songs[so]->sections[se]->lines[li], ly, te);
+ songs[so]->sections[se]->lines[li]->text_above[c]->position = chord_pos;
+ struct ChoChord *intermediate = cho_chord_parse(chord);
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.name = strdup(intermediate->name);
+ if (songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.root) {
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.root = strdup(intermediate->root);
+ }
+ if (songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.ext) {
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.ext = strdup(intermediate->ext);
+ }
+ if (songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.bass) {
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.bass = strdup(intermediate->bass);
+ }
+ cho_chord_free(intermediate);
+ } else {
+ songs[so]->sections[se]->lines[li]->text_above = realloc(songs[so]->sections[se]->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
+ songs[so]->sections[se]->lines[li]->text_above[c] = malloc(sizeof(struct ChoLineItemAbove));
+ songs[so]->sections[se]->lines[li]->text_above[c]->is_chord = true;
+ chord_pos = cho_line_compute_chord_position(songs[so]->sections[se]->lines[li], ly, te);
+ songs[so]->sections[se]->lines[li]->text_above[c]->position = chord_pos;
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord = cho_chord_parse(chord);
+ }
memset(chord, 0, strlen(chord));
c++;
g_current_ftype = g_prev_ftype;
@@ -2203,6 +2224,14 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
state = STATE_ANNOTATION;
break;
}
+ if (prev_buf == '[' && buf == '<') {
+ songs[so]->sections[se]->lines[li]->text_above = realloc(songs[so]->sections[se]->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
+ songs[so]->sections[se]->lines[li]->text_above[c] = malloc(sizeof(struct ChoLineItemAbove));
+ songs[so]->sections[se]->lines[li]->text_above[c]->is_chord = true;
+ prev_state = STATE_CHORD;
+ state = STATE_MARKUP_TAG;
+ break;
+ }
chord[ch] = buf;
ch++;
break;
@@ -2240,10 +2269,22 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
return NULL;
}
tags[ta]->style = tag_style;
- cho_style_free(songs[so]->sections[se]->lines[li]->lyrics[ly]->style);
- songs[so]->sections[se]->lines[li]->lyrics[ly]->style = cho_style_duplicate(tag_style);
+ switch (prev_state) {
+ case STATE_LYRICS:
+ cho_style_free(songs[so]->sections[se]->lines[li]->lyrics[ly]->style);
+ songs[so]->sections[se]->lines[li]->lyrics[ly]->style = cho_style_duplicate(tag_style);
+ break;
+ case STATE_CHORD:
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord = malloc(sizeof(struct ChoChord));
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style = cho_style_duplicate(tag_style);
+ break;
+ case STATE_ANNOTATION:
+ break;
+ }
memset(tag_begin, 0, strlen(tag_begin));
- state = STATE_LYRICS;
+ state = prev_state;
+ prev_state = STATE_MARKUP_TAG_BEGIN;
+ // state = STATE_LYRICS;
break;
}
if (is_whitespace(buf)) {
@@ -2279,7 +2320,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
t = 0;
cho_tag_close_last_unclosed(tag_end, tags, ta);
memset(tag_end, 0, strlen(tag_end));
- state = return_to_state;
+ state = prev_state;
break;
}
if (t == 5) {
@@ -2329,11 +2370,22 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
return NULL;
}
tags[ta]->style = tag_style;
- cho_style_free(songs[so]->sections[se]->lines[li]->lyrics[ly]->style);
- songs[so]->sections[se]->lines[li]->lyrics[ly]->style = cho_style_duplicate(tag_style);
+ switch (prev_state) {
+ case STATE_LYRICS:
+ cho_style_free(songs[so]->sections[se]->lines[li]->lyrics[ly]->style);
+ songs[so]->sections[se]->lines[li]->lyrics[ly]->style = cho_style_duplicate(tag_style);
+ break;
+ case STATE_CHORD:
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord = malloc(sizeof(struct ChoChord));
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style = cho_style_duplicate(tag_style);
+ break;
+ case STATE_ANNOTATION:
+ break;
+ }
at = 0;
memset(tag_begin, 0, strlen(tag_begin));
- state = STATE_LYRICS;
+ state = prev_state;
+ prev_state = STATE_MARKUP_ATTR_NAME;
break;
} else {
tags[ta]->attrs[at]->name = realloc(tags[ta]->attrs[at]->name, (atn+1) * sizeof(char));
@@ -2386,12 +2438,23 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
return NULL;
}
tags[ta]->style = tag_style;
- cho_style_free(songs[so]->sections[se]->lines[li]->lyrics[ly]->style);
- songs[so]->sections[se]->lines[li]->lyrics[ly]->style = cho_style_duplicate(tag_style);
+ switch (prev_state) {
+ case STATE_LYRICS:
+ cho_style_free(songs[so]->sections[se]->lines[li]->lyrics[ly]->style);
+ songs[so]->sections[se]->lines[li]->lyrics[ly]->style = cho_style_duplicate(tag_style);
+ break;
+ case STATE_CHORD:
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord = malloc(sizeof(struct ChoChord));
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style = cho_style_duplicate(tag_style);
+ break;
+ case STATE_ANNOTATION:
+ break;
+ }
at = 0;
avs = AVS_NO;
memset(tag_begin, 0, strlen(tag_begin));
- state = STATE_LYRICS;
+ state = prev_state;
+ prev_state = STATE_MARKUP_ATTR_VALUE;
break;
}
if (
diff --git a/chordpro.h b/chordpro.h
@@ -213,7 +213,7 @@ struct ChoLineItemAbove {
bool is_chord;
union {
struct ChoChord *chord;
- struct ChoAnnotation *annot;
+ struct ChoAnnotation **annot;
} u;
};