mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
53 Commits
04.02.03-B
...
04.02.06
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e268bbf31d | ||
|
|
5863404de6 | ||
|
|
2de5996f4e | ||
|
|
695e79602a | ||
|
|
cf0d958da5 | ||
|
|
85b0348fa7 | ||
|
|
15a5d9a876 | ||
|
|
1baa6dab0c | ||
|
|
34bb250ba3 | ||
|
|
598b1b7464 | ||
|
|
e63d4be4e8 | ||
|
|
65561e7f34 | ||
|
|
da31dadb71 | ||
|
|
705adbb82a | ||
|
|
269f9788b6 | ||
|
|
5e1c5ae384 | ||
|
|
562eb83bde | ||
|
|
a53db00243 | ||
|
|
11375729db | ||
|
|
9fee354e6c | ||
|
|
ec76554d41 | ||
|
|
ddb0817c99 | ||
|
|
3d6ecd1f72 | ||
|
|
e3ec6565e9 | ||
|
|
8ed49ead7f | ||
|
|
49fbca416f | ||
|
|
82cd438fff | ||
|
|
946e1bca38 | ||
|
|
e40c81b5bf | ||
|
|
f23418480d | ||
|
|
bb4df39c50 | ||
|
|
5fec775863 | ||
|
|
a85980fec2 | ||
|
|
f3ea2962e6 | ||
|
|
3a5af23ab6 | ||
|
|
f9656edc51 | ||
|
|
5134b47d47 | ||
|
|
d4a183f3bf | ||
|
|
87e392de6c | ||
|
|
afc1667e64 | ||
|
|
8d25270c43 | ||
|
|
929866a770 | ||
|
|
395bad96a7 | ||
|
|
cd7be006c9 | ||
|
|
f658ba7ee7 | ||
|
|
7416f4c035 | ||
|
|
2860159ff7 | ||
|
|
64fa71ab09 | ||
|
|
ffbba7d4d1 | ||
|
|
fdcc2d8acf | ||
|
|
f1aa4d16af | ||
|
|
a55c5580f3 | ||
|
|
569e315306 |
14
configure.in
14
configure.in
@@ -1,6 +1,7 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(src/queue.c)
|
||||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([src/queue.c])
|
||||
|
||||
cat <<'EOF'
|
||||
|
||||
@@ -12,7 +13,7 @@ cat <<'EOF'
|
||||
|
||||
EOF
|
||||
|
||||
AC_CONFIG_HEADER(src/config.h)
|
||||
AC_CONFIG_HEADERS([src/config.h])
|
||||
|
||||
AC_ARG_ENABLE(perl-build-artifacts,
|
||||
[ --disable-perl-build-artifacts
|
||||
@@ -35,14 +36,14 @@ AC_CHECK_SIZEOF(unsigned int)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_CHECK_HEADERS(sys/types.h sys/file.h glob.h wctype.h locale.h langinfo.h)
|
||||
AC_CHECK_HEADERS(sys/types.h glob.h wctype.h locale.h langinfo.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_STRUCT_TM
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_HEADER_TIME
|
||||
AC_CHECK_HEADERS_ONCE([sys/time.h])
|
||||
|
||||
if test "$GCC" = yes; then
|
||||
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
|
||||
@@ -80,10 +81,11 @@ if test "$?" != 0 ; then
|
||||
exit 1
|
||||
fi
|
||||
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups)
|
||||
VERSION=04.02.02
|
||||
VERSION=04.02.06
|
||||
AC_SUBST(VERSION)
|
||||
AC_SUBST(PERL)
|
||||
AC_SUBST(PERLARTIFACTS)
|
||||
AC_SUBST(RELEASE_DATE)
|
||||
AC_OUTPUT(src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1)
|
||||
AC_CONFIG_FILES([src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1])
|
||||
AC_OUTPUT
|
||||
chmod a+x rem2pdf/bin/rem2pdf
|
||||
|
||||
@@ -1,6 +1,96 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 4.2 Patch 3 - 2023-??-??
|
||||
* VERSION 4.2 Patch 6 - 2023-09-12
|
||||
|
||||
- NEW FEATURE: remind: The "nonomitted()" function takes an optional
|
||||
extra INT argument called "step". See man page for details. Also
|
||||
allows the "start" argument to be greater than the "end" argument,
|
||||
in which case they are effectively swapped.
|
||||
|
||||
- NEW FEATURE: remind: The "slide()" function takes an optional extra
|
||||
INT argument called "step", similar to "nonomitted()". See man page
|
||||
for details.
|
||||
|
||||
- NEW FEATURE: remind: Added the $ParseUntriggered system variable;
|
||||
see the man page for details. You almost certainly will never need
|
||||
to use this.
|
||||
|
||||
- NEW FILE: holidays/ie.rem: Added Irish holidays, courtesy of
|
||||
Amy de Buitléir.
|
||||
|
||||
- CHANGE: remind: The "-tn" option sets all REM statement deltas to
|
||||
++n rather than adding n to any existing REM statement's delta.
|
||||
Additionally, the corresponding system variable $DeltaOffset has
|
||||
been renamed to $DeltaOverride.
|
||||
|
||||
- NEW OPTION: remind: Add the "-tz" option to explicitly set all
|
||||
REM statement deltas to zero.
|
||||
|
||||
- DOCUMENTATION FIX: remind: various documentation improvements.
|
||||
|
||||
- BUG FIX: Correct some errors in Italian localization, courtesy of
|
||||
Emanuele Torre
|
||||
|
||||
* VERSION 4.2 Patch 5 - 2023-04-11
|
||||
|
||||
- MINOR IMPROVEMENT: remind: If someone uses OMIT yyyy-mm-dd UNTIL yyyy-mm-dd
|
||||
give a better error message suggesting THROUGH instead of UNTIL.
|
||||
|
||||
- BUG FIX: remind: The fix for the combination of ADDOMIT and SATISFY that
|
||||
appeared in version 04.02.00 was not complete; the bug has finally been
|
||||
properly fixed.
|
||||
|
||||
- BUG FIX: remind: Remove an unnecessary #include <sys/file.h>.
|
||||
Nothing needed that and it broke compilation on FreeBSD.
|
||||
|
||||
* VERSION 4.2 Patch 4 - 2023-03-15
|
||||
|
||||
- NEW FEATURE: Remind: Add "htmlescape" and "htmlstriptags" built-in
|
||||
functions.
|
||||
|
||||
- NEW FEATURE: Rem2PDF: Add the "--wrap, -y" option to ensure that no
|
||||
printed calendar takes up more than 5 rows. If a calendar would normally
|
||||
require 6 rows, wrap it so the last day or two appear on the first
|
||||
row instead of on a sixth row.
|
||||
|
||||
- NEW FEATURE: Remind: Improve the -k option to allow specification of
|
||||
separate commands for immediately-issued vs. queued reminders. For
|
||||
example:
|
||||
|
||||
remind '-kcmd1 %s' '-k:cmd2 %s' ...
|
||||
|
||||
will use "cmd1" for immediately-issued reminders and "cmd2" for queued
|
||||
ones. If you only use '-k:cmd2 %s' then immediately-issued reminders
|
||||
are simply printed as usual rather than being passed to a command.
|
||||
|
||||
- IMPROVEMENT: Remind: Make "SPECIAL MSG" the same as just "MSG" and
|
||||
the same for MSF, RUN, PS and PSFILE. This effectively lets you use
|
||||
expression-pasting to determine the type of a REM command; see the
|
||||
remind(1) man page for details.
|
||||
|
||||
- MINOR IMPROVEMENT: If "make test" fails, output up to 200 lines of diff
|
||||
so we can see immediately what failed.
|
||||
|
||||
- DOCUMENTATION FIX: Fix some typos; fix TkRemind syntax description.
|
||||
|
||||
- TEST FIX: Make tests run reliably regardless of local machine's time zone.
|
||||
|
||||
- BUG FIX: TkRemind: Don't crash if local installation of Tk lacks the
|
||||
-underlinefg configuration option.
|
||||
|
||||
- BUG FIX: examples/defs.rem: Fix up US Thanksgiving example.
|
||||
|
||||
- BUG FIX: include/holidays/us.rem: Add logic for US holidays that are
|
||||
observed on a Friday if the holiday is a Saturday, or on a Monday if the
|
||||
holiday is a Sunday.
|
||||
|
||||
- BUG FIX: TkRemind: Don't cut off MOON text at the first white-space
|
||||
character.
|
||||
|
||||
- BUG FIX: Remind: prevent functions defined on the command-line (as in
|
||||
remind '-if(x)=whatever') from segfaulting.
|
||||
|
||||
* VERSION 4.2 Patch 3 - 2023-02-10
|
||||
|
||||
- NEW FEATURE: Remind: add the orthodoxeaster() function to return the
|
||||
date of Orthodox Easter.
|
||||
@@ -9,6 +99,9 @@ CHANGES TO REMIND
|
||||
|
||||
- IMPROVEMENT: Add Greek holiday file courtesy of JeiEl.
|
||||
|
||||
- IMPROVEMENT: Fix the Perl code (rem2pdf, rem2html) to silence Perl::Critic
|
||||
warnings
|
||||
|
||||
- IMPROVEMENT: Many internal code tweaks to eliminate many cppcheck
|
||||
static analysis warnings.
|
||||
|
||||
@@ -23,6 +116,9 @@ CHANGES TO REMIND
|
||||
|
||||
- BUG FIX: Remind: Add missing #include <fcntl.h> to funcs.c
|
||||
|
||||
- BUG FIX: Remind: Fix undefined integer-overflow behavior in built-in abs()
|
||||
function. Pointed out on IRC by "ubitux".
|
||||
|
||||
* VERSION 4.2 Patch 2 - 2023-01-01
|
||||
|
||||
- NEW FEATURE: Remind: Add the NOQUEUE modifier to the REM statement for
|
||||
|
||||
@@ -42,7 +42,6 @@ SET Week_1 1
|
||||
SET Week_2 8
|
||||
SET Week_3 15
|
||||
SET Week_4 22
|
||||
FSET _last(mo) "1 " + MON((mo%12)+1) + " --7"
|
||||
|
||||
#################################################################
|
||||
# Function that removes a single leading zero from a string... #
|
||||
@@ -126,6 +125,8 @@ REM Sat Sun SPECIAL SHADE 220
|
||||
# The following holidays were provided by Dave Rickel #
|
||||
# Modified by D. Skoll to give safe OMITs for moveable holidays #
|
||||
# #
|
||||
# NOTE: See include/holidays/us.rem for more up-to-date definitions #
|
||||
# #
|
||||
#############################################################################
|
||||
|
||||
SET SaveTrig $NumTrig
|
||||
@@ -189,7 +190,7 @@ REM Nov 11 MSG %"Veterans Day%"
|
||||
REM Oct 30 MSG %"Mischief Night%"
|
||||
REM Oct 31 MSG %"Halloween%"
|
||||
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG %"Election Day%"
|
||||
REM Last Thu in Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
|
||||
REM Thu Nov [Week_4] SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
|
||||
REM Fri Nov [Week_4+1] SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
|
||||
OMIT Dec 24 MSG %"Christmas Eve%"
|
||||
OMIT Dec 25 MSG %"Christmas%" Day
|
||||
|
||||
42
include/holidays/ie.rem
Normal file
42
include/holidays/ie.rem
Normal file
@@ -0,0 +1,42 @@
|
||||
;
|
||||
; Irish Holidays
|
||||
;
|
||||
; The dates for the Public ("bank") holidays are taken from the following site:
|
||||
; https://www.citizensinformation.ie/en/employment/employment-rights-and-conditions/leave-and-holidays/public-holidays/
|
||||
;
|
||||
; This file was derived from:
|
||||
; https://github.com/mhwombat/dotWombat/blob/master/.config/remind/IrishHolidays.rem
|
||||
; by Amy de Buitléir.
|
||||
|
||||
; fixed dates
|
||||
OMIT 31 December MSG New Year's Eve (Oíche Chinn Bliana) Public Holiday
|
||||
OMIT 1 January MSG New Year's Day (Lá Caille, Lá Bliana Nua) Public Holiday
|
||||
OMIT 17 March MSG Saint Patrick's Day (Lá Fhéile Pádraig) Public Holiday
|
||||
OMIT 24 December MSG Christmas Eve (Oíche Nollag) Public Holiday
|
||||
OMIT 25 December MSG Christmas Day (Lá Nollag) Public Holiday
|
||||
OMIT 26 December MSG Saint Stephen's Day, Wren Day (Lá Fhéile Stiofáin, Lá an Dreoilín) Public Holiday
|
||||
|
||||
; moving dates
|
||||
|
||||
; First Monday in May
|
||||
REM Monday 1 May SCANFROM -7 ADDOMIT MSG May Day (Lá Bealtaine) Public Holiday
|
||||
|
||||
; First Monday in June
|
||||
REM Monday 1 June SCANFROM -7 ADDOMIT MSG June Public Holiday
|
||||
|
||||
; First Monday in August
|
||||
REM Monday 1 August SCANFROM -7 ADDOMIT MSG August Public Holiday
|
||||
|
||||
; Last Monday in October
|
||||
REM Monday 1 -7 November SCANFROM -7 ADDOMIT MSG October Public Holiday
|
||||
|
||||
; Easter
|
||||
SET easter easterdate(today())
|
||||
REM [TRIGGER(easter-2)] MSG Good Friday (Aoine an Chéasta)
|
||||
REM [TRIGGER(easter)] MSG Easter Sunday (Domhnach Cásca)
|
||||
OMIT [TRIGGER(easter+1)] MSG Easter Monday (Luan Cásca) Public Holiday
|
||||
|
||||
; St. Brigid's Day
|
||||
REM 1 February MSG Saint Brigid's Day (Lá Fhéile Bríde or Imbolc)
|
||||
; The public holiday is the first Monday in February, or 1 February if the date falls on a Friday
|
||||
REM February SCANFROM -7 ADDOMIT SATISFY [($Td==1 && $Tw==5) || ($Td<8 && $Tw==1 && $Td!=4)] MSG Public Holiday
|
||||
@@ -14,6 +14,9 @@ REM [easterdate($Uy)+49] MSG Pentecost
|
||||
# which ones are omitted.
|
||||
|
||||
OMIT Jan 1 MSG New Year's Day
|
||||
REM 31 Dec SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG New Year's Day (observed)
|
||||
REM 2 Jan SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG New Year's Day (observed)
|
||||
|
||||
REM Third Monday in Jan MSG Martin Luther King - %"MLK Day%"
|
||||
REM Feb 2 MSG Ground Hog Day
|
||||
REM Feb 14 MSG Valentine's Day
|
||||
@@ -21,8 +24,8 @@ REM Third Monday in Feb SCANFROM -7 ADDOMIT MSG President's Day
|
||||
REM Mar 17 MSG St. Patrick's Day
|
||||
|
||||
# These are accurate for most places in North America
|
||||
REM MAYBE-UNCOMPUTABLE Sun November SATISFY [isdst($T) != isdst($T+1)] MSG Daylight Saving Time Ends
|
||||
REM MAYBE-UNCOMPUTABLE Sun March SATISFY [isdst($T) != isdst($T+1)] MSG Daylight Saving Time Starts
|
||||
REM MAYBE-UNCOMPUTABLE Sun November SATISFY [isdst($T) && !isdst($T+1)] MSG Daylight Saving Time Ends
|
||||
REM MAYBE-UNCOMPUTABLE Sun March SATISFY [!isdst($T) && isdst($T+1)] MSG Daylight Saving Time Starts
|
||||
|
||||
REM Apr 1 MSG %"April Fool's%" Day
|
||||
|
||||
@@ -49,14 +52,21 @@ REM Third Sat in May MSG Armed Forces Day
|
||||
REM Last Monday in May SCANFROM -7 ADDOMIT MSG Memorial Day
|
||||
REM Jun 14 MSG Flag Day
|
||||
|
||||
OMIT 19 June MSG Juneteenth
|
||||
REM 18 June SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Juneteenth (observed)
|
||||
REM 20 June SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Juneteenth (observed)
|
||||
|
||||
REM July 4 SCANFROM -7 ADDOMIT MSG Independence Day
|
||||
REM July 3 SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Independence Day (observed)
|
||||
REM July 5 SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Independence Day (observed)
|
||||
REM July 3 SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Independence Day (observed)
|
||||
REM July 5 SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Independence Day (observed)
|
||||
|
||||
REM Third Sun in June MSG Father's Day
|
||||
REM First Mon in Sep SCANFROM -7 ADDOMIT MSG Labor Day
|
||||
REM Second Mon in Oct MSG Columbus Day / Indigenous Peoples' Day
|
||||
REM Nov 11 MSG Veterans Day
|
||||
|
||||
OMIT 11 Nov MSG Veterans Day
|
||||
REM 10 Nov SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Veterans Day (observed)
|
||||
REM 12 Nov SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Veterans Day (observed)
|
||||
|
||||
REM Oct 30 MSG Mischief Night
|
||||
REM Oct 31 MSG Halloween
|
||||
@@ -64,8 +74,9 @@ REM Oct 31 MSG Halloween
|
||||
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG Election Day
|
||||
|
||||
REM Thu 22 Nov SCANFROM -7 ADDOMIT MSG Thanksgiving Day
|
||||
|
||||
REM Fri 23 Nov SCANFROM -7 ADDOMIT MSG Thanksgiving (cont.)
|
||||
|
||||
REM Dec 24 MSG Christmas Eve
|
||||
OMIT Dec 25 MSG %"Christmas%" Day
|
||||
REM 24 Dec SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Christmas (observed)
|
||||
REM 26 Dec SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Christmas (observed)
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
# This file is derived from a translation by Valerio Aimale
|
||||
|
||||
SET $Sunday "Domenica"
|
||||
SET $Monday "Lunedí"
|
||||
SET $Tuesday "Martedí"
|
||||
SET $Wednesday "Mercoledí"
|
||||
SET $Thursday "Giovedí"
|
||||
SET $Friday "Venerdí"
|
||||
SET $Monday "Lunedì"
|
||||
SET $Tuesday "Martedì"
|
||||
SET $Wednesday "Mercoledì"
|
||||
SET $Thursday "Giovedì"
|
||||
SET $Friday "Venerdì"
|
||||
SET $Saturday "Sabato"
|
||||
|
||||
SET $January "Gennaio"
|
||||
@@ -40,7 +40,7 @@ SET $Now "ora"
|
||||
SET $At "alle"
|
||||
SET $Minute "minuto"
|
||||
SET $Hour "ora"
|
||||
SET $Is "é"
|
||||
SET $Is "è"
|
||||
SET $Was "era"
|
||||
SET $And "e"
|
||||
SET $Hplu "a"
|
||||
|
||||
148
man/remind.1.in
148
man/remind.1.in
@@ -60,7 +60,9 @@ weeks to be produced.
|
||||
.B 'a'
|
||||
causes \fBRemind\fR to display reminders on the calendar on the
|
||||
day they actually occur \fIas well as\fR on any preceding days
|
||||
specified by the reminder's \fIdelta\fR.
|
||||
specified by the reminder's \fIdelta\fR. This \fIalso\fR causes
|
||||
\fBRemind\fR to include text outside %"...%" sequences that would
|
||||
otherwise be removed (though the actual %" markers themseves are removed.)
|
||||
.TP
|
||||
.B 'l'
|
||||
causes \fBRemind\fR to use VT100 line-drawing characters to draw
|
||||
@@ -222,8 +224,14 @@ regardless of the \fIdelta\fR supplied for each reminder.
|
||||
.TP
|
||||
.B \-t\fR\fIn\fR
|
||||
If you supply a number \fIn\fR after the \fB\-t\fR option, then
|
||||
\fBRemind\fR pretends that each non-expired reminder has a \fIdelta\fR
|
||||
of \fIn\fR days and triggers reminders accordingly.
|
||||
\fBRemind\fR pretends that echo \fBREM\fR command has a delta
|
||||
of \+\+\fIn\fR, regardles of any existing delta.
|
||||
.TP
|
||||
.B \-tz\fR
|
||||
If you supply the letter \fBz\fR after the \fB\-t\fR option, then
|
||||
\fBRemind\fR sets all REM statements' deltas to zero, regardless of the
|
||||
value supplied in the REM statement itself. In effect, this disables
|
||||
all deltas of the form \fB\+\fIn\fR and \fB\+\+\fIn\fR.
|
||||
.TP
|
||||
.B \-tt\fR[\fIn\fR]
|
||||
The \fB-tt\fR option causes \fBRemind\fR to assume a default delta of
|
||||
@@ -328,6 +336,18 @@ processes with the above technique. So be very careful. Because all
|
||||
shell and whitespace characters are escaped, the program you execute
|
||||
with the \fB\-k\fR option must be prepared to handle the entire
|
||||
message as a single argument.
|
||||
.PP
|
||||
If you follow the \fB\-k\fR option with a colon, then the command is applied
|
||||
only to queued timed reminders. Normal reminders are handled as usual.
|
||||
In the above example, if you want normal reminders to simply be displayed
|
||||
as usual, but queued reminders to be sent to notify-send, you could use:
|
||||
.PP
|
||||
.nf
|
||||
remind '\-k:notify-send %s &' ...
|
||||
.fi
|
||||
.PP
|
||||
You use both \fB\-k\fR\fIcmd1\fR and \fB\-k:\fR\fIcmd2\fR to use different
|
||||
commands for queued versus non-queued reminders.
|
||||
.RE
|
||||
.TP
|
||||
\fB\-z\fR[\fIn\fR] Runs \fBRemind\fR in the daemon mode. If \fIn\fR
|
||||
@@ -1006,7 +1026,7 @@ By comparison, if we had used "\-\-1", the reminder would be triggered on
|
||||
the last day of the month, regardless of the \fBOMIT\fR.
|
||||
.PP
|
||||
If you locally omit weekdays but also have globally-omitted weekdays, then
|
||||
the list of ommitted weekdays is the union of the two. Consider this
|
||||
the list of omitted weekdays is the union of the two. Consider this
|
||||
example:
|
||||
.PP
|
||||
.nf
|
||||
@@ -2565,6 +2585,28 @@ by \fBREM\fR commands; triggers in \fBIFTRIG\fR commands do
|
||||
not affect it.
|
||||
.RE
|
||||
.TP
|
||||
.B $ParseUntriggered
|
||||
A flag indicating whether or not \fBRemind\fR should fully parse \fBREM\fR
|
||||
statements that are not triggered. 0 means to skip parsing them and 1
|
||||
(the default) means to parse them.
|
||||
.PP
|
||||
.RS
|
||||
For example, if we have the following \fBREM\fR statement:
|
||||
.PP
|
||||
.nf
|
||||
REM 2020-01-01 MSG ["bad_expression" * 2]
|
||||
.fi
|
||||
.PP
|
||||
Then by default, \fBRemind\fR will fully parse the line and issue
|
||||
a "Type mismatch" error even if the reminder is not triggered. However,
|
||||
if \fB$ParseUntriggered\fR is set to 0, then \fBRemind\fR will not
|
||||
issue the error except on 2020-01-01, when the reminder is triggered.
|
||||
.PP
|
||||
Setting \fB$ParseUntriggered\fR to 0 may in some cases slightly
|
||||
improve performance, at the risk of not catching errors until a
|
||||
reminder is triggered.
|
||||
.RE
|
||||
.TP
|
||||
.B $PrefixLineNo (read-only)
|
||||
If non-zero, then the \fB\-l\fR option was supplied on the command line.
|
||||
.TP
|
||||
@@ -3074,6 +3116,16 @@ Support for Hebrew dates - see the section "THE HEBREW CALENDAR"
|
||||
.B hour(tq_time)
|
||||
Returns the hour component of \fItime\fR.
|
||||
.TP
|
||||
.B htmlescape(s_str)
|
||||
Returns a modified copy of \fIstr\fR where "<" is replaced with
|
||||
"<"; ">" is replaced with ">" and "&" is replaced with "&"
|
||||
.TP
|
||||
.B htmlstriptags(s_str)
|
||||
Returns a modified copy of \fIstr\fR where HTML tags are stripped
|
||||
out. The stripping algorithm is fairly naive; the function starts
|
||||
stripping characters when it encounters a "<" and it stops stripping
|
||||
when it encounters a ">".
|
||||
.TP
|
||||
.B iif(si_test1, x_arg1, [si_test2, x_arg2,...], x_default)
|
||||
If \fItest1\fR is not zero or the null string, returns \fIarg1\fR.
|
||||
Otherwise, if \fItest2\fR is not zero or the null string, returns
|
||||
@@ -3236,14 +3288,31 @@ is supplied, only the date component is used.
|
||||
Returns the time of "nautical twilight" on the specified \fIdate\fR. If
|
||||
\fIdate\fR is omitted, defaults to \fBtoday()\fR.
|
||||
.TP
|
||||
.B nonomitted(dq_start, dq_end [,s_wkday...])
|
||||
.B nonomitted(dq_start, dq_end [, i_step] [,s_wkday...])
|
||||
This function returns the number of \fInon-\fRomitted days between
|
||||
\fIstart\fR and \fIend\fR. If \fIstart\fR is non-omitted, then it is
|
||||
counted. \fIend\fR is never counted.
|
||||
.RS
|
||||
.PP
|
||||
Note that \fIend\fR must be greater than or equal to \fIstart\fR or an
|
||||
error is reported. In addition to using the global OMIT context, you
|
||||
Note that if \fIend\fR is less than \ffIstart\fR, the arguments
|
||||
are effectively swapped, so counting always begins from the older
|
||||
date.
|
||||
.PP
|
||||
If the third argument to \fBnonomitted\fR is an \fBINT\fR, then it must
|
||||
be greater than zero, and is consider to be the \fIstep\fR by which
|
||||
\fBnonomitted\fR counts. For example the following expression:
|
||||
.PP
|
||||
.nf
|
||||
nonomitted('2023-07-01', '2023-07-29', 7)
|
||||
.fi
|
||||
.PP
|
||||
returns the number of non-omitted Saturdays from 2023-07-01 up to
|
||||
(but not including) 2023-07-29. (Both 2023-07-01 and 2023-07-29 are
|
||||
Saturdays.)
|
||||
.PP
|
||||
If no \fIstep\fR argument is supplied, then a step of 1 is used.
|
||||
.PP
|
||||
In addition to using the global OMIT context, you
|
||||
can supply additional arguments that are names of weekdays to be
|
||||
omitted. However, in a \fBREM\fR command, any local \fBOMITFUNC\fR
|
||||
clause is \fInot\fR taken into account by this function.
|
||||
@@ -3464,10 +3533,13 @@ will set \fBa\fR to:
|
||||
.fi
|
||||
|
||||
.TP
|
||||
.B slide(d_start, i_amt [,s_wkday...])
|
||||
.B slide(d_start, i_amt [, i_step] [,s_wkday...])
|
||||
This function is the inverse of \fBnonomitted\fR. It adds \fIamt\fR
|
||||
days (which can be negative) to \fIstart\fR, \fInot counting omitted days\fR.
|
||||
The optional \fIwkday\fR arguments are additional weekday names to omit.
|
||||
(which can be negative) chunks of \fIstep\fR days to \fIstart\fR,
|
||||
\fInot counting omitted days\fR. If \fIstep\fR is not supplied, then
|
||||
it is assumed to be 1. Note that only every \fIstep\fRth day is
|
||||
tested to see if it is omitted. The optional \fIwkday\fR arguments
|
||||
are additional weekday names to omit.
|
||||
.RS
|
||||
.PP
|
||||
Consider this example:
|
||||
@@ -3487,6 +3559,26 @@ May 16 and 17. You can go backwards, too, so:
|
||||
.fi
|
||||
.PP
|
||||
takes \fIa\fR back to 2009-05-13.
|
||||
.PP
|
||||
Now consider this example:
|
||||
.PP
|
||||
.nf
|
||||
OMIT 14 May 2009
|
||||
SET a slide('2009-05-07', 2, 7)
|
||||
.fi
|
||||
.PP
|
||||
This sets \fIa\fR to '2009-05-28' because we skip ahead two weeks, not
|
||||
counting a week where the day we land on happens to be omitted. Contrast with
|
||||
this:
|
||||
.PP
|
||||
.nf
|
||||
OMIT 13 May 2009
|
||||
SET a slide('2009-05-07', 2, 7)
|
||||
.fi
|
||||
.PP
|
||||
which sets \fIa\fR to '2009-05-21'. Although 2009-05-13 is omitted, we
|
||||
don't "land" on it as we step forward in chunks of 7 days, so we never
|
||||
see that it is omitted.
|
||||
.RE
|
||||
.TP
|
||||
.B soleq(i_which [, dqi_start])
|
||||
@@ -4065,15 +4157,30 @@ You cannot use expression-pasting to determine the type (\fBMSG\fR,
|
||||
\fBCAL\fR, etc.) of a \fBREM\fR command. You can paste expressions
|
||||
before and after the \fBMSG\fR, etc. keywords, but cannot do something like
|
||||
this:
|
||||
.RS
|
||||
.PP
|
||||
.nf
|
||||
REM ["12 Nov 1993 AT 13:05 " + "MSG" + " BOO!"]
|
||||
REM ["12 Nov 1993 AT 13:05 " + "MSG" + " BOO!"]
|
||||
.fi
|
||||
.PP
|
||||
.B COMMON PITFALLS IN EXPRESSION PASTING
|
||||
However, as an escape hatch, the sequence \fBSPECIAL\fR \fItype\fR
|
||||
means the same thing as just \fItype\fR where \fItype\fR is one
|
||||
of MSG, MSF, RUN, CAL, PS and PSFILE. This lets you do something
|
||||
like this:
|
||||
.PP
|
||||
Remember, when pasting in expressions, that extra spaces are not
|
||||
inserted. Thus, something like:
|
||||
.nf
|
||||
SET type "MSG"
|
||||
REM 12 Nov 2024 SPECIAL [type] Hello
|
||||
.fi
|
||||
.PP
|
||||
You can use this to control the types of your reminders based on variables
|
||||
you set, how Remind is invoked, etc.
|
||||
.RE
|
||||
.PP
|
||||
.B COMMON PITFALLS WITH EXPRESSION PASTING
|
||||
.PP
|
||||
Remember that extra spaces are not inserted when an expression is
|
||||
pasted. Thus, something like:
|
||||
.PP
|
||||
.nf
|
||||
REM[expr]MSG[expr]
|
||||
@@ -4179,7 +4286,7 @@ you define a function taking no parameters. Here are some examples:
|
||||
.nf
|
||||
FSET double(x) 2*x
|
||||
FSET yeardiff(date1, date2) year(date1) - year(date2)
|
||||
FSET since(x) ord(year(trigdate())\-x)
|
||||
FSET since(x) ord($Ty \- x)
|
||||
.fi
|
||||
.PP
|
||||
The last function is useful in birthday reminders. For example:
|
||||
@@ -4194,6 +4301,12 @@ Dean was born in 1984. The above example, on 1 November 1992, would print:
|
||||
Dean's 8th birthday is today.
|
||||
.fi
|
||||
.PP
|
||||
Similarly, the function is useful in anniversary reminders. For example:
|
||||
.PP
|
||||
.nf
|
||||
REM 4 June MSG [since(1989)] anniversary of the Tiananmen Square massacre
|
||||
.fi
|
||||
.PP
|
||||
Notes:
|
||||
.TP
|
||||
o
|
||||
@@ -5501,7 +5614,7 @@ after the WEEK keyword.
|
||||
.PP
|
||||
.SH MISCELLANEOUS
|
||||
.PP
|
||||
.B COMMAND ABBREVIATIONS
|
||||
.B COMMAND AND KEYWORD ABBREVIATIONS
|
||||
.PP
|
||||
The following tokens can be abbreviated:
|
||||
.TP
|
||||
@@ -5528,6 +5641,9 @@ o
|
||||
\fBINCLUDE\fR --> \fBINC\fR
|
||||
.TP
|
||||
o
|
||||
\fBMAYBE-UNCOMPUTABLE\fR --> \fBMAYBE\fR
|
||||
.TP
|
||||
o
|
||||
\fBSCANFROM\fR --> \fBSCAN\fR
|
||||
.PP
|
||||
.B NIFTY EXAMPLES
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
.SH NAME
|
||||
tkremind \- graphical front-end to Remind calendar program
|
||||
.SH SYNOPSIS
|
||||
.B tkremind \fR[\fIoptions\fR] [\fIread_file\fR] [\fIwrite_file\fR] [\fIconfig_file\fR]
|
||||
.B tkremind \fR[\fIoptions\fR] [\fIread_file\fR [\fIwrite_file\fR [\fIconfig_file\fR]]]
|
||||
.SH DESCRIPTION
|
||||
\fBTkRemind\fR is a graphical front-end to the \fBRemind\fR program.
|
||||
It provides a friendly graphical interface which allows you to view
|
||||
|
||||
@@ -687,7 +687,7 @@ if ($Options{help}) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (-t STDIN) {
|
||||
if (-t STDIN) { ## no critic
|
||||
print STDERR "$TIDY_PROGNAME: Input should not come from a terminal.\n\n";
|
||||
usage(1);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ my $settings = {
|
||||
numbers_on_left => 0,
|
||||
small_calendars => 0,
|
||||
fill_entire_page => 0,
|
||||
|
||||
wrap_calendar => 0,
|
||||
media => 'Letter',
|
||||
width => 0,
|
||||
height => 0,
|
||||
@@ -86,6 +86,7 @@ Options:
|
||||
--media=MEDIA, -mMEDIA Size for specified media
|
||||
--width=W, -wW Specify media width in 1/72nds of an inch
|
||||
--height=H, -hH Specify media height in 1/72nds of an inch
|
||||
--wrap, -y Make calendar fit in at most 5 rows
|
||||
--title-font=FONT Specify font for calendar title
|
||||
--header-font=FONT Specify font for weekday names
|
||||
--daynum-font=FONT Specify font for day numbers
|
||||
@@ -114,6 +115,7 @@ my $ret = GetOptions('landscape|l' => \$settings->{landscape},
|
||||
'fill-page|e' => \$settings->{fill_entire_page},
|
||||
'media|m=s' => \$settings->{media},
|
||||
'width|w=i' => \$settings->{width},
|
||||
'wrap|y' => \$settings->{wrap_calendar},
|
||||
'height|h=i' => \$settings->{height},
|
||||
'title-font=s' => \$settings->{title_font},
|
||||
'header-font=s' => \$settings->{header_font},
|
||||
@@ -175,7 +177,7 @@ if ($settings->{landscape}) {
|
||||
}
|
||||
|
||||
# Don't read from a terminal
|
||||
if (-t STDIN) {
|
||||
if (-t STDIN) { ## no critic
|
||||
print STDERR "I can't read data from a terminal. Please run like this:\n";
|
||||
print STDERR " remind -pp [options] filename | $me [options] > out.pdf\n";
|
||||
exit(1);
|
||||
@@ -249,20 +251,21 @@ sub set_media
|
||||
sub set_media_from_file
|
||||
{
|
||||
my ($fn) = @_;
|
||||
if (!open(IN, '<', $fn)) {
|
||||
my $IN;
|
||||
if (!open($IN, '<', $fn)) {
|
||||
return 0;
|
||||
}
|
||||
while(<IN>) {
|
||||
while(<$IN>) {
|
||||
chomp;
|
||||
s/^\s+//;
|
||||
s/\s+$//;
|
||||
next if ($_ eq '');
|
||||
next if ($_ =~ /^#/);
|
||||
my $m = $_;
|
||||
close(IN);
|
||||
close($IN);
|
||||
return set_media($m);
|
||||
}
|
||||
close(IN);
|
||||
close($IN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -430,6 +433,14 @@ The default is 36.
|
||||
The size of the margin at the right of the page in 1/72ths of an inch.
|
||||
The default is 36.
|
||||
|
||||
=item --wrap, -y
|
||||
|
||||
Modify the calendar so that if it would normally require 6 rows to print,
|
||||
then the last day (or last two days, as needed) are moved to the
|
||||
first row of the calendar, and adjust the small calendar positions
|
||||
as needed. This results in a calendar that only requires 5 rows, but
|
||||
with the last day or two appearing in the I<first> row.
|
||||
|
||||
=item --verbose, -v
|
||||
|
||||
Print (on STDERR) the name of the month and year for each month that
|
||||
|
||||
@@ -110,7 +110,6 @@ sub read_one_month
|
||||
$self->{daysinnextmonth} = 0;
|
||||
$self->{prevmonthyear} = 0;
|
||||
$self->{nextmonthyear} = 0;
|
||||
|
||||
for (my $i=0; $i<=31; $i++) {
|
||||
$self->{entries}->[$i] = [];
|
||||
}
|
||||
@@ -134,7 +133,7 @@ sub read_one_month
|
||||
$line = $in->getline();
|
||||
chomp($line);
|
||||
if ($line =~ /^\S+ \S+ \S+ \S+ \S+ \S+ \S+$/) {
|
||||
@{$self->{daynames}} = map { s/_/ /g; $_; } (split(/ /, $line));
|
||||
@{$self->{daynames}} = map { s/_/ /g; $_; } (split(/ /, $line)); ## no critic
|
||||
} else {
|
||||
return (undef, "Cannot interpret line: $line");
|
||||
}
|
||||
@@ -213,7 +212,7 @@ hash keys found in the newer "remind -pp" JSON output.
|
||||
sub parse_oldstyle_line
|
||||
{
|
||||
my ($self, $line) = @_;
|
||||
return undef unless $line =~ m|^(\d+)/(\d+)/(\d+) (\S+) (\S+) (\S+) (\S+) (.*)$|;
|
||||
return unless $line =~ m|^(\d+)/(\d+)/(\d+) (\S+) (\S+) (\S+) (\S+) (.*)$|;
|
||||
|
||||
my $hash = {
|
||||
date => "$1-$2-$3",
|
||||
@@ -244,6 +243,143 @@ sub parse_oldstyle_line
|
||||
return $hash;
|
||||
}
|
||||
|
||||
=head2 setup_daymap
|
||||
|
||||
Set up the array that maps ($row, $col) to day number (or -1
|
||||
for rows/cols out of range.)
|
||||
|
||||
=cut
|
||||
sub setup_daymap
|
||||
{
|
||||
my ($self, $settings) = @_;
|
||||
# First column
|
||||
my $first_col = $self->{firstwkday};
|
||||
if ($self->{mondayfirst}) {
|
||||
$first_col--;
|
||||
if ($first_col < 0) {
|
||||
$first_col = 6;
|
||||
}
|
||||
}
|
||||
|
||||
# Last column
|
||||
my $last_col = ($first_col + $self->{daysinmonth} - 1) % 7;
|
||||
|
||||
# Number of rows
|
||||
my $rows = 1;
|
||||
my $last_day_on_row = 7 - $first_col;
|
||||
while ($last_day_on_row < $self->{daysinmonth}) {
|
||||
$last_day_on_row += 7;
|
||||
$rows++;
|
||||
}
|
||||
|
||||
# Add a row for small calendars if necessary
|
||||
if (($settings->{small_calendars} != 0) && ($first_col == 0) && ($last_col == 6)) {
|
||||
$rows++;
|
||||
$self->{extra_row} = 1;
|
||||
} else {
|
||||
$self->{extra_row} = 0;
|
||||
}
|
||||
$self->{rows} = $rows;
|
||||
$self->{daymap} = [];
|
||||
$self->{first_col} = $first_col;
|
||||
$self->{last_col} = $last_col;
|
||||
for (my $row=0; $row<$rows; $row++) {
|
||||
for (my $col=0; $col < 7; $col++) {
|
||||
$self->{daymap}->[$row]->[$col] = -1;
|
||||
}
|
||||
}
|
||||
$self->{nextcal_row} = -1;
|
||||
$self->{prevcal_row} = -1;
|
||||
$self->{nextcal_col} = 6;
|
||||
$self->{prevcal_col} = 0;
|
||||
# Figure out where to draw the small calendars
|
||||
my $extra_row = $self->{extra_row};
|
||||
if ($settings->{small_calendars} == 1) {
|
||||
if ($last_col <= 4 || ($last_col == 6 && $extra_row)) {
|
||||
$self->{prevcal_row} = $rows-1;
|
||||
$self->{prevcal_col} = 5;
|
||||
$self->{nextcal_row} = $rows-1;
|
||||
$self->{nextcal_col} = 6;
|
||||
} else {
|
||||
$self->{prevcal_row} = 0;
|
||||
$self->{prevcal_col} = 0;
|
||||
$self->{nextcal_row} = 0;
|
||||
$self->{nextcal_col} = 1;
|
||||
}
|
||||
} elsif ($settings->{small_calendars} == 2) {
|
||||
if ($first_col >= 2) {
|
||||
$self->{prevcal_row} = 0;
|
||||
$self->{prevcal_col} = 0;
|
||||
$self->{nextcal_row} = 0;
|
||||
$self->{nextcal_col} = 1;
|
||||
} else {
|
||||
$self->{prevcal_row} = $rows-1;
|
||||
$self->{prevcal_col} = 5;
|
||||
$self->{nextcal_row} = $rows-1;
|
||||
$self->{nextcal_col} = 6;
|
||||
}
|
||||
} elsif ($settings->{small_calendars} == 3) {
|
||||
if ($first_col >= 1 && $last_col <= 5) {
|
||||
$self->{prevcal_row} = 0;
|
||||
$self->{prevcal_col} = 0;
|
||||
$self->{nextcal_row} = $rows-1;
|
||||
$self->{nextcal_col} = 6;
|
||||
} else {
|
||||
if ($last_col <= 4 || ($last_col == 6 && $extra_row)) {
|
||||
$self->{prevcal_row} = $rows-1;
|
||||
$self->{prevcal_col} = 5;
|
||||
$self->{nextcal_row} = $rows-1;
|
||||
$self->{nextcal_col} = 6;
|
||||
} else {
|
||||
$self->{prevcal_row} = 0;
|
||||
$self->{prevcal_col} = 0;
|
||||
$self->{nextcal_row} = 0;
|
||||
$self->{nextcal_col} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $col = $first_col;
|
||||
my $row = 0;
|
||||
my $day = 1;
|
||||
while ($day <= $self->{daysinmonth}) {
|
||||
$self->{daymap}->[$row]->[$col] = $day;
|
||||
$day++;
|
||||
$col++;
|
||||
if ($col > 6) {
|
||||
$row++;
|
||||
$col = 0;
|
||||
}
|
||||
}
|
||||
|
||||
# Check if we should wrap the calendar
|
||||
if ($self->{rows} == 6 && $settings->{wrap_calendar}) {
|
||||
# Move everything in the last row to the first row
|
||||
my $occupied_col = 0;
|
||||
for (my $col=0; $col<7; $col++) {
|
||||
if ($self->{daymap}->[5]->[$col] > 0) {
|
||||
$self->{daymap}->[0]->[$col] = $self->{daymap}->[5]->[$col];
|
||||
$occupied_col = $col;
|
||||
} else {
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ($settings->{small_calendars}) {
|
||||
$self->{prevcal_row} = 0;
|
||||
$self->{prevcal_col} = $occupied_col+1;
|
||||
$self->{nextcal_row} = 0;
|
||||
$self->{nextcal_col} = $occupied_col+2;
|
||||
for (my $col = 6; $col > 0; $col--) {
|
||||
if ($self->{daymap}->[0]->[$col] < 0) {
|
||||
$self->{nextcal_col} = $col;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
$self->{rows} = 5;
|
||||
}
|
||||
}
|
||||
|
||||
=head2 read_one_month_pp($in, $specials_accepted)
|
||||
|
||||
This function reads one month's worth of data from the file handle
|
||||
@@ -329,6 +465,7 @@ sub render
|
||||
{
|
||||
my ($self, $cr, $settings) = @_;
|
||||
|
||||
$self->setup_daymap($settings);
|
||||
$self->{horiz_lines} = [];
|
||||
$cr->set_line_cap('square');
|
||||
my $so_far = $self->draw_title($cr, $settings);
|
||||
@@ -347,111 +484,25 @@ sub render
|
||||
$self->{remaining_space} = $settings->{height} - $settings->{margin_bottom} - $so_far;
|
||||
|
||||
$self->{minimum_row_height} = $self->{remaining_space} / 9;
|
||||
# First column
|
||||
my $first_col = $self->{firstwkday};
|
||||
if ($self->{mondayfirst}) {
|
||||
$first_col--;
|
||||
if ($first_col < 0) {
|
||||
$first_col = 6;
|
||||
}
|
||||
}
|
||||
|
||||
# Last column
|
||||
my $last_col = ($first_col + $self->{daysinmonth} - 1) % 7;
|
||||
|
||||
# Number of rows
|
||||
my $rows = 1;
|
||||
my $last_day_on_row = 7 - $first_col;
|
||||
while ($last_day_on_row < $self->{daysinmonth}) {
|
||||
$last_day_on_row += 7;
|
||||
$rows++;
|
||||
}
|
||||
|
||||
my $extra_row = 0;
|
||||
# Add a row for small calendars if necessary
|
||||
if (($settings->{small_calendars} != 0) && ($first_col == 0) && ($last_col == 6)) {
|
||||
$rows++;
|
||||
$extra_row++;
|
||||
}
|
||||
|
||||
# Figure out where to draw the small calendars
|
||||
my $prevcal_top = 0;
|
||||
my $nextcal_top = 0;
|
||||
my $prevcal_bottom = 0;
|
||||
my $nextcal_bottom = 0;
|
||||
|
||||
if ($settings->{small_calendars} == 1) {
|
||||
if ($last_col <= 4 || ($last_col == 6 && $extra_row)) {
|
||||
$prevcal_bottom = 1;
|
||||
$nextcal_bottom = 1;
|
||||
} else {
|
||||
$prevcal_top = 1;
|
||||
$nextcal_top = 1;
|
||||
}
|
||||
} elsif ($settings->{small_calendars} == 2) {
|
||||
if ($first_col >= 2) {
|
||||
$prevcal_top = 1;
|
||||
$nextcal_top = 1;
|
||||
} else {
|
||||
$prevcal_bottom = 1;
|
||||
$nextcal_bottom = 1;
|
||||
}
|
||||
} elsif ($settings->{small_calendars} == 3) {
|
||||
if ($first_col >= 1 && $last_col <= 5) {
|
||||
$prevcal_top = 1;
|
||||
$nextcal_bottom = 1;
|
||||
} else {
|
||||
if ($last_col <= 4 || ($last_col == 6 && $extra_row)) {
|
||||
$prevcal_bottom = 1;
|
||||
$nextcal_bottom = 1;
|
||||
} else {
|
||||
$prevcal_top = 1;
|
||||
$nextcal_top = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Row height if we are filling the page
|
||||
$self->{row_height} = $self->{remaining_space} / $rows;
|
||||
$self->{row_height} = $self->{remaining_space} / $self->{rows};
|
||||
|
||||
my ($start_col, $start_day);
|
||||
for (my $row = 0; $row < $rows; $row++) {
|
||||
if ($row == 0) {
|
||||
$start_day = 1;
|
||||
$start_col = $first_col;
|
||||
} else {
|
||||
$start_col = 0;
|
||||
}
|
||||
for (my $row = 0; $row < $self->{rows}; $row++) {
|
||||
my $old_so_far = $so_far;
|
||||
$so_far = $self->draw_row($cr, $settings, $so_far, $row, $start_day, $start_col);
|
||||
$start_day += 7 - $start_col;
|
||||
$so_far = $self->draw_row($cr, $settings, $so_far, $row);
|
||||
push(@{$self->{horiz_lines}}, $so_far);
|
||||
if ($row == 0) {
|
||||
if ($prevcal_top) {
|
||||
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 0, $so_far - $old_so_far, $settings);
|
||||
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
|
||||
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
|
||||
$settings, $self->{prevmonthname}, $self->{daysinprevmonth}, ($first_col + 35 - $self->{daysinprevmonth}) % 7);
|
||||
}
|
||||
if ($nextcal_top) {
|
||||
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 1, $so_far - $old_so_far, $settings);
|
||||
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
|
||||
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
|
||||
$settings, $self->{nextmonthname}, $self->{daysinnextmonth}, ($last_col + 1) % 7);
|
||||
}
|
||||
} elsif ($row == $rows-1) {
|
||||
if ($prevcal_bottom) {
|
||||
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 5, $so_far - $old_so_far, $settings);
|
||||
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
|
||||
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
|
||||
$settings, $self->{prevmonthname}, $self->{daysinprevmonth}, ($first_col + 35 - $self->{daysinprevmonth}) % 7);
|
||||
}
|
||||
if ($nextcal_bottom) {
|
||||
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 6, $so_far - $old_so_far, $settings);
|
||||
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
|
||||
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
|
||||
$settings, $self->{nextmonthname}, $self->{daysinnextmonth}, ($last_col + 1) % 7);
|
||||
}
|
||||
if ($row == $self->{prevcal_row}) {
|
||||
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, $self->{prevcal_col}, $so_far - $old_so_far, $settings);
|
||||
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
|
||||
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
|
||||
$settings, $self->{prevmonthname}, $self->{daysinprevmonth}, ($self->{first_col} + 35 - $self->{daysinprevmonth}) % 7);
|
||||
}
|
||||
if ($row == $self->{nextcal_row}) {
|
||||
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, $self->{nextcal_col}, $so_far - $old_so_far, $settings);
|
||||
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
|
||||
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
|
||||
$settings, $self->{nextmonthname}, $self->{daysinnextmonth}, ($self->{last_col} + 1) % 7);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,23 +546,18 @@ calendar row.
|
||||
=cut
|
||||
sub draw_row
|
||||
{
|
||||
my ($self, $cr, $settings, $so_far, $row, $start_day, $start_col) = @_;
|
||||
my ($self, $cr, $settings, $so_far, $row) = @_;
|
||||
|
||||
my $col = $start_col;
|
||||
my $day = $start_day;
|
||||
my $height = 0;
|
||||
|
||||
# Preview them to figure out the row height...
|
||||
if (!$settings->{fill_entire_page}) {
|
||||
while ($col < 7) {
|
||||
for (my $col=0; $col<7; $col++) {
|
||||
my $day = $self->{daymap}->[$row]->[$col];
|
||||
next if ($day < 1);
|
||||
my $h = $self->draw_day($cr, $settings, $so_far, $day, $col, 0);
|
||||
$height = $h if ($h > $height);
|
||||
$day++;
|
||||
$col++;
|
||||
last if ($day > $self->{daysinmonth});
|
||||
}
|
||||
$col = $start_col;
|
||||
$day = $start_day;
|
||||
} else {
|
||||
$height = $self->{row_height} - $settings->{border_size} * 2;
|
||||
}
|
||||
@@ -520,10 +566,10 @@ sub draw_row
|
||||
$height = $self->{minimum_row_height};
|
||||
}
|
||||
# Now draw for real
|
||||
while ($col < 7 && $day <= $self->{daysinmonth}) {
|
||||
for (my $col=0; $col<7; $col++) {
|
||||
my $day = $self->{daymap}->[$row]->[$col];
|
||||
next if ($day < 1);
|
||||
$self->draw_day($cr, $settings, $so_far, $day, $col, $height);
|
||||
$day++;
|
||||
$col++;
|
||||
}
|
||||
|
||||
return $so_far + $height + $settings->{border_size};
|
||||
@@ -908,7 +954,7 @@ sub create_from_stream
|
||||
return(undef, 'Unable to parse JSON stream');
|
||||
}
|
||||
|
||||
=head2 Remind::PDF::Multi->create_from_stream($json, $specials_accepted)
|
||||
=head2 Remind::PDF::Multi->create_from_json($json, $specials_accepted)
|
||||
|
||||
This method takes data from a JSON string <$json>. C<$specials_accepted>
|
||||
is a hashref of SPECIAL reminder types to accept; the key is the name of the
|
||||
|
||||
@@ -240,6 +240,9 @@ set Option(PrintOrient) landscape
|
||||
set OptDescr(PrintFill) "(0/1) If 1, fill entire page when printing"
|
||||
set Option(PrintFill) 1
|
||||
|
||||
set OptDescr(WrapCal) "(0/1) If 1, make printed calendars occupy at most 5 rows"
|
||||
set Option(WrapCal) 0
|
||||
|
||||
set OptDescr(PrintDaysRight) "(0/1) If 1, put day numbers in the top-right of each calendar box"
|
||||
set Option(PrintDaysRight) 1
|
||||
|
||||
@@ -1290,6 +1293,7 @@ proc DoPrint {} {
|
||||
radiobutton .p.portrait -text "Portrait" -variable Option(PrintOrient) -value portrait
|
||||
|
||||
checkbutton .p.fill -text "Fill page" -variable Option(PrintFill)
|
||||
checkbutton .p.wrap -text "Use at most 5 rows (PDF only)" -variable Option(WrapCal)
|
||||
checkbutton .p.right -text "Day numbers at top-right" -variable Option(PrintDaysRight)
|
||||
checkbutton .p.encoding -text "ISO 8859-1 PostScript encoding" -variable Option(PrintEncoding)
|
||||
checkbutton .p.calendars -text "Print small calendars" -variable Option(PrintSmallCalendars)
|
||||
@@ -1300,12 +1304,14 @@ proc DoPrint {} {
|
||||
if {$HaveRem2PDF} {
|
||||
pack .p.f1 .p.ff .p.f2 .p.f2a .p.f3 .p.f3a \
|
||||
-side top -fill both -expand 1 -anchor w
|
||||
pack .p.fill .p.wrap .p.right .p.encoding .p.calendars -in .p.f3a \
|
||||
-side top -anchor w -fill none -expand 0
|
||||
} else {
|
||||
pack .p.f1 .p.f2 .p.f2a .p.f3 .p.f3a \
|
||||
-side top -fill both -expand 1 -anchor w
|
||||
}
|
||||
pack .p.fill .p.right .p.encoding .p.calendars -in .p.f3a \
|
||||
pack .p.fill .p.right .p.encoding .p.calendars -in .p.f3a \
|
||||
-side top -anchor w -fill none -expand 0
|
||||
}
|
||||
pack .p.f4 -side top -fill both -expand 1 -anchor w
|
||||
pack .p.f11 .p.f12 -in .p.f1 -side top -fill none -expand 0 -anchor w
|
||||
pack .p.tofile .p.filename .p.browse -in .p.f11 -side left -fill none -expand 0 -anchor w
|
||||
@@ -1398,6 +1404,11 @@ proc DoPrint {} {
|
||||
}
|
||||
}
|
||||
|
||||
if {$Option(WrapCal)} {
|
||||
if {$Option(PrintFormat) == "pdf"} {
|
||||
append cmd " --wrap"
|
||||
}
|
||||
}
|
||||
if {$Option(PrintOrient) == "landscape"} {
|
||||
append cmd " -l"
|
||||
}
|
||||
@@ -3326,7 +3337,9 @@ proc EditableEnter { w } {
|
||||
set c [$w tag cget $ctag -foreground]
|
||||
}
|
||||
if {"$c" != ""} {
|
||||
$w tag configure $tag -underline 1 -underlinefg $c
|
||||
$w tag configure $tag -underline 1
|
||||
# underlinefg not supported on older versions of Tk
|
||||
eval { $w tag configure $tag -underlinefg $c }
|
||||
} else {
|
||||
$w tag configure $tag -underline 1
|
||||
}
|
||||
@@ -3633,7 +3646,9 @@ proc DoShadeSpecial { n r g b } {
|
||||
#***********************************************************************
|
||||
proc DoMoonSpecial { n stuff fntag day } {
|
||||
set msg ""
|
||||
set num [scan $stuff "%d %d %d %s" phase junk1 junk2 msg]
|
||||
# Yes, this is gross, but the odds of ctrl-A appearing
|
||||
# in the text associated with a MOON are small.
|
||||
set num [scan $stuff {%d %d %d %[^]} phase junk1 junk2 msg]
|
||||
if {$num < 1} {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1811,8 +1811,12 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
DBufFree(&buf);
|
||||
if (tok.type == T_Empty || tok.type == T_Comment) {
|
||||
r = OK;
|
||||
if (trig.addomit) {
|
||||
r = AddGlobalOmit(LastTriggerDate);
|
||||
}
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
return r;
|
||||
}
|
||||
if (tok.type != T_RemType || tok.val == SAT_TYPE) {
|
||||
FreeTrig(&trig);
|
||||
@@ -1830,6 +1834,10 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
DBufFree(&buf);
|
||||
}
|
||||
trig.typ = tok.val;
|
||||
|
||||
/* Convert some SPECIALs back to plain types */
|
||||
FixSpecialType(&trig);
|
||||
|
||||
if (trig.typ == MSG_TYPE ||
|
||||
trig.typ == CAL_TYPE ||
|
||||
trig.typ == MSF_TYPE) {
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
/* Define if your <sys/time.h> declares struct tm. */
|
||||
#undef TM_IN_SYS_TIME
|
||||
|
||||
/* Define if you have the <sys/file.h> header file. */
|
||||
#undef HAVE_SYS_FILE_H
|
||||
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
|
||||
85
src/dorem.c
85
src/dorem.c
@@ -123,8 +123,12 @@ int DoRem(ParsePtr p)
|
||||
}
|
||||
StrnCpy(trig.passthru, DBufValue(&buf), PASSTHRU_LEN);
|
||||
DBufFree(&buf);
|
||||
}
|
||||
trig.typ = tok.val;
|
||||
}
|
||||
trig.typ = tok.val;
|
||||
|
||||
/* Convert some SPECIALs back to plain types */
|
||||
FixSpecialType(&trig);
|
||||
|
||||
dse = LastTriggerDate;
|
||||
if (!LastTrigValid || PurgeMode) {
|
||||
FreeTrig(&trig);
|
||||
@@ -188,16 +192,18 @@ int DoRem(ParsePtr p)
|
||||
|
||||
r = OK;
|
||||
if (ShouldTriggerReminder(&trig, &tim, dse, &err)) {
|
||||
if ( (r=TriggerReminder(p, &trig, &tim, dse)) ) {
|
||||
if ( (r=TriggerReminder(p, &trig, &tim, dse, 0)) ) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
/* Parse the rest of the line to catch any potential
|
||||
expression-pasting errors */
|
||||
while (ParseChar(p, &r, 0)) {
|
||||
if (r != 0) {
|
||||
break;
|
||||
if (ParseUntriggered) {
|
||||
while (ParseChar(p, &r, 0)) {
|
||||
if (r != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -370,6 +376,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
}
|
||||
StrnCpy(trig->passthru, DBufValue(&buf), PASSTHRU_LEN);
|
||||
}
|
||||
FixSpecialType(trig);
|
||||
parsing = 0;
|
||||
break;
|
||||
|
||||
@@ -893,7 +900,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
/* Trigger the reminder if it's a RUN or MSG type. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse)
|
||||
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued)
|
||||
{
|
||||
int r, y, m, d;
|
||||
char PrioExpr[VAR_NAME_LEN+25];
|
||||
@@ -901,8 +908,21 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse)
|
||||
DynamicBuffer buf, calRow;
|
||||
DynamicBuffer pre_buf;
|
||||
char const *s;
|
||||
char const *msg_command = NULL;
|
||||
Value v;
|
||||
|
||||
if (MsgCommand) {
|
||||
msg_command = MsgCommand;
|
||||
}
|
||||
if (is_queued && QueuedMsgCommand) {
|
||||
msg_command = QueuedMsgCommand;
|
||||
}
|
||||
|
||||
/* A null command is no command */
|
||||
if (msg_command && !*msg_command) {
|
||||
msg_command = NULL;
|
||||
}
|
||||
|
||||
int red = -1, green = -1, blue = -1;
|
||||
int is_color = 0;
|
||||
|
||||
@@ -947,7 +967,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse)
|
||||
}
|
||||
/* If it's a MSG-type reminder, and no -k option was used, issue the banner. */
|
||||
if ((t->typ == MSG_TYPE || t->typ == MSF_TYPE)
|
||||
&& !DidMsgReminder && !NextMode && !MsgCommand) {
|
||||
&& !DidMsgReminder && !NextMode && !msg_command) {
|
||||
DidMsgReminder = 1;
|
||||
if (!DoSubstFromString(DBufValue(&Banner), &buf,
|
||||
DSEToday, NO_TIME) &&
|
||||
@@ -1091,7 +1111,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse)
|
||||
DBufPuts(&buf, Decolorize());
|
||||
}
|
||||
|
||||
if ((!MsgCommand && t->typ == MSG_TYPE) || t->typ == MSF_TYPE) {
|
||||
if ((!msg_command && t->typ == MSG_TYPE) || t->typ == MSF_TYPE) {
|
||||
if (DBufPutc(&buf, '\n') != OK) {
|
||||
DBufFree(&buf);
|
||||
return E_NO_MEM;
|
||||
@@ -1113,8 +1133,8 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse)
|
||||
switch(t->typ) {
|
||||
case MSG_TYPE:
|
||||
case PASSTHRU_TYPE:
|
||||
if (MsgCommand) {
|
||||
DoMsgCommand(MsgCommand, DBufValue(&buf));
|
||||
if (msg_command) {
|
||||
DoMsgCommand(msg_command, DBufValue(&buf));
|
||||
} else {
|
||||
printf("%s", DBufValue(&buf));
|
||||
}
|
||||
@@ -1182,19 +1202,28 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int dse, int *err)
|
||||
/* If "infinite delta" option is chosen, always trigger future reminders */
|
||||
if (InfiniteDelta || NextMode) return 1;
|
||||
|
||||
/* If there's a "warn" function, it overrides any deltas */
|
||||
/* If there's a "warn" function, it overrides any deltas except
|
||||
* DeltaOverride*/
|
||||
if (t->warn[0] != 0) {
|
||||
if (DeltaOffset) {
|
||||
if (dse <= DSEToday + DeltaOffset) {
|
||||
if (DeltaOverride > 0) {
|
||||
if (dse <= DSEToday + DeltaOverride) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return ShouldTriggerBasedOnWarn(t, dse, err);
|
||||
}
|
||||
|
||||
/* Zero delta */
|
||||
if (DeltaOverride < 0) {
|
||||
return dse == DSEToday;
|
||||
}
|
||||
|
||||
/* Move back by delta days, if any */
|
||||
if (t->delta != NO_DELTA) {
|
||||
if (t->delta < 0)
|
||||
if (DeltaOverride) {
|
||||
/* A positive DeltaOverride takes precedence over everything */
|
||||
dse = dse - DeltaOverride;
|
||||
} else if (t->delta != NO_DELTA) {
|
||||
if (t->delta < 0)
|
||||
dse = dse + t->delta;
|
||||
else {
|
||||
int iter = 0;
|
||||
@@ -1219,7 +1248,7 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int dse, int *err)
|
||||
}
|
||||
|
||||
/* Should we trigger the reminder? */
|
||||
return (dse <= DSEToday + DeltaOffset);
|
||||
return (dse <= DSEToday);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1466,3 +1495,25 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FixSpecialType(Trigger *t)
|
||||
{
|
||||
if (t->typ != PASSTHRU_TYPE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert SPECIAL MSG / MSF / RUN / CAL to just plain MSG / MSF / etc */
|
||||
if (!StrCmpi(t->passthru, "MSG")) {
|
||||
t->typ = MSG_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "MSF")) {
|
||||
t->typ = MSF_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "RUN")) {
|
||||
t->typ = RUN_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "CAL")) {
|
||||
t->typ = CAL_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "PS")) {
|
||||
t->typ = PS_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "PSFILE")) {
|
||||
t->typ = PSF_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
mode != CAL_MODE &&
|
||||
mode != ADVANCE_MODE &&
|
||||
t->typ != RUN_TYPE &&
|
||||
!MsgCommand) {
|
||||
!(MsgCommand && *MsgCommand)) {
|
||||
if (DBufPutc(dbuf, '\n') != OK) return E_NO_MEM;
|
||||
}
|
||||
break;
|
||||
@@ -794,7 +794,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
break;
|
||||
|
||||
case '_':
|
||||
if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || (mode != CAL_MODE && mode != ADVANCE_MODE && !MsgCommand)) {
|
||||
if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || (mode != CAL_MODE && mode != ADVANCE_MODE && !(MsgCommand && *MsgCommand))) {
|
||||
snprintf(s, sizeof(s), "%s", NL);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), " ");
|
||||
|
||||
151
src/funcs.c
151
src/funcs.c
@@ -30,10 +30,6 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_SYS_FILE_H
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
@@ -101,6 +97,8 @@ static int FHebday (func_info *);
|
||||
static int FHebmon (func_info *);
|
||||
static int FHebyear (func_info *);
|
||||
static int FHour (func_info *);
|
||||
static int FHtmlEscape (func_info *);
|
||||
static int FHtmlStriptags (func_info *);
|
||||
static int FIif (func_info *);
|
||||
static int FIndex (func_info *);
|
||||
static int FIsdst (func_info *);
|
||||
@@ -265,6 +263,8 @@ BuiltinFunc Func[] = {
|
||||
{ "hebmon", 1, 1, 0, FHebmon },
|
||||
{ "hebyear", 1, 1, 0, FHebyear },
|
||||
{ "hour", 1, 1, 1, FHour },
|
||||
{ "htmlescape", 1, 1, 1, FHtmlEscape },
|
||||
{ "htmlstriptags",1, 1, 1, FHtmlStriptags },
|
||||
{ "iif", 1, NO_MAX, 1, FIif },
|
||||
{ "index", 2, 3, 1, FIndex },
|
||||
{ "isany", 1, NO_MAX, 1, FIsAny },
|
||||
@@ -914,9 +914,14 @@ static int FAbs(func_info *info)
|
||||
|
||||
ASSERT_TYPE(0, INT_TYPE);
|
||||
v = ARGV(0);
|
||||
if (v == INT_MIN) return E_2HIGH;
|
||||
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = (v < 0) ? (-v) : v;
|
||||
v = RETVAL;
|
||||
|
||||
/* The following test is probably redundant given the test
|
||||
for v == INT_MIN above, but I'll leave it in just in case. */
|
||||
if (v < 0) return E_2HIGH;
|
||||
return OK;
|
||||
}
|
||||
@@ -1162,15 +1167,27 @@ static int FPad(func_info *info)
|
||||
if (Nargs < 4 || !ARGV(3)) {
|
||||
/* Pad on the LEFT */
|
||||
for (i=0; i<wantlen-len; i++) {
|
||||
DBufPutc(&dbuf, *s++);
|
||||
if (DBufPutc(&dbuf, *s++) != OK) {
|
||||
DBufFree(&dbuf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
if (!*s) s = ARGSTR(1);
|
||||
}
|
||||
DBufPuts(&dbuf, ARGSTR(0));
|
||||
if (DBufPuts(&dbuf, ARGSTR(0)) != OK) {
|
||||
DBufFree(&dbuf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
} else {
|
||||
/* Pad on the RIGHT */
|
||||
DBufPuts(&dbuf, ARGSTR(0));
|
||||
if (DBufPuts(&dbuf, ARGSTR(0)) != OK) {
|
||||
DBufFree(&dbuf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
for (i=0; i<wantlen-len; i++) {
|
||||
DBufPutc(&dbuf, *s++);
|
||||
if (DBufPutc(&dbuf, *s++) != OK) {
|
||||
DBufFree(&dbuf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
if (!*s) s = ARGSTR(1);
|
||||
}
|
||||
}
|
||||
@@ -2243,6 +2260,92 @@ static int FHebyear(func_info *info)
|
||||
RETVAL = y;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
/* */
|
||||
/* htmlescape - replace <. > and & by < > and & */
|
||||
/* */
|
||||
/****************************************************************/
|
||||
static int FHtmlEscape(func_info *info)
|
||||
{
|
||||
DynamicBuffer dbuf;
|
||||
char const *s;
|
||||
int r;
|
||||
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
|
||||
DBufInit(&dbuf);
|
||||
|
||||
s = ARGSTR(0);
|
||||
while(*s) {
|
||||
switch(*s) {
|
||||
case '<':
|
||||
r = DBufPuts(&dbuf, "<");
|
||||
break;
|
||||
|
||||
case '>':
|
||||
r = DBufPuts(&dbuf, ">");
|
||||
break;
|
||||
|
||||
case '&':
|
||||
r = DBufPuts(&dbuf, "&");
|
||||
break;
|
||||
|
||||
default:
|
||||
r = DBufPutc(&dbuf, *s);
|
||||
break;
|
||||
}
|
||||
if (r != OK) {
|
||||
DBufFree(&dbuf);
|
||||
return r;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
r = RetStrVal(DBufValue(&dbuf), info);
|
||||
DBufFree(&dbuf);
|
||||
return r;
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
/* */
|
||||
/* htmlstriptags - strip out HTML tags from a string */
|
||||
/* */
|
||||
/****************************************************************/
|
||||
static int FHtmlStriptags(func_info *info)
|
||||
{
|
||||
DynamicBuffer dbuf;
|
||||
char const *s;
|
||||
int r = OK;
|
||||
|
||||
int in_tag = 0;
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
|
||||
DBufInit(&dbuf);
|
||||
|
||||
s = ARGSTR(0);
|
||||
while(*s) {
|
||||
if (!in_tag) {
|
||||
if (*s == '<') {
|
||||
in_tag = 1;
|
||||
} else {
|
||||
r = DBufPutc(&dbuf, *s);
|
||||
}
|
||||
} else {
|
||||
if (*s == '>') {
|
||||
in_tag = 0;
|
||||
}
|
||||
}
|
||||
if (r != OK) {
|
||||
DBufFree(&dbuf);
|
||||
return r;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
r = RetStrVal(DBufValue(&dbuf), info);
|
||||
DBufFree(&dbuf);
|
||||
return r;
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
/* */
|
||||
/* FEasterdate - calc. easter Sunday from a year. */
|
||||
@@ -3187,6 +3290,8 @@ FSlide(func_info *info)
|
||||
{
|
||||
int r, omit, d, i, localomit, amt;
|
||||
Token tok;
|
||||
int step = 1;
|
||||
int localargs = 2;
|
||||
|
||||
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
|
||||
ASSERT_TYPE(1, INT_TYPE);
|
||||
@@ -3196,8 +3301,13 @@ FSlide(func_info *info)
|
||||
if (amt > 1000000) return E_2HIGH;
|
||||
if (amt < -1000000) return E_2LOW;
|
||||
|
||||
if (Nargs > 2 && ARG(2).type == INT_TYPE) {
|
||||
step = ARGV(2);
|
||||
if (step < 1) return E_2LOW;
|
||||
localargs++;
|
||||
}
|
||||
localomit = 0;
|
||||
for (i=2; i<Nargs; i++) {
|
||||
for (i=localargs; i<Nargs; i++) {
|
||||
if (ARG(i).type != STR_TYPE) return E_BAD_TYPE;
|
||||
FindToken(ARG(i).v.str, &tok);
|
||||
if (tok.type != T_WkDay) return E_UNKNOWN_TOKEN;
|
||||
@@ -3208,14 +3318,14 @@ FSlide(func_info *info)
|
||||
if ((WeekdayOmits | localomit) == 0x7F && amt != 0) return E_2MANY_LOCALOMIT;
|
||||
if (amt > 0) {
|
||||
while(amt) {
|
||||
d++;
|
||||
d += step;
|
||||
r = IsOmitted(d, localomit, NULL, &omit);
|
||||
if (r) return r;
|
||||
if (!omit) amt--;
|
||||
}
|
||||
} else {
|
||||
while(amt) {
|
||||
d--;
|
||||
d -= step;
|
||||
if (d < 0) return E_DATE_OVER;
|
||||
r = IsOmitted(d, localomit, NULL, &omit);
|
||||
if (r) return r;
|
||||
@@ -3232,6 +3342,8 @@ FNonomitted(func_info *info)
|
||||
{
|
||||
int d1, d2, ans, localomit, i;
|
||||
int omit, r;
|
||||
int step = 1;
|
||||
int localargs = 2;
|
||||
Token tok;
|
||||
|
||||
if (!HASDATE(ARG(0)) ||
|
||||
@@ -3240,10 +3352,20 @@ FNonomitted(func_info *info)
|
||||
}
|
||||
d1 = DATEPART(ARG(0));
|
||||
d2 = DATEPART(ARG(1));
|
||||
if (d2 < d1) return E_2LOW;
|
||||
if (d2 < d1) {
|
||||
i = d1;
|
||||
d1 = d2;
|
||||
d2 = i;
|
||||
}
|
||||
|
||||
/* Check for a "step" argument - it's an INT */
|
||||
if (Nargs > 2 && ARG(2).type == INT_TYPE) {
|
||||
step = ARGV(2);
|
||||
if (step < 1) return E_2LOW;
|
||||
localargs++;
|
||||
}
|
||||
localomit = 0;
|
||||
for (i=2; i<Nargs; i++) {
|
||||
for (i=localargs; i<Nargs; i++) {
|
||||
if (ARG(i).type != STR_TYPE) return E_BAD_TYPE;
|
||||
FindToken(ARG(i).v.str, &tok);
|
||||
if (tok.type != T_WkDay) return E_UNKNOWN_TOKEN;
|
||||
@@ -3252,11 +3374,12 @@ FNonomitted(func_info *info)
|
||||
|
||||
ans = 0;
|
||||
while (d1 < d2) {
|
||||
r = IsOmitted(d1++, localomit, NULL, &omit);
|
||||
r = IsOmitted(d1, localomit, NULL, &omit);
|
||||
if (r) return r;
|
||||
if (!omit) {
|
||||
ans++;
|
||||
}
|
||||
d1 += step;
|
||||
}
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = ans;
|
||||
|
||||
@@ -52,6 +52,7 @@ EXTERN uid_t TrustedUsers[MAX_TRUSTED_USERS];
|
||||
|
||||
EXTERN INIT( int NumTrustedUsers, 0);
|
||||
EXTERN INIT( char const *MsgCommand, NULL);
|
||||
EXTERN INIT( char const *QueuedMsgCommand, NULL);
|
||||
EXTERN INIT( int ShowAllErrors, 0);
|
||||
EXTERN INIT( int DebugFlag, 0);
|
||||
EXTERN INIT( int DoCalendar, 0);
|
||||
@@ -69,7 +70,7 @@ EXTERN INIT( int Hush, 0);
|
||||
EXTERN INIT( int NextMode, 0);
|
||||
EXTERN INIT( int InfiniteDelta, 0);
|
||||
EXTERN INIT( int DefaultTDelta, 0);
|
||||
EXTERN INIT( int DeltaOffset, 0);
|
||||
EXTERN INIT( int DeltaOverride, 0);
|
||||
EXTERN INIT( int RunDisabled, 0);
|
||||
EXTERN INIT( int IgnoreOnce, 0);
|
||||
EXTERN INIT( int SortByTime, 0);
|
||||
@@ -78,6 +79,7 @@ EXTERN INIT( int SortByPrio, 0);
|
||||
EXTERN INIT( int UntimedBeforeTimed, 0);
|
||||
EXTERN INIT( int DefaultPrio, NO_PRIORITY);
|
||||
EXTERN INIT( long SysTime, -1L);
|
||||
EXTERN INIT( int ParseUntriggered, 1);
|
||||
|
||||
EXTERN char const *InitialFile;
|
||||
EXTERN int FileAccessDate;
|
||||
|
||||
20
src/init.c
20
src/init.c
@@ -341,10 +341,15 @@ void InitRemind(int argc, char const *argv[])
|
||||
} else if (!*arg) {
|
||||
InfiniteDelta = 1;
|
||||
} else {
|
||||
PARSENUM(DeltaOffset, arg);
|
||||
if (DeltaOffset < 0) {
|
||||
DeltaOffset = 0;
|
||||
}
|
||||
if (*arg == 'z') {
|
||||
DeltaOverride = -1;
|
||||
arg++;
|
||||
} else {
|
||||
PARSENUM(DeltaOverride, arg);
|
||||
if (DeltaOverride < 0) {
|
||||
DeltaOverride = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
@@ -600,7 +605,12 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
case 'k':
|
||||
case 'K':
|
||||
MsgCommand = arg;
|
||||
if (*arg == ':') {
|
||||
arg++;
|
||||
QueuedMsgCommand = arg;
|
||||
} else {
|
||||
MsgCommand = arg;
|
||||
}
|
||||
while (*arg) arg++; /* Chew up remaining chars in this arg */
|
||||
break;
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Domenica"
|
||||
#define L_MONDAY "Lunedí"
|
||||
#define L_TUESDAY "Martedí"
|
||||
#define L_WEDNESDAY "Mercoledí"
|
||||
#define L_THURSDAY "Giovedí"
|
||||
#define L_FRIDAY "Venerdí"
|
||||
#define L_MONDAY "Lunedì"
|
||||
#define L_TUESDAY "Martedì"
|
||||
#define L_WEDNESDAY "Mercoledì"
|
||||
#define L_THURSDAY "Giovedì"
|
||||
#define L_FRIDAY "Venerdì"
|
||||
#define L_SATURDAY "Sabato"
|
||||
|
||||
/* Month names */
|
||||
@@ -68,7 +68,7 @@
|
||||
#define L_AT "alle"
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "or"
|
||||
#define L_IS "é"
|
||||
#define L_IS "è"
|
||||
#define L_WAS "era"
|
||||
#define L_AND "e"
|
||||
/* What to add to make "hour" plural */
|
||||
|
||||
10
src/main.c
10
src/main.c
@@ -26,16 +26,10 @@
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
#include <time.h>
|
||||
#if defined(HAVE_SYS_TIME_H)
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#if defined(HAVE_SYS_TIME_H) || defined (TIME_WITH_SYS_TIME)
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#endif
|
||||
#include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef REM_USE_WCHAR
|
||||
|
||||
@@ -377,8 +377,12 @@ int DoOmit(ParsePtr p)
|
||||
break;
|
||||
|
||||
default:
|
||||
Eprint("%s: `%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN],
|
||||
DBufValue(&buf));
|
||||
if (tok.type == T_Until) {
|
||||
Eprint("OMIT: UNTIL not allowed; did you mean THROUGH?");
|
||||
} else {
|
||||
Eprint("%s: `%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN],
|
||||
DBufValue(&buf));
|
||||
}
|
||||
DBufFree(&buf);
|
||||
return E_UNKNOWN_TOKEN;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ int DoRem (ParsePtr p);
|
||||
int DoFlush (ParsePtr p);
|
||||
void DoExit (ParsePtr p);
|
||||
int ParseRem (ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals);
|
||||
int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int dse);
|
||||
int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued);
|
||||
int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int dse, int *err);
|
||||
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode);
|
||||
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int dse, int tim);
|
||||
@@ -177,6 +177,7 @@ int push_call(char const *filename, char const *func, int lineno);
|
||||
void clear_callstack(void);
|
||||
int print_callstack(FILE *fp);
|
||||
void pop_call(void);
|
||||
void FixSpecialType(Trigger *trig);
|
||||
#ifdef REM_USE_WCHAR
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <wctype.h>
|
||||
|
||||
@@ -267,7 +267,7 @@ void HandleQueuedReminders(void)
|
||||
/* Set up global variables so some functions like trigdate()
|
||||
and trigtime() work correctly */
|
||||
SaveAllTriggerInfo(&(q->t), &(q->tt), DSEToday, q->tt.ttime, 1);
|
||||
(void) TriggerReminder(&p, &trig, &q->tt, DSEToday);
|
||||
(void) TriggerReminder(&p, &trig, &q->tt, DSEToday, 1);
|
||||
if (Daemon < 0) {
|
||||
printf("NOTE endreminder\n");
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ void IssueSortedReminders(void)
|
||||
next = cur->next;
|
||||
switch(cur->typ) {
|
||||
case MSG_TYPE:
|
||||
if (MsgCommand) {
|
||||
if (MsgCommand && *MsgCommand) {
|
||||
DoMsgCommand(MsgCommand, cur->text);
|
||||
} else {
|
||||
if (cur->trigdate != olddate) {
|
||||
|
||||
@@ -124,7 +124,11 @@ int DoFset(ParsePtr p)
|
||||
DBufFree(&buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
func->filename = StrDup(FileName);
|
||||
if (FileName) {
|
||||
func->filename = StrDup(FileName);
|
||||
} else {
|
||||
func->filename = StrDup("[cmdline]");
|
||||
}
|
||||
if (!func->filename) {
|
||||
free(func);
|
||||
return E_NO_MEM;
|
||||
|
||||
@@ -792,7 +792,7 @@ static SysVar SysVarArr[] = {
|
||||
{"DefaultColor", 1, SPECIAL_TYPE, default_color_func, 0, 0 },
|
||||
{"DefaultPrio", 1, INT_TYPE, &DefaultPrio, 0, 9999 },
|
||||
{"DefaultTDelta", 1, INT_TYPE, &DefaultTDelta, 0, 1440 },
|
||||
{"DeltaOffset", 0, INT_TYPE, &DeltaOffset, 0, 0 },
|
||||
{"DeltaOverride", 0, INT_TYPE, &DeltaOverride, 0, 0 },
|
||||
{"DontFork", 0, INT_TYPE, &DontFork, 0, 0 },
|
||||
{"DontQueue", 0, INT_TYPE, &DontQueue, 0, 0 },
|
||||
{"DontTrigAts", 0, INT_TYPE, &DontIssueAts, 0, 0 },
|
||||
@@ -839,6 +839,7 @@ static SysVar SysVarArr[] = {
|
||||
{"NumTrig", 0, INT_TYPE, &NumTriggered, 0, 0 },
|
||||
{"October", 1, STR_TYPE, &DynamicMonthName[9], 0, 0 },
|
||||
{"On", 1, STR_TYPE, &DynamicOn, 0, 0 },
|
||||
{"ParseUntriggered", 1, INT_TYPE, &ParseUntriggered, 0, 1 },
|
||||
{"Pm", 1, STR_TYPE, &DynamicPm, 0, 0 },
|
||||
{"PrefixLineNo", 0, INT_TYPE, &DoPrefixLineNo, 0, 0 },
|
||||
{"PSCal", 0, INT_TYPE, &PsCal, 0, 0 },
|
||||
|
||||
@@ -27,6 +27,10 @@ if test `id -u` = 0 ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set a known timezone so moon phases show up in predictable places
|
||||
TZ=UTC
|
||||
export TZ
|
||||
|
||||
# If we're already in a utf-8 locale, do
|
||||
# nothing; otherwise, set LC_ALL
|
||||
OK=0
|
||||
@@ -404,6 +408,18 @@ TZ=Europe/Berlin ../src/remind -dxe ../tests/tz.rem >> ../tests/test.out 2>&1
|
||||
# Test that banner is printed on every iteration
|
||||
echo "MSG Should be three banners." | ../src/remind - 2022-10-20 '*3' >> ../tests/test.out 2>&1
|
||||
|
||||
# Test the -tn option
|
||||
echo "REM May 23 +10 MSG Orange %b" | ../src/remind - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 +10 MSG Quux %b" | ../src/remind -t1 - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 +10 MSG Cabbage %b" | ../src/remind -t2 - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 MSG Banana %b" | ../src/remind - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 MSG Carrot %b" | ../src/remind -t1 - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 MSG Apple %b" | ../src/remind -t2 - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
|
||||
# Test the -tz option
|
||||
echo "REM May 22 +10 MSG Foo %b" | ../src/remind - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 22 +10 MSG Bar %b" | ../src/remind -tz - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
|
||||
# World-writable file
|
||||
rm -rf include_dir/ww
|
||||
touch include_dir/ww
|
||||
@@ -418,6 +434,9 @@ chmod 0777 include_dir/ww
|
||||
../src/remind include_dir/ww >> ../tests/test.out 2>&1
|
||||
rm -rf include_dir/ww
|
||||
|
||||
# This segfaulted in 04.02.03
|
||||
../src/remind -h '-imsgprefix(x)="foo"' /dev/null >> ../tests/test.out 2>&1
|
||||
|
||||
# Remove references to SysInclude, which is build-specific
|
||||
grep -F -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out
|
||||
cmp -s ../tests/test.out ../tests/test.cmp
|
||||
@@ -428,7 +447,11 @@ else
|
||||
echo "Remind: Acceptance test FAILED"
|
||||
echo ""
|
||||
echo "Examine the file test.out to see where it differs from the"
|
||||
echo "reference file test.cmp."
|
||||
echo "reference file test.cmp. Here are the first 200 lines of"
|
||||
echo "diff -u test.out test.cmp"
|
||||
echo ""
|
||||
diff -u ../tests/test.out ../tests/test.cmp | head -n 200
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
1204
tests/test.cmp
1204
tests/test.cmp
File diff suppressed because it is too large
Load Diff
@@ -482,7 +482,7 @@ msg [$December]%
|
||||
msg [$DefaultColor]%
|
||||
msg [$DefaultPrio]%
|
||||
msg [$DefaultTDelta]%
|
||||
msg [$DeltaOffset]%
|
||||
msg [$DeltaOverride]%
|
||||
msg [$DontFork]%
|
||||
msg [$DontQueue]%
|
||||
msg [$DontTrigAts]%
|
||||
@@ -866,6 +866,27 @@ FUNSET circle square rectangle
|
||||
# Should fail
|
||||
SET a square(5)
|
||||
|
||||
# htmlescape
|
||||
set a htmlescape("foo")
|
||||
REM MSG [a]
|
||||
set a htmlescape("<&>")
|
||||
REM MSG [a]
|
||||
set a htmlescape("@&^#*@&^##$*&@><><@#@#><@#>%%_#$foobarquux")
|
||||
REM MSG [a]
|
||||
|
||||
# htmlstriptags
|
||||
set a htmlstriptags("foobar")
|
||||
set a htmlstriptags("This is <b>bold</b>")
|
||||
set a htmlstriptags("This is <unclosed whut?")
|
||||
set a htmlstriptags("this is > whut <b>foo</b>")
|
||||
set a htmlstriptags("<img src=\"foo\">")
|
||||
|
||||
# $ParseUntriggered
|
||||
REM 2 Jan 1990 MSG ["bad_expr" * 2]
|
||||
SET $ParseUntriggered 0
|
||||
REM 2 Jan 1990 MSG ["bad_expr" * 2]
|
||||
SET $ParseUntriggered 1
|
||||
|
||||
# Don't want Remind to queue reminders
|
||||
EXIT
|
||||
|
||||
|
||||
@@ -26,6 +26,25 @@ REM 12 AUG SPECIAL MOON 0
|
||||
# Test nonomitted
|
||||
REM MSG [nonomitted('2007-08-01', today())] NonOmit-1
|
||||
REM MSG [nonomitted('2007-08-01', today(), "Sat", "Sun")] NonOmit-2
|
||||
REM MSG [nonomitted('2007-08-01', '2007-08-30', 7)]
|
||||
REM MSG [nonomitted('2007-08-01', '2007-08-29', 7)]
|
||||
REM MSG [nonomitted('2007-08-28', '2007-08-01', 7)]
|
||||
|
||||
PUSH-OMIT-CONTEXT
|
||||
OMIT 2007-08-15
|
||||
REM MSG [nonomitted('2007-08-01', '2007-08-30', 7)]
|
||||
REM MSG [nonomitted('2007-08-01', '2007-08-29', 7)]
|
||||
REM MSG [nonomitted('2007-08-01', '2007-08-28', 7)]
|
||||
POP-OMIT-CONTEXT
|
||||
|
||||
# Test slide
|
||||
REM MSG [slide('2007-08-03', 4)]
|
||||
REM MSG [slide('2007-08-03', 4, 7)]
|
||||
|
||||
PUSH-OMIT-CONTEXT
|
||||
OMIT 2007-08-17
|
||||
REM MSG [slide('2007-08-03', 4, 7)]
|
||||
POP-OMIT-CONTEXT
|
||||
|
||||
# Test SPECIAL COLOR with an AT clause
|
||||
REM 20 AUG AT 13:45 SPECIAL COLOR 6 7 8 Mooo!
|
||||
|
||||
Reference in New Issue
Block a user