commit 1eeaad2ae0779e34f6a80dc0310f9bd2d6bb2867
parent 5cdcd20adae1254f08388e25d3989462bf4d0823
Author: nibo <nibo@relim.de>
Date: Fri, 11 Oct 2024 14:26:47 +0200
Implement 'chorus' directive
two new settings:
- default chorus label
- if the chorus should be quoted or not
Diffstat:
5 files changed, 333 insertions(+), 112 deletions(-)
diff --git a/chordpro.c b/chordpro.c
@@ -1424,6 +1424,14 @@ static struct ChoMetadata *cho_metadata_new(void)
return meta;
}
+static void cho_metadata_free(struct ChoMetadata *meta)
+{
+ free(meta->name);
+ free(meta->value);
+ cho_style_free(meta->style);
+ free(meta);
+}
+
const char *cho_metadata_get(struct ChoMetadata **metadata, const char *name)
{
int m;
@@ -1611,6 +1619,19 @@ static void cho_chord_free(struct ChoChord *chord)
free(chord);
}
+static struct ChoChord *cho_chord_copy(struct ChoChord *chord)
+{
+ struct ChoChord *copy = malloc(sizeof(struct ChoChord));
+ copy->style = cho_style_duplicate(chord->style);
+ copy->is_canonical = chord->is_canonical;
+ copy->qual = chord->qual;
+ copy->name = strdup(chord->name);
+ copy->root = chord->root ? strdup(chord->root) : NULL;
+ copy->ext = chord->ext ? strdup(chord->ext) : NULL;
+ copy->bass = chord->bass ? strdup(chord->bass) : NULL;
+ return copy;
+}
+
/* returns how many bytes make up the root; returns 0 if no root was found */
static int cho_chord_root_parse(const char *str, struct ChoChord *chord)
{
@@ -1825,6 +1846,21 @@ static struct ChoAnnotation *cho_annotation_new(void)
return annot;
}
+static void cho_annotation_free(struct ChoAnnotation *annot)
+{
+ cho_style_free(annot->style);
+ free(annot->text);
+ free(annot);
+}
+
+static struct ChoAnnotation *cho_annotation_copy(struct ChoAnnotation *annot)
+{
+ struct ChoAnnotation *copy = malloc(sizeof(struct ChoAnnotation));
+ copy->style = cho_style_duplicate(annot->style);
+ copy->text = strdup(annot->text);
+ return copy;
+}
+
int cho_text_above_count(struct ChoLineItemAbove **text_above)
{
int i = 0;
@@ -1833,26 +1869,27 @@ int cho_text_above_count(struct ChoLineItemAbove **text_above)
return i;
}
-static struct ChoLine *cho_line_new(void)
+static void cho_text_above_free(struct ChoLineItemAbove *text_above)
{
- struct ChoLine *line = malloc(sizeof(struct ChoLine));
- line->text_above = NULL;
- line->lyrics = NULL;
- line->btype = BT_LINE;
- return line;
+ if (text_above->is_chord) {
+ cho_chord_free(text_above->u.chord);
+ } else {
+ cho_annotation_free(text_above->u.annot);
+ }
+ free(text_above);
}
-static int cho_line_compute_chord_position(struct ChoLine *line, int ly, int te)
+static struct ChoLineItemAbove *cho_text_above_copy(struct ChoLineItemAbove *text_above)
{
- if (ly == 0)
- return te;
- ly--;
- size_t lyrics_len = 0;
- while (ly >= 0) {
- lyrics_len += strlen(line->lyrics[ly]->text);
- ly--;
+ struct ChoLineItemAbove *copy = malloc(sizeof(struct ChoLineItemAbove));
+ copy->position = text_above->position;
+ copy->is_chord = text_above->is_chord;
+ if (copy->is_chord) {
+ copy->u.chord = cho_chord_copy(text_above->u.chord);
+ } else {
+ copy->u.annot = cho_annotation_copy(text_above->u.annot);
}
- return lyrics_len + te;
+ return copy;
}
static struct ChoLineItem *cho_line_item_new(void)
@@ -1870,6 +1907,14 @@ static void cho_line_item_free(struct ChoLineItem *item)
free(item);
}
+static struct ChoLineItem *cho_line_item_copy(struct ChoLineItem *item)
+{
+ struct ChoLineItem *copy = malloc(sizeof(struct ChoLineItem));
+ copy->style = cho_style_duplicate(item->style);
+ copy->text = strdup(item->text);
+ return copy;
+}
+
int cho_line_item_count(struct ChoLineItem **items)
{
int i = 0;
@@ -1878,6 +1923,57 @@ int cho_line_item_count(struct ChoLineItem **items)
return i;
}
+static struct ChoLine *cho_line_new(void)
+{
+ struct ChoLine *line = malloc(sizeof(struct ChoLine));
+ line->text_above = NULL;
+ line->lyrics = NULL;
+ line->btype = BT_LINE;
+ return line;
+}
+
+static void cho_line_free(struct ChoLine *line)
+{
+ int i;
+ for (i = 0; line->lyrics[i]; i++) {
+ cho_line_item_free(line->lyrics[i]);
+ }
+ for (i = 0; line->text_above[i]; i++) {
+ cho_text_above_free(line->text_above[i]);
+ }
+ free(line->lyrics);
+ free(line->text_above);
+ free(line);
+}
+
+static int cho_line_compute_chord_position(struct ChoLine *line, int ly, int te)
+{
+ if (ly == 0)
+ return te;
+ ly--;
+ size_t lyrics_len = 0;
+ while (ly >= 0) {
+ lyrics_len += strlen(line->lyrics[ly]->text);
+ ly--;
+ }
+ return lyrics_len + te;
+}
+
+static struct ChoLabel *cho_section_label_copy(struct ChoLabel *label)
+{
+ struct ChoLabel *copy = malloc(sizeof(struct ChoLabel));
+ copy->name = strdup(label->name);
+ copy->style = cho_style_duplicate(label->style);
+ return copy;
+}
+
+static void cho_section_label_free(struct ChoLabel *label)
+{
+ free(label->name);
+ cho_style_free(label->style);
+ free(label);
+}
+
static struct ChoSection *cho_section_new(void)
{
struct ChoSection *section = malloc(sizeof(struct ChoSection));
@@ -1887,6 +1983,52 @@ static struct ChoSection *cho_section_new(void)
return section;
}
+static void cho_section_free(struct ChoSection *section)
+{
+ if (section->label) {
+ cho_section_label_free(section->label);
+ }
+ int i;
+ for (i = 0; section->lines[i]; i++) {
+ cho_line_free(section->lines[i]);
+ }
+ free(section->lines);
+ free(section);
+}
+
+static struct ChoSection *cho_section_copy(struct ChoSection *section)
+{
+ struct ChoSection *copy = malloc(sizeof(struct ChoSection));
+ copy->type = section->type;
+ if (section->label) {
+ copy->label = cho_section_label_copy(section->label);
+ } else {
+ copy->label = NULL;
+ }
+ copy->lines = NULL;
+ int li, c, ly;
+ for (li = 0; section->lines[li]; li++) {
+ copy->lines = realloc(copy->lines, (li+1) * sizeof(struct ChoLine *));
+ copy->lines[li] = cho_line_new();
+ copy->lines[li]->btype = section->lines[li]->btype;
+ for (c = 0; section->lines[li]->text_above[c]; c++) {
+ copy->lines[li]->text_above = realloc(copy->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
+ copy->lines[li]->text_above[c] = cho_text_above_copy(section->lines[li]->text_above[c]);
+ }
+ copy->lines[li]->text_above = realloc(copy->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
+ copy->lines[li]->text_above[c] = NULL;
+ for (ly = 0; section->lines[li]->lyrics[ly]; ly++) {
+ copy->lines[li]->lyrics = realloc(copy->lines[li]->lyrics, (ly+1) * sizeof(struct ChoLineItem *));
+ copy->lines[li]->lyrics[ly] = cho_line_item_copy(section->lines[li]->lyrics[ly]);
+ }
+ copy->lines[li]->lyrics = realloc(copy->lines[li]->lyrics, (ly+1) * sizeof(struct ChoLineItem *));
+ copy->lines[li]->lyrics[ly] = NULL;
+ }
+ copy->lines = realloc(copy->lines, (li+1) * sizeof(struct ChoLine *));
+ copy->lines[li] = NULL;
+ return copy;
+}
+
static struct ChoSong *cho_song_new(void)
{
struct ChoSong *song = malloc(sizeof(struct ChoSong));
@@ -1905,61 +2047,13 @@ int cho_song_count(struct ChoSong **songs)
static void cho_song_free(struct ChoSong *song)
{
- int i = 0;
- int k = 0;
- int c = 0;
- int ly = 0;
- while (song->metadata[i] != NULL) {
- free(song->metadata[i]->name);
- free(song->metadata[i]->value);
- if (song->metadata[i]->style) {
- cho_style_free(song->metadata[i]->style);
- }
- free(song->metadata[i]);
- i++;
+ int i;
+ for (i = 0; song->metadata[i]; i++) {
+ cho_metadata_free(song->metadata[i]);
}
free(song->metadata);
- i = 0;
- while (song->sections[i] != NULL) {
- if (song->sections[i]->label) {
- free(song->sections[i]->label->name);
- cho_style_free(song->sections[i]->label->style);
- free(song->sections[i]->label);
- }
- while (song->sections[i]->lines[k] != NULL) {
- while (song->sections[i]->lines[k]->lyrics[ly] != NULL) {
- cho_style_free(song->sections[i]->lines[k]->lyrics[ly]->style);
- free(song->sections[i]->lines[k]->lyrics[ly]->text);
- free(song->sections[i]->lines[k]->lyrics[ly]);
- ly++;
- }
- while (song->sections[i]->lines[k]->text_above[c] != NULL) {
- if (song->sections[i]->lines[k]->text_above[c]->is_chord) {
- cho_style_free(song->sections[i]->lines[k]->text_above[c]->u.chord->style);
- free(song->sections[i]->lines[k]->text_above[c]->u.chord->name);
- free(song->sections[i]->lines[k]->text_above[c]->u.chord->root);
- free(song->sections[i]->lines[k]->text_above[c]->u.chord->ext);
- free(song->sections[i]->lines[k]->text_above[c]->u.chord->bass);
- free(song->sections[i]->lines[k]->text_above[c]->u.chord);
- } else {
- cho_style_free(song->sections[i]->lines[k]->text_above[c]->u.annot->style);
- free(song->sections[i]->lines[k]->text_above[c]->u.annot->text);
- free(song->sections[i]->lines[k]->text_above[c]->u.annot);
- }
- free(song->sections[i]->lines[k]->text_above[c]);
- c++;
- }
- free(song->sections[i]->lines[k]->lyrics);
- free(song->sections[i]->lines[k]->text_above);
- free(song->sections[i]->lines[k]);
- ly = 0;
- c = 0;
- k++;
- }
- free(song->sections[i]->lines);
- free(song->sections[i]);
- k = 0;
- i++;
+ for (i = 0; song->sections[i]; i++) {
+ cho_section_free(song->sections[i]);
}
free(song->sections);
free(song);
@@ -2103,14 +2197,12 @@ static struct ChoImage *cho_image_directive_parse(const char *str)
{
} */
-static char *cho_find_chorus_label_name(struct ChoSection **sections, int se)
+static struct ChoSection *cho_find_previous_chorus(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 sections[i];
}
}
return NULL;
@@ -2470,6 +2562,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct
struct Style *tag_style;
struct StyleProperty sprop;
struct ChoChord *tmp_chord;
+ struct ChoSection *chorus;
struct ChoImage *image;
while (feof(fp) == 0) {
read = fread(&buf, 1, 1, fp);
@@ -2612,25 +2705,74 @@ struct ChoSong **cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct
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]);
+ chorus = cho_find_previous_chorus(songs[so]->sections, se);
+ if (chorus) {
+ if (config->output->chorus->quote) {
+ 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;
+ 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] = NULL;
+ ly = 0;
+ te = 0;
+ 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] = NULL;
+ c = 0;
+ cho_line_free(songs[so]->sections[se]->lines[li]);
+ // songs[so]->sections[se]->lines = realloc(songs[so]->sections[se]->lines, (li+1) * sizeof(struct ChoLine *));
+ songs[so]->sections[se]->lines[li] = NULL;
+ li = 0;
+ se++;
+ songs[so]->sections = realloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
+ songs[so]->sections[se] = cho_section_copy(chorus);
+ se++;
+ songs[so]->sections = realloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
+ songs[so]->sections[se] = cho_section_new();
+ songs[so]->sections[se]->lines = malloc(sizeof(struct ChoLine *));
+ songs[so]->sections[se]->lines[li] = cho_line_new();
+ songs[so]->sections[se]->lines[li]->lyrics = malloc(sizeof(struct ChoLineItem *));
+ songs[so]->sections[se]->lines[li]->lyrics[ly] = cho_line_item_new();
+ } else {
+ if (chorus->label) {
+ label = strdup(chorus->label->name);
+ } else {
+ label = strdup(config->output->chorus->label);
+ }
+ 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);
+ }
} else {
- ly++;
+ if (config->output->chorus->quote) {
+ cho_log(LOG_WARN, "Can't quote chorus because it's not defined previously.");
+ }
+ label = strdup(config->output->chorus->label);
+ 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);
}
- 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);
@@ -2790,21 +2932,76 @@ struct ChoSong **cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct
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]);
+ chorus = cho_find_previous_chorus(songs[so]->sections, se);
+ if (chorus) {
+ if (config->output->chorus->quote) {
+ 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;
+ 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] = NULL;
+ ly = 0;
+ te = 0;
+ 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] = NULL;
+ c = 0;
+ cho_line_free(songs[so]->sections[se]->lines[li]);
+ // songs[so]->sections[se]->lines = realloc(songs[so]->sections[se]->lines, (li+1) * sizeof(struct ChoLine *));
+ songs[so]->sections[se]->lines[li] = NULL;
+ li = 0;
+ se++;
+ songs[so]->sections = realloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
+ songs[so]->sections[se] = cho_section_copy(chorus);
+ if (songs[so]->sections[se]->label) {
+ free(songs[so]->sections[se]->label->name);
+ songs[so]->sections[se]->label->name = label;
+ } else {
+ songs[so]->sections[se]->label = malloc(sizeof(struct ChoLabel));
+ g_current_ftype = SF_LABEL;
+ songs[so]->sections[se]->label->style = cho_style_new_default();
+ }
+ se++;
+ songs[so]->sections = realloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
+ songs[so]->sections[se] = cho_section_new();
+ songs[so]->sections[se]->lines = malloc(sizeof(struct ChoLine *));
+ songs[so]->sections[se]->lines[li] = cho_line_new();
+ songs[so]->sections[se]->lines[li]->lyrics = malloc(sizeof(struct ChoLineItem *));
+ songs[so]->sections[se]->lines[li]->lyrics[ly] = cho_line_item_new();
+ } else {
+ 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);
+ }
} else {
- ly++;
+ if (config->output->chorus->quote) {
+ cho_log(LOG_WARN, "Can't quote chorus because it's not defined previously.");
+ }
+ 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);
}
- 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);
diff --git a/chordpro.h b/chordpro.h
@@ -252,6 +252,10 @@ enum BreakType {
BT_EMPTY
};
+/*
+ INFO: Depending on the 'dtype' the other
+ fields have a meaningful value or not.
+*/
struct ChoDirective {
enum DirectiveType dtype;
enum SectionType stype;
diff --git a/config.c b/config.c
@@ -297,6 +297,9 @@ static struct Config *config_load_default(void)
{
struct Config *config = malloc(sizeof(struct Config));
config->output = malloc(sizeof(struct ConfigOutput));
+ config->output->chorus = malloc(sizeof(struct ConfigChorus));
+ config->output->chorus->label = strdup("Chorus");
+ config->output->chorus->quote = false;
config->output->system = NS_COMMON;
config->output->printable_items = malloc(12 * sizeof(struct PrintableItem *));
config->output->printable_items[0] = config_printable_item_new("title");
@@ -348,12 +351,15 @@ static void config_printable_item_print_as_toml(struct PrintableItem *item)
void config_print_default(void)
{
struct Config *config = config_load_default();
- int i = 0;
+ printf("[notes]\n\n");
+ config_notes_print_as_toml(config->output->system, config->output->notes);
printf("[output]\n\n");
printf("system = \"%s\"\n\n", config_naming_system_to_config_string(config->output->system));
- printf("[output.notes]\n\n");
- config_notes_print_as_toml(config->output->system, config->output->notes);
+ printf("[output.chorus]\n\n");
+ printf("label = \"Chorus\"\n");
+ printf("quote = false\n\n");
printf("[output.styles]\n\n");
+ int i = 0;
while (config->output->printable_items[i] != NULL) {
config_printable_item_print_as_toml(config->output->printable_items[i]);
i++;
@@ -575,16 +581,27 @@ struct Config *config_load(const char *filepath)
}
toml_table_t *output = toml_table_table(table, "output");
if (output) {
- toml_table_t *notes;
+ toml_table_t *notes, *chorus;
toml_value_t value;
enum NamingSystem system;
struct Note **custom_notes;
+ chorus = toml_table_table(output, "chorus");
+ if (chorus) {
+ value = toml_table_string(chorus, "label");
+ if (value.ok) {
+ free(config->output->chorus->label);
+ config->output->chorus->label = value.u.s;
+ }
+ value = toml_table_bool(chorus, "quote");
+ if (value.ok) {
+ config->output->chorus->quote = value.u.b;
+ }
+ }
value = toml_table_string(output, "system");
if (value.ok) {
system = config_naming_system_parse(value.u.s);
if (system == NS_CUSTOM) {
notes = toml_table_table(table, "notes");
- // notes = toml_table_table(output, "notes");
if (!notes) {
util_log(LOG_ERR, "Custom notes '%s' has no corresponding definition in [notes].", value.u.s);
return NULL;
@@ -678,6 +695,8 @@ struct Config *config_load(const char *filepath)
void config_free(struct Config *config)
{
int i;
+ free(config->output->chorus->label);
+ free(config->output->chorus);
for (i = 0; config->output->printable_items[i]; i++) {
config_printable_item_free(config->output->printable_items[i]);
}
diff --git a/config.h b/config.h
@@ -36,13 +36,12 @@ enum NoteType {
struct ConfigChords {
enum NamingSystem system;
enum ParseMode mode;
- // struct Note **notes;
};
-/* struct Config {
- struct PrintableItem **printable_items;
- struct ConfigChords *chords;
-}; */
+struct ConfigChorus {
+ char *label;
+ bool quote;
+};
struct ConfigParser {
struct ConfigChords *chords;
@@ -50,6 +49,7 @@ struct ConfigParser {
};
struct ConfigOutput {
+ struct ConfigChorus *chorus;
enum NamingSystem system;
struct PrintableItem **printable_items;
struct Note **notes;
diff --git a/todo b/todo
@@ -23,3 +23,4 @@ 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
+rename functions *_duplicate to *_copy