lorid

convert chordpro to pdf
git clone git://git.relim.de/lorid.git
Log | Files | Refs | README | LICENSE

commit a4b139b6ed79b49ff242c3b4bdd30605446708f8
parent 4f825dd807715e457bfccdb30870d6e81db1588b
Author: nibo <nibo@relim.de>
Date:   Tue,  6 Aug 2024 16:24:26 +0200

WIP

Diffstat:
Mchordpro.c | 99++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Mchordpro.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; };