mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 06:18:47 +02:00
Add the triginfo("header") function and corresponding %<...> substitution sequence.
This commit is contained in:
@@ -177,7 +177,7 @@
|
||||
"slide" "soleq" "stdout" "strlen" "substr" "sunrise" "sunset" "time"
|
||||
"timepart" "timezone" "today" "trig" "trigback" "trigdate"
|
||||
"trigdatetime" "trigdelta" "trigduration" "trigeventduration"
|
||||
"trigeventstart" "trigfrom" "trigger" "trigpriority" "trigrep"
|
||||
"trigeventstart" "trigfrom" "trigger" "triginfo" "trigpriority" "trigrep"
|
||||
"trigscanfrom" "trigtags" "trigtime" "trigtimedelta" "trigtimerep"
|
||||
"triguntil" "trigvalid" "typeof" "tzconvert" "upper" "utctolocal"
|
||||
"value" "version" "weekno" "wkday" "wkdaynum" "year")
|
||||
|
||||
@@ -1661,6 +1661,11 @@ is replaced with "\fIyy\fR", the last two digits of the year.
|
||||
is replaced with the lookup of \fIany_text\fR in the translation table.
|
||||
It is the equivalent of [_("any_text")] but is more convenient to type.
|
||||
.TP
|
||||
.B %<\fIany_text\fR\fB>
|
||||
is replaced with the INFO value associated with the header \fIany_text\fR
|
||||
or the empty string if no such INFO value exists. It is the
|
||||
equivalent of [triginfo("any_text")] but is more convenient to type.
|
||||
.TP
|
||||
.B %_
|
||||
(percent-underscore) is replaced with a newline. You can use this to
|
||||
achieve multi-line reminders. Note that calendar back-ends vary in
|
||||
@@ -4292,7 +4297,23 @@ whose value is the maximum of "yyyy-mm-dd" and today.
|
||||
.B trigfrom()
|
||||
Returns (as a \fBDATE\fR type) the \fBFROM\fR parameter of the last \fBREM\fR or
|
||||
\fBIFTRIG\fR command. If there was no \fBFROM\fR parameter, returns the integer -1.
|
||||
|
||||
.TP
|
||||
.B triginfo(s_header)
|
||||
Returns a \fBSTRING\fR that is the INFO item associated with the header
|
||||
\fIheader\fR. The header should \fInot\fR contain a colon. Header name
|
||||
comparisons are case-insensitive.
|
||||
.RS
|
||||
.PP
|
||||
For example, the following will assign "At home" to the variable a and
|
||||
the empty string to variable b:
|
||||
.PP
|
||||
.nf
|
||||
REM INFO "Location: At home" MSG test
|
||||
SET a triginfo("location")
|
||||
SET b triginfo("no_such_header")
|
||||
.fi
|
||||
.PP
|
||||
.RE
|
||||
.TP
|
||||
.B trigger(d_date [,t_time [,i_utcflag]]) \fRor\fB trigger(q_datetime [,i_utcflag])
|
||||
Returns a string suitable for use in a \fBREM\fR command or a
|
||||
|
||||
@@ -215,6 +215,33 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
if (c == '<') {
|
||||
DynamicBuffer header;
|
||||
char const *val;
|
||||
DBufInit(&header);
|
||||
|
||||
while(1) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(&header);
|
||||
return err;
|
||||
}
|
||||
if (!c || c == '>') {
|
||||
break;
|
||||
}
|
||||
DBufPutc(&header, c);
|
||||
}
|
||||
if (!c) {
|
||||
Wprint(tr("Warning: Unterminated %%<...> substitution sequence"));
|
||||
}
|
||||
err = OK;
|
||||
val = FindTrigInfo(t, DBufValue(&header));
|
||||
DBufFree(&header);
|
||||
if (val) {
|
||||
SHIP_OUT(val);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (c == '(') {
|
||||
DynamicBuffer orig;
|
||||
DynamicBuffer translated;
|
||||
|
||||
13
src/funcs.c
13
src/funcs.c
@@ -162,6 +162,7 @@ static int FTrigdate (func_info *);
|
||||
static int FTrigdatetime (func_info *);
|
||||
static int FTrigdelta (func_info *);
|
||||
static int FTrigduration (func_info *);
|
||||
static int FTriginfo (func_info *);
|
||||
static int FTrigeventduration(func_info *);
|
||||
static int FTrigeventstart (func_info *);
|
||||
static int FTrigfrom (func_info *);
|
||||
@@ -326,6 +327,7 @@ BuiltinFunc Func[] = {
|
||||
{ "trigeventstart", 0, 0, 0, FTrigeventstart, NULL },
|
||||
{ "trigfrom", 0, 0, 0, FTrigfrom, NULL },
|
||||
{ "trigger", 1, 3, 0, FTrigger, NULL },
|
||||
{ "triginfo", 1, 1, 1, FTriginfo, NULL },
|
||||
{ "trigpriority", 0, 0, 0, FTrigpriority, NULL },
|
||||
{ "trigrep", 0, 0, 0, FTrigrep, NULL },
|
||||
{ "trigscanfrom", 0, 0, 0, FTrigscanfrom, NULL },
|
||||
@@ -1620,6 +1622,17 @@ static int FTrigeventduration(func_info *info)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FTriginfo(func_info *info)
|
||||
{
|
||||
char const *s;
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
s = FindTrigInfo(&LastTrigger, ARGSTR(0));
|
||||
if (!s) {
|
||||
return RetStrVal("", info);
|
||||
}
|
||||
return RetStrVal(s, info);
|
||||
}
|
||||
|
||||
static int FTrigeventstart(func_info *info)
|
||||
{
|
||||
if (LastTrigger.eventstart == NO_TIME) {
|
||||
|
||||
@@ -282,3 +282,4 @@ void FreeTrigInfoChain(TrigInfo *ti);
|
||||
int AppendTrigInfo(Trigger *t, char const *info);
|
||||
int TrigInfoHeadersAreTheSame(char const *i1, char const *i2);
|
||||
int TrigInfoIsValid(char const *info);
|
||||
char const *FindTrigInfo(Trigger *t, char const *header);
|
||||
|
||||
@@ -794,3 +794,26 @@ TrigInfoIsValid(char const *info)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
char const *
|
||||
FindTrigInfo(Trigger *t, char const *header)
|
||||
{
|
||||
TrigInfo *ti;
|
||||
size_t len;
|
||||
char const *s;
|
||||
|
||||
if (!t || !header || !*header) return NULL;
|
||||
|
||||
ti = t->infos;
|
||||
len = strlen(header);
|
||||
while(ti) {
|
||||
if (!strncasecmp(ti->info, header, len) &&
|
||||
ti->info[len] == ':') {
|
||||
s = ti->info + len + 1;
|
||||
while(isspace(*s)) s++;
|
||||
return s;
|
||||
}
|
||||
ti = ti->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -647,7 +647,7 @@ EOF
|
||||
|
||||
# The INFO keyword
|
||||
../src/remind -pp - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
REM Wed INFO "Location: here" INFO "Summary: Nope" MSG Meeting
|
||||
REM Wed INFO "Location: here" INFO "Summary: Nope" MSG Meeting [triginfo("location")] %<summary> %<nonexist> [triginfo("cabbage")]
|
||||
EOF
|
||||
|
||||
# Invalid info strings
|
||||
|
||||
@@ -24164,6 +24164,7 @@ trigeventduration
|
||||
trigeventstart
|
||||
trigfrom
|
||||
trigger
|
||||
triginfo
|
||||
trigpriority
|
||||
trigrep
|
||||
trigscanfrom
|
||||
@@ -24541,6 +24542,7 @@ TRANSLATE "Warning: UNTIL/THROUGH date earlier than SCANFROM date" ""
|
||||
TRANSLATE "Warning: UNTIL/THROUGH date earlier than start date" ""
|
||||
TRANSLATE "Warning: Unable to save ONCE timestamp to %s: %s" ""
|
||||
TRANSLATE "Warning: Unterminated %%(...) substitution sequence" ""
|
||||
TRANSLATE "Warning: Unterminated %%<...> substitution sequence" ""
|
||||
TRANSLATE "Warning: Unterminated %%{...} substitution sequence" ""
|
||||
TRANSLATE "Warning: Useless use of UNTIL with fully-specified date and no *rep" ""
|
||||
TRANSLATE "Warning: Variable name `%.*s...' truncated to `%.*s'" ""
|
||||
@@ -24659,10 +24661,10 @@ February 2024 29 4 0
|
||||
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
|
||||
January 31
|
||||
March 31
|
||||
{"date":"2024-02-07","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"body":"Meeting"}
|
||||
{"date":"2024-02-14","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"body":"Meeting"}
|
||||
{"date":"2024-02-21","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"body":"Meeting"}
|
||||
{"date":"2024-02-28","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"body":"Meeting"}
|
||||
{"date":"2024-02-07","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"rawbody":"Meeting [triginfo(\"location\")] %<summary> %<nonexist> [triginfo(\"cabbage\")]","body":"Meeting here Nope "}
|
||||
{"date":"2024-02-14","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"rawbody":"Meeting [triginfo(\"location\")] %<summary> %<nonexist> [triginfo(\"cabbage\")]","body":"Meeting here Nope "}
|
||||
{"date":"2024-02-21","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"rawbody":"Meeting [triginfo(\"location\")] %<summary> %<nonexist> [triginfo(\"cabbage\")]","body":"Meeting here Nope "}
|
||||
{"date":"2024-02-28","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"rawbody":"Meeting [triginfo(\"location\")] %<summary> %<nonexist> [triginfo(\"cabbage\")]","body":"Meeting here Nope "}
|
||||
# rem2ps2 end
|
||||
-stdin-(1): Invalid INFO string: Must be of the form "Header: Value"
|
||||
-stdin-(2): Invalid INFO string: Must be of the form "Header: Value"
|
||||
|
||||
Reference in New Issue
Block a user