commit 028be083bbd82237b40c65d237eeb0dc77e4f465
parent a4b139b6ed79b49ff242c3b4bdd30605446708f8
Author: nibo <nibo@relim.de>
Date: Wed, 7 Aug 2024 10:24:23 +0200
Finish implementing chord markup
Markup tags inside chords can't be nested
and there can only be one tag. Having multiple
tags will result in the last tags' style being
applied.
Diffstat:
10 files changed, 72 insertions(+), 61 deletions(-)
diff --git a/chordpro.c b/chordpro.c
@@ -141,6 +141,35 @@ 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 *cho_state_to_string(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 inline bool is_whitespace(char c)
{
if (
@@ -1254,6 +1283,16 @@ static struct ChoChord *cho_chord_new(void)
return chord;
}
+static void cho_chord_free(struct ChoChord *chord)
+{
+ cho_style_free(chord->style);
+ free(chord->name);
+ free(chord->root);
+ free(chord->ext);
+ free(chord->bass);
+ free(chord);
+}
+
/* 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)
{
@@ -1790,6 +1829,7 @@ END:
struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
{
g_config = config;
+ bool is_chord_already_initialized = false;
char buf = 0;
char prev_buf = '\n';
char directive_name[16];
@@ -1799,7 +1839,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
char tag_end[6];
char annotation[512];
enum State state = STATE_LYRICS;
- enum State prev_state;
+ enum State prev_state = STATE_LYRICS;
unsigned int line_number = 1;
int dn = 0;
int dv = 0;
@@ -1833,10 +1873,11 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
struct Tag **tags = NULL;
struct Style *tag_style;
struct StyleProperty sprop;
+ struct ChoChord *tmp_chord;
while (feof(fp) == 0) {
read = fread(&buf, 1, 1, fp);
if (read == 1) {
- // printf("state: %s, prev_buf: %c, buf: %c\n", the_state(state), prev_buf, buf);
+ // printf("state: %s, prev_state: %s, prev_buf: %c, buf: %c\n", cho_state_to_string(state), cho_state_to_string(prev_state), prev_buf, buf);
switch (state) {
case STATE_LYRICS:
if (prev_buf == '\n' && buf == '#') {
@@ -2187,25 +2228,22 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
ch = 0;
g_prev_ftype = g_current_ftype;
g_current_ftype = SF_CHORD;
- if (
- prev_state == STATE_MARKUP_TAG_BEGIN ||
- prev_state == STATE_MARKUP_ATTR_NAME ||
- prev_state == STATE_MARKUP_ATTR_VALUE
- ) {
+ if (is_chord_already_initialized) {
chord_pos = cho_line_compute_chord_position(songs[so]->sections[se]->lines[li], ly, te);
songs[so]->sections[se]->lines[li]->text_above[c]->position = chord_pos;
- struct ChoChord *intermediate = cho_chord_parse(chord);
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.name = strdup(intermediate->name);
- if (songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.root) {
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.root = strdup(intermediate->root);
+ tmp_chord = cho_chord_parse(chord);
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->name = strdup(tmp_chord->name);
+ if (songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->root) {
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->root = strdup(tmp_chord->root);
}
- if (songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.ext) {
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.ext = strdup(intermediate->ext);
+ if (songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->ext) {
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->ext = strdup(tmp_chord->ext);
}
- if (songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.bass) {
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord.bass = strdup(intermediate->bass);
+ if (songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->bass) {
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->bass = strdup(tmp_chord->bass);
}
- cho_chord_free(intermediate);
+ cho_chord_free(tmp_chord);
+ is_chord_already_initialized = false;
} else {
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] = malloc(sizeof(struct ChoLineItemAbove));
@@ -2224,10 +2262,14 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
state = STATE_ANNOTATION;
break;
}
- if (prev_buf == '[' && buf == '<') {
- 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] = malloc(sizeof(struct ChoLineItemAbove));
- songs[so]->sections[se]->lines[li]->text_above[c]->is_chord = true;
+ if (buf == '<') {
+ if (prev_buf == '[') {
+ 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] = malloc(sizeof(struct ChoLineItemAbove));
+ songs[so]->sections[se]->lines[li]->text_above[c]->is_chord = true;
+ songs[so]->sections[se]->lines[li]->text_above[c]->u.chord = cho_chord_new();
+ is_chord_already_initialized = true;
+ }
prev_state = STATE_CHORD;
state = STATE_MARKUP_TAG;
break;
@@ -2275,16 +2317,16 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
songs[so]->sections[se]->lines[li]->lyrics[ly]->style = cho_style_duplicate(tag_style);
break;
case STATE_CHORD:
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord = malloc(sizeof(struct ChoChord));
+ cho_style_free(songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style);
songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style = cho_style_duplicate(tag_style);
break;
case STATE_ANNOTATION:
break;
+ default:
+ fprintf(stderr, "INFO: Invalid prev_state '%s'.\n", cho_state_to_string(prev_state));
}
memset(tag_begin, 0, strlen(tag_begin));
state = prev_state;
- prev_state = STATE_MARKUP_TAG_BEGIN;
- // state = STATE_LYRICS;
break;
}
if (is_whitespace(buf)) {
@@ -2376,16 +2418,17 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
songs[so]->sections[se]->lines[li]->lyrics[ly]->style = cho_style_duplicate(tag_style);
break;
case STATE_CHORD:
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord = malloc(sizeof(struct ChoChord));
+ cho_style_free(songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style);
songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style = cho_style_duplicate(tag_style);
break;
case STATE_ANNOTATION:
break;
+ default:
+ fprintf(stderr, "INFO: Invalid prev_state '%s'.\n", cho_state_to_string(prev_state));
}
at = 0;
memset(tag_begin, 0, strlen(tag_begin));
state = prev_state;
- prev_state = STATE_MARKUP_ATTR_NAME;
break;
} else {
tags[ta]->attrs[at]->name = realloc(tags[ta]->attrs[at]->name, (atn+1) * sizeof(char));
@@ -2444,17 +2487,18 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
songs[so]->sections[se]->lines[li]->lyrics[ly]->style = cho_style_duplicate(tag_style);
break;
case STATE_CHORD:
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord = malloc(sizeof(struct ChoChord));
+ cho_style_free(songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style);
songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style = cho_style_duplicate(tag_style);
break;
case STATE_ANNOTATION:
break;
+ default:
+ fprintf(stderr, "INFO: Invalid prev_state '%s'.\n", cho_state_to_string(prev_state));
}
at = 0;
avs = AVS_NO;
memset(tag_begin, 0, strlen(tag_begin));
state = prev_state;
- prev_state = STATE_MARKUP_ATTR_VALUE;
break;
}
if (
@@ -2516,35 +2560,6 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
#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) {
diff --git a/chordpro.h b/chordpro.h
@@ -213,7 +213,7 @@ struct ChoLineItemAbove {
bool is_chord;
union {
struct ChoChord *chord;
- struct ChoAnnotation **annot;
+ struct ChoAnnotation *annot;
} u;
};
diff --git a/fonts/Inter-Bold.ttf b/fonts/Inter-Bold.ttf
Binary files differ.
diff --git a/fonts/Inter-BoldItalic.ttf b/fonts/Inter-BoldItalic.ttf
Binary files differ.
diff --git a/fonts/Inter-Italic.ttf b/fonts/Inter-Italic.ttf
Binary files differ.
diff --git a/fonts/Inter-Light.ttf b/fonts/Inter-Light.ttf
Binary files differ.
diff --git a/fonts/Inter-LightItalic.ttf b/fonts/Inter-LightItalic.ttf
Binary files differ.
diff --git a/fonts/Inter-Regular.ttf b/fonts/Inter-Regular.ttf
Binary files differ.
diff --git a/lorid.c b/lorid.c
@@ -11,9 +11,6 @@
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/todo b/todo
@@ -7,7 +7,6 @@ metadata directives
%{blabla} in lyrics and chords
conditional metadata directives
chords
- implement markup
transpose
define chords
chord diagrams