lorid

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

commit f7126d012b878b189d3e5512e8bb9817e21209d4
parent 245ab0fb0ae37601d43bc6deceb5f857fd295f62
Author: nibo <nibo@relim.de>
Date:   Tue, 19 Nov 2024 20:55:34 +0100

Improve metadata directive parsing

Diffstat:
Mchordpro.c | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Mchordpro.h | 5+++++
Mlorid.c | 5+++++
3 files changed, 79 insertions(+), 30 deletions(-)

diff --git a/chordpro.c b/chordpro.c @@ -21,7 +21,7 @@ static const char *environment_directives[] = { }; static const char *metadata_directives[] = { - "title", "sorttitle", "subtitle", + "title", "t", "subtitle", "st", "sorttitle", "artist", "composer", "lyricist", "copyright", "album", "year", "key", "time", "tempo", "duration", "capo", @@ -2890,6 +2890,7 @@ cho_directive_new(void) directive->sprop = SPT_EMPTY; directive->ftype = SF_EMPTY; directive->btype = BT_EMPTY; + directive->meta = OTHER; directive->style = cho_style_new_default(); return directive; } @@ -3004,6 +3005,33 @@ cho_directive_parse(const char *name) directive->ftype = SF_TEXT; goto END; } + if ( + !strcmp(name, metadata_directives[TITLE]) || + !strcmp(name, metadata_directives[T]) + ) { + directive->dtype = DT_METADATA; + directive->meta = TITLE; + cho_style_free(directive->style); + g_prev_ftype = g_current_ftype; + g_current_ftype = SF_TITLE; + directive->style = cho_style_new_default(); + g_current_ftype = g_prev_ftype; + goto END; + + } else if ( + !strcmp(name, metadata_directives[SUBTITLE]) || + !strcmp(name, metadata_directives[ST]) + ) { + directive->dtype = DT_METADATA; + directive->meta = SUBTITLE; + cho_style_free(directive->style); + g_prev_ftype = g_current_ftype; + g_current_ftype = SF_SUBTITLE; + directive->style = cho_style_new_default(); + g_current_ftype = g_prev_ftype; + goto END; + } + i = 4; while (metadata_directives[i] != NULL) { if (!strcmp(metadata_directives[i], name)) { directive->dtype = DT_METADATA; @@ -3289,7 +3317,7 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) char tag_start[6]; char tag_end[6]; char custom_directive[64]; - char *label; + char *label, *metadata_value; enum State state = STATE_LYRICS; enum State prev_state = STATE_LYRICS; int dn = 0; @@ -3571,12 +3599,7 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) } break; case DT_METADATA: - cho_log(LOG_INFO, "Metadata directive '%s' has no value.", directive_name); - songs[so]->metadata = erealloc(songs[so]->metadata, (m+1) * sizeof(struct ChoMetadata *)); - songs[so]->metadata[m] = cho_metadata_new(); - songs[so]->metadata[m]->name = strdup(directive_name); - m++; - memset(directive_name, 0, strlen(directive_name)); + cho_log(LOG_WARN, "Ignoring metadata directive '%s' because it has no value.", directive_name); break; case DT_FORMATTING: cho_log(LOG_WARN, "Formatting directive '%s' has no value.", directive_name); @@ -3828,33 +3851,49 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) } break; case DT_METADATA: - if (!strcmp(directive_name, "meta")) { - metadata = cho_metadata_split(directive_value); - if (metadata) { + metadata_value = str_remove_leading_whitespace(directive_value); + if (strlen(metadata_value) == 0) { + cho_log(LOG_WARN, "Ignoring metadata directive '%s' because it has no value.", directive_name); + free(metadata_value); + break; + } + switch (directive->meta) { + case TITLE: + songs[so]->metadata = erealloc(songs[so]->metadata, (m+1) * sizeof(struct ChoMetadata *)); + songs[so]->metadata[m] = cho_metadata_new(); + songs[so]->metadata[m]->name = strdup("title"); + songs[so]->metadata[m]->value = metadata_value; + cho_style_free(songs[so]->metadata[m]->style); + songs[so]->metadata[m]->style = cho_style_copy(directive->style); + m++; + break; + case SUBTITLE: + songs[so]->metadata = erealloc(songs[so]->metadata, (m+1) * sizeof(struct ChoMetadata *)); + songs[so]->metadata[m] = cho_metadata_new(); + songs[so]->metadata[m]->name = strdup("subtitle"); + songs[so]->metadata[m]->value = metadata_value; + cho_style_free(songs[so]->metadata[m]->style); + songs[so]->metadata[m]->style = cho_style_copy(directive->style); + m++; + break; + default: + if (!strcmp(directive_name, "meta")) { + metadata = cho_metadata_split(directive_value); + if (!metadata) { + LOG_DEBUG("cho_metadata_split failed."); + return NULL; + } songs[so]->metadata = erealloc(songs[so]->metadata, (m+1) * sizeof(struct ChoMetadata *)); songs[so]->metadata[m] = metadata; m++; + free(metadata_value); } else { - LOG_DEBUG("cho_metadata_split failed."); - return NULL; - } - } else { - songs[so]->metadata = erealloc(songs[so]->metadata, (m+1) * sizeof(struct ChoMetadata *)); - songs[so]->metadata[m] = cho_metadata_new(); - songs[so]->metadata[m]->name = strdup(directive_name); - songs[so]->metadata[m]->value = str_remove_leading_whitespace(directive_value); - if (!strcmp(directive_name, "title")) { - g_prev_ftype = g_current_ftype; - g_current_ftype = SF_TITLE; - songs[so]->metadata[m]->style = cho_style_new_default(); - g_current_ftype = g_prev_ftype; - } else if (!strcmp(directive_name, "subtitle")) { - g_prev_ftype = g_current_ftype; - g_current_ftype = SF_SUBTITLE; - songs[so]->metadata[m]->style = cho_style_new_default(); - g_current_ftype = g_prev_ftype; + songs[so]->metadata = erealloc(songs[so]->metadata, (m+1) * sizeof(struct ChoMetadata *)); + songs[so]->metadata[m] = cho_metadata_new(); + songs[so]->metadata[m]->name = strdup(directive_name); + songs[so]->metadata[m]->value = metadata_value; + m++; } - m++; } break; case DT_FORMATTING: diff --git a/chordpro.h b/chordpro.h @@ -20,6 +20,10 @@ enum EnvironmentDirective { START_OF_GRID, SOG, END_OF_GRID, EOG }; +enum MetadataDirective { + TITLE, T, SUBTITLE, ST, OTHER +}; + enum FormattingDirective { COMMENT, C, HIGHLIGHT, COMMENT_ITALIC, CI, COMMENT_BOX, CB @@ -271,6 +275,7 @@ struct ChoDirective { enum StylePropertyType sprop; enum SongFragmentType ftype; enum BreakType btype; + enum MetadataDirective meta; struct ChoStyle *style; }; diff --git a/lorid.c b/lorid.c @@ -70,6 +70,11 @@ main(int argc, char *argv[]) LOG_DEBUG("cho_songs_parse failed."); return 1; } + struct ChoMetadata **m = songs[0]->metadata; + while (*m) { + printf("'%s' = '%s'\n", (*m)->name, (*m)->value); + m++; + } char *pdf_filename = out_pdf_create(argc == optind+1 ? argv[argc-1] : NULL, output ? output : NULL, songs, config); if (!pdf_filename) { LOG_DEBUG("out_pdf_new failed.");