commit 3c289cc1606ab9392130318b2f0467462242b250
parent 79a5a9893f502100d29ea2dac399a4115a543b91
Author: nibo <nibo@relim.de>
Date: Tue, 6 Aug 2024 10:18:19 +0200
Add title style and reset default style on {new_song}
Diffstat:
4 files changed, 55 insertions(+), 30 deletions(-)
diff --git a/chordpro.c b/chordpro.c
@@ -848,6 +848,9 @@ struct Style *cho_style_new_from_config(enum SongFragmentType ftype)
case SF_LABEL:
printable_item = config_printable_item_get(g_config->printable_items, "label");
return cho_style_duplicate(printable_item->style);
+ case SF_TITLE:
+ printable_item = config_printable_item_get(g_config->printable_items, "title");
+ return cho_style_duplicate(printable_item->style);
default:
printable_item = config_printable_item_get(g_config->printable_items, "text");
return cho_style_duplicate(printable_item->style);
@@ -1287,14 +1290,22 @@ static void cho_style_change_default(struct StyleProperty sprop)
switch (sprop.type) {
case SPT_FONT:
free(default_style_properties[i].u.font_name);
- default_style_properties[i].u.font_name = strdup(sprop.u.font_name);
+ if (sprop.u.font_name) {
+ default_style_properties[i].u.font_name = strdup(sprop.u.font_name);
+ } else {
+ default_style_properties[i].u.font_name = NULL;
+ }
break;
case SPT_SIZE:
default_style_properties[i].u.font_size = sprop.u.font_size;
break;
case SPT_COLOR:
free(default_style_properties[i].u.foreground_color);
- default_style_properties[i].u.foreground_color = cho_rgbcolor_duplicate(sprop.u.foreground_color);
+ if (sprop.u.foreground_color) {
+ default_style_properties[i].u.foreground_color = cho_rgbcolor_duplicate(sprop.u.foreground_color);
+ } else {
+ default_style_properties[i].u.foreground_color = NULL;
+ }
break;
default:
fprintf(stderr, "INFO: Invalid style property type '%d'.\n", sprop.type);
@@ -1303,6 +1314,28 @@ static void cho_style_change_default(struct StyleProperty sprop)
}
}
+static void cho_style_reset_default(void)
+{
+ unsigned int i;
+ for (i = 0; i<LENGTH(default_style_properties); i++) {
+ switch (default_style_properties[i].type) {
+ case SPT_FONT:
+ free(default_style_properties[i].u.font_name);
+ default_style_properties[i].u.font_name = NULL;
+ break;
+ case SPT_SIZE:
+ default_style_properties[i].u.font_size = EMPTY;
+ break;
+ case SPT_COLOR:
+ free(default_style_properties[i].u.foreground_color);
+ default_style_properties[i].u.foreground_color = NULL;
+ break;
+ default:
+ fprintf(stderr, "INFO: Invalid style property type '%d'.\n", default_style_properties[i].type);
+ }
+ }
+}
+
static struct Attr *cho_tag_attr_new(void)
{
struct Attr *attr = malloc(sizeof(struct Attr));
@@ -1388,6 +1421,7 @@ static struct ChoMetadata *cho_metadata_new(void)
struct ChoMetadata *meta = malloc(sizeof(struct ChoMetadata));
meta->name = NULL;
meta->value = NULL;
+ meta->style = NULL;
return meta;
}
@@ -1671,6 +1705,9 @@ static void cho_song_free(struct ChoSong *song)
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++;
}
@@ -2179,6 +2216,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
se++;
songs[so]->sections = realloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
songs[so]->sections[se] = NULL;
+ cho_style_reset_default();
so++;
songs = realloc(songs, (so+1) * sizeof(struct ChoSong *));
songs[so] = cho_song_new();
@@ -2194,29 +2232,23 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
songs[so]->sections[se]->lines[li]->lyrics[ly] = cho_line_item_new();
break;
case DT_FONT:
- config_style = cho_style_new_from_config(g_current_ftype);
+ // Reset to default
sprop.ftype = directive->ftype;
sprop.type = directive->sprop;
switch (directive->sprop) {
case SPT_FONT:
- sprop.u.font_name = strdup(config_style->font->name);
+ sprop.u.font_name = NULL;
break;
case SPT_SIZE:
- sprop.u.font_size = config_style->font->size;
+ sprop.u.font_size = EMPTY;
break;
case SPT_COLOR:
- sprop.u.foreground_color = cho_rgbcolor_duplicate(config_style->foreground_color);
+ sprop.u.foreground_color = NULL;
break;
default:
fprintf(stderr, "INFO: Ignoring invalid style property type '%s'.\n", the_style_property_type(directive->sprop));
}
cho_style_change_default(sprop);
- if (sprop.type == SPT_FONT) {
- free(sprop.u.font_name);
- } else if (sprop.type == SPT_COLOR) {
- free(sprop.u.foreground_color);
- }
- cho_style_free(config_style);
break;
case DT_CUSTOM:
fprintf(stderr, "INFO: Ignoring custom directive '%s'.\n", directive_name);
@@ -2294,7 +2326,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
case DT_METADATA:
if (strcmp(directive_name, "meta") == 0) {
metadata = cho_metadata_split(directive_value);
- if (metadata != NULL) {
+ if (metadata) {
songs[so]->metadata = realloc(songs[so]->metadata, (m+1) * sizeof(struct ChoMetadata *));
songs[so]->metadata[m] = metadata;
m++;
@@ -2304,6 +2336,12 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
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") == 0) {
+ 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;
+ }
m++;
}
break;
@@ -2636,16 +2674,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
free(songs[so]->sections[se]->lines[li]->lyrics);
free(songs[so]->sections[se]->lines[li]->text_above);
free(songs[so]->sections[se]->lines[li]);
-
- unsigned int i;
- for (i = 0; i<LENGTH(default_style_properties); i++) {
- if (default_style_properties[i].type == SPT_FONT) {
- free(default_style_properties[i].u.font_name);
- } else if (default_style_properties[i].type == SPT_COLOR) {
- free(default_style_properties[i].u.foreground_color);
- }
- }
-
+ cho_style_reset_default();
songs[so]->sections[se]->lines[li] = NULL;
songs[so]->metadata = realloc(songs[so]->metadata, (m+1) * sizeof(struct ChoMetadata *));
songs[so]->metadata[m] = NULL;
diff --git a/chordpro.h b/chordpro.h
@@ -185,6 +185,7 @@ struct ChoDirective {
struct ChoMetadata {
char *name;
char *value;
+ struct Style *style;
};
struct ChoChord {
diff --git a/out_pdf.c b/out_pdf.c
@@ -636,17 +636,12 @@ static struct Text **text_create(struct ChoSong **songs, struct Config *config)
text[t]->lines = NULL;
for (m = 0; songs[so]->metadata[m]; m++) {
if (strcmp(songs[so]->metadata[m]->name, "title") == 0) {
- printable_item = config_printable_item_get(config->printable_items, "title");
- if (!printable_item) {
- fprintf(stderr, "config_printable_item_get failed.\n");
- return NULL;
- }
text[t]->lines = realloc(text[t]->lines, (tl+1) * sizeof(struct TextLine *));
text[t]->lines[tl] = malloc(sizeof(struct TextLine));
text[t]->lines[tl]->items = malloc(2 * sizeof(struct TextLineItem *));
text[t]->lines[tl]->items[0] = malloc(sizeof(struct TextLineItem));
text[t]->lines[tl]->items[0]->text = strdup(songs[so]->metadata[m]->value);
- text[t]->lines[tl]->items[0]->style = cho_style_duplicate(printable_item->style);
+ text[t]->lines[tl]->items[0]->style = cho_style_duplicate(songs[so]->metadata[m]->style);
width = text_width(text[t]->lines[tl]->items[0]);
if (width == EMPTY) {
fprintf(stderr, "text_width failed.\n");
diff --git a/todo b/todo
@@ -4,7 +4,7 @@ apply all config in cho_songs_parse() instead of out_pdf_new()
'image' directive
https://chordpro.org/chordpro/directives-image/
metadata directives
- %{blabla}
+ %{blabla} in lyrics and chords
add style to every metadata
font, size, colour directives
chords