mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
26 Commits
05.03.00-B
...
05.03.00
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
6
Makefile
6
Makefile
@@ -23,8 +23,7 @@ install:
|
||||
@$(MAKE) -C rem2html install
|
||||
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
|
||||
clean:
|
||||
find . -name '*~' -exec rm {} \;
|
||||
-rm man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1 scripts/tkremind
|
||||
-find . -name '*~' -exec rm {} \;
|
||||
-$(MAKE) -C src clean
|
||||
-$(MAKE) -C rem2pdf clean
|
||||
|
||||
@@ -44,7 +43,8 @@ test:
|
||||
@$(MAKE) -C src -s test
|
||||
|
||||
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
|
||||
./configure
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
"slide" "soleq" "stdout" "strlen" "substr" "sunrise" "sunset" "time"
|
||||
"timepart" "timezone" "today" "trig" "trigback" "trigdate"
|
||||
"trigdatetime" "trigdelta" "trigduration" "trigeventduration"
|
||||
"trigeventstart" "trigfrom" "trigger" "trigpriority" "trigrep"
|
||||
"trigeventstart" "trigfrom" "trigger" "triginfo" "trigpriority" "trigrep"
|
||||
"trigscanfrom" "trigtags" "trigtime" "trigtimedelta" "trigtimerep"
|
||||
"triguntil" "trigvalid" "typeof" "tzconvert" "upper" "utctolocal"
|
||||
"value" "version" "weekno" "wkday" "wkdaynum" "year")
|
||||
|
||||
@@ -1,17 +1,35 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 5.3 Patch 0 - 2025-02-??
|
||||
* VERSION 5.3 Patch 0 - 2025-02-04
|
||||
|
||||
- NEW FEATURE: remind: Add the "INFO" clause to the REM command. This
|
||||
is intended for storing additional metadata about an event, such as
|
||||
the location and a longer description. The intention is to make
|
||||
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
|
||||
creating a reminder; these are converted to INFO clauses. Also support
|
||||
a popup window with the extra information when hovering over a reminder
|
||||
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
|
||||
strings, where "AB" is a pair of hex digits.
|
||||
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
REM 1 Feb 2022 MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 22 Jan 2023 MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 10 Feb 2024 MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 29 Jan 2025 MSG %(Chinese New Year) (%(Snake))
|
||||
REM 17 Feb 2026 MSG %(Chinese New Year) (%(Horse))
|
||||
REM 6 Feb 2027 MSG %(Chinese New Year) (%(Goat))
|
||||
REM 26 Jan 2028 MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 13 Feb 2029 MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 3 Feb 2030 MSG %(Chinese New Year) (%(Dog))
|
||||
REM 23 Jan 2031 MSG %(Chinese New Year) (%(Pig))
|
||||
REM 11 Feb 2032 MSG %(Chinese New Year) (%(Rat))
|
||||
REM 31 Jan 2033 MSG %(Chinese New Year) (%(Ox))
|
||||
REM 19 Feb 2034 MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 8 Feb 2035 MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 28 Jan 2036 MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 15 Feb 2037 MSG %(Chinese New Year) (%(Snake))
|
||||
REM 4 Feb 2038 MSG %(Chinese New Year) (%(Horse))
|
||||
REM 24 Jan 2039 MSG %(Chinese New Year) (%(Goat))
|
||||
REM 12 Feb 2040 MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 1 Feb 2041 MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 22 Jan 2042 MSG %(Chinese New Year) (%(Dog))
|
||||
REM 10 Feb 2043 MSG %(Chinese New Year) (%(Pig))
|
||||
REM 30 Jan 2044 MSG %(Chinese New Year) (%(Rat))
|
||||
REM 17 Feb 2045 MSG %(Chinese New Year) (%(Ox))
|
||||
REM 6 Feb 2046 MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 26 Jan 2047 MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 14 Feb 2048 MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 2 Feb 2049 MSG %(Chinese New Year) (%(Snake))
|
||||
REM 23 Jan 2050 MSG %(Chinese New Year) (%(Horse))
|
||||
REM 1 Feb 2022 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 22 Jan 2023 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 10 Feb 2024 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 29 Jan 2025 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
REM 17 Feb 2026 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||
REM 6 Feb 2027 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||
REM 26 Jan 2028 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 13 Feb 2029 INFO "Url: https://en.wikipedia.org/wiki/Rooster_(zodiac)" MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 3 Feb 2030 INFO "Url: https://en.wikipedia.org/wiki/Dog_(zodiac)" MSG %(Chinese New Year) (%(Dog))
|
||||
REM 23 Jan 2031 INFO "Url: https://en.wikipedia.org/wiki/Pig_(zodiac)" MSG %(Chinese New Year) (%(Pig))
|
||||
REM 11 Feb 2032 INFO "Url: https://en.wikipedia.org/wiki/Rat_(zodiac)" MSG %(Chinese New Year) (%(Rat))
|
||||
REM 31 Jan 2033 INFO "Url: https://en.wikipedia.org/wiki/Ox_(zodiac)" MSG %(Chinese New Year) (%(Ox))
|
||||
REM 19 Feb 2034 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 8 Feb 2035 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 28 Jan 2036 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 15 Feb 2037 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
REM 4 Feb 2038 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||
REM 24 Jan 2039 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||
REM 12 Feb 2040 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 1 Feb 2041 INFO "Url: https://en.wikipedia.org/wiki/Rooster_(zodiac)" MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 22 Jan 2042 INFO "Url: https://en.wikipedia.org/wiki/Dog_(zodiac)" MSG %(Chinese New Year) (%(Dog))
|
||||
REM 10 Feb 2043 INFO "Url: https://en.wikipedia.org/wiki/Pig_(zodiac)" MSG %(Chinese New Year) (%(Pig))
|
||||
REM 30 Jan 2044 INFO "Url: https://en.wikipedia.org/wiki/Rat_(zodiac)" MSG %(Chinese New Year) (%(Rat))
|
||||
REM 17 Feb 2045 INFO "Url: https://en.wikipedia.org/wiki/Ox_(zodiac)" MSG %(Chinese New Year) (%(Ox))
|
||||
REM 6 Feb 2046 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 26 Jan 2047 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 14 Feb 2048 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 2 Feb 2049 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
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 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
|
||||
IF !Reform
|
||||
REM [hebdate(2, "Tishrey")] MSG Rosh Hashana 2
|
||||
REM [_PastSat(3, "Tishrey")] MSG Tzom Gedalia
|
||||
REM [hebdate(2, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Rosh_Hashanah" MSG Rosh Hashana 2
|
||||
REM [_PastSat(3, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Fast_of_Gedalia" MSG Tzom Gedalia
|
||||
ENDIF
|
||||
|
||||
REM [hebdate(10, "Tishrey")] MSG Yom Kippur
|
||||
REM [hebdate(15, "Tishrey")] MSG Sukkot 1
|
||||
REM [hebdate(10, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Yom_Kippur" MSG Yom Kippur
|
||||
REM [hebdate(15, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Sukkot" MSG Sukkot 1
|
||||
|
||||
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
|
||||
|
||||
REM [hebdate(21, "Tishrey")] MSG Hoshana Rabba
|
||||
REM [hebdate(22, "Tishrey")] MSG Shemini Atzeret
|
||||
REM [hebdate(21, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Hoshana_Rabbah" MSG Hoshana Rabba
|
||||
REM [hebdate(22, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Shemini_Atzeret" MSG Shemini Atzeret
|
||||
|
||||
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
|
||||
REM [hebdate(23, "Tishrey")] MSG Simchat Torah
|
||||
REM [hebdate(23, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Simchat_Torah" MSG Simchat Torah
|
||||
ENDIF
|
||||
|
||||
# Because Kislev can change length, we must be more careful about Chanukah
|
||||
FSET _chan(x) HEBDATE(24, "Kislev", $U-9)+x
|
||||
REM [_chan(1)] MSG Chanukah 1
|
||||
REM [_chan(2)] MSG Chanukah 2
|
||||
REM [_chan(3)] MSG Chanukah 3
|
||||
REM [_chan(4)] MSG Chanukah 4
|
||||
REM [_chan(5)] MSG Chanukah 5
|
||||
REM [_chan(6)] MSG Chanukah 6
|
||||
REM [_chan(7)] MSG Chanukah 7
|
||||
REM [_chan(8)] MSG Chanukah 8
|
||||
REM [_chan(1)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 1
|
||||
REM [_chan(2)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 2
|
||||
REM [_chan(3)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 3
|
||||
REM [_chan(4)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 4
|
||||
REM [_chan(5)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 5
|
||||
REM [_chan(6)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 6
|
||||
REM [_chan(7)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 7
|
||||
REM [_chan(8)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG Chanukah 8
|
||||
|
||||
# Not sure about Reform's position on the next one.
|
||||
IF !Reform
|
||||
# 10 Tevet will never be a Saturday, so whether or not to
|
||||
# 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
|
||||
|
||||
REM [hebdate(15, "Shvat")] MSG Tu B'Shvat
|
||||
REM [hebdate(14, "Adar A")] MSG Purim Katan
|
||||
REM [hebdate(15, "Shvat")] INFO "Url: https://en.wikipedia.org/wiki/Tu_BiShvat" MSG Tu B'Shvat
|
||||
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 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
|
||||
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
|
||||
REM [hebdate(14, "Adar")] MSG Purim
|
||||
REM [hebdate(15, "Nisan")] MSG Pesach
|
||||
REM [hebdate(14, "Adar")] INFO "Url: https://en.wikipedia.org/wiki/Purim" MSG Purim
|
||||
REM [hebdate(15, "Nisan")] INFO "Url: https://en.wikipedia.org/wiki/Passover" MSG Pesach
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
REM [hebdate(22, "Nisan")] MSG Pesach 8
|
||||
REM [hebdate(22, "Nisan")] INFO "Url: https://en.wikipedia.org/wiki/Passover" MSG Pesach 8
|
||||
ENDIF
|
||||
|
||||
REM [hebdate(27, "Nisan")] MSG Yom HaShoah
|
||||
REM [_BackTwoFri(4, "Iyar")] MSG Yom HaZikaron
|
||||
REM [_BackTwoSat(5, "Iyar")] MSG Yom Ha'atzmaut
|
||||
REM [hebdate(27, "Nisan")] INFO "Url: https://en.wikipedia.org/wiki/Yom_HaShoah" MSG Yom HaShoah
|
||||
REM [_BackTwoFri(4, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Yom_HaZikaron" MSG Yom HaZikaron
|
||||
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
|
||||
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
|
||||
|
||||
REM [hebdate(28, "Iyar")] MSG Yom Yerushalayim
|
||||
REM [hebdate(6, "Sivan")] MSG Shavuot
|
||||
REM [hebdate(28, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Jerusalem_Day" MSG Yom Yerushalayim
|
||||
REM [hebdate(6, "Sivan")] INFO "Url: https://en.wikipedia.org/wiki/Shavuot" MSG Shavuot
|
||||
|
||||
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
|
||||
|
||||
# Fairly sure Reform Jews don't observe the next two
|
||||
IF !Reform
|
||||
# Tzom Tamuz and Tish'a B'Av are moved to Sunday if they normally
|
||||
# fall on a Saturday
|
||||
REM [_PastSat(17, "Tamuz")] MSG Tzom Tammuz
|
||||
REM [_PastSat(9, "Av")] MSG Tish'a B'Av
|
||||
REM [_PastSat(17, "Tamuz")] INFO "Url: https://en.wikipedia.org/wiki/Seventeenth_of_Tammuz" MSG Tzom Tammuz
|
||||
REM [_PastSat(9, "Av")] INFO "Url: https://en.wikipedia.org/wiki/Tisha_B%27Av" MSG Tish'a B'Av
|
||||
ENDIF
|
||||
|
||||
@@ -4,31 +4,31 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
REM Sun 14 Feb MSG Start of Aromantic Spectrum Awareness Week
|
||||
REM 1 Mar MSG Zero Discrimination Day
|
||||
REM 31 Mar MSG Trans Day of Visibility
|
||||
REM 6 Apr MSG International Asexuality Day
|
||||
REM Wed 8 Apr MSG International Day of Pink
|
||||
REM 26 Apr MSG Lesbian Visibility Day
|
||||
REM 17 May MSG International Day Against Homophobia, Biphobia and Transphobia
|
||||
REM 19 May MSG Agender Pride Day
|
||||
REM 24 May MSG Pansexual & Panromantic Awareness Day
|
||||
REM 1 Jun MSG Start of LGBT Pride Month
|
||||
REM 5 Jun MSG Aromantic Visibility Day
|
||||
REM Mon 8 Jul MSG Start of Non-Binary Awareness Week
|
||||
REM 14 Jul MSG Non-Binary People's Day
|
||||
REM 16 Jul MSG Drag Day
|
||||
REM 9 Aug MSG Start of Dyke Week
|
||||
REM 16 Sep MSG Start of Bisexual Awareness Week
|
||||
REM 23 Sep MSG Celebrate Bisexuality Day
|
||||
REM 8 Oct MSG Lesbian Day
|
||||
REM 11 Oct MSG National Coming Out Day
|
||||
REM Wed 15 Oct MSG Pronouns Day
|
||||
REM 17 Oct MSG Start of Genderfluid Visibility Week
|
||||
REM Sun 19 Oct MSG Start of Ace Week
|
||||
REM 26 Oct MSG Intersex Awareness Day
|
||||
REM 8 Nov MSG Intersex Day of Remembrance
|
||||
REM 1 Nov MSG Start of Trans Awareness Month
|
||||
REM Sun 1 Nov MSG Trans Parent Day
|
||||
REM 13 Nov MSG Start of Trans Awareness Week
|
||||
REM 20 Nov MSG Transgender Day of Remembrance
|
||||
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 INFO "Url: https://en.wikipedia.org/wiki/Zero_Discrimination_Day" MSG Zero Discrimination Day
|
||||
REM 31 Mar INFO "Url: https://en.wikipedia.org/wiki/International_Transgender_Day_of_Visibility" MSG Trans Day of Visibility
|
||||
REM 6 Apr INFO "Url: https://en.wikipedia.org/wiki/Asexuality#International_Asexuality_Day" MSG International Asexuality Day
|
||||
REM Wed 8 Apr INFO "Url: https://en.wikipedia.org/wiki/International_Day_of_Pink" MSG International Day of Pink
|
||||
REM 26 Apr INFO "Url: https://en.wikipedia.org/wiki/Lesbian_Visibility_Day" MSG Lesbian Visibility Day
|
||||
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 24 May MSG Pansexual & Panromantic Awareness Day
|
||||
REM 1 Jun INFO "Url: https://en.wikipedia.org/wiki/LGBT_Pride_Month" MSG Start of LGBT Pride Month
|
||||
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 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 INFO "Url: https://en.wikipedia.org/wiki/International_Drag_Day" MSG International Drag Day
|
||||
REM 9 Aug MSG Start of Dyke Week
|
||||
REM 16 Sep INFO "Url: https://en.wikipedia.org/wiki/Bisexual_Awareness_Week" MSG Start of Bisexual Awareness Week
|
||||
REM 23 Sep INFO "Url: https://en.wikipedia.org/wiki/Celebrate_Bisexuality_Day" MSG Celebrate Bisexuality Day
|
||||
REM 8 Oct MSG Lesbian Day
|
||||
REM 11 Oct INFO "Url: https://en.wikipedia.org/wiki/National_Coming_Out_Day" MSG National Coming Out 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 Sun 19 Oct INFO "Url: https://en.wikipedia.org/wiki/Asexuality#Ace_Week" MSG Start of Ace Week
|
||||
REM 26 Oct INFO "Url: https://en.wikipedia.org/wiki/Intersex_Awareness_Day" MSG Intersex Awareness Day
|
||||
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 Sun 1 Nov MSG Trans Parent Day
|
||||
REM 13 Nov INFO "Url: https://en.wikipedia.org/wiki/Transgender_Awareness_Week" MSG Start of Trans Awareness Week
|
||||
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
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
REM Sat 1 Mar MSG Mardi Gras Parade
|
||||
REM Fri 1 Sep --7 MSG Wear it Purple Day
|
||||
REM 1 Oct MSG Start of LGBT History Month
|
||||
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 INFO "Url: https://en.wikipedia.org/wiki/Wear_it_Purple_Day" MSG Wear it Purple Day
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
REM 1 Feb MSG Start of LGBT History Month
|
||||
REM 6 May MSG Start of Trans+ History Week
|
||||
REM 1 Feb INFO "Url: https://en.wikipedia.org/wiki/LGBT_History_Month" MSG Start of LGBT History Month
|
||||
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
|
||||
|
||||
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 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 12 Jun MSG Pulse Night of Remembrance
|
||||
REM 28 Jun MSG Stonewall Riots Anniversary
|
||||
REM 12 Jun INFO "Url: https://en.wikipedia.org/wiki/Orlando_nightclub_shooting" MSG Pulse Night of Remembrance
|
||||
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 Oct MSG Start of LGBT History Month
|
||||
REM Thu 15 Oct MSG Spirit Day
|
||||
REM 1 Oct INFO "Url: https://en.wikipedia.org/wiki/LGBT_History_Month" MSG Start of LGBT History Month
|
||||
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
|
||||
|
||||
IF $CalMode || $PsCal
|
||||
REM [moondate(0)] SPECIAL MOON 0 -1 -1 [moontime(0)]
|
||||
REM [moondate(1)] SPECIAL MOON 1 -1 -1 [moontime(1)]
|
||||
REM [moondate(2)] SPECIAL MOON 2 -1 -1 [moontime(2)]
|
||||
REM [moondate(3)] SPECIAL MOON 3 -1 -1 [moontime(3)]
|
||||
REM [moondate(0)] INFO "Url: https://en.wikipedia.org/wiki/New_moon" SPECIAL MOON 0 -1 -1 [moontime(0)]
|
||||
REM [moondate(1)] INFO "Url: https://en.wikipedia.org/wiki/Lunar_phase" SPECIAL MOON 1 -1 -1 [moontime(1)]
|
||||
REM [moondate(2)] INFO "Url: https://en.wikipedia.org/wiki/Full_moon" SPECIAL MOON 2 -1 -1 [moontime(2)]
|
||||
REM [moondate(3)] INFO "Url: https://en.wikipedia.org/wiki/Lunar_phase" SPECIAL MOON 3 -1 -1 [moontime(3)]
|
||||
ELSE
|
||||
REM NOQUEUE [moondatetime(0)] MSG %(New Moon) (%2)
|
||||
REM NOQUEUE [moondatetime(1)] MSG %(First Quarter) (%2)
|
||||
REM NOQUEUE [moondatetime(2)] MSG %(Full Moon) (%2)
|
||||
REM NOQUEUE [moondatetime(3)] MSG %(Last Quarter) (%2)
|
||||
REM NOQUEUE INFO "Url: https://en.wikipedia.org/wiki/New_moon" [moondatetime(0)] MSG %(New Moon) (%2)
|
||||
REM NOQUEUE INFO "Url: https://en.wikipedia.org/wiki/Lunar_phase" [moondatetime(1)] MSG %(First Quarter) (%2)
|
||||
REM NOQUEUE INFO "Url: https://en.wikipedia.org/wiki/Full_moon" [moondatetime(2)] MSG %(Full Moon) (%2)
|
||||
REM NOQUEUE INFO "Url: https://en.wikipedia.org/wiki/Lunar_phase" [moondatetime(3)] MSG %(Last Quarter) (%2)
|
||||
ENDIF
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
|
||||
IF $LatDeg >= 0
|
||||
# Northern Hemisphere
|
||||
REM NOQUEUE [soleq(0)] MSG %"%(Vernal Equinox)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(1)] MSG %"%(Summer Solstice)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(2)] MSG %"%(Autumnal Equinox)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(3)] MSG %"%(Winter Solstice)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(0)] INFO "Url: https://en.wikipedia.org/wiki/March_equinox" MSG %"%(Vernal Equinox)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(1)] INFO "Url: https://en.wikipedia.org/wiki/Summer_solstice" MSG %"%(Summer Solstice)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(2)] INFO "Url: https://en.wikipedia.org/wiki/September_equinox" MSG %"%(Autumnal Equinox)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(3)] INFO "Url: https://en.wikipedia.org/wiki/Winter_solstice" MSG %"%(Winter Solstice)%" [$Is] %3.
|
||||
ELSE
|
||||
# Southern Hemisphere
|
||||
REM NOQUEUE [soleq(0)] MSG %"%(Autumnal Equinox)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(1)] MSG %"%(Winter Solstice)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(2)] MSG %"%(Vernal Equinox)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(3)] MSG %"%(Summer Solstice)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(0)] INFO "Url: https://en.wikipedia.org/wiki/March_equinox" MSG %"%(Autumnal Equinox)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(1)] INFO "Url: https://en.wikipedia.org/wiki/Winter_solstice" MSG %"%(Winter Solstice)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(2)] INFO "Url: https://en.wikipedia.org/wiki/September_equinox" MSG %"%(Vernal Equinox)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(3)] INFO "Url: https://en.wikipedia.org/wiki/Summer_solstice" MSG %"%(Summer Solstice)%" [$Is] %3.
|
||||
ENDIF
|
||||
|
||||
@@ -184,14 +184,14 @@ by the reminder's \fIdelta\fR.
|
||||
.TP
|
||||
.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
|
||||
that the output contains additional information for use by a back-end such as the
|
||||
\fBRem2PS\fR program, which creates a PostScript calendar, and various
|
||||
other back-end programs. If \fIn\fR starts with "+", then it specifies
|
||||
a number of weeks rather than a number of months, and back-ends are expected
|
||||
to produce weekly calendars. Note that not all back-ends support
|
||||
weekly calendars; currently, only \fBrem2pdf\fR does. Specifying a weekly
|
||||
calendar implicitly enables the pure JSON interchange format, similar
|
||||
to \fB\-ppp\fR.
|
||||
that the output contains additional information for use by a back-end
|
||||
such as the \fBRem2PS\fR program, which creates a PostScript calendar,
|
||||
and various other back-end programs. If \fIn\fR starts with "+", then
|
||||
it specifies a number of weeks rather than a number of months, and
|
||||
back-ends are expected to produce weekly calendars. Note that not all
|
||||
back-ends support weekly calendars; currently, only \fBrem2pdf\fR and
|
||||
\fBrem2html\fR do. Specifying a weekly calendar implicitly enables
|
||||
the pure JSON interchange format, similar to \fB\-ppp\fR.
|
||||
.RS
|
||||
.PP
|
||||
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
|
||||
is disabled and the %"...%" sequences are preserved in the output.
|
||||
.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\-o\fR option.
|
||||
.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.
|
||||
It is the equivalent of [_("any_text")] but is more convenient to type.
|
||||
.TP
|
||||
.B %<\fIany_text\fR\fB>
|
||||
is replaced with the INFO value associated with the header \fIany_text\fR
|
||||
or the empty string if no such INFO value exists. It is the
|
||||
equivalent of [triginfo("any_text")] but is more convenient to type.
|
||||
.TP
|
||||
.B %_
|
||||
(percent-underscore) is replaced with a newline. You can use this to
|
||||
achieve multi-line reminders. Note that calendar back-ends vary in
|
||||
@@ -4292,7 +4301,23 @@ whose value is the maximum of "yyyy-mm-dd" and today.
|
||||
.B trigfrom()
|
||||
Returns (as a \fBDATE\fR type) the \fBFROM\fR parameter of the last \fBREM\fR or
|
||||
\fBIFTRIG\fR command. If there was no \fBFROM\fR parameter, returns the integer -1.
|
||||
|
||||
.TP
|
||||
.B triginfo(s_header)
|
||||
Returns a \fBSTRING\fR that is the INFO item associated with the header
|
||||
\fIheader\fR. The header should \fInot\fR contain a colon. Header name
|
||||
comparisons are case-insensitive.
|
||||
.RS
|
||||
.PP
|
||||
For example, the following will assign "At home" to the variable a and
|
||||
the empty string to variable b:
|
||||
.PP
|
||||
.nf
|
||||
REM INFO "Location: At home" MSG test
|
||||
SET a triginfo("location")
|
||||
SET b triginfo("no_such_header")
|
||||
.fi
|
||||
.PP
|
||||
.RE
|
||||
.TP
|
||||
.B trigger(d_date [,t_time [,i_utcflag]]) \fRor\fB trigger(q_datetime [,i_utcflag])
|
||||
Returns a string suitable for use in a \fBREM\fR command or a
|
||||
|
||||
@@ -103,9 +103,10 @@ The sixth control specifies what \fBRemind\fR should do if a reminder
|
||||
falls on a holiday or weekend.
|
||||
|
||||
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
|
||||
\fBLocation:\fR and \fBDescription:\fR boxes. If you enter anything
|
||||
here, they will be added as \fBINFO\fR items to the reminder.
|
||||
you want, you can enter a location, a URL, and and longer description
|
||||
in the \fBLocation:\fR, \fBURL:\fR and \fBDescription:\fR boxes. If
|
||||
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 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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
=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
|
||||
|
||||
Older versions of rem2html used to highlight today's date with a red outline.
|
||||
@@ -359,10 +366,14 @@ sub parse_input
|
||||
chomp;
|
||||
last if /^\# rem2ps2? end$/;
|
||||
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*(.*)$/) {
|
||||
($y, $m, $d, $special, $tag, $duration, $time, $body) =
|
||||
($1, $2, $3, $4, $5, $6, $7, $8);
|
||||
$title = '';
|
||||
} elsif (/\{/) {
|
||||
my $obj;
|
||||
if ($Options{utf8}) {
|
||||
@@ -371,6 +382,11 @@ sub parse_input
|
||||
$obj = decode_json($_);
|
||||
}
|
||||
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;
|
||||
$m = $2;
|
||||
$d = $3;
|
||||
@@ -379,6 +395,7 @@ sub parse_input
|
||||
$duration = $obj->{duration} || '*';
|
||||
$time = $obj->{time} || '*';
|
||||
$body = $obj->{body};
|
||||
$title = info_to_title($obj->{info});
|
||||
} else {
|
||||
next;
|
||||
}
|
||||
@@ -392,7 +409,8 @@ sub parse_input
|
||||
} elsif ($special eq 'WEEK') {
|
||||
$body =~ s/^\s+//;
|
||||
$body =~ s/\s+$//;
|
||||
$weeks->{$d1} = $body;
|
||||
$weeks->{$d1}->{body} = $body;
|
||||
$weeks->{$d1}->{url} = $url;
|
||||
} elsif ($special eq 'MOON') {
|
||||
if ($body =~ /(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) {
|
||||
my ($phase, $moonsize, $fontsize, $msg) = ($1, $2, $3, $4);
|
||||
@@ -402,6 +420,7 @@ sub parse_input
|
||||
$moons->[$d]->{'phase'} = $1;
|
||||
$moons->[$d]->{'msg'} = '';
|
||||
}
|
||||
$moons->[$d]->{url} = $url;
|
||||
} elsif ($special eq 'SHADE') {
|
||||
if ($body =~ /(\d+)\s+(\d+)\s+(\d+)/) {
|
||||
$shades->[$d] = sprintf("#%02X%02X%02X",
|
||||
@@ -415,10 +434,10 @@ sub parse_input
|
||||
my($r, $g, $b, $text) = ($1, $2, $3, $4);
|
||||
my $color = sprintf("style=\"color: #%02X%02X%02X;\"",
|
||||
$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 '*') {
|
||||
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;
|
||||
@@ -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
|
||||
{
|
||||
my ($c, $type) = @_;
|
||||
@@ -537,6 +579,15 @@ sub emit_one_ppp_calendar
|
||||
my $duration = $obj->{duration} || '*';
|
||||
my $time = $obj->{time} || '*';
|
||||
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);
|
||||
if ($special eq 'HTML') {
|
||||
push(@{$days->[$col]}, $body);
|
||||
@@ -545,7 +596,8 @@ sub emit_one_ppp_calendar
|
||||
} elsif ($special eq 'WEEK') {
|
||||
$body =~ s/^\s+//;
|
||||
$body =~ s/\s+$//;
|
||||
$weeks->{$col} = $body;
|
||||
$weeks->{$col}->{body} = $body;
|
||||
$weeks->{$col}->{url} = $url;
|
||||
} elsif ($special eq 'MOON') {
|
||||
if ($body =~ /(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) {
|
||||
my ($phase, $moonsize, $fontsize, $msg) = ($1, $2, $3, $4);
|
||||
@@ -555,6 +607,7 @@ sub emit_one_ppp_calendar
|
||||
$moons->[$col]->{'phase'} = $1;
|
||||
$moons->[$col]->{'msg'} = '';
|
||||
}
|
||||
$moons->[$col]->{url} = $url;
|
||||
} elsif ($special eq 'SHADE') {
|
||||
if ($body =~ /(\d+)\s+(\d+)\s+(\d+)/) {
|
||||
$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 $color = sprintf("style=\"color: #%02X%02X%02X;\"",
|
||||
$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 '*') {
|
||||
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);
|
||||
@@ -846,7 +899,11 @@ sub draw_day_cell
|
||||
my $shade = $shades->[$day];
|
||||
my $week = '';
|
||||
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;
|
||||
if ($Options{nostyle}) {
|
||||
@@ -907,10 +964,16 @@ sub draw_day_cell
|
||||
$alt = 'last';
|
||||
$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}) {
|
||||
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 {
|
||||
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>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
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
|
||||
|
||||
B<rem2pdf> will produce weekly calendars if you invoke B<remind> with the
|
||||
|
||||
@@ -75,6 +75,10 @@ sub render
|
||||
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
|
||||
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_wrap('word-char');
|
||||
my $body;
|
||||
@@ -108,7 +112,13 @@ sub render
|
||||
$self->{g} / 255,
|
||||
$self->{b} / 255);
|
||||
$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);
|
||||
if ($url) {
|
||||
$cr->tag_end(Cairo::TAG_LINK);
|
||||
}
|
||||
$cr->restore();
|
||||
}
|
||||
return $h;
|
||||
@@ -142,7 +152,18 @@ sub render
|
||||
|
||||
$cr->save();
|
||||
$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);
|
||||
if ($url) {
|
||||
$cr->tag_end(Cairo::TAG_LINK);
|
||||
}
|
||||
$cr->restore();
|
||||
|
||||
return 0;
|
||||
@@ -204,12 +225,30 @@ sub render
|
||||
$xc = $x1 + $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);
|
||||
if ($url) {
|
||||
$cr->tag_end(Cairo::TAG_LINK);
|
||||
}
|
||||
if ($layout) {
|
||||
$cr->save();
|
||||
$cr->move_to ($xc + ($self->{size}/2) + $settings->{border_size},
|
||||
$yc + ($self->{size}/2) - $self->{fontsize} );
|
||||
if ($url) {
|
||||
$cr->tag_begin(Cairo::TAG_LINK, "uri='$url'");
|
||||
}
|
||||
Pango::Cairo::show_layout($cr, $layout);
|
||||
if ($url) {
|
||||
$cr->tag_end(Cairo::TAG_LINK);
|
||||
}
|
||||
$cr->restore();
|
||||
}
|
||||
}
|
||||
@@ -284,6 +323,10 @@ sub render
|
||||
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 $url;
|
||||
if ($self->{info} && $self->{info}->{url}) {
|
||||
$url = $self->{info}->{url};
|
||||
}
|
||||
my $layout = Pango::Cairo::create_layout($cr);
|
||||
|
||||
$layout->set_width(1024 * ($x2 - $x1 - 2 * $settings->{border_size}));
|
||||
@@ -316,7 +359,13 @@ sub render
|
||||
} else {
|
||||
$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);
|
||||
if ($url) {
|
||||
$cr->tag_end(Cairo::TAG_LINK);
|
||||
}
|
||||
$cr->restore();
|
||||
}
|
||||
return $h;
|
||||
|
||||
@@ -585,6 +585,7 @@ proc CreateCalFrame { w dayNames } {
|
||||
-highlightthickness 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 REM <ButtonPress-2> "OpenUrl $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.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 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 configure -state disabled -takefocus 0
|
||||
}
|
||||
@@ -656,6 +658,7 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
$w.t$i tag delete $t
|
||||
}
|
||||
$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 configure -state disabled -takefocus 0
|
||||
}
|
||||
@@ -686,6 +689,7 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
$w.t$i tag delete $t
|
||||
}
|
||||
$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 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.entry -row 0 -column 1 -in $w.msg -sticky nsew
|
||||
|
||||
# LOCATION and DESCRIPTION
|
||||
# LOCATION, DESCRIPTION and URL
|
||||
label $w.loclab -text "Location: "
|
||||
entry $w.location
|
||||
balloon_add_help $w.location "Enter the location, if any"
|
||||
grid $w.loclab -row 1 -column 0 -in $w.msg -sticky e
|
||||
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: "
|
||||
text $w.description -width 80 -height 5
|
||||
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.description -row 2 -column 1 -in $w.msg -sticky nsew
|
||||
grid $w.desclab -row 3 -column 0 -in $w.msg -sticky e
|
||||
grid $w.description -row 3 -column 1 -in $w.msg -sticky nsew
|
||||
|
||||
grid columnconfigure $w.msg 0 -weight 0
|
||||
grid columnconfigure $w.msg 1 -weight 1
|
||||
grid rowconfigure $w.msg 0 -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
|
||||
set nbut 0
|
||||
foreach but $args {
|
||||
@@ -2309,6 +2320,11 @@ proc CreateReminder {w} {
|
||||
set description "Description: $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!
|
||||
global Remind
|
||||
set f [open "|$Remind -arq -e - 2>@1" r+]
|
||||
@@ -2969,11 +2985,16 @@ proc DaemonReadable { file } {
|
||||
set tag [dict get $obj tags]
|
||||
}
|
||||
set body [dict get $obj body]
|
||||
if {[dict exists $obj info]} {
|
||||
set info [dict get $obj info]
|
||||
} else {
|
||||
set info [dict create]
|
||||
}
|
||||
set qid "*"
|
||||
if {[dict exists $obj qid]} {
|
||||
set qid [dict get $obj qid]
|
||||
}
|
||||
IssueBackgroundReminder $body $time $now $tag $qid
|
||||
IssueBackgroundReminder $body $time $now $tag $qid $info
|
||||
}
|
||||
"queue" {
|
||||
set queue [dict get $obj queue]
|
||||
@@ -3017,7 +3038,7 @@ proc DaemonReadable { file } {
|
||||
# Description:
|
||||
# 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
|
||||
if {$Option(Deiconify)} {
|
||||
wm deiconify .
|
||||
@@ -3046,7 +3067,7 @@ proc IssueBackgroundReminder { body time now tag qid } {
|
||||
wm iconname $w "Reminder"
|
||||
wm title $w "Timed reminder ($time)"
|
||||
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
|
||||
|
||||
# Automatically shut down window after a minute if option says so
|
||||
@@ -3062,7 +3083,24 @@ 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]
|
||||
}
|
||||
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
|
||||
}
|
||||
pack $w.b -side top
|
||||
pack $w.ok -in $w.b -side left
|
||||
if {$qid != "*"} {
|
||||
@@ -3502,6 +3540,9 @@ proc ReadTaggedOptions { tag date } {
|
||||
if {[dict exists $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]} {
|
||||
lappend ans -txtentry-description [dict get $info description]
|
||||
}
|
||||
@@ -3637,6 +3678,29 @@ proc EditableLeave { w } {
|
||||
$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 } {
|
||||
global SynToObj Balloon
|
||||
set tags [$w tag names current]
|
||||
@@ -3651,7 +3715,7 @@ proc details_enter { w } {
|
||||
set obj $SynToObj($syntag)
|
||||
set lines {}
|
||||
if {![dict exists $obj info]} {
|
||||
return;
|
||||
return
|
||||
}
|
||||
set info [dict get $obj info]
|
||||
set llen 0
|
||||
@@ -3661,6 +3725,9 @@ proc details_enter { w } {
|
||||
if {[dict exists $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} {
|
||||
return;
|
||||
}
|
||||
@@ -3678,42 +3745,22 @@ proc details_popup { pairs } {
|
||||
global Balloon
|
||||
set maxwid 80
|
||||
set h .balloonhelp
|
||||
set c 0
|
||||
toplevel $h -bg #000000
|
||||
text $h.l -width $maxwid -height 16 -bd 0 -wrap word -relief flat -bg #FFFFC0
|
||||
$h.l tag configure bold -font {-weight bold}
|
||||
$h.l tag configure medium -font {-weight normal}
|
||||
frame $h.l -padx 0 -pady 0 -highlightthickness 0 -relief flat -bd 0 -bg #FFFFC0
|
||||
pack $h.l -side top -padx 1 -pady 1 -ipadx 2 -ipady 1
|
||||
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
|
||||
set geom [balloon_calculate_geometry $h]
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -2389,7 +2389,7 @@ void WriteJSONTimeTrigger(TimeTrig const *tt)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
WriteJSONInfoChain(TrigInfo *ti)
|
||||
{
|
||||
printf("\"info\":{");
|
||||
|
||||
@@ -215,6 +215,33 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
if (c == '<') {
|
||||
DynamicBuffer header;
|
||||
char const *val;
|
||||
DBufInit(&header);
|
||||
|
||||
while(1) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(&header);
|
||||
return err;
|
||||
}
|
||||
if (!c || c == '>') {
|
||||
break;
|
||||
}
|
||||
DBufPutc(&header, c);
|
||||
}
|
||||
if (!c) {
|
||||
Wprint(tr("Warning: Unterminated %%<...> substitution sequence"));
|
||||
}
|
||||
err = OK;
|
||||
val = FindTrigInfo(t, DBufValue(&header));
|
||||
DBufFree(&header);
|
||||
if (val) {
|
||||
SHIP_OUT(val);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (c == '(') {
|
||||
DynamicBuffer orig;
|
||||
DynamicBuffer translated;
|
||||
@@ -755,6 +782,8 @@ int DoSubstFromString(char const *source, DynamicBuffer *dbuf,
|
||||
if (tim == NO_TIME) tim=MinutesPastMidnight(0);
|
||||
CreateParser(source, &tempP);
|
||||
tempP.allownested = 0;
|
||||
tempTrig.infos = NULL;
|
||||
DBufInit(&tempTrig.tags);
|
||||
tempTrig.typ = MSG_TYPE;
|
||||
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 FTrigdelta (func_info *);
|
||||
static int FTrigduration (func_info *);
|
||||
static int FTriginfo (func_info *);
|
||||
static int FTrigeventduration(func_info *);
|
||||
static int FTrigeventstart (func_info *);
|
||||
static int FTrigfrom (func_info *);
|
||||
@@ -326,6 +327,7 @@ BuiltinFunc Func[] = {
|
||||
{ "trigeventstart", 0, 0, 0, FTrigeventstart, NULL },
|
||||
{ "trigfrom", 0, 0, 0, FTrigfrom, NULL },
|
||||
{ "trigger", 1, 3, 0, FTrigger, NULL },
|
||||
{ "triginfo", 1, 1, 1, FTriginfo, NULL },
|
||||
{ "trigpriority", 0, 0, 0, FTrigpriority, NULL },
|
||||
{ "trigrep", 0, 0, 0, FTrigrep, NULL },
|
||||
{ "trigscanfrom", 0, 0, 0, FTrigscanfrom, NULL },
|
||||
@@ -1620,6 +1622,17 @@ static int FTrigeventduration(func_info *info)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FTriginfo(func_info *info)
|
||||
{
|
||||
char const *s;
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
s = FindTrigInfo(&LastTrigger, ARGSTR(0));
|
||||
if (!s) {
|
||||
return RetStrVal("", info);
|
||||
}
|
||||
return RetStrVal(s, info);
|
||||
}
|
||||
|
||||
static int FTrigeventstart(func_info *info)
|
||||
{
|
||||
if (LastTrigger.eventstart == NO_TIME) {
|
||||
|
||||
19
src/main.c
19
src/main.c
@@ -145,6 +145,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
DBufInit(&(LastTrigger.tags));
|
||||
LastTrigger.infos = NULL;
|
||||
ClearLastTriggers();
|
||||
|
||||
atexit(exitfunc);
|
||||
@@ -1945,7 +1946,9 @@ void
|
||||
FreeTrig(Trigger *t)
|
||||
{
|
||||
DBufFree(&(t->tags));
|
||||
FreeTrigInfoChain(t->infos);
|
||||
if (t->infos) {
|
||||
FreeTrigInfoChain(t->infos);
|
||||
}
|
||||
t->infos = NULL;
|
||||
}
|
||||
|
||||
@@ -1972,8 +1975,7 @@ ClearLastTriggers(void)
|
||||
LastTrigger.warn[0] = 0;
|
||||
LastTrigger.omitfunc[0] = 0;
|
||||
LastTrigger.passthru[0] = 0;
|
||||
DBufFree(&(LastTrigger.tags));
|
||||
LastTrigger.infos = NULL;
|
||||
FreeTrig(&LastTrigger);
|
||||
LastTimeTrig.ttime = NO_TIME;
|
||||
LastTimeTrig.delta = NO_DELTA;
|
||||
LastTimeTrig.rep = NO_REP;
|
||||
@@ -1993,10 +1995,19 @@ SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigt
|
||||
void
|
||||
SaveLastTrigger(Trigger const *t)
|
||||
{
|
||||
DBufFree(&(LastTrigger.tags));
|
||||
FreeTrig(&LastTrigger);
|
||||
memcpy(&LastTrigger, t, sizeof(LastTrigger));
|
||||
|
||||
/* DON'T hang on to the invalid info chain! */
|
||||
LastTrigger.infos = NULL;
|
||||
DBufInit(&(LastTrigger.tags));
|
||||
|
||||
DBufPuts(&(LastTrigger.tags), DBufValue(&(t->tags)));
|
||||
TrigInfo *cur = t->infos;
|
||||
while(cur) {
|
||||
AppendTrigInfo(&LastTrigger, cur->info);
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -282,3 +282,5 @@ void FreeTrigInfoChain(TrigInfo *ti);
|
||||
int AppendTrigInfo(Trigger *t, char const *info);
|
||||
int TrigInfoHeadersAreTheSame(char const *i1, char const *i2);
|
||||
int TrigInfoIsValid(char const *info);
|
||||
char const *FindTrigInfo(Trigger *t, char const *header);
|
||||
void WriteJSONInfoChain(TrigInfo *ti);
|
||||
|
||||
@@ -474,6 +474,9 @@ void HandleQueuedReminders(void)
|
||||
PrintJSONKeyPairString("qid", qid);
|
||||
PrintJSONKeyPairString("ttime", SimpleTimeNoSpace(q->tt.ttime));
|
||||
PrintJSONKeyPairString("now", SimpleTimeNoSpace(MinutesPastMidnight(1)));
|
||||
if (q->t.infos) {
|
||||
WriteJSONInfoChain(q->t.infos);
|
||||
}
|
||||
PrintJSONKeyPairString("tags", DBufValue(&q->t.tags));
|
||||
} else {
|
||||
printf("NOTE reminder %s",
|
||||
|
||||
@@ -342,7 +342,7 @@ int main(int argc, char *argv[])
|
||||
while (!feof(stdin)) {
|
||||
DBufGets(&buf, stdin);
|
||||
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);
|
||||
}
|
||||
first_line = 0;
|
||||
|
||||
@@ -706,7 +706,9 @@ FreeTrigInfo(TrigInfo *ti)
|
||||
{
|
||||
if (ti->info) {
|
||||
free( (void *) ti->info);
|
||||
ti->info = NULL;
|
||||
}
|
||||
ti->next = NULL;
|
||||
free(ti);
|
||||
}
|
||||
|
||||
@@ -792,3 +794,26 @@ TrigInfoIsValid(char const *info)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
char const *
|
||||
FindTrigInfo(Trigger *t, char const *header)
|
||||
{
|
||||
TrigInfo *ti;
|
||||
size_t len;
|
||||
char const *s;
|
||||
|
||||
if (!t || !header || !*header) return NULL;
|
||||
|
||||
ti = t->infos;
|
||||
len = strlen(header);
|
||||
while(ti) {
|
||||
if (!strncasecmp(ti->info, header, len) &&
|
||||
ti->info[len] == ':') {
|
||||
s = ti->info + len + 1;
|
||||
while(isspace(*s)) s++;
|
||||
return s;
|
||||
}
|
||||
ti = ti->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -647,7 +647,7 @@ EOF
|
||||
|
||||
# The INFO keyword
|
||||
../src/remind -pp - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
REM Wed INFO "Location: here" INFO "Summary: Nope" MSG Meeting
|
||||
REM Wed INFO "Location: here" INFO "Summary: Nope" MSG Meeting [triginfo("location")] %<summary> %<nonexist> [triginfo("cabbage")]
|
||||
EOF
|
||||
|
||||
# Invalid info strings
|
||||
|
||||
@@ -24164,6 +24164,7 @@ trigeventduration
|
||||
trigeventstart
|
||||
trigfrom
|
||||
trigger
|
||||
triginfo
|
||||
trigpriority
|
||||
trigrep
|
||||
trigscanfrom
|
||||
@@ -24541,6 +24542,7 @@ TRANSLATE "Warning: UNTIL/THROUGH date earlier than SCANFROM date" ""
|
||||
TRANSLATE "Warning: UNTIL/THROUGH date earlier than start date" ""
|
||||
TRANSLATE "Warning: Unable to save ONCE timestamp to %s: %s" ""
|
||||
TRANSLATE "Warning: Unterminated %%(...) substitution sequence" ""
|
||||
TRANSLATE "Warning: Unterminated %%<...> substitution sequence" ""
|
||||
TRANSLATE "Warning: Unterminated %%{...} substitution sequence" ""
|
||||
TRANSLATE "Warning: Useless use of UNTIL with fully-specified date and no *rep" ""
|
||||
TRANSLATE "Warning: Variable name `%.*s...' truncated to `%.*s'" ""
|
||||
@@ -24659,10 +24661,10 @@ February 2024 29 4 0
|
||||
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
|
||||
January 31
|
||||
March 31
|
||||
{"date":"2024-02-07","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"body":"Meeting"}
|
||||
{"date":"2024-02-14","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"body":"Meeting"}
|
||||
{"date":"2024-02-21","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"body":"Meeting"}
|
||||
{"date":"2024-02-28","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"body":"Meeting"}
|
||||
{"date":"2024-02-07","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"rawbody":"Meeting [triginfo(\"location\")] %<summary> %<nonexist> [triginfo(\"cabbage\")]","body":"Meeting here Nope "}
|
||||
{"date":"2024-02-14","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"rawbody":"Meeting [triginfo(\"location\")] %<summary> %<nonexist> [triginfo(\"cabbage\")]","body":"Meeting here Nope "}
|
||||
{"date":"2024-02-21","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"rawbody":"Meeting [triginfo(\"location\")] %<summary> %<nonexist> [triginfo(\"cabbage\")]","body":"Meeting here Nope "}
|
||||
{"date":"2024-02-28","filename":"-","lineno":1,"info":{"location":"here","summary":"Nope"},"wd":["Wednesday"],"priority":5000,"rawbody":"Meeting [triginfo(\"location\")] %<summary> %<nonexist> [triginfo(\"cabbage\")]","body":"Meeting here Nope "}
|
||||
# rem2ps2 end
|
||||
-stdin-(1): Invalid INFO string: Must be of the form "Header: Value"
|
||||
-stdin-(2): Invalid INFO string: Must be of the form "Header: Value"
|
||||
|
||||
Reference in New Issue
Block a user