commit b589ffd2a01350f88c5676b737b0da0280978838
parent 9d9c20021fc5f2537a7057cc906a04f6155781e4
Author: nibo <nibo@relim.de>
Date: Tue, 11 Jun 2024 21:28:56 +0200
Work
Diffstat:
| M | chordpro.c | | | 113 | ++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------- |
| M | chordpro.h | | | 42 | +++++++++--------------------------------- |
| M | lorid.c | | | 73 | ++++++++++++++++++++++++++++++++++++++++--------------------------------- |
3 files changed, 120 insertions(+), 108 deletions(-)
diff --git a/chordpro.c b/chordpro.c
@@ -46,8 +46,6 @@ static const char *the_state(enum State state)
return "STATE_MARKUP_TAG_BEGIN";
case STATE_MARKUP_TAG_END:
return "STATE_MARKUP_TAG_END";
- case STATE_MARKUP_TAG_INSIDE:
- return "STATE_MARKUP_TAG_INSIDE";
case STATE_MARKUP_TAG:
return "STATE_MARKUP_TAG";
case STATE_MARKUP_ATTR_NAME:
@@ -78,8 +76,6 @@ const char *the_dtype(enum DirectiveType dtype)
const char *the_stype(enum SectionType stype)
{
switch (stype) {
- case ST_NOTHING:
- return "ST_NOTHING";
case ST_CHORUS:
return "ST_CHORUS";
case ST_VERSE:
@@ -99,10 +95,8 @@ const char *the_stype(enum SectionType stype)
const char *the_pos(enum Position pos)
{
switch (pos) {
- case POS_NOTHING:
- return "POS_NOTHING";
- case POS_BEGIN:
- return "POS_BEGIN";
+ case POS_START:
+ return "POS_START";
case POS_END:
return "POS_END";
}
@@ -386,13 +380,13 @@ struct Style *cho_style_duplicate(struct Style *style)
return copy;
}
-struct Style *cho_style_get(const char *tag_name, struct Attr **attrs, struct Style *prev_style)
+struct Style *cho_style_get(const char *tag_name, struct Attr **attrs, struct Style *inherited_style)
{
size_t value_len, last_char;
struct RGBColor *rgb_color;
struct Style *style;
- if (prev_style)
- style = cho_style_duplicate(prev_style);
+ if (inherited_style)
+ style = cho_style_duplicate(inherited_style);
else
style = cho_style_new();
if (strcmp(tag_name, "span") == 0) {
@@ -708,7 +702,7 @@ void cho_tag_close_last_unclosed(const char *tag_name, struct Tag **tags, int la
{
int i = last_index;
while (i >= 0) {
- if (strcmp(tags[i]->name, tag_name) == 0) {
+ if (strcmp(tags[i]->name, tag_name) == 0 && !tags[i]->is_closed) {
tags[i]->is_closed = true;
return;
}
@@ -717,6 +711,24 @@ void cho_tag_close_last_unclosed(const char *tag_name, struct Tag **tags, int la
fprintf(stderr, "INFO: Didn't find a start tag for the end tag '%s'.\n", tag_name);
}
+struct Style *cho_tag_style_inherit(struct Tag **tags, int prev_index)
+{
+ int i = prev_index;
+ while (i >= 0) {
+ if (!tags[i]->is_closed) {
+ return tags[i]->style;
+ }
+ i--;
+ }
+ /*
+ Doesn't mean there is an error.
+ If no style can be inherited the
+ default style should be used.
+ */
+ printf("cho_tag_style_inherit: Return NULL\n");
+ return NULL;
+}
+
void cho_directive_free(struct ChoDirective *directive)
{
cho_style_free(directive->style);
@@ -805,7 +817,7 @@ void cho_line_item_free(struct ChoLineItem *item)
struct ChoSection *cho_section_new(void)
{
struct ChoSection *section = malloc(sizeof(struct ChoSection));
- section->type = ST_NOTHING;
+ section->type = -1;
section->name = NULL;
section->lines = NULL;
return section;
@@ -883,7 +895,7 @@ struct ChoDirective *directive_parse(const char *name)
strcmp(name, environment_directives[1]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
- directive->position = POS_BEGIN;
+ directive->position = POS_START;
directive->stype = ST_CHORUS;
goto END;
} else if (
@@ -899,7 +911,7 @@ struct ChoDirective *directive_parse(const char *name)
strcmp(name, environment_directives[6]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
- directive->position = POS_BEGIN;
+ directive->position = POS_START;
directive->stype = ST_VERSE;
goto END;
} else if (
@@ -915,7 +927,7 @@ struct ChoDirective *directive_parse(const char *name)
strcmp(name, environment_directives[10]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
- directive->position = POS_BEGIN;
+ directive->position = POS_START;
directive->stype = ST_BRIDGE;
goto END;
} else if (
@@ -931,7 +943,7 @@ struct ChoDirective *directive_parse(const char *name)
strcmp(name, environment_directives[14]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
- directive->position = POS_BEGIN;
+ directive->position = POS_START;
directive->stype = ST_TAB;
goto END;
} else if (
@@ -947,7 +959,7 @@ struct ChoDirective *directive_parse(const char *name)
strcmp(name, environment_directives[18]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
- directive->position = POS_BEGIN;
+ directive->position = POS_START;
directive->stype = ST_GRID;
goto END;
} else if (
@@ -962,8 +974,8 @@ struct ChoDirective *directive_parse(const char *name)
while (metadata_directives[i] != NULL) {
if (strcmp(metadata_directives[i], name) == 0) {
directive->dtype = DT_METADATA;
- directive->stype = ST_NOTHING;
- directive->position = POS_NOTHING;
+ directive->stype = -1;
+ directive->position = -1;
goto END;
}
i++;
@@ -976,8 +988,8 @@ struct ChoDirective *directive_parse(const char *name)
) {
directive->style->background_color = cho_rgbcolor_new(228, 228, 228);
directive->dtype = DT_FORMATTING;
- directive->stype = ST_NOTHING;
- directive->position = POS_NOTHING;
+ directive->stype = -1;
+ directive->position = -1;
goto END;
} else if (
strcmp(formatting_directives[3], name) == 0 ||
@@ -985,8 +997,8 @@ struct ChoDirective *directive_parse(const char *name)
) {
directive->style->font_style = FS_ITALIC;
directive->dtype = DT_FORMATTING;
- directive->stype = ST_NOTHING;
- directive->position = POS_NOTHING;
+ directive->stype = -1;
+ directive->position = -1;
goto END;
} else if (
strcmp(formatting_directives[5], name) == 0 ||
@@ -994,22 +1006,22 @@ struct ChoDirective *directive_parse(const char *name)
) {
directive->style->boxed = true;
directive->dtype = DT_FORMATTING;
- directive->stype = ST_NOTHING;
- directive->position = POS_NOTHING;
+ directive->stype = -1;
+ directive->position = -1;
goto END;
}
while (preamble_directives[i] != NULL) {
if (strcmp(preamble_directives[i], name) == 0) {
directive->dtype = DT_PREAMBLE;
directive->stype = ST_NEWSONG;
- directive->position = POS_NOTHING;
+ directive->position = -1;
goto END;
}
i++;
}
directive->dtype = DT_CUSTOM;
- directive->stype = ST_NOTHING;
- directive->position = POS_NOTHING;
+ directive->stype = -1;
+ directive->position = -1;
END:
return directive;
}
@@ -1032,8 +1044,6 @@ struct ChoSong **cho_parse(FILE *fp)
int m = 0;
int ly = 0;
int t = 0;
- int an = 0;
- int av = 0;
int so = 0;
int se = 0;
int li = 0;
@@ -1055,7 +1065,6 @@ struct ChoSong **cho_parse(FILE *fp)
songs[so]->sections[se]->lines[li]->lyrics = malloc(sizeof(struct ChoLineItem *));
songs[so]->sections[se]->lines[li]->lyrics[ly] = cho_line_item_new();
struct Tag **tags = NULL;
- struct Style *prev_style;
struct Style *tag_style;
while (feof(fp) == 0) {
read = fread(&buf, 1, 1, fp);
@@ -1074,6 +1083,7 @@ struct ChoSong **cho_parse(FILE *fp)
if (buf == '<') {
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;
+ 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] = cho_line_item_new();
@@ -1084,11 +1094,26 @@ struct ChoSong **cho_parse(FILE *fp)
if (buf == '\n') {
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;
- te = 0;
- ly++;
+ if (strlen(songs[so]->sections[se]->lines[li]->lyrics[ly]->text) == 0) {
+ cho_line_item_free(songs[so]->sections[se]->lines[li]->lyrics[ly]);
+ if (ly == 0) {
+ if (!songs[so]->sections[se]->lines[li]->chords) {
+ free(songs[so]->sections[se]->lines[li]->lyrics);
+ 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] = cho_line_new();
+ 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();
+ break;
+ }
+ }
+ } 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] = NULL;
ly = 0;
+ te = 0;
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;
@@ -1115,7 +1140,7 @@ struct ChoSong **cho_parse(FILE *fp)
switch (directive->dtype) {
case DT_ENVIRONMENT:
switch (directive->position) {
- case POS_BEGIN:
+ case POS_START:
cho_line_item_free(songs[so]->sections[se]->lines[li]->lyrics[ly]);
free(songs[so]->sections[se]->lines[li]->lyrics);
ly = 0;
@@ -1210,7 +1235,7 @@ struct ChoSong **cho_parse(FILE *fp)
switch (directive->dtype) {
case DT_ENVIRONMENT:
switch (directive->position) {
- case POS_BEGIN:
+ case POS_START:
cho_line_item_free(songs[so]->sections[se]->lines[li]->lyrics[ly]);
free(songs[so]->sections[se]->lines[li]->lyrics);
ly = 0;
@@ -1263,13 +1288,17 @@ struct ChoSong **cho_parse(FILE *fp)
}
break;
case DT_FORMATTING:
+ 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] = cho_line_item_new();
cho_style_free(songs[so]->sections[se]->lines[li]->lyrics[ly]->style);
songs[so]->sections[se]->lines[li]->lyrics[ly]->style = cho_style_duplicate(directive->style);
- songs[so]->sections[se]->lines[li]->lyrics[ly]->text = string_remove_leading_whitespace(directive_value);
- te = 0;
+ char *trimmed_directive_value = string_remove_leading_whitespace(directive_value);
+ songs[so]->sections[se]->lines[li]->lyrics[ly]->text = trimmed_directive_value;
+ te += strlen(trimmed_directive_value);
+ // te = 0;
break;
case DT_PREAMBLE:
fprintf(stderr, "INFO: Preamble directive '%s' can't have a value.\n", directive_name);
@@ -1308,7 +1337,7 @@ struct ChoSong **cho_parse(FILE *fp)
tag_begin[t] = 0;
t = 0;
tags[ta]->name = strdup(tag_begin);
- tag_style = cho_style_get(tag_begin, NULL, ta == 0 ? NULL : tags[ta-1]->style);
+ tag_style = cho_style_get(tag_begin, NULL, cho_tag_style_inherit(tags, ta-1));
if (tag_style == NULL) {
fprintf(stderr, "cho_style_get failed.\n");
return NULL;
@@ -1345,7 +1374,7 @@ struct ChoSong **cho_parse(FILE *fp)
tags = realloc(tags, (ta+1) * sizeof(struct Tag *));
tags[ta] = cho_tag_new();
state = STATE_MARKUP_TAG_BEGIN;
- // If we not use 'goto' we loose the first character of the begin tag name
+ // If we don't use 'goto' we loose the first character of the begin tag name
goto MARKUP_TAG_BEGIN;
case STATE_MARKUP_TAG_END:
if (buf == '>') {
@@ -1397,7 +1426,7 @@ struct ChoSong **cho_parse(FILE *fp)
if (tags[ta]->attrs[at-1]->value) {
cho_tag_attr_free(tags[ta]->attrs[at]);
tags[ta]->attrs[at] = NULL;
- tag_style = cho_style_get(tag_begin, tags[ta]->attrs, ta == 0 ? NULL : tags[ta-1]->style);
+ tag_style = cho_style_get(tag_begin, tags[ta]->attrs, cho_tag_style_inherit(tags, ta-1));
if (tag_style == NULL) {
fprintf(stderr, "cho_style_get failed.\n");
return NULL;
@@ -1454,7 +1483,7 @@ struct ChoSong **cho_parse(FILE *fp)
at++;
tags[ta]->attrs = realloc(tags[ta]->attrs, (at+1) * sizeof(struct Attr *));
tags[ta]->attrs[at] = NULL;
- tag_style = cho_style_get(tag_begin, tags[ta]->attrs, ta == 0 ? NULL : tags[ta-1]->style);
+ tag_style = cho_style_get(tag_begin, tags[ta]->attrs, cho_tag_style_inherit(tags, ta-1));
if (tag_style == NULL) {
fprintf(stderr, "cho_style_get failed.\n");
return NULL;
diff --git a/chordpro.h b/chordpro.h
@@ -55,26 +55,6 @@ struct Style {
char *href;
};
-/* struct StyleHelper {
- bool exist_font;
- bool exist_font_family;
- bool exist_font_size;
- bool exist_font_style;
- bool exist_font_weight;
- bool exist_foreground_color;
- bool exist_background_color;
- bool exist_underline_style;
- bool exist_underline_color;
- bool exist_overline_style;
- bool exist_overline_color;
- bool exist_strikethrough;
- bool exist_strikethrough_color;
- bool exist_boxed;
- bool exist_boxed_color;
- bool exist_rise;
- bool exist_href;
-}; */
-
struct Attr {
char *name;
char *value;
@@ -101,7 +81,6 @@ enum State {
STATE_CHORD,
STATE_MARKUP_TAG_BEGIN,
STATE_MARKUP_TAG_END,
- STATE_MARKUP_TAG_INSIDE,
STATE_MARKUP_TAG,
STATE_MARKUP_ATTR_NAME,
STATE_MARKUP_ATTR_VALUE
@@ -117,7 +96,6 @@ enum DirectiveType {
enum SectionType {
ST_NEWSONG,
- ST_NOTHING,
ST_CHORUS,
ST_VERSE,
ST_BRIDGE,
@@ -126,18 +104,10 @@ enum SectionType {
};
enum Position {
- POS_NOTHING,
- POS_BEGIN, // rename to POS_START
+ POS_START,
POS_END
};
-/* enum LineStyle {
- LS_NORMAL,
- LS_GREY_BACKGROUND,
- LS_ITALIC,
- LS_BOX
-}; */
-
struct ChoDirective {
enum DirectiveType dtype;
enum SectionType stype;
@@ -162,9 +132,7 @@ struct ChoLineItem {
};
struct ChoLine {
- // enum LineStyle style;
struct ChoChord **chords;
- // char *lyrics;
struct ChoLineItem **lyrics;
};
@@ -181,6 +149,14 @@ struct ChoSong {
struct ChoSong **cho_parse(FILE *fp);
void cho_songs_free(struct ChoSong **song);
+void cho_style_print(struct Style *style);
+
+/* Debugging */
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);
diff --git a/lorid.c b/lorid.c
@@ -46,39 +46,46 @@ 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;*/
- /* 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");*/
- /*}*/
+ // struct ChoChord **chords;
+ enum SectionType stype;
+ struct ChoLineItem *line_item;
+ int s = 0;
+ int li = 0;
+ // int c = 0;
+ int ly = 0;
+ struct ChoSong *song = songs[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) {
+ printf("---- BEGIN LINE ----\n");
+ /* 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; */
+ while (song->sections[s]->lines[li]->lyrics[ly] != NULL) {
+ line_item = song->sections[s]->lines[li]->lyrics[ly];
+ if (strlen(line_item->text) > 0) {
+ printf("text: %s\n", line_item->text);
+ cho_style_print(line_item->style);
+ }
+ ly++;
+ }
+ ly = 0;
+ li++;
+ printf("---- END LINE ------\n");
+ }
+ li = 0;
+ s++;
+ printf("---- END SECTION ------\n");
+ }
cho_songs_free(songs);
fclose(fp);
return 0;