Compare commits

...

73 Commits

Author SHA1 Message Date
Dianne Skoll
fdc3e4d23d Update WHATSNEW 2022-09-22 15:00:30 -04:00
Dianne Skoll
f179c837e1 Update regression tests. 2022-09-22 08:56:58 -04:00
Dianne Skoll
740bb44956 Don't consider IFTRIG true if we could not compute a trigger date.
Bug noted by Gunther Reißig
2022-09-22 08:48:19 -04:00
Dianne Skoll
5b953769fe Obey $DefaultColor in a SATISFY-type reminder.
Bug found by Gunther Reißig.
2022-09-22 08:37:37 -04:00
Dianne Skoll
1ae00ce778 No need to reset NumTriggered. 2022-09-21 19:11:30 -04:00
Dianne Skoll
a01e05c1db Fix bug introduced in commit 98c5bf511e:
Don't print a banner when issuing a queued reminder.
2022-09-21 18:17:25 -04:00
Dianne Skoll
63fb3e99f3 Make "test" depend on "all" rather than just "remind" 2022-09-19 13:56:11 -04:00
Dianne Skoll
6cf7f5d2d8 Merge branch 'add_ci' into 'master'
Add ci

See merge request dskoll/remind!2
2022-09-19 17:54:45 +00:00
Jochen Sprickerhof
316eb43303 Add Gitlab CI 2022-09-19 19:51:15 +02:00
Dianne Skoll
576112a39a Merge branch 'drop_fgrep' into 'master'
Replace deprecated fgrep by grep

