mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 23:08:40 +02:00
Compare commits
34 Commits
04.02.03-B
...
04.02.04
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fee354e6c | ||
|
|
ec76554d41 | ||
|
|
ddb0817c99 | ||
|
|
3d6ecd1f72 | ||
|
|
e3ec6565e9 | ||
|
|
8ed49ead7f | ||
|
|
49fbca416f | ||
|
|
82cd438fff | ||
|
|
946e1bca38 | ||
|
|
e40c81b5bf | ||
|
|
f23418480d | ||
|
|
bb4df39c50 | ||
|
|
5fec775863 | ||
|
|
a85980fec2 | ||
|
|
f3ea2962e6 | ||
|
|
3a5af23ab6 | ||
|
|
f9656edc51 | ||
|
|
5134b47d47 | ||
|
|
d4a183f3bf | ||
|
|
87e392de6c | ||
|
|
afc1667e64 | ||
|
|
8d25270c43 | ||
|
|
929866a770 | ||
|
|
395bad96a7 | ||
|
|
cd7be006c9 | ||
|
|
f658ba7ee7 | ||
|
|
7416f4c035 | ||
|
|
2860159ff7 | ||
|
|
64fa71ab09 | ||
|
|
ffbba7d4d1 | ||
|
|
fdcc2d8acf | ||
|
|
f1aa4d16af | ||
|
|
a55c5580f3 | ||
|
|
569e315306 |
2
configure
vendored
2
configure
vendored
@@ -4025,7 +4025,7 @@ _ACEOF
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
VERSION=04.02.02
|
VERSION=04.02.04
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ if test "$?" != 0 ; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups)
|
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups)
|
||||||
VERSION=04.02.02
|
VERSION=04.02.04
|
||||||
AC_SUBST(VERSION)
|
AC_SUBST(VERSION)
|
||||||
AC_SUBST(PERL)
|
AC_SUBST(PERL)
|
||||||
AC_SUBST(PERLARTIFACTS)
|
AC_SUBST(PERLARTIFACTS)
|
||||||
|
|||||||
@@ -1,6 +1,53 @@
|
|||||||
CHANGES TO REMIND
|
CHANGES TO REMIND
|
||||||
|
|
||||||
* VERSION 4.2 Patch 3 - 2023-??-??
|
* VERSION 4.2 Patch 4 - 2023-03-15
|
||||||
|
|
||||||
|
- NEW FEATURE: Remind: Add "htmlescape" and "htmlstriptags" built-in
|
||||||
|
functions.
|
||||||
|
|
||||||
|
- NEW FEATURE: Rem2PDF: Add the "--wrap, -y" option to ensure that no
|
||||||
|
printed calendar takes up more than 5 rows. If a calendar would normally
|
||||||
|
require 6 rows, wrap it so the last day or two appear on the first
|
||||||
|
row instead of on a sixth row.
|
||||||
|
|
||||||
|
- NEW FEATURE: Remind: Improve the -k option to allow specification of
|
||||||
|
separate commands for immediately-issued vs. queued reminders. For
|
||||||
|
example:
|
||||||
|
|
||||||
|
remind '-kcmd1 %s' '-k:cmd2 %s' ...
|
||||||
|
|
||||||
|
will use "cmd1" for immediately-issued reminders and "cmd2" for queued
|
||||||
|
ones. If you only use '-k:cmd2 %s' then immediately-issued reminders
|
||||||
|
are simply printed as usual rather than being passed to a command.
|
||||||
|
|
||||||
|
- IMPROVEMENT: Remind: Make "SPECIAL MSG" the same as just "MSG" and
|
||||||
|
the same for MSF, RUN, PS and PSFILE. This effectively lets you use
|
||||||
|
expression-pasting to determine the type of a REM command; see the
|
||||||
|
remind(1) man page for details.
|
||||||
|
|
||||||
|
- MINOR IMPROVEMENT: If "make test" fails, output up to 200 lines of diff
|
||||||
|
so we can see immediately what failed.
|
||||||
|
|
||||||
|
- DOCUMENTATION FIX: Fix some typos; fix TkRemind syntax description.
|
||||||
|
|
||||||
|
- TEST FIX: Make tests run reliably regardless of local machine's time zone.
|
||||||
|
|
||||||
|
- BUG FIX: TkRemind: Don't crash if local installation of Tk lacks the
|
||||||
|
-underlinefg configuration option.
|
||||||
|
|
||||||
|
- BUG FIX: examples/defs.rem: Fix up US Thanksgiving example.
|
||||||
|
|
||||||
|
- BUG FIX: include/holidays/us.rem: Add logic for US holidays that are
|
||||||
|
observed on a Friday if the holiday is a Saturday, or on a Monday if the
|
||||||
|
holiday is a Sunday.
|
||||||
|
|
||||||
|
- BUG FIX: TkRemind: Don't cut off MOON text at the first white-space
|
||||||
|
character.
|
||||||
|
|
||||||
|
- BUG FIX: Remind: prevent functions defined on the command-line (as in
|
||||||
|
remind '-if(x)=whatever') from segfaulting.
|
||||||
|
|
||||||
|
* VERSION 4.2 Patch 3 - 2023-02-10
|
||||||
|
|
||||||
- NEW FEATURE: Remind: add the orthodoxeaster() function to return the
|
- NEW FEATURE: Remind: add the orthodoxeaster() function to return the
|
||||||
date of Orthodox Easter.
|
date of Orthodox Easter.
|
||||||
@@ -9,6 +56,9 @@ CHANGES TO REMIND
|
|||||||
|
|
||||||
- IMPROVEMENT: Add Greek holiday file courtesy of JeiEl.
|
- IMPROVEMENT: Add Greek holiday file courtesy of JeiEl.
|
||||||
|
|
||||||
|
- IMPROVEMENT: Fix the Perl code (rem2pdf, rem2html) to silence Perl::Critic
|
||||||
|
warnings
|
||||||
|
|
||||||
- IMPROVEMENT: Many internal code tweaks to eliminate many cppcheck
|
- IMPROVEMENT: Many internal code tweaks to eliminate many cppcheck
|
||||||
static analysis warnings.
|
static analysis warnings.
|
||||||
|
|
||||||
@@ -23,6 +73,9 @@ CHANGES TO REMIND
|
|||||||
|
|
||||||
- BUG FIX: Remind: Add missing #include <fcntl.h> to funcs.c
|
- BUG FIX: Remind: Add missing #include <fcntl.h> to funcs.c
|
||||||
|
|
||||||
|
- BUG FIX: Remind: Fix undefined integer-overflow behavior in built-in abs()
|
||||||
|
function. Pointed out on IRC by "ubitux".
|
||||||
|
|
||||||
* VERSION 4.2 Patch 2 - 2023-01-01
|
* VERSION 4.2 Patch 2 - 2023-01-01
|
||||||
|
|
||||||
- NEW FEATURE: Remind: Add the NOQUEUE modifier to the REM statement for
|
- NEW FEATURE: Remind: Add the NOQUEUE modifier to the REM statement for
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ SET Week_1 1
|
|||||||
SET Week_2 8
|
SET Week_2 8
|
||||||
SET Week_3 15
|
SET Week_3 15
|
||||||
SET Week_4 22
|
SET Week_4 22
|
||||||
FSET _last(mo) "1 " + MON((mo%12)+1) + " --7"
|
|
||||||
|
|
||||||
#################################################################
|
#################################################################
|
||||||
# Function that removes a single leading zero from a string... #
|
# Function that removes a single leading zero from a string... #
|
||||||
@@ -126,6 +125,8 @@ REM Sat Sun SPECIAL SHADE 220
|
|||||||
# The following holidays were provided by Dave Rickel #
|
# The following holidays were provided by Dave Rickel #
|
||||||
# Modified by D. Skoll to give safe OMITs for moveable holidays #
|
# Modified by D. Skoll to give safe OMITs for moveable holidays #
|
||||||
# #
|
# #
|
||||||
|
# NOTE: See include/holidays/us.rem for more up-to-date definitions #
|
||||||
|
# #
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
SET SaveTrig $NumTrig
|
SET SaveTrig $NumTrig
|
||||||
@@ -189,7 +190,7 @@ REM Nov 11 MSG %"Veterans Day%"
|
|||||||
REM Oct 30 MSG %"Mischief Night%"
|
REM Oct 30 MSG %"Mischief Night%"
|
||||||
REM Oct 31 MSG %"Halloween%"
|
REM Oct 31 MSG %"Halloween%"
|
||||||
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG %"Election Day%"
|
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG %"Election Day%"
|
||||||
REM Last Thu in Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
|
REM Thu Nov [Week_4] SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
|
||||||
REM Fri Nov [Week_4+1] SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
|
REM Fri Nov [Week_4+1] SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
|
||||||
OMIT Dec 24 MSG %"Christmas Eve%"
|
OMIT Dec 24 MSG %"Christmas Eve%"
|
||||||
OMIT Dec 25 MSG %"Christmas%" Day
|
OMIT Dec 25 MSG %"Christmas%" Day
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ REM [easterdate($Uy)+49] MSG Pentecost
|
|||||||
# which ones are omitted.
|
# which ones are omitted.
|
||||||
|
|
||||||
OMIT Jan 1 MSG New Year's Day
|
OMIT Jan 1 MSG New Year's Day
|
||||||
|
REM 31 Dec SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG New Year's Day (observed)
|
||||||
|
REM 2 Jan SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG New Year's Day (observed)
|
||||||
|
|
||||||
REM Third Monday in Jan MSG Martin Luther King - %"MLK Day%"
|
REM Third Monday in Jan MSG Martin Luther King - %"MLK Day%"
|
||||||
REM Feb 2 MSG Ground Hog Day
|
REM Feb 2 MSG Ground Hog Day
|
||||||
REM Feb 14 MSG Valentine's Day
|
REM Feb 14 MSG Valentine's Day
|
||||||
@@ -21,8 +24,8 @@ REM Third Monday in Feb SCANFROM -7 ADDOMIT MSG President's Day
|
|||||||
REM Mar 17 MSG St. Patrick's Day
|
REM Mar 17 MSG St. Patrick's Day
|
||||||
|
|
||||||
# These are accurate for most places in North America
|
# These are accurate for most places in North America
|
||||||
REM MAYBE-UNCOMPUTABLE Sun November SATISFY [isdst($T) != isdst($T+1)] MSG Daylight Saving Time Ends
|
REM MAYBE-UNCOMPUTABLE Sun November SATISFY [isdst($T) && !isdst($T+1)] MSG Daylight Saving Time Ends
|
||||||
REM MAYBE-UNCOMPUTABLE Sun March SATISFY [isdst($T) != isdst($T+1)] MSG Daylight Saving Time Starts
|
REM MAYBE-UNCOMPUTABLE Sun March SATISFY [!isdst($T) && isdst($T+1)] MSG Daylight Saving Time Starts
|
||||||
|
|
||||||
REM Apr 1 MSG %"April Fool's%" Day
|
REM Apr 1 MSG %"April Fool's%" Day
|
||||||
|
|
||||||
@@ -49,14 +52,21 @@ REM Third Sat in May MSG Armed Forces Day
|
|||||||
REM Last Monday in May SCANFROM -7 ADDOMIT MSG Memorial Day
|
REM Last Monday in May SCANFROM -7 ADDOMIT MSG Memorial Day
|
||||||
REM Jun 14 MSG Flag Day
|
REM Jun 14 MSG Flag Day
|
||||||
|
|
||||||
|
OMIT 19 June MSG Juneteenth
|
||||||
|
REM 18 June SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Juneteenth (observed)
|
||||||
|
REM 20 June SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Juneteenth (observed)
|
||||||
|
|
||||||
REM July 4 SCANFROM -7 ADDOMIT MSG Independence Day
|
REM July 4 SCANFROM -7 ADDOMIT MSG Independence Day
|
||||||
REM July 3 SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Independence Day (observed)
|
REM July 3 SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Independence Day (observed)
|
||||||
REM July 5 SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Independence Day (observed)
|
REM July 5 SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Independence Day (observed)
|
||||||
|
|
||||||
REM Third Sun in June MSG Father's Day
|
REM Third Sun in June MSG Father's Day
|
||||||
REM First Mon in Sep SCANFROM -7 ADDOMIT MSG Labor Day
|
REM First Mon in Sep SCANFROM -7 ADDOMIT MSG Labor Day
|
||||||
REM Second Mon in Oct MSG Columbus Day / Indigenous Peoples' Day
|
REM Second Mon in Oct MSG Columbus Day / Indigenous Peoples' Day
|
||||||
REM Nov 11 MSG Veterans Day
|
|
||||||
|
OMIT 11 Nov MSG Veterans Day
|
||||||
|
REM 10 Nov SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Veterans Day (observed)
|
||||||
|
REM 12 Nov SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Veterans Day (observed)
|
||||||
|
|
||||||
REM Oct 30 MSG Mischief Night
|
REM Oct 30 MSG Mischief Night
|
||||||
REM Oct 31 MSG Halloween
|
REM Oct 31 MSG Halloween
|
||||||
@@ -64,8 +74,9 @@ REM Oct 31 MSG Halloween
|
|||||||
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG Election Day
|
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG Election Day
|
||||||
|
|
||||||
REM Thu 22 Nov SCANFROM -7 ADDOMIT MSG Thanksgiving Day
|
REM Thu 22 Nov SCANFROM -7 ADDOMIT MSG Thanksgiving Day
|
||||||
|
|
||||||
REM Fri 23 Nov SCANFROM -7 ADDOMIT MSG Thanksgiving (cont.)
|
REM Fri 23 Nov SCANFROM -7 ADDOMIT MSG Thanksgiving (cont.)
|
||||||
|
|
||||||
REM Dec 24 MSG Christmas Eve
|
REM Dec 24 MSG Christmas Eve
|
||||||
OMIT Dec 25 MSG %"Christmas%" Day
|
OMIT Dec 25 MSG %"Christmas%" Day
|
||||||
|
REM 24 Dec SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Christmas (observed)
|
||||||
|
REM 26 Dec SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Christmas (observed)
|
||||||
|
|||||||
@@ -328,6 +328,18 @@ processes with the above technique. So be very careful. Because all
|
|||||||
shell and whitespace characters are escaped, the program you execute
|
shell and whitespace characters are escaped, the program you execute
|
||||||
with the \fB\-k\fR option must be prepared to handle the entire
|
with the \fB\-k\fR option must be prepared to handle the entire
|
||||||
message as a single argument.
|
message as a single argument.
|
||||||
|
.PP
|
||||||
|
If you follow the \fB\-k\fR option with a colon, then the command is applied
|
||||||
|
only to queued timed reminders. Normal reminders are handled as usual.
|
||||||
|
In the above example, if you want normal reminders to simply be displayed
|
||||||
|
as usual, but queued reminders to be sent to notify-send, you could use:
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
remind '\-k:notify-send %s &' ...
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
You use both \fB\-k\fR\fIcmd1\fR and \fB\-k:\fR\fIcmd2\fR to use different
|
||||||
|
commands for queued versus non-queued reminders.
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
\fB\-z\fR[\fIn\fR] Runs \fBRemind\fR in the daemon mode. If \fIn\fR
|
\fB\-z\fR[\fIn\fR] Runs \fBRemind\fR in the daemon mode. If \fIn\fR
|
||||||
@@ -1006,7 +1018,7 @@ By comparison, if we had used "\-\-1", the reminder would be triggered on
|
|||||||
the last day of the month, regardless of the \fBOMIT\fR.
|
the last day of the month, regardless of the \fBOMIT\fR.
|
||||||
.PP
|
.PP
|
||||||
If you locally omit weekdays but also have globally-omitted weekdays, then
|
If you locally omit weekdays but also have globally-omitted weekdays, then
|
||||||
the list of ommitted weekdays is the union of the two. Consider this
|
the list of omitted weekdays is the union of the two. Consider this
|
||||||
example:
|
example:
|
||||||
.PP
|
.PP
|
||||||
.nf
|
.nf
|
||||||
@@ -3074,6 +3086,16 @@ Support for Hebrew dates - see the section "THE HEBREW CALENDAR"
|
|||||||
.B hour(tq_time)
|
.B hour(tq_time)
|
||||||
Returns the hour component of \fItime\fR.
|
Returns the hour component of \fItime\fR.
|
||||||
.TP
|
.TP
|
||||||
|
.B htmlescape(s_str)
|
||||||
|
Returns a modified copy of \fIstr\fR where "<" is replaced with
|
||||||
|
"<"; ">" is replaced with ">" and "&" is replaced with "&"
|
||||||
|
.TP
|
||||||
|
.B htmlstriptags(s_str)
|
||||||
|
Returns a modified copy of \fIstr\fR where HTML tags are stripped
|
||||||
|
out. The stripping algorithm is fairly naive; the function starts
|
||||||
|
stripping characters when it encounters a "<" and it stops stripping
|
||||||
|
when it encounters a ">".
|
||||||
|
.TP
|
||||||
.B iif(si_test1, x_arg1, [si_test2, x_arg2,...], x_default)
|
.B iif(si_test1, x_arg1, [si_test2, x_arg2,...], x_default)
|
||||||
If \fItest1\fR is not zero or the null string, returns \fIarg1\fR.
|
If \fItest1\fR is not zero or the null string, returns \fIarg1\fR.
|
||||||
Otherwise, if \fItest2\fR is not zero or the null string, returns
|
Otherwise, if \fItest2\fR is not zero or the null string, returns
|
||||||
@@ -4065,15 +4087,30 @@ You cannot use expression-pasting to determine the type (\fBMSG\fR,
|
|||||||
\fBCAL\fR, etc.) of a \fBREM\fR command. You can paste expressions
|
\fBCAL\fR, etc.) of a \fBREM\fR command. You can paste expressions
|
||||||
before and after the \fBMSG\fR, etc. keywords, but cannot do something like
|
before and after the \fBMSG\fR, etc. keywords, but cannot do something like
|
||||||
this:
|
this:
|
||||||
|
.RS
|
||||||
.PP
|
.PP
|
||||||
.nf
|
.nf
|
||||||
REM ["12 Nov 1993 AT 13:05 " + "MSG" + " BOO!"]
|
REM ["12 Nov 1993 AT 13:05 " + "MSG" + " BOO!"]
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
.B COMMON PITFALLS IN EXPRESSION PASTING
|
However, as an escape hatch, the sequence \fBSPECIAL\fR \fItype\fR
|
||||||
|
means the same thing as just \fItype\fR where \fItype\fR is one
|
||||||
|
of MSG, MSF, RUN, CAL, PS and PSFILE. This lets you do something
|
||||||
|
like this:
|
||||||
.PP
|
.PP
|
||||||
Remember, when pasting in expressions, that extra spaces are not
|
.nf
|
||||||
inserted. Thus, something like:
|
SET type "MSG"
|
||||||
|
REM 12 Nov 2024 SPECIAL [type] Hello
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
You can use this to control the types of your reminders based on variables
|
||||||
|
you set, how Remind is invoked, etc.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
.B COMMON PITFALLS WITH EXPRESSION PASTING
|
||||||
|
.PP
|
||||||
|
Remember that extra spaces are not inserted when an expression is
|
||||||
|
pasted. Thus, something like:
|
||||||
.PP
|
.PP
|
||||||
.nf
|
.nf
|
||||||
REM[expr]MSG[expr]
|
REM[expr]MSG[expr]
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.SH NAME
|
.SH NAME
|
||||||
tkremind \- graphical front-end to Remind calendar program
|
tkremind \- graphical front-end to Remind calendar program
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B tkremind \fR[\fIoptions\fR] [\fIread_file\fR] [\fIwrite_file\fR] [\fIconfig_file\fR]
|
.B tkremind \fR[\fIoptions\fR] [\fIread_file\fR [\fIwrite_file\fR [\fIconfig_file\fR]]]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
\fBTkRemind\fR is a graphical front-end to the \fBRemind\fR program.
|
\fBTkRemind\fR is a graphical front-end to the \fBRemind\fR program.
|
||||||
It provides a friendly graphical interface which allows you to view
|
It provides a friendly graphical interface which allows you to view
|
||||||
|
|||||||
@@ -687,7 +687,7 @@ if ($Options{help}) {
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-t STDIN) {
|
if (-t STDIN) { ## no critic
|
||||||
print STDERR "$TIDY_PROGNAME: Input should not come from a terminal.\n\n";
|
print STDERR "$TIDY_PROGNAME: Input should not come from a terminal.\n\n";
|
||||||
usage(1);
|
usage(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ my $settings = {
|
|||||||
numbers_on_left => 0,
|
numbers_on_left => 0,
|
||||||
small_calendars => 0,
|
small_calendars => 0,
|
||||||
fill_entire_page => 0,
|
fill_entire_page => 0,
|
||||||
|
wrap_calendar => 0,
|
||||||
media => 'Letter',
|
media => 'Letter',
|
||||||
width => 0,
|
width => 0,
|
||||||
height => 0,
|
height => 0,
|
||||||
@@ -86,6 +86,7 @@ Options:
|
|||||||
--media=MEDIA, -mMEDIA Size for specified media
|
--media=MEDIA, -mMEDIA Size for specified media
|
||||||
--width=W, -wW Specify media width in 1/72nds of an inch
|
--width=W, -wW Specify media width in 1/72nds of an inch
|
||||||
--height=H, -hH Specify media height in 1/72nds of an inch
|
--height=H, -hH Specify media height in 1/72nds of an inch
|
||||||
|
--wrap, -y Make calendar fit in at most 5 rows
|
||||||
--title-font=FONT Specify font for calendar title
|
--title-font=FONT Specify font for calendar title
|
||||||
--header-font=FONT Specify font for weekday names
|
--header-font=FONT Specify font for weekday names
|
||||||
--daynum-font=FONT Specify font for day numbers
|
--daynum-font=FONT Specify font for day numbers
|
||||||
@@ -114,6 +115,7 @@ my $ret = GetOptions('landscape|l' => \$settings->{landscape},
|
|||||||
'fill-page|e' => \$settings->{fill_entire_page},
|
'fill-page|e' => \$settings->{fill_entire_page},
|
||||||
'media|m=s' => \$settings->{media},
|
'media|m=s' => \$settings->{media},
|
||||||
'width|w=i' => \$settings->{width},
|
'width|w=i' => \$settings->{width},
|
||||||
|
'wrap|y' => \$settings->{wrap_calendar},
|
||||||
'height|h=i' => \$settings->{height},
|
'height|h=i' => \$settings->{height},
|
||||||
'title-font=s' => \$settings->{title_font},
|
'title-font=s' => \$settings->{title_font},
|
||||||
'header-font=s' => \$settings->{header_font},
|
'header-font=s' => \$settings->{header_font},
|
||||||
@@ -175,7 +177,7 @@ if ($settings->{landscape}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Don't read from a terminal
|
# Don't read from a terminal
|
||||||
if (-t STDIN) {
|
if (-t STDIN) { ## no critic
|
||||||
print STDERR "I can't read data from a terminal. Please run like this:\n";
|
print STDERR "I can't read data from a terminal. Please run like this:\n";
|
||||||
print STDERR " remind -pp [options] filename | $me [options] > out.pdf\n";
|
print STDERR " remind -pp [options] filename | $me [options] > out.pdf\n";
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -249,20 +251,21 @@ sub set_media
|
|||||||
sub set_media_from_file
|
sub set_media_from_file
|
||||||
{
|
{
|
||||||
my ($fn) = @_;
|
my ($fn) = @_;
|
||||||
if (!open(IN, '<', $fn)) {
|
my $IN;
|
||||||
|
if (!open($IN, '<', $fn)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
while(<IN>) {
|
while(<$IN>) {
|
||||||
chomp;
|
chomp;
|
||||||
s/^\s+//;
|
s/^\s+//;
|
||||||
s/\s+$//;
|
s/\s+$//;
|
||||||
next if ($_ eq '');
|
next if ($_ eq '');
|
||||||
next if ($_ =~ /^#/);
|
next if ($_ =~ /^#/);
|
||||||
my $m = $_;
|
my $m = $_;
|
||||||
close(IN);
|
close($IN);
|
||||||
return set_media($m);
|
return set_media($m);
|
||||||
}
|
}
|
||||||
close(IN);
|
close($IN);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,6 +433,14 @@ The default is 36.
|
|||||||
The size of the margin at the right of the page in 1/72ths of an inch.
|
The size of the margin at the right of the page in 1/72ths of an inch.
|
||||||
The default is 36.
|
The default is 36.
|
||||||
|
|
||||||
|
=item --wrap, -y
|
||||||
|
|
||||||
|
Modify the calendar so that if it would normally require 6 rows to print,
|
||||||
|
then the last day (or last two days, as needed) are moved to the
|
||||||
|
first row of the calendar, and adjust the small calendar positions
|
||||||
|
as needed. This results in a calendar that only requires 5 rows, but
|
||||||
|
with the last day or two appearing in the I<first> row.
|
||||||
|
|
||||||
=item --verbose, -v
|
=item --verbose, -v
|
||||||
|
|
||||||
Print (on STDERR) the name of the month and year for each month that
|
Print (on STDERR) the name of the month and year for each month that
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ sub read_one_month
|
|||||||
$self->{daysinnextmonth} = 0;
|
$self->{daysinnextmonth} = 0;
|
||||||
$self->{prevmonthyear} = 0;
|
$self->{prevmonthyear} = 0;
|
||||||
$self->{nextmonthyear} = 0;
|
$self->{nextmonthyear} = 0;
|
||||||
|
|
||||||
for (my $i=0; $i<=31; $i++) {
|
for (my $i=0; $i<=31; $i++) {
|
||||||
$self->{entries}->[$i] = [];
|
$self->{entries}->[$i] = [];
|
||||||
}
|
}
|
||||||
@@ -134,7 +133,7 @@ sub read_one_month
|
|||||||
$line = $in->getline();
|
$line = $in->getline();
|
||||||
chomp($line);
|
chomp($line);
|
||||||
if ($line =~ /^\S+ \S+ \S+ \S+ \S+ \S+ \S+$/) {
|
if ($line =~ /^\S+ \S+ \S+ \S+ \S+ \S+ \S+$/) {
|
||||||
@{$self->{daynames}} = map { s/_/ /g; $_; } (split(/ /, $line));
|
@{$self->{daynames}} = map { s/_/ /g; $_; } (split(/ /, $line)); ## no critic
|
||||||
} else {
|
} else {
|
||||||
return (undef, "Cannot interpret line: $line");
|
return (undef, "Cannot interpret line: $line");
|
||||||
}
|
}
|
||||||
@@ -213,7 +212,7 @@ hash keys found in the newer "remind -pp" JSON output.
|
|||||||
sub parse_oldstyle_line
|
sub parse_oldstyle_line
|
||||||
{
|
{
|
||||||
my ($self, $line) = @_;
|
my ($self, $line) = @_;
|
||||||
return undef unless $line =~ m|^(\d+)/(\d+)/(\d+) (\S+) (\S+) (\S+) (\S+) (.*)$|;
|
return unless $line =~ m|^(\d+)/(\d+)/(\d+) (\S+) (\S+) (\S+) (\S+) (.*)$|;
|
||||||
|
|
||||||
my $hash = {
|
my $hash = {
|
||||||
date => "$1-$2-$3",
|
date => "$1-$2-$3",
|
||||||
@@ -244,6 +243,143 @@ sub parse_oldstyle_line
|
|||||||
return $hash;
|
return $hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=head2 setup_daymap
|
||||||
|
|
||||||
|
Set up the array that maps ($row, $col) to day number (or -1
|
||||||
|
for rows/cols out of range.)
|
||||||
|
|
||||||
|
=cut
|
||||||
|
sub setup_daymap
|
||||||
|
{
|
||||||
|
my ($self, $settings) = @_;
|
||||||
|
# First column
|
||||||
|
my $first_col = $self->{firstwkday};
|
||||||
|
if ($self->{mondayfirst}) {
|
||||||
|
$first_col--;
|
||||||
|
if ($first_col < 0) {
|
||||||
|
$first_col = 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Last column
|
||||||
|
my $last_col = ($first_col + $self->{daysinmonth} - 1) % 7;
|
||||||
|
|
||||||
|
# Number of rows
|
||||||
|
my $rows = 1;
|
||||||
|
my $last_day_on_row = 7 - $first_col;
|
||||||
|
while ($last_day_on_row < $self->{daysinmonth}) {
|
||||||
|
$last_day_on_row += 7;
|
||||||
|
$rows++;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add a row for small calendars if necessary
|
||||||
|
if (($settings->{small_calendars} != 0) && ($first_col == 0) && ($last_col == 6)) {
|
||||||
|
$rows++;
|
||||||
|
$self->{extra_row} = 1;
|
||||||
|
} else {
|
||||||
|
$self->{extra_row} = 0;
|
||||||
|
}
|
||||||
|
$self->{rows} = $rows;
|
||||||
|
$self->{daymap} = [];
|
||||||
|
$self->{first_col} = $first_col;
|
||||||
|
$self->{last_col} = $last_col;
|
||||||
|
for (my $row=0; $row<$rows; $row++) {
|
||||||
|
for (my $col=0; $col < 7; $col++) {
|
||||||
|
$self->{daymap}->[$row]->[$col] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$self->{nextcal_row} = -1;
|
||||||
|
$self->{prevcal_row} = -1;
|
||||||
|
$self->{nextcal_col} = 6;
|
||||||
|
$self->{prevcal_col} = 0;
|
||||||
|
# Figure out where to draw the small calendars
|
||||||
|
my $extra_row = $self->{extra_row};
|
||||||
|
if ($settings->{small_calendars} == 1) {
|
||||||
|
if ($last_col <= 4 || ($last_col == 6 && $extra_row)) {
|
||||||
|
$self->{prevcal_row} = $rows-1;
|
||||||
|
$self->{prevcal_col} = 5;
|
||||||
|
$self->{nextcal_row} = $rows-1;
|
||||||
|
$self->{nextcal_col} = 6;
|
||||||
|
} else {
|
||||||
|
$self->{prevcal_row} = 0;
|
||||||
|
$self->{prevcal_col} = 0;
|
||||||
|
$self->{nextcal_row} = 0;
|
||||||
|
$self->{nextcal_col} = 1;
|
||||||
|
}
|
||||||
|
} elsif ($settings->{small_calendars} == 2) {
|
||||||
|
if ($first_col >= 2) {
|
||||||
|
$self->{prevcal_row} = 0;
|
||||||
|
$self->{prevcal_col} = 0;
|
||||||
|
$self->{nextcal_row} = 0;
|
||||||
|
$self->{nextcal_col} = 1;
|
||||||
|
} else {
|
||||||
|
$self->{prevcal_row} = $rows-1;
|
||||||
|
$self->{prevcal_col} = 5;
|
||||||
|
$self->{nextcal_row} = $rows-1;
|
||||||
|
$self->{nextcal_col} = 6;
|
||||||
|
}
|
||||||
|
} elsif ($settings->{small_calendars} == 3) {
|
||||||
|
if ($first_col >= 1 && $last_col <= 5) {
|
||||||
|
$self->{prevcal_row} = 0;
|
||||||
|
$self->{prevcal_col} = 0;
|
||||||
|
$self->{nextcal_row} = $rows-1;
|
||||||
|
$self->{nextcal_col} = 6;
|
||||||
|
} else {
|
||||||
|
if ($last_col <= 4 || ($last_col == 6 && $extra_row)) {
|
||||||
|
$self->{prevcal_row} = $rows-1;
|
||||||
|
$self->{prevcal_col} = 5;
|
||||||
|
$self->{nextcal_row} = $rows-1;
|
||||||
|
$self->{nextcal_col} = 6;
|
||||||
|
} else {
|
||||||
|
$self->{prevcal_row} = 0;
|
||||||
|
$self->{prevcal_col} = 0;
|
||||||
|
$self->{nextcal_row} = 0;
|
||||||
|
$self->{nextcal_col} = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my $col = $first_col;
|
||||||
|
my $row = 0;
|
||||||
|
my $day = 1;
|
||||||
|
while ($day <= $self->{daysinmonth}) {
|
||||||
|
$self->{daymap}->[$row]->[$col] = $day;
|
||||||
|
$day++;
|
||||||
|
$col++;
|
||||||
|
if ($col > 6) {
|
||||||
|
$row++;
|
||||||
|
$col = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if we should wrap the calendar
|
||||||
|
if ($self->{rows} == 6 && $settings->{wrap_calendar}) {
|
||||||
|
# Move everything in the last row to the first row
|
||||||
|
my $occupied_col = 0;
|
||||||
|
for (my $col=0; $col<7; $col++) {
|
||||||
|
if ($self->{daymap}->[5]->[$col] > 0) {
|
||||||
|
$self->{daymap}->[0]->[$col] = $self->{daymap}->[5]->[$col];
|
||||||
|
$occupied_col = $col;
|
||||||
|
} else {
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($settings->{small_calendars}) {
|
||||||
|
$self->{prevcal_row} = 0;
|
||||||
|
$self->{prevcal_col} = $occupied_col+1;
|
||||||
|
$self->{nextcal_row} = 0;
|
||||||
|
$self->{nextcal_col} = $occupied_col+2;
|
||||||
|
for (my $col = 6; $col > 0; $col--) {
|
||||||
|
if ($self->{daymap}->[0]->[$col] < 0) {
|
||||||
|
$self->{nextcal_col} = $col;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$self->{rows} = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
=head2 read_one_month_pp($in, $specials_accepted)
|
=head2 read_one_month_pp($in, $specials_accepted)
|
||||||
|
|
||||||
This function reads one month's worth of data from the file handle
|
This function reads one month's worth of data from the file handle
|
||||||
@@ -329,6 +465,7 @@ sub render
|
|||||||
{
|
{
|
||||||
my ($self, $cr, $settings) = @_;
|
my ($self, $cr, $settings) = @_;
|
||||||
|
|
||||||
|
$self->setup_daymap($settings);
|
||||||
$self->{horiz_lines} = [];
|
$self->{horiz_lines} = [];
|
||||||
$cr->set_line_cap('square');
|
$cr->set_line_cap('square');
|
||||||
my $so_far = $self->draw_title($cr, $settings);
|
my $so_far = $self->draw_title($cr, $settings);
|
||||||
@@ -347,111 +484,25 @@ sub render
|
|||||||
$self->{remaining_space} = $settings->{height} - $settings->{margin_bottom} - $so_far;
|
$self->{remaining_space} = $settings->{height} - $settings->{margin_bottom} - $so_far;
|
||||||
|
|
||||||
$self->{minimum_row_height} = $self->{remaining_space} / 9;
|
$self->{minimum_row_height} = $self->{remaining_space} / 9;
|
||||||
# First column
|
|
||||||
my $first_col = $self->{firstwkday};
|
|
||||||
if ($self->{mondayfirst}) {
|
|
||||||
$first_col--;
|
|
||||||
if ($first_col < 0) {
|
|
||||||
$first_col = 6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Last column
|
|
||||||
my $last_col = ($first_col + $self->{daysinmonth} - 1) % 7;
|
|
||||||
|
|
||||||
# Number of rows
|
|
||||||
my $rows = 1;
|
|
||||||
my $last_day_on_row = 7 - $first_col;
|
|
||||||
while ($last_day_on_row < $self->{daysinmonth}) {
|
|
||||||
$last_day_on_row += 7;
|
|
||||||
$rows++;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $extra_row = 0;
|
|
||||||
# Add a row for small calendars if necessary
|
|
||||||
if (($settings->{small_calendars} != 0) && ($first_col == 0) && ($last_col == 6)) {
|
|
||||||
$rows++;
|
|
||||||
$extra_row++;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Figure out where to draw the small calendars
|
|
||||||
my $prevcal_top = 0;
|
|
||||||
my $nextcal_top = 0;
|
|
||||||
my $prevcal_bottom = 0;
|
|
||||||
my $nextcal_bottom = 0;
|
|
||||||
|
|
||||||
if ($settings->{small_calendars} == 1) {
|
|
||||||
if ($last_col <= 4 || ($last_col == 6 && $extra_row)) {
|
|
||||||
$prevcal_bottom = 1;
|
|
||||||
$nextcal_bottom = 1;
|
|
||||||
} else {
|
|
||||||
$prevcal_top = 1;
|
|
||||||
$nextcal_top = 1;
|
|
||||||
}
|
|
||||||
} elsif ($settings->{small_calendars} == 2) {
|
|
||||||
if ($first_col >= 2) {
|
|
||||||
$prevcal_top = 1;
|
|
||||||
$nextcal_top = 1;
|
|
||||||
} else {
|
|
||||||
$prevcal_bottom = 1;
|
|
||||||
$nextcal_bottom = 1;
|
|
||||||
}
|
|
||||||
} elsif ($settings->{small_calendars} == 3) {
|
|
||||||
if ($first_col >= 1 && $last_col <= 5) {
|
|
||||||
$prevcal_top = 1;
|
|
||||||
$nextcal_bottom = 1;
|
|
||||||
} else {
|
|
||||||
if ($last_col <= 4 || ($last_col == 6 && $extra_row)) {
|
|
||||||
$prevcal_bottom = 1;
|
|
||||||
$nextcal_bottom = 1;
|
|
||||||
} else {
|
|
||||||
$prevcal_top = 1;
|
|
||||||
$nextcal_top = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Row height if we are filling the page
|
# Row height if we are filling the page
|
||||||
$self->{row_height} = $self->{remaining_space} / $rows;
|
$self->{row_height} = $self->{remaining_space} / $self->{rows};
|
||||||
|
|
||||||
my ($start_col, $start_day);
|
for (my $row = 0; $row < $self->{rows}; $row++) {
|
||||||
for (my $row = 0; $row < $rows; $row++) {
|
|
||||||
if ($row == 0) {
|
|
||||||
$start_day = 1;
|
|
||||||
$start_col = $first_col;
|
|
||||||
} else {
|
|
||||||
$start_col = 0;
|
|
||||||
}
|
|
||||||
my $old_so_far = $so_far;
|
my $old_so_far = $so_far;
|
||||||
$so_far = $self->draw_row($cr, $settings, $so_far, $row, $start_day, $start_col);
|
$so_far = $self->draw_row($cr, $settings, $so_far, $row);
|
||||||
$start_day += 7 - $start_col;
|
|
||||||
push(@{$self->{horiz_lines}}, $so_far);
|
push(@{$self->{horiz_lines}}, $so_far);
|
||||||
if ($row == 0) {
|
if ($row == $self->{prevcal_row}) {
|
||||||
if ($prevcal_top) {
|
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, $self->{prevcal_col}, $so_far - $old_so_far, $settings);
|
||||||
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 0, $so_far - $old_so_far, $settings);
|
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
|
||||||
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
|
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
|
||||||
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
|
$settings, $self->{prevmonthname}, $self->{daysinprevmonth}, ($self->{first_col} + 35 - $self->{daysinprevmonth}) % 7);
|
||||||
$settings, $self->{prevmonthname}, $self->{daysinprevmonth}, ($first_col + 35 - $self->{daysinprevmonth}) % 7);
|
}
|
||||||
}
|
if ($row == $self->{nextcal_row}) {
|
||||||
if ($nextcal_top) {
|
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, $self->{nextcal_col}, $so_far - $old_so_far, $settings);
|
||||||
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 1, $so_far - $old_so_far, $settings);
|
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
|
||||||
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
|
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
|
||||||
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
|
$settings, $self->{nextmonthname}, $self->{daysinnextmonth}, ($self->{last_col} + 1) % 7);
|
||||||
$settings, $self->{nextmonthname}, $self->{daysinnextmonth}, ($last_col + 1) % 7);
|
|
||||||
}
|
|
||||||
} elsif ($row == $rows-1) {
|
|
||||||
if ($prevcal_bottom) {
|
|
||||||
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 5, $so_far - $old_so_far, $settings);
|
|
||||||
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
|
|
||||||
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
|
|
||||||
$settings, $self->{prevmonthname}, $self->{daysinprevmonth}, ($first_col + 35 - $self->{daysinprevmonth}) % 7);
|
|
||||||
}
|
|
||||||
if ($nextcal_bottom) {
|
|
||||||
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 6, $so_far - $old_so_far, $settings);
|
|
||||||
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
|
|
||||||
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
|
|
||||||
$settings, $self->{nextmonthname}, $self->{daysinnextmonth}, ($last_col + 1) % 7);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,23 +546,18 @@ calendar row.
|
|||||||
=cut
|
=cut
|
||||||
sub draw_row
|
sub draw_row
|
||||||
{
|
{
|
||||||
my ($self, $cr, $settings, $so_far, $row, $start_day, $start_col) = @_;
|
my ($self, $cr, $settings, $so_far, $row) = @_;
|
||||||
|
|
||||||
my $col = $start_col;
|
|
||||||
my $day = $start_day;
|
|
||||||
my $height = 0;
|
my $height = 0;
|
||||||
|
|
||||||
# Preview them to figure out the row height...
|
# Preview them to figure out the row height...
|
||||||
if (!$settings->{fill_entire_page}) {
|
if (!$settings->{fill_entire_page}) {
|
||||||
while ($col < 7) {
|
for (my $col=0; $col<7; $col++) {
|
||||||
|
my $day = $self->{daymap}->[$row]->[$col];
|
||||||
|
next if ($day < 1);
|
||||||
my $h = $self->draw_day($cr, $settings, $so_far, $day, $col, 0);
|
my $h = $self->draw_day($cr, $settings, $so_far, $day, $col, 0);
|
||||||
$height = $h if ($h > $height);
|
$height = $h if ($h > $height);
|
||||||
$day++;
|
|
||||||
$col++;
|
|
||||||
last if ($day > $self->{daysinmonth});
|
|
||||||
}
|
}
|
||||||
$col = $start_col;
|
|
||||||
$day = $start_day;
|
|
||||||
} else {
|
} else {
|
||||||
$height = $self->{row_height} - $settings->{border_size} * 2;
|
$height = $self->{row_height} - $settings->{border_size} * 2;
|
||||||
}
|
}
|
||||||
@@ -520,10 +566,10 @@ sub draw_row
|
|||||||
$height = $self->{minimum_row_height};
|
$height = $self->{minimum_row_height};
|
||||||
}
|
}
|
||||||
# Now draw for real
|
# Now draw for real
|
||||||
while ($col < 7 && $day <= $self->{daysinmonth}) {
|
for (my $col=0; $col<7; $col++) {
|
||||||
|
my $day = $self->{daymap}->[$row]->[$col];
|
||||||
|
next if ($day < 1);
|
||||||
$self->draw_day($cr, $settings, $so_far, $day, $col, $height);
|
$self->draw_day($cr, $settings, $so_far, $day, $col, $height);
|
||||||
$day++;
|
|
||||||
$col++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $so_far + $height + $settings->{border_size};
|
return $so_far + $height + $settings->{border_size};
|
||||||
@@ -908,7 +954,7 @@ sub create_from_stream
|
|||||||
return(undef, 'Unable to parse JSON stream');
|
return(undef, 'Unable to parse JSON stream');
|
||||||
}
|
}
|
||||||
|
|
||||||
=head2 Remind::PDF::Multi->create_from_stream($json, $specials_accepted)
|
=head2 Remind::PDF::Multi->create_from_json($json, $specials_accepted)
|
||||||
|
|
||||||
This method takes data from a JSON string <$json>. C<$specials_accepted>
|
This method takes data from a JSON string <$json>. C<$specials_accepted>
|
||||||
is a hashref of SPECIAL reminder types to accept; the key is the name of the
|
is a hashref of SPECIAL reminder types to accept; the key is the name of the
|
||||||
|
|||||||
@@ -240,6 +240,9 @@ set Option(PrintOrient) landscape
|
|||||||
set OptDescr(PrintFill) "(0/1) If 1, fill entire page when printing"
|
set OptDescr(PrintFill) "(0/1) If 1, fill entire page when printing"
|
||||||
set Option(PrintFill) 1
|
set Option(PrintFill) 1
|
||||||
|
|
||||||
|
set OptDescr(WrapCal) "(0/1) If 1, make printed calendars occupy at most 5 rows"
|
||||||
|
set Option(WrapCal) 0
|
||||||
|
|
||||||
set OptDescr(PrintDaysRight) "(0/1) If 1, put day numbers in the top-right of each calendar box"
|
set OptDescr(PrintDaysRight) "(0/1) If 1, put day numbers in the top-right of each calendar box"
|
||||||
set Option(PrintDaysRight) 1
|
set Option(PrintDaysRight) 1
|
||||||
|
|
||||||
@@ -1290,6 +1293,7 @@ proc DoPrint {} {
|
|||||||
radiobutton .p.portrait -text "Portrait" -variable Option(PrintOrient) -value portrait
|
radiobutton .p.portrait -text "Portrait" -variable Option(PrintOrient) -value portrait
|
||||||
|
|
||||||
checkbutton .p.fill -text "Fill page" -variable Option(PrintFill)
|
checkbutton .p.fill -text "Fill page" -variable Option(PrintFill)
|
||||||
|
checkbutton .p.wrap -text "Use at most 5 rows (PDF only)" -variable Option(WrapCal)
|
||||||
checkbutton .p.right -text "Day numbers at top-right" -variable Option(PrintDaysRight)
|
checkbutton .p.right -text "Day numbers at top-right" -variable Option(PrintDaysRight)
|
||||||
checkbutton .p.encoding -text "ISO 8859-1 PostScript encoding" -variable Option(PrintEncoding)
|
checkbutton .p.encoding -text "ISO 8859-1 PostScript encoding" -variable Option(PrintEncoding)
|
||||||
checkbutton .p.calendars -text "Print small calendars" -variable Option(PrintSmallCalendars)
|
checkbutton .p.calendars -text "Print small calendars" -variable Option(PrintSmallCalendars)
|
||||||
@@ -1300,12 +1304,14 @@ proc DoPrint {} {
|
|||||||
if {$HaveRem2PDF} {
|
if {$HaveRem2PDF} {
|
||||||
pack .p.f1 .p.ff .p.f2 .p.f2a .p.f3 .p.f3a \
|
pack .p.f1 .p.ff .p.f2 .p.f2a .p.f3 .p.f3a \
|
||||||
-side top -fill both -expand 1 -anchor w
|
-side top -fill both -expand 1 -anchor w
|
||||||
|
pack .p.fill .p.wrap .p.right .p.encoding .p.calendars -in .p.f3a \
|
||||||
|
-side top -anchor w -fill none -expand 0
|
||||||
} else {
|
} else {
|
||||||
pack .p.f1 .p.f2 .p.f2a .p.f3 .p.f3a \
|
pack .p.f1 .p.f2 .p.f2a .p.f3 .p.f3a \
|
||||||
-side top -fill both -expand 1 -anchor w
|
-side top -fill both -expand 1 -anchor w
|
||||||
}
|
pack .p.fill .p.right .p.encoding .p.calendars -in .p.f3a \
|
||||||
pack .p.fill .p.right .p.encoding .p.calendars -in .p.f3a \
|
|
||||||
-side top -anchor w -fill none -expand 0
|
-side top -anchor w -fill none -expand 0
|
||||||
|
}
|
||||||
pack .p.f4 -side top -fill both -expand 1 -anchor w
|
pack .p.f4 -side top -fill both -expand 1 -anchor w
|
||||||
pack .p.f11 .p.f12 -in .p.f1 -side top -fill none -expand 0 -anchor w
|
pack .p.f11 .p.f12 -in .p.f1 -side top -fill none -expand 0 -anchor w
|
||||||
pack .p.tofile .p.filename .p.browse -in .p.f11 -side left -fill none -expand 0 -anchor w
|
pack .p.tofile .p.filename .p.browse -in .p.f11 -side left -fill none -expand 0 -anchor w
|
||||||
@@ -1398,6 +1404,11 @@ proc DoPrint {} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if {$Option(WrapCal)} {
|
||||||
|
if {$Option(PrintFormat) == "pdf"} {
|
||||||
|
append cmd " --wrap"
|
||||||
|
}
|
||||||
|
}
|
||||||
if {$Option(PrintOrient) == "landscape"} {
|
if {$Option(PrintOrient) == "landscape"} {
|
||||||
append cmd " -l"
|
append cmd " -l"
|
||||||
}
|
}
|
||||||
@@ -3326,7 +3337,9 @@ proc EditableEnter { w } {
|
|||||||
set c [$w tag cget $ctag -foreground]
|
set c [$w tag cget $ctag -foreground]
|
||||||
}
|
}
|
||||||
if {"$c" != ""} {
|
if {"$c" != ""} {
|
||||||
$w tag configure $tag -underline 1 -underlinefg $c
|
$w tag configure $tag -underline 1
|
||||||
|
# underlinefg not supported on older versions of Tk
|
||||||
|
eval { $w tag configure $tag -underlinefg $c }
|
||||||
} else {
|
} else {
|
||||||
$w tag configure $tag -underline 1
|
$w tag configure $tag -underline 1
|
||||||
}
|
}
|
||||||
@@ -3633,7 +3646,9 @@ proc DoShadeSpecial { n r g b } {
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
proc DoMoonSpecial { n stuff fntag day } {
|
proc DoMoonSpecial { n stuff fntag day } {
|
||||||
set msg ""
|
set msg ""
|
||||||
set num [scan $stuff "%d %d %d %s" phase junk1 junk2 msg]
|
# Yes, this is gross, but the odds of ctrl-A appearing
|
||||||
|
# in the text associated with a MOON are small.
|
||||||
|
set num [scan $stuff {%d %d %d %[^]} phase junk1 junk2 msg]
|
||||||
if {$num < 1} {
|
if {$num < 1} {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1830,6 +1830,10 @@ static int DoCalRem(ParsePtr p, int col)
|
|||||||
DBufFree(&buf);
|
DBufFree(&buf);
|
||||||
}
|
}
|
||||||
trig.typ = tok.val;
|
trig.typ = tok.val;
|
||||||
|
|
||||||
|
/* Convert some SPECIALs back to plain types */
|
||||||
|
FixSpecialType(&trig);
|
||||||
|
|
||||||
if (trig.typ == MSG_TYPE ||
|
if (trig.typ == MSG_TYPE ||
|
||||||
trig.typ == CAL_TYPE ||
|
trig.typ == CAL_TYPE ||
|
||||||
trig.typ == MSF_TYPE) {
|
trig.typ == MSF_TYPE) {
|
||||||
|
|||||||
56
src/dorem.c
56
src/dorem.c
@@ -123,8 +123,12 @@ int DoRem(ParsePtr p)
|
|||||||
}
|
}
|
||||||
StrnCpy(trig.passthru, DBufValue(&buf), PASSTHRU_LEN);
|
StrnCpy(trig.passthru, DBufValue(&buf), PASSTHRU_LEN);
|
||||||
DBufFree(&buf);
|
DBufFree(&buf);
|
||||||
}
|
}
|
||||||
trig.typ = tok.val;
|
trig.typ = tok.val;
|
||||||
|
|
||||||
|
/* Convert some SPECIALs back to plain types */
|
||||||
|
FixSpecialType(&trig);
|
||||||
|
|
||||||
dse = LastTriggerDate;
|
dse = LastTriggerDate;
|
||||||
if (!LastTrigValid || PurgeMode) {
|
if (!LastTrigValid || PurgeMode) {
|
||||||
FreeTrig(&trig);
|
FreeTrig(&trig);
|
||||||
@@ -188,7 +192,7 @@ int DoRem(ParsePtr p)
|
|||||||
|
|
||||||
r = OK;
|
r = OK;
|
||||||
if (ShouldTriggerReminder(&trig, &tim, dse, &err)) {
|
if (ShouldTriggerReminder(&trig, &tim, dse, &err)) {
|
||||||
if ( (r=TriggerReminder(p, &trig, &tim, dse)) ) {
|
if ( (r=TriggerReminder(p, &trig, &tim, dse, 0)) ) {
|
||||||
FreeTrig(&trig);
|
FreeTrig(&trig);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -370,6 +374,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
|||||||
}
|
}
|
||||||
StrnCpy(trig->passthru, DBufValue(&buf), PASSTHRU_LEN);
|
StrnCpy(trig->passthru, DBufValue(&buf), PASSTHRU_LEN);
|
||||||
}
|
}
|
||||||
|
FixSpecialType(trig);
|
||||||
parsing = 0;
|
parsing = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -893,7 +898,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
|||||||
/* Trigger the reminder if it's a RUN or MSG type. */
|
/* Trigger the reminder if it's a RUN or MSG type. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse)
|
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued)
|
||||||
{
|
{
|
||||||
int r, y, m, d;
|
int r, y, m, d;
|
||||||
char PrioExpr[VAR_NAME_LEN+25];
|
char PrioExpr[VAR_NAME_LEN+25];
|
||||||
@@ -901,8 +906,21 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse)
|
|||||||
DynamicBuffer buf, calRow;
|
DynamicBuffer buf, calRow;
|
||||||
DynamicBuffer pre_buf;
|
DynamicBuffer pre_buf;
|
||||||
char const *s;
|
char const *s;
|
||||||
|
char const *msg_command = NULL;
|
||||||
Value v;
|
Value v;
|
||||||
|
|
||||||
|
if (MsgCommand) {
|
||||||
|
msg_command = MsgCommand;
|
||||||
|
}
|
||||||
|
if (is_queued && QueuedMsgCommand) {
|
||||||
|
msg_command = QueuedMsgCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A null command is no command */
|
||||||
|
if (msg_command && !*msg_command) {
|
||||||
|
msg_command = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int red = -1, green = -1, blue = -1;
|
int red = -1, green = -1, blue = -1;
|
||||||
int is_color = 0;
|
int is_color = 0;
|
||||||
|
|
||||||
@@ -947,7 +965,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse)
|
|||||||
}
|
}
|
||||||
/* If it's a MSG-type reminder, and no -k option was used, issue the banner. */
|
/* If it's a MSG-type reminder, and no -k option was used, issue the banner. */
|
||||||
if ((t->typ == MSG_TYPE || t->typ == MSF_TYPE)
|
if ((t->typ == MSG_TYPE || t->typ == MSF_TYPE)
|
||||||
&& !DidMsgReminder && !NextMode && !MsgCommand) {
|
&& !DidMsgReminder && !NextMode && !msg_command) {
|
||||||
DidMsgReminder = 1;
|
DidMsgReminder = 1;
|
||||||
if (!DoSubstFromString(DBufValue(&Banner), &buf,
|
if (!DoSubstFromString(DBufValue(&Banner), &buf,
|
||||||
DSEToday, NO_TIME) &&
|
DSEToday, NO_TIME) &&
|
||||||
@@ -1091,7 +1109,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse)
|
|||||||
DBufPuts(&buf, Decolorize());
|
DBufPuts(&buf, Decolorize());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!MsgCommand && t->typ == MSG_TYPE) || t->typ == MSF_TYPE) {
|
if ((!msg_command && t->typ == MSG_TYPE) || t->typ == MSF_TYPE) {
|
||||||
if (DBufPutc(&buf, '\n') != OK) {
|
if (DBufPutc(&buf, '\n') != OK) {
|
||||||
DBufFree(&buf);
|
DBufFree(&buf);
|
||||||
return E_NO_MEM;
|
return E_NO_MEM;
|
||||||
@@ -1113,8 +1131,8 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse)
|
|||||||
switch(t->typ) {
|
switch(t->typ) {
|
||||||
case MSG_TYPE:
|
case MSG_TYPE:
|
||||||
case PASSTHRU_TYPE:
|
case PASSTHRU_TYPE:
|
||||||
if (MsgCommand) {
|
if (msg_command) {
|
||||||
DoMsgCommand(MsgCommand, DBufValue(&buf));
|
DoMsgCommand(msg_command, DBufValue(&buf));
|
||||||
} else {
|
} else {
|
||||||
printf("%s", DBufValue(&buf));
|
printf("%s", DBufValue(&buf));
|
||||||
}
|
}
|
||||||
@@ -1466,3 +1484,25 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FixSpecialType(Trigger *t)
|
||||||
|
{
|
||||||
|
if (t->typ != PASSTHRU_TYPE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert SPECIAL MSG / MSF / RUN / CAL to just plain MSG / MSF / etc */
|
||||||
|
if (!StrCmpi(t->passthru, "MSG")) {
|
||||||
|
t->typ = MSG_TYPE;
|
||||||
|
} else if (!StrCmpi(t->passthru, "MSF")) {
|
||||||
|
t->typ = MSF_TYPE;
|
||||||
|
} else if (!StrCmpi(t->passthru, "RUN")) {
|
||||||
|
t->typ = RUN_TYPE;
|
||||||
|
} else if (!StrCmpi(t->passthru, "CAL")) {
|
||||||
|
t->typ = CAL_TYPE;
|
||||||
|
} else if (!StrCmpi(t->passthru, "PS")) {
|
||||||
|
t->typ = PS_TYPE;
|
||||||
|
} else if (!StrCmpi(t->passthru, "PSFILE")) {
|
||||||
|
t->typ = PSF_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
|||||||
mode != CAL_MODE &&
|
mode != CAL_MODE &&
|
||||||
mode != ADVANCE_MODE &&
|
mode != ADVANCE_MODE &&
|
||||||
t->typ != RUN_TYPE &&
|
t->typ != RUN_TYPE &&
|
||||||
!MsgCommand) {
|
!(MsgCommand && *MsgCommand)) {
|
||||||
if (DBufPutc(dbuf, '\n') != OK) return E_NO_MEM;
|
if (DBufPutc(dbuf, '\n') != OK) return E_NO_MEM;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -794,7 +794,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case '_':
|
case '_':
|
||||||
if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || (mode != CAL_MODE && mode != ADVANCE_MODE && !MsgCommand)) {
|
if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || (mode != CAL_MODE && mode != ADVANCE_MODE && !(MsgCommand && *MsgCommand))) {
|
||||||
snprintf(s, sizeof(s), "%s", NL);
|
snprintf(s, sizeof(s), "%s", NL);
|
||||||
} else {
|
} else {
|
||||||
snprintf(s, sizeof(s), " ");
|
snprintf(s, sizeof(s), " ");
|
||||||
|
|||||||
115
src/funcs.c
115
src/funcs.c
@@ -101,6 +101,8 @@ static int FHebday (func_info *);
|
|||||||
static int FHebmon (func_info *);
|
static int FHebmon (func_info *);
|
||||||
static int FHebyear (func_info *);
|
static int FHebyear (func_info *);
|
||||||
static int FHour (func_info *);
|
static int FHour (func_info *);
|
||||||
|
static int FHtmlEscape (func_info *);
|
||||||
|
static int FHtmlStriptags (func_info *);
|
||||||
static int FIif (func_info *);
|
static int FIif (func_info *);
|
||||||
static int FIndex (func_info *);
|
static int FIndex (func_info *);
|
||||||
static int FIsdst (func_info *);
|
static int FIsdst (func_info *);
|
||||||
@@ -265,6 +267,8 @@ BuiltinFunc Func[] = {
|
|||||||
{ "hebmon", 1, 1, 0, FHebmon },
|
{ "hebmon", 1, 1, 0, FHebmon },
|
||||||
{ "hebyear", 1, 1, 0, FHebyear },
|
{ "hebyear", 1, 1, 0, FHebyear },
|
||||||
{ "hour", 1, 1, 1, FHour },
|
{ "hour", 1, 1, 1, FHour },
|
||||||
|
{ "htmlescape", 1, 1, 1, FHtmlEscape },
|
||||||
|
{ "htmlstriptags",1, 1, 1, FHtmlStriptags },
|
||||||
{ "iif", 1, NO_MAX, 1, FIif },
|
{ "iif", 1, NO_MAX, 1, FIif },
|
||||||
{ "index", 2, 3, 1, FIndex },
|
{ "index", 2, 3, 1, FIndex },
|
||||||
{ "isany", 1, NO_MAX, 1, FIsAny },
|
{ "isany", 1, NO_MAX, 1, FIsAny },
|
||||||
@@ -914,9 +918,14 @@ static int FAbs(func_info *info)
|
|||||||
|
|
||||||
ASSERT_TYPE(0, INT_TYPE);
|
ASSERT_TYPE(0, INT_TYPE);
|
||||||
v = ARGV(0);
|
v = ARGV(0);
|
||||||
|
if (v == INT_MIN) return E_2HIGH;
|
||||||
|
|
||||||
RetVal.type = INT_TYPE;
|
RetVal.type = INT_TYPE;
|
||||||
RETVAL = (v < 0) ? (-v) : v;
|
RETVAL = (v < 0) ? (-v) : v;
|
||||||
v = RETVAL;
|
v = RETVAL;
|
||||||
|
|
||||||
|
/* The following test is probably redundant given the test
|
||||||
|
for v == INT_MIN above, but I'll leave it in just in case. */
|
||||||
if (v < 0) return E_2HIGH;
|
if (v < 0) return E_2HIGH;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -1162,15 +1171,27 @@ static int FPad(func_info *info)
|
|||||||
if (Nargs < 4 || !ARGV(3)) {
|
if (Nargs < 4 || !ARGV(3)) {
|
||||||
/* Pad on the LEFT */
|
/* Pad on the LEFT */
|
||||||
for (i=0; i<wantlen-len; i++) {
|
for (i=0; i<wantlen-len; i++) {
|
||||||
DBufPutc(&dbuf, *s++);
|
if (DBufPutc(&dbuf, *s++) != OK) {
|
||||||
|
DBufFree(&dbuf);
|
||||||
|
return E_NO_MEM;
|
||||||
|
}
|
||||||
if (!*s) s = ARGSTR(1);
|
if (!*s) s = ARGSTR(1);
|
||||||
}
|
}
|
||||||
DBufPuts(&dbuf, ARGSTR(0));
|
if (DBufPuts(&dbuf, ARGSTR(0)) != OK) {
|
||||||
|
DBufFree(&dbuf);
|
||||||
|
return E_NO_MEM;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Pad on the RIGHT */
|
/* Pad on the RIGHT */
|
||||||
DBufPuts(&dbuf, ARGSTR(0));
|
if (DBufPuts(&dbuf, ARGSTR(0)) != OK) {
|
||||||
|
DBufFree(&dbuf);
|
||||||
|
return E_NO_MEM;
|
||||||
|
}
|
||||||
for (i=0; i<wantlen-len; i++) {
|
for (i=0; i<wantlen-len; i++) {
|
||||||
DBufPutc(&dbuf, *s++);
|
if (DBufPutc(&dbuf, *s++) != OK) {
|
||||||
|
DBufFree(&dbuf);
|
||||||
|
return E_NO_MEM;
|
||||||
|
}
|
||||||
if (!*s) s = ARGSTR(1);
|
if (!*s) s = ARGSTR(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2243,6 +2264,92 @@ static int FHebyear(func_info *info)
|
|||||||
RETVAL = y;
|
RETVAL = y;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* htmlescape - replace <. > and & by < > and & */
|
||||||
|
/* */
|
||||||
|
/****************************************************************/
|
||||||
|
static int FHtmlEscape(func_info *info)
|
||||||
|
{
|
||||||
|
DynamicBuffer dbuf;
|
||||||
|
char const *s;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
ASSERT_TYPE(0, STR_TYPE);
|
||||||
|
|
||||||
|
DBufInit(&dbuf);
|
||||||
|
|
||||||
|
s = ARGSTR(0);
|
||||||
|
while(*s) {
|
||||||
|
switch(*s) {
|
||||||
|
case '<':
|
||||||
|
r = DBufPuts(&dbuf, "<");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '>':
|
||||||
|
r = DBufPuts(&dbuf, ">");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '&':
|
||||||
|
r = DBufPuts(&dbuf, "&");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
r = DBufPutc(&dbuf, *s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (r != OK) {
|
||||||
|
DBufFree(&dbuf);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
r = RetStrVal(DBufValue(&dbuf), info);
|
||||||
|
DBufFree(&dbuf);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* htmlstriptags - strip out HTML tags from a string */
|
||||||
|
/* */
|
||||||
|
/****************************************************************/
|
||||||
|
static int FHtmlStriptags(func_info *info)
|
||||||
|
{
|
||||||
|
DynamicBuffer dbuf;
|
||||||
|
char const *s;
|
||||||
|
int r = OK;
|
||||||
|
|
||||||
|
int in_tag = 0;
|
||||||
|
ASSERT_TYPE(0, STR_TYPE);
|
||||||
|
|
||||||
|
DBufInit(&dbuf);
|
||||||
|
|
||||||
|
s = ARGSTR(0);
|
||||||
|
while(*s) {
|
||||||
|
if (!in_tag) {
|
||||||
|
if (*s == '<') {
|
||||||
|
in_tag = 1;
|
||||||
|
} else {
|
||||||
|
r = DBufPutc(&dbuf, *s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (*s == '>') {
|
||||||
|
in_tag = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (r != OK) {
|
||||||
|
DBufFree(&dbuf);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
r = RetStrVal(DBufValue(&dbuf), info);
|
||||||
|
DBufFree(&dbuf);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************/
|
/****************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* FEasterdate - calc. easter Sunday from a year. */
|
/* FEasterdate - calc. easter Sunday from a year. */
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ EXTERN uid_t TrustedUsers[MAX_TRUSTED_USERS];
|
|||||||
|
|
||||||
EXTERN INIT( int NumTrustedUsers, 0);
|
EXTERN INIT( int NumTrustedUsers, 0);
|
||||||
EXTERN INIT( char const *MsgCommand, NULL);
|
EXTERN INIT( char const *MsgCommand, NULL);
|
||||||
|
EXTERN INIT( char const *QueuedMsgCommand, NULL);
|
||||||
EXTERN INIT( int ShowAllErrors, 0);
|
EXTERN INIT( int ShowAllErrors, 0);
|
||||||
EXTERN INIT( int DebugFlag, 0);
|
EXTERN INIT( int DebugFlag, 0);
|
||||||
EXTERN INIT( int DoCalendar, 0);
|
EXTERN INIT( int DoCalendar, 0);
|
||||||
|
|||||||
@@ -600,7 +600,12 @@ void InitRemind(int argc, char const *argv[])
|
|||||||
|
|
||||||
case 'k':
|
case 'k':
|
||||||
case 'K':
|
case 'K':
|
||||||
MsgCommand = arg;
|
if (*arg == ':') {
|
||||||
|
arg++;
|
||||||
|
QueuedMsgCommand = arg;
|
||||||
|
} else {
|
||||||
|
MsgCommand = arg;
|
||||||
|
}
|
||||||
while (*arg) arg++; /* Chew up remaining chars in this arg */
|
while (*arg) arg++; /* Chew up remaining chars in this arg */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ int DoRem (ParsePtr p);
|
|||||||
int DoFlush (ParsePtr p);
|
int DoFlush (ParsePtr p);
|
||||||
void DoExit (ParsePtr p);
|
void DoExit (ParsePtr p);
|
||||||
int ParseRem (ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals);
|
int ParseRem (ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals);
|
||||||
int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int dse);
|
int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued);
|
||||||
int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int dse, int *err);
|
int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int dse, int *err);
|
||||||
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode);
|
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode);
|
||||||
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int dse, int tim);
|
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int dse, int tim);
|
||||||
@@ -177,6 +177,7 @@ int push_call(char const *filename, char const *func, int lineno);
|
|||||||
void clear_callstack(void);
|
void clear_callstack(void);
|
||||||
int print_callstack(FILE *fp);
|
int print_callstack(FILE *fp);
|
||||||
void pop_call(void);
|
void pop_call(void);
|
||||||
|
void FixSpecialType(Trigger *trig);
|
||||||
#ifdef REM_USE_WCHAR
|
#ifdef REM_USE_WCHAR
|
||||||
#define _XOPEN_SOURCE 600
|
#define _XOPEN_SOURCE 600
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ void HandleQueuedReminders(void)
|
|||||||
/* Set up global variables so some functions like trigdate()
|
/* Set up global variables so some functions like trigdate()
|
||||||
and trigtime() work correctly */
|
and trigtime() work correctly */
|
||||||
SaveAllTriggerInfo(&(q->t), &(q->tt), DSEToday, q->tt.ttime, 1);
|
SaveAllTriggerInfo(&(q->t), &(q->tt), DSEToday, q->tt.ttime, 1);
|
||||||
(void) TriggerReminder(&p, &trig, &q->tt, DSEToday);
|
(void) TriggerReminder(&p, &trig, &q->tt, DSEToday, 1);
|
||||||
if (Daemon < 0) {
|
if (Daemon < 0) {
|
||||||
printf("NOTE endreminder\n");
|
printf("NOTE endreminder\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ void IssueSortedReminders(void)
|
|||||||
next = cur->next;
|
next = cur->next;
|
||||||
switch(cur->typ) {
|
switch(cur->typ) {
|
||||||
case MSG_TYPE:
|
case MSG_TYPE:
|
||||||
if (MsgCommand) {
|
if (MsgCommand && *MsgCommand) {
|
||||||
DoMsgCommand(MsgCommand, cur->text);
|
DoMsgCommand(MsgCommand, cur->text);
|
||||||
} else {
|
} else {
|
||||||
if (cur->trigdate != olddate) {
|
if (cur->trigdate != olddate) {
|
||||||
|
|||||||
@@ -124,7 +124,11 @@ int DoFset(ParsePtr p)
|
|||||||
DBufFree(&buf);
|
DBufFree(&buf);
|
||||||
return E_NO_MEM;
|
return E_NO_MEM;
|
||||||
}
|
}
|
||||||
func->filename = StrDup(FileName);
|
if (FileName) {
|
||||||
|
func->filename = StrDup(FileName);
|
||||||
|
} else {
|
||||||
|
func->filename = StrDup("[cmdline]");
|
||||||
|
}
|
||||||
if (!func->filename) {
|
if (!func->filename) {
|
||||||
free(func);
|
free(func);
|
||||||
return E_NO_MEM;
|
return E_NO_MEM;
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ if test `id -u` = 0 ; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Set a known timezone so moon phases show up in predictable places
|
||||||
|
TZ=UTC
|
||||||
|
export TZ
|
||||||
|
|
||||||
# If we're already in a utf-8 locale, do
|
# If we're already in a utf-8 locale, do
|
||||||
# nothing; otherwise, set LC_ALL
|
# nothing; otherwise, set LC_ALL
|
||||||
OK=0
|
OK=0
|
||||||
@@ -418,6 +422,9 @@ chmod 0777 include_dir/ww
|
|||||||
../src/remind include_dir/ww >> ../tests/test.out 2>&1
|
../src/remind include_dir/ww >> ../tests/test.out 2>&1
|
||||||
rm -rf include_dir/ww
|
rm -rf include_dir/ww
|
||||||
|
|
||||||
|
# This segfaulted in 04.02.03
|
||||||
|
../src/remind -h '-imsgprefix(x)="foo"' /dev/null >> ../tests/test.out 2>&1
|
||||||
|
|
||||||
# Remove references to SysInclude, which is build-specific
|
# Remove references to SysInclude, which is build-specific
|
||||||
grep -F -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out
|
grep -F -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out
|
||||||
cmp -s ../tests/test.out ../tests/test.cmp
|
cmp -s ../tests/test.out ../tests/test.cmp
|
||||||
@@ -428,7 +435,11 @@ else
|
|||||||
echo "Remind: Acceptance test FAILED"
|
echo "Remind: Acceptance test FAILED"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Examine the file test.out to see where it differs from the"
|
echo "Examine the file test.out to see where it differs from the"
|
||||||
echo "reference file test.cmp."
|
echo "reference file test.cmp. Here are the first 200 lines of"
|
||||||
|
echo "diff -u test.out test.cmp"
|
||||||
|
echo ""
|
||||||
|
diff -u ../tests/test.out ../tests/test.cmp | head -n 200
|
||||||
|
echo ""
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1060,7 +1060,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() => "04.02.02"
|
version() => "04.02.04"
|
||||||
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"
|
||||||
@@ -2644,7 +2644,7 @@ a086 4
|
|||||||
a109 2012-01-01
|
a109 2012-01-01
|
||||||
a128 2018-02-03@16:45
|
a128 2018-02-03@16:45
|
||||||
a039 "February"
|
a039 "February"
|
||||||
a058 "04.02.02"
|
a058 "04.02.04"
|
||||||
a077 "1992 92\n"
|
a077 "1992 92\n"
|
||||||
a096 -4
|
a096 -4
|
||||||
a119 -1
|
a119 -1
|
||||||
@@ -4786,6 +4786,41 @@ FUNSET circle square rectangle
|
|||||||
SET a square(5)
|
SET a square(5)
|
||||||
../tests/test.rem(867): Undefined function: `square'
|
../tests/test.rem(867): Undefined function: `square'
|
||||||
|
|
||||||
|
# htmlescape
|
||||||
|
set a htmlescape("foo")
|
||||||
|
htmlescape("foo") => "foo"
|
||||||
|
REM MSG [a]
|
||||||
|
../tests/test.rem(871): Trig = Saturday, 16 February, 1991
|
||||||
|
a => "foo"
|
||||||
|
foo
|
||||||
|
|
||||||
|
set a htmlescape("<&>")
|
||||||
|
htmlescape("<&>") => "<&>"
|
||||||
|
REM MSG [a]
|
||||||
|
../tests/test.rem(873): Trig = Saturday, 16 February, 1991
|
||||||
|
a => "<&>"
|
||||||
|
<&>
|
||||||
|
|
||||||
|
set a htmlescape("@&^#*@&^##$*&@><><@#@#><@#>%%_#$foobarquux")
|
||||||
|
htmlescape("@&^#*@&^##$*&@><><@#@#><@#>%%_#$foobarqu"...) => "@&^#*@&^##$*&@><>&l"...
|
||||||
|
REM MSG [a]
|
||||||
|
../tests/test.rem(875): Trig = Saturday, 16 February, 1991
|
||||||
|
a => "@&^#*@&^##$*&@><>&l"...
|
||||||
|
@&^#*@&^##$*&@><><@#@#><@#>%_#$foobarquux
|
||||||
|
|
||||||
|
|
||||||
|
# htmlstriptags
|
||||||
|
set a htmlstriptags("foobar")
|
||||||
|
htmlstriptags("foobar") => "foobar"
|
||||||
|
set a htmlstriptags("This is <b>bold</b>")
|
||||||
|
htmlstriptags("This is <b>bold</b>") => "This is bold"
|
||||||
|
set a htmlstriptags("This is <unclosed whut?")
|
||||||
|
htmlstriptags("This is <unclosed whut?") => "This is "
|
||||||
|
set a htmlstriptags("this is > whut <b>foo</b>")
|
||||||
|
htmlstriptags("this is > whut <b>foo</b>") => "this is > whut foo"
|
||||||
|
set a htmlstriptags("<img src=\"foo\">")
|
||||||
|
htmlstriptags("<img src=\"foo\">") => ""
|
||||||
|
|
||||||
# Don't want Remind to queue reminders
|
# Don't want Remind to queue reminders
|
||||||
EXIT
|
EXIT
|
||||||
|
|
||||||
|
|||||||
@@ -866,6 +866,21 @@ FUNSET circle square rectangle
|
|||||||
# Should fail
|
# Should fail
|
||||||
SET a square(5)
|
SET a square(5)
|
||||||
|
|
||||||
|
# htmlescape
|
||||||
|
set a htmlescape("foo")
|
||||||
|
REM MSG [a]
|
||||||
|
set a htmlescape("<&>")
|
||||||
|
REM MSG [a]
|
||||||
|
set a htmlescape("@&^#*@&^##$*&@><><@#@#><@#>%%_#$foobarquux")
|
||||||
|
REM MSG [a]
|
||||||
|
|
||||||
|
# htmlstriptags
|
||||||
|
set a htmlstriptags("foobar")
|
||||||
|
set a htmlstriptags("This is <b>bold</b>")
|
||||||
|
set a htmlstriptags("This is <unclosed whut?")
|
||||||
|
set a htmlstriptags("this is > whut <b>foo</b>")
|
||||||
|
set a htmlstriptags("<img src=\"foo\">")
|
||||||
|
|
||||||
# Don't want Remind to queue reminders
|
# Don't want Remind to queue reminders
|
||||||
EXIT
|
EXIT
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user