lorid

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

commit 4f825dd807715e457bfccdb30870d6e81db1588b
parent 3c289cc1606ab9392130318b2f0467462242b250
Author: nibo <nibo@relim.de>
Date:   Tue,  6 Aug 2024 12:32:23 +0200

Add DEBUG flag and remove duplicate functions

Diffstat:
MMakefile | 2+-
Mchordpro.c | 469++++++++++++++++++++++++++++++++++---------------------------------------------
Mchordpro.h | 21++++++---------------
Mconfig.c | 6+++---
Mlorid.c | 3+++
Mout_pdf.c | 19++-----------------
Mtodo | 3+--
7 files changed, 217 insertions(+), 306 deletions(-)

diff --git a/Makefile b/Makefile @@ -8,7 +8,7 @@ SRC = util.c fontconfig.c config.c chordpro.c out_pdf.c lorid.c all: $(CC) ${CFLAGS} -O2 ${SRC} -o lorid ${LDFLAGS} debug: - $(CC) ${CFLAGS} -g ${SRC} -o lorid ${LDFLAGS} + $(CC) ${CFLAGS} -DDEBUG=1 -g ${SRC} -o lorid ${LDFLAGS} fontconfig: $(CC) -g chordpro.c fontconfig.c -o fontconfig -lfontconfig parser: diff --git a/chordpro.c b/chordpro.c @@ -141,234 +141,6 @@ static enum SongFragmentType g_current_ftype = SF_TEXT; static enum SongFragmentType g_prev_ftype = SF_TEXT; static struct Config *g_config = NULL; -static const char *the_state(enum State state) -{ - switch (state) { - case STATE_LYRICS: - return "STATE_LYRICS"; - case STATE_DIRECTIVE_NAME: - return "STATE_DIRECTIVE_NAME"; - case STATE_DIRECTIVE_VALUE: - return "STATE_DIRECTIVE_VALUE"; - case STATE_CHORD: - return "STATE_CHORD"; - case STATE_ANNOTATION: - return "STATE_ANNOTATION"; - case STATE_MARKUP_TAG_BEGIN: - return "STATE_MARKUP_TAG_BEGIN"; - case STATE_MARKUP_TAG_END: - return "STATE_MARKUP_TAG_END"; - case STATE_MARKUP_TAG: - return "STATE_MARKUP_TAG"; - case STATE_MARKUP_ATTR_NAME: - return "STATE_MARKUP_ATTR_NAME"; - case STATE_MARKUP_ATTR_VALUE: - return "STATE_MARKUP_ATTR_VALUE"; - case STATE_COMMENT: - return "STATE_COMMENT"; - } - return ""; -} - -const char *the_dtype(enum DirectiveType dtype) -{ - switch (dtype) { - case DT_EMPTY: - return "DT_EMPTY"; - case DT_ENVIRONMENT: - return "DT_ENVIRONMENT"; - case DT_METADATA: - return "DT_METADATA"; - case DT_FORMATTING: - return "DT_FORMATTING"; - case DT_PREAMBLE: - return "DT_PREAMBLE"; - case DT_FONT: - return "DT_FONT"; - case DT_CUSTOM: - return "DT_CUSTOM"; - } - return ""; -} - -const char *the_stype(enum SectionType stype) -{ - switch (stype) { - case ST_EMPTY: - return "ST_EMPTY"; - case ST_CHORUS: - return "ST_CHORUS"; - case ST_VERSE: - return "ST_VERSE"; - case ST_BRIDGE: - return "ST_BRIDGE"; - case ST_TAB: - return "ST_TAB"; - case ST_GRID: - return "ST_GRID"; - case ST_NEWSONG: - return "ST_NEWSONG"; - } - return ""; -} - -const char *the_pos(enum Position pos) -{ - switch (pos) { - case POS_EMPTY: - return "POS_EMPTY"; - case POS_START: - return "POS_START"; - case POS_END: - return "POS_END"; - } - return ""; -} - -const char *the_font_family(enum FontFamily font_family) -{ - switch (font_family) { - case FF_EMPTY: - return "FF_EMPTY"; - case FF_NORMAL: - return "FF_NORMAL"; - case FF_SANS: - return "FF_SANS"; - case FF_SERIF: - return "FF_SERIF"; - case FF_MONOSPACE: - return "FF_MONOSPACE"; - } - return ""; -} - -const char *the_font_style(enum FontStyle style) -{ - switch (style) { - case FS_EMPTY: - return "FS_EMPTY"; - case FS_ROMAN: - return "FS_ROMAN"; - case FS_OBLIQUE: - return "FS_OBLIQUE"; - case FS_ITALIC: - return "FS_ITALIC"; - } - return ""; -} - -const char *the_font_weight(enum FontWeight weight) -{ - switch (weight) { - case FW_EMPTY: - return "FW_EMPTY"; - case FW_REGULAR: - return "FW_REGULAR"; - case FW_BOLD: - return "FW_BOLD"; - } - return ""; -} - -const char *the_rgb_color(struct RGBColor *color) -{ - static char str[100]; - sprintf((char *)&str, "rgb(%d,%d,%d) ", color->red, color->green, color->blue); - size_t len = strlen((char *)&str); - sprintf((char *)&str[len], "\x1b[38;2;%d;%d;%dm🬎\x1b[0m", color->red, color->green, color->blue); - return str; -} - -const char *the_line_style(enum LineStyle style) -{ - switch (style) { - case LS_EMPTY: - return "LS_EMPTY"; - case LS_SINGLE: - return "LS_SINGLE"; - case LS_DOUBLE: - return "LS_DOUBLE"; - case LS_NONE: - return "LS_NONE"; - } - return ""; -} - -const char *the_song_fragment_type(enum SongFragmentType ftype) -{ - switch (ftype) { - case SF_EMPTY: - return "SF_EMPTY"; - case SF_CHORD: - return "SF_CHORD"; - case SF_ANNOT: - return "SF_ANNOT"; - case SF_CHORUS: - return "SF_CHORUS"; - case SF_FOOTER: - return "SF_FOOTER"; - case SF_GRID: - return "SF_GRID"; - case SF_TAB: - return "SF_TAB"; - case SF_TOC: - return "SF_TOC"; - case SF_TEXT: - return "SF_TEXT"; - case SF_TITLE: - return "SF_TITLE"; - case SF_LABEL: - return "SF_LABEL"; - } - return ""; -} - -const char *the_style_property_type(enum StylePropertyType type) -{ - switch (type) { - case SPT_EMPTY: - return "SPT_EMPTY"; - case SPT_FONT: - return "SPT_FONT"; - case SPT_SIZE: - return "SPT_SIZE"; - case SPT_COLOR: - return "SPT_COLOR"; - } - return ""; -} - -void the_default_style_properties(void) -{ - unsigned int i; - for (i = 0; i<LENGTH(default_style_properties); i++) { - printf( - "%s %s ", - the_song_fragment_type(default_style_properties[i].ftype), - the_style_property_type(default_style_properties[i].type) - ); - switch (default_style_properties[i].type) { - case SPT_FONT: - if (default_style_properties[i].u.font_name) - printf("%s\n", default_style_properties[i].u.font_name); - else - printf("NULL\n"); - break; - case SPT_SIZE: - printf("%.1f\n", default_style_properties[i].u.font_size); - break; - case SPT_COLOR: - if (default_style_properties[i].u.foreground_color) - printf("%s\n", the_rgb_color(default_style_properties[i].u.foreground_color)); - else - printf("NULL\n"); - break; - default: - printf("Invalid StylePropertyType value '%d'.\n", default_style_properties[i].type); - } - } -} - static inline bool is_whitespace(char c) { if ( @@ -592,20 +364,6 @@ struct Font *cho_font_duplicate(struct Font *font) return copy; } -void cho_font_print(struct Font *font) -{ - printf("---- BEGIN FONT ----\n"); - if (font->name) - printf("font name: %s\n", font->name); - else - printf("font name: NULL\n"); - printf("font family: %s\n", the_font_family(font->family)); - printf("font style: %s\n", the_font_style(font->style)); - printf("font weight: %s\n", the_font_weight(font->weight)); - printf("font size: %f\n", font->size); - printf("---- END FONT ------\n"); -} - void cho_font_free(struct Font *font) { free(font->name); @@ -703,6 +461,20 @@ void cho_font_print_as_toml(struct Font *font, const char *section) printf("\n"); } +void cho_font_print(struct Font *font) +{ + printf("---- BEGIN FONT ----\n"); + if (font->name) + printf("font name: %s\n", font->name); + else + printf("font name: NULL\n"); + printf("font family: %s\n", cho_font_family_to_string(font->family)); + printf("font style: %s\n", cho_font_style_to_string(font->style)); + printf("font weight: %s\n", cho_font_weight_to_string(font->weight)); + printf("font size: %f\n", font->size); + printf("---- END FONT ------\n"); +} + enum LineStyle cho_linestyle_parse(const char *str) { if (strcmp(str, "single") == 0) { @@ -728,6 +500,21 @@ const char *cho_linestyle_to_string(enum LineStyle linestyle) } } +static const char *cho_style_property_type_to_string(enum StylePropertyType type) +{ + switch (type) { + case SPT_EMPTY: + return "SPT_EMPTY"; + case SPT_FONT: + return "SPT_FONT"; + case SPT_SIZE: + return "SPT_SIZE"; + case SPT_COLOR: + return "SPT_COLOR"; + } + return ""; +} + static bool cho_style_property_apply_default(enum SongFragmentType current_ftype, enum StylePropertyType ptype, struct Style *style) { unsigned int i; @@ -1237,28 +1024,6 @@ struct Style *cho_style_get(const char *tag_name, struct Attr **attrs, struct St return style; } -void cho_style_print(struct Style *style) -{ - printf("---- BEGIN STYLE ----\n"); - cho_font_print(style->font); - printf("foreground_color: %s\n", the_rgb_color(style->foreground_color)); - printf("background_color: %s\n", the_rgb_color(style->background_color)); - printf("underline_style: %s\n", the_line_style(style->underline_style)); - printf("underline_color: %s\n", the_rgb_color(style->underline_color)); - printf("overline_style: %s\n", the_line_style(style->overline_style)); - printf("overline_color: %s\n", the_rgb_color(style->overline_color)); - printf("strikethrough: %d\n", style->strikethrough); - printf("strikethrough_color: %s\n", the_rgb_color(style->strikethrough_color)); - printf("boxed: %d\n", style->boxed); - printf("boxed_color: %s\n", the_rgb_color(style->boxed_color)); - printf("rise: %f\n", style->rise); - if (style->href) - printf("href: %s\n", style->href); - else - printf("href: NULL\n"); - printf("---- END STYLE ------\n\n"); -} - void cho_style_print_as_toml(struct Style *style, const char *section) { printf("foreground_color = \"%s\"\n", cho_rgbcolor_to_string(style->foreground_color)); @@ -2067,7 +1832,6 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config) songs[so]->sections[se]->lines[li]->lyrics[ly] = cho_line_item_new(); struct Tag **tags = NULL; struct Style *tag_style; - struct Style *config_style; struct StyleProperty sprop; while (feof(fp) == 0) { read = fread(&buf, 1, 1, fp); @@ -2151,7 +1915,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config) directive = cho_directive_parse(directive_name); /* printf( "directive: '%s'\ndtype: %s, stype: %s, position: %s\n", - directive_name, dtype(directive->dtype), the_stype(directive->stype), pos(directive->position) + directive_name, cho_debug_dtype(directive->dtype), cho_debug_the_stype(directive->stype), cho_debug_the_pos(directive->position) ); */ switch (directive->dtype) { case DT_ENVIRONMENT: @@ -2246,7 +2010,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config) sprop.u.foreground_color = NULL; break; default: - fprintf(stderr, "INFO: Ignoring invalid style property type '%s'.\n", the_style_property_type(directive->sprop)); + fprintf(stderr, "INFO: Ignoring invalid style property type '%s'.\n", cho_style_property_type_to_string(directive->sprop)); } cho_style_change_default(sprop); break; @@ -2471,7 +2235,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config) t = 0; tags[ta]->name = strdup(tag_begin); tag_style = cho_style_get(tag_begin, NULL, cho_tag_style_inherit(tags, ta-1)); - if (tag_style == NULL) { + if (!tag_style) { fprintf(stderr, "cho_style_get failed.\n"); return NULL; } @@ -2687,3 +2451,172 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config) return songs; } +#ifdef DEBUG + +static const char *cho_debug_the_state(enum State state) +{ + switch (state) { + case STATE_LYRICS: + return "STATE_LYRICS"; + case STATE_DIRECTIVE_NAME: + return "STATE_DIRECTIVE_NAME"; + case STATE_DIRECTIVE_VALUE: + return "STATE_DIRECTIVE_VALUE"; + case STATE_CHORD: + return "STATE_CHORD"; + case STATE_ANNOTATION: + return "STATE_ANNOTATION"; + case STATE_MARKUP_TAG_BEGIN: + return "STATE_MARKUP_TAG_BEGIN"; + case STATE_MARKUP_TAG_END: + return "STATE_MARKUP_TAG_END"; + case STATE_MARKUP_TAG: + return "STATE_MARKUP_TAG"; + case STATE_MARKUP_ATTR_NAME: + return "STATE_MARKUP_ATTR_NAME"; + case STATE_MARKUP_ATTR_VALUE: + return "STATE_MARKUP_ATTR_VALUE"; + case STATE_COMMENT: + return "STATE_COMMENT"; + } + return ""; +} + +static const char *cho_debug_the_dtype(enum DirectiveType dtype) +{ + switch (dtype) { + case DT_EMPTY: + return "DT_EMPTY"; + case DT_ENVIRONMENT: + return "DT_ENVIRONMENT"; + case DT_METADATA: + return "DT_METADATA"; + case DT_FORMATTING: + return "DT_FORMATTING"; + case DT_PREAMBLE: + return "DT_PREAMBLE"; + case DT_FONT: + return "DT_FONT"; + case DT_CUSTOM: + return "DT_CUSTOM"; + } + return ""; +} + +static const char *cho_debug_the_stype(enum SectionType stype) +{ + switch (stype) { + case ST_EMPTY: + return "ST_EMPTY"; + case ST_CHORUS: + return "ST_CHORUS"; + case ST_VERSE: + return "ST_VERSE"; + case ST_BRIDGE: + return "ST_BRIDGE"; + case ST_TAB: + return "ST_TAB"; + case ST_GRID: + return "ST_GRID"; + case ST_NEWSONG: + return "ST_NEWSONG"; + } + return ""; +} + +static const char *cho_debug_the_pos(enum Position pos) +{ + switch (pos) { + case POS_EMPTY: + return "POS_EMPTY"; + case POS_START: + return "POS_START"; + case POS_END: + return "POS_END"; + } + return ""; +} + +static const char *cho_debug_the_song_fragment_type(enum SongFragmentType ftype) +{ + switch (ftype) { + case SF_EMPTY: + return "SF_EMPTY"; + case SF_CHORD: + return "SF_CHORD"; + case SF_ANNOT: + return "SF_ANNOT"; + case SF_CHORUS: + return "SF_CHORUS"; + case SF_FOOTER: + return "SF_FOOTER"; + case SF_GRID: + return "SF_GRID"; + case SF_TAB: + return "SF_TAB"; + case SF_TOC: + return "SF_TOC"; + case SF_TEXT: + return "SF_TEXT"; + case SF_TITLE: + return "SF_TITLE"; + case SF_LABEL: + return "SF_LABEL"; + } + return ""; +} + +static void cho_debug_the_default_style_properties(void) +{ + unsigned int i; + for (i = 0; i<LENGTH(default_style_properties); i++) { + printf( + "%s %s ", + cho_debug_the_song_fragment_type(default_style_properties[i].ftype), + cho_style_property_type_to_string(default_style_properties[i].type) + ); + switch (default_style_properties[i].type) { + case SPT_FONT: + if (default_style_properties[i].u.font_name) + printf("%s\n", default_style_properties[i].u.font_name); + else + printf("NULL\n"); + break; + case SPT_SIZE: + printf("%.1f\n", default_style_properties[i].u.font_size); + break; + case SPT_COLOR: + if (default_style_properties[i].u.foreground_color) + printf("%s\n", cho_rgbcolor_to_string(default_style_properties[i].u.foreground_color)); + else + printf("NULL\n"); + break; + default: + printf("Invalid StylePropertyType value '%d'.\n", default_style_properties[i].type); + } + } +} + +void cho_debug_style_print(struct Style *style) +{ + printf("---- BEGIN STYLE ----\n"); + cho_font_print(style->font); + printf("foreground_color: %s\n", cho_rgbcolor_to_string(style->foreground_color)); + printf("background_color: %s\n", cho_rgbcolor_to_string(style->background_color)); + printf("underline_style: %s\n", cho_linestyle_to_string(style->underline_style)); + printf("underline_color: %s\n", cho_rgbcolor_to_string(style->underline_color)); + printf("overline_style: %s\n", cho_linestyle_to_string(style->overline_style)); + printf("overline_color: %s\n", cho_rgbcolor_to_string(style->overline_color)); + printf("strikethrough: %d\n", style->strikethrough); + printf("strikethrough_color: %s\n", cho_rgbcolor_to_string(style->strikethrough_color)); + printf("boxed: %d\n", style->boxed); + printf("boxed_color: %s\n", cho_rgbcolor_to_string(style->boxed_color)); + printf("rise: %f\n", style->rise); + if (style->href) + printf("href: %s\n", style->href); + else + printf("href: NULL\n"); + printf("---- END STYLE ------\n\n"); +} + +#endif /* DEBUG */ diff --git a/chordpro.h b/chordpro.h @@ -241,6 +241,7 @@ struct ChoSong { struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config); int cho_song_count(struct ChoSong **songs); void cho_songs_free(struct ChoSong **song); + int cho_line_item_count(struct ChoLineItem **items); int cho_text_above_count(struct ChoLineItemAbove **text_above); @@ -254,33 +255,23 @@ void cho_style_print_as_toml(struct Style *style, const char *section); struct RGBColor *cho_color_parse(const char *str); enum LineStyle cho_linestyle_parse(const char *str); + struct Font *cho_font_new(void); void cho_font_free(struct Font *font); +void cho_font_print(struct Font *font); struct Font *cho_font_duplicate(struct Font *font); void cho_fonts_free(struct Font **fonts); - char *cho_font_name_normalize(const char *name); - enum FontFamily cho_font_family_parse(const char *str); const char *cho_font_family_to_string(enum FontFamily font_family); - enum FontStyle cho_font_style_parse(const char *str); const char *cho_font_style_to_string(enum FontStyle style); - enum FontWeight cho_font_weight_parse(const char *str); const char *cho_font_weight_to_string(enum FontWeight weight); void cho_font_print_as_toml(struct Font *font, const char *section); -/* Debugging */ -void cho_font_print(struct Font *font); -void cho_style_print(struct Style *style); -const char *the_dtype(enum DirectiveType dtype); -const char *the_stype(enum SectionType stype); -const char *the_pos(enum Position pos); -const char *the_font_family(enum FontFamily font_family); -const char *the_font_style(enum FontStyle style); -const char *the_font_weight(enum FontWeight weight); -const char *the_rgb_color(struct RGBColor *color); -const char *the_line_style(enum LineStyle style); +#ifdef DEBUG +void cho_debug_style_print(struct Style *style); +#endif /* DEBUG */ #endif /* _CHORDPRO_H_ */ diff --git a/config.c b/config.c @@ -116,9 +116,6 @@ static struct Note **config_notes_new_default(enum NamingSystem system) struct Note **notes_default = malloc(8 * sizeof(struct Note *)); struct Note *notes; switch (system) { - case NS_COMMON: - notes = (struct Note *)&notes_common; - break; case NS_GERMAN: notes = (struct Note *)&notes_german; break; @@ -128,6 +125,9 @@ static struct Note **config_notes_new_default(enum NamingSystem system) case NS_LATIN: notes = (struct Note *)&notes_latin; break; + default: + notes = (struct Note *)&notes_common; + break; } int i; for (i = 0; i<7; i++) { diff --git a/lorid.c b/lorid.c @@ -11,6 +11,9 @@ int main(int argc, char *argv[]) { +#ifdef DEBUG + printf("Hello World\n"); +#endif static struct option long_options[] = { { "print-default-config", no_argument, 0, 'p' }, { "config", required_argument, 0, 'c' }, diff --git a/out_pdf.c b/out_pdf.c @@ -26,22 +26,6 @@ static pdfio_obj_t *out_pdf_fnt_obj_get_by_name(const char *name) return NULL; } -/* static void out_pdf_font_add(struct Font *font, struct Font ***array) -{ - int a = 0; - if (!*array) { - *array = realloc(*array, 2 * sizeof(struct Font *)); - (*array)[0] = font; - (*array)[1] = NULL; - } else { - while ((*array)[a] != NULL) - a++; - *array = realloc(*array, (a+2) * sizeof(struct Font *)); - (*array)[a] = font; - (*array)[a+1] = NULL; - } -} */ - static bool out_pdf_font_add_if_not_in(struct Font *font, struct Font ***array) { int a = 0; @@ -586,7 +570,8 @@ static enum Bool out_pdf_text_above_is_enough_space(struct ChoLine *line, struct return B_TRUE; } -static struct SpaceNeeded *needs_space(struct SpaceNeeded **spaces, int ly, int i) { +static struct SpaceNeeded *needs_space(struct SpaceNeeded **spaces, int ly, int i) +{ int sn; for (sn = 0; spaces[sn]; sn++) { if (spaces[sn]->line_item_index == ly && spaces[sn]->text_index == i) { diff --git a/todo b/todo @@ -5,8 +5,7 @@ apply all config in cho_songs_parse() instead of out_pdf_new() https://chordpro.org/chordpro/directives-image/ metadata directives %{blabla} in lyrics and chords - add style to every metadata - font, size, colour directives + conditional metadata directives chords implement markup transpose