See merge request dskoll/remind!1
2022-09-19 17:50:03 +00:00
Jochen Sprickerhof
6607223abb Replace deprecated fgrep by grep -F 2022-09-19 19:49:20 +02:00
Dianne Skoll
9e85b1932d Mark today in bold iff "remind -c" color output is enabled. 2022-09-19 11:32:10 -04:00
Dianne Skoll
4ba7f5b1f2 Only embolden today if stdout is a tty 2022-09-19 10:44:21 -04:00
Dianne Skoll
fc93ae890a Allow NULL pointers to be supplied to FromJulian if we are not interested in specific values 2022-09-17 23:04:34 -04:00
Dianne Skoll
8051d01945 Document change in Makefile install/install-stripped targets. 2022-09-17 09:07:27 -04:00
Dianne Skoll
63430c59f7 Make "make install" *not* strip debugging symbols; add "make install-stripped" target to strip them. 2022-09-17 09:04:45 -04:00
Dianne Skoll
c646bfc63f Make today's date bold in -c mode. 2022-09-16 21:01:10 -04:00
Dianne Skoll
58dea8f69b Support greyscale version of SHADE. 2022-09-16 20:44:59 -04:00
Dianne Skoll
f1c82dcb37 Update docs; bump version to 04.01.00. 2022-09-16 19:54:04 -04:00
Dianne Skoll
b984b66819 Put a space before the "***" representing today in -c mode. 2022-09-16 16:15:01 -04:00
Dianne Skoll
44bdae302b Allow 2 (=TERMINAL_BACKGROUND_UNKNOWN) for m in -@n,m,b 2022-09-16 15:58:51 -04:00
Dianne Skoll
8eb6b250fb Add support for the WEEK speical. 2022-09-16 15:08:53 -04:00
Dianne Skoll
d838c41bf2 Add tests for stdout() function. 2022-09-16 14:14:06 -04:00
Dianne Skoll
f9dbf36496 Don't backgroundize the row with day numbers. 2022-09-16 13:53:33 -04:00
Dianne Skoll
fe1427db28 Finalize support for SPECIAL SHADE in "remind -c" 2022-09-16 13:50:23 -04:00
Dianne Skoll
2621ad5604 Tweak calendar column-to-day handling. 2022-09-16 13:43:20 -04:00
Dianne Skoll
efecf2e1ea Make "remind -c" optionally support the SPECIAL SHADE 2022-09-16 11:41:18 -04:00
Dianne Skoll
8666e6357e Start working on support for SHADE in remind -c output. 2022-09-16 08:42:20 -04:00
Dianne Skoll
ae7069c9cb Gotta use the right sscanf format. :( 2022-09-15 18:43:58 -04:00
Dianne Skoll
0c6ab3e607 Properly parse args to MOON special 2022-09-15 18:37:46 -04:00
Dianne Skoll
17d6a60c0a Fix moon-phase-in-terminal printing and add tests. 2022-09-15 18:23:03 -04:00
Dianne Skoll
e3e0a541dc Print moon phases in terminal if terminal supports UTF-8 2022-09-15 18:18:05 -04:00
Jochen Sprickerhof
712aa08fbc make test depend on all 2022-09-08 16:32:04 +02:00
Dianne Skoll
98c5bf511e Print banner prior to first MSG-type reminder. 2022-09-06 09:14:55 -04:00
Dianne Skoll
1f9281628f Add home page to rem2pdf.1 and rem2html.1 2022-08-27 11:21:24 -04:00
Dianne Skoll
8fb15aed17 Do a sanity-check to make sure we pick up a release date. 2022-08-27 10:26:51 -04:00
Dianne Skoll
a24c3a8542 Remove generated man pages when running "make clean" 2022-08-27 10:24:29 -04:00
Dianne Skoll
8f8059e3f3 Generate man files from *.in versions to include release date and version number. 2022-08-27 10:22:31 -04:00
Dianne Skoll
24bb462199 Rename *.1 to *.1.in 2022-08-27 10:14:16 -04:00
Dianne Skoll
38e914f171 Get release date. 2022-08-27 10:06:02 -04:00
Dianne Skoll
4a02c54e8d Add home page to man pages. 2022-08-26 16:33:39 -04:00
Dianne Skoll
5fe169438a Document behavior of DO and filedir() with respect to symbolic links. 2022-08-22 09:19:30 -04:00
Dianne Skoll
a7ef6e851a Fix error in Makefile - remove duplicate clean: definition 2022-08-21 10:24:30 -04:00
Dianne Skoll
4d57b9d0aa Pass CFLAGS at link-time
Thanks to Zoltan Puskas for suggestion.
2022-08-21 10:23:16 -04:00
Dianne Skoll
5a7452d9f6 Add install-nostripped top-level target.
Thanks to Zoltan Puskas for suggestion.
2022-08-21 10:22:58 -04:00
Dianne Skoll
3916887aff Update change log. 2022-08-16 09:24:51 -04:00
Dianne Skoll
f84f59fa91 Bump version to 04.00.03. 2022-08-15 14:48:59 -04:00
Dianne Skoll
1032f8908e Don't create mysterious files named '&1' when creating new reminders. Sigh. 2022-08-11 11:32:59 -04:00
Dianne Skoll
6c2e8fc608 Document calendar_body and plain_body. 2022-08-08 11:49:06 -04:00
Dianne Skoll
012e527fb5 Fix parsing of old-style output. 2022-08-06 12:06:09 -04:00
Dianne Skoll
62198c9807 Use the new calendar_body/plain_body fields. 2022-08-06 11:54:32 -04:00
Dianne Skoll
de95224d62 Use new calendar_body / plain_body elements. 2022-08-06 11:49:35 -04:00
Dianne Skoll
be374a0464 Update test suite for new JSON output. 2022-08-06 09:09:06 -04:00
Dianne Skoll
fe9b3186d7 Add plain_body and calendar_body keys to JSON output. 2022-08-06 09:06:54 -04:00
Dianne Skoll
8405ea6c53 Add note about how to kill remind in queue mode. 2022-08-06 08:34:16 -04:00
Dianne Skoll
4274d05e10 Fix man page typo 2022-08-05 22:09:36 -04:00
Dianne Skoll
4e80ce1159 Don't make SIGINT kill a background process; don't call printf from a signal-handler; use sigaction instead of signal 2022-08-05 22:04:44 -04:00
Dianne Skoll
52f473f2af Update .gitignore 2022-08-04 10:34:45 -04:00
Dianne Skoll
1d6ca51bf9 Update docs. 2022-08-02 14:58:15 -04:00
Dianne Skoll
e662d0b3dd Bump version to 04.00.02 2022-08-02 14:51:00 -04:00
Dianne Skoll
b910d557d1 Document new form of OMIT command. 2022-07-27 15:16:23 -04:00
Dianne Skoll
a4ad0a9e97 Rename error constant. 2022-07-27 15:06:04 -04:00
Dianne Skoll
07f67e7dd7 Better error messages 2022-07-27 15:03:48 -04:00
Dianne Skoll
d6575773fb Don't let THROUGH date be before START date in OMIT. 2022-07-27 14:55:34 -04:00
Dianne Skoll
ac1303886e Add another test. 2022-07-27 14:47:11 -04:00
Dianne Skoll
1569992184 Add test for more flexible OMIT 2022-07-27 14:43:54 -04:00
Dianne Skoll
55a1f1d746 Implement more flexible OMIT. We can do things like:
OMIT May       - equivalent to "OMIT May 1" ... "OMIT May 31"
    OMIT Nov 20 THROUGH Dec 4
    OMIT Apr THROUGH May
    OMIT 2023-12-25 THROUGH 2024-01-06
2022-07-27 14:39:43 -04:00
Dianne Skoll
ef7742a3cc Add GitHub README 2022-07-19 10:12:46 -04:00
Dianne Skoll
ef48c2020b Fix typo 2022-07-12 20:44:57 -04:00
Dianne Skoll
6dcb25073b Make $T behave as documented: If trigger date is not valid, should return 0. 2022-07-04 14:23:39 -04:00
Dianne Skoll
4824b07ec8 Document inotifywait 2022-07-03 19:47:06 -04:00
Dianne Skoll
a8f1228fb7 Update TkRemind man page. 2022-07-03 19:13:05 -04:00
Dianne Skoll
80e51d1d0f Make calendar with 6 rows in a month handle resizing properly.
Fixes https://github.com/dfskoll/remind/issues/1
2022-07-01 16:45:25 -04:00
36 changed files with 1773 additions and 909 deletions

7
.github/README.md vendored Normal file
View File

@@ -0,0 +1,7 @@
# Remind has moved
For various reasons, I have decided to move Remind off GitHub. This repo
will be archived. To create merge requests or issues, please visit
Remind's new home at https://salsa.debian.org/dskoll/remind
-- Dianne Skoll

5
.gitignore vendored
View File

@@ -10,6 +10,10 @@ autom4te.cache
blib/
config.log
config.status
man/rem.1
man/rem2ps.1
man/remind.1
man/tkremind.1
pm_to_blib
rem2html/Makefile
rem2html/rem2html.1
@@ -17,6 +21,7 @@ rem2pdf/Makefile.PL
rem2pdf/Makefile.old
rem2pdf/Makefile.top
rem2pdf/bin/rem2pdf
set-irc-topic
src/*.tar.gz*
src/Makefile
src/config.h

13
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,13 @@
tests:
image: 'debian:stable-slim'
before_script:
- apt update && apt-get -y install gcc make
- useradd --create-home testuser
- chown -R testuser .
- chmod -R go-w .
script:
- LANG=C.UTF-8 su testuser -c 'make test'
artifacts:
when: always
paths:
- tests/test.out

View File

@@ -12,21 +12,34 @@ all: src/Makefile
@$(MAKE) -C rem2pdf -f Makefile.top
install:
@echo ""
@echo "*********************"
@echo "* *"
@echo "* Installing REMIND *"
@echo "* *"
@echo "*********************"
@echo "**********************************"
@echo "* *"
@echo "* Installing REMIND (unstripped) *"
@echo "* *"
@echo "**********************************"
@echo ""
@$(MAKE) -C src install
@$(MAKE) -C rem2html install
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
clean:
find . -name '*~' -exec rm {} \;
-rm man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1
-$(MAKE) -C src clean
-$(MAKE) -C rem2pdf clean
test:
install-stripped:
@echo ""
@echo "********************************"
@echo "* *"
@echo "* Installing REMIND (stripped) *"
@echo "* *"
@echo "**********************************"
@echo ""
@$(MAKE) -C src install-stripped
@$(MAKE) -C rem2html install
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
test: all
@$(MAKE) -C src -s test
distclean: clean

18
configure vendored
View File

@@ -622,6 +622,7 @@ ac_includes_default="\
ac_header_list=
ac_subst_vars='LTLIBOBJS
LIBOBJS
RELEASE_DATE
PERLARTIFACTS
VERSION
EGREP
@@ -3994,6 +3995,14 @@ else
PERLARTIFACTS='NO_PACKLIST=1 NO_PERLLOCAL=1'
fi
RELEASE_DATE=`grep '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]' docs/WHATSNEW | head -n 1 | awk '{print $NF}'`
# Sanity-check release date
echo "$RELEASE_DATE" | grep '^....-..-..$' > /dev/null 2>&1
if test "$?" != 0 ; then
echo "*** COULD NOT DETERMINE RELEASE DATE: docs/WHATSNEW is incorrect!"
exit 1
fi
for ac_func in setenv unsetenv glob mbstowcs setlocale initgroups
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
@@ -4006,11 +4015,12 @@ _ACEOF
fi
done
VERSION=04.00.01
VERSION=04.01.00
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf"
ac_config_files="$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"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -4710,6 +4720,10 @@ do
"rem2pdf/Makefile.PL") CONFIG_FILES="$CONFIG_FILES rem2pdf/Makefile.PL" ;;
"rem2pdf/Makefile.top") CONFIG_FILES="$CONFIG_FILES rem2pdf/Makefile.top" ;;
"rem2pdf/bin/rem2pdf") CONFIG_FILES="$CONFIG_FILES rem2pdf/bin/rem2pdf" ;;
"man/rem.1") CONFIG_FILES="$CONFIG_FILES man/rem.1" ;;
"man/rem2ps.1") CONFIG_FILES="$CONFIG_FILES man/rem2ps.1" ;;
"man/remind.1") CONFIG_FILES="$CONFIG_FILES man/remind.1" ;;
"man/tkremind.1") CONFIG_FILES="$CONFIG_FILES man/tkremind.1" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac

View File

@@ -64,10 +64,19 @@ else
PERLARTIFACTS='NO_PACKLIST=1 NO_PERLLOCAL=1'
fi
RELEASE_DATE=`grep '[[0-9]][[0-9]][[0-9]][[0-9]]-[[0-9]][[0-9]]-[[0-9]][[0-9]]' docs/WHATSNEW | head -n 1 | awk '{print $NF}'`
# Sanity-check release date
echo "$RELEASE_DATE" | grep '^....-..-..$' > /dev/null 2>&1
if test "$?" != 0 ; then
echo "*** COULD NOT DETERMINE RELEASE DATE: docs/WHATSNEW is incorrect!"
exit 1
fi
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups)
VERSION=04.00.01
VERSION=04.01.00
AC_SUBST(VERSION)
AC_SUBST(PERL)
AC_SUBST(PERLARTIFACTS)
AC_OUTPUT(src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf)
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)
chmod a+x rem2pdf/bin/rem2pdf

View File

@@ -1,5 +1,79 @@
CHANGES TO REMIND
* VERSION 4.1 Patch 0 - ????-??-??
- NEW FEATURE: remind: "remind -c" now supports the MOON special, printing
the moon phases in the calendar if the locale supports UTF-8 encoding.
- NEW FEATURE: remind: "remind -c" now supports the SHADE special. Works
best with the 256-color extended XTerm palette or 24-bit true-color
terminal escape sequences.
- NEW FEATURE: remind: "remind -c" now supports the WEEK special.
- NEW FEATURE: remind: The new "stdout()" function returns a string describing
where stdout is going. Examples of return values are "TTY" if remind's
output is going to terminal, "FILE" if it's redirected to a plain file,
or "PIPE" if it's going to a pipe. See the man page for all the details.
- CHANGE: "make install" now no longer strips debugging symbols from the
remind and rem2ps executables. Use "make install-stripped" if you want
them stripped.
- CHANGE: remind: "remind -c" highlights today's date in bold, if
colors are enabled.
- DOCUMENTATION FIX: Document behavior of DO and filedir() with respect
to symbolic links.
- DOCUMENTATION FIX: Add home page link to man pages. Suggested by Ian! D.
Allen.
- DOCUMENTATION FIX: Make date in man pages actually be the release date.
Include Remind version in man pages. Also suggested by Ian! D. Allen.
- BUG FIX: Makefiles: Pass CFLAGS at link-time so link-time optimization
actually happens. Pointed out by Zolan Puskas.
- BUG FIX: If the first REM command to trigger was a RUN command, the banner
would not print. This has been fixed.
- BUG FIX: replace deprecated 'fgrep' with 'grep -F' (Jochen Sprickerhof)
- BUG FIX: make "make test" depend on "make all" (Jochen Sprickerhof)
- BUG FIX: make "REM ... SATISFY ... MSG foo" respect $DefaultColor. Bug
reported by Gunther Reißig.
- BUG FIX: Don't consider IFTRIG true if we could not compute a trigger date.
Bug noted by Gunther Reißig
* VERSION 4.0 Patch 3 - 2022-08-16
- IMPROVEMENT: remind: add plain_body and calendar_body JSON keys in -pp...
output.
- BUG FIX: tkremind: Don't create empty files called '&1' when creating
a new reminder.
- BUG FIX: remind: Don't call signal-unsafe functions from signal handler
* VERSION 4.0 Patch 2 - 2022-08-02
- IMPROVEMENT: remind: Allow more forms of OMIT as per Ian! D. Allen's request:
OMIT Month [THROUGH Month]
OMIT Day Month [THROUGH Day Month]
OMIT Day Month Year [THROUGH Day Month Year]
- BUG FIX: Make $T behave as documented, exactly like trigdate(). $T would
return '1989-12-31' rather than 0 if the trigger date was not valid.
- BUG FIX: TkRemind: Fix resizing bug for a calendar with 6 rows.
- DOCUMENTATION IMPROVEMENT: Improve TkRemind documentation; document use
of inotifywait if available.
* VERSION 4.0 Patch 1 - 2022-06-03
- IMPROVEMENT: Add $SuppressLRM system variable to suppress the UTF-8
@@ -1188,7 +1262,7 @@ CHANGES TO REMIND
- Made parser _very_ forgiving -- the type of reminder now defaults
to MSG. This lets you have lines in the reminder file like this:
Feb 9, 1998 Meeting with Joe.
Feb 9, 1998 Meeting with Joe.
But I don't recommend abusing it. It's mostly to ease migration from
UNIX calendar(1) files.
@@ -1779,7 +1853,7 @@ CHANGES TO REMIND
- Removed identifiers in the C source beginning with "_" to conform
to ANSI practice.
- Fixed a bug in the -u option which resulted in environment variables
SHELL and USER not being set correctly. Also made -u set the LOGNAME
environment variable.
@@ -1852,7 +1926,7 @@ CHANGES TO REMIND
- Fixed all the source files to include "config.h" first.
- Changed the way triggers are calculated so that trigger dates are
- Changed the way triggers are calculated so that trigger dates are
always valid if year, month and day are specified, and there is no
UNTIL clause. See MAN page section "DETAILS ABOUT TRIGVALID()."
@@ -1994,6 +2068,3 @@ CHANGES TO REMIND
* Version 1.0
- never publicly released.

View File

@@ -1,4 +1,4 @@
.TH REM 1 "14 March 2022"
.TH REM 1 "@RELEASE_DATE@" "User Commands" "VERSION @VERSION@"
.UC 4
.SH NAME
rem \- Invoke Remind with a default filename
@@ -16,5 +16,7 @@ the filename $HOME/.reminders
.PP
.SH AUTHOR
Remind was written by Dianne Skoll <dianne@skoll.ca>
.SH HOME PAGE
https://dianne.skoll.ca/projects/remind/
.SH SEE ALSO
\fBremind\fR

View File

@@ -1,4 +1,4 @@
.TH REM2PS 1 "14 March 2022"
.TH REM2PS 1 "@RELEASE_DATE@" "User Commands" "VERSION @VERSION@"
.UC 4
.SH NAME
rem2ps \- draw a PostScript calendar from Remind output
@@ -586,6 +586,18 @@ For a SHADE or COLOR special, the blue color component.
.B body \fIbody\fR
The body of the reminder to issue. Always present.
.TP
.B calendar_body \fIbody\fR
The text appropriate to include in a calendar. Only present if the
original body contains %"...%" sequences and the "q" modifier was used
with Remind's "-pp..." flag.
.TP
.B plain_body \fIbody\fR
The "plain" body of the reminder with any %"...%" sequences removed.
If your back-end is designed to draw a calendar, then it should
use the \fBcalendar_body\fR if present. If not, then it
should use the \fBplain_body\fR if present, and if not, then it
should fall back on the \fBbody\fR.
.TP
.B rawbody \fIraw\fR
The "raw" body of the reminder, before any expression-pasting or
substitution-sequence processing. If the raw body would be the same
@@ -674,6 +686,8 @@ resulting PostScript output will probably not work.
You should ensure that the values you supply for margin widths are sensible.
If they are too big for the media size, \fBRem2ps\fR will not complain,
but again, the PostScript output will probably not work.
.SH HOME PAGE
https://dianne.skoll.ca/projects/remind/
.SH SEE ALSO
\fBremind\fR, \fBrem2pdf\fR, \fBrem2html\fR, \fBtkremind\fR.

View File

@@ -1,4 +1,4 @@
.TH REMIND 1 "14 March 2022"
.TH REMIND 1 "@RELEASE_DATE@" "User Commands" "VERSION @VERSION@"
.UC 4
.SH NAME
remind \- a sophisticated reminder service
@@ -78,18 +78,18 @@ display.
.B 'c'
causes \fBRemind\fR to use VT100 escape sequences to approximate
SPECIAL COLOR reminders. Note that this flag is kept for
backwards-compatibility; you should use the \fB\-@\fI[n][,m]\fR
backwards-compatibility; you should use the \fB\-@\fI[n][,m][,b]\fR
command-line option instead.
.RE
.TP
.B \-@\fR[\fIn\fR][,\fIm\fR]
Tells \fBRemind\fR to approximate SPECIAL COLOR reminders using VT100
escape sequences. The approximation is (of necessity) very
coarse, because the VT100 only has eight different color sequences,
each with one of two brightnesses. A color component greater than
64 is considered "on", and if any of the three color components is
greater than 128, the color is considered "bright".
.B \-@\fR[\fIn\fR][,\fIm\fR][,\fIb\fR]
Tells \fBRemind\fR to approximate SPECIAL COLOR and SHADE reminders
using VT100 escape sequences. The approximation is (of necessity)
very coarse, because the VT100 only has eight different color
sequences, each with one of two brightnesses. A color component
greater than 64 is considered "on", and if any of the three color
components is greater than 128, the color is considered "bright".
.RS
.PP
If you supply the optional numeric parameters, the have the following
@@ -99,14 +99,27 @@ by many terminal emulators such as xterm. And \fIn\fR=2 tells it to
use escape sequences that support true 24-bit colors, again supported
by many terminal emulators such as xterm.
.PP
If the optional \fIm\fR parameter is supplied following a comma,
then \fIm\fR=0 tells \fBRemind\fR that the terminal background is dark,
and \fBRemind\fR will brighten up dark colors to make them visible. If
If the optional \fIm\fR parameter is supplied following a comma, then
\fIm\fR=0 tells \fBRemind\fR that the terminal background is dark, and
\fBRemind\fR will brighten up dark colors to make them visible. If
\fIm\fR=1, then \fBRemind\fR assumes the terminal background is light
and it will darken bright colors to make them visible. If no \fIm\fR
is supplied, then \fBRemind\fR does not perform any adjustments, and
some reminders may be hard or impossible to see if the color is too close
to the terminal background color.
is supplied, or it is supplied as \fIm\fR=2, then \fBRemind\fR does
not perform any adjustments, and some reminders may be hard or
impossible to see if the color is too close to the terminal background
color.
.PP
If the optional \fIb\fR parameter is supplied following a comma, then
\fIb=0\fR tells \fBRemind\fR to ignore SPECIAL SHADE reminders (the
default) and \fIb=1\fR tells \fBRemind\fR to respect SPECIAL SHADE
reminders by emitting VT100 escape codes to color the background of the
calendar cell. Note that SHADE does not work well unless you are
using the extended 256-color palette (\fIn\fR=1) or the true
24-bit colors (\fIn\fR=2). Note that for calendar cells that are
shaded, the clamping mechanism described earlier for \fIm=0\fR or
\fIm=1\fR is skipped; it is assumed that if you set \fIboth\fR the
foreground color of a reminder and the background color of a cell,
then you know what you are doing.
.RE
.TP
.B \-w\fR\fIcol\fR[,\fIpad\fR[,\fIspc\fR]]]
@@ -1532,11 +1545,11 @@ In addition to being a keyword in the \fBREM\fR command,
\fBOMIT\fR is a command in its own right. Its syntax is:
.PP
.RS
\fBOMIT\fR \fIday\fR \fImonth\fR [\fIyear\fR]
\fBOMIT\fR [\fIday\fR] \fImonth\fR [\fIyear\fR]
.PP
or:
.PP
\fBOMIT\fR \fIday1\fR \fImonth1\fR \fIyear1\fR \fBTHROUGH\fR \fIday2\fR \fImonth2\fR \fIyear2\fR
\fBOMIT\fR [\fIday1\fR] \fImonth1\fR [\fIyear1\fR] \fBTHROUGH\fR [\fIday2\fR] \fImonth2\fR [\fIyear2\fR]
.RE
.PP
The \fBOMIT\fR command is used to "globally" omit certain days
@@ -1545,8 +1558,13 @@ The \fBOMIT\fR command is used to "globally" omit certain days
"\-\-" and "\+\+" forms. Some examples:
.PP
.nf
OMIT 1 Jan
OMIT 7 Sep 1992
OMIT 1 Jan
OMIT 7 Sep 1992
OMIT 15 Jan THROUGH 14 Feb
OMIT May # Equivalent to OMIT May 1 THROUGH May 31
OMIT 25 Dec THROUGH 4 Jan
OMIT 2023-05-03 THROUGH 2023-05-12
OMIT Jun THROUGH July # Equivalent to OMIT Jun 1 THROUGH July 31
.fi
.PP
The first example specifies a holiday that occurs on the same date each
@@ -1578,9 +1596,7 @@ equivalent:
.fi
.PP
The \fBTHROUGH\fR keyword lets you conveniently OMIT a range of days.
The starting and ending points must be fully-specified (ie, they must
include day, month and year.). For example, the following sequences
are equivalent:
For example, the following sequences are equivalent:
.PP
.nf
OMIT 3 Jan 2011
@@ -1592,12 +1608,28 @@ are equivalent:
OMIT 3 Jan 2011 THROUGH 5 Jan 2011
.fi
.PP
You can make a THROUGH \fBOMIT\fR do double-duty as a \fBREM\fR command:
You can make a THROUGH \fBOMIT\fR do double-duty as a \fBREM\fR command as
long as both dates are fully specified
.PP
.nf
OMIT 6 Sep 2010 THROUGH 10 Sep 2010 MSG Vacation
.fi
.PP
If you use a THROUGH clause, then either the year must be supplied before
and after the THROUGH, or it must be missing before and after the THROUGH.
The following are legal:
.PP
.nf
OMIT 25 Dec THROUGH 6 Jan
OMIT 25 Dec 2024 THROUGH 6 Jan 2025
.fi
.PP
But the following are not:
.PP
.nf
OMIT 25 Dec THROUGH 6 Jan 2025
OMIT 25 Dec 2024 THROUGH 6 Jan
.nf
.PP
You can debug your global OMITs with the following command:
.PP
@@ -1706,6 +1738,12 @@ Arguably, the \fBINCLUDE\fR command should have worked the way \fBDO\fR
does right from the start, but changing it would have broken
backward-compatibility, hence the introduction of \fBDO\fR.
.PP
Note that if the currently-processing reminders file was specified as
a symbolic link to a file that is not in the same directory as the
symbolic link itself, \fBDO\fR will fail. \fBRemind\fR does \fInot\fR
resolve the real path of symbolic links, so you should avoid using
symbolic links to files.
.PP
.SH THE RUN COMMAND
.PP
If you include other files in your reminder script, you may not always
@@ -2342,8 +2380,8 @@ For example, the coordinates of the Statue of Liberty in New York City
are approximately set by:
.PP
.nf
SET $Latitude "40.68933"
SET $Longitude "-74.04454"
SET $Latitude "40.68933"
SET $Longitude "-74.04454"
.fi
.RE
.TP
@@ -2812,6 +2850,13 @@ This includes the file "stuff" in the same directory as the
current file being processed. Note that this workaround is
no longer necessary because \fBDO stuff\fR will achieve the
same goal.
.PP
Note that if the currently-processing reminders file was specified as
a symbolic link, then \fBfiledir()\fR returns the directory containing
the symbolic link and \fInot\fR the directory containing the target
of the symbolic link. You should avoid using
symbolic links to files unless both the symbolic link and its target
happen to be in the same directory.
.RE
.TP
.B filename()
@@ -3236,9 +3281,24 @@ May 16 and 17. You can go backwards, too, so:
takes \fIa\fR back to 2009-05-13.
.RE
.TP
.B stdout()
Returns a string representing where Remind's standard output is going.
The return values are one of the following: "TTY" if standard-output
is a terminal, "BLOCKDEV" if it is a block device (very unlikely),
"CHARDEV" if it is a character device (eg, /dev/null), "DIR" if it
is a directory (very unlikely), "PIPE" if it is a pipe or FIFO,
"SYMLINK" if it is a symlink (very unlikely), "SOCKET" if it is a
socket, or "UNKNOWN" if it could not be determined.
.RS
.PP
The purpose of \fBstdout()\fR is mostly to distinguish between TTY
and non-TTY output; you may wish to change or disable colors if the
output is not going to a TTY.
.RE
.TP
.B strlen(s_str)
Returns the length of \fIstr\fR. If the length of \fIstr\fR is too large
to represent as an integers, emits a "Number too high" error.
to represent as an integer, emits a "Number too high" error.
.TP
.B substr(s_str, i_start [,i_end])
Returns a \fBSTRING\fR consisting of all characters in \fIstr\fR from
@@ -4825,7 +4885,7 @@ Suppose you want to change the "%b" sequence to substitute "the day
after tomorrow" for an event two days from now. You could do this:
.PP
.nf
FSET subst_bx(a,d,t) iif(d==today()+2, "the day after tomorrow", \
FSET subst_bx(a,d,t) iif(d==today()+2, "the day after tomorrow", \\
"in " + (d-today()) + " days' time")
REM [today()+3] ++3 MSG Event 1 is %b%
REM [today()+2] ++3 MSG Event 2 is %b%
@@ -5439,7 +5499,8 @@ Almanac Office, USNO.
.PP
Richard Siegel and Michael and Sharon Strassfeld, \fIThe First Jewish
Catalog\fR, Jewish Publication Society of America.
.PP
.SH HOME PAGE
https://dianne.skoll.ca/projects/remind/
.SH SEE ALSO
.PP
\fBrem\fR(1), \fBrem2ps\fR(1), \fBrem2pdf\fR(1), \fBtkremind\fR(1), \fBrem2html\fR(1)

View File

@@ -1,4 +1,4 @@
.TH TKREMIND 1 "14 March 2022"
.TH TKREMIND 1 "@RELEASE_DATE@" "User Commands" "VERSION @VERSION@"
.UC 4
.SH NAME
tkremind \- graphical front-end to Remind calendar program
@@ -18,13 +18,13 @@ as well as the tcllib extension. It also requires a \fBwish\fR
binary. If you are using Tcl/Tk 8.5, you may also need either the Img
or the tkpng extension to handle PNG images.
.SH OPTIONS
\fBTkRemind\fR itself has no options. However, it passes certain options
on to \fBRemind\fR. The options it passes are
\fB\-b\fR, \fB\-g\fR, \fB\-x\fR, \fB\-i\fR and \fB\-m\fR.
See the \fBRemind\fR man page for details about the options.
Note that \fBTkRemind\fR will respect the \fB\-m\fR and
\fB\-b1\fR options and adjust its appearance accordingly.
.SH COMMAND-LINE OPTIONS
\fBTkRemind\fR itself has no command-line options. However, it passes
certain options on to \fBRemind\fR. The options it passes are
\fB\-b\fR, \fB\-g\fR, \fB\-x\fR, \fB\-i\fR and \fB\-m\fR. See the
\fBRemind\fR man page for details about the options. Note that
\fBTkRemind\fR will respect the \fB\-m\fR and \fB\-b1\fR options and
adjust its appearance accordingly.
\fIRead_file\fR is the file from which \fBTkRemind\fR reads reminders.
It is in standard \fBRemind\fR format. \fIWrite_file\fR is the file
@@ -44,8 +44,14 @@ include the line:
.PP
\fIConfig_file\fR is the file in which \fBTkRemind\fR stores
its options. If it is omitted, it defaults to \fI$HOME/.tkremindrt\fR.
its options. If it is omitted, it defaults to \fI$HOME/.config/tkremindrc\fR.
.PP
If \fB$HOME/.reminders\fR is a \fIdirectory\fR, then \fBTkRemind\fR defaults to
reading \fB$HOME/.reminders\fR and writing new reminders to
\fB$HOME/.reminders/100-tkremind.rem\fR. If you want to keep your
reminders in a directory \fB$HOME/.reminders\fR, you should create that
directory before starting \fBTkRemind\fR.
.SH THE CALENDAR WINDOW
When you start \fBTkRemind\fR, it displays a calendar for the current
month, with today's date highlighted. Reminders are filled into each
@@ -274,7 +280,7 @@ Similar to Change entry font, but applies to calendar heading
.PP
Once you've configured the options the way you like them,
press \fBApply Options\fR to put them into effect, \fBSave Options\fR
to put them into effect and save them in $HOME/.tkremindrc, or
to put them into effect and save them in $HOME/.config/tkremindrc, or
\fBCancel\fR to cancel any changes you made.
.SH KEYBOARD SHORTCUTS
@@ -293,6 +299,19 @@ Next Month
.B Home
Today
.SH IMMEDIATE UPDATES
If you are running \fBTkRemind\fR on Linux and have the
\fBinotifywait\fR program installed (part of the \fBinotify-tools\fR
or similar package), then \fBTkRemind\fR redraws the calendar window
\fIimmediately\fR if \fB$HOME/.reminders\fR changes (or, if it is a
directory, any files in that directory change.)
.PP
This lets \fBTkRemind\fR react immediately to hand-edited reminders or
to reminder files that are imported from another calendar system (for example,
you may have a cron job that periodically imports your Google Calendar
entries into Remind format.)
.SH ODDS AND ENDS
\fBTkRemind\fR performs some basic consistency checks when you add or
preview a reminder. However, if you edit a reminder in the previewer,
@@ -323,8 +342,7 @@ You can use this to activate certain reminders in different ways
for \fBTkRemind\fR (for example).
.PP
\fBTkRemind\fR uses tags to keep track of reminders in the
script file. It also places special comments in the reminder
file to store additional state. You can certainly mix
script file. You can certainly mix
"hand-crafted" reminders with reminders created by \fBTkRemind\fR
if you are aware of the following rules and limitations:
.TP
@@ -334,15 +352,16 @@ where \fInnn\fR is a number. You should not use such \fBTAG\fRs
in hand-crafted reminders.
.TP
o
Do not edit lines starting with "# TKTAGnnn", "# TKEND", or any
lines in between. You can move such lines, but be careful to move
them as a single block.
.TP
o
Hand-crafted reminders cannot be edited with \fBTkRemind\fR, and
for hand-crafted timed reminders, you will not be presented with
the "Don't remind me again" option when they pop up.
.PP
However, rather than mixing hand-edited files with \fBTkRemind\fR-generated
ones, it is better to make \fB$HOME/.reminders\fR a directory and keep
your hand-edited files in a separate \fB*.rem\fR file than \fBTkRemind\fR's
\fB100-tkremind.rem\fR file.
.SH SERVER MODE
\fBRemind\fR has a special mode for interacting with programs like
@@ -400,14 +419,16 @@ This line is emitted in response to a \fBSTATUS\fR command. The number
.SH AUTHOR
TkRemind was written by Dianne Skoll <dianne@skoll.ca>
\fBTkRemind\fR is Copyright 1996-2020 by Dianne Skoll.
\fBTkRemind\fR is Copyright 1996-2022 by Dianne Skoll.
.SH FILES
$HOME/.reminders -- default reminder file.
$HOME/.reminders -- default reminder file or directory.
$HOME/.tkremindrc -- \fBTkRemind\fR saved options.
$HOME/.config/tkremindrc -- \fBTkRemind\fR saved options.
.SH HOME PAGE
https://dianne.skoll.ca/projects/remind/
.SH SEE ALSO
\fBremind\fR, \fBrem2ps\fR, \fBrem2pdf\fR, \fBrem2html\fR

View File

@@ -130,6 +130,10 @@ today's date, add the following reminder to your reminders file:
rem2html was written by Dianne Skoll with much inspiration from an
earlier version by Don Schwarz.
=head1 HOME PAGE
L<https://dianne.skoll.ca/projects/remind/>
=head1 SEE ALSO
B<remind>, B<rem2ps>, B<rem2pdf>, B<tkremind>

View File

@@ -504,6 +504,10 @@ of each calendar box:
B<Rem2PDF> was written by Dianne Skoll <dianne@skoll.ca>
=head1 HOME PAGE
L<https://dianne.skoll.ca/projects/remind/>
=head1 SEE ALSO
B<remind>, B<rem2ps>, B<rem2html>, B<tkremind>

View File

@@ -227,14 +227,16 @@ sub parse_oldstyle_line
if ($hash->{passthru}) {
if ($hash->{passthru} =~ /^(shade|color|colour)$/i) {
if ($hash->{body} =~ /^\s*(\d+)\s+(\d+)\s+(\d+)/) {
if ($hash->{body} =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s*(.*)/) {
$hash->{r} = $1;
$hash->{g} = $2;
$hash->{b} = $3;
} elsif ($hash->{body} =~ /^\s*(\d+)/) {
$hash->{body} = $4;
} elsif ($hash->{body} =~ /^\s*(\d+)\s*(.*)/) {
$hash->{r} = $1;
$hash->{g} = $1;
$hash->{b} = $1;
$hash->{body} = $2;
}
}
}

View File

@@ -76,7 +76,15 @@ sub render
$layout->set_width(1024 * ($x2 - $x1 - 2 * $settings->{border_size}));
$layout->set_wrap('word-char');
$layout->set_text(Encode::decode('UTF-8', $self->{body}));
my $body;
if (exists($self->{calendar_body})) {
$body = $self->{calendar_body};
} elsif (exists($self->{plain_body})) {
$body = $self->{plain_body};
} else {
$body = $self->{body};
}
$layout->set_text(Encode::decode('UTF-8', $body));
my $desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . $settings->{entry_size} . 'px');
$layout->set_font_description($desc);
my ($wid, $h) = $layout->get_pixel_size();
@@ -233,11 +241,9 @@ sub _adjust
package Remind::PDF::Entry::color;
use base 'Remind::PDF::Entry';
# Strip the RGB prefix from body
# Nothing to do for COLOR-type reminder
sub _adjust
{
my ($self) = @_;
$self->{body} =~ s/^\d+\s+\d+\s+\d+\s+//;
}
package Remind::PDF::Entry::postscript;

View File

@@ -547,7 +547,9 @@ proc ConfigureCalFrame { w firstDay numDays } {
$w.t$i configure -state disabled -takefocus 0
}
for {set i $first} {$i <= $last} {incr i} {
set row [expr ($i/7)+1]
grid $w.f$i
grid rowconfigure $w $row -weight 1
pack $w.l$i -in $w.f$i -side top -expand 0 -fill x
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
raise $w.l$i
@@ -581,7 +583,7 @@ proc ConfigureCalFrame { w firstDay numDays } {
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
raise $w.l$i
raise $w.t$i
grid rowconfigure $w [expr $row+1] -weight 1
grid rowconfigure $w $row -weight 1
}
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
$w.l$i configure -state disabled
@@ -1089,8 +1091,13 @@ proc FillCalWindow {} {
} else {
set tag "*"
}
set stuff [dict get $obj body]
if {[dict exists $obj calendar_body]} {
set stuff [dict get $obj calendar_body]
} elseif {[dict exists $obj plain_body]} {
set stuff [dict get $obj plain_body]
} else {
set stuff [dict get $obj body]
}
set day [string trimleft $day 0]
set n [expr $day+$offset]
set month [string trimleft $month 0]
@@ -1114,30 +1121,31 @@ proc FillCalWindow {} {
}
"COLOUR" -
"COLOR" {
if {[regexp {^ *([0-9]+) +([0-9]+) +([0-9]+) +(.*)$} $stuff all r g b rest]} {
if {$r > 255} {
set r 255
} elseif {$r < 0} {
set r 0
}
if {$g > 255} {
set g 255
} elseif {$g < 0} {
set g 0
}
if {$b > 255} {
set b 255
} elseif {$b < 0} {
set b 0
}
set color [format "%02X%02X%02X" $r $g $b]
set extratags "clr$color"
.cal.t$n configure -state normal
.cal.t$n tag configure $extratags -foreground "#$color"
.cal.t$n configure -state disabled -takefocus 0
set stuff $rest
set type "COLOR"
}
set r [dict get $obj r]
set g [dict get $obj g]
set b [dict get $obj b]
if {$r > 255} {
set r 255
} elseif {$r < 0} {
set r 0
}
if {$g > 255} {
set g 255
} elseif {$g < 0} {
set g 0
}
if {$b > 255} {
set b 255
} elseif {$b < 0} {
set b 0
}
set color [format "%02X%02X%02X" $r $g $b]
set extratags "clr$color"
.cal.t$n configure -state normal
.cal.t$n tag configure $extratags -foreground "#$color"
.cal.t$n configure -state disabled -takefocus 0
set stuff $stuff
set type "COLOR"
}
}
if { $type != "*" && $type != "COLOR" && $type != "COLOUR"} {
@@ -2104,7 +2112,7 @@ proc CreateReminder {w} {
# Check it out!
global Remind
set f [open "|$Remind -arq -e - 2>&1" r+]
set f [open "|$Remind -arq -e - 2>@1" r+]
puts $f "BANNER %"
puts $f "$rem MSG %"
puts $f "MSG %_%_%_%_"

View File

@@ -36,7 +36,7 @@ REMINDOBJS= $(REMINDSRCS:.c=.o)
all: remind rem2ps
test: remind
test: all
@sh ../tests/test-rem
.c.o:
@@ -45,12 +45,12 @@ test: remind
$(REMINDOBJS): $(REMINDHDRS)
rem2ps: rem2ps.o dynbuf.o json.o
@CC@ @LDFLAGS@ $(LDEXTRA) -o rem2ps rem2ps.o dynbuf.o json.o -lm
@CC@ @CFLAGS@ @LDFLAGS@ $(LDEXTRA) -o rem2ps rem2ps.o dynbuf.o json.o -lm
remind: $(REMINDOBJS)
@CC@ @LDFLAGS@ $(LDEXTRA) -o remind $(REMINDOBJS) @LIBS@
@CC@ @CFLAGS@ @LDFLAGS@ $(LDEXTRA) -o remind $(REMINDOBJS) @LIBS@
install-nostripped: all
install: all
-mkdir -p $(DESTDIR)$(bindir) || true
for prog in $(PROGS) $(SCRIPTS) ; do \
$(INSTALL_PROGRAM) $$prog $(DESTDIR)$(bindir) || exit 1; \
@@ -64,7 +64,7 @@ install-nostripped: all
-mkdir -p $(DESTDIR)$(datarootdir)/remind || true
cp -R ../include/* $(DESTDIR)$(datarootdir)/remind
install: install-nostripped
install-stripped: install
strip $(DESTDIR)$(bindir)/remind || true
strip $(DESTDIR)$(bindir)/rem2ps || true

View File

@@ -147,6 +147,47 @@ static char *VT100Colors[2][2][2][2] /* [Br][R][G][B] */ = {
}
};
static char *VT100BGColors[2][2][2] /* [R][G][B] */ = {
{
{
/* 0, 0, 0 = Black */ "\x1B[0;40m",
/* 0, 0, 1 = Blue */ "\x1B[0;44m"
},
{
/* 0, 1, 0 = Green */ "\x1B[0;42m",
/* 0, 1, 1 = Cyan */ "\x1B[0;46m"
}
},
{
{
/* 1, 0, 0 = Red */ "\x1B[0;41m",
/* 1, 0, 1 = Magenta */ "\x1B[0;45m"
},
{
/* 1, 1, 0 = Yellow */ "\x1B[0;43m",
/* 1, 1, 1 = White */ "\x1B[0;47m"
}
}
};
/* Moon phase icons in UTF-8 */
static char const *moonphase_emojis[] = {
"\xF0\x9F\x8C\x91",
"\xF0\x9F\x8C\x93",
"\xF0\x9F\x8C\x95",
"\xF0\x9F\x8C\x97"
};
/* Moon phases for each day 1-31, up to 32 chars per moon-phase string
including termination \0 */
static char moons[32][32];
/* Week indicators */
static char weeks[32][32];
/* Background colors of each day 1-31, rgb */
static int bgcolor[32][3];
static struct line_drawing *linestruct;
#define DRAW(x) fputs(linestruct->x, stdout)
@@ -229,13 +270,14 @@ static struct xterm256_colors XTerm256Colors[] =
/* Global variables */
static CalEntry *CalColumn[7];
static int ColToDay[7];
static int ColSpaces;
static int DidAMonth;
static int DidADay;
static void ColorizeEntry(CalEntry const *e);
static void ColorizeEntry(CalEntry const *e, int clamp);
static void SortCol (CalEntry **col);
static void DoCalendarOneWeek (int nleft);
static void DoCalendarOneMonth (void);
@@ -244,7 +286,7 @@ static void WriteWeekHeaderLine (void);
static void WritePostHeaderLine (void);
static void PrintLeft (char const *s, int width, char pad);
static void PrintCentered (char const *s, int width, char *pad);
static int WriteOneCalLine (void);
static int WriteOneCalLine (int jul, int wd);
static int WriteOneColLine (int col);
static void GenerateCalEntries (int col);
static void WriteCalHeader (void);
@@ -256,6 +298,46 @@ static void WriteBottomCalLine (void);
static void WriteIntermediateCalLine (void);
static void WriteCalDays (void);
static int
DayOf(int jul)
{
int d;
FromJulian(jul, NULL, NULL, &d);
return d;
}
static void
Backgroundize(int d)
{
if (d < 1 || d > 31) {
return;
}
if (!UseBGVTChars) {
return;
}
if (bgcolor[d][0] < 0) {
return;
}
printf("%s", Colorize(bgcolor[d][0], bgcolor[d][1], bgcolor[d][2], 1, 0));
}
static void
UnBackgroundize(int d)
{
if (d < 1 || d > 31) {
return;
}
if (!UseBGVTChars) {
return;
}
if (bgcolor[d][0] < 0) {
return;
}
printf("%s", Decolorize());
}
static void
send_lrm(void)
{
@@ -293,6 +375,19 @@ despace(char const *s)
return buf;
}
void PrintJSONChar(char c) {
switch(c) {
case '\b': printf("\\b"); break;
case '\f': printf("\\f"); break;
case '\n': printf("\\n"); break;
case '\r': printf("\\r"); break;
case '\t': printf("\\t"); break;
case '"': printf("\\\""); break;
case '\\': printf("\\\\"); break;
default: printf("%c", c);
}
}
void PrintJSONString(char const *s)
{
while (*s) {
@@ -497,16 +592,13 @@ ClampColor(int *r, int *g, int *b)
}
char const *
Decolorize(int r, int g, int b)
Decolorize(void)
{
if (!strcmp(Colorize(r, g, b), "")) {
return "";
}
return "\x1B[0m";
}
static char const *
Colorize256(int r, int g, int b)
Colorize256(int r, int g, int b, int bg, int clamp)
{
static char buf[40];
int best = -1;
@@ -515,7 +607,9 @@ Colorize256(int r, int g, int b)
struct xterm256_colors *cur;
size_t i;
ClampColor(&r, &g, &b);
if (clamp) {
ClampColor(&r, &g, &b);
}
for (i=0; i<(sizeof(XTerm256Colors) / sizeof(XTerm256Colors[0])); i++) {
cur = &XTerm256Colors[i];
dist = ((r - cur->r) * (r - cur->r)) +
@@ -527,31 +621,42 @@ Colorize256(int r, int g, int b)
}
}
cur = &XTerm256Colors[best];
sprintf(buf, "\x1B[38;5;%dm", best);
if (bg) {
sprintf(buf, "\x1B[48;5;%dm", best);
} else {
sprintf(buf, "\x1B[38;5;%dm", best);
}
return buf;
}
static char const *
ColorizeTrue(int r, int g, int b)
ColorizeTrue(int r, int g, int b, int bg, int clamp)
{
static char buf[40];
ClampColor(&r, &g, &b);
sprintf(buf, "\x1B[38;2;%d;%d;%dm", r, g, b);
if (clamp) {
ClampColor(&r, &g, &b);
}
if (bg) {
sprintf(buf, "\x1B[48;2;%d;%d;%dm", r, g, b);
} else {
sprintf(buf, "\x1B[38;2;%d;%d;%dm", r, g, b);
}
return buf;
}
char const *
Colorize(int r, int g, int b)
Colorize(int r, int g, int b, int bg, int clamp)
{
int bright = 0;
if (UseTrueColors) {
return ColorizeTrue(r, g, b);
return ColorizeTrue(r, g, b, bg, clamp);
}
if (Use256Colors) {
return Colorize256(r, g, b);
return Colorize256(r, g, b, bg, clamp);
}
if (r > 128 || g > 128 || b > 128) {
bright = 1;
}
@@ -562,20 +667,24 @@ Colorize(int r, int g, int b)
if (b > 64) b = 1;
else b = 0;
if (TerminalBackground == TERMINAL_BACKGROUND_DARK) {
if (clamp && TerminalBackground == TERMINAL_BACKGROUND_DARK && !bg) {
/* Convert black-on-black to grey */
if (!r && !g && !b) return VT100Colors[1][0][0][0];
}
if (TerminalBackground == TERMINAL_BACKGROUND_LIGHT) {
if (clamp && TerminalBackground == TERMINAL_BACKGROUND_LIGHT && !bg) {
/* Convert white-on-white to grey */
if (r && g && b) return VT100Colors[1][0][0][0];
}
return VT100Colors[bright][r][g][b];
if (bg) {
return VT100BGColors[r][g][b];
} else {
return VT100Colors[bright][r][g][b];
}
}
static void ColorizeEntry(CalEntry const *e)
static void ColorizeEntry(CalEntry const *e, int clamp)
{
printf("%s", Colorize(e->r, e->g, e->b));
printf("%s", Colorize(e->r, e->g, e->b, 0, clamp));
}
static int
@@ -599,6 +708,92 @@ ComputeCalWidth(int x)
return w.ws_col;
}
static void
InitMoonsAndShades(void)
{
int i;
/* Initialize the moon array */
if (encoding_is_utf8) {
for (i=0; i<=31; i++) {
moons[i][0] = 0;
}
}
/* Clear SHADEs */
if (UseBGVTChars) {
for (i=0; i<=31; i++) {
bgcolor[i][0] = -1;
bgcolor[i][1] = -1;
bgcolor[i][2] = -1;
}
}
/* Clear weeks */
for(i=0; i<=31; i++) {
weeks[i][0] = 0;
}
}
static void
SetShadeEntry(int jul, char const *shade)
{
int y, m, d;
int r, g, b;
/* Don't bother if we're not doing SHADE specials */
if (!UseBGVTChars) {
return;
}
if (sscanf(shade, "%d %d %d", &r, &g, &b) != 3) {
if (sscanf(shade, "%d", &r) != 1) {
return;
}
g = r;
b = r;
}
if (r < 0 || g < 0 || b < 0 || r > 255 || g > 255 || b > 255) {
return;
}
FromJulian(jul, &y, &m, &d);
bgcolor[d][0] = r;
bgcolor[d][1] = g;
bgcolor[d][2] = b;
}
static void
SetMoonEntry(int jul, char const *moon)
{
int phase;
int y, m, d;
char msg[32];
/* Don't bother unless it's utf-8 */
if (!encoding_is_utf8) {
return;
}
msg[0] = 0;
if (sscanf(moon, "%d %*d %*d %31[^\x01]", &phase, msg) < 4) {
if (sscanf(moon, "%d", &phase) != 1) {
/* Malformed MOON special; ignore */
fprintf(stderr, "Oops 1\n");
return;
}
}
if (phase < 0 || phase > 3) {
/* Bad phase */
fprintf(stderr, "Oops 2\n");
return;
}
FromJulian(jul, &y, &m, &d);
if (msg[0]) {
snprintf(moons[d], sizeof(moons[d]), "%s %s", moonphase_emojis[phase], msg);
} else {
snprintf(moons[d], sizeof(moons[d]), "%s", moonphase_emojis[phase]);
}
}
/***************************************************************/
/* */
/* ProduceCalendar */
@@ -681,18 +876,22 @@ static void DoCalendarOneWeek(int nleft)
int LinesWritten = 0;
int OrigJul = JulianToday;
InitMoonsAndShades();
/* Fill in the column entries */
for (i=0; i<7; i++) {
ColToDay[i] = DayOf(JulianToday);
GenerateCalEntries(i);
JulianToday++;
}
/* Output the entries */
/* Figure out weekday of first column */
if (MondayFirst) wd = JulianToday % 7;
else wd = (JulianToday + 1) % 7;
/* Output the entries */
/* If it's "Simple Calendar" format, do it simply... */
if (DoSimpleCalendar) {
if (MondayFirst) wd = JulianToday % 7;
else wd = (JulianToday + 1) % 7;
for (i=0; i<7; i++) {
WriteSimpleEntries(i, OrigJul+i-wd);
}
@@ -704,13 +903,33 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
FromJulian(OrigJul+i, &y, &m, &d);
FromJulian(OrigJul+i, &y, &m, &d);
char const *mon = get_month_name(m);
snprintf(buf, sizeof(buf), "%d %s ", d, get_month_abbrev(mon));
if (OrigJul+i == RealToday)
PrintLeft(buf, ColSpaces, '*');
else
if (moons[d][0]) {
if (weeks[d][0]) {
snprintf(buf, sizeof(buf), "%d %s %s %s ", d, get_month_abbrev(mon), weeks[d], moons[d]);
} else {
snprintf(buf, sizeof(buf), "%d %s %s ", d, get_month_abbrev(mon), moons[d]);
}
} else {
if (weeks[d][0]) {
snprintf(buf, sizeof(buf), "%d %s %s ", d, get_month_abbrev(mon), weeks[d]);
} else {
snprintf(buf, sizeof(buf), "%d %s ", d, get_month_abbrev(mon));
}
}
if (OrigJul+i == RealToday) {
if (UseVTColors) {
printf("\x1B[1m"); /* Bold */
}
PrintLeft(buf, ColSpaces-1, '*');
if (UseVTColors) {
printf("\x1B[0m"); /* Normal */
}
putchar(' ');
} else {
PrintLeft(buf, ColSpaces, ' ');
}
gon();
DRAW(tb);
goff();
@@ -721,7 +940,10 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
d = ColToDay[i];
Backgroundize(d);
PrintLeft("", ColSpaces, ' ');
UnBackgroundize(d);
gon();
DRAW(tb);
goff();
@@ -732,7 +954,7 @@ static void DoCalendarOneWeek(int nleft)
/* Write the body lines */
done = 0;
while (!done) {
done = WriteOneCalLine();
done = WriteOneCalLine(OrigJul, wd);
LinesWritten++;
}
@@ -742,7 +964,10 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
d = ColToDay[i];
Backgroundize(d);
PrintLeft("", ColSpaces, ' ');
UnBackgroundize(d);
gon();
DRAW(tb);
goff();
@@ -769,6 +994,8 @@ static void DoCalendarOneMonth(void)
{
int y, m, d, mm, yy, i, j;
InitMoonsAndShades();
if (!DoSimpleCalendar) WriteCalHeader();
DidADay = 0;
@@ -869,10 +1096,15 @@ static int WriteCalendarRow(void)
if (!MondayFirst) wd = (JulianToday + 1) % 7;
else wd = JulianToday % 7;
for (i=0; i<7; i++) {
ColToDay[i] = 0;
}
/* Fill in the column entries */
for (i=wd; i<7; i++) {
if (d+i-wd > DaysInMonth(m, y)) break;
GenerateCalEntries(i);
ColToDay[i] = DayOf(JulianToday);
JulianToday++;
}
@@ -895,9 +1127,27 @@ static int WriteCalendarRow(void)
if (i < wd || d+i-wd>DaysInMonth(m, y))
PrintLeft("", ColSpaces, ' ');
else {
sprintf(buf, "%d ", d+i-wd);
if (moons[d+i-wd][0]) {
if (weeks[d+i-wd][0]) {
snprintf(buf, sizeof(buf), "%d %s %s ", d+i-wd, weeks[d+i-wd], moons[d+i-wd]);
} else {
snprintf(buf, sizeof(buf), "%d %s ", d+i-wd, moons[d+i-wd]);
}
} else {
if (weeks[d+i-wd][0]) {
snprintf(buf, sizeof(buf), "%d %s ", d+i-wd, weeks[d+i-wd]);
} else {
snprintf(buf, sizeof(buf), "%d ", d+i-wd);
}
}
if (Julian(y, m, d+i-wd) == RealToday) {
if (UseVTColors) {
printf("\x1B[1m"); /* Bold */
}
PrintLeft(buf, ColSpaces-1, '*');
if (UseVTColors) {
printf("\x1B[0m"); /* Normal */
}
putchar(' ');
} else {
PrintLeft(buf, ColSpaces, ' ');
@@ -913,7 +1163,9 @@ static int WriteCalendarRow(void)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
Backgroundize(ColToDay[i]);
PrintLeft("", ColSpaces, ' ');
UnBackgroundize(ColToDay[i]);
gon();
DRAW(tb);
goff();
@@ -924,7 +1176,7 @@ static int WriteCalendarRow(void)
/* Write the body lines */
done = 0;
while (!done) {
done = WriteOneCalLine();
done = WriteOneCalLine(OrigJul, wd);
LinesWritten++;
}
@@ -934,7 +1186,9 @@ static int WriteCalendarRow(void)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
Backgroundize(ColToDay[i]);
PrintLeft("", ColSpaces, ' ');
UnBackgroundize(ColToDay[i]);
gon();
DRAW(tb);
goff();
@@ -1105,19 +1359,25 @@ static void PrintCentered(char const *s, int width, char *pad)
/* Write a single line. */
/* */
/***************************************************************/
static int WriteOneCalLine(void)
static int WriteOneCalLine(int start_jul, int wd)
{
int done = 1, i;
int y, m, d;
gon();
DRAW(tb);
goff();
for (i=0; i<7; i++) {
FromJulian(start_jul+i, &y, &m, &d);
d -= wd;
if (CalColumn[i]) {
Backgroundize(ColToDay[i]);
if (WriteOneColLine(i)) done = 0;
} else {
Backgroundize(ColToDay[i]);
PrintCentered("", ColSpaces, " ");
}
UnBackgroundize(ColToDay[i]);
gon();
DRAW(tb);
goff();
@@ -1146,9 +1406,12 @@ static int WriteOneColLine(int col)
wchar_t const *wspace;
int width;
#endif
int clamp = 1;
int numwritten = 0;
int d = ColToDay[col];
if (d && UseBGVTChars && bgcolor[d][0] != -1) {
clamp = 0;
}
/* Print as many characters as possible within the column */
#ifdef REM_USE_WCHAR
if (e->wc_text) {
@@ -1191,7 +1454,7 @@ static int WriteOneColLine(int col)
/* Colorize reminder if necessary */
if (UseVTColors && e->is_color) {
ColorizeEntry(e);
ColorizeEntry(e, clamp);
}
/* If we couldn't find a space char, print what we have. */
@@ -1228,9 +1491,10 @@ static int WriteOneColLine(int col)
}
}
/* Decolorize reminder if necessary */
/* Decolorize reminder if necessary, but keep any SHADE */
if (UseVTColors && e->is_color) {
printf("%s", Decolorize(e->r, e->g, e->b));
printf("%s", Decolorize());
Backgroundize(d);
}
/* Possibly send lrm control sequence */
@@ -1283,7 +1547,7 @@ static int WriteOneColLine(int col)
/* Colorize reminder if necessary */
if (UseVTColors && e->is_color) {
ColorizeEntry(e);
ColorizeEntry(e, clamp);
}
/* If we couldn't find a space char, print what we have. */
@@ -1311,9 +1575,10 @@ static int WriteOneColLine(int col)
}
}
/* Decolorize reminder if necessary */
/* Decolorize reminder if necessary, but keep SHADE */
if (UseVTColors && e->is_color) {
printf("%s", Decolorize(e->r, e->g, e->b));
printf("%s", Decolorize());
Backgroundize(d);
}
/* Flesh out the rest of the column */
@@ -1587,6 +1852,19 @@ static int DoCalRem(ParsePtr p, int col)
DBufFree(&buf);
}
trig.typ = tok.val;
if (trig.typ == MSG_TYPE ||
trig.typ == CAL_TYPE ||
trig.typ == MSF_TYPE) {
is_color = (
DefaultColorR != -1
&& DefaultColorG != -1
&& DefaultColorB != -1);
if (is_color) {
col_r = DefaultColorR;
col_g = DefaultColorG;
col_b = DefaultColorB;
}
}
jul = LastTriggerDate;
if (!LastTrigValid) {
FreeTrig(&trig);
@@ -1650,10 +1928,49 @@ static int DoCalRem(ParsePtr p, int col)
}
}
if (trig.typ == PASSTHRU_TYPE) {
if (!PsCal && StrCmpi(trig.passthru, "COLOR") && StrCmpi(trig.passthru, "COLOUR")) {
if (!PsCal && !StrCmpi(trig.passthru, "SHADE")) {
if (jul == JulianToday) {
DBufInit(&obuf);
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
if (r) {
DBufFree(&obuf);
FreeTrig(&trig);
return r;
}
SetShadeEntry(jul, DBufValue(&obuf));
DBufFree(&obuf);
}
}
if (!PsCal && !StrCmpi(trig.passthru, "WEEK")) {
if (jul == JulianToday) {
DBufInit(&obuf);
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
if (r) {
DBufFree(&obuf);
FreeTrig(&trig);
return r;
}
sscanf(DBufValue(&obuf), "%31[^\x01]", weeks[DayOf(jul)]);
DBufFree(&obuf);
}
}
if (!PsCal && StrCmpi(trig.passthru, "COLOR") && StrCmpi(trig.passthru, "COLOUR") && StrCmpi(trig.passthru, "MOON")) {
FreeTrig(&trig);
return OK;
}
if (!PsCal && !StrCmpi(trig.passthru, "MOON")) {
if (jul == JulianToday) {
DBufInit(&obuf);
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
if (r) {
DBufFree(&obuf);
FreeTrig(&trig);
return r;
}
SetMoonEntry(jul, DBufValue(&obuf));
DBufFree(&obuf);
}
}
if (!StrCmpi(trig.passthru, "COLOR") ||
!StrCmpi(trig.passthru, "COLOUR")) {
is_color = 1;
@@ -1912,6 +2229,7 @@ static void WriteSimpleEntryProtocol1(CalEntry *e)
static void WriteSimpleEntryProtocol2(CalEntry *e, int today)
{
int done = 0;
char const *s;
if (DoPrefixLineNo) {
PrintJSONKeyPairString("filename", e->filename);
PrintJSONKeyPairInt("lineno", e->lineno);
@@ -2038,6 +2356,45 @@ static void WriteSimpleEntryProtocol2(CalEntry *e, int today)
if (strcmp(e->raw_text, e->text)) {
PrintJSONKeyPairString("rawbody", e->raw_text);
}
/* Figure out calendar_body and plain_body */
if (DontSuppressQuoteMarkers) {
s = strstr(e->text, "%\"");
if (s) {
s += 2;
printf("\"calendar_body\":\"");
while (*s) {
if (*s == '%' && *(s+1) == '"') {
break;
}
PrintJSONChar(*s);
s++;
}
printf("\",");
}
}
s = strstr(e->text, "%\"");
if (s || e->is_color) {
printf("\"plain_body\":\"");
s = e->text;
if (e->is_color) {
while(*s && !isspace(*s)) s++;
while(*s && isspace(*s)) s++;
while(*s && !isspace(*s)) s++;
while(*s && isspace(*s)) s++;
while(*s && !isspace(*s)) s++;
while(*s && isspace(*s)) s++;
}
while(*s) {
if (*s == '%' && *(s+1) == '"') {
s += 2;
continue;
}
PrintJSONChar(*s);
s++;
}
printf("\",");
}
printf("\"body\":\"");
PrintJSONString(e->text);
printf("\"");

View File

@@ -868,6 +868,8 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
}
}
}
/***************************************************************/
/* */
/* TriggerReminder */
@@ -929,7 +931,8 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
}
/* 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)
&& !NumTriggered && !NextMode && !MsgCommand) {
&& !DidMsgReminder && !NextMode && !MsgCommand) {
DidMsgReminder = 1;
if (!DoSubstFromString(DBufValue(&Banner), &buf,
JulianToday, NO_TIME) &&
DBufLen(&buf)) {
@@ -1030,7 +1033,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
if (!r) {
if (!DoCoerce(STR_TYPE, &v)) {
if (is_color) {
DBufPuts(&buf, Colorize(red, green, blue));
DBufPuts(&buf, Colorize(red, green, blue, 0, 1));
}
if (DBufPuts(&buf, v.v.str) != OK) {
DBufFree(&buf);
@@ -1044,7 +1047,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
}
if (is_color) {
DBufPuts(&buf, Colorize(red, green, blue));
DBufPuts(&buf, Colorize(red, green, blue, 0, 1));
}
if ( (r=DoSubst(p, &buf, t, tim, jul, NORMAL_MODE)) ) return r;
if (t->typ != RUN_TYPE) {
@@ -1055,7 +1058,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
if (!r) {
if (!DoCoerce(STR_TYPE, &v)) {
if (is_color) {
DBufPuts(&buf, Colorize(red, green, blue));
DBufPuts(&buf, Colorize(red, green, blue, 0, 1));
}
if (DBufPuts(&buf, v.v.str) != OK) {
DBufFree(&buf);
@@ -1069,7 +1072,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
}
if (is_color) {
DBufPuts(&buf, Decolorize(red, green, blue));
DBufPuts(&buf, Decolorize());
}
if ((!MsgCommand && t->typ == MSG_TYPE) || t->typ == MSF_TYPE) {

View File

@@ -70,7 +70,7 @@
#define E_MON_TWICE 51
#define E_DAY_TWICE 52
#define E_UNKNOWN_TOKEN 53
#define E_SPEC_MON_DAY 54
#define E_SPEC_MON 54
#define E_2MANY_PART 55
#define E_2MANY_FULL 56
#define E_PUSH_NOPOP 57
@@ -187,7 +187,7 @@ EXTERN char *ErrMsg[]
"Month specified twice",
"Day specified twice",
"Unknown token",
"Must specify month and day in OMIT command",
"Must specify month in OMIT command",
"Too many partial OMITs",
"Too many full OMITs",
"Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT",

View File

@@ -121,6 +121,7 @@ static int FRealtoday (func_info *);
static int FSgn (func_info *);
static int FShell (func_info *);
static int FSlide (func_info *);
static int FStdout (func_info *);
static int FStrlen (func_info *);
static int FSubstr (func_info *);
static int FSunrise (func_info *);
@@ -276,6 +277,7 @@ BuiltinFunc Func[] = {
{ "shell", 1, 2, 0, FShell },
{ "shellescape", 1, 1, 1, FShellescape },
{ "slide", 2, NO_MAX, 0, FSlide },
{ "stdout", 0, 0, 1, FStdout },
{ "strlen", 1, 1, 1, FStrlen },
{ "substr", 2, 3, 1, FSubstr },
{ "sunrise", 0, 1, 0, FSunrise},
@@ -1237,6 +1239,35 @@ static int FLower(func_info *info)
return OK;
}
/***************************************************************/
/* */
/* FStdout - return the type of file descriptor for stdout */
/* */
/***************************************************************/
static int FStdout(func_info *info)
{
struct stat statbuf;
int r;
if (isatty(STDOUT_FILENO)) {
return RetStrVal("TTY", info);
}
if (fstat(STDOUT_FILENO, &statbuf) < 0) {
return RetStrVal("UNKNOWN", info);
}
switch(statbuf.st_mode & S_IFMT) {
case S_IFBLK: r = RetStrVal("BLOCKDEV", info); break;
case S_IFCHR: r = RetStrVal("CHARDEV", info); break;
case S_IFDIR: r = RetStrVal("DIR",info); break;
case S_IFIFO: r = RetStrVal("PIPE",info); break;
case S_IFLNK: r = RetStrVal("SYMLINK", info); break;
case S_IFREG: r = RetStrVal("FILE",info); break;
case S_IFSOCK: r = RetStrVal("SOCKET", info); break;
default: r = RetStrVal("UNKNOWN", info); break;
}
return r;
}
/***************************************************************/
/* */
/* FToday - return the system's notion of "today" */

View File

@@ -111,11 +111,13 @@ EXTERN INIT( int LastTriggerTime, 0);
EXTERN INIT( int ShouldCache, 0);
EXTERN char const *CurLine;
EXTERN INIT( int NumTriggered, 0);
EXTERN INIT( int DidMsgReminder, 0);
EXTERN int ArgC;
EXTERN char const **ArgV;
EXTERN INIT( int CalLines, CAL_LINES);
EXTERN INIT( int CalPad, 1);
EXTERN INIT( int UseVTChars, 0);
EXTERN INIT( int UseBGVTChars, 0);
EXTERN INIT( int UseUTF8Chars, 0);
EXTERN INIT( int UseVTColors, 0);
EXTERN INIT( int Use256Colors, 0);

View File

@@ -43,7 +43,8 @@
* simple calendar format.
* -r = Disallow RUN mode
* -c[n] = Produce a calendar for n months (default = 1)
* -@[n,m] = Colorize n=0 VT100 n=1 85 n=2 True m=0 dark terminal m=1 light
* -@[n,m,b]= Colorize n=0 VT100 n=1 85 n=2 True m=0 dark terminal m=1 light
* b=0 ignore SHADE b=1 respect SHADE
* -w[n,n,n] = Specify output device width, padding and spacing
* -s[n] = Produce calendar in "simple calendar" format
* -p[n] = Produce calendar in format compatible with rem2ps
@@ -233,22 +234,36 @@ void InitRemind(int argc, char const *argv[])
} else if (x == 2) {
UseTrueColors = 1;
} else if (x != 0) {
fprintf(ErrFp, "%s: -@n,m: n must be 0, 1 or 2 (assuming 0)\n",
fprintf(ErrFp, "%s: -@n,m,b: n must be 0, 1 or 2 (assuming 0)\n",
argv[0]);
}
}
if (*arg == ',') {
arg++;
PARSENUM(x, arg);
if (x == 0) {
TerminalBackground = TERMINAL_BACKGROUND_DARK;
} else if (x == 1) {
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
} else {
fprintf(ErrFp, "%s: -@n,m: m must be 0 or 1\n",
argv[0]);
if (*arg != ',') {
PARSENUM(x, arg);
if (x == 0) {
TerminalBackground = TERMINAL_BACKGROUND_DARK;
} else if (x == 1) {
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
} else if (x == 2) {
TerminalBackground = TERMINAL_BACKGROUND_UNKNOWN;
} else {
fprintf(ErrFp, "%s: -@n,m,b: m must be 0, 1 or 2 (assuming 2)\n",
argv[0]);
}
}
}
if (*arg == ',') {
arg++;
PARSENUM(x, arg);
if (x != 0 && x != 1) {
fprintf(ErrFp, "%s: -@n,m,b: b must be 0 or 1 (assuming 0)\n",
argv[0]);
x = 0;
}
UseBGVTChars = x;
}
break;
case 'j':
@@ -689,7 +704,7 @@ void Usage(void)
fprintf(ErrFp, "Options:\n");
fprintf(ErrFp, " -n Output next occurrence of reminders in simple format\n");
fprintf(ErrFp, " -r Disable RUN directives\n");
fprintf(ErrFp, " -@[n,m] Colorize COLOR reminders\n");
fprintf(ErrFp, " -@[n,m,b] Colorize COLOR/SHADE reminders\n");
fprintf(ErrFp, " -c[a][n] Produce a calendar for n (default 1) months\n");
fprintf(ErrFp, " -c[a]+[n] Produce a calendar for n (default 1) weeks\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Specify width, padding and spacing of calendar\n");

View File

@@ -195,7 +195,7 @@ EXTERN char *ErrMsg[] =
"Kuukausi annettu kahdesti",
"Päivä annettu kahdesti",
"Tuntematon sana tai merkki",
"OMIT-komennossa on annettava kuukausi ja päivä",
"OMIT-komennossa on annettava kuukausi",
"Liian monta osittaista OMIT-komentoa",
"Liian monta täydellistä OMIT-komentoa",
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",

View File

@@ -185,7 +185,7 @@ EXTERN char *ErrMsg[] =
"Miesiąc podany dwókrotnie",
"Dzień podany dwókrotnie",
"Nieznane słowo",
"W komendzie OMIT trzeba podać miesiąc i dzień",
"W komendzie OMIT trzeba podać miesiąc",
"Za dużo częściowych komend OMIT",
"Za dużo pełnych komend OMIT",
"Ostrzeżenie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT",

View File

@@ -194,7 +194,7 @@ EXTERN char *ErrMsg[] =
"Mes especificado duas vezes",
"Dia especificado duas vezes",
"Token desconhecido",
"Mes e dia devem ser especificados no comando OMIT",
"O mes deve ser especificados no comando OMIT",
"Muitos OMITs parciais",
"Muitos OMITs full",
"Aviso: PUSH-OMIT-CONTEXT sem POP-OMIT-CONTEXT correspondente",

View File

@@ -329,7 +329,8 @@ int Julian(int year, int month, int day)
/* */
/* FromJulian */
/* */
/* Convert a Julian date to year, month, day. */
/* Convert a Julian date to year, month, day. You may supply */
/* NULL for y, m or d if you're not interested in that value */
/* */
/***************************************************************/
void FromJulian(int jul, int *y, int *m, int *d)
@@ -358,9 +359,15 @@ void FromJulian(int jul, int *y, int *m, int *d)
try_mon++;
t = DaysInMonth(try_mon, try_yr);
}
*y = try_yr;
*m = try_mon;
*d = jul + 1;
if (y) {
*y = try_yr;
}
if (m) {
*m = try_mon;
}
if (d) {
*d = jul + 1;
}
return;
}
@@ -857,19 +864,19 @@ int DoIfTrig(ParsePtr p)
Eprint("%s", ErrMsg[r]);
}
}
syndrome = IF_TRUE | BEFORE_ELSE;
syndrome = IF_FALSE | BEFORE_ELSE;
}
else {
if (ShouldTriggerReminder(&trig, &tim, jul, &err)) {
syndrome = IF_TRUE | BEFORE_ELSE;
} else {
syndrome = IF_FALSE | BEFORE_ELSE;
if (PurgeMode) {
PurgeEchoLine("%s\n", "#!P: The next IFTRIG did not trigger.");
PurgeEchoLine("%s\n", "#!P: REM statements in IFTRIG block not checked for purging.");
}
}
}
if (syndrome == (IF_FALSE | BEFORE_ELSE) && PurgeMode) {
PurgeEchoLine("%s\n", "#!P: The next IFTRIG did not trigger.");
PurgeEchoLine("%s\n", "#!P: REM statements in IFTRIG block not checked for purging.");
}
FreeTrig(&trig);
}
NumIfs++;
@@ -1357,13 +1364,23 @@ void UTCToLocal(int utcdate, int utctime, int *locdate, int *loctime)
/* command-line flag is supplied. */
/* */
/***************************************************************/
static sig_atomic_t got_sigint = 0;
void SigIntHandler(int d)
void
SigIntHandler(int d)
{
UNUSED(d);
signal(SIGINT, SigIntHandler);
GotSigInt();
exit(0);
got_sigint = 1;
}
int
GotSigInt(void)
{
if (got_sigint) {
got_sigint = 0;
return 1;
}
return 0;
}
void

