lorid

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

commit 165d8b925f31ec8d3a4eb9feafa330545bfc6ca9
parent 56243a4c30ca1172edba725bd1e0e7f4064afdaa
Author: nibo <nibo@relim.de>
Date:   Sat, 22 Mar 2025 11:10:53 +0100

Imrove metadata substitutions

Support metadata names that have a dot inside
like e.g. 'chordpro.version'

Diffstat:
Msrc/chordpro.c | 61++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/chordpro.h | 3++-
2 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/src/chordpro.c b/src/chordpro.c @@ -1896,13 +1896,6 @@ cho_metadata_substitution_replace( return NULL; } -/* - FIXME: metadata item names containing a dot like 'chordpro.version' simply doesn't work. - Their naming is against the naming rule described at 'https://www.chordpro.org/beta/directives-meta/'. - Handle the following metadata item names specially: 'chordpro.version', 'instrument.type', - 'instrument.description', 'user.name' and 'user.fullname'. -*/ -// TODO: %{lang=""|yes|no} prints langs' value and the string 'yes', that's wrong. static char * cho_metadata_substitution_parse( struct ChoContext *ctx, @@ -1911,12 +1904,14 @@ cho_metadata_substitution_parse( enum State state_before_substitution ) { + bool substitution_exist = false; int o = 0; char *out = NULL; int len = strlen(str); int i; for (i = 0; i<len; i++) { if (str[i] == '%' && str[i+1] == '{') { + substitution_exist = true; i += 2; break; } @@ -1964,8 +1959,7 @@ cho_metadata_substitution_parse( } if (c == '.') { name[n] = 0; - n = 0; - state = MSS_NAME_INDEX; + state = MSS_NAME_OR_INDEX; break; } if (prev_c != '\\' && c == '|') { @@ -1978,7 +1972,26 @@ cho_metadata_substitution_parse( n++; break; } - case MSS_NAME_INDEX: { + case MSS_NAME_OR_INDEX: { + if (c == '-' || isdigit(c)) { + n = 0; + name_index[n] = c; + n++; + state = MSS_INDEX; + break; + } else + if (islower(c)) { + name[n] = '.'; + n++; + name[n] = c; + n++; + state = MSS_NAME; + break; + } + cho_log(ctx, LOG_ERR, "Invalid character after the dot."); + return NULL; + } + case MSS_INDEX: { if (c == '=') { name_index[n] = 0; n = 0; @@ -1991,7 +2004,7 @@ cho_metadata_substitution_parse( state = MSS_TRUE_TEXT; break; } - if (c != '-' && !isdigit(c)) { + if (!isdigit(c)) { // TODO: Find a better term for 'metadata substitution name index'! cho_log(ctx, LOG_ERR, "Specify a positive or negative number in metadata substitution name index."); return NULL; @@ -2089,7 +2102,7 @@ cho_metadata_substitution_parse( case MSS_NAME: name[n] = 0; break; - case MSS_NAME_INDEX: + case MSS_INDEX: name_index[n] = 0; break; case MSS_VALUE: @@ -2125,7 +2138,7 @@ cho_metadata_substitution_parse( } if (name[0] != 0) { replaced = cho_metadata_substitution_replace(ctx, name, value, index); - if (replaced) { + if (replaced[0] != 0) { if (true_text[0] != 0) { substituted = cho_metadata_substitution_parse(ctx, true_text, name, STATE_METADATA_SUBSTITUTION); for (ch = substituted; *ch; ch++) { @@ -2141,7 +2154,6 @@ cho_metadata_substitution_parse( o++; } } - free(replaced); } else { if (false_text[0] != 0) { substituted = cho_metadata_substitution_parse(ctx, false_text, name, STATE_METADATA_SUBSTITUTION); @@ -2159,22 +2171,25 @@ cho_metadata_substitution_parse( } } } + free(replaced); } else { if (state_before_substitution != STATE_METADATA_SUBSTITUTION) { cho_log(ctx, LOG_ERR, "An empty metadata substitution can only be used inside of another metadata substitution."); return NULL; } - replaced = cho_metadata_substitution_replace(ctx, parent_name, "", 0); - if (replaced) { - for (ch = replaced; *ch; ch++) { - out = erealloc(out, (o+1) * sizeof(char)); - out[o] = *ch; - o++; + if (substitution_exist) { + replaced = cho_metadata_substitution_replace(ctx, parent_name, "", 0); + if (replaced[0] != 0) { + for (ch = replaced; *ch; ch++) { + out = erealloc(out, (o+1) * sizeof(char)); + out[o] = *ch; + o++; + } + } else { + cho_log(ctx, LOG_WARN, "There is no metadata item named '%s'.", parent_name); } - } else { - cho_log(ctx, LOG_WARN, "There is no metadata item named '%s'.", parent_name); + free(replaced); } - free(replaced); } for (; i<len; i++) { out = erealloc(out, (o+1) * sizeof(char)); diff --git a/src/chordpro.h b/src/chordpro.h @@ -34,7 +34,8 @@ enum ChordDiagramState { enum MetadataSubstitutionState { MSS_NAME, - MSS_NAME_INDEX, + MSS_NAME_OR_INDEX, + MSS_INDEX, MSS_VALUE, MSS_TRUE_TEXT, MSS_FALSE_TEXT,