Compare commits

..

32 Commits

Author SHA1 Message Date
Dianne Skoll
b86245c4c6 Fix wording. 2024-03-25 10:24:39 -04:00
Dianne Skoll
499fcfad41 Fix typo 2024-03-25 10:24:20 -04:00
Dianne Skoll
bddbbf061b Update changelog. 2024-03-25 10:21:05 -04:00
Dianne Skoll
05136f4cf0 Add a basic CSS file for the demo WWW stuff. 2024-03-25 10:12:46 -04:00
Dianne Skoll
e62e3d5d03 More multitrig examples. 2024-03-24 11:05:15 -04:00
Dianne Skoll
595fdaa4a4 Increment version to 04.03.04. 2024-03-24 10:54:44 -04:00
Dianne Skoll
133febc2c1 Document that you can't have an AT clause in a multitrig trigger. 2024-03-24 10:50:21 -04:00
Dianne Skoll
f8c6d7ff6c Document multitrig. 2024-03-24 10:46:53 -04:00
Dianne Skoll
db3341db91 Fix bug in code that stripes the Queue... output grey and white. 2024-03-23 10:57:56 -04:00
Dianne Skoll
8cbcd3ec01 Show Hebrew dates on PDF version of Jewish holiday calendar. 2024-03-22 17:38:30 -04:00
Dianne Skoll
4c6512e9b6 Update the HTML remind demo. 2024-03-22 17:26:23 -04:00
Dianne Skoll
4769789a8f More common HTML path. 2024-03-22 17:14:13 -04:00
Dianne Skoll
b4a8cb085c Add "blank PDF calendar" to www choices. 2024-03-22 17:13:21 -04:00
Dianne Skoll
4f816d52fd Another test for multitrig / scanfrom interaction. 2024-03-22 12:40:50 -04:00
Dianne Skoll
94b3a0248d Add tests for multitrig 2024-03-22 12:39:58 -04:00
Dianne Skoll
5fbf1d82e4 Remove duplicated line. 2024-03-22 11:23:04 -04:00
Dianne Skoll
55eb3ebe95 Add multitrig built-in function which is how trig() should originally have been done. 2024-03-22 11:21:26 -04:00
Dianne Skoll
2afa3c5558 Raise windows after errors so they remain visible. 2024-03-21 16:08:18 -04:00
Dianne Skoll
30d9a42db2 Remove debugging statement. 2024-03-21 12:39:48 -04:00
Dianne Skoll
74d357b84d Use placeholders that are less likely to be used as filenames. :) 2024-03-21 12:22:43 -04:00
Dianne Skoll
09c98a93ec Fix month navigation. 2024-03-21 12:19:39 -04:00
Dianne Skoll
ed89ab7c04 Remove unnecessary code and variable. 2024-03-21 12:13:32 -04:00
Dianne Skoll
27c74be02b Don't need to monitor reminder file for changes; reap zombies. 2024-03-21 12:11:39 -04:00
Dianne Skoll
8f22ab39dc Apply POSIX-escaping to filenames. 2024-03-21 11:46:29 -04:00
Dianne Skoll
795c53f4ce Format queue items better; make them clickable to open an editor. 2024-03-21 11:02:07 -04:00
Dianne Skoll
3fd18a9cc0 Document clickable errors. 2024-03-21 10:45:32 -04:00
Dianne Skoll
a5afb4a87e In the "show errors" text box, fire up the editor when you click on an error if we can figure out the filename and line number. 2024-03-20 20:53:19 -04:00
Dianne Skoll
379fc4542d Make errors stand out more obviously. 2024-03-20 20:33:46 -04:00
Dianne Skoll
538ef6c8ce Check for both $CalMode and $PsCal 2024-03-20 16:32:02 -04:00
Dianne Skoll
95c7e8856c Add standard "moonphases.rem" file with moon phases. 2024-03-20 16:28:50 -04:00
Dianne Skoll
95523c8f10 Convert cosd() function into a macro. 2024-03-19 16:26:07 -04:00
Dianne Skoll
97b53d5e40 Fix typo 2024-03-18 11:18:46 -04:00
21 changed files with 464 additions and 156 deletions

2
configure vendored
View File

@@ -4225,7 +4225,7 @@ then :
fi fi
VERSION=04.03.03 VERSION=04.03.04

View File

@@ -88,7 +88,7 @@ if test "$?" != 0 ; then
fi fi
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups inotify_init1) AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups inotify_init1)
VERSION=04.03.03 VERSION=04.03.04
AC_SUBST(VERSION) AC_SUBST(VERSION)
AC_SUBST(PERL) AC_SUBST(PERL)
AC_SUBST(PERLARTIFACTS) AC_SUBST(PERLARTIFACTS)

View File

@@ -1,5 +1,33 @@
CHANGES TO REMIND CHANGES TO REMIND
* VERSION 4.3 Patch 4 - 2024-03-25
* NEW FEATURE: remind: Add the new "multitrig" function, which is how "trig"
should have worked in the first place. See man page for details.
* IMPROVEMENT: tkremind: Make errors in your reminders file stand out more
prominently.
* IMPROVEMENT: tkremind: If you click on an error in the "Errors..." popup,
tkremind will open a text editor on the offending file and line.
* IMPROVEMENT: tkremind: Format the "Queue..." output better and make queue
items clickable; clicking on a queue item opens a text editor on the
corresponding file and line.
* IMPROVEMENT: Add a standard [$SysInclude]/moonphases.rem file to display
moon phases on your calendar.
* IMPROVEMENT: Clean up the demo code in www/ and add PDF output.
* BUG FIX: tkremind: Correctly handle filenames containing spaces and other
characters that tend to confuse the shell.
* BUG FIX: tkremind: Raise dialog boxes after errors so that they
remain visible.
* CLEANUP: tkremind: Remove some dead code.
* VERSION 4.3 Patch 3 - 2024-03-18 * VERSION 4.3 Patch 3 - 2024-03-18
* IMPROVEMENT: tkremind: Update icon to include a white border so it shows * IMPROVEMENT: tkremind: Update icon to include a white border so it shows
@@ -14,7 +42,7 @@ CHANGES TO REMIND
* MINOR NEW FEATURE: Add a "-ds" debugging flag to print out expression-parsing * MINOR NEW FEATURE: Add a "-ds" debugging flag to print out expression-parsing
stack high-water marks on exit. This esoteric feature is of no use to stack high-water marks on exit. This esoteric feature is of no use to
anyone by the Remind author. anyone but the Remind author.
* IMPROVEMENT: tkremind: Stop using the deprecated tk_dialog command in favor * IMPROVEMENT: tkremind: Stop using the deprecated tk_dialog command in favor
of the newer tk_messageBox command. of the newer tk_messageBox command.