View File

@@ -271,7 +271,6 @@ static void InsertIntoSortedArray(int *array, int num, int key)
*cur = key;
}
static int DoThroughOmit(ParsePtr p, int y, int m, int d);
static void DumpOmits(void);
/***************************************************************/
@@ -283,11 +282,15 @@ static void DumpOmits(void);
/***************************************************************/
int DoOmit(ParsePtr p)
{
int y = NO_YR, m = NO_MON, d = NO_DAY, r;
int y[2] = {NO_YR, NO_YR}, m[2] = {NO_MON, NO_MON}, d[2] = {NO_DAY, NO_DAY}, r;
Token tok;
int parsing=1;
int parsing = 1;
int seen_through = 0;
int syndrome;
int not_first_token = -1;
int start, end, tmp;
int mc, dc;
DynamicBuffer buf;
DBufInit(&buf);
@@ -308,28 +311,28 @@ int DoOmit(ParsePtr p)
case T_Date:
DBufFree(&buf);
if (y != NO_YR) return E_YR_TWICE;
if (m != NO_MON) return E_MON_TWICE;
if (d != NO_DAY) return E_DAY_TWICE;
FromJulian(tok.val, &y, &m, &d);
if (y[seen_through] != NO_YR) return E_YR_TWICE;
if (m[seen_through] != NO_MON) return E_MON_TWICE;
if (d[seen_through] != NO_DAY) return E_DAY_TWICE;
FromJulian(tok.val, &y[seen_through], &m[seen_through], &d[seen_through]);
break;
case T_Year:
DBufFree(&buf);
if (y != NO_YR) return E_YR_TWICE;
y = tok.val;
if (y[seen_through] != NO_YR) return E_YR_TWICE;
y[seen_through] = tok.val;
break;
case T_Month:
DBufFree(&buf);
if (m != NO_MON) return E_MON_TWICE;
m = tok.val;
if (m[seen_through] != NO_MON) return E_MON_TWICE;
m[seen_through] = tok.val;
break;
case T_Day:
DBufFree(&buf);
if (d != NO_DAY) return E_DAY_TWICE;
d = tok.val;
if (d[seen_through] != NO_DAY) return E_DAY_TWICE;
d[seen_through] = tok.val;
break;
case T_Delta:
@@ -338,8 +341,9 @@ int DoOmit(ParsePtr p)
case T_Through:
DBufFree(&buf);
if (y == NO_YR || m == NO_MON || d == NO_DAY) return E_INCOMPLETE;
return DoThroughOmit(p, y, m, d);
if (seen_through) return E_UNTIL_TWICE;
seen_through = 1;
break;
case T_Empty:
case T_Comment:
@@ -358,26 +362,85 @@ int DoOmit(ParsePtr p)
return E_UNKNOWN_TOKEN;
}
}
if (m == NO_MON || d == NO_DAY) return E_SPEC_MON_DAY;
if (y == NO_YR) {
if (NumPartialOmits == MAX_PARTIAL_OMITS) return E_2MANY_PART;
if (d > MonthDays[m]) return E_BAD_DATE;
syndrome = (m<<5) + d;
if (!BexistsIntArray(PartialOmitArray, NumPartialOmits, syndrome)) {
InsertIntoSortedArray(PartialOmitArray, NumPartialOmits, syndrome);
NumPartialOmits++;
}
if (!seen_through) {
/* We must have at least a month */
if (m[0] == NO_MON) return E_SPEC_MON;
m[1] = m[0];
y[1] = y[0];
if (d[0] == NO_DAY) {
d[0] = 1;
if (y[0] == NO_YR) {
d[1] = MonthDays[m[0]];
} else {
d[1] = DaysInMonth(m[0], y[0]);
}
} else {
d[1] = d[0];
m[1] = m[0];
y[1] = y[0];
}
} else {
if (d > DaysInMonth(m, y)) return E_BAD_DATE;
syndrome = Julian(y, m, d);
r = AddGlobalOmit(syndrome);
if (r) {
return r;
if (m[0] == NO_MON) return E_SPEC_MON;
if (m[1] == NO_MON) return E_SPEC_MON;
if ((y[0] != NO_YR && y[1] == NO_YR) ||
(y[0] == NO_YR && y[1] != NO_YR)) {
return E_BAD_DATE;
}
if (d[0] == NO_DAY) d[0] = 1;
if (d[1] == NO_DAY) {
if (y[1] == NO_YR) {
d[1] = MonthDays[m[1]];
} else {
d[1] = DaysInMonth(m[1], y[1]);
}
}
}
if (y[0] == NO_YR) {
/* Partial OMITs */
if (d[0] > MonthDays[m[0]]) return E_BAD_DATE;
if (d[1] > MonthDays[m[1]]) return E_BAD_DATE;
dc = d[0];
mc = m[0];
while(1) {
syndrome = (mc<<5) + dc;
if (!BexistsIntArray(PartialOmitArray, NumPartialOmits, syndrome)) {
InsertIntoSortedArray(PartialOmitArray, NumPartialOmits, syndrome);
NumPartialOmits++;
}
if (mc == m[1] && dc == d[1]) {
break;
}
dc++;
if (dc > MonthDays[mc]) {
dc = 1;
mc++;
if (mc > 11) {
mc = 0;
}
}
}
} else {
/* Full OMITs */
if (d[0] > DaysInMonth(m[0], y[0])) return E_BAD_DATE;
if (d[1] > DaysInMonth(m[1], y[1])) return E_BAD_DATE;
start = Julian(y[0], m[0], d[0]);
end = Julian(y[1], m[1], d[1]);
if (end < start) {
Eprint("Error: THROUGH date earlier than start date");
return E_BAD_DATE;
}
for (tmp = start; tmp <= end; tmp++) {
if (!BexistsIntArray(FullOmitArray, NumFullOmits, tmp)) {
if (NumFullOmits >= MAX_FULL_OMITS) return E_2MANY_FULL;
InsertIntoSortedArray(FullOmitArray, NumFullOmits, tmp);
NumFullOmits++;
}
}
}
if (tok.type == T_Tag || tok.type == T_Duration || tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
return OK;
@@ -394,95 +457,6 @@ AddGlobalOmit(int jul)
return OK;
}
static int
DoThroughOmit(ParsePtr p, int ystart, int mstart, int dstart)
{
int yend = NO_YR, mend = NO_MON, dend = NO_DAY, r;
int start, end, tmp;
int parsing = 1;
Token tok;
DynamicBuffer buf;
DBufInit(&buf);
while(parsing) {
if ( (r=ParseToken(p, &buf)) ) return r;
FindToken(DBufValue(&buf), &tok);
switch(tok.type) {
case T_Date:
DBufFree(&buf);
if (yend != NO_YR) return E_YR_TWICE;
if (mend != NO_MON) return E_MON_TWICE;
if (dend != NO_DAY) return E_DAY_TWICE;
FromJulian(tok.val, &yend, &mend, &dend);
break;
case T_Year:
DBufFree(&buf);
if (yend != NO_YR) return E_YR_TWICE;
yend = tok.val;
break;
case T_Month:
DBufFree(&buf);
if (mend != NO_MON) return E_MON_TWICE;
mend = tok.val;
break;
case T_Day:
DBufFree(&buf);
if (dend != NO_DAY) return E_DAY_TWICE;
dend = tok.val;
break;
case T_Empty:
case T_Comment:
case T_RemType:
case T_Priority:
case T_Tag:
case T_Duration:
DBufFree(&buf);
parsing = 0;
break;
default:
Eprint("%s: `%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN],
DBufValue(&buf));
DBufFree(&buf);
return E_UNKNOWN_TOKEN;
}
}
if (yend == NO_YR || mend == NO_MON || dend == NO_DAY) return E_INCOMPLETE;
if (dend > DaysInMonth(mend, yend)) return E_BAD_DATE;
if (dstart > DaysInMonth(mstart, ystart)) return E_BAD_DATE;
start = Julian(ystart, mstart, dstart);
end = Julian(yend, mend, dend);
if (end < start) {
Wprint("Warning: Swapping dates on OMIT ... THROUGH ... line");
tmp = start;
start = end;
end = tmp;
}
tmp = end - start + 1;
/* Don't create any OMITs if there would be too many. */
if (NumFullOmits + tmp >= MAX_FULL_OMITS) return E_2MANY_FULL;
for (tmp = start; tmp <= end; tmp++) {
if (!BexistsIntArray(FullOmitArray, NumFullOmits, tmp)) {
InsertIntoSortedArray(FullOmitArray, NumFullOmits, tmp);
NumFullOmits++;
}
}
if (tok.type == T_Tag || tok.type == T_Duration || tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
return OK;
}
void
DumpOmits(void)
{

View File

@@ -22,6 +22,7 @@
#define isempty(c) (isspace(c) || ((c) == '\\'))
#include "dynbuf.h"
#include <ctype.h>
int CallUserFunc (char const *name, int nargs, ParsePtr p);
int DoFset (ParsePtr p);
@@ -143,7 +144,7 @@ int MoonPhase (int date, int time);
void HuntPhase (int startdate, int starttim, int phas, int *date, int *time);
int CompareRems (int dat1, int tim1, int prio1, int dat2, int tim2, int prio2, int bydate, int bytime, int byprio, int untimed_first);
void SigIntHandler (int d);
void GotSigInt (void);
int GotSigInt (void);
void PurgeEchoLine(char const *fmt, ...);
void FreeTrig(Trigger *t);
void AppendTag(DynamicBuffer *buf, char const *s);
@@ -154,8 +155,8 @@ void SaveLastTimeTrig(TimeTrig const *t);
void SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigtime, int valid);
void PerIterationInit(void);
char const *Decolorize(int r, int g, int b);
char const *Colorize(int r, int g, int b);
char const *Decolorize(void);
char const *Colorize(int r, int g, int b, int bg, int clamp);
void PrintJSONString(char const *s);
void PrintJSONKeyPairInt(char const *name, int val);
void PrintJSONKeyPairString(char const *name, char const *val);

View File

@@ -59,6 +59,7 @@ static QueuedRem *FindNextReminder (void);
static int CalculateNextTimeUsingSched (QueuedRem *q);
static void DaemonWait (struct timeval *sleep_tv);
static void reread (void);
static void PrintQueue(void);
/***************************************************************/
/* */
@@ -123,9 +124,10 @@ void HandleQueuedReminders(void)
Trigger trig;
struct timeval tv;
struct timeval sleep_tv;
struct sigaction sa;
/* Suppress the BANNER from being issued */
NumTriggered = 1;
DidMsgReminder = 1;
/* Turn off sorting -- otherwise, TriggerReminder has no effect! */
SortByDate = 0;
@@ -161,7 +163,11 @@ void HandleQueuedReminders(void)
q = q->next;
}
if (!DontFork || Daemon) signal(SIGINT, SigIntHandler);
if (!DontFork || Daemon) {
sa.sa_handler = SigIntHandler;
sa.sa_flags = 0;
(void) sigaction(SIGINT, &sa, NULL);
}
/* Sit in a loop, issuing reminders when necessary */
while(1) {
@@ -205,6 +211,10 @@ void HandleQueuedReminders(void)
sleep(SleepTime);
}
if (GotSigInt()) {
PrintQueue();
}
/* If not in daemon mode and day has rolled around,
exit -- not much we can do. */
if (!Daemon) {
@@ -337,13 +347,13 @@ static QueuedRem *FindNextReminder(void)
/***************************************************************/
/* */
/* GotSigInt */
/* PrintQueue */
/* */
/* Split out what's done on a SIGINT from the SIGINT Handler. */
/* This will be necessary for OS/2 multithreaded. */
/* For debugging: Print queue contents to STDOUT */
/* */
/***************************************************************/
void GotSigInt(void)
static
void PrintQueue(void)
{
QueuedRem *q = QueueHead;
@@ -368,6 +378,7 @@ void GotSigInt(void)
q = q->next;
}
printf(NL);
printf("To terminate program, send SIGQUIT (probably Ctrl-\\ on the keyboard.)%s", NL);
}
/***************************************************************/

View File

@@ -170,10 +170,11 @@ static int latitude_func(int do_set, Value *val)
static int trig_date_func(int do_set, Value *val)
{
UNUSED(do_set);
val->type = DATE_TYPE;
if (!LastTrigValid) {
val->type = INT_TYPE;
val->v.val = 0;
} else {
val->type = DATE_TYPE;
val->v.val = LastTriggerDate;
}
return OK;

View File

@@ -15,3 +15,6 @@ REM 28 SPECIAL COLOUR 129 0 129 Bright Magenta
REM 28 SPECIAL COLOUR 129 129 0 Bright Yellow
REM 28 SPECIAL COLOUR 129 129 129 Bright White
SET $DefaultColor "255 255 0"
REM 23 SATISFY [1] MSG DefaultColor_Yellow

View File

@@ -123,23 +123,37 @@ REM Mon OMITFUNC foo MSG bar
EOF
# Test default color
../src/remind -ppp - 1 Jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -pppq - 1 Jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
REM 2 MSG Normal
SET $DefaultColor "255 0 0"
REM 3 MSG Red
REM 3 MSG %"Red%" on the calendar!
SET $DefaultColor "-1 -1 -1"
REM 4 MSG Normal
# Should give an error
SET $DefaultColor "256 0 0"
EOF
# Test stdout
../src/remind - 1 jan 2012 <<'EOF' >> ../tests/test.out 2>&1
BANNER %
MSG STDOUT is a: [stdout()]%
EOF
../src/remind - 1 jan 2012 <<'EOF' 2>&1 | cat >> ../tests/test.out
BANNER %
MSG STDOUT is a: [stdout()]%
EOF
# Test -@ option
../src/remind -w,0,0 -@0 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@0,,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@0
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -153,12 +167,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@0,0 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@0,0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@0,0
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -172,12 +189,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@0,1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@0,1
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -191,12 +211,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@1,,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@1
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -210,12 +233,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@1,0 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@1,0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@1,0
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -229,12 +255,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@1,1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@1,1
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -248,12 +277,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@2 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@2,,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@2
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -267,12 +299,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@2,0 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@2,0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@2,0
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -286,12 +321,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@2,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@2,1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@2,1
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -332,7 +370,7 @@ fi
../src/remind -cu '-i$SuppressLRM=1' ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
# Remove references to SysInclude, which is build-specific
fgrep -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out
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
if [ "$?" = "0" ]; then
echo "Remind: Acceptance test PASSED"

File diff suppressed because it is too large Load Diff

View File

@@ -436,6 +436,7 @@ set a132 trigdatetime()
set a133 trigduration()
set a134 trigeventstart()
set a135 trigeventduration()
set a136 stdout()
# These will issue errors
REM Mon OMIT Mon SKIP MSG Never ever ever...
@@ -730,6 +731,11 @@ msg [a]
set x psshade(50)
set x psmoon(0)
# Recursive expression evaluation
FSET _f(x) 0
SET tmp evaltrig("Wed SKIP OMITFUNC _f",date(1992,1,8))
REM MSG [tmp]
# Trig
IF trig("sun +1") || trig("thu +1")
REM [trig()] +1 MSG Foo %b
@@ -798,6 +804,21 @@ set a pad(11:33, " ", 12)
set a pad(11:33, " ", 12, 1)
set a pad("foo", "0", $MaxStringLen+1)
# Test OMIT
CLEAR-OMIT-CONTEXT
OMIT Apr
OMIT Jun THROUGH July 15
OMIT Sep 5 THROUGH Sep 10
OMIT 2024-12-25 THROUGH 2025-01-04
OMIT Apr 2022 through July
OMIT DUMP
CLEAR-OMIT-CONTEXT
OMIT 2000-01-01 THROUGH 2020-12-31
OMIT Dec 5 2029 through Dec 4 2029
# Don't want Remind to queue reminders
EXIT

View File

@@ -1,4 +1,9 @@
MSG ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский
MSG עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית
Wed MSG With tabs and spaces
Wed MSG With tabs and spaces
REM [moondate(0)] MSG 🌑
REM [moondate(1)] MSG 🌓 woo
REM [moondate(2)] MSG 🌕 blech bo
REM [moondate(3)] MSG 🌗 zo zo oz