commit 8b71175992609d9bd033c5229d577708b27c8b19
parent a5b28eb3d9a33bedfb44568ad30ca23132c2e28c
Author: nibo <nibo@relim.de>
Date: Tue, 13 Aug 2024 08:57:05 +0200
Support start_of_* and end_of_* custom directives
Diffstat:
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/chordpro.c b/chordpro.c
@@ -1909,6 +1909,17 @@ static struct ChoDirective *cho_directive_parse(const char *name)
directive->btype = BT_COLUMN;
goto END;
}
+ if (str_starts_with(name, "start_of_")) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->position = POS_START;
+ directive->stype = ST_CUSTOM;
+ goto END;
+ } else if (str_starts_with(name, "end_of_")) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->position = POS_END;
+ directive->stype = ST_CUSTOM;
+ goto END;
+ }
directive->dtype = DT_CUSTOM;
END:
return directive;
@@ -1920,11 +1931,12 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
bool is_chord_already_initialized = false;
char buf = 0;
char prev_buf = '\n';
- char directive_name[16];
- char directive_value[512];
+ char directive_name[128];
+ char directive_value[128];
char chord[15];
char tag_begin[6];
char tag_end[6];
+ char custom_directive[64];
enum State state = STATE_LYRICS;
enum State prev_state = STATE_LYRICS;
unsigned int line_number = 1;
@@ -2053,6 +2065,10 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
g_current_ftype = directive->ftype;
switch (directive->position) {
case POS_START:
+ if (directive->stype == ST_CUSTOM) {
+ memset(custom_directive, 0, sizeof(custom_directive));
+ strcpy(custom_directive, &directive_name[9]);
+ }
cho_line_item_free(songs[so]->sections[se]->lines[li]->lyrics[ly]);
free(songs[so]->sections[se]->lines[li]->lyrics);
ly = 0;
@@ -2070,6 +2086,11 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
break;
case POS_END:
if (directive->stype == songs[so]->sections[se]->type) {
+ if (directive->stype == ST_CUSTOM) {
+ if (strcmp(custom_directive, &directive_name[7]) != 0) {
+ break;
+ }
+ }
cho_line_item_free(songs[so]->sections[se]->lines[li]->lyrics[ly]);
free(songs[so]->sections[se]->lines[li]->lyrics);
ly = 0;
@@ -2194,6 +2215,10 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
g_current_ftype = directive->ftype;
switch (directive->position) {
case POS_START:
+ if (directive->stype == ST_CUSTOM) {
+ memset(custom_directive, 0, sizeof(custom_directive));
+ strcpy(custom_directive, &directive_name[9]);
+ }
cho_line_item_free(songs[so]->sections[se]->lines[li]->lyrics[ly]);
free(songs[so]->sections[se]->lines[li]->lyrics);
ly = 0;
@@ -2758,6 +2783,8 @@ static const char *cho_debug_the_stype(enum SectionType stype)
return "ST_GRID";
case ST_NEWSONG:
return "ST_NEWSONG";
+ case ST_CUSTOM:
+ return "ST_CUSTOM";
}
return "";
}
diff --git a/chordpro.h b/chordpro.h
@@ -157,7 +157,8 @@ enum SectionType {
ST_VERSE,
ST_BRIDGE,
ST_TAB,
- ST_GRID
+ ST_GRID,
+ ST_CUSTOM
};
enum Position {
diff --git a/todo b/todo
@@ -16,6 +16,7 @@ introduce parse errors: make parser bulletproof
stop execution
*_to_string functions sometimes return stringified enum and sometimes config value
allow {start_of_*},{end_of_*} custom directives
+parse environment directive value when: label="Verse 1"
# pdf output
break lines when too long