14
include/moonphases.rem Normal file
View File

@@ -0,0 +1,14 @@
# Moon phases
# 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)]
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)
ENDIF

View File

@@ -3355,6 +3355,62 @@ which default to \fBtoday()\fR and midnight, respectively. The returned
value is an integer from 0 to 359, representing the phase of the moon value is an integer from 0 to 359, representing the phase of the moon
in degrees. 0 is a new moon, 180 is a full moon, 90 is first-quarter, etc. in degrees. 0 is a new moon, 180 is a full moon, 90 is first-quarter, etc.
.TP .TP
.B multitrig(s_trig1 [,s_trig2, [... s_trigN]])
\fBmultitrig\fR evaluates each string as a trigger, similar to \fBevaltrig\fR,
and returns the \fIearliest\fR trigger date that is on or after \fBtoday()\fR.
\fBmultitrig\fR is similar to \fBtrig\fR but has the following difference:
.RS
.PP
\fBtrig\fR returns the \fIfirst\fR trigger date that would have triggered today,
whereas \fBmultitrig\fR returns the \fIearliest\fR trigger date later than
today, regardless of whether it would have triggered today.
.PP
If no trigger can be computed that is later than \fBtoday()\fR, then
\fBmultitrig\fR returns 1990-01-01.
.PP
Consider the following examples, assuming that today is Sunday, 24 March 2024:
.PP
.nf
# Returns 1990-01-01 because neither would trigger today
SET a trig("Mon", "Wed")
# Returns 2024-03-25 because it's the earlier trigger date
SET a multitrig("Mon", "Wed")
# Returns 2024-03-27 because it's the first that would trigger today
SET a trig("Wed +3", "Mon +3")
# Returns 2024-03-25 because it's the earlier trigger date
SET a multitrig("Wed +3", "Mon +3")
# Returns 1990-01-01 because all triggers have expired
SET a multitrig("2000", "2022", "1998", "2023")
.fi
.PP
In general, \fBmultitrig\fR works better with the Remind algorithm than
\fBtrig\fR and should be used most of the time. As an example, this
reminder is issued at the end of each quarter:
.PP
.nf
REM [multitrig("Mar 31", "Jun 30", "Sep 30", "Dec 31")] +7 MSG \\
%"End of [ord($Tm/3)] quarter%" is %b.
.fi
.PP
If you want the last working day of each quarter, you could use:
.PP
.nf
PUSH-OMIT-CONTEXT
OMIT Sat Sun
REM [multitrig("Mar ~1", "Jun ~1", "Sep ~1", "Dec ~1")] +7 MSG \\
%"Last working day of [ord($Tm/3)] quarter%" is %b.
POP-OMIT-CONTEXT
.fi
.PP
Note that unlike \fBevaltrig\fR, \fBmultitrig\fR always returns a \fBDATE\fR
and never a \fBDATETIME\fR. Including an \fBAT\fR clause in a trigger
supplied to \fBmultitrig\fR will result in an error.
.RE
.TP
.B ndawn([dq_date]) .B ndawn([dq_date])
Returns the time of "nautical dawn" on the specified \fIdate\fR. If Returns the time of "nautical dawn" on the specified \fIdate\fR. If
\fIdate\fR is omitted, defaults to \fBtoday()\fR. If a \fIdatetime\fR object \fIdate\fR is omitted, defaults to \fBtoday()\fR. If a \fIdatetime\fR object
@@ -5368,7 +5424,7 @@ as:
.PP .PP
You can define your own substitution sequences in addition to the built-in You can define your own substitution sequences in addition to the built-in
ones as follows: If you define a function named \fBsubst_\fIname\fB(alt, date, time)\fR, then the sequence \fB%{name}\fR calls the function with \fBalt\fR ones as follows: If you define a function named \fBsubst_\fIname\fB(alt, date, time)\fR, then the sequence \fB%{name}\fR calls the function with \fBalt\fR
set to 0 and \fBdate\fR and \fRtime\fR to the trigger date and time, set to 0 and \fBdate\fR and \fBtime\fR to the trigger date and time,
respectively. The \fB%{name}\fR sequence is replaced with whatever the respectively. The \fB%{name}\fR sequence is replaced with whatever the
function returns. The sequence \fB%*{name}\fR is similar, but calls function returns. The sequence \fB%*{name}\fR is similar, but calls
the function with \fBalt\fR set to 1. the function with \fBalt\fR set to 1.

View File

@@ -184,7 +184,9 @@ on the reminder.
If there are any errors in your reminder file, the "Queue..." button If there are any errors in your reminder file, the "Queue..." button
changes to "Errors...". Click on "Errors..." to see the Remind error changes to "Errors...". Click on "Errors..." to see the Remind error
output. Click "OK" to close the error window; this makes the button output. Click "OK" to close the error window; this makes the button
in the main TkRemind window to revert to "Queue..." in the main TkRemind window to revert to "Queue..." You can click on
any error message to open an editor on the file and line number that
caused the error.
.SH BACKGROUND REMINDERS .SH BACKGROUND REMINDERS

View File

