commit 5cdcd20adae1254f08388e25d3989462bf4d0823
parent c5e180a993b8aba8d80f2bc098eceb27f44bf4d1
Author: nibo <nibo@relim.de>
Date: Thu, 10 Oct 2024 13:45:02 +0200
Start implementing 'chorus' directive
Diffstat:
| M | chordpro.c | | | 61 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
| M | todo | | | 6 | +----- |
2 files changed, 61 insertions(+), 6 deletions(-)
diff --git a/chordpro.c b/chordpro.c
@@ -2103,6 +2103,19 @@ static struct ChoImage *cho_image_directive_parse(const char *str)
{
} */
+static char *cho_find_chorus_label_name(struct ChoSection **sections, int se)
+{
+ int i;
+ for (i = se; i>=0; i--) {
+ if (sections[i]->type == ST_CHORUS) {
+ if (sections[i]->label) {
+ return strdup(sections[i]->label->name);
+ }
+ }
+ }
+ return NULL;
+}
+
static struct ChoDirective *cho_directive_new(void)
{
struct ChoDirective *directive = malloc(sizeof(struct ChoDirective));
@@ -2144,6 +2157,10 @@ static struct ChoDirective *cho_directive_parse(const char *name)
directive->stype = ST_CHORUS;
directive->ftype = SF_TEXT;
goto END;
+ } else if (!strcmp(name, environment_directives[CHORUS])) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->ftype = SF_LABEL;
+ goto END;
} else if (
!strcmp(name, environment_directives[START_OF_VERSE]) ||
!strcmp(name, environment_directives[SOV])
@@ -2411,6 +2428,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct
char tag_begin[6];
char tag_end[6];
char custom_directive[64];
+ char *label;
enum State state = STATE_LYRICS;
enum State prev_state = STATE_LYRICS;
int dn = 0;
@@ -2592,6 +2610,28 @@ struct ChoSong **cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct
songs[so]->sections[se]->lines[li]->lyrics[ly] = cho_line_item_new();
}
break;
+ case POS_EMPTY:
+ /* INFO: {chorus} */
+ label = cho_find_chorus_label_name(songs[so]->sections, se);
+ if (!label) {
+ label = strdup("Chorus");
+ }
+ songs[so]->sections[se]->lines[li]->lyrics[ly]->text = realloc(songs[so]->sections[se]->lines[li]->lyrics[ly]->text, (te+1) * sizeof(char));
+ songs[so]->sections[se]->lines[li]->lyrics[ly]->text[te] = 0;
+ if (strlen(songs[so]->sections[se]->lines[li]->lyrics[ly]->text) == 0) {
+ cho_line_item_free(songs[so]->sections[se]->lines[li]->lyrics[ly]);
+ } else {
+ ly++;
+ }
+ 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();
+ cho_style_free(songs[so]->sections[se]->lines[li]->lyrics[ly]->style);
+ g_current_ftype = SF_LABEL;
+ songs[so]->sections[se]->lines[li]->lyrics[ly]->style = cho_style_new_default();
+ songs[so]->sections[se]->lines[li]->lyrics[ly]->text = label;
+ te += strlen(label);
+ cho_log(LOG_INFO, "{chorus} directive in sight.");
+ break;
default:
cho_log(LOG_ERR, "Invalid position value '%d'.", directive->position);
return NULL;
@@ -2747,6 +2787,25 @@ struct ChoSong **cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct
songs[so]->sections[se]->lines[li]->lyrics[ly] = cho_line_item_new();
}
break;
+ case POS_EMPTY:
+ /* INFO: {chorus: ...} */
+ label = str_remove_leading_whitespace(directive_value);
+ songs[so]->sections[se]->lines[li]->lyrics[ly]->text = realloc(songs[so]->sections[se]->lines[li]->lyrics[ly]->text, (te+1) * sizeof(char));
+ songs[so]->sections[se]->lines[li]->lyrics[ly]->text[te] = 0;
+ if (strlen(songs[so]->sections[se]->lines[li]->lyrics[ly]->text) == 0) {
+ cho_line_item_free(songs[so]->sections[se]->lines[li]->lyrics[ly]);
+ } else {
+ ly++;
+ }
+ 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();
+ cho_style_free(songs[so]->sections[se]->lines[li]->lyrics[ly]->style);
+ g_current_ftype = SF_LABEL;
+ songs[so]->sections[se]->lines[li]->lyrics[ly]->style = cho_style_new_default();
+ songs[so]->sections[se]->lines[li]->lyrics[ly]->text = label;
+ te += strlen(label);
+ cho_log(LOG_INFO, "{chorus: ...} directive in sight.");
+ break;
default:
cho_log(LOG_ERR, "Invalid position value '%d'.", directive->position);
return NULL;
@@ -2792,7 +2851,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct
}
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();
- cho_style_free(songs[so]->sections[se]->lines[li]->lyrics[ly]->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(directive->style);
char *trimmed_directive_value = str_remove_leading_whitespace(directive_value);
songs[so]->sections[se]->lines[li]->lyrics[ly]->text = trimmed_directive_value;
diff --git a/todo b/todo
@@ -1,5 +1,5 @@
'chorus' directive
- decide how to implement
+ add config options 'default_label' and 'quote'
'image' directive
https://chordpro.org/chordpro/directives-image/
metadata directives
@@ -23,7 +23,3 @@ render in two or more columns
find better name for PrintableItem, TextAbove
consider freeing memory in case of errors
decide and then change consistent global variables prefix 'g_' or not
-change logging:
- #define LOG_DEBUG
- #define LOG_INFO
- <filepath> <line_number> <log_level> <msg>