lorid

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

commit 52067be37cffb0b14ca8553f0eafad81ebad1676
parent b0e41e3f6bfe7a4033153c633a7e7f719978c806
Author: nibo <nibo@relim.de>
Date:   Mon, 27 May 2024 19:51:58 +0200

 Not nothing and not something specific

Diffstat:
MMakefile | 2++
Mchordpro.c | 161+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mchordpro.h | 5++---
Mlorid.c | 80+++++++++++++++++++++++++++++++++++++------------------------------------------
Atodo | 6++++++
5 files changed, 135 insertions(+), 119 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,2 +1,4 @@ all: $(CC) -Wall -Wextra -O2 chordpro.c lorid.c -o lorid +debug: + $(CC) -g -Wall -Wextra chordpro.c lorid.c -o lorid diff --git a/chordpro.c b/chordpro.c @@ -4,7 +4,7 @@ #include <string.h> #include "chordpro.h" -char *string_remove_leading_whitespace(const char *str) +static char *string_remove_leading_whitespace(const char *str) { int i = 0; while (str[i] == ' ' || str[i] == '\t') { @@ -238,6 +238,16 @@ void cho_song_free(struct ChoSong *song) free(song); } +void cho_songs_free(struct ChoSong **songs) +{ + int so = 0; + while (songs[so] != NULL) { + cho_song_free(songs[so]); + so++; + } + free(songs); +} + struct ChoDirective *directive_parse(const char *name) { struct ChoDirective *directive = malloc(sizeof(struct ChoDirective)); @@ -379,15 +389,17 @@ END: return directive; } -struct ChoSong *cho_parse(FILE *fp) +struct ChoSong **cho_parse(FILE *fp) { - struct ChoSong *song = cho_song_new(); - int s = 0; - song->sections = malloc((s+1) * sizeof(struct ChoSection *)); - song->sections[s] = cho_section_new(); + struct ChoSong **songs = malloc(sizeof(struct ChoSong *)); + int so = 0; + songs[so] = cho_song_new(); + int se = 0; + songs[so]->sections = malloc((se+1) * sizeof(struct ChoSection *)); + songs[so]->sections[se] = cho_section_new(); int li = 0; - song->sections[s]->lines = realloc(song->sections[s]->lines, (li+1) * sizeof(struct ChoLine *)); - song->sections[s]->lines[li] = cho_line_new(); + songs[so]->sections[se]->lines = realloc(songs[so]->sections[se]->lines, (li+1) * sizeof(struct ChoLine *)); + songs[so]->sections[se]->lines[li] = cho_line_new(); int dn = 0; int dv = 0; int ch = 0; @@ -417,19 +429,19 @@ struct ChoSong *cho_parse(FILE *fp) break; } if (buf == '\n') { - song->sections[s]->lines[li]->lyrics = realloc(song->sections[s]->lines[li]->lyrics, (ly+1) * sizeof(char)); - song->sections[s]->lines[li]->lyrics[ly] = 0; + songs[so]->sections[se]->lines[li]->lyrics = realloc(songs[so]->sections[se]->lines[li]->lyrics, (ly+1) * sizeof(char)); + songs[so]->sections[se]->lines[li]->lyrics[ly] = 0; ly = 0; - song->sections[s]->lines[li]->chords = realloc(song->sections[s]->lines[li]->chords, (c+1) * sizeof(struct ChoChord *)); - song->sections[s]->lines[li]->chords[c] = NULL; + songs[so]->sections[se]->lines[li]->chords = realloc(songs[so]->sections[se]->lines[li]->chords, (c+1) * sizeof(struct ChoChord *)); + songs[so]->sections[se]->lines[li]->chords[c] = NULL; c = 0; li++; - song->sections[s]->lines = realloc(song->sections[s]->lines, (li+1) * sizeof(struct ChoLine *)); - song->sections[s]->lines[li] = cho_line_new(); + songs[so]->sections[se]->lines = realloc(songs[so]->sections[se]->lines, (li+1) * sizeof(struct ChoLine *)); + songs[so]->sections[se]->lines[li] = cho_line_new(); break; } - song->sections[s]->lines[li]->lyrics = realloc(song->sections[s]->lines[li]->lyrics, (ly+1) * sizeof(char)); - song->sections[s]->lines[li]->lyrics[ly] = buf; + songs[so]->sections[se]->lines[li]->lyrics = realloc(songs[so]->sections[se]->lines[li]->lyrics, (ly+1) * sizeof(char)); + songs[so]->sections[se]->lines[li]->lyrics[ly] = buf; ly++; break; case STATE_DIRECTIVE_NAME: @@ -445,35 +457,35 @@ struct ChoSong *cho_parse(FILE *fp) case DT_ENVIRONMENT: switch (directive->position) { case POS_BEGIN: - free(song->sections[s]->lines[li]); - song->sections[s]->lines[li] = NULL; - s++; - song->sections = realloc(song->sections, (s+1) * sizeof(struct ChoSection *)); - song->sections[s] = cho_section_new(); - song->sections[s]->type = directive->stype; + free(songs[so]->sections[se]->lines[li]); + songs[so]->sections[se]->lines[li] = NULL; + se++; + songs[so]->sections = realloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *)); + songs[so]->sections[se] = cho_section_new(); + songs[so]->sections[se]->type = directive->stype; li = 0; - song->sections[s]->lines = malloc(sizeof(struct ChoLine *)); - song->sections[s]->lines[li] = cho_line_new(); + songs[so]->sections[se]->lines = malloc(sizeof(struct ChoLine *)); + songs[so]->sections[se]->lines[li] = cho_line_new(); break; case POS_END: - if (directive->stype == song->sections[s]->type) { - free(song->sections[s]->lines[li]); - song->sections[s]->lines[li] = NULL; - s++; - song->sections = realloc(song->sections, (s+1) * sizeof(struct ChoSection *)); - song->sections[s] = cho_section_new(); + if (directive->stype == songs[so]->sections[se]->type) { + free(songs[so]->sections[se]->lines[li]); + songs[so]->sections[se]->lines[li] = NULL; + se++; + songs[so]->sections = realloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *)); + songs[so]->sections[se] = cho_section_new(); li = 0; - song->sections[s]->lines = malloc(sizeof(struct ChoLine *)); - song->sections[s]->lines[li] = cho_line_new(); + songs[so]->sections[se]->lines = malloc(sizeof(struct ChoLine *)); + songs[so]->sections[se]->lines[li] = cho_line_new(); } break; } break; case DT_METADATA: fprintf(stderr, "INFO: Metadata directive '%s' has no value.\n", directive_name); - song->metadata = realloc(song->metadata, (m+1) * sizeof(struct ChoMetadata *)); - song->metadata[m] = cho_metadata_new(); - song->metadata[m]->name = strdup(directive_name); + songs[so]->metadata = realloc(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)); break; @@ -512,27 +524,27 @@ struct ChoSong *cho_parse(FILE *fp) case DT_ENVIRONMENT: switch (directive->position) { case POS_BEGIN: - free(song->sections[s]->lines[li]); - song->sections[s]->lines[li] = NULL; - s++; - song->sections = realloc(song->sections, (s+1) * sizeof(struct ChoSection *)); - song->sections[s] = cho_section_new(); - song->sections[s]->type = directive->stype; - song->sections[s]->name = string_remove_leading_whitespace(directive_value); + free(songs[so]->sections[se]->lines[li]); + songs[so]->sections[se]->lines[li] = NULL; + se++; + songs[so]->sections = realloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *)); + songs[so]->sections[se] = cho_section_new(); + songs[so]->sections[se]->type = directive->stype; + songs[so]->sections[se]->name = string_remove_leading_whitespace(directive_value); li = 0; - song->sections[s]->lines = malloc(sizeof(struct ChoLine *)); - song->sections[s]->lines[li] = cho_line_new(); + songs[so]->sections[se]->lines = malloc(sizeof(struct ChoLine *)); + songs[so]->sections[se]->lines[li] = cho_line_new(); break; case POS_END: - if (directive->stype == song->sections[s]->type) { - free(song->sections[s]->lines[li]); - song->sections[s]->lines[li] = NULL; - s++; - song->sections = realloc(song->sections, (s+1) * sizeof(struct ChoSection *)); - song->sections[s] = cho_section_new(); + if (directive->stype == songs[so]->sections[se]->type) { + free(songs[so]->sections[se]->lines[li]); + songs[so]->sections[se]->lines[li] = NULL; + se++; + songs[so]->sections = realloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *)); + songs[so]->sections[se] = cho_section_new(); li = 0; - song->sections[s]->lines = malloc(sizeof(struct ChoLine *)); - song->sections[s]->lines[li] = cho_line_new(); + songs[so]->sections[se]->lines = malloc(sizeof(struct ChoLine *)); + songs[so]->sections[se]->lines[li] = cho_line_new(); } break; } @@ -541,22 +553,22 @@ struct ChoSong *cho_parse(FILE *fp) if (strcmp(directive_name, "meta") == 0) { metadata = cho_metadata_split(directive_value); if (metadata != NULL) { - song->metadata = realloc(song->metadata, (m+1) * sizeof(struct ChoMetadata *)); - song->metadata[m] = metadata; + songs[so]->metadata = realloc(songs[so]->metadata, (m+1) * sizeof(struct ChoMetadata *)); + songs[so]->metadata[m] = metadata; m++; } } else { - song->metadata = realloc(song->metadata, (m+1) * sizeof(struct ChoMetadata *)); - song->metadata[m] = cho_metadata_new(); - song->metadata[m]->name = strdup(directive_name); - song->metadata[m]->value = string_remove_leading_whitespace(directive_value); + songs[so]->metadata = realloc(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 = string_remove_leading_whitespace(directive_value); m++; } break; case DT_FORMATTING: - song->sections[s]->lines[li]->style = directive->style; - song->sections[s]->lines[li]->lyrics = string_remove_leading_whitespace(directive_value); - ly = strlen(song->sections[s]->lines[li]->lyrics); + songs[so]->sections[se]->lines[li]->style = directive->style; + songs[so]->sections[se]->lines[li]->lyrics = string_remove_leading_whitespace(directive_value); + ly = strlen(songs[so]->sections[se]->lines[li]->lyrics); break; case DT_PREAMBLE: break; @@ -576,10 +588,10 @@ struct ChoSong *cho_parse(FILE *fp) if (buf == ']') { chord[ch] = 0; ch = 0; - song->sections[s]->lines[li]->chords = realloc(song->sections[s]->lines[li]->chords, (c+1) * sizeof(struct ChoChord *)); - song->sections[s]->lines[li]->chords[c] = cho_chord_new(); - song->sections[s]->lines[li]->chords[c]->index_in_lyrics = ly; - song->sections[s]->lines[li]->chords[c]->chord = strdup(chord); + songs[so]->sections[se]->lines[li]->chords = realloc(songs[so]->sections[se]->lines[li]->chords, (c+1) * sizeof(struct ChoChord *)); + songs[so]->sections[se]->lines[li]->chords[c] = cho_chord_new(); + songs[so]->sections[se]->lines[li]->chords[c]->index_in_lyrics = ly; + songs[so]->sections[se]->lines[li]->chords[c]->chord = strdup(chord); memset(chord, 0, strlen(chord)); c++; state = STATE_LYRICS; @@ -594,13 +606,16 @@ struct ChoSong *cho_parse(FILE *fp) return NULL; } } - free(song->sections[s]->lines[li]); - song->sections[s]->lines[li] = NULL; - song->metadata = realloc(song->metadata, (m+1) * sizeof(struct ChoMetadata *)); - song->metadata[m] = NULL; - s++; - song->sections = realloc(song->sections, (s+1) * sizeof(struct ChoSection *)); - song->sections[s] = NULL; - return song; + free(songs[so]->sections[se]->lines[li]); + songs[so]->sections[se]->lines[li] = NULL; + songs[so]->metadata = realloc(songs[so]->metadata, (m+1) * sizeof(struct ChoMetadata *)); + songs[so]->metadata[m] = NULL; + se++; + songs[so]->sections = realloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *)); + songs[so]->sections[se] = NULL; + so++; + songs = realloc(songs, (so+1) * sizeof(struct ChoSong *)); + songs[so] = NULL; + return songs; } diff --git a/chordpro.h b/chordpro.h @@ -70,8 +70,7 @@ struct ChoSong { struct ChoSection **sections; }; -struct ChoSong *cho_parse(FILE *fp); -void cho_song_free(struct ChoSong *song); -char *string_remove_leading_whitespace(const char *str); +struct ChoSong **cho_parse(FILE *fp); +void cho_songs_free(struct ChoSong **song); const char *the_stype(enum SectionType stype); const char *the_style(enum LineStyle style); diff --git a/lorid.c b/lorid.c @@ -25,9 +25,9 @@ int main(int argc, char *argv[]) fprintf(stderr, "fopen failed.\n"); return 1; } - struct ChoSong *song = cho_parse(fp); - if (song == NULL) { - fprintf(stderr, "chordpro_parse failed.\n"); + struct ChoSong **songs = cho_parse(fp); + if (songs == NULL) { + fprintf(stderr, "cho_parse failed.\n"); return 1; } /*int m = 0;*/ @@ -44,46 +44,40 @@ int main(int argc, char *argv[]) /* m++;*/ /*}*/ /*printf("---- END METADATA ------\n");*/ - char *lyrics; - struct ChoChord **chords; - enum SectionType stype; - enum LineStyle style; - int s = 0; - int li = 0; - int c = 0; - while (song->sections[s] != NULL) { - printf("---- BEGIN SECTION ----\n"); - stype = song->sections[s]->type; - printf("stype: %s\n", the_stype(stype)); - if (song->sections[s]->name) { - printf("name: %s\n", song->sections[s]->name); - } - while (song->sections[s]->lines[li] != NULL) { - /*chords = song->sections[s]->lines[li]->chords;*/ - /*while (chords[c] != NULL) {*/ - /* printf("index: %d, chord: %s | ", chords[c]->index_in_lyrics, chords[c]->chord);*/ - /* c++;*/ - /*}*/ - /*printf("\n");*/ - /*c = 0;*/ - /*lyrics = song->sections[s]->lines[li]->lyrics;*/ - /*if (strlen(lyrics) > 0) {*/ - /* printf("lyrics: %s\n", lyrics);*/ - /* style = song->sections[s]->lines[li]->style;*/ - /* printf("style: %s\n", the_style(style));*/ - /*}*/ - style = song->sections[s]->lines[li]->style; - lyrics = song->sections[s]->lines[li]->lyrics; - if (strlen(lyrics) > 0) { - printf("style %s, line %s\n", the_style(style), lyrics); - } - li++; - } - li = 0; - s++; - printf("---- END SECTION ------\n"); - } - cho_song_free(song); + /*char *lyrics;*/ + /*struct ChoChord **chords;*/ + /*enum SectionType stype;*/ + /*enum LineStyle style;*/ + /*int s = 0;*/ + /*int li = 0;*/ + /*int c = 0;*/ + /*while (song->sections[s] != NULL) {*/ + /* printf("---- BEGIN SECTION ----\n");*/ + /* stype = song->sections[s]->type;*/ + /* printf("stype: %s\n", the_stype(stype));*/ + /* if (song->sections[s]->name) {*/ + /* printf("name: %s\n", song->sections[s]->name);*/ + /* }*/ + /* while (song->sections[s]->lines[li] != NULL) {*/ + /* chords = song->sections[s]->lines[li]->chords;*/ + /* while (chords[c] != NULL) {*/ + /* printf("index: %d, chord: %s | ", chords[c]->index_in_lyrics, chords[c]->chord);*/ + /* c++;*/ + /* }*/ + /* printf("\n");*/ + /* c = 0;*/ + /* style = song->sections[s]->lines[li]->style;*/ + /* lyrics = song->sections[s]->lines[li]->lyrics;*/ + /* if (strlen(lyrics) > 0) {*/ + /* printf("style %s, line %s\n", the_style(style), lyrics);*/ + /* }*/ + /* li++;*/ + /* }*/ + /* li = 0;*/ + /* s++;*/ + /* printf("---- END SECTION ------\n");*/ + /*}*/ + cho_songs_free(songs); fclose(fp); return 0; } diff --git a/todo b/todo @@ -0,0 +1,6 @@ +'chorus' directive + decide how to implement +'image' directive + decide if implement +chordpro markup + https://chordpro.org/chordpro/chordpro_markup/