@@ -388,7 +388,7 @@ proc extract_syntag { tag } {
#*********************************************************************** #***********************************************************************
proc Initialize {} { proc Initialize {} {
global DayNames argc argv CommandLine ReminderFile AppendFile Remind PSCmd global DayNames argc argv CommandLine ReminderFile AppendFile Remind PSCmd
global MondayFirst TwentyFourHourMode ReminderFileModTime global MondayFirst TwentyFourHourMode
global TodayDay TodayMonth TodayYear global TodayDay TodayMonth TodayYear
global Option ConfigFile global Option ConfigFile
@@ -400,8 +400,8 @@ proc Initialize {} {
set TodayYear [clock format $now -format %Y] set TodayYear [clock format $now -format %Y]
set TodayDay [string trim [clock format $now -format %e]] set TodayDay [string trim [clock format $now -format %e]]
set CommandLine "|$Remind -itkremind=1 -pp -y -l EXTRA" set CommandLine "$Remind -itkremind=1 -pp -y -l @EXTRA@"
set PSCmd "$Remind -itkremind=1 -itkprint=1 -pp -l EXTRA" set PSCmd "$Remind -itkremind=1 -itkprint=1 -pp -l @EXTRA@"
set i 0 set i 0
while {$i < $argc} { while {$i < $argc} {
if {[regexp -- {-[bgxim].*} [lindex $argv $i]]} { if {[regexp -- {-[bgxim].*} [lindex $argv $i]]} {
@@ -473,49 +473,12 @@ proc Initialize {} {
exit 1 exit 1
} }
append CommandLine " $ReminderFile" append CommandLine " "
append PSCmd " $ReminderFile" append CommandLine [posix_escape $ReminderFile]
append PSCmd " "
append PSCmd [posix_escape $ReminderFile]
# Get modification time of ReminderFile set CommandLine "|/bin/sh -c \"$CommandLine @MONTH@ @YEAR@\""
set ReminderFileModTime -1
catch {
set ReminderFileModTime [file mtime $ReminderFile]
}
MonitorReminderFile
# puts "CommandLine: $CommandLine"
}
#---------------------------------------------------------------------------
# MonitorReminderFile
# If Reminder File modtime changes, restart daemon
#---------------------------------------------------------------------------
proc MonitorReminderFile {} {
global ReminderFileModTime ReminderFile
if {$ReminderFileModTime < 0} {
# Could not stat file
return
}
set mtime -1
catch {
set mtime [file mtime $ReminderFile]
}
if {$mtime < 0} {
# Doh!
return
}
# Run ourselves again
after 60000 MonitorReminderFile
# Redraw calendar and restart daemon if needed
if {$ReminderFileModTime < $mtime} {
set ReminderFileModTime $mtime
ScheduleUpdateForChanges
}
} }
#*********************************************************************** #***********************************************************************
@@ -1119,8 +1082,11 @@ proc FillCalWindow {} {
set_button_to_queue set_button_to_queue
set month [lindex $MonthNames $CurMonth] set month [lindex $MonthNames $CurMonth]
set cmd [regsub EXTRA $CommandLine $Option(ExtraRemindArgs)] set cmd [regsub @EXTRA@ $CommandLine $Option(ExtraRemindArgs)]
set file [open "$cmd $month $CurYear" r] set cmd [regsub @MONTH@ $cmd $month]
set cmd [regsub @YEAR@ $cmd $CurYear]
set file [open $cmd r]
# Look for # rem2ps2 begin line # Look for # rem2ps2 begin line
while { [gets $file line] >= 0 } { while { [gets $file line] >= 0 } {
if { [string compare "$line" "# rem2ps2 begin"] == 0 } { break } if { [string compare "$line" "# rem2ps2 begin"] == 0 } { break }
@@ -1447,16 +1413,17 @@ proc DoPrint {} {
return return
} }
} }
set fname [posix_escape $fname]
set fname "> $fname" set fname "> $fname"
} else { } else {
set fname "| $cmd" set fname "| $cmd"
} }
if {$HaveRem2PDF && $Option(PrintFormat) == "pdf"} { if {$HaveRem2PDF && $Option(PrintFormat) == "pdf"} {
set p [regsub EXTRA $PSCmd "-itkpdf=1 $Option(ExtraRemindArgs)"] set p [regsub @EXTRA@ $PSCmd "-itkpdf=1 $Option(ExtraRemindArgs)"]
set cmd "$p 1 [lindex $MonthNames $CurMonth] $CurYear | $Rem2PDF" set cmd "$p 1 [lindex $MonthNames $CurMonth] $CurYear | $Rem2PDF"
} else { } else {
set p [regsub EXTRA $PSCmd $Option(ExtraRemindArgs)] set p [regsub @EXTRA@ $PSCmd $Option(ExtraRemindArgs)]
set cmd "$p 1 [lindex $MonthNames $CurMonth] $CurYear | $Rem2PS" set cmd "$p 1 [lindex $MonthNames $CurMonth] $CurYear | $Rem2PS"
set Option(PrintFormat) ps set Option(PrintFormat) ps
} }
@@ -1525,7 +1492,7 @@ proc DoPrint {} {
append cmd " $fname" append cmd " $fname"
Status "Printing..." Status "Printing..."
if {[catch {eval "exec $cmd"} err]} { if {[catch {exec /bin/sh "-c" $cmd} err]} {
set RemindErrors [unique_lines $err] set RemindErrors [unique_lines $err]
set_button_to_errors set_button_to_errors
} }
@@ -1544,6 +1511,7 @@ proc PrintFileBrowse {} {
.p.filename icursor end .p.filename icursor end
.p.filename xview end .p.filename xview end
} }
raise .p
} }
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
@@ -1596,10 +1564,12 @@ proc DoGoto {} {
set year [.g.y.e get] set year [.g.y.e get]
if { ! [regexp {^[0-9]+$} $year] } { if { ! [regexp {^[0-9]+$} $year] } {
show_error {Illegal year specified (1990-5990)} show_error {Illegal year specified (1990-5990)}
raise .g
return return
} }
if { $year < 1990 || $year > 5990 } { if { $year < 1990 || $year > 5990 } {
show_error {Illegal year specified (1990-5990)} show_error {Illegal year specified (1990-5990)}
raise .g
return return
} }
set month [lsearch -exact $MonthNames [.g.mon cget -text]] set month [lsearch -exact $MonthNames [.g.mon cget -text]]
@@ -2079,6 +2049,7 @@ proc ModifyDay {d firstDay} {
set problem [catch {set rem [CreateReminder .mod]} err] set problem [catch {set rem [CreateReminder .mod]} err]
if {$problem} { if {$problem} {
show_error $err show_error $err
raise .mod
} else { } else {
if {$ModifyDialogResult == 3} { if {$ModifyDialogResult == 3} {
set rem [EditReminder $rem Cancel "Add reminder"] set rem [EditReminder $rem Cancel "Add reminder"]
@@ -2618,8 +2589,9 @@ proc BrowseForFileRead {w {dir ""}} {
if {$dir == ""} { if {$dir == ""} {
set dir [$w.cwd cget -text] set dir [$w.cwd cget -text]
} }
if {[catch "cd $dir" err]} { if {[catch {cd $dir} err]} {
show_error "$err" show_error "$err"
raise $w
return return
} }
$w.cwd configure -text [pwd] $w.cwd configure -text [pwd]
@@ -2662,10 +2634,11 @@ proc BrowseForFileRead {w {dir ""}} {
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
proc StartBackgroundRemindDaemon {} { proc StartBackgroundRemindDaemon {} {
global Remind DaemonFile ReminderFile Option TwentyFourHourMode global Remind DaemonFile ReminderFile Option TwentyFourHourMode
set fname [posix_escape $ReminderFile]
if {$TwentyFourHourMode} { if {$TwentyFourHourMode} {
set problem [catch { set DaemonFile [open "|$Remind -b1 -zj -y -itkremind=1 $Option(ExtraRemindArgs) $ReminderFile" "r+"] } err] set problem [catch { set DaemonFile [open "|/bin/sh -c \"$Remind -b1 -zj -y -itkremind=1 $Option(ExtraRemindArgs) $fname\"" "r+"] } err]
} else { } else {
set problem [catch { set DaemonFile [open "|$Remind -zj -y -itkremind=1 $Option(ExtraRemindArgs) $ReminderFile" "r+"] } err] set problem [catch { set DaemonFile [open "|/bin/sh -c \"$Remind -zj -y -itkremind=1 $Option(ExtraRemindArgs) $fname\"" "r+"] } err]
} }
if {$problem} { if {$problem} {
show_error "Can't start Remind daemon in background: $err" show_error "Can't start Remind daemon in background: $err"
@@ -2704,13 +2677,7 @@ proc StopBackgroundRemindDaemon {} {
# Restarts the background Remind daemon # Restarts the background Remind daemon
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
proc RestartBackgroundRemindDaemon {} { proc RestartBackgroundRemindDaemon {} {
global DaemonFile ReminderFile ReminderFileModTime global DaemonFile ReminderFile
# Don't let the background handler trigger another reread
catch {
set mtime [file mtime $ReminderFile]
set ReminderFileModTime $mtime
}
catch { catch {
puts $DaemonFile "REREAD" puts $DaemonFile "REREAD"
@@ -2752,11 +2719,30 @@ proc ShowQueue { queue } {
if { $did > 0 } { if { $did > 0 } {
$w.t insert end "\n" $w.t insert end "\n"
} }
foreach r $q { set fntag ""
catch {
set fname [dict get $q filename]
set lineno [dict get $q lineno]
set fntag [string cat "FILE_" $lineno "_" $fname]
}
if { "$fntag" != "" } {
$w.t tag bind $fntag <Enter> [list $w.t tag configure $fntag -underline 1]
$w.t tag bind $fntag <Leave> [list $w.t tag configure $fntag -underline 0]
$w.t tag bind $fntag <ButtonPress-1> [list FireEditor $w.t $fntag]
$w.t tag bind $fntag <ButtonPress-3> [list FireEditor $w.t $fntag]
}
foreach key [list time nexttime body] {
set r [dict get $q $key]
if { $toggle != 0 } { if { $toggle != 0 } {
$w.t insert end "$r " grey $w.t insert end "$key=$r" [list grey $fntag]
if {"$key" != "body"} {
$w.t insert end "; " [list grey $fntag]
}
} else { } else {
$w.t insert end "$r " $w.t insert end "$key=$r" [list $fntag]
if {"$key" != "body"} {
$w.t insert end "; " [list $fntag]
}
} }
} }
$w.t insert end "\n" $w.t insert end "\n"
@@ -2765,6 +2751,8 @@ proc ShowQueue { queue } {
} }
if { $did == 0 } { if { $did == 0 } {
$w.t insert end "(Queue is empty)\n" $w.t insert end "(Queue is empty)\n"
} else {
$w.t insert end "\n\nClick on a queue item to open an editor on the corresponding REM command.\n"
} }
$w.t configure -state disabled $w.t configure -state disabled
} }
@@ -3340,6 +3328,12 @@ proc ReadTaggedOptions { tag date } {
} }
return $ans return $ans
} }
# Make a string safe for passing to shell.
proc posix_escape { str } {
return [string cat "'" [string map [list {'} {'\''}] $str] "'"]
}
proc FireEditor { w {fntag ""}} { proc FireEditor { w {fntag ""}} {
global Option global Option
global EditorPid global EditorPid
@@ -3355,7 +3349,7 @@ proc FireEditor { w {fntag ""}} {
return return
} }
set editor $Option(Editor) set editor $Option(Editor)
regsub -all "%s" $editor $file editor regsub -all "%s" $editor [posix_escape $file] editor
regsub -all "%d" $editor $line editor regsub -all "%d" $editor $line editor
# Don't fire up a second editor if first is running # Don't fire up a second editor if first is running
@@ -3905,6 +3899,10 @@ proc CreateMoonWindows {} {
#*********************************************************************** #***********************************************************************
proc DisplayTimeContinuously {} { proc DisplayTimeContinuously {} {
DisplayTime DisplayTime
# Reap any zombies
eval { exec true }
set secs [clock format [clock seconds] -format "%S"] set secs [clock format [clock seconds] -format "%S"]
# Doh -- don't interpret as an octal number if leading zero # Doh -- don't interpret as an octal number if leading zero
scan $secs "%d" decSecs scan $secs "%d" decSecs
@@ -4279,12 +4277,13 @@ proc update_color_buttons { w } {
} }
proc set_button_to_queue {} { proc set_button_to_queue {} {
global Option
balloon_set_help .b.queue "See the queue of pending reminders (debugging purposes only)" balloon_set_help .b.queue "See the queue of pending reminders (debugging purposes only)"
.b.queue configure -text {Queue...} -command {DoQueue} .b.queue configure -text {Queue...} -command {DoQueue} -foreground $Option(LabelColor) -background $Option(WinBackground)
} }
proc set_button_to_errors {} { proc set_button_to_errors {} {
balloon_set_help .b.queue "See the list of errors from the most recent operation" balloon_set_help .b.queue "See the list of errors from the most recent operation"
.b.queue configure -text {Errors...} -command {ShowErrors} .b.queue configure -text {Errors...} -command {ShowErrors} -bg #FF5555 -fg black
} }
proc ShowErrors {} { proc ShowErrors {} {
@@ -4302,7 +4301,25 @@ proc ShowErrors {} {
grid columnconfigure $w 1 -weight 0 grid columnconfigure $w 1 -weight 0
grid rowconfigure $w 0 -weight 1 grid rowconfigure $w 0 -weight 1
grid rowconfigure $w 1 -weight 0 grid rowconfigure $w 1 -weight 0
$w.t insert end $RemindErrors set l [split $RemindErrors "\n"]
set i 0
foreach line $l {
if {[regexp {^(.*)\(([0-9]+)\)} $line dummy fname lineno]} {
incr i
set fntag [string cat "FILE_" $lineno "_" $fname]
$w.t insert end $line [list ERR "ERR$i" $fntag]
$w.t tag bind "ERR$i" <ButtonPress-1> [list FireEditor $w.t $fntag]
$w.t tag bind "ERR$i" <ButtonPress-3> [list FireEditor $w.t $fntag]
$w.t tag bind "ERR$i" <Enter> "$w.t tag configure ERR$i -underline 1"
$w.t tag bind "ERR$i" <Leave> "$w.t tag configure ERR$i -underline 0"
} else {
$w.t insert end $line
}
$w.t insert end "\n"
}
if {$i > 0} {
$w.t insert end "\nIf an error message is underlined when you hover over it, click button-1 to edit the offending file at the line number of the error.\n"
}
$w.t configure -state disabled $w.t configure -state disabled
CenterWindow $w . CenterWindow $w .
} }

View File

@@ -10,7 +10,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* */ /* */
/***************************************************************/ /***************************************************************/
#include "version.h" #include "version.h"
#include "config.h" #include "config.h"
@@ -66,8 +65,6 @@ static int FAbs (func_info *);
static int FAccess (func_info *); static int FAccess (func_info *);
static int FAmpm (func_info *); static int FAmpm (func_info *);
static int FAnsicolor (func_info *); static int FAnsicolor (func_info *);
static int FTrig (func_info *);
static int FIsAny (func_info *);
static int FArgs (func_info *); static int FArgs (func_info *);
static int FAsc (func_info *); static int FAsc (func_info *);
static int FBaseyr (func_info *); static int FBaseyr (func_info *);
@@ -101,6 +98,7 @@ static int FHtmlEscape (func_info *);
static int FHtmlStriptags (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 FIsAny (func_info *);
static int FIsdst (func_info *); static int FIsdst (func_info *);
static int FIsleap (func_info *); static int FIsleap (func_info *);
static int FIsomitted (func_info *); static int FIsomitted (func_info *);
@@ -117,6 +115,7 @@ static int FMoondate (func_info *);
static int FMoondatetime (func_info *); static int FMoondatetime (func_info *);
static int FMoonphase (func_info *); static int FMoonphase (func_info *);
static int FMoontime (func_info *); static int FMoontime (func_info *);
static int FMultiTrig (func_info *);
static int FNDawn (func_info *); static int FNDawn (func_info *);
static int FNDusk (func_info *); static int FNDusk (func_info *);
static int FNonomitted (func_info *); static int FNonomitted (func_info *);
@@ -134,6 +133,7 @@ static int FRealtoday (func_info *);
static int FRows (func_info *); static int FRows (func_info *);
static int FSgn (func_info *); static int FSgn (func_info *);
static int FShell (func_info *); static int FShell (func_info *);
static int FShellescape (func_info *);
static int FSlide (func_info *); static int FSlide (func_info *);
static int FSoleq (func_info *); static int FSoleq (func_info *);
static int FStdout (func_info *); static int FStdout (func_info *);
@@ -156,9 +156,9 @@ static int FTrigeventstart (func_info *);
static int FTrigfrom (func_info *); static int FTrigfrom (func_info *);
static int FTrigger (func_info *); static int FTrigger (func_info *);
static int FTrigpriority (func_info *); static int FTrigpriority (func_info *);
static int FTrigtags (func_info *);
static int FTrigrep (func_info *); static int FTrigrep (func_info *);
static int FTrigscanfrom (func_info *); static int FTrigscanfrom (func_info *);
static int FTrigtags (func_info *);
static int FTrigtime (func_info *); static int FTrigtime (func_info *);
static int FTrigtimedelta (func_info *); static int FTrigtimedelta (func_info *);
static int FTrigtimerep (func_info *); static int FTrigtimerep (func_info *);
@@ -166,15 +166,14 @@ static int FTriguntil (func_info *);
static int FTrigvalid (func_info *); static int FTrigvalid (func_info *);
static int FTypeof (func_info *); static int FTypeof (func_info *);
static int FTzconvert (func_info *); static int FTzconvert (func_info *);
static int FUpper (func_info *);
static int FUTCToLocal (func_info *); static int FUTCToLocal (func_info *);
static int FUpper (func_info *);
static int FValue (func_info *); static int FValue (func_info *);
static int FVersion (func_info *); static int FVersion (func_info *);
static int FWeekno (func_info *); static int FWeekno (func_info *);
static int FWkday (func_info *); static int FWkday (func_info *);
static int FWkdaynum (func_info *); static int FWkdaynum (func_info *);
static int FYear (func_info *); static int FYear (func_info *);
static int FShellescape (func_info *);
static int CleanUpAfterFunc (func_info *); static int CleanUpAfterFunc (func_info *);
static int CheckArgs (BuiltinFunc *f, int nargs); static int CheckArgs (BuiltinFunc *f, int nargs);
@@ -285,6 +284,7 @@ BuiltinFunc Func[] = {
{ "moondatetime", 1, 3, 0, FMoondatetime }, { "moondatetime", 1, 3, 0, FMoondatetime },
{ "moonphase", 0, 2, 0, FMoonphase }, { "moonphase", 0, 2, 0, FMoonphase },
{ "moontime", 1, 3, 0, FMoontime }, { "moontime", 1, 3, 0, FMoontime },
{ "multitrig", 1, NO_MAX, 0, FMultiTrig },
{ "ndawn", 0, 1, 0, FNDawn}, { "ndawn", 0, 1, 0, FNDawn},
{ "ndusk", 0, 1, 0, FNDusk}, { "ndusk", 0, 1, 0, FNDusk},
{ "nonomitted", 2, NO_MAX, 0, FNonomitted }, { "nonomitted", 2, NO_MAX, 0, FNonomitted },
@@ -3521,6 +3521,57 @@ FEvalTrig(func_info *info)
return OK; return OK;
} }
static int
FMultiTrig(func_info *info)
{
Parser p;
Trigger trig;
TimeTrig tim;
int dse;
int r;
int i;
int earliest = -1;
RetVal.type = DATE_TYPE;
RETVAL = 0;
for (i=0; i<Nargs; i++) {
ASSERT_TYPE(i, STR_TYPE);
}
for (i=0; i<Nargs; i++) {
CreateParser(ARGSTR(i), &p);
p.allownested = 0;
r = ParseRem(&p, &trig, &tim, 0);
if (r) {
DestroyParser(&p);
return r;
}
if (trig.typ != NO_TYPE) {
DestroyParser(&p);
FreeTrig(&trig);
return E_PARSE_ERR;
}
if (tim.ttime != NO_TIME) {
Eprint("Cannot use AT clause in multitrig() function");
return E_PARSE_ERR;
}
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
DestroyParser(&p);
if (r != E_CANT_TRIG) {
if (dse < earliest || earliest < 0) {
earliest = dse;
}
}
FreeTrig(&trig);
}
if (earliest >= 0) {
RETVAL = earliest;
}
return OK;
}
static int LastTrig = 0; static int LastTrig = 0;
static int static int
FTrig(func_info *info) FTrig(func_info *info)
@@ -3558,20 +3609,18 @@ FTrig(func_info *info)
return E_PARSE_ERR; return E_PARSE_ERR;
} }
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0); dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
DestroyParser(&p);
if (r == E_CANT_TRIG) { if (r == E_CANT_TRIG) {
DestroyParser(&p);
FreeTrig(&trig); FreeTrig(&trig);
continue; continue;
} }
if (ShouldTriggerReminder(&trig, &tim, dse, &r)) { if (ShouldTriggerReminder(&trig, &tim, dse, &r)) {
LastTrig = dse; LastTrig = dse;
RETVAL = dse; RETVAL = dse;
DestroyParser(&p);
FreeTrig(&trig); FreeTrig(&trig);
return OK; return OK;
} }
DestroyParser(&p);
FreeTrig(&trig); FreeTrig(&trig);
} }
return OK; return OK;
@@ -3684,11 +3733,8 @@ mean_december_solstice(double y)
} }
/* Cosine of an angle specified in degrees */ /* Cosine of an angle specified in degrees */
static double #define PI_BY_180 0.01745329251994329576923690768
cosd(double degrees) #define cosd(theta) cos( (theta) * PI_BY_180)
{
return cos((degrees / 180.0) * 3.14159265358979);
}
/* Astronomical Algorithms by Meeus, p. 179 /* Astronomical Algorithms by Meeus, p. 179
These weird periodic components refine the mean solstice/equinox dates These weird periodic components refine the mean solstice/equinox dates

File diff suppressed because one or more lines are too long

View File

@@ -784,6 +784,15 @@ ENDIF
REM [trig("Mon", "Tue", "Wed", "Sat")] MSG foo REM [trig("Mon", "Tue", "Wed", "Sat")] MSG foo
REM [trig("Mon", "Tue", "Wed")] MSG bar REM [trig("Mon", "Tue", "Wed")] MSG bar
# Multitrig
REM [multitrig("10", "17")] MSG multitrig-1
REM [multitrig("Feb 15", "Mar 20")] MSG multitrig-2
REM [multitrig("Oct 7 1992", "1991")] MSG multitrig-3
REM [multitrig("16 Feb AFTER OMIT Sat Sun", "29 March")] MSG multitrig-4
REM [multitrig("2", "3", "5", "7")] MSG multitrig-5
REM [multitrig("15 SCANFROM -7", "14 SCANFROM -7")] MSG multitrig-6
REM [multitrig("15 SCANFROM -7", "14 SCANFROM -7")] SCANFROM -7 MSG multitrig-7
# The new syntactic sugar # The new syntactic sugar
REM First Monday January MSG x REM First Monday January MSG x
REM Second Tuesday in April MSG x REM Second Tuesday in April MSG x

View File

@@ -12,10 +12,10 @@ CGIDIR = /cgi-bin
# The complete path to the directory containing the HTML file "calendar.html". # The complete path to the directory containing the HTML file "calendar.html".
# This is a sample file containing links to all the scripts. This path # This is a sample file containing links to all the scripts. This path
# should be the path as seen by the UNIX operating system # should be the path as seen by the UNIX operating system
HTMLDIR = /var/www/remind HTMLDIR = /var/www/html/remind
# Where you stick images and CSS files, as seen by UNIX # Where you stick images and CSS files, as seen by UNIX
IMAGEDIR = /var/www/remind/resources IMAGEDIR = /var/www/html/remind/resources
# Where images and CSS files are, as seen by web browsers # Where images and CSS files are, as seen by web browsers
IMAGEBASE = /remind/resources IMAGEBASE = /remind/resources
@@ -32,6 +32,7 @@ datarootdir=@datarootdir@
# Where do Remind and Rem2PS executables live? # Where do Remind and Rem2PS executables live?
REMIND = $(bindir)/remind REMIND = $(bindir)/remind
REM2PS = $(bindir)/rem2ps REM2PS = $(bindir)/rem2ps
REM2PDF = $(bindir)/rem2pdf
REM2HTML = $(bindir)/rem2html REM2HTML = $(bindir)/rem2html
# If your Web server requires CGI programs to have a .cgi suffix, use # If your Web server requires CGI programs to have a .cgi suffix, use
# the next line. Otherwise, comment it out # the next line. Otherwise, comment it out
@@ -46,6 +47,7 @@ SEDSCRIPT = -e 's@%CGIDIR%@$(CGIDIR)@g' \
-e 's@%REMIND%@$(REMIND)@g' \ -e 's@%REMIND%@$(REMIND)@g' \
-e 's@%IMAGEBASE%@$(IMAGEBASE)@g' \ -e 's@%IMAGEBASE%@$(IMAGEBASE)@g' \
-e 's@%REM2PS%@$(REM2PS)@g' \ -e 's@%REM2PS%@$(REM2PS)@g' \
-e 's@%REM2PDF%@$(REM2PDF)@g' \
-e 's@%REM2HTML%@$(REM2HTML)@g' \ -e 's@%REM2HTML%@$(REM2HTML)@g' \
-e 's@cal_dispatch@cal_dispatch$(CGISUFFIX)@g' \ -e 's@cal_dispatch@cal_dispatch$(CGISUFFIX)@g' \
@@ -57,7 +59,8 @@ all:
install: install:
-mkdir -p $(DESTDIR)$(SCRIPTDIR) -mkdir -p $(DESTDIR)$(SCRIPTDIR)
-mkdir -p $(DESTDIR)$(HTMLDIR) -mkdir -p $(DESTDIR)$(HTMLDIR)
cp calps hebdate hebps hebhtml moon sunrise sunset $(DESTDIR)$(SCRIPTDIR) cp calps calpdf hebps hebpdf hebhtml moon sunrise sunset $(DESTDIR)$(SCRIPTDIR)
sed $(SEDSCRIPT) < hebdate > $(DESTDIR)$(SCRIPTDIR)/hebdate
sed $(SEDSCRIPT) < cal_dispatch-DIST > $(DESTDIR)$(SCRIPTDIR)/cal_dispatch$(CGISUFFIX) sed $(SEDSCRIPT) < cal_dispatch-DIST > $(DESTDIR)$(SCRIPTDIR)/cal_dispatch$(CGISUFFIX)
sed $(SEDSCRIPT) < hebdate.rem-DIST > $(DESTDIR)$(SCRIPTDIR)/hebdate.rem sed $(SEDSCRIPT) < hebdate.rem-DIST > $(DESTDIR)$(SCRIPTDIR)/hebdate.rem
sed $(SEDSCRIPT) < moon.rem-DIST > $(DESTDIR)$(SCRIPTDIR)/moon.rem sed $(SEDSCRIPT) < moon.rem-DIST > $(DESTDIR)$(SCRIPTDIR)/moon.rem
@@ -73,14 +76,14 @@ install:
chmod 644 $(DESTDIR)$(SCRIPTDIR)/blank.rem chmod 644 $(DESTDIR)$(SCRIPTDIR)/blank.rem
chmod 644 $(DESTDIR)$(HTMLDIR)/calendar.html chmod 644 $(DESTDIR)$(HTMLDIR)/calendar.html
chmod 755 $(DESTDIR)$(SCRIPTDIR)/cal_dispatch$(CGISUFFIX) chmod 755 $(DESTDIR)$(SCRIPTDIR)/cal_dispatch$(CGISUFFIX)
chmod 755 $(DESTDIR)$(SCRIPTDIR)/calps $(DESTDIR)$(SCRIPTDIR)/hebdate \ chmod 755 $(DESTDIR)$(SCRIPTDIR)/calpdf $(DESTDIR)$(SCRIPTDIR)/calps $(DESTDIR)$(SCRIPTDIR)/hebdate \
$(DESTDIR)$(SCRIPTDIR)/hebps $(DESTDIR)$(SCRIPTDIR)/moon \ $(DESTDIR)$(SCRIPTDIR)/hebps $(DESTDIR)$(SCRIPTDIR)/hebpdf $(DESTDIR)$(SCRIPTDIR)/moon \
$(DESTDIR)$(SCRIPTDIR)/sunrise $(DESTDIR)$(SCRIPTDIR)/sunset \ $(DESTDIR)$(SCRIPTDIR)/sunrise $(DESTDIR)$(SCRIPTDIR)/sunset \
$(DESTDIR)$(SCRIPTDIR)/hebhtml \ $(DESTDIR)$(SCRIPTDIR)/hebhtml \
-mkdir -p $(DESTDIR)$(IMAGEDIR) -mkdir -p $(DESTDIR)$(IMAGEDIR)
cp rem-default.css *.png $(DESTDIR)$(IMAGEDIR) cp calendar.css rem-default.css *.png $(DESTDIR)$(IMAGEDIR)
chmod 644 $(DESTDIR)$(IMAGEDIR)/rem-default.css $(DESTDIR)$(IMAGEDIR)/*.png chmod 644 $(DESTDIR)$(IMAGEDIR)/calendar.css $(DESTDIR)$(IMAGEDIR)/rem-default.css $(DESTDIR)$(IMAGEDIR)/*.png

View File

@@ -28,6 +28,10 @@ export REMIND
REM2PS=%REM2PS% REM2PS=%REM2PS%
export REM2PS export REM2PS
# Set REM2PDF to the full pathname of the rem2pdf executable
REM2PDF=%REM2PDF%
export REM2PDF
######################### #########################
# #
# Don't change anything after this. # Don't change anything after this.
@@ -56,6 +60,10 @@ case "$1" in
exec $DIR/calps exec $DIR/calps
;; ;;
calpdf)
exec $DIR/calpdf
;;
moon) moon)
exec $DIR/moon exec $DIR/moon
;; ;;
@@ -64,6 +72,10 @@ case "$1" in
exec $DIR/hebps exec $DIR/hebps
;; ;;
hebpdf)
exec $DIR/hebpdf
;;
hebhtml) hebhtml)
if [ "$2" = "" -o "$3" = "" ] ; then if [ "$2" = "" -o "$3" = "" ] ; then
exec $DIR/hebhtml exec $DIR/hebhtml

41
www/calendar.css Normal file
View File

@@ -0,0 +1,41 @@
html, body {
padding: 0px;
margin-left: 10px;
margin-right: 10px;
font-family: "Open Sans", Arial, sans-serif
background: #FFFFFF;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 5px;
margin-bottom: 5px;
padding-top: 0px;
padding-bottom: 0px;
font-family: inherit;
font-weight: 600;
}
h1, .h1 {
font-size: 1.75rem; }
h2, .h2 {
font-size: 1.5rem; }
h3, .h3 {
font-size: 1.25rem; }
a {
text-decoration: none;
color: #1a0dab;
}
a:visited {
text-decoration: none;
color: #1a0dab;
}
a:hover {
text-decoration: none;
color: #ff0000;
}

View File

@@ -1,7 +1,8 @@
<HTML> <HTML>
<!-- Sample HTML file with links to the calendar stuff --> <!-- Sample HTML file with links to the calendar stuff -->
<HEAD> <HEAD>
<TITLE>Remind Calendar Server</TITLE> <TITLE>Remind Calendar Server</TITLE>
<LINK rel="stylesheet" href="%IMAGEBASE%/calendar.css">
</HEAD> </HEAD>
<BODY> <BODY>
@@ -15,10 +16,14 @@ Sunset Information</a><P>
Moon Phase Information</a><P> Moon Phase Information</a><P>
<a HREF="%CGIDIR%/cal_dispatch?calps"> <a HREF="%CGIDIR%/cal_dispatch?calps">
Blank PostScript Calendar</a> (Approximately 20kB)<P> Blank PostScript Calendar</a> (Approximately 20kB)<P>
<a HREF="%CGIDIR%/cal_dispatch?calpdf">
Blank PDF Calendar</a> (Approximately 15kB)<P>
<a HREF="%CGIDIR%/cal_dispatch?hebdate"> <a HREF="%CGIDIR%/cal_dispatch?hebdate">
Today's Hebrew Date</a><P> Today's Hebrew Date</a><P>
<a HREF="%CGIDIR%/cal_dispatch?hebps"> <a HREF="%CGIDIR%/cal_dispatch?hebps">
PostScript Calendar with Jewish Holidays</a> (Approximately 35 kB)<P> PostScript Calendar with Jewish Holidays</a> (Approximately 35 kB)<P>
<a HREF="%CGIDIR%/cal_dispatch?hebpdf">
PDF Calendar with Jewish Holidays</a> (Approximately 20 kB)<P>
<a HREF="%CGIDIR%/cal_dispatch?hebhtml"> <a HREF="%CGIDIR%/cal_dispatch?hebhtml">
HTML Calendar with Jewish Holidays</a> HTML Calendar with Jewish Holidays</a>
<HR> <HR>

11
www/calpdf Normal file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
# PostScript calendar shell script
#
# This file is part of REMIND.
# Copyright (C) 1992-2018 by Dianne Skoll
echo "Content-type: application/pdf"
echo
$REMIND -p $DIR/blank.rem | $REM2PDF -e -c3 -l
exit 0

View File

@@ -11,6 +11,7 @@ cat <<EOM
<HTML> <HTML>
<HEAD> <HEAD>
<TITLE>Hebrew date</TITLE> <TITLE>Hebrew date</TITLE>
<LINK rel="stylesheet" href="%IMAGEBASE%/calendar.css">
</HEAD> </HEAD>
<BODY> <BODY>

View File

@@ -165,13 +165,15 @@ ENDIF
IF !$PSCAL IF !$PSCAL
REM 20 ++40 msg Also available: <a HREF="%CGIDIR%/cal_dispatch?hebps">a PostScript calendar</a> (about 35KB) for %m %y, complete with Hebrew dates, Jewish holidays, and moon phases for [$Location]. REM 20 ++40 msg Also available: <a HREF="%CGIDIR%/cal_dispatch?hebps">a PostScript calendar</a> (about 35KB) for %m %y, complete with Hebrew dates, Jewish holidays, and moon phases for [$Location].
REM 20 ++40 msg And: <a HREF="%CGIDIR%/cal_dispatch?hebhtml">an HTML version</a> of the above. REM 20 ++40 msg And: <a HREF="%CGIDIR%/cal_dispatch?hebhtml">an HTML version</a> of the above.
REM 20 ++40 msg And: <a HREF="%CGIDIR%/cal_dispatch?hebpdf">a PDF version</a> of the above.
ELSE ELSE
[trigger(moondate(0))] SPECIAL MOON 0 REM [moondate(0)] SPECIAL MOON 0
[trigger(moondate(1))] SPECIAL MOON 1 REM [moondate(1)] SPECIAL MOON 1
[trigger(moondate(2))] SPECIAL MOON 2 REM [moondate(2)] SPECIAL MOON 2
[trigger(moondate(3))] SPECIAL MOON 3 REM [moondate(3)] SPECIAL MOON 3
REM PS Border Border moveto /DayFont findfont 10 scalefont setfont ([hebday(today())] [hebmon(today())]) show REM PS Border Border moveto /DayFont findfont 10 scalefont setfont ([hebday($U)] [hebmon($U)]) show
REM SPECIAL HTML <P>[hebday(today())] [hebmon(today())]</P> REM SPECIAL HTML <P>[hebday($U)] [hebmon($U)]</P>
REM SPECIAL PANGO @4,-1 <span size="6400"><i>[hebday($U)] [hebmon($U)]</i></span>
ENDIF ENDIF

17
www/hebpdf Normal file
View File

@@ -0,0 +1,17 @@
#!/bin/sh
# Hebrew PostScript calendar shell script
#
# This file is part of REMIND.
# Copyright (C) 1992-2018 by Dianne Skoll
# Figure out the month: If day <= 20, use this month; otherwise, use
# next month.
echo "Content-type: application/pdf"
echo ""
$REMIND - <<EOR
BANNER %
REM 20 ++40 RUN $REMIND -iHTML=0 -p $DIR/hebdate.rem %m %y | $REM2PDF -e -c3 -l
EOR
exit 0

View File

@@ -9,6 +9,7 @@ banner %
MSG <HEAD>% MSG <HEAD>%
MSG <TITLE>Moon over [$Location]</TITLE>% MSG <TITLE>Moon over [$Location]</TITLE>%
MSG <LINK rel="stylesheet" href="%IMAGEBASE%/calendar.css">%
MSG </HEAD>% MSG </HEAD>%
MSG <BODY> MSG <BODY>

View File

@@ -8,6 +8,7 @@ set now now()
banner % banner %
MSG <HEAD>% MSG <HEAD>%
MSG <TITLE>Sunrise in [$Location]</TITLE>% MSG <TITLE>Sunrise in [$Location]</TITLE>%
MSG <LINK rel="stylesheet" href="%IMAGEBASE%/calendar.css">%
MSG </HEAD>% MSG </HEAD>%
MSG <BODY> MSG <BODY>

View File

@@ -10,6 +10,7 @@ banner %
MSG <HEAD>% MSG <HEAD>%
MSG <TITLE>Sunset in [$Location]</TITLE>% MSG <TITLE>Sunset in [$Location]</TITLE>%
MSG <LINK rel="stylesheet" href="%IMAGEBASE%/calendar.css">%
MSG </HEAD>% MSG </HEAD>%
MSG <BODY> MSG <BODY>