mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 23:08:40 +02:00
Compare commits
36 Commits
05.03.00-B
...
curses_rem
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae17834610 | ||
|
|
5acbb907b4 | ||
|
|
21ecc28ea4 | ||
|
|
b37a7cd993 | ||
|
|
64679817ae | ||
|
|
1ef1033379 | ||
|
|
7d42750043 | ||
|
|
1dc0afc0ca | ||
|
|
a0aede4069 | ||
|
|
a5a7637696 | ||
|
|
38a597a374 | ||
|
|
66ba9257a5 | ||
|
|
c5374c09fb | ||
|
|
9c93e7e6a1 | ||
|
|
3487f6f46a | ||
|
|
da8a72d7cd | ||
|
|
f391b6221f | ||
|
|
a8c0b20f9e | ||
|
|
5684a86df9 | ||
|
|
3abaaacd98 | ||
|
|
7eae7a9157 | ||
|
|
a0d8c93a34 | ||
|
|
8bf22dbb36 | ||
|
|
6b2622f3d3 | ||
|
|
8abdf6d988 | ||
|
|
991e409739 | ||
|
|
3c2bb76523 | ||
|
|
8555352c18 | ||
|
|
34f8486c10 | ||
|
|
5adb5d893e | ||
|
|
2f11b6fdc8 | ||
|
|
49d46c1397 | ||
|
|
1641f99f97 | ||
|
|
f9f9552850 | ||
|
|
3b43222585 | ||
|
|
231d9d77e7 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -35,3 +35,4 @@ www/Makefile
|
|||||||
gmon.out
|
gmon.out
|
||||||
tests/once.timestamp
|
tests/once.timestamp
|
||||||
src/xlat.c
|
src/xlat.c
|
||||||
|
cremind/Makefile.PL
|
||||||
|
|||||||
6
Makefile
6
Makefile
@@ -23,8 +23,7 @@ install:
|
|||||||
@$(MAKE) -C rem2html install
|
@$(MAKE) -C rem2html install
|
||||||
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
|
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
|
||||||
clean:
|
clean:
|
||||||
find . -name '*~' -exec rm {} \;
|
-find . -name '*~' -exec rm {} \;
|
||||||
-rm man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1 scripts/tkremind
|
|
||||||
-$(MAKE) -C src clean
|
-$(MAKE) -C src clean
|
||||||
-$(MAKE) -C rem2pdf clean
|
-$(MAKE) -C rem2pdf clean
|
||||||
|
|
||||||
@@ -44,7 +43,8 @@ test:
|
|||||||
@$(MAKE) -C src -s test
|
@$(MAKE) -C src -s test
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f config.cache config.log config.status src/Makefile src/config.h tests/test.out www/Makefile rem2pdf/Makefile.top rem2pdf/Makefile.old rem2pdf/Makefile rem2pdf/Makefile.PL rem2pdf/bin/rem2pdf rem2html/rem2html
|
-rm -f config.cache config.log config.status src/Makefile src/config.h tests/test.out www/Makefile rem2pdf/Makefile.top rem2pdf/Makefile.old rem2pdf/Makefile rem2pdf/Makefile.PL rem2pdf/bin/rem2pdf rem2html/rem2html
|
||||||
|
-rm -f man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1 scripts/tkremind
|
||||||
|
|
||||||
src/Makefile: src/Makefile.in
|
src/Makefile: src/Makefile.in
|
||||||
./configure
|
./configure
|
||||||
|
|||||||
21
configure
vendored
21
configure
vendored
@@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.71 for remind 05.03.00.
|
# Generated by GNU Autoconf 2.71 for remind 05.03.02.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
|
# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
|
||||||
@@ -608,8 +608,8 @@ MAKEFLAGS=
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='remind'
|
PACKAGE_NAME='remind'
|
||||||
PACKAGE_TARNAME='remind'
|
PACKAGE_TARNAME='remind'
|
||||||
PACKAGE_VERSION='05.03.00'
|
PACKAGE_VERSION='05.03.02'
|
||||||
PACKAGE_STRING='remind 05.03.00'
|
PACKAGE_STRING='remind 05.03.02'
|
||||||
PACKAGE_BUGREPORT=''
|
PACKAGE_BUGREPORT=''
|
||||||
PACKAGE_URL='https://dianne.skoll.ca/projects/remind/'
|
PACKAGE_URL='https://dianne.skoll.ca/projects/remind/'
|
||||||
|
|
||||||
@@ -1265,7 +1265,7 @@ if test "$ac_init_help" = "long"; then
|
|||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures remind 05.03.00 to adapt to many kinds of systems.
|
\`configure' configures remind 05.03.02 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@@ -1327,7 +1327,7 @@ fi
|
|||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of remind 05.03.00:";;
|
short | recursive ) echo "Configuration of remind 05.03.02:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@@ -1415,7 +1415,7 @@ fi
|
|||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
remind configure 05.03.00
|
remind configure 05.03.02
|
||||||
generated by GNU Autoconf 2.71
|
generated by GNU Autoconf 2.71
|
||||||
|
|
||||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
@@ -1865,7 +1865,7 @@ cat >config.log <<_ACEOF
|
|||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by remind $as_me 05.03.00, which was
|
It was created by remind $as_me 05.03.02, which was
|
||||||
generated by GNU Autoconf 2.71. Invocation command line was
|
generated by GNU Autoconf 2.71. Invocation command line was
|
||||||
|
|
||||||
$ $0$ac_configure_args_raw
|
$ $0$ac_configure_args_raw
|
||||||
@@ -4209,7 +4209,7 @@ printf "%s\n" "#define CONFIG_CMD \"$CONFIG_CMD\"" >>confdefs.h
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h rem2html/Makefile rem2html/rem2html rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1 scripts/tkremind"
|
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h rem2html/Makefile rem2html/rem2html rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1 scripts/tkremind cremind/Makefile.PL"
|
||||||
|
|
||||||
cat >confcache <<\_ACEOF
|
cat >confcache <<\_ACEOF
|
||||||
# This file is a shell script that caches the results of configure
|
# This file is a shell script that caches the results of configure
|
||||||
@@ -4710,7 +4710,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by remind $as_me 05.03.00, which was
|
This file was extended by remind $as_me 05.03.02, which was
|
||||||
generated by GNU Autoconf 2.71. Invocation command line was
|
generated by GNU Autoconf 2.71. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@@ -4775,7 +4775,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
|||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config='$ac_cs_config_escaped'
|
ac_cs_config='$ac_cs_config_escaped'
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
remind config.status 05.03.00
|
remind config.status 05.03.02
|
||||||
configured by $0, generated by GNU Autoconf 2.71,
|
configured by $0, generated by GNU Autoconf 2.71,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
@@ -4911,6 +4911,7 @@ do
|
|||||||
"man/remind.1") CONFIG_FILES="$CONFIG_FILES man/remind.1" ;;
|
"man/remind.1") CONFIG_FILES="$CONFIG_FILES man/remind.1" ;;
|
||||||
"man/tkremind.1") CONFIG_FILES="$CONFIG_FILES man/tkremind.1" ;;
|
"man/tkremind.1") CONFIG_FILES="$CONFIG_FILES man/tkremind.1" ;;
|
||||||
"scripts/tkremind") CONFIG_FILES="$CONFIG_FILES scripts/tkremind" ;;
|
"scripts/tkremind") CONFIG_FILES="$CONFIG_FILES scripts/tkremind" ;;
|
||||||
|
"cremind/Makefile.PL") CONFIG_FILES="$CONFIG_FILES cremind/Makefile.PL" ;;
|
||||||
|
|
||||||
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
|
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_INIT(remind, 05.03.00, , , https://dianne.skoll.ca/projects/remind/)
|
AC_INIT(remind, 05.03.02, , , https://dianne.skoll.ca/projects/remind/)
|
||||||
AC_CONFIG_SRCDIR([src/queue.c])
|
AC_CONFIG_SRCDIR([src/queue.c])
|
||||||
|
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
@@ -95,7 +95,7 @@ AC_SUBST(VERSION)
|
|||||||
AC_SUBST(PERL)
|
AC_SUBST(PERL)
|
||||||
AC_SUBST(PERLARTIFACTS)
|
AC_SUBST(PERLARTIFACTS)
|
||||||
AC_SUBST(RELEASE_DATE)
|
AC_SUBST(RELEASE_DATE)
|
||||||
AC_CONFIG_FILES([src/Makefile www/Makefile src/version.h rem2html/Makefile rem2html/rem2html rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1 scripts/tkremind])
|
AC_CONFIG_FILES([src/Makefile www/Makefile src/version.h rem2html/Makefile rem2html/rem2html rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1 scripts/tkremind cremind/Makefile.PL])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
chmod a+x rem2pdf/bin/rem2pdf
|
chmod a+x rem2pdf/bin/rem2pdf
|
||||||
chmod a+x scripts/tkremind
|
chmod a+x scripts/tkremind
|
||||||
|
|||||||
@@ -177,7 +177,7 @@
|
|||||||
"slide" "soleq" "stdout" "strlen" "substr" "sunrise" "sunset" "time"
|
"slide" "soleq" "stdout" "strlen" "substr" "sunrise" "sunset" "time"
|
||||||
"timepart" "timezone" "today" "trig" "trigback" "trigdate"
|
"timepart" "timezone" "today" "trig" "trigback" "trigdate"
|
||||||
"trigdatetime" "trigdelta" "trigduration" "trigeventduration"
|
"trigdatetime" "trigdelta" "trigduration" "trigeventduration"
|
||||||
"trigeventstart" "trigfrom" "trigger" "trigpriority" "trigrep"
|
"trigeventstart" "trigfrom" "trigger" "triginfo" "trigpriority" "trigrep"
|
||||||
"trigscanfrom" "trigtags" "trigtime" "trigtimedelta" "trigtimerep"
|
"trigscanfrom" "trigtags" "trigtime" "trigtimedelta" "trigtimerep"
|
||||||
"triguntil" "trigvalid" "typeof" "tzconvert" "upper" "utctolocal"
|
"triguntil" "trigvalid" "typeof" "tzconvert" "upper" "utctolocal"
|
||||||
"value" "version" "weekno" "wkday" "wkdaynum" "year")
|
"value" "version" "weekno" "wkday" "wkdaynum" "year")
|
||||||
|
|||||||
21
cremind/Makefile.PL.in
Normal file
21
cremind/Makefile.PL.in
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
use ExtUtils::MakeMaker;
|
||||||
|
{
|
||||||
|
# Override pod2man options
|
||||||
|
package MY;
|
||||||
|
sub manifypods {
|
||||||
|
my ($self,%attribs) = @_;
|
||||||
|
my $result = $self->SUPER::manifypods(%attribs);
|
||||||
|
$result =~ s/^(POD2MAN_EXE\s*=\s*)(.+)$/$1$2 --center 'VERSION @VERSION@' --date '@RELEASE_DATE@'/m;
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteMakefile(
|
||||||
|
NAME => 'cremind"
|
||||||
|
AUTHOR => q{Dianne Skoll <dianne@skoll.ca>},
|
||||||
|
VERSION => '@VERSION@',
|
||||||
|
PREREQ_PM => {
|
||||||
|
'Curses::UI' => 0,
|
||||||
|
},
|
||||||
|
EXE_FILES => [ 'bin/cremind' ]
|
||||||
|
);
|
||||||
43
cremind/bin/cremind
Normal file
43
cremind/bin/cremind
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Curses::UI;
|
||||||
|
|
||||||
|
my $panes;
|
||||||
|
my $cui = Curses::UI->new(
|
||||||
|
-clear_on_exit => 1,
|
||||||
|
-color_support => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
sub check_window_size {
|
||||||
|
if ($Curses::LINES < 24 || $Curses::COLS < 80) {
|
||||||
|
$cui->dialog("This program needs a terminal window at least 24 lines by 80 columns. This one is " . $Curses::LINES . " by " . $Curses::COLS);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub create_panes {
|
||||||
|
$panes->{calendar} = $cui->add(
|
||||||
|
'calendar', 'Window',
|
||||||
|
-x => 0,
|
||||||
|
-y => 0,
|
||||||
|
-bfg => 'green',
|
||||||
|
-width => 23,
|
||||||
|
-border => 1,
|
||||||
|
-height => 10);
|
||||||
|
$panes->{calendar}->add('cal', 'TextViewer',
|
||||||
|
-text =>
|
||||||
|
" March 2025\n" .
|
||||||
|
"Su Mo Tu We Th Fr Sa\n" .
|
||||||
|
" 1 2 3 4 5 6 7\n" .
|
||||||
|
" 8 9 10 11 12 13 14\n" .
|
||||||
|
"15 16 17 18 19 20 21\n" .
|
||||||
|
"22 23 24 25 26 27 28\n" .
|
||||||
|
"29 30 31\n")
|
||||||
|
}
|
||||||
|
check_window_size();
|
||||||
|
create_panes();
|
||||||
|
alarm(3);
|
||||||
|
$cui->mainloop();
|
||||||
|
|
||||||
@@ -1,17 +1,50 @@
|
|||||||
CHANGES TO REMIND
|
CHANGES TO REMIND
|
||||||
|
|
||||||
* VERSION 5.3 Patch 0 - 2025-02-??
|
* VERSION 5.3 Patch 2 - 2025-02-09
|
||||||
|
|
||||||
|
- CHANGE: remind: Revert a change to the way "-y" tags are generated that
|
||||||
|
was introduced in 05.03.01. The change broke a library that depended
|
||||||
|
on it being generated in the old way.
|
||||||
|
|
||||||
|
* VERSION 5.3 Patch 1 - 2025-02-07
|
||||||
|
|
||||||
|
- IMPROVEMENT: TkRemind: When we pop up a timed reminder, make any "Url:"
|
||||||
|
info string into a clickable link.
|
||||||
|
|
||||||
|
- IMPROVEMENT: rem2pdf: Improve the layout of the small monthly calendars.
|
||||||
|
|
||||||
|
- BUG FIX: rem2pdf: Add checks for all Perl dependencies.
|
||||||
|
|
||||||
|
* VERSION 5.3 Patch 0 - 2025-02-04
|
||||||
|
|
||||||
- NEW FEATURE: remind: Add the "INFO" clause to the REM command. This
|
- NEW FEATURE: remind: Add the "INFO" clause to the REM command. This
|
||||||
is intended for storing additional metadata about an event, such as
|
is intended for storing additional metadata about an event, such as
|
||||||
the location and a longer description. The intention is to make
|
the location and a longer description. The intention is to make
|
||||||
Remind <-> iCal conversions preserve as much information as possible.
|
Remind <-> iCal conversions preserve as much information as possible.
|
||||||
|
|
||||||
|
- NEW FEATURE: rem2html, rem2pdf, tkremind: Add support for the "Url:"
|
||||||
|
info string that turns reminders into hyper-links. For example,
|
||||||
|
consider this reminder:
|
||||||
|
|
||||||
|
REM 15 INFO "Url: https://foo.example" MSG Foo
|
||||||
|
|
||||||
|
The text "Foo" will be made into a link to "https://foo.example"
|
||||||
|
by rem2html and rem2pdf. If you middle-click it in tkremind, it
|
||||||
|
will open the URL.
|
||||||
|
|
||||||
|
- NEW FEATURE: remind: Add the triginfo() built-in function so a reminder
|
||||||
|
body can refer to INFO data. Add the %<...> substitution filter as a
|
||||||
|
shorthand for [triginfo("...")]
|
||||||
|
|
||||||
- NEW FEATURE: TkRemind: Add "Location" and "Description" fields when
|
- NEW FEATURE: TkRemind: Add "Location" and "Description" fields when
|
||||||
creating a reminder; these are converted to INFO clauses. Also support
|
creating a reminder; these are converted to INFO clauses. Also support
|
||||||
a popup window with the extra information when hovering over a reminder
|
a popup window with the extra information when hovering over a reminder
|
||||||
in the calendar display.
|
in the calendar display.
|
||||||
|
|
||||||
|
- IMPROVEMENT: Update the reminder files included with Remind to add
|
||||||
|
INFO strings with Wikipedia URLs for various holidays and
|
||||||
|
astronomical events.
|
||||||
|
|
||||||
- IMPROVEMENT: remind: Add the "\xAB" escape sequence for parsing quoted
|
- IMPROVEMENT: remind: Add the "\xAB" escape sequence for parsing quoted
|
||||||
strings, where "AB" is a pair of hex digits.
|
strings, where "AB" is a pair of hex digits.
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
REM 1 Feb 2022 MSG %(Chinese New Year) (%(Tiger))
|
REM 1 Feb 2022 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||||
REM 22 Jan 2023 MSG %(Chinese New Year) (%(Rabbit))
|
REM 22 Jan 2023 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||||
REM 10 Feb 2024 MSG %(Chinese New Year) (%(Dragon))
|
REM 10 Feb 2024 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||||
REM 29 Jan 2025 MSG %(Chinese New Year) (%(Snake))
|
REM 29 Jan 2025 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||||
REM 17 Feb 2026 MSG %(Chinese New Year) (%(Horse))
|
REM 17 Feb 2026 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||||
REM 6 Feb 2027 MSG %(Chinese New Year) (%(Goat))
|
REM 6 Feb 2027 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||||
REM 26 Jan 2028 MSG %(Chinese New Year) (%(Monkey))
|
REM 26 Jan 2028 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||||
REM 13 Feb 2029 MSG %(Chinese New Year) (%(Rooster))
|
REM 13 Feb 2029 INFO "Url: https://en.wikipedia.org/wiki/Rooster_(zodiac)" MSG %(Chinese New Year) (%(Rooster))
|
||||||
REM 3 Feb 2030 MSG %(Chinese New Year) (%(Dog))
|
REM 3 Feb 2030 INFO "Url: https://en.wikipedia.org/wiki/Dog_(zodiac)" MSG %(Chinese New Year) (%(Dog))
|
||||||
REM 23 Jan 2031 MSG %(Chinese New Year) (%(Pig))
|
REM 23 Jan 2031 INFO "Url: https://en.wikipedia.org/wiki/Pig_(zodiac)" MSG %(Chinese New Year) (%(Pig))
|
||||||
REM 11 Feb 2032 MSG %(Chinese New Year) (%(Rat))
|
REM 11 Feb 2032 INFO "Url: https://en.wikipedia.org/wiki/Rat_(zodiac)" MSG %(Chinese New Year) (%(Rat))
|
||||||
REM 31 Jan 2033 MSG %(Chinese New Year) (%(Ox))
|
REM 31 Jan 2033 INFO "Url: https://en.wikipedia.org/wiki/Ox_(zodiac)" MSG %(Chinese New Year) (%(Ox))
|
||||||
REM 19 Feb 2034 MSG %(Chinese New Year) (%(Tiger))
|
REM 19 Feb 2034 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||||
REM 8 Feb 2035 MSG %(Chinese New Year) (%(Rabbit))
|
REM 8 Feb 2035 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||||
REM 28 Jan 2036 MSG %(Chinese New Year) (%(Dragon))
|
REM 28 Jan 2036 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||||
REM 15 Feb 2037 MSG %(Chinese New Year) (%(Snake))
|
REM 15 Feb 2037 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||||
REM 4 Feb 2038 MSG %(Chinese New Year) (%(Horse))
|
REM 4 Feb 2038 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||||
REM 24 Jan 2039 MSG %(Chinese New Year) (%(Goat))
|
REM 24 Jan 2039 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||||
REM 12 Feb 2040 MSG %(Chinese New Year) (%(Monkey))
|
REM 12 Feb 2040 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||||
REM 1 Feb 2041 MSG %(Chinese New Year) (%(Rooster))
|
REM 1 Feb 2041 INFO "Url: https://en.wikipedia.org/wiki/Rooster_(zodiac)" MSG %(Chinese New Year) (%(Rooster))
|
||||||
REM 22 Jan 2042 MSG %(Chinese New Year) (%(Dog))
|
REM 22 Jan 2042 INFO "Url: https://en.wikipedia.org/wiki/Dog_(zodiac)" MSG %(Chinese New Year) (%(Dog))
|
||||||
REM 10 Feb 2043 MSG %(Chinese New Year) (%(Pig))
|
REM 10 Feb 2043 INFO "Url: https://en.wikipedia.org/wiki/Pig_(zodiac)" MSG %(Chinese New Year) (%(Pig))
|
||||||
REM 30 Jan 2044 MSG %(Chinese New Year) (%(Rat))
|
REM 30 Jan 2044 INFO "Url: https://en.wikipedia.org/wiki/Rat_(zodiac)" MSG %(Chinese New Year) (%(Rat))
|
||||||
REM 17 Feb 2045 MSG %(Chinese New Year) (%(Ox))
|
REM 17 Feb 2045 INFO "Url: https://en.wikipedia.org/wiki/Ox_(zodiac)" MSG %(Chinese New Year) (%(Ox))
|
||||||
REM 6 Feb 2046 MSG %(Chinese New Year) (%(Tiger))
|
REM 6 Feb 2046 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||||
REM 26 Jan 2047 MSG %(Chinese New Year) (%(Rabbit))
|
REM 26 Jan 2047 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||||
REM 14 Feb 2048 MSG %(Chinese New Year) (%(Dragon))
|
REM 14 Feb 2048 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||||
REM 2 Feb 2049 MSG %(Chinese New Year) (%(Snake))
|
REM 2 Feb 2049 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||||
REM 23 Jan 2050 MSG %(Chinese New Year) (%(Horse))
|
REM 23 Jan 2050 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||||
|
|||||||
@@ -18,90 +18,90 @@ FSET _BackTwoSat(x, y) IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)-2)
|
|||||||
SET InIsrael VALUE("InIsrael", 0)
|
SET InIsrael VALUE("InIsrael", 0)
|
||||||
SET Reform VALUE("Reform", 0)
|
SET Reform VALUE("Reform", 0)
|
||||||
|
|
||||||
REM [hebdate(1, "Tishrey")] MSG Rosh Hashana 1
|
REM [hebdate(1, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Rosh_Hashanah" MSG Rosh Hashana 1
|
||||||
|
|
||||||
# No RH-2 or Tzom Gedalia in Reform
|
# No RH-2 or Tzom Gedalia in Reform
|
||||||
IF !Reform
|
IF !Reform
|
||||||
REM [hebdate(2, "Tishrey")] MSG Rosh Hashana 2
|
REM [hebdate(2, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Rosh_Hashanah" MSG Rosh Hashana 2
|
||||||
REM [_PastSat(3, "Tishrey")] MSG Tzom Gedalia
|
REM [_PastSat(3, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Fast_of_Gedalia" MSG Tzom Gedalia
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
REM [hebdate(10, "Tishrey")] MSG Yom Kippur
|
REM [hebdate(10, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Yom_Kippur" MSG Yom Kippur
|
||||||
REM [hebdate(15, "Tishrey")] MSG Sukkot 1
|
REM [hebdate(15, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Sukkot" MSG Sukkot 1
|
||||||
|
|
||||||
IF !InIsrael
|
IF !InIsrael
|
||||||
REM [hebdate(16, "Tishrey")] MSG Sukkot 2
|
REM [hebdate(16, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Sukkot" MSG Sukkot 2
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
REM [hebdate(21, "Tishrey")] MSG Hoshana Rabba
|
REM [hebdate(21, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Hoshana_Rabbah" MSG Hoshana Rabba
|
||||||
REM [hebdate(22, "Tishrey")] MSG Shemini Atzeret
|
REM [hebdate(22, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Shemini_Atzeret" MSG Shemini Atzeret
|
||||||
|
|
||||||
IF InIsrael
|
IF InIsrael
|
||||||
REM [hebdate(22, "Tishrey")] MSG Simchat Torah
|
REM [hebdate(22, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Simchat_Torah" MSG Simchat Torah
|
||||||
ELSE
|
ELSE
|
||||||
REM [hebdate(23, "Tishrey")] MSG Simchat Torah
|
REM [hebdate(23, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Simchat_Torah" MSG Simchat Torah
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
# Because Kislev can change length, we must be more careful about Chanukah
|
# Because Kislev can change length, we must be more careful about Chanukah
|
||||||
FSET _chan(x) HEBDATE(24, "Kislev", $U-9)+x
|
FSET _chan(x) HEBDATE(24, "Kislev", $U-9)+x
|
||||||
REM [_chan(1)] MSG Chanukah 1
|
REM [_chan(1)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 1
|
||||||
REM [_chan(2)] MSG Chanukah 2
|
REM [_chan(2)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 2
|
||||||
REM [_chan(3)] MSG Chanukah 3
|
REM [_chan(3)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 3
|
||||||
REM [_chan(4)] MSG Chanukah 4
|
REM [_chan(4)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 4
|
||||||
REM [_chan(5)] MSG Chanukah 5
|
REM [_chan(5)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 5
|
||||||
REM [_chan(6)] MSG Chanukah 6
|
REM [_chan(6)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 6
|
||||||
REM [_chan(7)] MSG Chanukah 7
|
REM [_chan(7)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 7
|
||||||
REM [_chan(8)] MSG Chanukah 8
|
REM [_chan(8)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 8
|
||||||
|
|
||||||
# Not sure about Reform's position on the next one.
|
# Not sure about Reform's position on the next one.
|
||||||
IF !Reform
|
IF !Reform
|
||||||
# 10 Tevet will never be a Saturday, so whether or not to
|
# 10 Tevet will never be a Saturday, so whether or not to
|
||||||
# move it is moot. (Thanks to Art Werschulz.)
|
# move it is moot. (Thanks to Art Werschulz.)
|
||||||
REM [hebdate(10, "Tevet")] MSG Tzom Tevet
|
REM [hebdate(10, "Tevet")] INFO "Url: https://en.wikipedia.org/wiki/Tenth_of_Tevet" MSG Tzom Tevet
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
REM [hebdate(15, "Shvat")] MSG Tu B'Shvat
|
REM [hebdate(15, "Shvat")] INFO "Url: https://en.wikipedia.org/wiki/Tu_BiShvat" MSG Tu B'Shvat
|
||||||
REM [hebdate(14, "Adar A")] MSG Purim Katan
|
REM [hebdate(14, "Adar A")] INFO "Url: https://en.wikipedia.org/wiki/Purim#Purim_Katan" MSG Purim Katan
|
||||||
|
|
||||||
# If Purim is on Sunday, then Fast of Esther is 11 Adar.
|
# If Purim is on Sunday, then Fast of Esther is 11 Adar.
|
||||||
IF WKDAYNUM(_h2(13, "Adar")) != 6
|
IF WKDAYNUM(_h2(13, "Adar")) != 6
|
||||||
REM [_h2(13, "Adar")] MSG Fast of Esther
|
REM [_h2(13, "Adar")] INFO "Url: https://en.wikipedia.org/wiki/Fast_of_Esther" MSG Fast of Esther
|
||||||
ELSE
|
ELSE
|
||||||
REM [_h2(11, "Adar")] MSG Fast of Esther
|
REM [_h2(11, "Adar")] INFO "Url: https://en.wikipedia.org/wiki/Fast_of_Esther" MSG Fast of Esther
|
||||||
ENDIF
|
ENDIF
|
||||||
REM [hebdate(14, "Adar")] MSG Purim
|
REM [hebdate(14, "Adar")] INFO "Url: https://en.wikipedia.org/wiki/Purim" MSG Purim
|
||||||
REM [hebdate(15, "Nisan")] MSG Pesach
|
REM [hebdate(15, "Nisan")] INFO "Url: https://en.wikipedia.org/wiki/Passover" MSG Pesach
|
||||||
|
|
||||||
IF !InIsrael
|
IF !InIsrael
|
||||||
REM [hebdate(16, "Nisan")] MSG Pesach 2
|
REM [hebdate(16, "Nisan")] INFO "Url: https://en.wikipedia.org/wiki/Passover" MSG Pesach 2
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
REM [hebdate(21, "Nisan")] MSG Pesach 7
|
REM [hebdate(21, "Nisan")] INFO "Url: https://en.wikipedia.org/wiki/Passover" MSG Pesach 7
|
||||||
|
|
||||||
IF !InIsrael && !Reform
|
IF !InIsrael && !Reform
|
||||||
REM [hebdate(22, "Nisan")] MSG Pesach 8
|
REM [hebdate(22, "Nisan")] INFO "Url: https://en.wikipedia.org/wiki/Passover" MSG Pesach 8
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
REM [hebdate(27, "Nisan")] MSG Yom HaShoah
|
REM [hebdate(27, "Nisan")] INFO "Url: https://en.wikipedia.org/wiki/Yom_HaShoah" MSG Yom HaShoah
|
||||||
REM [_BackTwoFri(4, "Iyar")] MSG Yom HaZikaron
|
REM [_BackTwoFri(4, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Yom_HaZikaron" MSG Yom HaZikaron
|
||||||
REM [_BackTwoSat(5, "Iyar")] MSG Yom Ha'atzmaut
|
REM [_BackTwoSat(5, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Independence_Day_(Israel)" MSG Yom Ha'atzmaut
|
||||||
|
|
||||||
# Not sure about Reform's position on Lag B'Omer
|
# Not sure about Reform's position on Lag B'Omer
|
||||||
IF !Reform
|
IF !Reform
|
||||||
REM [hebdate(18, "Iyar")] MSG Lag B'Omer
|
REM [hebdate(18, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Lag_BaOmer" MSG Lag B'Omer
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
REM [hebdate(28, "Iyar")] MSG Yom Yerushalayim
|
REM [hebdate(28, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Jerusalem_Day" MSG Yom Yerushalayim
|
||||||
REM [hebdate(6, "Sivan")] MSG Shavuot
|
REM [hebdate(6, "Sivan")] INFO "Url: https://en.wikipedia.org/wiki/Shavuot" MSG Shavuot
|
||||||
|
|
||||||
IF !InIsrael && !Reform
|
IF !InIsrael && !Reform
|
||||||
REM [hebdate(7, "Sivan")] MSG Shavuot 2
|
REM [hebdate(7, "Sivan")] INFO "Url: https://en.wikipedia.org/wiki/Shavuot" MSG Shavuot 2
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
# Fairly sure Reform Jews don't observe the next two
|
# Fairly sure Reform Jews don't observe the next two
|
||||||
IF !Reform
|
IF !Reform
|
||||||
# Tzom Tamuz and Tish'a B'Av are moved to Sunday if they normally
|
# Tzom Tamuz and Tish'a B'Av are moved to Sunday if they normally
|
||||||
# fall on a Saturday
|
# fall on a Saturday
|
||||||
REM [_PastSat(17, "Tamuz")] MSG Tzom Tammuz
|
REM [_PastSat(17, "Tamuz")] INFO "Url: https://en.wikipedia.org/wiki/Seventeenth_of_Tammuz" MSG Tzom Tammuz
|
||||||
REM [_PastSat(9, "Av")] MSG Tish'a B'Av
|
REM [_PastSat(9, "Av")] INFO "Url: https://en.wikipedia.org/wiki/Tisha_B%27Av" MSG Tish'a B'Av
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|||||||
@@ -4,31 +4,31 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
REM Sun 14 Feb MSG Start of Aromantic Spectrum Awareness Week
|
REM Sun 14 Feb INFO "Url: https://en.wikipedia.org/wiki/Aromantic_Spectrum_Awareness_Week" MSG Start of Aromantic Spectrum Awareness Week
|
||||||
REM 1 Mar MSG Zero Discrimination Day
|
REM 1 Mar INFO "Url: https://en.wikipedia.org/wiki/Zero_Discrimination_Day" MSG Zero Discrimination Day
|
||||||
REM 31 Mar MSG Trans Day of Visibility
|
REM 31 Mar INFO "Url: https://en.wikipedia.org/wiki/International_Transgender_Day_of_Visibility" MSG Trans Day of Visibility
|
||||||
REM 6 Apr MSG International Asexuality Day
|
REM 6 Apr INFO "Url: https://en.wikipedia.org/wiki/Asexuality#International_Asexuality_Day" MSG International Asexuality Day
|
||||||
REM Wed 8 Apr MSG International Day of Pink
|
REM Wed 8 Apr INFO "Url: https://en.wikipedia.org/wiki/International_Day_of_Pink" MSG International Day of Pink
|
||||||
REM 26 Apr MSG Lesbian Visibility Day
|
REM 26 Apr INFO "Url: https://en.wikipedia.org/wiki/Lesbian_Visibility_Day" MSG Lesbian Visibility Day
|
||||||
REM 17 May MSG International Day Against Homophobia, Biphobia and Transphobia
|
REM 17 May INFO "Url: https://en.wikipedia.org/wiki/International_Day_Against_Homophobia,_Biphobia_and_Transphobia" MSG International Day Against Homophobia, Biphobia and Transphobia
|
||||||
REM 19 May MSG Agender Pride Day
|
REM 19 May MSG Agender Pride Day
|
||||||
REM 24 May MSG Pansexual & Panromantic Awareness Day
|
REM 24 May MSG Pansexual & Panromantic Awareness Day
|
||||||
REM 1 Jun MSG Start of LGBT Pride Month
|
REM 1 Jun INFO "Url: https://en.wikipedia.org/wiki/LGBT_Pride_Month" MSG Start of LGBT Pride Month
|
||||||
REM 5 Jun MSG Aromantic Visibility Day
|
REM 5 Jun INFO "Url: https://en.wikipedia.org/wiki/Aromantic_Visibility_Day" MSG Aromantic Visibility Day
|
||||||
REM Mon 8 Jul MSG Start of Non-Binary Awareness Week
|
REM Mon 8 Jul MSG Start of Non-Binary Awareness Week
|
||||||
REM 14 Jul MSG Non-Binary People's Day
|
REM 14 Jul INFO "Url: https://en.wikipedia.org/wiki/International_Non-Binary_People%27s_Day" MSG International Non-Binary People's Day
|
||||||
REM 16 Jul MSG Drag Day
|
REM 16 Jul INFO "Url: https://en.wikipedia.org/wiki/International_Drag_Day" MSG International Drag Day
|
||||||
REM 9 Aug MSG Start of Dyke Week
|
REM 9 Aug MSG Start of Dyke Week
|
||||||
REM 16 Sep MSG Start of Bisexual Awareness Week
|
REM 16 Sep INFO "Url: https://en.wikipedia.org/wiki/Bisexual_Awareness_Week" MSG Start of Bisexual Awareness Week
|
||||||
REM 23 Sep MSG Celebrate Bisexuality Day
|
REM 23 Sep INFO "Url: https://en.wikipedia.org/wiki/Celebrate_Bisexuality_Day" MSG Celebrate Bisexuality Day
|
||||||
REM 8 Oct MSG Lesbian Day
|
REM 8 Oct MSG Lesbian Day
|
||||||
REM 11 Oct MSG National Coming Out Day
|
REM 11 Oct INFO "Url: https://en.wikipedia.org/wiki/National_Coming_Out_Day" MSG National Coming Out Day
|
||||||
REM Wed 15 Oct MSG Pronouns Day
|
REM Wed 15 Oct INFO "Url: https://en.wikipedia.org/wiki/Preferred_gender_pronoun" MSG Pronouns Day
|
||||||
REM 17 Oct MSG Start of Genderfluid Visibility Week
|
REM 17 Oct MSG Start of Genderfluid Visibility Week
|
||||||
REM Sun 19 Oct MSG Start of Ace Week
|
REM Sun 19 Oct INFO "Url: https://en.wikipedia.org/wiki/Asexuality#Ace_Week" MSG Start of Ace Week
|
||||||
REM 26 Oct MSG Intersex Awareness Day
|
REM 26 Oct INFO "Url: https://en.wikipedia.org/wiki/Intersex_Awareness_Day" MSG Intersex Awareness Day
|
||||||
REM 8 Nov MSG Intersex Day of Remembrance
|
REM 8 Nov INFO "Url: https://en.wikipedia.org/wiki/Intersex_Day_of_Remembrance" MSG Intersex Day of Remembrance
|
||||||
REM 1 Nov MSG Start of Trans Awareness Month
|
REM 1 Nov MSG Start of Trans Awareness Month
|
||||||
REM Sun 1 Nov MSG Trans Parent Day
|
REM Sun 1 Nov MSG Trans Parent Day
|
||||||
REM 13 Nov MSG Start of Trans Awareness Week
|
REM 13 Nov INFO "Url: https://en.wikipedia.org/wiki/Transgender_Awareness_Week" MSG Start of Trans Awareness Week
|
||||||
REM 20 Nov MSG Transgender Day of Remembrance
|
REM 20 Nov INFO "Url: https://en.wikipedia.org/wiki/Transgender_Day_of_Remembrance" MSG Transgender Day of Remembrance
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
# These are the holidays recognized in Australia
|
# These are the holidays recognized in Australia
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
REM Sat 1 Mar MSG Mardi Gras Parade
|
REM Sat 1 Mar INFO "Url: https://en.wikipedia.org/wiki/Sydney_Gay_and_Lesbian_Mardi_Gras" MSG Mardi Gras Parade
|
||||||
REM Fri 1 Sep --7 MSG Wear it Purple Day
|
REM Fri 1 Sep --7 INFO "Url: https://en.wikipedia.org/wiki/Wear_it_Purple_Day" MSG Wear it Purple Day
|
||||||
REM 1 Oct MSG Start of LGBT History Month
|
REM 1 Oct INFO "Url: https://en.wikipedia.org/wiki/LGBT_History_Month" MSG Start of LGBT History Month
|
||||||
|
|||||||
@@ -4,4 +4,4 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
REM 1 Oct MSG Start of LGBT History Month
|
REM 1 Oct INFO "Url: https://en.wikipedia.org/wiki/LGBT_History_Month" MSG Start of LGBT History Month
|
||||||
|
|||||||
@@ -4,4 +4,4 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
REM 9 Jul MSG Lesbian Visibility Day
|
REM 9 Jul INFO "Url: https://en.wikipedia.org/wiki/Lesbian_Visibility_Day" MSG Lesbian Visibility Day
|
||||||
|
|||||||
@@ -4,4 +4,4 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
REM 22 May MSG Irish Marriage Referendum Day
|
REM 22 May INFO "Url: https://en.wikipedia.org/wiki/Thirty-fourth_Amendment_of_the_Constitution_of_Ireland" MSG Irish Marriage Referendum Day
|
||||||
|
|||||||
@@ -4,4 +4,4 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
REM 2 Jul MSG Indian Coming Out Day
|
REM 2 Jul INFO "Url: https://en.wikipedia.org/wiki/Indian_Coming_Out_Day" MSG Indian Coming Out Day
|
||||||
|
|||||||
@@ -4,5 +4,5 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
REM 1 Feb MSG Start of LGBT History Month
|
REM 1 Feb INFO "Url: https://en.wikipedia.org/wiki/LGBT_History_Month" MSG Start of LGBT History Month
|
||||||
REM 6 May MSG Start of Trans+ History Week
|
REM 6 May INFO "Url: https://en.wikipedia.org/wiki/Trans%2B_History_Week" MSG Start of Trans+ History Week
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
REM 1 Mar MSG Start of Bisexual Health Awareness Month
|
REM 1 Mar MSG Start of Bisexual Health Awareness Month
|
||||||
REM Fri 8 Apr MSG Day of Silence
|
REM Fri 8 Apr INFO "Url: https://en.wikipedia.org/wiki/Day_of_Silence" MSG Day of Silence
|
||||||
REM 9 Apr MSG Sapphic Visibility Day
|
REM 9 Apr MSG Sapphic Visibility Day
|
||||||
REM 22 May MSG Harvey Milk Day
|
REM 22 May INFO "Url: https://en.wikipedia.org/wiki/Harvey_Milk_Day" MSG Harvey Milk Day
|
||||||
REM 5 Jun MSG HIV Long-Term Survivors Awareness Day
|
REM 5 Jun MSG HIV Long-Term Survivors Awareness Day
|
||||||
REM 12 Jun MSG Pulse Night of Remembrance
|
REM 12 Jun INFO "Url: https://en.wikipedia.org/wiki/Orlando_nightclub_shooting" MSG Pulse Night of Remembrance
|
||||||
REM 28 Jun MSG Stonewall Riots Anniversary
|
REM 28 Jun INFO "Url: https://en.wikipedia.org/wiki/Stonewall_Riots" MSG Stonewall Riots Anniversary
|
||||||
REM 1 Aug MSG Start of Transgender History Month (CA)
|
REM 1 Aug MSG Start of Transgender History Month (CA)
|
||||||
REM 1 Oct MSG Start of LGBT History Month
|
REM 1 Oct INFO "Url: https://en.wikipedia.org/wiki/LGBT_History_Month" MSG Start of LGBT History Month
|
||||||
REM Thu 15 Oct MSG Spirit Day
|
REM Thu 15 Oct INFO "Url: https://en.wikipedia.org/wiki/Spirit_Day" MSG Spirit Day
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
IF $CalMode || $PsCal
|
IF $CalMode || $PsCal
|
||||||
REM [moondate(0)] SPECIAL MOON 0 -1 -1 [moontime(0)]
|
REM [moondate(0)] INFO "Url: https://en.wikipedia.org/wiki/New_moon" SPECIAL MOON 0 -1 -1 [moontime(0)]
|
||||||
REM [moondate(1)] SPECIAL MOON 1 -1 -1 [moontime(1)]
|
REM [moondate(1)] INFO "Url: https://en.wikipedia.org/wiki/Lunar_phase" SPECIAL MOON 1 -1 -1 [moontime(1)]
|
||||||
REM [moondate(2)] SPECIAL MOON 2 -1 -1 [moontime(2)]
|
REM [moondate(2)] INFO "Url: https://en.wikipedia.org/wiki/Full_moon" SPECIAL MOON 2 -1 -1 [moontime(2)]
|
||||||
REM [moondate(3)] SPECIAL MOON 3 -1 -1 [moontime(3)]
|
REM [moondate(3)] INFO "Url: https://en.wikipedia.org/wiki/Lunar_phase" SPECIAL MOON 3 -1 -1 [moontime(3)]
|
||||||
ELSE
|
ELSE
|
||||||
REM NOQUEUE [moondatetime(0)] MSG %(New Moon) (%2)
|
REM NOQUEUE INFO "Url: https://en.wikipedia.org/wiki/New_moon" [moondatetime(0)] MSG %(New Moon) (%2)
|
||||||
REM NOQUEUE [moondatetime(1)] MSG %(First Quarter) (%2)
|
REM NOQUEUE INFO "Url: https://en.wikipedia.org/wiki/Lunar_phase" [moondatetime(1)] MSG %(First Quarter) (%2)
|
||||||
REM NOQUEUE [moondatetime(2)] MSG %(Full Moon) (%2)
|
REM NOQUEUE INFO "Url: https://en.wikipedia.org/wiki/Full_moon" [moondatetime(2)] MSG %(Full Moon) (%2)
|
||||||
REM NOQUEUE [moondatetime(3)] MSG %(Last Quarter) (%2)
|
REM NOQUEUE INFO "Url: https://en.wikipedia.org/wiki/Lunar_phase" [moondatetime(3)] MSG %(Last Quarter) (%2)
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
|
|
||||||
IF $LatDeg >= 0
|
IF $LatDeg >= 0
|
||||||
# Northern Hemisphere
|
# Northern Hemisphere
|
||||||
REM NOQUEUE [soleq(0)] MSG %"%(Vernal Equinox)%" [$Is] %3.
|
REM NOQUEUE [soleq(0)] INFO "Url: https://en.wikipedia.org/wiki/March_equinox" MSG %"%(Vernal Equinox)%" [$Is] %3.
|
||||||
REM NOQUEUE [soleq(1)] MSG %"%(Summer Solstice)%" [$Is] %3.
|
REM NOQUEUE [soleq(1)] INFO "Url: https://en.wikipedia.org/wiki/Summer_solstice" MSG %"%(Summer Solstice)%" [$Is] %3.
|
||||||
REM NOQUEUE [soleq(2)] MSG %"%(Autumnal Equinox)%" [$Is] %3.
|
REM NOQUEUE [soleq(2)] INFO "Url: https://en.wikipedia.org/wiki/September_equinox" MSG %"%(Autumnal Equinox)%" [$Is] %3.
|
||||||
REM NOQUEUE [soleq(3)] MSG %"%(Winter Solstice)%" [$Is] %3.
|
REM NOQUEUE [soleq(3)] INFO "Url: https://en.wikipedia.org/wiki/Winter_solstice" MSG %"%(Winter Solstice)%" [$Is] %3.
|
||||||
ELSE
|
ELSE
|
||||||
# Southern Hemisphere
|
# Southern Hemisphere
|
||||||
REM NOQUEUE [soleq(0)] MSG %"%(Autumnal Equinox)%" [$Is] %3.
|
REM NOQUEUE [soleq(0)] INFO "Url: https://en.wikipedia.org/wiki/March_equinox" MSG %"%(Autumnal Equinox)%" [$Is] %3.
|
||||||
REM NOQUEUE [soleq(1)] MSG %"%(Winter Solstice)%" [$Is] %3.
|
REM NOQUEUE [soleq(1)] INFO "Url: https://en.wikipedia.org/wiki/Winter_solstice" MSG %"%(Winter Solstice)%" [$Is] %3.
|
||||||
REM NOQUEUE [soleq(2)] MSG %"%(Vernal Equinox)%" [$Is] %3.
|
REM NOQUEUE [soleq(2)] INFO "Url: https://en.wikipedia.org/wiki/September_equinox" MSG %"%(Vernal Equinox)%" [$Is] %3.
|
||||||
REM NOQUEUE [soleq(3)] MSG %"%(Summer Solstice)%" [$Is] %3.
|
REM NOQUEUE [soleq(3)] INFO "Url: https://en.wikipedia.org/wiki/Summer_solstice" MSG %"%(Summer Solstice)%" [$Is] %3.
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|||||||
@@ -184,14 +184,14 @@ by the reminder's \fIdelta\fR.
|
|||||||
.TP
|
.TP
|
||||||
.B \-p\fR[\fBa\fR][\fBp\fR][\fBp\fR][\fBq\fR][+]\fIn\fR
|
.B \-p\fR[\fBa\fR][\fBp\fR][\fBp\fR][\fBq\fR][+]\fIn\fR
|
||||||
The \fB\-p\fR option is very similar to the \fB\-s\fR option, except
|
The \fB\-p\fR option is very similar to the \fB\-s\fR option, except
|
||||||
that the output contains additional information for use by a back-end such as the
|
that the output contains additional information for use by a back-end
|
||||||
\fBRem2PS\fR program, which creates a PostScript calendar, and various
|
such as the \fBRem2PS\fR program, which creates a PostScript calendar,
|
||||||
other back-end programs. If \fIn\fR starts with "+", then it specifies
|
and various other back-end programs. If \fIn\fR starts with "+", then
|
||||||
a number of weeks rather than a number of months, and back-ends are expected
|
it specifies a number of weeks rather than a number of months, and
|
||||||
to produce weekly calendars. Note that not all back-ends support
|
back-ends are expected to produce weekly calendars. Note that not all
|
||||||
weekly calendars; currently, only \fBrem2pdf\fR does. Specifying a weekly
|
back-ends support weekly calendars; currently, only \fBrem2pdf\fR and
|
||||||
calendar implicitly enables the pure JSON interchange format, similar
|
\fBrem2html\fR do. Specifying a weekly calendar implicitly enables
|
||||||
to \fB\-ppp\fR.
|
the pure JSON interchange format, similar to \fB\-ppp\fR.
|
||||||
.RS
|
.RS
|
||||||
.PP
|
.PP
|
||||||
The format of the \fB\-p\fR output is described in the \fBrem2ps(1)\fR
|
The format of the \fB\-p\fR output is described in the \fBrem2ps(1)\fR
|
||||||
@@ -207,6 +207,10 @@ format, again documented in \fBrem2ps(1)\fR. If you include a \fBq\fR
|
|||||||
letter with this option, then the normal calendar-mode substitution filter
|
letter with this option, then the normal calendar-mode substitution filter
|
||||||
is disabled and the %"...%" sequences are preserved in the output.
|
is disabled and the %"...%" sequences are preserved in the output.
|
||||||
.PP
|
.PP
|
||||||
|
Note that to pass INFO strings to a back-end, you must use \fB\-pp\fR
|
||||||
|
or \fB\-ppp\fR. The simpler \fB\-p\fR format is not capable of
|
||||||
|
transmitting the INFO strings to the back-end.
|
||||||
|
.PP
|
||||||
The \fB\-p\fR, \fB\-pp\fR and \fB\-ppp\fR options implicitly enable
|
The \fB\-p\fR, \fB\-pp\fR and \fB\-ppp\fR options implicitly enable
|
||||||
the \fB\-o\fR option.
|
the \fB\-o\fR option.
|
||||||
.PP
|
.PP
|
||||||
@@ -1661,6 +1665,11 @@ is replaced with "\fIyy\fR", the last two digits of the year.
|
|||||||
is replaced with the lookup of \fIany_text\fR in the translation table.
|
is replaced with the lookup of \fIany_text\fR in the translation table.
|
||||||
It is the equivalent of [_("any_text")] but is more convenient to type.
|
It is the equivalent of [_("any_text")] but is more convenient to type.
|
||||||
.TP
|
.TP
|
||||||
|
.B %<\fIany_text\fR\fB>
|
||||||
|
is replaced with the INFO value associated with the header \fIany_text\fR
|
||||||
|
or the empty string if no such INFO value exists. It is the
|
||||||
|
equivalent of [triginfo("any_text")] but is more convenient to type.
|
||||||
|
.TP
|
||||||
.B %_
|
.B %_
|
||||||
(percent-underscore) is replaced with a newline. You can use this to
|
(percent-underscore) is replaced with a newline. You can use this to
|
||||||
achieve multi-line reminders. Note that calendar back-ends vary in
|
achieve multi-line reminders. Note that calendar back-ends vary in
|
||||||
@@ -4292,7 +4301,23 @@ whose value is the maximum of "yyyy-mm-dd" and today.
|
|||||||
.B trigfrom()
|
.B trigfrom()
|
||||||
Returns (as a \fBDATE\fR type) the \fBFROM\fR parameter of the last \fBREM\fR or
|
Returns (as a \fBDATE\fR type) the \fBFROM\fR parameter of the last \fBREM\fR or
|
||||||
\fBIFTRIG\fR command. If there was no \fBFROM\fR parameter, returns the integer -1.
|
\fBIFTRIG\fR command. If there was no \fBFROM\fR parameter, returns the integer -1.
|
||||||
|
.TP
|
||||||
|
.B triginfo(s_header)
|
||||||
|
Returns a \fBSTRING\fR that is the INFO item associated with the header
|
||||||
|
\fIheader\fR. The header should \fInot\fR contain a colon. Header name
|
||||||
|
comparisons are case-insensitive.
|
||||||
|
.RS
|
||||||
|
.PP
|
||||||
|
For example, the following will assign "At home" to the variable a and
|
||||||
|
the empty string to variable b:
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
REM INFO "Location: At home" MSG test
|
||||||
|
SET a triginfo("location")
|
||||||
|
SET b triginfo("no_such_header")
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
.RE
|
||||||
.TP
|
.TP
|
||||||
.B trigger(d_date [,t_time [,i_utcflag]]) \fRor\fB trigger(q_datetime [,i_utcflag])
|
.B trigger(d_date [,t_time [,i_utcflag]]) \fRor\fB trigger(q_datetime [,i_utcflag])
|
||||||
Returns a string suitable for use in a \fBREM\fR command or a
|
Returns a string suitable for use in a \fBREM\fR command or a
|
||||||
|
|||||||
@@ -103,9 +103,10 @@ The sixth control specifies what \fBRemind\fR should do if a reminder
|
|||||||
falls on a holiday or weekend.
|
falls on a holiday or weekend.
|
||||||
|
|
||||||
Enter the body of the reminder into the \fBSummary:\fR text entry. If
|
Enter the body of the reminder into the \fBSummary:\fR text entry. If
|
||||||
you want, you can enter a location and longer description in the
|
you want, you can enter a location, a URL, and and longer description
|
||||||
\fBLocation:\fR and \fBDescription:\fR boxes. If you enter anything
|
in the \fBLocation:\fR, \fBURL:\fR and \fBDescription:\fR boxes. If
|
||||||
here, they will be added as \fBINFO\fR items to the reminder.
|
you enter anything here, they will be added as \fBINFO\fR items to the
|
||||||
|
reminder.
|
||||||
|
|
||||||
To add the reminder to the reminder file, click \fBAdd to reminder file\fR.
|
To add the reminder to the reminder file, click \fBAdd to reminder file\fR.
|
||||||
To close the dialog without adding the reminder to the file, click
|
To close the dialog without adding the reminder to the file, click
|
||||||
@@ -186,6 +187,11 @@ If a reminder has location or description \fBINFO\fR items, then
|
|||||||
hovering over the reminder will pop up a window containing the
|
hovering over the reminder will pop up a window containing the
|
||||||
location and/or description information.
|
location and/or description information.
|
||||||
|
|
||||||
|
.SH HYPERLINKS
|
||||||
|
|
||||||
|
If a reminder has a "Url:" INFO string set, then middle-clicking
|
||||||
|
will open the URL using \fBxdg-open\fR.
|
||||||
|
|
||||||
.SH ERRORS
|
.SH ERRORS
|
||||||
|
|
||||||
If there are any errors in your reminder file, the "Queue..." button
|
If there are any errors in your reminder file, the "Queue..." button
|
||||||
|
|||||||
@@ -128,6 +128,13 @@ The standard SPECIALs supported by all back-ends
|
|||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
|
=head1 INFO STRINGS SUPPORTED
|
||||||
|
|
||||||
|
Rem2html supports one INFO string, namely C<Url>. Its value
|
||||||
|
should be a URL. If the C<Url> INFO string is supplied for
|
||||||
|
a normal reminder, a COLOR special, a MOON special or a WEEK
|
||||||
|
special, the corresponding output is turned into a hyperlink.
|
||||||
|
|
||||||
=head1 HIGHLIGHTING TODAY
|
=head1 HIGHLIGHTING TODAY
|
||||||
|
|
||||||
Older versions of rem2html used to highlight today's date with a red outline.
|
Older versions of rem2html used to highlight today's date with a red outline.
|
||||||
@@ -359,10 +366,14 @@ sub parse_input
|
|||||||
chomp;
|
chomp;
|
||||||
last if /^\# rem2ps2? end$/;
|
last if /^\# rem2ps2? end$/;
|
||||||
next if /^\#/;
|
next if /^\#/;
|
||||||
my ($y, $m, $d, $special, $tag, $duration, $time, $body);
|
my ($y, $m, $d, $special, $tag, $duration, $time, $body, $title);
|
||||||
|
my $url_pre = '';
|
||||||
|
my $url_post = '';
|
||||||
|
my $url;
|
||||||
if (m/^(\d*).(\d*).(\d*)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*)$/) {
|
if (m/^(\d*).(\d*).(\d*)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*)$/) {
|
||||||
($y, $m, $d, $special, $tag, $duration, $time, $body) =
|
($y, $m, $d, $special, $tag, $duration, $time, $body) =
|
||||||
($1, $2, $3, $4, $5, $6, $7, $8);
|
($1, $2, $3, $4, $5, $6, $7, $8);
|
||||||
|
$title = '';
|
||||||
} elsif (/\{/) {
|
} elsif (/\{/) {
|
||||||
my $obj;
|
my $obj;
|
||||||
if ($Options{utf8}) {
|
if ($Options{utf8}) {
|
||||||
@@ -371,6 +382,11 @@ sub parse_input
|
|||||||
$obj = decode_json($_);
|
$obj = decode_json($_);
|
||||||
}
|
}
|
||||||
next unless ($obj->{date} =~ /^(\d+)-(\d+)-(\d+)$/);
|
next unless ($obj->{date} =~ /^(\d+)-(\d+)-(\d+)$/);
|
||||||
|
if ($obj->{info} && $obj->{info}->{url}) {
|
||||||
|
$url = $obj->{info}->{url};
|
||||||
|
$url_pre = "<a href=\"$url\">";
|
||||||
|
$url_post = "</a>";
|
||||||
|
}
|
||||||
$y = $1;
|
$y = $1;
|
||||||
$m = $2;
|
$m = $2;
|
||||||
$d = $3;
|
$d = $3;
|
||||||
@@ -379,6 +395,7 @@ sub parse_input
|
|||||||
$duration = $obj->{duration} || '*';
|
$duration = $obj->{duration} || '*';
|
||||||
$time = $obj->{time} || '*';
|
$time = $obj->{time} || '*';
|
||||||
$body = $obj->{body};
|
$body = $obj->{body};
|
||||||
|
$title = info_to_title($obj->{info});
|
||||||
} else {
|
} else {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
@@ -392,7 +409,8 @@ sub parse_input
|
|||||||
} elsif ($special eq 'WEEK') {
|
} elsif ($special eq 'WEEK') {
|
||||||
$body =~ s/^\s+//;
|
$body =~ s/^\s+//;
|
||||||
$body =~ s/\s+$//;
|
$body =~ s/\s+$//;
|
||||||
$weeks->{$d1} = $body;
|
$weeks->{$d1}->{body} = $body;
|
||||||
|
$weeks->{$d1}->{url} = $url;
|
||||||
} elsif ($special eq 'MOON') {
|
} elsif ($special eq 'MOON') {
|
||||||
if ($body =~ /(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) {
|
if ($body =~ /(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) {
|
||||||
my ($phase, $moonsize, $fontsize, $msg) = ($1, $2, $3, $4);
|
my ($phase, $moonsize, $fontsize, $msg) = ($1, $2, $3, $4);
|
||||||
@@ -402,6 +420,7 @@ sub parse_input
|
|||||||
$moons->[$d]->{'phase'} = $1;
|
$moons->[$d]->{'phase'} = $1;
|
||||||
$moons->[$d]->{'msg'} = '';
|
$moons->[$d]->{'msg'} = '';
|
||||||
}
|
}
|
||||||
|
$moons->[$d]->{url} = $url;
|
||||||
} elsif ($special eq 'SHADE') {
|
} elsif ($special eq 'SHADE') {
|
||||||
if ($body =~ /(\d+)\s+(\d+)\s+(\d+)/) {
|
if ($body =~ /(\d+)\s+(\d+)\s+(\d+)/) {
|
||||||
$shades->[$d] = sprintf("#%02X%02X%02X",
|
$shades->[$d] = sprintf("#%02X%02X%02X",
|
||||||
@@ -415,10 +434,10 @@ sub parse_input
|
|||||||
my($r, $g, $b, $text) = ($1, $2, $3, $4);
|
my($r, $g, $b, $text) = ($1, $2, $3, $4);
|
||||||
my $color = sprintf("style=\"color: #%02X%02X%02X;\"",
|
my $color = sprintf("style=\"color: #%02X%02X%02X;\"",
|
||||||
$r % 256, $g % 256, $b % 256);
|
$r % 256, $g % 256, $b % 256);
|
||||||
push(@{$days->[$d]}, "<p$class $color>" . fix_whitespace(escape_html($text)) . '</p>');
|
push(@{$days->[$d]}, "<p$class$title $color>" . $url_pre . fix_whitespace(escape_html($text)) . $url_post . '</p>');
|
||||||
}
|
}
|
||||||
} elsif ($special eq '*') {
|
} elsif ($special eq '*') {
|
||||||
push(@{$days->[$d]}, "<p$class>" . fix_whitespace(escape_html($body)) . '</p>');
|
push(@{$days->[$d]}, "<p$class$title>" . $url_pre . fix_whitespace(escape_html($body)) . $url_post . '</p>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $found_data;
|
return $found_data;
|
||||||
@@ -477,6 +496,29 @@ sub emit_ppp_calendars
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub info_to_title
|
||||||
|
{
|
||||||
|
my ($info) = @_;
|
||||||
|
if (!$info) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
my $done_one = 0;
|
||||||
|
my $title = '';
|
||||||
|
foreach my $key ('location', 'description') {
|
||||||
|
next unless $info->{$key};
|
||||||
|
if ($done_one) {
|
||||||
|
$title .= "
";
|
||||||
|
}
|
||||||
|
$done_one = 1;
|
||||||
|
my $val = escape_html($info->{$key});
|
||||||
|
$val =~ s/\n/
/g;
|
||||||
|
$val =~ s/"/"/g;
|
||||||
|
$val =~ s/</</g;
|
||||||
|
$title .= ucfirst($key) . ': ' . $val;
|
||||||
|
}
|
||||||
|
return " title=\"$title\"";
|
||||||
|
}
|
||||||
|
|
||||||
sub emit_one_ppp_calendar
|
sub emit_one_ppp_calendar
|
||||||
{
|
{
|
||||||
my ($c, $type) = @_;
|
my ($c, $type) = @_;
|
||||||
@@ -537,6 +579,15 @@ sub emit_one_ppp_calendar
|
|||||||
my $duration = $obj->{duration} || '*';
|
my $duration = $obj->{duration} || '*';
|
||||||
my $time = $obj->{time} || '*';
|
my $time = $obj->{time} || '*';
|
||||||
my $body = $obj->{body};
|
my $body = $obj->{body};
|
||||||
|
my $title = info_to_title($obj->{info});
|
||||||
|
my $url_pre = '';
|
||||||
|
my $url_post = '';
|
||||||
|
my $url = '';
|
||||||
|
if ($obj->{info} && $obj->{info}->{url}) {
|
||||||
|
$url = $obj->{info}->{url};
|
||||||
|
$url_pre = "<a href=\"$url\">";
|
||||||
|
$url_post = "</a>";
|
||||||
|
}
|
||||||
$special = uc($special);
|
$special = uc($special);
|
||||||
if ($special eq 'HTML') {
|
if ($special eq 'HTML') {
|
||||||
push(@{$days->[$col]}, $body);
|
push(@{$days->[$col]}, $body);
|
||||||
@@ -545,7 +596,8 @@ sub emit_one_ppp_calendar
|
|||||||
} elsif ($special eq 'WEEK') {
|
} elsif ($special eq 'WEEK') {
|
||||||
$body =~ s/^\s+//;
|
$body =~ s/^\s+//;
|
||||||
$body =~ s/\s+$//;
|
$body =~ s/\s+$//;
|
||||||
$weeks->{$col} = $body;
|
$weeks->{$col}->{body} = $body;
|
||||||
|
$weeks->{$col}->{url} = $url;
|
||||||
} elsif ($special eq 'MOON') {
|
} elsif ($special eq 'MOON') {
|
||||||
if ($body =~ /(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) {
|
if ($body =~ /(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) {
|
||||||
my ($phase, $moonsize, $fontsize, $msg) = ($1, $2, $3, $4);
|
my ($phase, $moonsize, $fontsize, $msg) = ($1, $2, $3, $4);
|
||||||
@@ -555,6 +607,7 @@ sub emit_one_ppp_calendar
|
|||||||
$moons->[$col]->{'phase'} = $1;
|
$moons->[$col]->{'phase'} = $1;
|
||||||
$moons->[$col]->{'msg'} = '';
|
$moons->[$col]->{'msg'} = '';
|
||||||
}
|
}
|
||||||
|
$moons->[$col]->{url} = $url;
|
||||||
} elsif ($special eq 'SHADE') {
|
} elsif ($special eq 'SHADE') {
|
||||||
if ($body =~ /(\d+)\s+(\d+)\s+(\d+)/) {
|
if ($body =~ /(\d+)\s+(\d+)\s+(\d+)/) {
|
||||||
$shades->[$col] = sprintf("#%02X%02X%02X",
|
$shades->[$col] = sprintf("#%02X%02X%02X",
|
||||||
@@ -568,10 +621,10 @@ sub emit_one_ppp_calendar
|
|||||||
my($r, $g, $b, $text) = ($1, $2, $3, $4);
|
my($r, $g, $b, $text) = ($1, $2, $3, $4);
|
||||||
my $color = sprintf("style=\"color: #%02X%02X%02X;\"",
|
my $color = sprintf("style=\"color: #%02X%02X%02X;\"",
|
||||||
$r % 256, $g % 256, $b % 256);
|
$r % 256, $g % 256, $b % 256);
|
||||||
push(@{$days->[$col]}, "<p$class $color>" . fix_whitespace(escape_html($text)) . '</p>');
|
push(@{$days->[$col]}, "<p$class$title $color>" . $url_pre . fix_whitespace(escape_html($text)) . $url_post . '</p>');
|
||||||
}
|
}
|
||||||
} elsif ($special eq '*') {
|
} elsif ($special eq '*') {
|
||||||
push(@{$days->[$col]}, "<p$class>" . fix_whitespace(escape_html($body)) . '</p>');
|
push(@{$days->[$col]}, "<p$class$title>" . $url_pre . fix_whitespace(escape_html($body)) . $url_post . '</p>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output_calendar($type, $cols_to_date_info);
|
output_calendar($type, $cols_to_date_info);
|
||||||
@@ -846,7 +899,11 @@ sub draw_day_cell
|
|||||||
my $shade = $shades->[$day];
|
my $shade = $shades->[$day];
|
||||||
my $week = '';
|
my $week = '';
|
||||||
if (exists($weeks->{$day})) {
|
if (exists($weeks->{$day})) {
|
||||||
$week = ' ' . $weeks->{$day};
|
if ($weeks->{$day}->{url}) {
|
||||||
|
$week = ' <a href="' . $weeks->{$day}->{url} . '">' . escape_html($weeks->{$day}->{body}) . '</a>';
|
||||||
|
} else {
|
||||||
|
$week = ' ' . escape_html($weeks->{$day}->{body});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
my $class;
|
my $class;
|
||||||
if ($Options{nostyle}) {
|
if ($Options{nostyle}) {
|
||||||
@@ -907,10 +964,16 @@ sub draw_day_cell
|
|||||||
$alt = 'last';
|
$alt = 'last';
|
||||||
$title = escape_html(t('Last Quarter'));
|
$title = escape_html(t('Last Quarter'));
|
||||||
}
|
}
|
||||||
|
my $url_pre = '';
|
||||||
|
my $url_post = '';
|
||||||
|
if ($moons->[$day]->{url}) {
|
||||||
|
$url_pre = '<a href="' . $moons->[$day]->{url} . '">';
|
||||||
|
$url_post = '</a>';
|
||||||
|
}
|
||||||
if ($Options{nostyle}) {
|
if ($Options{nostyle}) {
|
||||||
print("<div style=\"float: left\"><img border=\"0\" width=\"16\" height=\"16\" alt=\"$alt\" title=\"$title\" src=\"$img\">$msg</div>");
|
print("<div style=\"float: left\">$url_pre<img border=\"0\" width=\"16\" height=\"16\" alt=\"$alt\" title=\"$title\" src=\"$img\">msg$url_post</div>");
|
||||||
} else {
|
} else {
|
||||||
print("<div class=\"rem-moon\"><img width=\"16\" height=\"16\" alt=\"$alt\" title=\"$title\" src=\"$img\">$msg</div>");
|
print("<div class=\"rem-moon\">$url_pre<img width=\"16\" height=\"16\" alt=\"$alt\" title=\"$title\" src=\"$img\">$msg$url_post</div>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ WriteMakefile(
|
|||||||
'Getopt::Long' => 0,
|
'Getopt::Long' => 0,
|
||||||
'Cairo' => 0,
|
'Cairo' => 0,
|
||||||
'Pango' => 0,
|
'Pango' => 0,
|
||||||
|
'JSON::MaybeXS' => 0,
|
||||||
|
'Encode' => 0,
|
||||||
},
|
},
|
||||||
EXE_FILES => [ 'bin/rem2pdf' ]
|
EXE_FILES => [ 'bin/rem2pdf' ]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,16 +7,18 @@ bindir=@bindir@
|
|||||||
datadir=@datadir@
|
datadir=@datadir@
|
||||||
datarootdir=@datarootdir@
|
datarootdir=@datarootdir@
|
||||||
PERL=@PERL@
|
PERL=@PERL@
|
||||||
PERLMODS_NEEDED=Getopt::Long Cairo Pango
|
PERLMODS_NEEDED=Cairo Encode ExtUtils::MakeMaker Getopt::Long JSON::MaybeXS Pango
|
||||||
|
|
||||||
all: Makefile
|
all: Makefile
|
||||||
@if test "$(PERL)" = "" ; then \
|
@if test "$(PERL)" = "" ; then \
|
||||||
echo "Not building rem2pdf; Perl is required"; exit 0; fi; \
|
echo "Not building rem2pdf; Perl is required"; exit 0; fi; \
|
||||||
|
OK=1; \
|
||||||
for m in $(PERLMODS_NEEDED) ; \
|
for m in $(PERLMODS_NEEDED) ; \
|
||||||
do \
|
do \
|
||||||
$(PERL) -M$$m -e 1 > /dev/null 2>&1; \
|
$(PERL) -M$$m -e 1 > /dev/null 2>&1; \
|
||||||
if test $$? != 0 ; then echo "Not building rem2pdf; missing $$m"; exit 0; fi; \
|
if test $$? != 0 ; then echo "Missing Perl module: $$m"; OK=0; fi; \
|
||||||
done; \
|
done; \
|
||||||
|
if test "$$OK" != "1" ; then echo "Not building rem2pdf because of missing perl module(s)"; exit 0; fi; \
|
||||||
$(MAKE) all && exit 0; \
|
$(MAKE) all && exit 0; \
|
||||||
exit 1;
|
exit 1;
|
||||||
|
|
||||||
|
|||||||
@@ -573,6 +573,13 @@ it is syntactically correct. If you use invalid Pango markup, the
|
|||||||
Pango library will print a warning and B<rem2pdf> will not render any
|
Pango library will print a warning and B<rem2pdf> will not render any
|
||||||
output for the invalid reminder.
|
output for the invalid reminder.
|
||||||
|
|
||||||
|
=head1 INFO STRINGS SUPPORTED
|
||||||
|
|
||||||
|
rem2pdf supports one INFO string, namely C<Url>. Its value should be
|
||||||
|
a URL. If the C<Url> INFO string is supplied for a normal reminder, a
|
||||||
|
COLOR special, a MOON special, a PANGO special or a WEEK special, the
|
||||||
|
corresponding output is turned into a hyperlink.
|
||||||
|
|
||||||
=head1 WEEKLY CALENDARS
|
=head1 WEEKLY CALENDARS
|
||||||
|
|
||||||
B<rem2pdf> will produce weekly calendars if you invoke B<remind> with the
|
B<rem2pdf> will produce weekly calendars if you invoke B<remind> with the
|
||||||
|
|||||||
@@ -821,7 +821,6 @@ sub draw_small_calendar
|
|||||||
$layout->set_text('88 ');
|
$layout->set_text('88 ');
|
||||||
my ($wid, $h) = $layout->get_pixel_size();
|
my ($wid, $h) = $layout->get_pixel_size();
|
||||||
$h += 1;
|
$h += 1;
|
||||||
|
|
||||||
# Month name
|
# Month name
|
||||||
$layout = Pango::Cairo::create_layout($cr);
|
$layout = Pango::Cairo::create_layout($cr);
|
||||||
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
|
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
|
||||||
@@ -835,6 +834,7 @@ sub draw_small_calendar
|
|||||||
|
|
||||||
$y += $h;
|
$y += $h;
|
||||||
# Day names
|
# Day names
|
||||||
|
$wid = $width / 7;
|
||||||
for (my $col=0; $col <7; $col++) {
|
for (my $col=0; $col <7; $col++) {
|
||||||
my $j;
|
my $j;
|
||||||
if ($self->{mondayfirst}) {
|
if ($self->{mondayfirst}) {
|
||||||
@@ -860,7 +860,11 @@ sub draw_small_calendar
|
|||||||
for (my $d=1; $d <= $days; $d++) {
|
for (my $d=1; $d <= $days; $d++) {
|
||||||
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
|
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
|
||||||
$layout->set_font_description($desc);
|
$layout->set_font_description($desc);
|
||||||
$layout->set_text($d);
|
my $dt = $d;
|
||||||
|
if (length($dt) < 2) {
|
||||||
|
$dt = ' ' . $dt;
|
||||||
|
}
|
||||||
|
$layout->set_text($dt);
|
||||||
$cr->save();
|
$cr->save();
|
||||||
$cr->move_to($x + $col*$wid, $y);
|
$cr->move_to($x + $col*$wid, $y);
|
||||||
Pango::Cairo::show_layout($cr, $layout);
|
Pango::Cairo::show_layout($cr, $layout);
|
||||||
@@ -892,20 +896,23 @@ sub calculate_small_calendar_font_size
|
|||||||
my $font_size = int($scale * 10);
|
my $font_size = int($scale * 10);
|
||||||
|
|
||||||
# Check
|
# Check
|
||||||
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
|
while(1) {
|
||||||
$layout->set_font_description($desc);
|
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
|
||||||
$layout->set_text('88 88 88 88 88 88 88');
|
$layout->set_font_description($desc);
|
||||||
($wid, $h) = $layout->get_pixel_size();
|
$layout->set_text('88 88 88 88 88 88 88');
|
||||||
$h += 1;
|
($wid, $h) = $layout->get_pixel_size();
|
||||||
$h *= ($rows + 2); # row for month name; row for day names
|
$h += 1;
|
||||||
|
$h *= ($rows + 2); # row for month name; row for day names
|
||||||
|
|
||||||
$scale = $width / $wid;
|
$scale = $width / $wid;
|
||||||
if (($height / $h) < $scale) {
|
if (($height / $h) < $scale) {
|
||||||
$scale = $height / $h;
|
$scale = $height / $h;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($scale < 1) { # Font size is too big
|
if ($scale >= 1) { # Font size is OK
|
||||||
$font_size--;
|
last;
|
||||||
|
}
|
||||||
|
$font_size -= 0.1;
|
||||||
}
|
}
|
||||||
return $font_size;
|
return $font_size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,10 @@ sub render
|
|||||||
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
|
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
|
||||||
my $layout = Pango::Cairo::create_layout($cr);
|
my $layout = Pango::Cairo::create_layout($cr);
|
||||||
|
|
||||||
|
my $url;
|
||||||
|
if ($self->{info} && $self->{info}->{url}) {
|
||||||
|
$url = $self->{info}->{url};
|
||||||
|
}
|
||||||
$layout->set_width(1024 * ($x2 - $x1 - 2 * $settings->{border_size}));
|
$layout->set_width(1024 * ($x2 - $x1 - 2 * $settings->{border_size}));
|
||||||
$layout->set_wrap('word-char');
|
$layout->set_wrap('word-char');
|
||||||
my $body;
|
my $body;
|
||||||
@@ -108,7 +112,13 @@ sub render
|
|||||||
$self->{g} / 255,
|
$self->{g} / 255,
|
||||||
$self->{b} / 255);
|
$self->{b} / 255);
|
||||||
$cr->move_to($x1 + $settings->{border_size}, $so_far);
|
$cr->move_to($x1 + $settings->{border_size}, $so_far);
|
||||||
|
if ($url) {
|
||||||
|
$cr->tag_begin(Cairo::TAG_LINK, "uri='$url'");
|
||||||
|
}
|
||||||
Pango::Cairo::show_layout($cr, $layout);
|
Pango::Cairo::show_layout($cr, $layout);
|
||||||
|
if ($url) {
|
||||||
|
$cr->tag_end(Cairo::TAG_LINK);
|
||||||
|
}
|
||||||
$cr->restore();
|
$cr->restore();
|
||||||
}
|
}
|
||||||
return $h;
|
return $h;
|
||||||
@@ -142,7 +152,18 @@ sub render
|
|||||||
|
|
||||||
$cr->save();
|
$cr->save();
|
||||||
$cr->move_to($x2 - $settings->{border_size}/4 - $wid, $y2 - $settings->{border_size}/4 - $h);
|
$cr->move_to($x2 - $settings->{border_size}/4 - $wid, $y2 - $settings->{border_size}/4 - $h);
|
||||||
|
my $url;
|
||||||
|
if ($self->{info} && $self->{info}->{url}) {
|
||||||
|
$url = $self->{info}->{url};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($url) {
|
||||||
|
$cr->tag_begin(Cairo::TAG_LINK, "uri='$url'");
|
||||||
|
}
|
||||||
Pango::Cairo::show_layout($cr, $layout);
|
Pango::Cairo::show_layout($cr, $layout);
|
||||||
|
if ($url) {
|
||||||
|
$cr->tag_end(Cairo::TAG_LINK);
|
||||||
|
}
|
||||||
$cr->restore();
|
$cr->restore();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -204,12 +225,30 @@ sub render
|
|||||||
$xc = $x1 + $settings->{border_size} + ($self->{size} / 2);
|
$xc = $x1 + $settings->{border_size} + ($self->{size} / 2);
|
||||||
$yc = $so_far + $settings->{border_size} + ($self->{size} / 2);
|
$yc = $so_far + $settings->{border_size} + ($self->{size} / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $url;
|
||||||
|
if ($self->{info} && $self->{info}->{url}) {
|
||||||
|
$url = $self->{info}->{url};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($url) {
|
||||||
|
$cr->tag_begin(Cairo::TAG_LINK, "uri='$url'");
|
||||||
|
}
|
||||||
$self->draw_moon($xc, $yc, $cr);
|
$self->draw_moon($xc, $yc, $cr);
|
||||||
|
if ($url) {
|
||||||
|
$cr->tag_end(Cairo::TAG_LINK);
|
||||||
|
}
|
||||||
if ($layout) {
|
if ($layout) {
|
||||||
$cr->save();
|
$cr->save();
|
||||||
$cr->move_to ($xc + ($self->{size}/2) + $settings->{border_size},
|
$cr->move_to ($xc + ($self->{size}/2) + $settings->{border_size},
|
||||||
$yc + ($self->{size}/2) - $self->{fontsize} );
|
$yc + ($self->{size}/2) - $self->{fontsize} );
|
||||||
|
if ($url) {
|
||||||
|
$cr->tag_begin(Cairo::TAG_LINK, "uri='$url'");
|
||||||
|
}
|
||||||
Pango::Cairo::show_layout($cr, $layout);
|
Pango::Cairo::show_layout($cr, $layout);
|
||||||
|
if ($url) {
|
||||||
|
$cr->tag_end(Cairo::TAG_LINK);
|
||||||
|
}
|
||||||
$cr->restore();
|
$cr->restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,6 +323,10 @@ sub render
|
|||||||
my ($self, $pdf, $cr, $settings, $so_far, $day, $col, $height) = @_;
|
my ($self, $pdf, $cr, $settings, $so_far, $day, $col, $height) = @_;
|
||||||
|
|
||||||
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
|
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
|
||||||
|
my $url;
|
||||||
|
if ($self->{info} && $self->{info}->{url}) {
|
||||||
|
$url = $self->{info}->{url};
|
||||||
|
}
|
||||||
my $layout = Pango::Cairo::create_layout($cr);
|
my $layout = Pango::Cairo::create_layout($cr);
|
||||||
|
|
||||||
$layout->set_width(1024 * ($x2 - $x1 - 2 * $settings->{border_size}));
|
$layout->set_width(1024 * ($x2 - $x1 - 2 * $settings->{border_size}));
|
||||||
@@ -316,7 +359,13 @@ sub render
|
|||||||
} else {
|
} else {
|
||||||
$cr->move_to($x1 + $settings->{border_size}, $so_far);
|
$cr->move_to($x1 + $settings->{border_size}, $so_far);
|
||||||
}
|
}
|
||||||
|
if ($url) {
|
||||||
|
$cr->tag_begin(Cairo::TAG_LINK, "uri='$url'");
|
||||||
|
}
|
||||||
Pango::Cairo::show_layout($cr, $layout);
|
Pango::Cairo::show_layout($cr, $layout);
|
||||||
|
if ($url) {
|
||||||
|
$cr->tag_end(Cairo::TAG_LINK);
|
||||||
|
}
|
||||||
$cr->restore();
|
$cr->restore();
|
||||||
}
|
}
|
||||||
return $h;
|
return $h;
|
||||||
|
|||||||
@@ -585,6 +585,7 @@ proc CreateCalFrame { w dayNames } {
|
|||||||
-highlightthickness 0
|
-highlightthickness 0
|
||||||
frame $w.f$f -padx 0 -pady 0 -highlightthickness 0 -relief flat -bd 0
|
frame $w.f$f -padx 0 -pady 0 -highlightthickness 0 -relief flat -bd 0
|
||||||
$w.t$f tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$f"
|
$w.t$f tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$f"
|
||||||
|
$w.t$f tag bind REM <ButtonPress-2> "OpenUrl $w.t$f"
|
||||||
$w.t$f tag bind REM <ButtonPress-3> "FireEditor $w.t$f"
|
$w.t$f tag bind REM <ButtonPress-3> "FireEditor $w.t$f"
|
||||||
pack $w.l$f -in $w.f$f -side top -expand 0 -fill x
|
pack $w.l$f -in $w.f$f -side top -expand 0 -fill x
|
||||||
pack $w.t$f -in $w.f$f -side top -expand 1 -fill both
|
pack $w.t$f -in $w.f$f -side top -expand 1 -fill both
|
||||||
@@ -635,6 +636,7 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
|||||||
$w.t$i tag delete $t
|
$w.t$i tag delete $t
|
||||||
}
|
}
|
||||||
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
|
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
|
||||||
|
$w.t$i tag bind REM <ButtonPress-2> "OpenUrl $w.t$i"
|
||||||
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
|
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
|
||||||
$w.t$i configure -state disabled -takefocus 0
|
$w.t$i configure -state disabled -takefocus 0
|
||||||
}
|
}
|
||||||
@@ -656,6 +658,7 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
|||||||
$w.t$i tag delete $t
|
$w.t$i tag delete $t
|
||||||
}
|
}
|
||||||
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
|
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
|
||||||
|
$w.t$i tag bind REM <ButtonPress-2> "OpenUrl $w.t$i"
|
||||||
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
|
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
|
||||||
$w.t$i configure -state disabled -takefocus 0
|
$w.t$i configure -state disabled -takefocus 0
|
||||||
}
|
}
|
||||||
@@ -686,6 +689,7 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
|||||||
$w.t$i tag delete $t
|
$w.t$i tag delete $t
|
||||||
}
|
}
|
||||||
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
|
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
|
||||||
|
$w.t$i tag bind REM <ButtonPress-2> "OpenUrl $w.t$i"
|
||||||
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
|
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
|
||||||
$w.t$i configure -state disabled -takefocus 0
|
$w.t$i configure -state disabled -takefocus 0
|
||||||
}
|
}
|
||||||
@@ -1925,24 +1929,31 @@ proc CreateModifyDialog {w day firstDay args} {
|
|||||||
grid $w.msglab -row 0 -column 0 -in $w.msg -sticky e
|
grid $w.msglab -row 0 -column 0 -in $w.msg -sticky e
|
||||||
grid $w.entry -row 0 -column 1 -in $w.msg -sticky nsew
|
grid $w.entry -row 0 -column 1 -in $w.msg -sticky nsew
|
||||||
|
|
||||||
# LOCATION and DESCRIPTION
|
# LOCATION, DESCRIPTION and URL
|
||||||
label $w.loclab -text "Location: "
|
label $w.loclab -text "Location: "
|
||||||
entry $w.location
|
entry $w.location
|
||||||
balloon_add_help $w.location "Enter the location, if any"
|
balloon_add_help $w.location "Enter the location, if any"
|
||||||
grid $w.loclab -row 1 -column 0 -in $w.msg -sticky e
|
grid $w.loclab -row 1 -column 0 -in $w.msg -sticky e
|
||||||
grid $w.location -row 1 -column 1 -in $w.msg -sticky nsew
|
grid $w.location -row 1 -column 1 -in $w.msg -sticky nsew
|
||||||
|
|
||||||
|
label $w.urllab -text "URL: "
|
||||||
|
entry $w.url
|
||||||
|
balloon_add_help $w.url "Enter the URL, if any"
|
||||||
|
grid $w.urllab -row 2 -column 0 -in $w.msg -sticky e
|
||||||
|
grid $w.url -row 2 -column 1 -in $w.msg -sticky nsew
|
||||||
|
|
||||||
label $w.desclab -text "Description: "
|
label $w.desclab -text "Description: "
|
||||||
text $w.description -width 80 -height 5
|
text $w.description -width 80 -height 5
|
||||||
balloon_add_help $w.description "Enter a detailed description, if any"
|
balloon_add_help $w.description "Enter a detailed description, if any"
|
||||||
grid $w.desclab -row 2 -column 0 -in $w.msg -sticky e
|
grid $w.desclab -row 3 -column 0 -in $w.msg -sticky e
|
||||||
grid $w.description -row 2 -column 1 -in $w.msg -sticky nsew
|
grid $w.description -row 3 -column 1 -in $w.msg -sticky nsew
|
||||||
|
|
||||||
grid columnconfigure $w.msg 0 -weight 0
|
grid columnconfigure $w.msg 0 -weight 0
|
||||||
grid columnconfigure $w.msg 1 -weight 1
|
grid columnconfigure $w.msg 1 -weight 1
|
||||||
grid rowconfigure $w.msg 0 -weight 0
|
grid rowconfigure $w.msg 0 -weight 0
|
||||||
grid rowconfigure $w.msg 1 -weight 0
|
grid rowconfigure $w.msg 1 -weight 0
|
||||||
grid rowconfigure $w.msg 2 -weight 1
|
grid rowconfigure $w.msg 2 -weight 0
|
||||||
|
grid rowconfigure $w.msg 3 -weight 1
|
||||||
# BUTTONS
|
# BUTTONS
|
||||||
set nbut 0
|
set nbut 0
|
||||||
foreach but $args {
|
foreach but $args {
|
||||||
@@ -2309,6 +2320,11 @@ proc CreateReminder {w} {
|
|||||||
set description "Description: $description"
|
set description "Description: $description"
|
||||||
append rem " INFO [RemQuotedString $description]"
|
append rem " INFO [RemQuotedString $description]"
|
||||||
}
|
}
|
||||||
|
set url [string trim [$w.url get]]
|
||||||
|
if {$url != ""} {
|
||||||
|
set url "Url: $url"
|
||||||
|
append rem " INFO [RemQuotedString $url]"
|
||||||
|
}
|
||||||
# Check it out!
|
# Check it out!
|
||||||
global Remind
|
global Remind
|
||||||
set f [open "|$Remind -arq -e - 2>@1" r+]
|
set f [open "|$Remind -arq -e - 2>@1" r+]
|
||||||
@@ -2969,11 +2985,16 @@ proc DaemonReadable { file } {
|
|||||||
set tag [dict get $obj tags]
|
set tag [dict get $obj tags]
|
||||||
}
|
}
|
||||||
set body [dict get $obj body]
|
set body [dict get $obj body]
|
||||||
|
if {[dict exists $obj info]} {
|
||||||
|
set info [dict get $obj info]
|
||||||
|
} else {
|
||||||
|
set info [dict create]
|
||||||
|
}
|
||||||
set qid "*"
|
set qid "*"
|
||||||
if {[dict exists $obj qid]} {
|
if {[dict exists $obj qid]} {
|
||||||
set qid [dict get $obj qid]
|
set qid [dict get $obj qid]
|
||||||
}
|
}
|
||||||
IssueBackgroundReminder $body $time $now $tag $qid
|
IssueBackgroundReminder $body $time $now $tag $qid $info
|
||||||
}
|
}
|
||||||
"queue" {
|
"queue" {
|
||||||
set queue [dict get $obj queue]
|
set queue [dict get $obj queue]
|
||||||
@@ -3017,7 +3038,7 @@ proc DaemonReadable { file } {
|
|||||||
# Description:
|
# Description:
|
||||||
# Reads a background reminder from daemon and pops up window.
|
# Reads a background reminder from daemon and pops up window.
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
proc IssueBackgroundReminder { body time now tag qid } {
|
proc IssueBackgroundReminder { body time now tag qid info } {
|
||||||
global BgCounter Option Ignore DaemonFile HAVE_SYSNOTIFY NOTIFY_SEND_PATH
|
global BgCounter Option Ignore DaemonFile HAVE_SYSNOTIFY NOTIFY_SEND_PATH
|
||||||
if {$Option(Deiconify)} {
|
if {$Option(Deiconify)} {
|
||||||
wm deiconify .
|
wm deiconify .
|
||||||
@@ -3046,7 +3067,7 @@ proc IssueBackgroundReminder { body time now tag qid } {
|
|||||||
wm iconname $w "Reminder"
|
wm iconname $w "Reminder"
|
||||||
wm title $w "Timed reminder ($time)"
|
wm title $w "Timed reminder ($time)"
|
||||||
label $w.l -text "Reminder for $time issued at $now"
|
label $w.l -text "Reminder for $time issued at $now"
|
||||||
message $w.msg -width 6i -text $body
|
message $w.msg -aspect 2000 -text $body -justify left -anchor w -font {-weight bold} -relief groove -bd 2
|
||||||
frame $w.b
|
frame $w.b
|
||||||
|
|
||||||
# Automatically shut down window after a minute if option says so
|
# Automatically shut down window after a minute if option says so
|
||||||
@@ -3062,7 +3083,36 @@ proc IssueBackgroundReminder { body time now tag qid } {
|
|||||||
button $w.nomore -text "Don't remind me again today" -command [list ClosePopup $w $after_token "" 1 "ignore" $tag $body $time $qid]
|
button $w.nomore -text "Don't remind me again today" -command [list ClosePopup $w $after_token "" 1 "ignore" $tag $body $time $qid]
|
||||||
}
|
}
|
||||||
pack $w.l -side top
|
pack $w.l -side top
|
||||||
pack $w.msg -side top -expand 1 -fill both
|
pack $w.msg -side top -expand 1 -fill both -anchor w
|
||||||
|
frame $w.f
|
||||||
|
pack $w.f -side top -expand 1 -fill both
|
||||||
|
set row 0
|
||||||
|
if {[dict exists $info location]} {
|
||||||
|
label $w.f.l1 -text "Location: " -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight bold}
|
||||||
|
message $w.f.l2 -text [dict get $info location] -justify left -anchor w -aspect 2000 -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight normal}
|
||||||
|
grid $w.f.l1 -row $row -column 0 -sticky nw
|
||||||
|
grid $w.f.l2 -row $row -column 1 -sticky new
|
||||||
|
incr row
|
||||||
|
}
|
||||||
|
if {[dict exists $info description]} {
|
||||||
|
label $w.f.m1 -text "Description: " -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight bold}
|
||||||
|
message $w.f.m2 -text [dict get $info description] -justify left -anchor w -aspect 2000 -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight normal}
|
||||||
|
grid $w.f.m1 -row $row -column 0 -sticky nw
|
||||||
|
grid $w.f.m2 -row $row -column 1 -sticky new
|
||||||
|
incr row
|
||||||
|
}
|
||||||
|
if {[dict exists $info url]} {
|
||||||
|
set url [dict get $info url]
|
||||||
|
message $w.f.u -text $url -justify left -anchor w -aspect 2000 -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight normal -underline 0} -fg #0000F0
|
||||||
|
grid $w.f.u -row $row -column 0 -columnspan 2 -sticky new
|
||||||
|
bind $w.f.u <Button-1> [list exec xdg-open "$url"]
|
||||||
|
bind $w.f.u <Button-2> [list exec xdg-open "$url"]
|
||||||
|
bind $w.f.u <Button-3> [list exec xdg-open "$url"]
|
||||||
|
bind $w.f.u <Enter> [list $w.f.u configure -font {-weight normal -underline 1}]
|
||||||
|
bind $w.f.u <Leave> [list $w.f.u configure -font {-weight normal -underline 0}]
|
||||||
|
balloon_add_help $w.f.u "Click to open $url"
|
||||||
|
incr row
|
||||||
|
}
|
||||||
pack $w.b -side top
|
pack $w.b -side top
|
||||||
pack $w.ok -in $w.b -side left
|
pack $w.ok -in $w.b -side left
|
||||||
if {$qid != "*"} {
|
if {$qid != "*"} {
|
||||||
@@ -3502,6 +3552,9 @@ proc ReadTaggedOptions { tag date } {
|
|||||||
if {[dict exists $info location]} {
|
if {[dict exists $info location]} {
|
||||||
lappend ans -entry-location [dict get $info location]
|
lappend ans -entry-location [dict get $info location]
|
||||||
}
|
}
|
||||||
|
if {[dict exists $info url]} {
|
||||||
|
lappend ans -entry-url [dict get $info url]
|
||||||
|
}
|
||||||
if {[dict exists $info description]} {
|
if {[dict exists $info description]} {
|
||||||
lappend ans -txtentry-description [dict get $info description]
|
lappend ans -txtentry-description [dict get $info description]
|
||||||
}
|
}
|
||||||
@@ -3637,6 +3690,29 @@ proc EditableLeave { w } {
|
|||||||
$w tag configure $tag -underline 0
|
$w tag configure $tag -underline 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc OpenUrl { w } {
|
||||||
|
global SynToObj Balloon
|
||||||
|
set tags [$w tag names current]
|
||||||
|
set index [lsearch -glob $tags "__syn__*"]
|
||||||
|
if {$index < 0} {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
set syntag [lindex $tags $index]
|
||||||
|
if {![info exists SynToObj($syntag)]} {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
set obj $SynToObj($syntag)
|
||||||
|
if {![dict exists $obj info]} {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
set info [dict get $obj info]
|
||||||
|
if {![dict exists $info url]} {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
set url [dict get $info url]
|
||||||
|
exec xdg-open "$url"
|
||||||
|
}
|
||||||
|
|
||||||
proc details_enter { w } {
|
proc details_enter { w } {
|
||||||
global SynToObj Balloon
|
global SynToObj Balloon
|
||||||
set tags [$w tag names current]
|
set tags [$w tag names current]
|
||||||
@@ -3651,7 +3727,7 @@ proc details_enter { w } {
|
|||||||
set obj $SynToObj($syntag)
|
set obj $SynToObj($syntag)
|
||||||
set lines {}
|
set lines {}
|
||||||
if {![dict exists $obj info]} {
|
if {![dict exists $obj info]} {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
set info [dict get $obj info]
|
set info [dict get $obj info]
|
||||||
set llen 0
|
set llen 0
|
||||||
@@ -3661,6 +3737,9 @@ proc details_enter { w } {
|
|||||||
if {[dict exists $info description]} {
|
if {[dict exists $info description]} {
|
||||||
lappend lines [list "Description:" [dict get $info description]]
|
lappend lines [list "Description:" [dict get $info description]]
|
||||||
}
|
}
|
||||||
|
if {[dict exists $info url]} {
|
||||||
|
lappend lines [list "URL:" "Middle-click to open [dict get $info url]"]
|
||||||
|
}
|
||||||
if {[llength $lines] < 1} {
|
if {[llength $lines] < 1} {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3678,42 +3757,22 @@ proc details_popup { pairs } {
|
|||||||
global Balloon
|
global Balloon
|
||||||
set maxwid 80
|
set maxwid 80
|
||||||
set h .balloonhelp
|
set h .balloonhelp
|
||||||
|
set c 0
|
||||||
toplevel $h -bg #000000
|
toplevel $h -bg #000000
|
||||||
text $h.l -width $maxwid -height 16 -bd 0 -wrap word -relief flat -bg #FFFFC0
|
frame $h.l -padx 0 -pady 0 -highlightthickness 0 -relief flat -bd 0 -bg #FFFFC0
|
||||||
$h.l tag configure bold -font {-weight bold}
|
pack $h.l -side top -padx 1 -pady 1 -ipadx 2 -ipady 1
|
||||||
$h.l tag configure medium -font {-weight normal}
|
|
||||||
foreach pair $pairs {
|
foreach pair $pairs {
|
||||||
$h.l insert end [lindex $pair 0] bold " " medium [lindex $pair 1] medium "\n" medium
|
label $h.lab$c -text "[lindex $pair 0] " -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -bg #FFFFC0 -font {-weight bold}
|
||||||
|
message $h.m$c -text "[lindex $pair 1] " -justify left -anchor w -aspect 2000 -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -bg #FFFFC0 -font {-weight normal}
|
||||||
|
grid $h.lab$c -in $h.l -row $c -column 0 -sticky nw
|
||||||
|
grid $h.m$c -in $h.l -row $c -column 1 -sticky new
|
||||||
|
incr c
|
||||||
}
|
}
|
||||||
# Now calculate actual text window size
|
|
||||||
set wid 0
|
|
||||||
set height 0
|
|
||||||
set text [$h.l get 1.0 end]
|
|
||||||
set text [string trim $text]
|
|
||||||
set lines [split $text "\n"]
|
|
||||||
foreach line $lines {
|
|
||||||
incr height
|
|
||||||
set len [string length $line]
|
|
||||||
incr len
|
|
||||||
if {$len > $wid} {
|
|
||||||
set wid $len
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if {$wid > $maxwid} {
|
|
||||||
set wid $maxwid
|
|
||||||
}
|
|
||||||
### NOTE: I should be using "count -displaylines" to size
|
|
||||||
### the window, but Tk gives the wrong answer. I think
|
|
||||||
### there is a bug in the text widget. So we count the
|
|
||||||
### number of lines and add 5 and hope for the best...
|
|
||||||
incr height 5
|
|
||||||
$h.l configure -width $wid -height $height
|
|
||||||
pack $h.l -padx 1 -pady 1 -ipadx 2 -ipady 1
|
|
||||||
$h.l configure -state disabled
|
|
||||||
wm overrideredirect $h 1
|
wm overrideredirect $h 1
|
||||||
set geom [balloon_calculate_geometry $h]
|
set geom [balloon_calculate_geometry $h]
|
||||||
wm geometry $h $geom
|
wm geometry $h $geom
|
||||||
set Balloon(HelpId) [after $Balloon(StayTime) [list catch { destroy $h }]]
|
set Balloon(HelpId) [after 10000 "catch { destroy $h }"]
|
||||||
set Balloon(MustLeave) 1
|
set Balloon(MustLeave) 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2389,7 +2389,7 @@ void WriteJSONTimeTrigger(TimeTrig const *tt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
WriteJSONInfoChain(TrigInfo *ti)
|
WriteJSONInfoChain(TrigInfo *ti)
|
||||||
{
|
{
|
||||||
printf("\"info\":{");
|
printf("\"info\":{");
|
||||||
@@ -2944,9 +2944,6 @@ char const *SynthesizeTag(void)
|
|||||||
static char out[128];
|
static char out[128];
|
||||||
MD5Init(&ctx);
|
MD5Init(&ctx);
|
||||||
MD5Update(&ctx, (unsigned char *) CurLine, strlen(CurLine));
|
MD5Update(&ctx, (unsigned char *) CurLine, strlen(CurLine));
|
||||||
MD5Update(&ctx, (unsigned char *) FileName, strlen(FileName));
|
|
||||||
snprintf((char *) buf, sizeof(buf), "%d", LineNo);
|
|
||||||
MD5Update(&ctx, buf, strlen( (char *) buf));
|
|
||||||
MD5Final(buf, &ctx);
|
MD5Final(buf, &ctx);
|
||||||
snprintf(out, sizeof(out), "__syn__%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
snprintf(out, sizeof(out), "__syn__%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||||
(unsigned int) buf[0], (unsigned int) buf[1],
|
(unsigned int) buf[0], (unsigned int) buf[1],
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
|||||||
int origLen = DBufLen(dbuf);
|
int origLen = DBufLen(dbuf);
|
||||||
int altmode;
|
int altmode;
|
||||||
int r;
|
int r;
|
||||||
|
int origtime;
|
||||||
Value v;
|
Value v;
|
||||||
UserFunc *func;
|
UserFunc *func;
|
||||||
|
|
||||||
@@ -87,6 +88,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
|||||||
if (tt) {
|
if (tt) {
|
||||||
tim = tt->ttime;
|
tim = tt->ttime;
|
||||||
}
|
}
|
||||||
|
origtime = tim;
|
||||||
if (tim == NO_TIME) tim = curtime;
|
if (tim == NO_TIME) tim = curtime;
|
||||||
tdiff = tim - curtime;
|
tdiff = tim - curtime;
|
||||||
adiff = ABS(tdiff);
|
adiff = ABS(tdiff);
|
||||||
@@ -215,6 +217,33 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
|||||||
if (!c) {
|
if (!c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (c == '<') {
|
||||||
|
DynamicBuffer header;
|
||||||
|
char const *val;
|
||||||
|
DBufInit(&header);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
c = ParseChar(p, &err, 0);
|
||||||
|
if (err) {
|
||||||
|
DBufFree(&header);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (!c || c == '>') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DBufPutc(&header, c);
|
||||||
|
}
|
||||||
|
if (!c) {
|
||||||
|
Wprint(tr("Warning: Unterminated %%<...> substitution sequence"));
|
||||||
|
}
|
||||||
|
err = OK;
|
||||||
|
val = FindTrigInfo(t, DBufValue(&header));
|
||||||
|
DBufFree(&header);
|
||||||
|
if (val) {
|
||||||
|
SHIP_OUT(val);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (c == '(') {
|
if (c == '(') {
|
||||||
DynamicBuffer orig;
|
DynamicBuffer orig;
|
||||||
DynamicBuffer translated;
|
DynamicBuffer translated;
|
||||||
@@ -378,6 +407,12 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
|||||||
Eprint("%s", GetErr(r));
|
Eprint("%s", GetErr(r));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (origtime == NO_TIME) {
|
||||||
|
if ((c >= '0' && c <= '9') || (c == '!')) {
|
||||||
|
Wprint(tr("`%%%c' substitution sequence should not be used without an AT clause"), c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch(UPPER(c)) {
|
switch(UPPER(c)) {
|
||||||
case 'A':
|
case 'A':
|
||||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||||
@@ -755,6 +790,8 @@ int DoSubstFromString(char const *source, DynamicBuffer *dbuf,
|
|||||||
if (tim == NO_TIME) tim=MinutesPastMidnight(0);
|
if (tim == NO_TIME) tim=MinutesPastMidnight(0);
|
||||||
CreateParser(source, &tempP);
|
CreateParser(source, &tempP);
|
||||||
tempP.allownested = 0;
|
tempP.allownested = 0;
|
||||||
|
tempTrig.infos = NULL;
|
||||||
|
DBufInit(&tempTrig.tags);
|
||||||
tempTrig.typ = MSG_TYPE;
|
tempTrig.typ = MSG_TYPE;
|
||||||
tempTime.ttime = tim;
|
tempTime.ttime = tim;
|
||||||
|
|
||||||
|
|||||||
13
src/funcs.c
13
src/funcs.c
@@ -162,6 +162,7 @@ static int FTrigdate (func_info *);
|
|||||||
static int FTrigdatetime (func_info *);
|
static int FTrigdatetime (func_info *);
|
||||||
static int FTrigdelta (func_info *);
|
static int FTrigdelta (func_info *);
|
||||||
static int FTrigduration (func_info *);
|
static int FTrigduration (func_info *);
|
||||||
|
static int FTriginfo (func_info *);
|
||||||
static int FTrigeventduration(func_info *);
|
static int FTrigeventduration(func_info *);
|
||||||
static int FTrigeventstart (func_info *);
|
static int FTrigeventstart (func_info *);
|
||||||
static int FTrigfrom (func_info *);
|
static int FTrigfrom (func_info *);
|
||||||
@@ -326,6 +327,7 @@ BuiltinFunc Func[] = {
|
|||||||
{ "trigeventstart", 0, 0, 0, FTrigeventstart, NULL },
|
{ "trigeventstart", 0, 0, 0, FTrigeventstart, NULL },
|
||||||
{ "trigfrom", 0, 0, 0, FTrigfrom, NULL },
|
{ "trigfrom", 0, 0, 0, FTrigfrom, NULL },
|
||||||
{ "trigger", 1, 3, 0, FTrigger, NULL },
|
{ "trigger", 1, 3, 0, FTrigger, NULL },
|
||||||
|
{ "triginfo", 1, 1, 1, FTriginfo, NULL },
|
||||||
{ "trigpriority", 0, 0, 0, FTrigpriority, NULL },
|
{ "trigpriority", 0, 0, 0, FTrigpriority, NULL },
|
||||||
{ "trigrep", 0, 0, 0, FTrigrep, NULL },
|
{ "trigrep", 0, 0, 0, FTrigrep, NULL },
|
||||||
{ "trigscanfrom", 0, 0, 0, FTrigscanfrom, NULL },
|
{ "trigscanfrom", 0, 0, 0, FTrigscanfrom, NULL },
|
||||||
@@ -1620,6 +1622,17 @@ static int FTrigeventduration(func_info *info)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int FTriginfo(func_info *info)
|
||||||
|
{
|
||||||
|
char const *s;
|
||||||
|
ASSERT_TYPE(0, STR_TYPE);
|
||||||
|
s = FindTrigInfo(&LastTrigger, ARGSTR(0));
|
||||||
|
if (!s) {
|
||||||
|
return RetStrVal("", info);
|
||||||
|
}
|
||||||
|
return RetStrVal(s, info);
|
||||||
|
}
|
||||||
|
|
||||||
static int FTrigeventstart(func_info *info)
|
static int FTrigeventstart(func_info *info)
|
||||||
{
|
{
|
||||||
if (LastTrigger.eventstart == NO_TIME) {
|
if (LastTrigger.eventstart == NO_TIME) {
|
||||||
|
|||||||
19
src/main.c
19
src/main.c
@@ -145,6 +145,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
DBufInit(&(LastTrigger.tags));
|
DBufInit(&(LastTrigger.tags));
|
||||||
|
LastTrigger.infos = NULL;
|
||||||
ClearLastTriggers();
|
ClearLastTriggers();
|
||||||
|
|
||||||
atexit(exitfunc);
|
atexit(exitfunc);
|
||||||
@@ -1945,7 +1946,9 @@ void
|
|||||||
FreeTrig(Trigger *t)
|
FreeTrig(Trigger *t)
|
||||||
{
|
{
|
||||||
DBufFree(&(t->tags));
|
DBufFree(&(t->tags));
|
||||||
FreeTrigInfoChain(t->infos);
|
if (t->infos) {
|
||||||
|
FreeTrigInfoChain(t->infos);
|
||||||
|
}
|
||||||
t->infos = NULL;
|
t->infos = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1972,8 +1975,7 @@ ClearLastTriggers(void)
|
|||||||
LastTrigger.warn[0] = 0;
|
LastTrigger.warn[0] = 0;
|
||||||
LastTrigger.omitfunc[0] = 0;
|
LastTrigger.omitfunc[0] = 0;
|
||||||
LastTrigger.passthru[0] = 0;
|
LastTrigger.passthru[0] = 0;
|
||||||
DBufFree(&(LastTrigger.tags));
|
FreeTrig(&LastTrigger);
|
||||||
LastTrigger.infos = NULL;
|
|
||||||
LastTimeTrig.ttime = NO_TIME;
|
LastTimeTrig.ttime = NO_TIME;
|
||||||
LastTimeTrig.delta = NO_DELTA;
|
LastTimeTrig.delta = NO_DELTA;
|
||||||
LastTimeTrig.rep = NO_REP;
|
LastTimeTrig.rep = NO_REP;
|
||||||
@@ -1993,10 +1995,19 @@ SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigt
|
|||||||
void
|
void
|
||||||
SaveLastTrigger(Trigger const *t)
|
SaveLastTrigger(Trigger const *t)
|
||||||
{
|
{
|
||||||
DBufFree(&(LastTrigger.tags));
|
FreeTrig(&LastTrigger);
|
||||||
memcpy(&LastTrigger, t, sizeof(LastTrigger));
|
memcpy(&LastTrigger, t, sizeof(LastTrigger));
|
||||||
|
|
||||||
|
/* DON'T hang on to the invalid info chain! */
|
||||||
|
LastTrigger.infos = NULL;
|
||||||
DBufInit(&(LastTrigger.tags));
|
DBufInit(&(LastTrigger.tags));
|
||||||
|
|
||||||
DBufPuts(&(LastTrigger.tags), DBufValue(&(t->tags)));
|
DBufPuts(&(LastTrigger.tags), DBufValue(&(t->tags)));
|
||||||
|
TrigInfo *cur = t->infos;
|
||||||
|
while(cur) {
|
||||||
|
AppendTrigInfo(&LastTrigger, cur->info);
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -282,3 +282,5 @@ void FreeTrigInfoChain(TrigInfo *ti);
|
|||||||
int AppendTrigInfo(Trigger *t, char const *info);
|
int AppendTrigInfo(Trigger *t, char const *info);
|
||||||
int TrigInfoHeadersAreTheSame(char const *i1, char const *i2);
|
int TrigInfoHeadersAreTheSame(char const *i1, char const *i2);
|
||||||
int TrigInfoIsValid(char const *info);
|
int TrigInfoIsValid(char const *info);
|
||||||
|
char const *FindTrigInfo(Trigger *t, char const *header);
|
||||||
|
void WriteJSONInfoChain(TrigInfo *ti);
|
||||||
|
|||||||
@@ -474,6 +474,9 @@ void HandleQueuedReminders(void)
|
|||||||
PrintJSONKeyPairString("qid", qid);
|
PrintJSONKeyPairString("qid", qid);
|
||||||
PrintJSONKeyPairString("ttime", SimpleTimeNoSpace(q->tt.ttime));
|
PrintJSONKeyPairString("ttime", SimpleTimeNoSpace(q->tt.ttime));
|
||||||
PrintJSONKeyPairString("now", SimpleTimeNoSpace(MinutesPastMidnight(1)));
|
PrintJSONKeyPairString("now", SimpleTimeNoSpace(MinutesPastMidnight(1)));
|
||||||
|
if (q->t.infos) {
|
||||||
|
WriteJSONInfoChain(q->t.infos);
|
||||||
|
}
|
||||||
PrintJSONKeyPairString("tags", DBufValue(&q->t.tags));
|
PrintJSONKeyPairString("tags", DBufValue(&q->t.tags));
|
||||||
} else {
|
} else {
|
||||||
printf("NOTE reminder %s",
|
printf("NOTE reminder %s",
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ int main(int argc, char *argv[])
|
|||||||
while (!feof(stdin)) {
|
while (!feof(stdin)) {
|
||||||
DBufGets(&buf, stdin);
|
DBufGets(&buf, stdin);
|
||||||
if (first_line && (!strcmp(DBufValue(&buf), "["))) {
|
if (first_line && (!strcmp(DBufValue(&buf), "["))) {
|
||||||
fprintf(stderr, "Rem2PS: It appears that you have invoked Remind with the -ppp option.\n Please use either -p or -pp, but not -ppp.\n");
|
fprintf(stderr, "Rem2PS: It appears that you have invoked Remind with the -ppp option.\n Please use either -p or -pp, but not -ppp. Also, Rem2PS does\n not support weekly calendars, so do not use -p+ or -pp+.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
first_line = 0;
|
first_line = 0;
|
||||||
|
|||||||
@@ -706,7 +706,9 @@ FreeTrigInfo(TrigInfo *ti)
|
|||||||
{
|
{
|
||||||
if (ti->info) {
|
if (ti->info) {
|
||||||
free( (void *) ti->info);
|
free( (void *) ti->info);
|
||||||
|
ti->info = NULL;
|
||||||
}
|
}
|
||||||
|
ti->next = NULL;
|
||||||
free(ti);
|
free(ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -792,3 +794,26 @@ TrigInfoIsValid(char const *info)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char const *
|
||||||
|
FindTrigInfo(Trigger *t, char const *header)
|
||||||
|
{
|
||||||
|
TrigInfo *ti;
|
||||||
|
size_t len;
|
||||||
|
char const *s;
|
||||||
|
|
||||||
|
if (!t || !header || !*header) return NULL;
|
||||||
|
|
||||||
|
ti = t->infos;
|
||||||
|
len = strlen(header);
|
||||||
|
while(ti) {
|
||||||
|
if (!strncasecmp(ti->info, header, len) &&
|
||||||
|
ti->info[len] == ':') {
|
||||||
|
s = ti->info + len + 1;
|
||||||
|
while(isspace(*s)) s++;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
ti = ti->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|||||||
@@ -647,7 +647,7 @@ EOF
|
|||||||
|
|
||||||
# The INFO keyword
|
# The INFO keyword
|
||||||
../src/remind -pp - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
../src/remind -pp - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||||
REM Wed INFO "Location: here" INFO "Summary: Nope" MSG Meeting
|
REM Wed INFO "Location: here" INFO "Summary: Nope" MSG Meeting [triginfo("location")] %<summary> %<nonexist> [triginfo("cabbage")]
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Invalid info strings
|
# Invalid info strings
|
||||||
@@ -690,6 +690,11 @@ set a "\x0P"
|
|||||||
set a "\x00P"
|
set a "\x00P"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
# Test diagnostics when using a timed substitution without an AT clause
|
||||||
|
../src/remind - 1 Feb 2024 1:00 <<EOF >> ../tests/test.out 2>&1
|
||||||
|
REM MSG %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %! hahaha
|
||||||
|
EOF
|
||||||
|
|
||||||
# Test translate table dumping
|
# Test translate table dumping
|
||||||
../src/remind - 1 Feb 2024 <<EOF >> ../tests/test.out 2>&1
|
../src/remind - 1 Feb 2024 <<EOF >> ../tests/test.out 2>&1
|
||||||
TRANSLATE "\x03" "BREAK"
|
TRANSLATE "\x03" "BREAK"
|
||||||
|
|||||||
@@ -1047,7 +1047,7 @@ set a057 value("a05"+"6")
|
|||||||
"a05" + "6" => "a056"
|
"a05" + "6" => "a056"
|
||||||
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||||
set a058 version()
|
set a058 version()
|
||||||
version() => "05.03.00"
|
version() => "05.03.02"
|
||||||
set a059 wkday(today())
|
set a059 wkday(today())
|
||||||
today() => 1991-02-16
|
today() => 1991-02-16
|
||||||
wkday(1991-02-16) => "Saturday"
|
wkday(1991-02-16) => "Saturday"
|
||||||
@@ -2611,7 +2611,7 @@ a056 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
|||||||
a007 "1991-02-16"
|
a007 "1991-02-16"
|
||||||
a057 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
a057 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||||
a008 "11:44"
|
a008 "11:44"
|
||||||
a058 "05.03.00"
|
a058 "05.03.02"
|
||||||
a059 "Saturday"
|
a059 "Saturday"
|
||||||
a010 12
|
a010 12
|
||||||
a060 6
|
a060 6
|
||||||
@@ -5632,8 +5632,8 @@ REM SATISFY ""
|
|||||||
REM SATISFY [version() > "01.00.00"]
|
REM SATISFY [version() > "01.00.00"]
|
||||||
../tests/test.rem(1050): SATISFY: expression has no reference to trigdate() or $T...
|
../tests/test.rem(1050): SATISFY: expression has no reference to trigdate() or $T...
|
||||||
../tests/test.rem(1050): Trig = Saturday, 16 February, 1991
|
../tests/test.rem(1050): Trig = Saturday, 16 February, 1991
|
||||||
version() => "05.03.00"
|
version() => "05.03.02"
|
||||||
"05.03.00" > "01.00.00" => 1
|
"05.03.02" > "01.00.00" => 1
|
||||||
../tests/test.rem(1050): Trig(satisfied) = Saturday, 16 February, 1991
|
../tests/test.rem(1050): Trig(satisfied) = Saturday, 16 February, 1991
|
||||||
REM SATISFY [max(x, max(x, 1, 2, 3), 4, 5, 6) * 5]
|
REM SATISFY [max(x, max(x, 1, 2, 3), 4, 5, 6) * 5]
|
||||||
../tests/test.rem(1051): SATISFY: expression has no reference to trigdate() or $T...
|
../tests/test.rem(1051): SATISFY: expression has no reference to trigdate() or $T...
|
||||||
@@ -23200,7 +23200,7 @@ SECURITY: Won't read world-writable file or directory!
|
|||||||
Error reading include_dir/ww: Can't open file
|
Error reading include_dir/ww: Can't open file
|
||||||
SECURITY: Won't read world-writable file or directory!
|
SECURITY: Won't read world-writable file or directory!
|
||||||
Error reading include_dir/ww: No files matching *.rem
|
Error reading include_dir/ww: No files matching *.rem
|
||||||
05.03.00
|
05.03.02
|
||||||
Enabling test mode: This is meant for the acceptance test.
|
Enabling test mode: This is meant for the acceptance test.
|
||||||
Do not use --test in production.
|
Do not use --test in production.
|
||||||
In test mode, the system time is fixed at 2025-01-06@19:00
|
In test mode, the system time is fixed at 2025-01-06@19:00
|
||||||
@@ -24164,6 +24164,7 @@ trigeventduration
|
|||||||
trigeventstart
|
trigeventstart
|
||||||
trigfrom
|
trigfrom
|
||||||
trigger
|
trigger
|
||||||
|
triginfo
|
||||||
trigpriority
|
trigpriority
|
||||||
trigrep
|
trigrep
|
||||||
trigscanfrom
|
trigscanfrom
|
||||||
@@ -24541,11 +24542,13 @@ TRANSLATE "Warning: UNTIL/THROUGH date earlier than SCANFROM date" ""
|
|||||||
TRANSLATE "Warning: UNTIL/THROUGH date earlier than start date" ""
|
TRANSLATE "Warning: UNTIL/THROUGH date earlier than start date" ""
|
||||||
TRANSLATE "Warning: Unable to save ONCE timestamp to %s: %s" ""
|
TRANSLATE "Warning: Unable to save ONCE timestamp to %s: %s" ""
|
||||||
TRANSLATE "Warning: Unterminated %%(...) substitution sequence" ""
|
TRANSLATE "Warning: Unterminated %%(...) substitution sequence" ""
|
||||||
|
TRANSLATE "Warning: Unterminated %%<...> substitution sequence" ""
|
||||||
TRANSLATE "Warning: Unterminated %%{...} substitution sequence" ""
|
TRANSLATE "Warning: Unterminated %%{...} substitution sequence" ""
|
||||||
TRANSLATE "Warning: Useless use of UNTIL with fully-specified date and no *rep" ""
|
TRANSLATE "Warning: Useless use of UNTIL with fully-specified date and no *rep" ""
|
||||||
TRANSLATE "Warning: Variable name `%.*s...' truncated to `%.*s'" ""
|
TRANSLATE "Warning: Variable name `%.*s...' truncated to `%.*s'" ""
|
||||||
TRANSLATE "You have OMITted everything! The space-time continuum is at risk." ""
|
TRANSLATE "You have OMITted everything! The space-time continuum is at risk." ""
|
||||||
TRANSLATE "\\x00 is not a valid escape sequence" ""
|
TRANSLATE "\\x00 is not a valid escape sequence" ""
|
||||||
|
TRANSLATE "`%%%c' substitution sequence should not be used without an AT clause" ""
|
||||||
TRANSLATE "did you mean" ""
|
TRANSLATE "did you mean" ""
|
||||||
TRANSLATE "here" ""
|
TRANSLATE "here" ""
|
||||||
TRANSLATE "psmoon() is deprecated; use SPECIAL MOON instead." ""
|
TRANSLATE "psmoon() is deprecated; use SPECIAL MOON instead." ""
|
||||||
@@ -24659,10 +24662,10 @@ February 2024 29 4 0
|
|||||||
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
|
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
|
||||||
January 31
|
January 31
|
||||||
March 31
|
March 31
|
||||||
{"date":"2024-02-07","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"body":"Meeting"}
|
{"date":"2024-02-07","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"rawbody":"Meeting [triginfo(\"location\")] %<summary> %<nonexist> [triginfo(\"cabbage\")]","body":"Meeting here Nope "}
|
||||||
{"date":"2024-02-14","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"body":"Meeting"}
|
{"date":"2024-02-14","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"rawbody":"Meeting [triginfo(\"location\")] %<summary> %<nonexist> [triginfo(\"cabbage\")]","body":"Meeting here Nope "}
|
||||||
{"date":"2024-02-21","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"body":"Meeting"}
|
{"date":"2024-02-21","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"rawbody":"Meeting [triginfo(\"location\")] %<summary> %<nonexist> [triginfo(\"cabbage\")]","body":"Meeting here Nope "}
|
||||||
{"date":"2024-02-28","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"body":"Meeting"}
|
{"date":"2024-02-28","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"rawbody":"Meeting [triginfo(\"location\")] %<summary> %<nonexist> [triginfo(\"cabbage\")]","body":"Meeting here Nope "}
|
||||||
# rem2ps2 end
|
# rem2ps2 end
|
||||||
-stdin-(1): Invalid INFO string: Must be of the form "Header: Value"
|
-stdin-(1): Invalid INFO string: Must be of the form "Header: Value"
|
||||||
-stdin-(2): Invalid INFO string: Must be of the form "Header: Value"
|
-stdin-(2): Invalid INFO string: Must be of the form "Header: Value"
|
||||||
@@ -24689,6 +24692,21 @@ a "xPOO"
|
|||||||
-stdin-(24): \x00 is not a valid escape sequence
|
-stdin-(24): \x00 is not a valid escape sequence
|
||||||
-stdin-(25): \x00 is not a valid escape sequence
|
-stdin-(25): \x00 is not a valid escape sequence
|
||||||
-stdin-(26): \x00 is not a valid escape sequence
|
-stdin-(26): \x00 is not a valid escape sequence
|
||||||
|
-stdin-(1): `%0' substitution sequence should not be used without an AT clause
|
||||||
|
-stdin-(1): `%1' substitution sequence should not be used without an AT clause
|
||||||
|
-stdin-(1): `%2' substitution sequence should not be used without an AT clause
|
||||||
|
-stdin-(1): `%3' substitution sequence should not be used without an AT clause
|
||||||
|
-stdin-(1): `%4' substitution sequence should not be used without an AT clause
|
||||||
|
-stdin-(1): `%5' substitution sequence should not be used without an AT clause
|
||||||
|
-stdin-(1): `%6' substitution sequence should not be used without an AT clause
|
||||||
|
-stdin-(1): `%7' substitution sequence should not be used without an AT clause
|
||||||
|
-stdin-(1): `%8' substitution sequence should not be used without an AT clause
|
||||||
|
-stdin-(1): `%9' substitution sequence should not be used without an AT clause
|
||||||
|
-stdin-(1): `%!' substitution sequence should not be used without an AT clause
|
||||||
|
Reminders for Thursday, 1st February, 2024:
|
||||||
|
|
||||||
|
s now at 1:00am at 01:00 0 0 from now 0 0 s is hahaha
|
||||||
|
|
||||||
# Translation table
|
# Translation table
|
||||||
TRANSLATE "LANGID" "en"
|
TRANSLATE "LANGID" "en"
|
||||||
TRANSLATE "\x03" "BREAK"
|
TRANSLATE "\x03" "BREAK"
|
||||||
|
|||||||
Reference in New Issue
Block a user