Compare commits

...

167 Commits

Author SHA1 Message Date
Dianne Skoll
732ce8283f Update docs. 2022-03-11 21:47:50 -05:00
Dianne Skoll
122bd3e07e Add comment 2022-03-11 21:27:33 -05:00
Dianne Skoll
0ac5cbb837 Properly cope with two of the same moon phase in a given month. 2022-03-11 21:26:22 -05:00
Dianne Skoll
7f3d4812a8 Add Lastday and Lastworkday syntactic sugar 2022-03-11 21:11:16 -05:00
Dianne Skoll
e1fa11c94c Add the First/Second/Third/Fourth/Last syntactic sugar and the
~N/~~N forms of "back"
2022-03-11 20:53:52 -05:00
Dianne Skoll
c06c65acf1 Properly apply options in the right order. 2022-03-11 19:57:20 -05:00
Dianne Skoll
a84fa0bc8f Add canned "Light Theme" and "Dark Theme" buttons. 2022-03-11 19:46:40 -05:00
Dianne Skoll
054648e02b More display tweakage. 2022-03-11 14:35:39 -05:00
Dianne Skoll
9548041334 Tweak display; make keyboard traversal better. 2022-03-11 14:29:07 -05:00
Dianne Skoll
da306f2900 Tweak wording 2022-03-11 13:46:43 -05:00
Dianne Skoll
26587aea02 Give more control over TkRemind colors. 2022-03-11 13:38:11 -05:00
Dianne Skoll
adc86e0f00 Allow setting of "Today" highlight color. 2022-03-10 11:53:00 -05:00
Dianne Skoll
a9ed5f075e Document that trig() and SATISFY should not be mixed. 2022-03-05 11:35:55 -05:00
Dianne Skoll
21e30c980e Test multiple-argument version of trig() 2022-03-04 17:29:23 -05:00
Dianne Skoll
a657b2e55a Update man page. 2022-03-04 15:40:39 -05:00
Dianne Skoll
ff8c55b8b6 Rename "wouldtrig" to just "trig" 2022-03-04 15:38:07 -05:00
Dianne Skoll
eb36c5bca0 Allow wouldtrig() to take an arbitrary number of args; document it. 2022-03-04 15:24:52 -05:00
Dianne Skoll
89173ce1ee Allow logical operators to accept any non-string operands.
Make wouldtrig() return a date.
2022-03-04 14:59:17 -05:00
Dianne Skoll
5d115ba3e3 Document actual behavior of IF command. 2022-03-04 14:58:49 -05:00
Dianne Skoll
7e3adeb9c9 Make wouldtrig return the trigger date (as an INT, coercable to a date)
Update man page.
2022-03-04 12:28:13 -05:00
Dianne Skoll
080cda86fa Document new || and && return values. 2022-03-04 12:12:49 -05:00
Dianne Skoll
6274cbad52 Make || return first true val and && return last val if first val is true. 2022-03-04 12:11:25 -05:00
Dianne Skoll
85c4ad821d Add note about Remind lacking short-circuit logical operators. 2022-03-04 11:45:37 -05:00
Dianne Skoll
b758a2fea8 Tweak formatting. 2022-03-04 11:40:46 -05:00
Dianne Skoll
6619cc7ca4 Add wouldtrig tests. 2022-03-04 11:33:03 -05:00
Dianne Skoll
961f7a8a62 Document wouldtrig() 2022-03-04 11:21:14 -05:00
Dianne Skoll
905287901f Add zero-argument form of wouldtrig. 2022-03-04 11:16:33 -05:00
Dianne Skoll
669be7bf57 Add wouldtrig function. 2022-03-04 11:00:09 -05:00
Dianne Skoll
9b8eb2dc4c Support calling EvalExpr recursively 2022-03-04 10:49:20 -05:00
Dianne Skoll
00ab7b196d Set default of $MaxSatIter to 1000 instead of 150.
Computers are much faster than when Remind was first written;
we can handle a much higher limit.
2022-03-04 08:18:49 -05:00
Dianne Skoll
f616be4bdd Add comment about operator precedence. 2022-03-04 08:16:58 -05:00
Dianne Skoll
8ae9ce8523 Tweak man page. 2022-03-02 15:30:56 -05:00
Dianne Skoll
6d2bbbd7e2 Another diagnostic message. 2022-03-02 15:25:27 -05:00
Dianne Skoll
1453be83b2 Add more diagnostics for bad UNTIL dates. 2022-03-02 15:17:03 -05:00
Dianne Skoll
8659131be2 Use proper keyword in error message. 2022-03-02 14:43:11 -05:00
Dianne Skoll
0276ce322d Diagnose if UNTIL is earlier than start date unless there is a nonconst expr 2022-03-02 09:11:01 -05:00
Dianne Skoll
b36c99a34b Move successful exit to one spot. 2022-03-02 09:01:33 -05:00
Dianne Skoll
ad575f1485 Proper check for overfull box. 2022-03-01 16:15:00 -05:00
Dianne Skoll
a9162f1472 Proper calculation for warning of overfull box. 2022-03-01 16:12:55 -05:00
Dianne Skoll
221e2554a9 Prep for 03.04.01 release. 2022-02-23 11:09:39 -05:00
Dianne Skoll
04ec6c3695 Update TodayDay, TodayMonth and TodayYear in Initialize, in case date has rolled over 2022-02-15 10:04:30 -05:00
Dianne Skoll
b1594980fc Add --disable-perl-build-artifacts flag to configure. 2022-02-13 10:42:50 -05:00
Dianne Skoll
024a8ef38d Double-check that chosen font size for small calendars won't overflow box. 2022-02-13 10:33:21 -05:00
Dianne Skoll
b281051421 Don't overflow small calendar box. 2022-02-12 23:30:08 -05:00
Dianne Skoll
aa1b275b51 Support INSTALL_BASE 2022-02-11 10:55:59 -05:00
Dianne Skoll
c22ca68857 Support INSTALL_BASE env var 2022-02-11 10:39:31 -05:00
Dianne Skoll
3804ce3fe3 Prep for 03.04.00 release. 2022-02-10 17:15:01 -05:00
Dianne Skoll
0977f1db04 Don't export the 'php' directory. 2022-02-10 10:07:41 -05:00
Dianne Skoll
83c97934c9 Fix typo 2022-02-09 09:43:11 -05:00
Dianne Skoll
44c9d74caa Preserve #include "custom.h" in config.h.in. Patch due to Jochen Sprickerhof 2022-02-09 09:10:47 -05:00
Dianne Skoll
172f56754a Fix groff errors - patch from Jochen Sprickerhof 2022-02-09 08:59:58 -05:00
Dianne Skoll
dc184cc713 Don't fail "make clean" in src - patch from Jochen Sprickerhof. 2022-02-09 08:58:47 -05:00
Dianne Skoll
2c30088553 Update docs. 2022-02-08 13:31:11 -05:00
Dianne Skoll
6f0c189afb Edit proper file 2022-02-08 13:23:29 -05:00
Dianne Skoll
0e2996c3e1 Update "See also" 2022-02-08 13:22:32 -05:00
Dianne Skoll
ce8040dd1f Add generated file to .gitignore 2022-02-08 13:19:07 -05:00
Dianne Skoll
a8fd2d463d Update man pages 2022-02-08 13:18:48 -05:00
Dianne Skoll
237813127c Document how to highlight "today" in rem2html 2022-02-08 13:10:15 -05:00
Dianne Skoll
3e6259532f Support the old-style "REM ... SPECIAL SHADE grey" variant. 2022-02-03 19:34:09 -05:00
Dianne Skoll
c015441130 Don't barf if libcairo is too old. 2022-02-03 17:27:31 -05:00
Dianne Skoll
9661455fee Set default heading size to 12 instead of 14. 2022-02-03 16:27:38 -05:00
Dianne Skoll
df983b4123 Make sure all system variables are accessible. 2022-02-03 16:16:28 -05:00
Dianne Skoll
068d5429eb Fix variable sort order 2022-02-03 16:12:13 -05:00
Dianne Skoll
6c593fe849 Update docs. 2022-02-02 11:43:27 -05:00
Dianne Skoll
6a7bdb2ec7 Note the defalt font is Sans 2022-02-01 20:02:09 -05:00
Dianne Skoll
a4aead18dd Default font to "Sans" instead of "Helvetica" in rem2pdf... gives better output 2022-02-01 20:01:00 -05:00
Dianne Skoll
d277154d9f Update WHATSNEW 2022-02-01 19:56:51 -05:00
Dianne Skoll
d2662fb026 Remove unused macro and misleading comment. 2022-02-01 19:52:48 -05:00
Dianne Skoll
2f522ea705 Remove unused macro SIZEOF_UNSIGNED_SHORT 2022-02-01 19:51:45 -05:00
Dianne Skoll
cd68041312 Get rid of obsolete PutChar and Putc macros. 2022-02-01 16:05:06 -05:00
Dianne Skoll
9c2556f16d Remove some old cruft; increase number of full OMITs from 500 to 1000. 2022-01-31 14:43:44 -05:00
Dianne Skoll
b80b938d3d Take values from build.tk 2022-01-31 14:38:28 -05:00
Dianne Skoll
0bd6278050 Fix typo. 2022-01-31 14:37:47 -05:00
Dianne Skoll
b2746f28db Include seconds in lat/lon settings. 2022-01-31 14:35:47 -05:00
Dianne Skoll
cfd3698b53 Remove extraneous spaces. 2022-01-31 09:03:56 -05:00
Dianne Skoll
6b5150d30e Update docs. 2022-01-31 09:01:10 -05:00
Dianne Skoll
b011adf94e Fix build.tk 2022-01-31 09:00:02 -05:00
Dianne Skoll
d09b725710 Create proper custom.h 2022-01-31 08:55:34 -05:00
Dianne Skoll
2f1e3524df Replace the various LAT_ and LONG_ macros with DEFAULT_LATITUDE and DEFAULT_LONGITUDE 2022-01-31 08:52:18 -05:00
Dianne Skoll
2de47cfa51 Update docs 2022-01-30 14:42:01 -05:00
Dianne Skoll
15a778075d Update whatsnew. 2022-01-30 14:36:07 -05:00
Dianne Skoll
2502191982 Fix up display_len vs len 2022-01-30 14:22:52 -05:00
Dianne Skoll
47af91d136 Fix PrintCentered. 2022-01-30 14:19:36 -05:00
Dianne Skoll
e249fe3a17 Bump version to 03.04.00. 2022-01-30 14:03:48 -05:00
Dianne Skoll
72838a07f3 Make rem2pdf take a -v option. 2022-01-30 14:02:34 -05:00
Dianne Skoll
c098acc659 Update man pages. 2022-01-30 13:58:33 -05:00
Dianne Skoll
15ee32b5bd Update rem2ps man page. 2022-01-30 13:43:36 -05:00
Dianne Skoll
5a059d9b09 Missed one 2022-01-30 12:35:05 -05:00
Dianne Skoll
77516dbdff Remove a few more files in "make distclean" 2022-01-30 12:34:36 -05:00
Dianne Skoll
835af9ad6a Fix various UTF-8 handling bugs; properly re-space month and day names. 2022-01-30 12:31:38 -05:00
Dianne Skoll
4c30db06c0 Allow spaces in month and day names 2022-01-30 12:02:08 -05:00
Dianne Skoll
3aee12073e Start allowing spaces in month and day names (convert to _ on -p output) 2022-01-30 12:00:57 -05:00
Dianne Skoll
654fd78ee7 Replace spaces in day names with '_' 2022-01-30 11:54:13 -05:00
Dianne Skoll
b8126d3a85 Add POD to Entry.pm 2022-01-30 11:06:50 -05:00
Dianne Skoll
3054091688 Add POD to PDF.pm 2022-01-30 11:00:36 -05:00
Dianne Skoll
6e0fd7ea5f Fix manpage cross-references. 2022-01-30 10:13:10 -05:00
Dianne Skoll
bbb82029d2 Make TkRemind support PDF output iff rem2pdf is installed. 2022-01-29 23:02:06 -05:00
Dianne Skoll
716d7bcc92 Tweak test file. 2022-01-29 22:29:34 -05:00
Dianne Skoll
e7a6bf0e19 Avoid "wide char" error. 2022-01-29 22:29:28 -05:00
Dianne Skoll
27c17252e7 Tweak 2022-01-29 22:23:43 -05:00
Dianne Skoll
940254bec6 Add another feature demo 2022-01-29 22:23:16 -05:00
Dianne Skoll
79952d52f1 Add note about invalid markup 2022-01-29 22:22:09 -05:00
Dianne Skoll
e58545d3f6 Finish rem2pdf man page. 2022-01-29 22:20:01 -05:00
Dianne Skoll
b7c9643a05 Also handle -ppp output. 2022-01-29 21:32:44 -05:00
Dianne Skoll
c2be6c348a Fix incorrect logic. 2022-01-29 21:30:32 -05:00
Dianne Skoll
0161f81389 Support old-style -p format as well. 2022-01-29 16:03:56 -05:00
Dianne Skoll
2a2df322dc More consistent error messages. 2022-01-28 18:30:01 -05:00
Dianne Skoll
b276b5fdce Start on man page. 2022-01-28 17:11:28 -05:00
Dianne Skoll
b5f7dabf10 Set default paper size correctly. 2022-01-28 16:42:58 -05:00
Dianne Skoll
307f8a07e0 Don't bother doing work if we set a system variable to the same as existing. 2022-01-28 13:14:14 -05:00
Dianne Skoll
3fe5e2becd More pango test tweaks. 2022-01-28 12:09:47 -05:00
Dianne Skoll
e8a4acf517 Fix height calculation. 2022-01-28 11:51:26 -05:00
Dianne Skoll
9ba28c01e7 Tweak test file to exercise dayname display. 2022-01-28 11:33:58 -05:00
Dianne Skoll
ff3b04f46d Add --help; properly grab first char of day name 2022-01-28 11:25:58 -05:00
Dianne Skoll
9f6f452b18 Don't make rem2pdf.in executable 2022-01-28 11:20:00 -05:00
Dianne Skoll
9b4e35841e Make rem2pdf executable 2022-01-28 11:16:36 -05:00
Dianne Skoll
927e260f5b Generate rem2pdf/bin/rem2pdf so we can embed VERSION 2022-01-28 11:15:07 -05:00
Dianne Skoll
949156f77c Add usage() 2022-01-28 10:40:56 -05:00
Dianne Skoll
cc59fcac58 Fix edge-case with small calendar placement. 2022-01-27 21:51:15 -05:00
Dianne Skoll
db624d8a8a Better error messages. 2022-01-27 21:41:12 -05:00
Dianne Skoll
ae90243352 Don't emit bogus PDF if there's an input error. 2022-01-27 21:37:33 -05:00
Dianne Skoll
ff58c7f699 Don't rebuild Makefile from Makefile.PL unnecessarily 2022-01-27 21:32:36 -05:00
Dianne Skoll
bd9738f6f4 Update test file. 2022-01-27 20:17:13 -05:00
Dianne Skoll
47e5c63290 Obey --small-cal-font option 2022-01-27 18:47:25 -05:00
Dianne Skoll
2abdcac15c Fix scaling of small calendars 2022-01-27 18:46:16 -05:00
Dianne Skoll
f0f12e4099 Refuse to read from a tty 2022-01-27 18:01:22 -05:00
Dianne Skoll
b1720317a4 Revert accidental deletion of lines from .gitignore. 2022-01-27 17:57:28 -05:00
Dianne Skoll
d90f466b53 Proper installation; 2022-01-27 17:56:33 -05:00
Dianne Skoll
fec84a5efc Ignore a generated file. 2022-01-27 17:47:26 -05:00
Dianne Skoll
1f3f869983 Fix up class names 2022-01-27 17:47:06 -05:00
Dianne Skoll
a6bd6f44bf Remove unneeded file. 2022-01-27 17:44:45 -05:00
Dianne Skoll
78aac61fe1 Ignore generated file 2022-01-27 17:42:50 -05:00
Dianne Skoll
8d735f0410 Build/install rem2pdf if prereqs are present 2022-01-27 17:42:22 -05:00
Dianne Skoll
de014732c6 Add more stuff to the script-testing. 2022-01-27 17:22:23 -05:00
Dianne Skoll
aae6511394 More-or-less working version of rem2pdf 2022-01-27 17:10:06 -05:00
Dianne Skoll
d973439b4f More pango-ization. 2022-01-27 15:12:24 -05:00
Dianne Skoll
32adce2de8 Support Pango markup with PANGO special. 2022-01-27 13:29:20 -05:00
Dianne Skoll
2ac6378fea More work on PDF rendering. 2022-01-27 12:41:24 -05:00
Dianne Skoll
153b7df5fc Get moons working. 2022-01-27 11:39:33 -05:00
Dianne Skoll
9d9bdabf79 More work 2022-01-27 10:23:30 -05:00
Dianne Skoll
2f8eaeacf0 More updates. 2022-01-27 09:18:41 -05:00
Dianne Skoll
dc07a3cf32 More work on Pango-ized rem2pdf 2022-01-26 21:11:48 -05:00
Dianne Skoll
b775e60d1b Start on rem2pdf via Cairo/Pango 2022-01-26 20:59:27 -05:00
Dianne Skoll
7290bccfd7 Start working on Remind -> PDF converter using Pango and Cairo 2022-01-26 16:38:49 -05:00
Dianne Skoll
a1d884ec3f Convert finnish.h and german.h to UTF-8 2022-01-26 10:16:23 -05:00
Dianne Skoll
cc05d88618 Convert danish.h to UTF-8 2022-01-26 10:09:48 -05:00
Dianne Skoll
2675fa53df Convert norwgian.h to UTF-8 2022-01-26 10:07:35 -05:00
Dianne Skoll
59ee9198e2 Convert polish.h to UTF-8 2022-01-26 10:01:05 -05:00
Dianne Skoll
5235936e7b Convert French file to UTF-8 2022-01-26 09:49:42 -05:00
Dianne Skoll
03ab44ea10 Don't allow $MonthName or $DayName system variables to be set to a value containing a space. 2022-01-25 22:35:21 -05:00
Dianne Skoll
b8c2d2b39b Bail if argv[0] == NULL. 2022-01-25 22:21:20 -05:00
Dianne Skoll
6ae7e71fbf Document the alternate %*-form of substitutions 2022-01-25 22:13:11 -05:00
Dianne Skoll
c49740ed81 Remove support for character sets other than UTF-8. 2022-01-25 22:08:20 -05:00
Dianne Skoll
16c0a819a9 Fix to language code. 2022-01-25 22:03:34 -05:00
Dianne Skoll
4a61fe73de Convert Italian to UTF-8 2022-01-25 21:55:13 -05:00
Dianne Skoll
a76feebe45 Convert languages to UTF-8 2022-01-25 21:52:09 -05:00
Dianne Skoll
3a52eadeb1 Handle custom day names in calendars. 2022-01-25 21:34:11 -05:00
Dianne Skoll
dd56b7c385 Add system variables for dynamically changing day and month names. 2022-01-25 19:18:59 -05:00
Dianne Skoll
f6f201085c Start adding support for dynamic month and day names. 2022-01-25 18:47:25 -05:00
Dianne Skoll
daf09d9d4e Fix doc bug. 2022-01-24 17:49:00 -05:00
Dianne Skoll
511cdb2784 Document changes to dynamic buffers. 2022-01-24 10:23:49 -05:00
Dianne Skoll
a567a9b777 Document that strlen() can return E_2HIGH 2022-01-22 18:42:11 -05:00
Dianne Skoll
05bc3af03d Use size_t rather than int to track dynamic buffer size.
This lets use create dynamic buffers larger than 2GB.
2022-01-22 18:40:27 -05:00
Dianne Skoll
7a048d1702 Document update to shell() 2022-01-22 18:26:22 -05:00
Dianne Skoll
8d7f9bcb8b Make shell() obey MaxStringLen 2022-01-22 18:24:38 -05:00
Dianne Skoll
9fd8b0f890 Update change to rem2html 2022-01-22 18:11:50 -05:00
Dianne Skoll
86873d0725 Use JSON::MaybeXS instead of JSON (courtesy of Ethan Rooke) 2022-01-22 18:09:02 -05:00
54 changed files with 4624 additions and 1953 deletions

3
.gitattributes vendored
View File

@@ -1,4 +1,5 @@
.gitignore export-ignore
.gitattributes export-ignore
remind.php export-ignore
sync-to-dianne-git export-ignore
sync-to-dianne-git export-ignore
php export-ignore

10
.gitignore vendored
View File

@@ -1,3 +1,4 @@
rem2pdf/Makefile.old
*.bak
*.o
*~
@@ -15,3 +16,12 @@ src/remind
src/version.h
tests/test.out
www/Makefile
rem2pdf/Makefile.PL
MYMETA.json
MYMETA.yml
Makefile
blib/
pm_to_blib
rem2pdf/Makefile.top
rem2pdf/bin/rem2pdf
rem2html/rem2html.1

View File

@@ -9,7 +9,7 @@ all: src/Makefile
@echo "*******************"
@echo ""
@cd src && $(MAKE) all LANGDEF=$(LANGDEF)
@$(MAKE) -C rem2pdf -f Makefile.top
install:
@echo ""
@echo "*********************"
@@ -20,16 +20,17 @@ install:
@echo ""
@$(MAKE) -C src install
@$(MAKE) -C rem2html install
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
clean:
find . -name '*~' -exec rm {} \;
cd src && $(MAKE) clean
-$(MAKE) -C src clean
-$(MAKE) -C rem2pdf clean
test:
@cd src && $(MAKE) -s test
@$(MAKE) -C src -s test
distclean: clean
rm -f config.cache config.log config.status src/Makefile src/config.h tests/test.out www/Makefile
rm -f config.cache config.log config.status src/Makefile src/config.h tests/test.out www/Makefile rem2pdf/Makefile.top rem2pdf/Makefile.old rem2pdf/Makefile rem2pdf/Makefile.PL rem2pdf/bin/rem2pdf
src/Makefile: src/Makefile.in
./configure

View File

@@ -27,16 +27,14 @@ proc SetConfigDefaults {} {
global Config
set Config(LAT_DEG) 45
set Config(LAT_MIN) 24
set Config(LAT_SEC) 14
set Config(LON_DEG) 75
set Config(LON_MIN) 39
set Config(LON_SEC) 23
set Config(LOCATION) "Ottawa"
set Config(DEFAULT_PAGE) "Letter"
set Config(DATESEP) "-"
set Config(TIMESEP) ":"
set Config(ISOLATIN1) 0
set Config(IBMEXTENDED) 0
set Config(ISOLATIN2) 0
set Config(IBM852) 0
set Config(NORTHERN_HEMISPHERE) 1
set Config(WESTERN_HEMISPHERE) 1
set Config(LANGUAGE) "English"
@@ -161,10 +159,14 @@ proc CreateLocationDialog { w } {
-from 0 -to 89 -length 300 -variable Config(LAT_DEG)
scale $w.latmin -label "Latitude (minutes)" -orient horizontal \
-from 0 -to 59 -length 300 -variable Config(LAT_MIN)
scale $w.latsec -label "Latitude (seconds)" -orient horizontal \
-from 0 -to 59 -length 300 -variable Config(LAT_SEC)
scale $w.londeg -label "Longitude (degrees)" -orient horizontal \
-from 0 -to 179 -length 300 -variable Config(LON_DEG)
scale $w.lonmin -label "Longtude (minutes)" -orient horizontal \
-from 0 -to 59 -length 300 -variable Config(LON_MIN)
scale $w.lonsec -label "Longitude (seconds)" -orient horizontal \
-from 0 -to 59 -length 300 -variable Config(LON_SEC)
radiobutton $w.north -text "Northern Hemisphere" \
-variable Config(NORTHERN_HEMISPHERE) -value 1
@@ -180,8 +182,10 @@ proc CreateLocationDialog { w } {
$w.location insert end $Config(LOCATION)
grid $w.latdeg -
grid $w.latmin -
grid $w.latsec -
grid $w.londeg -
grid $w.lonmin -
grid $w.lonsec -
grid $w.north $w.west
grid $w.south $w.east
@@ -233,19 +237,6 @@ proc CreateOptionsDialog { w } {
grid configure $w.timelabel -row 2 -column 0 -sticky e
grid configure $w.time -row 2 -column 1 -sticky nsew
label $w.charlabel -text "Character set: "
menubutton $w.char -text "ISO 8859-1" -indicatoron 1 -relief raised \
-menu $w.char.menu
menu $w.char.menu -tearoff 0
$w.char.menu add command -label "ISO 8859-1" -command "$w.char configure -text {ISO 8859-1}"
$w.char.menu add command -label "ISO 8859-2" -command "$w.char configure -text {ISO 8859-2}"
$w.char.menu add command -label "IBM Extended" -command "$w.char configure -text {IBM Extended}"
$w.char.menu add command -label "IBM CPI-852" -command "$w.char configure -text {ISO 8859-2}"
$w.char.menu add command -label "Plain ASCII" -command "$w.char configure -text {Plain ASCII}"
grid configure $w.charlabel -row 3 -column 0 -sticky e
grid configure $w.char -row 3 -column 1 -sticky nsew
label $w.langlabel -text "Language: "
menubutton $w.lang -text $Config(LANGUAGE) -indicatoron 1 -relief raised \
-menu $w.lang.menu
@@ -268,8 +259,8 @@ proc CreateOptionsDialog { w } {
$w.lang.menu add command -label $lang -command [list $w.lang configure -text $lang]
}
grid configure $w.langlabel -row 4 -column 0 -sticky e
grid configure $w.lang -row 4 -column 1 -sticky nsew
grid configure $w.langlabel -row 3 -column 0 -sticky e
grid configure $w.lang -row 3 -column 1 -sticky nsew
}
@@ -423,15 +414,19 @@ proc CreateCustomH {} {
# modify them willy-nilly
set LAT_DEG $Config(LAT_DEG)
set LAT_MIN $Config(LAT_MIN)
set LAT_SEC $Config(LAT_SEC)
set LON_DEG $Config(LON_DEG)
set LON_MIN $Config(LON_MIN)
set LON_SEC $Config(LON_SEC)
if {!$Config(NORTHERN_HEMISPHERE)} {
set LAT_DEG "-$LAT_DEG"
set LAT_MIN "-$LAT_MIN"
set LAT_SEC "-$LAT_SEC"
}
if {!$Config(WESTERN_HEMISPHERE)} {
set LON_DEG "-$LON_DEG"
set LON_MIN "-$LON_MIN"
set LON_SEC "-$LON_SEC"
}
set Config(LOCATION) [$Loc.location get]
@@ -446,38 +441,17 @@ proc CreateCustomH {} {
set Config(DATESEP) [$Options.date cget -text]
set Config(TIMESEP) [$Options.time cget -text]
switch -- [$Options.char cget -text] {
"ISO 8859-1" {
set Config(ISOLATIN1) 1
}
"ISO 8859-2" {
set Config(ISOLATIN2) 1
}
"IBM CPI-852" {
set Config(IBM852) 1
}
"IBM Extended" {
set Config(IBMEXTENDED) 1
}
}
while {[gets $in line] != -1} {
switch -glob -- $line {
"#define LAT_DEG *" {
puts $out "#define LAT_DEG $LAT_DEG"
.msgs insert end "#define LAT_DEG $LAT_DEG\n"
"#define DEFAULT_LATITUDE *" {
set lat [expr $LAT_DEG + ($LAT_MIN/60.0) + ($LAT_SEC/3600.0)];
puts $out "#define DEFAULT_LATITUDE $lat"
.msgs insert end "#define DEFAULT_LATITUDE $lat"
}
"#define LAT_MIN *" {
puts $out "#define LAT_MIN $LAT_MIN"
.msgs insert end "#define LAT_MIN $LAT_MIN\n"
}
"#define LON_DEG *" {
puts $out "#define LON_DEG $LON_DEG"
.msgs insert end "#define LON_DEG $LON_DEG\n"
}
"#define LON_MIN *" {
puts $out "#define LON_MIN $LON_MIN"
.msgs insert end "#define LON_MIN $LON_MIN\n"
"#define DEFAULT_LONGITUDE *" {
set lon [expr -1.0 * ($LON_DEG + ($LON_MIN/60.0) + ($LON_SEC/3600.0))]
puts $out "#define DEFAULT_LONGITUDE $lon"
.msgs insert end "#define DEFAULT_LONGITUDE $lon"
}
"#define LOCATION *" {
puts $out "#define LOCATION \"$Config(LOCATION)\""
@@ -495,22 +469,6 @@ proc CreateCustomH {} {
puts $out "#define TIMESEP '$Config(TIMESEP)'"
.msgs insert end "#define TIMESEP '$Config(TIMESEP)'\n"
}
"#define ISOLATIN1 *" {
puts $out "#define ISOLATIN1 $Config(ISOLATIN1)"
.msgs insert end "#define ISOLATIN1 $Config(ISOLATIN1)\n"
}
"#define ISOLATIN2 *" {
puts $out "#define ISOLATIN2 $Config(ISOLATIN2)"
.msgs insert end "#define ISOLATIN2 $Config(ISOLATIN2)\n"
}
"#define IBM852 *" {
puts $out "#define IBM852 $Config(IBM852)"
.msgs insert end "#define IBM852 $Config(IBM852)\n"
}
"#define IBMEXTENDED *" {
puts $out "#define IBMEXTENDED $Config(IBMEXTENDED)"
.msgs insert end "#define IBMEXTENDED $Config(IBMEXTENDED)\n"
}
default {
puts $out $line
}
@@ -806,14 +764,17 @@ proc SetConfigFromRemind {} {
# Query Remind for the rest
QueryRemind $rem LAT_DEG {$LatDeg}
QueryRemind $rem LAT_MIN {$LatMin}
QueryRemind $rem LAT_SEC {$LatSec}
QueryRemind $rem LON_DEG {$LongDeg}
QueryRemind $rem LON_MIN {$LongMin}
QueryRemind $rem LON_SEC {$LongSec}
QueryRemind $rem LOCATION {$Location}
QueryRemind $rem DATESEP {$DateSep}
QueryRemind $rem TIMESEP {$TimeSep}
QueryRemind $rem LANGUAGE {language()}
set $Config(LAT_MIN) [expr abs($Config(LAT_MIN))]
set $Config(LAT_SEC) [expr abs($Config(LAT_SEC))]
if {$Config(LAT_DEG) >= 0} {
set Config(NORTHERN_HEMISPHERE) 1
} else {
@@ -822,6 +783,7 @@ proc SetConfigFromRemind {} {
}
set $Config(LON_MIN) [expr abs($Config(LON_MIN))]
set $Config(LON_SEC) [expr abs($Config(LON_SEC))]
if {$Config(LON_DEG) >= 0} {
set Config(WESTERN_HEMISPHERE) 1
} else {

67
configure vendored
View File

@@ -622,6 +622,7 @@ ac_includes_default="\
ac_header_list=
ac_subst_vars='LTLIBOBJS
LIBOBJS
PERLARTIFACTS
VERSION
EGREP
GREP
@@ -681,6 +682,7 @@ SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
enable_perl_build_artifacts
'
ac_precious_vars='build_alias
host_alias
@@ -1305,6 +1307,13 @@ if test -n "$ac_init_help"; then
cat <<\_ACEOF
Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-perl-build-artifacts
Disable perllocal.pod and .packlist generation
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
@@ -2292,6 +2301,16 @@ EOF
ac_config_headers="$ac_config_headers src/config.h"
# Check whether --enable-perl-build-artifacts was given.
if test "${enable_perl_build_artifacts+set}" = set; then :
enableval=$enable_perl_build_artifacts; ac_cv_perlartifacts=$enableval
else
ac_cv_perlartifacts=yes
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3731,39 +3750,6 @@ fi
done
# The cast to long int works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
# This bug is HP SR number 8606223364.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned short" >&5
$as_echo_n "checking size of unsigned short... " >&6; }
if ${ac_cv_sizeof_unsigned_short+:} false; then :
$as_echo_n "(cached) " >&6
else
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned short))" "ac_cv_sizeof_unsigned_short" "$ac_includes_default"; then :
else
if test "$ac_cv_type_unsigned_short" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "cannot compute sizeof (unsigned short)
See \`config.log' for more details" "$LINENO" 5; }
else
ac_cv_sizeof_unsigned_short=0
fi
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_short" >&5
$as_echo "$ac_cv_sizeof_unsigned_short" >&6; }
cat >>confdefs.h <<_ACEOF
#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short
_ACEOF
# The cast to long int works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
@@ -3990,6 +3976,12 @@ if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
fi
if test "$ac_cv_perlartifacts" = "yes" ; then
PERLARTIFACTS=
else
PERLARTIFACTS='NO_PACKLIST=1 NO_PERLLOCAL=1'
fi
for ac_func in setenv unsetenv glob mbstowcs setlocale initgroups
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
@@ -4002,10 +3994,11 @@ _ACEOF
fi
done
VERSION=03.03.12
VERSION=03.04.02
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h rem2html/Makefile"
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -4702,6 +4695,9 @@ do
"www/Makefile") CONFIG_FILES="$CONFIG_FILES www/Makefile" ;;
"src/version.h") CONFIG_FILES="$CONFIG_FILES src/version.h" ;;
"rem2html/Makefile") CONFIG_FILES="$CONFIG_FILES rem2html/Makefile" ;;
"rem2pdf/Makefile.PL") CONFIG_FILES="$CONFIG_FILES rem2pdf/Makefile.PL" ;;
"rem2pdf/Makefile.top") CONFIG_FILES="$CONFIG_FILES rem2pdf/Makefile.top" ;;
"rem2pdf/bin/rem2pdf") CONFIG_FILES="$CONFIG_FILES rem2pdf/bin/rem2pdf" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
@@ -5288,3 +5284,4 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
chmod a+x rem2pdf/bin/rem2pdf

View File

@@ -14,6 +14,12 @@ EOF
AC_CONFIG_HEADER(src/config.h)
AC_ARG_ENABLE(perl-build-artifacts,
[ --disable-perl-build-artifacts
Disable perllocal.pod and .packlist generation], ac_cv_perlartifacts=$enableval, ac_cv_perlartifacts=yes)
AH_BOTTOM([#include <custom.h>])
dnl Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
@@ -27,7 +33,6 @@ dnl Replace `main' with a function in -lm:
AC_CHECK_LIB(m, sqrt)
dnl Integer sizes
AC_CHECK_SIZEOF(unsigned short)
AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
@@ -45,8 +50,16 @@ if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
fi
if test "$ac_cv_perlartifacts" = "yes" ; then
PERLARTIFACTS=
else
PERLARTIFACTS='NO_PACKLIST=1 NO_PERLLOCAL=1'
fi
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups)
VERSION=03.03.12
VERSION=03.04.02
AC_SUBST(VERSION)
AC_SUBST(PERL)
AC_OUTPUT(src/Makefile www/Makefile src/version.h rem2html/Makefile)
AC_SUBST(PERLARTIFACTS)
AC_OUTPUT(src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf)
chmod a+x rem2pdf/bin/rem2pdf

View File

@@ -69,6 +69,8 @@ know! Here are the basic guidelines:
- You can test your language file with the script "tests/tstlang.rem"
- Your localized strings must be encoded using UTF-8.
RELEASE NOTES -- miscellaneous info that couldn't go anywhere else!
1. POPUP REMINDERS

View File

@@ -1,6 +1,147 @@
CHANGES TO REMIND
* VERSION 3.3 Patch 12 - 2022-??-??
* VERSION 3.4 Patch 2 - 2022-??-??
- NEW FEATURE: remind: Add syntactic sugar to simplify some common
types of reminders. See "SYNTACTIC SUGAR FOR REM" in the remind
man page. Based on suggestions from Ian! D. Allen.
- NEW FEATURE: remind: Add the "trig" function to allow more
expressiveness when creating triggers. See man page for details.
- IMPROVEMENT: tkremind: Tweak the calendar display; improve ability to
customize colors, including supplying two built-in themes. Based on
patch and suggestion from Paulo (last name unknown).
- CHANGE: remind: Increase $MaxSatIter default to 1000 instead of 150.
Computers are much faster than when I first wrote remind and they
can handle this higher limit easily. The higher limit also enables
certain reasonable reminders that failed in the past because of the
low SATISFY iteration limit.
- CHANGE: remind: The "||" operator now returns the value of the first
non-zero operand rather than just returning 1 or 0. Similarly, "&&"
returns 0 if either operand is false or the value of the last
operand if both operands are true.
NOTE POTENTIAL INCOMPATIBILITY: Remind scripts that depend on ||
and && always returning exactly one of 1 or 0 may need
adjustment.
- CHANGE: The || and && operators can accept any non-STRING type as long
as both operands have the same type. The "false" values are defined
as follows; true values are any other value:
INT: 0
TIME: 00:00
DATE: '1990-01-01' (the Remind epoch)
DATETIME: '1990-01-01@00:00' (the Remind epoch)
- IMPROVEMENT: remind: Issue diagnostics if an UNTIL or THROUGH date
is earlier than any possible trigger date, as well as an UNTIL date
with a fully-specified date and no repeat ("*N"). Suggestion from
Ian! D. Allen.
- BUG FIX: tkremind: If the same moon phase appeared twice in a month,
TkRemind would not display the first occurrence correctly. This has
been fixed.
- BUG FIX: remind: The IF command documentation didn't reflect how it
actually worked; now it does.
- BUG FIX: remind: Use correct UNTIL/THROUGH keyword in error message.
- BUG FIX: rem2pdf: Correct the calculation that warns about an over-full
calendar box. Problem noted by Jonathan Kamens.
* VERSION 3.4 Patch 1 - 2022-02-23
- MINOR IMPROVEMENT: Support the INSTALL_BASE environment variable for
installing rem2pdf in a non-standard location like your home directory.
This is passed in to rem2pdf's Makefile at build and install time.
- MINOR IMPROVEMENT: ./configure: Add --disable-perl-build-artifacts flag
to avoid installation of perllocal.pod and .packlist files.
- BUG FIX: tkremind: If the system date rolls over, update the display
to correctly highlight the current date. This worked in older versions
of Remind, but was broken by 03.04.00.
- BUG FIX: rem2pdf: The small calendar font would sometimes be scaled
incorrectly so the small calendar overflowed the box. This has been
fixed.
* VERSION 3.4 Patch 0 - 2022-02-10
- MAJOR CHANGE: Remind and its helpers (except for rem2ps) fully support
UTF-8. If your system locale is a UTF-8 locale and your terminal
can handle UTF-8 encoding, you can enjoy full Unicode support in Remind.
- NEW FEATURE: Added a rem2pdf Remind-to-PDF converter. It can handle
the full UTF-8 character set and features a new PANGO special reminder
type that lets you format the text in the PDF calendar (by changing the
font size, color, underlining, etc.)
rem2pdf requires the Pango and Cairo Perl modules. On Debian or
Debian-derived systems, these may be installed with:
apt install libpango-perl libcairo-perl
Unlike rem2ps, the default font in rem2pdf is "Sans" rather than
"Helvetica", as Sans seems to be typeset better by the Pango library.
- NEW FEATURE: remind: New system variables $Sunday through $Saturday
and $January through $December let you set weekday and month names
to whatever you like, permitting you to produce calendars in your
local language, even if it's not one of the languages Remind supports
by default.
- NEW FEATURE: tkremind: If rem2pdf installed, TkRemind offers you the
choice of PDF or PostScript output in the Print dialog.
- CHANGE: remind: Increase the number of allowed "full OMITs" from 500
to 1000.
- CHANGE: Remove the annoying code that slowed compilation and running
on Windows and Mac OS X. I believe the point has been made and free
OSes have enough of a critical mass that the annoyances are
counter-productive.
- CLEANUP: remind: C source code: Replace the LAT_DEG, LAT_MIN,
LAT_SEC and LON_DEG, LON_MIN, LON_SEC macros with DEFAULT_LATITUDE
and DEFAULT_LONGITUDE.
- CLEANUP: remind: C source code: Remove various unused or obsolete macros.
- BUG FIXES: Minor fixups to groff source and Makefiles courtesy of
Jochen Sprickerhof.
- BUG FIX: Properly support formatting of double-wide characters in the
terminal mode "remind -c" calendar.
- BUG FIX: rem2html: Document how to highlight today with a red border
- BUG FIX: rem2html: Generate and install a man page for rem2html
- BUG FIX: remind: Get rid of LAT_DEG/LAT_MIN/LAT_SEC and
LON_DEG/LON_MIN/LON_SEC macros in favour of DEFAULT_LATITUDE and
DEFAULT_LONGITUDE.
- IMPROVEMENT: All localized languages now use UTF-8 exclusively.
Support for old character encodings like ISO-8859-1 and ISO-8859-2
has been dropped since modern UNIXes have pretty much standardized
on UTF-8.
- CHANGE: remind: Non-English versions of remind *no longer* accept
non-English month- and weekday-names in trigger specifications. This
was a misfeature. NOTE INCOMPATIBILITY.
* VERSION 3.3 Patch 12 - 2022-01-24
- UPDATE: rem2html: Use JSON::MaybeXS instead of JSON::Any, since JSON::Any
is deprecated. NOTE INCOMPATIBILITY: If you don't have JSON::MaybeXS
installed, you'll need to install it before trying to install or update
rem2html
- NEW FEATURE: Add a DO command. This is just like INCLUDE, but relative
paths are interpreted relative to the directory containing the current
@@ -19,6 +160,15 @@ CHANGES TO REMIND
- IMPROVEMENT: TkRemind: Store .tkremindrc in $XDG_CONFIG_HOME/tkremindrc
or $HOME/.config/tkremindrc as per the XDG Base Directory Specification.
- BUG FIX: remind: Make the shell() built-in function respect
$MaxStringLen
- BUG FIX: Use size_t to track the size of dynamic buffers rather than int.
This permits Remind to read in files with lines longer than 1GB and to
consume more than 1GB of output from the shell() command, both of which
will surely be massively useful. (The old limit was 1GB rather than 2GB
because of details of the dynamic buffer resizing algorithm.)
* VERSION 3.3 Patch 11 - 2021-12-30
- IMPROVEMENT: TkRemind: Save the print dialog settings so they persist.

View File

@@ -12,6 +12,10 @@ emits PostScript code (which draws a calendar) to the standard output.
See the section "Rem2PS Input Format" for details about the \fB\-p\fR
data. This may be useful if you wish to create other \fBRemind\fR
back-ends.
.PP
Note that \fBRem2PS\fR does not handle UTF-8 input. If you need to
render characters outside the ASCII character set, see
\fBrem2pdf\fR instead.
.SH OPTIONS
.TP
@@ -61,7 +65,9 @@ there is room and otherwise follows \fIn\fR=2 yields the same results as
.TP
.B \-i
Use ISO 8859-1 standard encoding for the PostScript fonts. If you do
not use this option, the default encoding is used.
not use this option, the default encoding is used. If you use this option,
you probably also need to convert Remind's output (typically UTF-8)
to ISO-8859-1 using \fBiconv\fR(1).
.TP
.B \-e
Make the calendar fill the entire page. By default, the calendar is
@@ -340,6 +346,10 @@ month (0 = Sunday, 1 = Monday, 6 = Saturday.) And \fImonday_first\fR is
1 if the \fB\-m\fR flag was supplied to \fBRemind\fR, or 0 if it was not.
All this information is supplied so back-ends don't need any date calculation
facilities.
Note that all spaces in \fImonth_name\fR will be replaced with
underscores. Back-ends should undo this replacement.
.TP
\fIsun mon tue wed thu fri sat\fR
This line consists of
@@ -347,6 +357,9 @@ space-separated names of days in whatever language \fBRemind\fR was
compiled for. This information can be used by back-ends to annotate
calendars, and means they don't have to be created for a specific
language.
Note that all spaces in day names will be replaced with
underscores. Back-ends should undo this replacement.
.TP
\fInext_mon next_days\fR
The name of the next month and the number of days in it.
@@ -662,4 +675,5 @@ You should ensure that the values you supply for margin widths are sensible.
If they are too big for the media size, \fBRem2ps\fR will not complain,
but again, the PostScript output will probably not work.
.SH SEE ALSO
\fBremind\fR
\fBremind\fR, \fBrem2pdf\fR, \fBrem2html\fR, \fBtkremind\fR.

View File

@@ -267,7 +267,7 @@ calendar output.
.TP
\fB\-x\fR[\fIn\fR]
Sets the iteration limit for the \fBSATISFY\fR clause of a \fBREM\fR
command. Defaults to 150.
command. Defaults to 1000.
.TP
\fB\-k\fR\fIcmd\fR
Instead of simply printing \fBMSG\fR-type
@@ -814,7 +814,8 @@ could be specified as:
However, events that do not repeat daily, weekly, monthly or yearly require
another approach. The \fIrepeat\fR component of the \fBREM\fR command
fills this need. To use it, you must completely specify a date (year, month
and day, and optionally weekday.) The \fIrepeat\fR component is an asterisk
and day, and optionally weekday); this is the start date of the
repetition period. The \fIrepeat\fR component is an asterisk
followed by a number specifying the repetition period in days.
.PP
For example, suppose you get paid every second Wednesday, and your
@@ -824,12 +825,12 @@ last payday was Wednesday, 28 October, 1992. You can use:
REM 28 Oct 1992 *14 MSG Payday
.fi
.PP
This issues the reminder every 14 days, starting from the calculated trigger
date. You can use \fIdelta\fR and \fIback\fR with \fIrepeat.\fR Note,
however, that the \fIback\fR is used only to compute the initial
trigger date; thereafter, the reminder repeats with the specified
This issues the reminder every 14 days, starting from 28 Oct 1992.
You can use \fIdelta\fR and \fIback\fR with \fIrepeat.\fR Note,
however, that the \fIback\fR is used only to compute the starting
date; thereafter, the reminder repeats with the specified
period. Similarly, if you specify a weekday, it is used only to calculate
the initial date, and does not affect the repetition period.
the starting date, and does not affect the repetition period.
.PP
.B SCANFROM \fRand\fB FROM
.PP
@@ -1152,6 +1153,84 @@ Note that \fIduration\fR is specified either in hours and minutes as a
duration of 00:00 or 0, then \fBRemind\fR behaves exactly as if no
\fBDURATION\fR at all had been present.
.PP
.SH SYNTACTIC SUGAR FOR REM
.PP
The REM command has syntactic sugar to let you express common
reminders. The following pairs of reminders are equivalent:
.PP
.nf
REM First Monday April MSG Foo
REM Mon 1 April MSG Foo
REM Second Monday May MSG Bar
REM Mon 8 May MSG Bar
REM Third Monday MSG Third Monday of every month
REM Mon 15 MSG Third Monday of every month
REM Fourth Sunday June 2025 MSG Fourth Sunday in June 2025
REM Sun 22 June 2025 MSG Fourth Sunday in June 2025
REM Last Monday MSG Last Monday of every month
REM Mon 1 --7 MSG Last Monday of every month
REM Last Monday April MSG Last Monday of every April
REM Mon 1 May --7 MSG Last Monday of every April
REM Last Monday December 2025 MSG Last Monday of Dec 2025
REM Monday 1 Jan 2026 --7 MSG Last Monday of Dec 2025
.fi
.PP
Note that \fBLast\fR effectively adjusts the month and year, if necessary, to
make the reminder trigger on the correct date.
.PP
The keyword \fBIN\fR is completely ignored, so you can write (for example):
.PP
.nf
REM Second Monday in May MSG foo
REM Last Monday in December 2025 MSG Bar
.fi
.PP
An alternate form of \fIback\fR makes writing reminders easier.
The following groups of reminders are equivalent:
.PP
.nf
REM ~~1 MSG Last day of every month
REM Lastday MSG Last day of every month
REM 1 --1 MSG Last day of every month
REM May ~~1 MSG Last day of May
REM Lastday May MSG Last day of May
REM 1 June --1 MSG Last day of May
REM Dec 2025 ~~1 MSG Last day of December 2025
REM Lastday Dec 2025 MSG Last day of December 2025
REM 1 Jan 2026 --1 MSG Last day of December 2025
REM Apr ~1 OMIT SAT SUN MSG Last workday of April
REM Lastworkday April OMIT SAT SUN MSG Last workday of April
REM 1 May -1 OMIT SAT SUN MSG Last workday of April
REM Apr ~~7 MSG Seventh-last day of April
REM 1 May --7 MSG Seventh-last day of April
REM Apr ~2 OMIT SAT SUN MSG Second-last workday of April
REM 1 May -2 OMIT SAT SUN MSG Second-last workday of April
.fi
.PP
As we see, "Lastday" is equivalent to ~~1 and "Lastworkday" to ~1.
.PP
Note that the First/Second/Third/Fourth/Last keywords and the ~ and ~~ form
of \fIback\fR imply a value for the day of the month; as such, they cannot
be combined with a day. Additionally, First/Second/Third/Fourth/Last
must have at least one weekday name. The following are illegal:
.PP
.nf
REM First Monday 3 June MSG Huh?
REM April 3 ~~1 MSG What?
REM Second June MSG Where's the weekday???
.fi
.PP
.SH THE SUBSTITUTION FILTER
.PP
@@ -1395,6 +1474,12 @@ the same as substitutions built up from the simpler %w, %y, etc.
sequences.
.TP
o
The a, c, e, f, g, h, i, j, k, l, u, v, 2, and 3 substitutions may
be preceded by an asterisk (for example, %*c) which causes the word
"at" or "on" that would normally be included in the output to be
omitted.
.TP
o
Any of the substitutions dealing with time (0 through 9 and '!')
produce undefined results if used in a reminder that does not have
an \fBAT\fR keyword. Also, if a reminder has a \fIdelta\fR and may
@@ -1822,7 +1907,7 @@ quotes \fImust\fR be supplied. This distinguishes date constants
from division or subtraction of integers. Examples:
.PP
.RS
\'1993/02/22', '1992-12-25', '1999/01/01'
\(aq1993/02/22', '1992-12-25', '1999/01/01'
.PP
Note that \fBDATE\fR values are \fIprinted\fR
without the quotes. Although either '-' or '/' is accepted as a date
@@ -1840,13 +1925,33 @@ constants with the addition of an "@HH:MM" part, optionally followed
by "am" or "pm". For example:
.PP
.RS
\'2008-04-05@23:11', '1999/02/03@14:06', '2001-04-07@08:30', '2020-01-01@3:20pm'
\(aq2008-04-05@23:11', '1999/02/03@14:06', '2001-04-07@08:30', '2020-01-01@3:20pm'
.PP
\fBDATETIME\fR values are printed without the quotes. Notes about date
and time separator characters for \fBDATE\fR and \fBTIME\fR constants apply
also to \fBDATETIME\fR constants.
.RE
.PP
.B ZERO VALUES
.PP
The non-string types all have an associated \fIzero\fR value, which is
treated as "false" by the IF command and the logical operators. The
zero values are:
.PP
.RS
.PP
\fBINT\fR - 0
.PP
\fBDATE\fR - '1990-01-01'
.PP
\fBTIME\fR - 00:00
.PP
\fBDATETIME\fR - '1990-01-01@00:00'
.RE
.PP
Additionally, for the purpose of the IF command (but \fInot\fR the
logical operators) the empty string "" is considered a false value.
.PP
.B OPERATORS
.PP
\fBRemind\fR has the following operators. Operators on the same line
@@ -1970,14 +2075,16 @@ If the operands are not of the same type, == returns 0 and != returns
.RE
.TP
.B &&
This is the logical AND operator. Both of its operands must be of
type \fBINT\fR. It returns 1 if both operands are non-zero, and 0
otherwise.
This is the logical AND operator. Both of its operands must be of the
same type and must not be \fBSTRING\fR type. Returns the second
operand if both operands are non-zero. Otherwise, returns a zero
of the same type as the operands.
.TP
.B ||
This is the logical OR operator. Both of its operands must be of
type \fBINT\fR. It returns 1 if either operand is non-zero, and 0
otherwise.
the same type and must not be of \fBSTRING\fR type. It returns
the first operand that is non-zero; if both operands are zero, then
returns a zero of the same type as the operands.
.PP
.B NOTES
.PP
@@ -2260,7 +2367,9 @@ The maximum number of iterations for the \fBSATISFY\fR clause
.TP
.B $MaxStringLen
A limit on the longest string that \fBRemind\fR will allow you
to create. The default is 65535.
to create. The default is 65535. If you set \fB$MaxStringLen\fR to 0
or to -1, then \fBremind\fR will allow you to create arbitrarily-long
strings, at least until it runs out of memory.
.TP
.B $MinsFromUTC
The number of minutes between Universal Time Coordinated and local time. If
@@ -2410,7 +2519,7 @@ Returns the time of "astronomical twilight" on the specified \fIdate\fR. If
.TP
.B ampm(tq_time [,s_am [,s_pm]])
Returns a \fBSTRING\fR that is the result of converting \fItime\fR
(which is either a \fBTIME\R or a \fBDATETIME\fR object) to "AM/PM"
(which is either a \fBTIME\fR or a \fBDATETIME\fR object) to "AM/PM"
format. The optional arguments \fIam\fR and \fIpm\fR are the strings
to append in the AM and PM case, respectively; they default to "AM"
and "PM". The function obeys the system variables $DateSep,
@@ -2744,7 +2853,7 @@ clauses are \fInot\fR taken into account by this function.
.TP
.B language()
Returns a \fBSTRING\fR naming the language supported by \fBRemind\fR.
(See "Foreign Language Support.") By default, \fBRemind\fR is compiled
(See "SUPPORT FOR OTHER LANGUAGES") By default, \fBRemind\fR is compiled
to support English messages, so this function returns "English". For
other languages, this function will return the English name of the
language (e.g. "German") Note that \fBlanguage()\fR is not available
@@ -3015,8 +3124,8 @@ not be executed.
.PP
If \fImaxlen\fR is specified, then \fBshell()\fR returns the first
\fImaxlen\fR characters of output (rather than the first 511). If
\fImaxlen\fR is specified as a negative number, then \fIall\fR the
output from \fIcmd\fR is returned.
\fImaxlen\fR is specified as a negative number, then it defaults to
the value of the system variable \fB$MaxStringLen\fR.
.RE
.TP
.B shellescape(s_str)
@@ -3062,7 +3171,8 @@ takes \fIa\fR back to 2009-05-13.
.RE
.TP
.B strlen(s_str)
Returns the length of \fIstr\fR.
Returns the length of \fIstr\fR. If the length of \fIstr\fR is too large
to represent as an integers, emits a "Number too high" error.
.TP
.B substr(s_str, i_start [,i_end])
Returns a \fBSTRING\fR consisting of all characters in \fIstr\fR from
@@ -3107,6 +3217,114 @@ Returns \fBRemind\fR's notion of "today." This may be the actual system
date, or a date supplied on the command line, or the date of the
calendar entry currently being computed.
.TP
.B trig(s_1 [,s_2, ...])
For each string argument s_\fIn\fR, \fBtrig\fR evaluates s_\fIn\fR
as if it were a REM or IFTRIG trigger
specification. If the trigger would trigger today, then the trigger
date is returned and no further triggers are evaluated. If none
of the triggers would trigger today, then the zero date
1990-01-01 is returned.
.RS
\fBtrig\fR also has a zero-argument form; this returns the trigger
date of the \fImost recent\fR \fBtrig\fR function that returned a
non-zero trigger date.
.PP
\fBtrig\fR can be used to make more sophisticated versions of
\fBIFTRIG\fR. For example, if you have meetings every Monday in
June and July, and you want warnings 3 days in advance, you
could use:
.nf
REM [trig("Mon Jun +3", "Mon July +3")] +3 MSG Meeting %b
.fi
.PP
NOTE: We need to repeat the +3 delta outside of the \fBtrig\fR
function for advance warning to work properly. This is because
\fBtrig\fR returns a date constant (the trigger date) and the
REM command does not know the details of \fBtrig\fR's arguments.
.PP
Note that because \fBRemind\fR does not have short-circuit logical
operators, something like:
.PP
.nf
SET a trig("Mon +7") || trig("Fri +7")
.fi
would set the value of trig() to the date of the following
Thursday. Even though trig("Mon +7") always returns true,
the logical-OR operator still evaluates trig("Fri +7") which
\fIalso\fR returns true and sets \fBtrig()\fR.
.PP
You can work around the lack of a short-circuit logical-OR as follows:
If \fBtrig\fR returns a true value, the specific value it returns
can be coerced to a DATE which is the trigger date. So the following code:
.PP
.nf
SET a trig("Mon +4") || trig("Fri +4")
IF a
REM [a] +4 MSG [wkday($T)] %b.
ENDIF
.fi
.PP
would operate as follows:
.PP
.nf
On Monday: Monday today.
On Tuesday: Friday in 3 days' time.
On Wednesday: Friday in 2 days' time.
On Thursday: Monday in 4 days' time.
On Friday: Monday in 3 days' time.
On Saturday: Monday in 2 days' time.
On Sunday: Monday tomorrow.
.fi
.PP
Compare with the following:
.PP
.nf
SET a trig("Mon +4") || trig("Fri +4")
IF a
REM [trig()] +4 MSG [wkday($T)] %b.
ENDIF
.fi
.PP
which yields:
.PP
.nf
On Monday: Friday in 4 days' time.
On Tuesday: Friday in 3 days' time.
On Wednesday: Friday in 2 days' time.
On Thursday: Friday tomorrow.
On Friday: Friday today.
On Saturday: Monday in 2 days' time.
On Sunday: Monday tomorrow.
.fi
.PP
That is because \fBtrig()\fR returns the trigger date of
the \fIlast\fR trig function that returns true,
whereas the value of \fBa\fR is the trigger date of the \fIfirst\fR
trig function that returns true.
.PP
\fBImportant Note\fR: Because \fBtrig()\fR always returns an absolute
date, it will \fBnot\fR work properly with a \fBSATISFY\fR clause.
Consider this reminder:
.PP
.nf
REM [trig("Mar", "Apr")] SATISFY [$Td == 15] MSG 15 Mar or April
.fi
.PP
If we run \fBRemind\fR on 5 March 2022, we might expect the trigger
date to be calculated as 15 March 2022... but that's not what happens.
Instead, the \fBtrig\fR function is evaluated first, and it returns
2022-03-05. So as far as \fBRemind\fR is concerned, the REM statement
becomes:
.PP
.nf
REM 2022-03-05 SATISFY [$Td == 15] MSG 15 Mar or April
.fi
.PP
and the SATISFY expression is never true. So: \fIDo not mix
trig() and SATISFY\fR.
.RE
.TP
.B trigdate()
Returns the calculated trigger date of the last \fBREM\fR
or \fBIFTRIG\fR command. If used
@@ -3188,18 +3406,17 @@ Returns (as a \fBDATE\fR type) the \fBFROM\fR parameter of the last \fBREM\fR or
.TP
.B trigger(d_date [,t_time [,i_utcflag]]) \fRor\fB trigger(q_datetime [,i_utcflag])
Returns a string suitable for use in a \fBREM\fR command or a \fBSCANFROM\fR
or UNTIL clause, allowing you to calculate trigger dates in advance.
Note that in earlier versions of \fBRemind\fR, \fBtrigger\fR was
required to convert a date into something the \fBREM\fR command could
consume. However, in this version of \fBRemind\fR, you can omit it.
Note that \fBtrigger()\fR \fIalways\fR returns its result in English,
even for foreign-language versions of \fBRemind\fR. This is to avoid
problems with certain C libraries that do not handle accented
characters properly. Normally, the \fIdate\fR and \fItime\fR are the
local date and time; however, if \fIutcflag\fR is non-zero, the
\fIdate\fR and \fItime\fR are interpreted as UTC times, and are
converted to local time. Examples:
Returns a string suitable for use in a \fBREM\fR command or a
\fBSCANFROM\fR or UNTIL clause, allowing you to calculate trigger
dates in advance. Note that in earlier versions of \fBRemind\fR,
\fBtrigger\fR was required to convert a date into something the
\fBREM\fR command could consume. However, in this version of
\fBRemind\fR, you can omit it. Note that \fBtrigger()\fR \fIalways\fR
returns its result in English, even for non-English versions of
\fBRemind\fR. Normally, the \fIdate\fR and \fItime\fR are the local
date and time; however, if \fIutcflag\fR is non-zero, the \fIdate\fR
and \fItime\fR are interpreted as UTC times, and are converted to
local time. Examples:
.RS
.PP
trigger('1993/04/01')
@@ -3524,12 +3741,12 @@ Note that the commands are shown indented for clarity. Also, the \fBELSE\fR
portion can be omitted. \fBIF\fR commands can be nested up to a small limit,
probably around 8 or 16 levels of nesting, depending on your system.
.PP
If the \fIexpr\fR evaluates to a non-zero \fBINT\fR, or a non-null
\fBSTRING\fR, then the \fBIF\fR portion is considered true, and the
\fIt-commands\fR are executed. If \fIexpr\fR evaluates to zero or
null, then the \fIf-commands\fR (if the \fBELSE\fR portion is present)
are executed. If \fIexpr\fR is not of type \fBINT\fR or \fBSTRING\fR,
then it is an error.
If the \fIexpr\fR evaluates to a non-zero \fBINT\fR, a \fBDATE\fR that
is not 1990-01-01, a \fBTIME\fR that is not 00:00, a \fBDATETIME\fR
that is not 1990-01-01@00:00, or a non-null \fBSTRING\fR, then the
\fBIF\fR portion is considered true, and the \fIt-commands\fR are
executed. If \fIexpr\fR evaluates to zero or null, then the
\fIf-commands\fR (if the \fBELSE\fR portion is present) are executed.
.PP
Examples:
.PP
@@ -4448,23 +4665,42 @@ error messages. For an example of this, define the following:
fset msgprefix(x) x/0
.fi
.PP
.SH FOREIGN LANGUAGE SUPPORT
.SH SUPPORT FOR OTHER LANGUAGES
.PP
Your version of \fBRemind\fR may have been compiled to support a
language other than English. This support may or may not be complete -
for example, all error and usage messages may still be in English.
However, at a minimum, foreign-language versions of \fBRemind\fR will
output names of months and weekdays in the foreign language. Also,
However, at a minimum, non-English versions of \fBRemind\fR will
output names of months and weekdays in the selected language. Also,
the substitution mechanism will substitute constructs suitable for the
foreign language rather than for English.
selected language rather than for English.
.PP
A foreign-language version of \fBRemind\fR will accept either the English
or foreign-language names of weekdays and months in a reminder script.
However, for compatibility between versions of \fBRemind\fR, you should
use only the English names in your scripts. Also, if your C compiler or
run-time libraries are not "8-bit clean" or don't understand the ISO-Latin
character set, month or day names with accented letters may not be
recognized.
Note that a non-English version of \fBRemind\fR will accept \fIonly\fR
English names of weekdays and months in a reminder script.
.PP
If there is no support for your particular language, you can set
\fBRemind\fR system variables so that calendars are printed using
your language's day and month names. The system variables that you
can set are:
.PP
.TP
.B $Monday, $Tuesday, $Wednesday, $Thursday, $Friday, $Saturday
Set each of these system variables to a string representing the corresponding
day's name in your language. Strings must be valid UTF-8 strings.
.TP
.B $January, $February, $March, $April, $May, $June, $July, $August, $September, $October, $November, $December
Set each of these system variables to a string representing the corresponding
month's name in your language. Strings must be valid UTF-8 strings.
.PP
Note that if you set the day- or month-name system variables, they
should be set in a section of your script that always is evaluated.
If you set them inside an \fBIF\fR statement, for example, results
are unpredictable.
.PP
Note also that the \fBRem2PS\fR back-end does not support the full
range of UTF-8 characters. The \fBTkRemind\fR, \fBrem2html\fR and
\fBrem2pdf\fR back-ends all do support the full UTF-8 range.
.PP
.SH THE HEBREW CALENDAR
.PP
@@ -4954,7 +5190,7 @@ was copied largely unmodified from "moontool" by John Walker. The
sunrise and sunset functions use ideas from programs by Michael
Schwartz and Marc T. Kaufman. The Hebrew calendar support was taken
from "hdate" by Amos Shapir. OS/2 support was done by Darrel
Hankerson, Russ Herman, and Norman Walsh. The supported foreign
Hankerson, Russ Herman, and Norman Walsh. The supported
languages and their translators are listed below. Languages marked
"complete" support error messages and usage instructions in that
language; all others only support the substitution filter mechanism
@@ -5023,4 +5259,5 @@ Catalog\fR, Jewish Publication Society of America.
.PP
.SH SEE ALSO
.PP
rem, rem2ps, tkremind
\fBrem\fR(1), \fBrem2ps\fR(1), \fBrem2pdf\fR(1), \fBtkremind\fR(1), \fBrem2html\fR(1)

View File

@@ -115,6 +115,8 @@ edit the reminder, thereby gaining access to advanced features of
To print the current month's calendar, click \fBPrint...\fR on the
main calendar window. This brings up the print dialog. Printing
either produces a PostScript file or sends PostScript to a UNIX command.
(If you have \fBrem2pdf\fR installed, you can choose to produce
PDF output rather than PostScript.)
Select the print destination by choosing either \fBTo file:\fR or
\fBTo command:\fR in the print dialog. Press \fBBrowse...\fR to bring
@@ -131,12 +133,13 @@ the directory.
Select the appropriate paper size and orientation. Activate
\fBFill page\fR if you want the calendar to fill the page. This should
be the normal case unless you have many reminders in a particular
day. (See the \fBRem2PS\fR documentation.)
day. (See the \fBRem2PS\fR or \fBrem2pdf\fR documentation.)
Finally, click \fBPrint\fR to print or \fBCancel\fR to cancel. Note
that during printing, \fBRemind\fR is called with the
\fB-itkremind=1\fR option and also an additional \fB-itkprint=1\fR
option.
option. If you are producing PDF output, then the option \fB-itkpdf=1\fR
is also supplied to \fBRemind\fR.
.SH EDITING REMINDERS
@@ -399,4 +402,5 @@ $HOME/.reminders -- default reminder file.
$HOME/.tkremindrc -- \fBTkRemind\fR saved options.
.SH SEE ALSO
remind, rem2ps
\fBremind\fR, \fBrem2ps\fR, \fBrem2pdf\fR, \fBrem2html\fR

View File

@@ -7,7 +7,7 @@ bindir=@bindir@
datadir=@datadir@
datarootdir=@datarootdir@
PERL=@PERL@
PERLMODS_NEEDED=JSON::Any Getopt::Long
PERLMODS_NEEDED=JSON::MaybeXS Getopt::Long
all:
true
@@ -19,6 +19,7 @@ install:
$(PERL) -M$$m -e 1 > /dev/null 2>&1; \
if test $$? != 0 ; then echo "Not installing rem2html; missing $$m"; exit 0; fi; \
done; \
pod2man rem2html > rem2html.1 && mkdir -p $(DESTDIR)$(mandir)/man1 && cp rem2html.1 $(DESTDIR)$(mandir)/man1/rem2html.1 || true; \
echo "Installing rem2html in $(DESTDIR)$(bindir)"; \
mkdir -p $(DESTDIR)$(bindir) && sed -e 's|^#!perl|#!$(PERL)|' < rem2html > $(DESTDIR)$(bindir)/rem2html && chmod 755 $(DESTDIR)$(bindir)/rem2html && exit 0; \
exit 1;

View File

@@ -4,7 +4,7 @@ use strict;
use warnings;
use Getopt::Long;
use JSON::Any;
use JSON::MaybeXS;
my %Options;
@@ -68,7 +68,7 @@ and newmoon.png, which are expected to live in C<--imgbase>.
=item --stylesheet I<url.css>
Use I<url.css> as the stylesheet. If this option is used,
I<url.css> is interpreted relative to B<imgbase> I<unless> it start
I<url.css> is interpreted relative to B<imgbase> I<unless> it starts
with a "/".
=item --nostyle
@@ -96,11 +96,43 @@ Insert I<html_text> right before the E<lt>/bodyE<gt> tag.
=back
=head1 SPECIALS SUPPORTED
The rem2html back-end supports the following SPECIAL reminders:
=over
=item HTML
Add an HTML reminder to the calendar. All HTML tags are available.
=item HTMLCLASS
Add a CSS class to the box representing the trigger date. See
"HIGHLIGHTING TODAY" for an example
=item WEEK, MOON, SHARE, COLOR
The standard SPECIALs supported by all back-ends
=back
=head1 HIGHLIGHTING TODAY
Older versions of rem2html used to highlight today's date with a red outline.
The current version does not do that by default. If you wish to highlight
today's date, add the following reminder to your reminders file:
REM [realtoday()] SPECIAL HTMLCLASS rem-today
=head1 AUTHOR
rem2html was written by Dianne Skoll with much inspiration from an
earlier version by Don Schwarz.
=head1 SEE ALSO
B<remind>, B<rem2ps>, B<rem2pdf>, B<tkremind>
=cut
sub usage
@@ -232,23 +264,30 @@ sub parse_input
chomp($line);
($Month, $Year, $Numdays, $Firstwkday, $Mondayfirst) = split(' ', $line);
$Month =~ s/_/ /g;
# Day names
$line = <STDIN>;
return 0 unless $line;
chomp($line);
@Daynames = split(' ', $line);
for (my $i=0; $i<7; $i++) {
$Daynames[$i] =~ s/_/ /g;
}
# Prevmon prevlen
$line = <STDIN>;
return 0 unless $line;
chomp($line);
($Prevmon, $Prevlen) = split(' ', $line);
$Prevmon =~ s/_/ /g;
# Nextmon nextlen
$line = <STDIN>;
return 0 unless $line;
chomp($line);
($Nextmon, $Nextlen) = split(' ', $line);
$Nextmon =~ s/_/ /g;
$found_data = 1;
my $class;
@@ -266,7 +305,7 @@ sub parse_input
($y, $m, $d, $special, $tag, $duration, $time, $body) =
($1, $2, $3, $4, $5, $6, $7, $8);
} elsif (/\{/) {
my $obj = JSON::Any->jsonToObj($_);
my $obj = decode_json($_);
next unless ($obj->{date} =~ /^(\d+)-(\d+)-(\d+)$/);
$y = $1;
$m = $2;
@@ -480,7 +519,7 @@ sub output_calendar
}
for (my $day=1; $day<=$Numdays; $day++) {
draw_day_cell($day, $number_of_rows);
draw_day_cell($day, $number_of_rows);
$col++;
if ($col == 7) {
$col = 0;

12
rem2pdf/Makefile.PL.in Normal file
View File

@@ -0,0 +1,12 @@
use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'Remind::PDF',
AUTHOR => q{Dianne Skoll <dianne@skoll.ca>},
VERSION => '@VERSION@',
PREREQ_PM => {
'Getopt::Long' => 0,
'Cairo' => 0,
'Pango' => 0,
},
EXE_FILES => [ 'bin/rem2pdf' ]
);

42
rem2pdf/Makefile.top.in Normal file
View File

@@ -0,0 +1,42 @@
# Set by configure - don't touch.
srcdir=@srcdir@
prefix=@prefix@
exec_prefix=@exec_prefix@
mandir=@mandir@
bindir=@bindir@
datadir=@datadir@
datarootdir=@datarootdir@
PERL=@PERL@
PERLMODS_NEEDED=Getopt::Long Cairo Pango
all: Makefile
@if test "$(PERL)" = "" ; then \
echo "Not building rem2pdf; Perl is required"; exit 0; fi; \
for m in $(PERLMODS_NEEDED) ; \
do \
$(PERL) -M$$m -e 1 > /dev/null 2>&1; \
if test $$? != 0 ; then echo "Not building rem2pdf; missing $$m"; exit 0; fi; \
done; \
$(MAKE) all && exit 0; \
exit 1;
install:
@if test "$(PERL)" = "" ; then \
echo "Not installing rem2pdf; Perl is required"; exit 0; fi; \
for m in $(PERLMODS_NEEDED) ; \
do \
$(PERL) -M$$m -e 1 > /dev/null 2>&1; \
if test $$? != 0 ; then echo "Not installing rem2pdf; missing $$m"; exit 0; fi; \
done; \
echo "Installing rem2pdf"; \
if test "$(INSTALL_BASE)" != "" ; then \
$(MAKE) install DESTDIR=$(DESTDIR) "INSTALL_BASE=$(INSTALL_BASE)" && exit 0; \
elif test "$(prefix)" = "/usr" ; then \
$(MAKE) install DESTDIR=$(DESTDIR) INSTALLDIRS=vendor && exit 0; \
else \
$(MAKE) install DESTDIR=$(DESTDIR) && exit 0; \
fi; \
exit 1;
Makefile: Makefile.PL
$(PERL) Makefile.PL @PERLARTIFACTS@ INSTALL_BASE=$(INSTALL_BASE) || true

22
rem2pdf/README Normal file
View File

@@ -0,0 +1,22 @@
rem2pdf is a Perl program that takes the output of "remind -p" and
produces a PDF calendar. See "man rem2pdf" for details.
rem2pdf has the following Perl modules as prerequisites:
Pango - https://metacpan.org/pod/Pango
Cairo - https://metacpan.org/pod/Cairo
On Debian or Debian-derived systems, these can be installed with:
apt install libpango-perl libcairo-perl
On Red Hat or Red Hat-derived systems, you need to install the perl-Pango
and perl-Cairo RPMs, which may require adding other repos to your list of
RPM sources.
rem2pdf is built and installed in the usual Perl program way:
perl Makefile.PL && make && sudo make install
--
Dianne Skoll - <dianne@skoll.ca>

509
rem2pdf/bin/rem2pdf.in Normal file
View File

@@ -0,0 +1,509 @@
#!@PERL@
use strict;
use warnings;
use Encode;
use Cairo;
use Pango;
use Getopt::Long;
my $VERSION = '@VERSION@';
use Remind::PDF;
my $media_to_size = {
"Letter" => [ 612, 792],
"Tabloid" => [ 792, 1224],
"Ledger" => [1224, 792],
"Legal" => [ 612, 1008],
"Statement" => [ 396, 612],
"Executive" => [ 540, 720],
"A3" => [ 842, 1190],
"A4" => [ 595, 842],
"A5" => [ 420, 595],
"B4" => [ 729, 1032],
"B5" => [ 519, 729],
"Folio" => [ 612, 936],
"Quarto" => [ 612, 780],
"10x14" => [ 720, 1008],
};
my $help = 0;
my $settings = {
landscape => 0,
numbers_on_left => 0,
small_calendars => 0,
fill_entire_page => 0,
media => 'Letter',
width => 0,
height => 0,
title_font => 'Sans',
header_font => 'Sans',
daynum_font => 'Sans Bold Oblique',
entry_font => 'Sans',
small_cal_font => 'Sans',
title_size => 14,
header_size => 12,
daynum_size => 14,
entry_size => 8,
border_size => 4,
line_thickness => 1,
margin_top => 36,
margin_bottom => 36,
margin_left => 36,
margin_right => 36,
verbose => 0,
};
my $me = $0;
$me =~ s/^.*\///;
set_default_media();
sub usage
{
print <<"EOF";
$me (version $VERSION): Convert Remind -pp output to a PDF calendar.
Usage: remind -pp [options] filename | $me [options] > out.pdf
Options:
--landscape, -l Print in landscape orientation
--small-calendars=N Choose location for small calendars
-cN Synonym for --small-calendars=N
--left-numbers, -x Print day numbers on the left
--fill-page, -e Fill the entire page
--media=MEDIA, -mMEDIA Size for specified media
--width=W, -wW Specify media width in 1/72nds of an inch
--height=H, -hH Specify media height in 1/72nds of an inch
--title-font=FONT Specify font for calendar title
--header-font=FONT Specify font for weekday names
--daynum-font=FONT Specify font for day numbers
--entry-font=FONT Specify font for calendar entries
--small-cal-font=FONT Specify font for small calendars
--title-size=S Specify size of font for calendar title in points
--header-size=S Specify size of font for weekday names
--daynum-size=S Specify size of font for day numbers
--entry-size=S Specify size of font for calendar entries
--border-size=S Specify size of gaps between items in 1/72nds of an inch
--line-thickness=S Specify line thickness in 1/72nds of an inch
--margin-top=S Specify top margin size in 1/72nds of an inch
--margin-bottom=S Specify bottom margin size in 1/72nds of an inch
--margin-left=S Specify left margin size in 1/72nds of an inch
--margin-right=S Specify right margin size in 1/72nds of an inch
--verbose, -v Print progress messages
--help Display this help
EOF
}
Getopt::Long::Configure('bundling_values');
my $ret = GetOptions('landscape|l' => \$settings->{landscape},
'small-calendars|c=i' => \$settings->{small_calendars},
'left-numbers|x' => \$settings->{numbers_on_left},
'fill-page|e' => \$settings->{fill_entire_page},
'media|m=s' => \$settings->{media},
'width|w=i' => \$settings->{width},
'height|h=i' => \$settings->{height},
'title-font=s' => \$settings->{title_font},
'header-font=s' => \$settings->{header_font},
'daynum-font=s' => \$settings->{daynum_font},
'entry-font=s' => \$settings->{entry_font},
'small-cal-font=s' => \$settings->{small_cal_font},
'title-size=f' => \$settings->{title_size},
'header-size=f' => \$settings->{header_size},
'daynum-size=f' => \$settings->{daynum_size},
'entry-size=f' => \$settings->{entry_size},
'border-size=f' => \$settings->{border_size},
'line-thickness=f' => \$settings->{line_thickness},
'margin-top=f' => \$settings->{margin_top},
'margin-bottom=f' => \$settings->{margin_bottom},
'margin-left=f' => \$settings->{margin_left},
'margin-right=f' => \$settings->{margin_right},
'verbose|v' => \$settings->{verbose},
'help' => \$help
);
if (!$ret) {
usage();
exit(1);
}
if ($help) {
usage();
exit(0);
}
if ($settings->{width} <= 0 ||
$settings->{height} <= 0) {
my $size = $media_to_size->{ucfirst($settings->{media})};
if (!$size) {
if (lc($settings->{media}) ne 'help') {
print STDERR "Unknown media " . $settings->{media} . "\n";
}
set_default_media();
printf("%-12s Size in 1/72 in\n", "Valid media:");
foreach my $m (sort { $a cmp $b } (keys(%$media_to_size))) {
if ($m eq $settings->{media}) {
print "* ";
} else {
print " ";
}
printf("%-12s %4d x %4d\n", $m,
$media_to_size->{$m}->[0],
$media_to_size->{$m}->[1]);
}
exit(1);
}
$settings->{width} = $size->[0];
$settings->{height} = $size->[1];
}
if ($settings->{landscape}) {
my $tmp = $settings->{width};
$settings->{width} = $settings->{height};
$settings->{height} = $tmp;
}
# Don't read from a terminal
if (-t STDIN) {
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";
exit(1);
}
my $done_one = 0;
my $errored_out = 0;
my $surface = Cairo::PdfSurface->create_for_stream(sub { print $_[1] unless $errored_out; }, undef,
$settings->{width}, $settings->{height});
# set_metadata not available in older versions of Cairo
eval { $surface->set_metadata('title', 'Calendar'); };
eval { $surface->set_metadata('author', 'Remind (https://dianne.skoll.ca/projects/remind/)'); };
eval { $surface->set_metadata('creator', 'rem2pdf (https://dianne.skoll.ca/projects/remind/)'); };
eval { $surface->set_metadata('subject', 'Calendar'); };
my $cr = Cairo::Context->create($surface);
$cr->set_line_width($settings->{line_thickness});
while(1) {
my ($obj, $err) = Remind::PDF->create_from_stream(*STDIN,
{color => 1,
shade => 1,
moon => 1,
pango => 1,
week => 1,});
if (!$obj) {
if (!$done_one) {
$errored_out = 1;
print STDERR "$me: $err\n";
exit(1);
}
last;
}
$done_one = 1;
$obj->render($cr, $settings);
}
$surface->finish();
sub set_default_media
{
my $paper;
$paper = $ENV{PAPERSIZE};
if ($paper && set_media(ucfirst($paper))) {
return 1;
}
if ($ENV{PAPERCONF}) {
if (set_media_from_file($ENV{PAPERCONF})) {
return 1;
}
}
if (set_media_from_file('/etc/papersize')) {
return 1;
}
return set_media('Letter');
}
sub set_media
{
my ($m) = @_;
return 0 unless $media_to_size->{$m};
$settings->{media} = $m;
return 1;
}
sub set_media_from_file
{
my ($fn) = @_;
if (!open(IN, '<', $fn)) {
return 0;
}
while(<IN>) {
chomp;
s/^\s+//;
s/\s+$//;
next if ($_ eq '');
next if ($_ =~ /^#/);
my $m = $_;
close(IN);
return set_media($m);
}
close(IN);
return 0;
}
__END__
=head1 NAME
rem2pdf - draw a PDF calendar from Remind output
=head1 SYNOPSIS
remind -pp [options] file | rem2pdf [options] > output.pdf
=head1 DESCRIPTION
B<rem2pdf> reads the standard input, which should be the results of
running B<remind> with the B<-p>, B<-pp> or B<-ppp> options. It emits
PDF code that draws a calendar to standard output.
B<rem2pdf> uses the Pango text formatting library (L<https://pango.gnome.org/>)
and the Cairo graphics library (L<https://www.cairographics.org/>) to produce
its output. The CPAN modules Pango (L<https://metacpan.org/pod/Pango>)
and Cairo (L<https://metacpan.org/pod/Cairo>) are prerequisites.
B<rem2pdf> assumes that its input stream is valid UTF-8. If this is not
the case, it may render output incorrectly or even fail to render
output at all.
=head1 OPTIONS
=over
=item --landscape, -l
Print the calendar in landscape orientation. Essentially, this swaps
the width and height of the output media.
=item --small-calendars=I<n>, -cI<n>
Control the inclusion of small calendars for the previous and next
month. Possible values for I<n> are:
=over
=item Z<>0
Do not draw any small calendares
=item Z<>1
Place the small calendars at the bottom-right if there is room;
otherwise, place them at the top-left.
=item Z<>2
Place the small calendars at the top-left if there is room; otherwise,
place them at the bottom-right.
=item Z<>3
Place the previous month's small calendar at the top-left and the next
month's at the bottom-right if there is room; otherwise, follow
I<n>=1. A moment's thought reveals that an option which splits the
calendars if there is room and otherwise follows I<n>=2 yields the
same results.
=back
=item --left-numbers, -x
Draw the day numbers in the top-left corner of each day's box rather than
the default top-right.
=item --fill-page, -e
Make the calendar fill the available space on the page.
=item --media=I<media>, -mI<media>
Specify the paper size (Letter, A4, etc.) For a list of valid media sizes,
run:
rem2pdf --media=help
The default media size will be marked with an asterisk.
=item --width=I<n>, -wI<n>, --height=I<m>, -hI<m>
Rather than specifying a named media size, directly specify the width
and height of the output in 1/72ths of an inch. You must specify both
width and height for the options to be respected.
=item --title-font=I<font>
Specify the font used for the calendar title. It can be any font that
the Pango library on your system can use. The default is Sans. If
you choose a font with spaces in its name, you may need to quote this
argument.
=item --header-font=I<font>
Specify the font used for the weekday names. The default is Sans.
=item --daynum-font=I<font>
Specify the font used for the day numbers. The default is
Sans Bold Oblique.
=item --entry-font=I<font>
Specify the font used for calendar entries. The default is Sans.
=item --small-cal-font=I<font>
Specify the font used for the small next- and previous-month
calendars. The default is Sans.
=item --title-size=I<n>
Specify the size of the title font in 1/72ths of an inch. The default
is 14. This size, and indeed all following sizes, may be specified as
floating-point numbers.
=item --header-size=I<n>
Specify the size of the header font in 1/72ths of an inch. The default is 14.
=item --daynum-size=I<n>
Specify the size of the day number font in 1/72ths of an inch. The
default is 14.
=item --entry-size=I<n>
Specify the size of the calendar entry font in 1/72ths of an inch.
The default is 8.
=item --border-size=I<n>
Specify the size of the blank border between the contents of a calendar
box and the centre of the lines surrounding it, in 1/72ths of an inch.
The default is 4.
=item --line-thickness=I<n>
Specify the thickness of the lines drawn on the calendar. The default is 1.
=item --margin-top=I<n>
The size of the margin at the top of the page in 1/72ths of an inch.
The default is 36.
=item --margin-bottom=I<n>
The size of the margin at the bottom of the page in 1/72ths of an inch.
The default is 36.
=item --margin-left=I<n>
The size of the margin at the left of the page in 1/72ths of an inch.
The default is 36.
=item --margin-right=I<n>
The size of the margin at the right of the page in 1/72ths of an inch.
The default is 36.
=item --verbose, -v
Print (on STDERR) the name of the month and year for each month that
is rendered.
=back
=head1 USAGE
To use B<rem2df>, pipe the output of B<remind> with one of the
B<-p>, B<-pp> or B<-ppp> options into B<rem2pdf>. The PDF output
will be sent to standard output. So for example, to print a 12-month
calendar for the year 2030, use:
remind -pp12 /dev/null Jan 2030 | rem2pdf -e -l -c=3 | lpr
You can concatenate multiple B<remind> runs. For example, the following
will produce a PDF calendar for January through March of 2023, and
June of 2023 (for a total of four pages);
(remind -pp3 Jan 2023 /dev/null ; \
remind -p June 2023 /dev/null) | rem2pdf -e -l -c=3 > cal.pdf
=head1 FORMATTED TEXT
B<rem2pdf> supports a B<SPECIAL> reminder type called B<PANGO>. This
lets you format text using the Pango markup language, described at
L<https://docs.gtk.org/Pango/pango_markup.html>. Here are some
examples:
REM Mon SPECIAL PANGO <b>Bold</b> and <i>italic</i>
REM Tue SPECIAL PANGO <span face="zapf chancery">Fancy</span>
REM Wed SPECIAL PANGO <span foreground="red"><b>Bold red</b></span>
Other back-ends such as B<rem2ps> and B<rem2html> will ignore PANGO
special reminders.
Neither B<remind> nor B<rem2pdf> will check the markup to ensure
it is syntactically correct. If you use invalid Pango markup, the
Pango library will print a warning and B<rem2pdf> will not render any
output for the invalid reminder.
=head1 ABSOLUTELY-POSITIONED TEXT
If your B<PANGO> special reminder starts with C<@I<x>,I<y>> where I<x>
and I<y> are floating-point numbers, then the Pango marked-up test is
positioned absolutely with respect to the day's box (and is not
counted when calculating the box's height.)
A positive I<x> value positions the left edge of the text I<x> points
to the right of the left side of the calender box, while a negative
I<x> value positions the right edge of the text I<x> points to the left
of the right side of the calender box.
A positive I<y> value positions the top edge of the text I<y> points
below the top of the calender box, while a negative I<y> value
positions the bottom edge of the text I<y> points above the bottom of
the calender box.
If you use absolutely-positioned text, it's up to you to make sure it
doesn't overlap other text; B<rem2pdf> takes no special precautions to
prevent this.
As an example, this places Sunrise and Sunset times at the bottom left
of each calendar box:
REM SPECIAL PANGO @1,-1 <span size="4800"><i>Rise [sunrise($U)] Set [sunset($U)]</i></span>
(Note that Pango expresses font sizes in 1024's of a point, so a size of
4800 works out to about 4.6 points.)
=head1 AUTHOR
B<Rem2PDF> was written by Dianne Skoll <dianne@skoll.ca>
=head1 SEE ALSO
B<remind>, B<rem2ps>, B<rem2html>, B<tkremind>

968
rem2pdf/lib/Remind/PDF.pm Normal file
View File

@@ -0,0 +1,968 @@
package Remind::PDF;
use strict;
use warnings;
use Cairo;
use Pango;
use Remind::PDF::Entry;
use Encode;
use JSON::MaybeXS;
=head1 NAME
Remind::PDF - Render a month's worth of Remind data to PDF
=head1 CLASS METHODS
=head2 Remind::PDF->create_from_stream($in, $specials_accepted)
This method reads data from an open file handle C<$in>. C<$specials_accepted>
is a hashref of SPECIAL reminder types to accept; the key is the name of the
SPECIAL (all lower-case) and the value should be 1. Any SPECIAL reminders
not in the hash are ignored.
This function returns a two-element array: C<($obj, $err)>. On success,
C<$obj> will be a C<Remind::PDF> object and C<$err> will be undef. On
failure, C<$obj> will be undef and C<$err> will be an error message.
=cut
sub create_from_stream
{
my ($class, $in, $specials_accepted) = @_;
while (<$in>) {
chomp;
if ($_ eq '# rem2ps begin' ||
$_ eq '# rem2ps2 begin') {
my $self = bless {}, $class;
return $self->read_one_month($in, $_, $specials_accepted);
} elsif ($_ eq '[') {
return Remind::PDF::Multi->create_from_stream($in, $specials_accepted);
}
}
return (undef, "Could not find any remind -p output anywhere");
}
=head2 Remind::PDF->create_from_hash($hash, $specials_accepted)
This method takes data from a hash C<$hash>, which must be one month's
worth of data from C<remind -ppp> output. C<$specials_accepted> is a
hashref of SPECIAL reminder types to accept; the key is the name of
the SPECIAL (all lower-case) and the value should be 1. Any SPECIAL
reminders not in the hash are ignored.
This function returns a two-element array: C<($obj, $err)>. On success,
C<$obj> will be a C<Remind::PDF> object and C<$err> will be undef. On
failure, C<$obj> will be undef and C<$err> will be an error message.
=cut
sub create_from_hash
{
my ($class, $hash, $specials_accepted) = @_;
bless $hash, $class;
my $filtered_entries = [];
for (my $i=0; $i<=31; $i++) {
$filtered_entries->[$i] = [];
}
foreach my $e (@{$hash->{entries}}) {
if ($hash->accept_special($e, $specials_accepted)) {
my $day = $e->{date};
$day =~ s/^\d\d\d\d-\d\d-//;
$day =~ s/^0//;
push(@{$filtered_entries->[$day]}, Remind::PDF::Entry->new_from_hash($e));
}
}
$hash->{entries} = $filtered_entries;
return $hash;
}
=head1 INSTANCE METHODS
=head2 read_one_month($in, $first_line, $specials_accepted)
This function reads one month's worth of data from the file handle
C<$in>. C<$first_line> is the line that was read from C<$in>
just before calling this function. C<$specials_accepted> is a
hashref as documented above.
The return value is the same C<($obj, $err)> two-element array
as C<create_from_stream> returns.
=cut
sub read_one_month
{
my ($self, $in, $first_line, $specials_accepted) = @_;
$self->{entries} = [];
$self->{daynames} = [];
$self->{monthname} = '';
$self->{year} = '';
$self->{daysinmonth} = 0;
$self->{firstwkday} = 0;
$self->{mondayfirst} = 0;
$self->{prevmonthname} = '';
$self->{nextmonthname} = '';
$self->{daysinprevmonth} = 0;
$self->{daysinnextmonth} = 0;
$self->{prevmonthyear} = 0;
$self->{nextmonthyear} = 0;
for (my $i=0; $i<=31; $i++) {
$self->{entries}->[$i] = [];
}
my $line = $in->getline();
chomp($line);
# Month Year Days FirstWkday MondayFirst
if ($line =~ /^(\S+) (\d+) (\d+) (\d+) (\d+)/) {
$self->{monthname} = $1;
$self->{year} = $2;
$self->{daysinmonth} = $3;
$self->{firstwkday} = $4;
$self->{mondayfirst} = $5;
} else {
return (undef, "Cannot interpret line: $line");
}
$self->{monthname} =~ s/_/ /g;
# Day names
$line = $in->getline();
chomp($line);
if ($line =~ /^\S+ \S+ \S+ \S+ \S+ \S+ \S+$/) {
@{$self->{daynames}} = map { s/_/ /g; $_; } (split(/ /, $line));
} else {
return (undef, "Cannot interpret line: $line");
}
# Prev month, num days
$line = $in->getline();
chomp($line);
if ($line =~ /^\S+ \d+$/) {
($self->{prevmonthname}, $self->{daysinprevmonth}) = split(/ /, $line);
} else {
return (undef, "Cannot interpret line: $line");
}
# Next month, num days
$line = $in->getline();
chomp($line);
if ($line =~ /^\S+ \d+$/) {
($self->{nextmonthname}, $self->{daysinnextmonth}) = split(/ /, $line);
} else {
return (undef, "Cannot interpret line: $line");
}
$self->{prevmonthname} =~ s/_/ /g;
$self->{nextmonthname} =~ s/_/ /g;
if ($first_line eq '# rem2ps2 begin') {
# remind -pp format
return $self->read_one_month_pp($in, $specials_accepted);
}
# Old-style "remind -p"
# TODO: Eventually support this?
return $self->read_one_month_p($in, $specials_accepted);
}
=head2 read_one_month_p($in, $specials_accepted)
This function reads one month's worth of data from the file handle
C<$in>, assuming the original "remind -p" format.
C<$specials_accepted> is a hashref as documented above.
The return value is the same C<($obj, $err)> two-element array
as C<create_from_stream> returns.
=cut
sub read_one_month_p
{
my ($self, $in, $specials_accepted) = @_;
my $line;
while ($line = $in->getline()) {
chomp($line);
if ($line eq '# rem2ps end') {
return ($self, undef);
}
# Ignore comments
next if $line =~ /^#/;
my $hash = $self->parse_oldstyle_line($line);
next unless $hash;
my $day = $hash->{date};
$day =~ s/^\d\d\d\d-\d\d-//;
$day =~ s/^0//;
if ($self->accept_special($hash, $specials_accepted)) {
push(@{$self->{entries}->[$day]}, Remind::PDF::Entry->new_from_hash($hash));
}
}
return (undef, "Missing # rem2ps end marker");
}
=head2 parse_oldstyle_line ($line)
This method parses an old-style "remind -p" line
and returns a hashref containing some or all of the
hash keys found in the newer "remind -pp" JSON output.
=cut
sub parse_oldstyle_line
{
my ($self, $line) = @_;
return undef unless $line =~ m|^(\d+)/(\d+)/(\d+) (\S+) (\S+) (\S+) (\S+) (.*)$|;
my $hash = {
date => "$1-$2-$3",
passthru => $4,
tags => $5,
duration => $6,
time => $7,
body => $8};
foreach my $key (qw(passthru tags time duration)) {
delete $hash->{$key} if $hash->{$key} eq '*';
}
if ($hash->{passthru}) {
if ($hash->{passthru} =~ /^(shade|color|colour)$/i) {
if ($hash->{body} =~ /^\s*(\d+)\s+(\d+)\s+(\d+)/) {
$hash->{r} = $1;
$hash->{g} = $2;
$hash->{b} = $3;
} elsif ($hash->{body} =~ /^\s*(\d+)/) {
$hash->{r} = $1;
$hash->{g} = $1;
$hash->{b} = $1;
}
}
}
return $hash;
}
=head2 read_one_month_pp($in, $specials_accepted)
This function reads one month's worth of data from the file handle
C<$in>, assuming the "remind -pp" partial-JSON format.
C<$specials_accepted> is a hashref as documented above.
The return value is the same C<($obj, $err)> two-element array
as C<create_from_stream> returns.
=cut
sub read_one_month_pp
{
my ($self, $in, $specials_accepted) = @_;
my $json = JSON::MaybeXS->new(utf8 => 0);
my $line;
while ($line = $in->getline()) {
chomp($line);
if ($line eq '# rem2ps2 end') {
return ($self, undef);
}
my $hash;
eval {
$hash = $json->decode($line);
};
if (!$hash) {
return (undef, "Unable to decode JSON: $@");
}
my $day = $hash->{date};
$day =~ s/^\d\d\d\d-\d\d-//;
$day =~ s/^0//;
if ($self->accept_special($hash, $specials_accepted)) {
push(@{$self->{entries}->[$day]}, Remind::PDF::Entry->new_from_hash($hash));
}
}
return (undef, "Missing # rem2ps2 end marker");
}
=head2 accept_special($hash, $specials_accepted)
Given a hashref C<$hash> consisting of one entry parsed
from the "remind -p" stream and a C<$specials_accepted> hash,
return 1 if we should include this entry in the calendar or
0 if mot.
=cut
sub accept_special
{
my ($self, $hash, $specials_accepted) = @_;
return 1 unless exists($hash->{passthru});
return 1 if $specials_accepted->{lc($hash->{passthru})};
return 0;
}
=head2 find_last_special($special, $entries)
Given an array of Reminder entries, find the last
C<$special>-type SPECIAL in the array. Return
the entry if one was found or undef if not.
=cut
sub find_last_special
{
my ($self, $special, $entries) = @_;
my $class = "Remind::PDF::Entry::$special";
my $found = undef;
foreach my $e (@$entries) {
$found = $e if ($e->isa($class));
}
return $found;
}
=head2 render($cr, $settings)
Render a calendar for one month. C<$cr> is a Cairo
drawing context, and C<$settings> is a settings hash
passed in by the caller. See the source code of
C<rem2pdf> for the contents of C<$settings>
=cut
sub render
{
my ($self, $cr, $settings) = @_;
$self->{horiz_lines} = [];
$cr->set_line_cap('square');
my $so_far = $self->draw_title($cr, $settings);
# Top line
push(@{$self->{horiz_lines}}, $so_far);
my $top_line = $so_far;
$so_far = $self->draw_daynames($cr, $settings, $so_far);
# Line under the days
push(@{$self->{horiz_lines}}, $so_far);
# Remaining space on page
$self->{remaining_space} = $settings->{height} - $settings->{margin_bottom} - $so_far;
$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
$self->{row_height} = $self->{remaining_space} / $rows;
my ($start_col, $start_day);
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;
$so_far = $self->draw_row($cr, $settings, $so_far, $row, $start_day, $start_col);
$start_day += 7 - $start_col;
push(@{$self->{horiz_lines}}, $so_far);
if ($row == 0) {
if ($prevcal_top) {
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},
$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_top) {
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},
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
$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);
}
}
}
if ($so_far > $settings->{height} - $settings->{margin_bottom}) {
print STDERR "WARNING: overfull calendar box\n";
}
# The vertical lines
my $cell = ($settings->{width} - $settings->{margin_left} - $settings->{margin_right}) / 7;
for (my $i=0; $i<=7; $i++) {
$cr->move_to($settings->{margin_left} + $i * $cell, $top_line);
$cr->line_to($settings->{margin_left} + $i * $cell, $so_far);
$cr->stroke();
}
# And the horizontal lines
foreach my $y (@{$self->{horiz_lines}}) {
$cr->move_to($settings->{margin_left}, $y);
$cr->line_to($settings->{width} - $settings->{margin_right}, $y);
$cr->stroke();
}
if ($settings->{verbose}) {
print STDERR "remdp2f: Rendered " . $self->{monthname} . ' ' . $self->{year} . "\n";
}
# Done this page
$cr->show_page();
}
=head2 draw_row($cr, $settings, $so_far, $row, $start_day, $start_col)
Draw a single row in the calendar. C<$cr> is a Cairo drawing context
and C<$settings> is the settings hash passed to C<render>. C<$so_far>
is the Y-coordinate of the top of the row; drawing starts at this
coordinate. C<$start_day> is the day of the month at which the
row starts and C<$start> col is the column number (0-6) at which
to start drawing from C<$start_day>
Returns the Y coordinate at which to start drawing the I<next>
calendar row.
=cut
sub draw_row
{
my ($self, $cr, $settings, $so_far, $row, $start_day, $start_col) = @_;
my $col = $start_col;
my $day = $start_day;
my $height = 0;
# Preview them to figure out the row height...
if (!$settings->{fill_entire_page}) {
while ($col < 7) {
my $h = $self->draw_day($cr, $settings, $so_far, $day, $col, 0);
$height = $h if ($h > $height);
$day++;
$col++;
last if ($day > $self->{daysinmonth});
}
$col = $start_col;
$day = $start_day;
} else {
$height = $self->{row_height} - $settings->{border_size} * 2;
}
if (!$settings->{fill_entire_page} && $height < $self->{minimum_row_height}) {
$height = $self->{minimum_row_height};
}
# Now draw for real
while ($col < 7 && $day <= $self->{daysinmonth}) {
$self->draw_day($cr, $settings, $so_far, $day, $col, $height);
$day++;
$col++;
}
return $so_far + $height + $settings->{border_size};
}
=head2 col_box_coordinates($so_far, $col, $height, $settings)
Returns a four-element array C<($x1, $y1, $x2, $y2)> representing
the bounding box of the calendar box at column C<$col> (0-6). C<$height>
is the height of the box and C<$settings> is the settings hashref
passed to C<render>.
=cut
sub col_box_coordinates
{
my ($self, $so_far, $col, $height, $settings) = @_;
my $cell = ($settings->{width} - $settings->{margin_left} - $settings->{margin_right}) / 7;
return (
$settings->{margin_left} + $cell * $col,
$so_far,
$settings->{margin_left} + $cell * ($col + 1),
$so_far + $height + $settings->{border_size},
);
}
=head2 draw_day($cr, $settings, $so_far, $day, $col, $height)
Renders a single day's worth of reminders. C<$cr> is a Cairo
drawing context and C<$settings> is the settings hash passed
to C<render>. C<$so_far> is the Y-coordinate of the top
of the box and C<$col> is the column number.
C<$height> is the height of the box. If C<$height> is passed
in as zero, then do not actually render anything... instead,
compute how high the box should be. If C<$height> is non-zero,
then it is the height of the box.
Returns the height required for the calendar box.
=cut
sub draw_day
{
my ($self, $cr, $settings, $so_far, $day, $col, $height) = @_;
my $top = $so_far;
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($so_far, $col, $height, $settings);
# Do shading if we're in "for real" mode
if ($height) {
my $shade = $self->find_last_special('shade', $self->{entries}->[$day]);
if ($shade) {
$cr->save;
$cr->set_source_rgb($shade->{r} / 255,
$shade->{g} / 255,
$shade->{b} / 255);
$cr->rectangle($x1, $y1, $x2 - $x1, $y2 - $y1);
$cr->fill();
$cr->restore;
}
}
# Draw the day number
my $layout = Pango::Cairo::create_layout($cr);
$layout->set_text($day);
my $desc = Pango::FontDescription->from_string($settings->{daynum_font} . ' ' . $settings->{daynum_size} . 'px');
$layout->set_font_description($desc);
my ($wid, $h) = $layout->get_pixel_size();
# Don't actually draw if we're just previewing to get the cell height
if ($height) {
$cr->save;
if ($settings->{numbers_on_left}) {
$cr->move_to($x1 + $settings->{border_size}, $so_far + $settings->{border_size});
} else {
$cr->move_to($x2 - $settings->{border_size} - $wid, $so_far + $settings->{border_size});
}
Pango::Cairo::show_layout($cr, $layout);
$cr->restore();
}
$so_far += $h + 2 * $settings->{border_size};
my $entry_height = 0;
my $done = 0;
foreach my $entry (@{$self->{entries}->[$day]}) {
# Moon and week should not adjust height
if ($entry->isa('Remind::PDF::Entry::moon') ||
$entry->isa('Remind::PDF::Entry::week')) {
$entry->render($self, $cr, $settings, $top, $day, $col, $height);
next;
}
# An absolutely-positioned Pango markup should not adjust height
# either
if ($entry->isa('Remind::PDF::Entry::pango') &&
defined($entry->{atx}) && defined($entry->{aty})) {
$entry->render($self, $cr, $settings, $top, $day, $col, $height);
next;
}
# Shade is done already
if ($entry->isa('Remind::PDF::Entry::shade')) {
next;
}
if ($done) {
$so_far += $settings->{border_size};
$entry_height += $settings->{border_size};
}
$done = 1;
my $h2 = $entry->render($self, $cr, $settings, $so_far, $day, $col, $height);
$entry_height += $h2;
$so_far += $h2;
}
if ($height) {
if ($h + $entry_height + 2 * $settings->{border_size} > $height) {
print STDERR "WARNING: overfull box at $day " . $self->{monthname} . ' ' . $self->{year} . "\n";
$entry_height = $height;
}
}
return $h + $entry_height + 2 * $settings->{border_size};
}
=head2 draw_daynames($cr, $settings, $so_far)
Draw the weekday names heading. C<$cr> is a Cairo drawing context
and C<$settings> is the settings hash passed to C<render>. C<$so_far>
is the Y-coordinate of the top of the row; drawing starts at this
coordinate.
Returns the Y coordinate at which to start drawing the first
calendar row.
=cut
sub draw_daynames
{
my ($self, $cr, $settings, $so_far) = @_;
my $w = $settings->{width} - $settings->{margin_left} - $settings->{margin_right};
my $cell = $w/7;
$so_far += $settings->{border_size};
my $height = 0;
for (my $i=0; $i<7; $i++) {
my $j;
if ($self->{mondayfirst}) {
$j = ($i + 1) % 7;
} else {
$j = $i;
}
my $layout = Pango::Cairo::create_layout($cr);
$layout->set_text(Encode::decode('UTF-8', $self->{daynames}->[$j]));
my $desc = Pango::FontDescription->from_string($settings->{header_font} . ' ' . $settings->{header_size} . 'px');
$layout->set_font_description($desc);
my ($wid, $h) = $layout->get_pixel_size();
$cr->save;
$cr->move_to($settings->{margin_left} + $i * $cell + $cell/2 - $wid/2, $so_far);
Pango::Cairo::show_layout($cr, $layout);
$cr->restore();
if ($h > $height) {
$height = $h;
}
}
return $so_far + $height + $settings->{border_size} * .75;
}
=head2 draw_title($cr, $settings)
Draw the title ("Monthname Year") at the top of the calendar.
C<$cr> is a Cairo drawing context
and C<$settings> is the settings hash passed to C<render>.
Returns the Y coordinate at which to start drawing the row
containing the weekday names.
=cut
sub draw_title
{
my ($self, $cr, $settings) = @_;
my $title = $self->{monthname} . ' ' . $self->{year};
# set_page_label not available in older versions of Cairo
eval { $cr->get_target()->set_page_label($title); };
my $layout = Pango::Cairo::create_layout($cr);
$layout->set_text(Encode::decode('UTF-8', $title));
my $desc = Pango::FontDescription->from_string($settings->{title_font} . ' ' . $settings->{title_size} . 'px');
$layout->set_font_description($desc);
my ($w, $h) = $layout->get_pixel_size();
$cr->save();
$cr->move_to($settings->{width}/2 - $w/2, $settings->{margin_top});
Pango::Cairo::show_layout($cr, $layout);
$cr->restore();
return $h + $settings->{margin_top} + $settings->{border_size};
}
=head2 draw_small_calendar($cr, $x, $y, $width, $height, $settings, $month, $days, $start_wkday)
Draw a small calendar on the Cairo context C<$cr>. The top left-hand
corner of the box is at C<($x, $y)> and the size of the box is
C<($width, $height>). $settings is the settings hashref passed to
C<render>. C<$month> is the name of the month to draw and C<$days> is
the number of days in the month. Finally, C<$start_wkday> is the
weekday (0=Sunday, 6=Saturday) on which the month starts
=cut
sub draw_small_calendar
{
my ($self, $cr, $x, $y, $width, $height, $settings, $month, $days, $start_wkday) = @_;
my $first_col = $start_wkday;
if ($self->{mondayfirst}) {
$first_col--;
if ($first_col < 0) {
$first_col = 6;
}
}
# Last column
my $last_col = ($first_col + $days - 1) % 7;
# Number of rows
my $rows = 1;
my $last_day_on_row = 7 - $first_col;
while ($last_day_on_row < $days) {
$last_day_on_row += 7;
$rows++;
}
my $font_size = $self->calculate_small_calendar_font_size($cr, $width, $height, $settings, $rows);
my $layout = Pango::Cairo::create_layout($cr);
my $desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
$layout->set_font_description($desc);
$layout->set_text('88 ');
my ($wid, $h) = $layout->get_pixel_size();
$h += 1;
# Month name
$layout = Pango::Cairo::create_layout($cr);
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
$layout->set_font_description($desc);
$layout->set_text(Encode::decode('UTF-8', $month));
my ($mw, $mh) = $layout->get_pixel_size();
$cr->save();
$cr->move_to($x + $width/2 - $mw/2, $y);
Pango::Cairo::show_layout($cr, $layout);
$cr->restore();
$y += $h;
# Day names
for (my $col=0; $col <7; $col++) {
my $j;
if ($self->{mondayfirst}) {
$j = ($col + 1) % 7;
} else {
$j = $col;
}
my $day = $self->{daynames}->[$j];
my $l = substr(Encode::decode('UTF-8', $day), 0, 1);
$layout = Pango::Cairo::create_layout($cr);
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
$layout->set_font_description($desc);
$layout->set_text($l);
$cr->save();
$cr->move_to($x + $col*$wid, $y);
Pango::Cairo::show_layout($cr, $layout);
$cr->restore();
}
$y += $h;
my $col = $start_wkday;
for (my $d=1; $d <= $days; $d++) {
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
$layout->set_font_description($desc);
$layout->set_text($d);
$cr->save();
$cr->move_to($x + $col*$wid, $y);
Pango::Cairo::show_layout($cr, $layout);
$cr->restore();
$col++;
if ($col > 6) {
$col = 0;
$y += $h;
}
}
}
sub calculate_small_calendar_font_size
{
my ($self, $cr, $width, $height, $settings, $rows) = @_;
my $layout = Pango::Cairo::create_layout($cr);
my $desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . '10px');
$layout->set_font_description($desc);
$layout->set_text('88 88 88 88 88 88 88');
my ($wid, $h) = $layout->get_pixel_size();
$h += 1;
$h *= ($rows + 2); # row for month name; row for day names
my $scale = $width / $wid;
if (($height / $h) < $scale) {
$scale = $height / $h;
}
my $font_size = int($scale * 10);
# Check
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
$layout->set_font_description($desc);
$layout->set_text('88 88 88 88 88 88 88');
($wid, $h) = $layout->get_pixel_size();
$h += 1;
$h *= ($rows + 2); # row for month name; row for day names
$scale = $width / $wid;
if (($height / $h) < $scale) {
$scale = $height / $h;
}
if ($scale < 1) { # Font size is too big
$font_size--;
}
return $font_size;
}
package Remind::PDF::Multi;
=head1 NAME
Remind::PDF::Multi - A container for multiple months' worth of calendar data
=head1 DESCRIPTION
The C<remind -ppp> output consists of a JSON array with each element
representing one month's worth of reminders. C<Remind::PDF::Multi>
reads this output and returns an instance of itself containing
an array of C<Remind::PDF> objects, one object for each month.
=head1 CLASS METHODS
=head2 Remind::PDF::Multi->create_from_stream($in, $specials_accepted)
This method reads data from an open file handle C<$in>. C<$specials_accepted>
is a hashref of SPECIAL reminder types to accept; the key is the name of the
SPECIAL (all lower-case) and the value should be 1. Any SPECIAL reminders
not in the hash are ignored.
This function returns a two-element array: C<($obj, $err)>. On
success, C<$obj> will be a C<Remind::PDF::Multi> object and C<$err>
will be undef. On failure, C<$obj> will be undef and C<$err> will be
an error message.
=cut
sub create_from_stream
{
my ($class, $in, $specials_accepted) = @_;
my $json = "[\n";
my $right_bracket = 0;
my $right_curly = 0;
while(<$in>) {
$json .= $_;
chomp;
if ($_ eq ']') {
$right_bracket++;
if ($right_bracket == 2 && $right_curly == 1) {
return $class->create_from_json($json, $specials_accepted);
}
} elsif($_ eq '}') {
$right_curly++;
} else {
$right_bracket = 0;
$right_curly = 0;
}
}
return(undef, 'Unable to parse JSON stream');
}
=head2 Remind::PDF::Multi->create_from_stream($json, $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
SPECIAL (all lower-case) and the value should be 1. Any SPECIAL reminders
not in the hash are ignored.
This function returns a two-element array: C<($obj, $err)>. On
success, C<$obj> will be a C<Remind::PDF::Multi> object and C<$err>
will be undef. On failure, C<$obj> will be undef and C<$err> will be
an error message.
=cut
sub create_from_json
{
my ($class, $json, $specials_accepted) = @_;
my $parser = JSON::MaybeXS->new(utf8 => 0);
my $array;
eval {
$array = $parser->decode($json);
};
if (!$array) {
return (undef, "Unable to decode JSON: $@");
}
if (ref($array) ne 'ARRAY') {
return (undef, "Expecting array; found " . ref($array));
}
my $self = bless { months => []}, $class;
foreach my $m (@$array) {
my ($e, $error) = Remind::PDF->create_from_hash($m, $specials_accepted);
if (!$e) {
return (undef, $error);
}
push(@{$self->{entries}}, $e);
}
return ($self, undef);
}
=head1 INSTANCE METHODS
=head2 render($cr, $settings)
Iterate through all the C<Remind::PDF> objects
and call their C<render> methods. This method
renders as many months worth of calendar data
as were read from the C<remind -ppp> stream
=cut
sub render
{
my ($self, $cr, $settings) = @_;
foreach my $e (@{$self->{entries}}) {
$e->render($cr, $settings);
}
}
1;

View File

@@ -0,0 +1,311 @@
package Remind::PDF::Entry;
use strict;
use warnings;
use Cairo;
use Pango;
use Encode;
=head1 NAME
Remind::PDF::Entry - Representation of one calendar entry
=head1 DESCRIPTION
C<Remind::PDF::Entry> and its subclasses represent one calendar
entry. They can be normal reminder-type entries or SPECIAL reminders.
=head1 CLASS METHODS
=head2 Remind::PDF::Entry->new_from_hash($hash)
Create and return a new C<Remind::PDF::Entry> based on one reminder's
worth of data from C<remind -p>. Returns a C<Remind::PDF::Entry> object,
or in the case of SPECIAL reminders, a subclass of C<Remind::PDF::Entry>.
=cut
sub new_from_hash
{
my ($class, $hash) = @_;
if (exists($hash->{passthru})) {
my $special = lc($hash->{passthru});
if ($special =~ /^(html|htmlclass|week|moon|shade|color|colour|postscript|psfile|pango)$/) {
$special = 'color' if $special eq 'colour';
$class = 'Remind::PDF::Entry::' . $special;
} else {
$class = 'Remind::PDF::Entry::UNKNOWN';
}
}
bless $hash, $class;
$hash->_adjust();
return $hash;
}
# Base class: Set the color to black
sub _adjust
{
my ($self) = @_;
$self->{r} = 0;
$self->{g} = 0;
$self->{b} = 0;
}
=head1 INSTANCE METHODS
=head2 render($pdf, $cr, $settings, $so_far, $day, $col, $height)
Render a single entry. C<$pdf> is the parent C<Remind::PDF>
object. C<$cr> is a Cairo drawing context and C<$settings> is the
usual settings hash. C<$so_far> is the Y-coordinate at which
to start drawing. C<$day> is the month day and C<$col> is
the calendar column. C<$height> is the height of the calendar
box.
If C<$height> is zero, then nothing should actually be drawn,
but the height of the calendar entry should be computed.
Returns the height of the calendar entry.
=cut
sub render
{
my ($self, $pdf, $cr, $settings, $so_far, $day, $col, $height) = @_;
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
my $layout = Pango::Cairo::create_layout($cr);
$layout->set_width(1024 * ($x2 - $x1 - 2 * $settings->{border_size}));
$layout->set_wrap('word-char');
$layout->set_text(Encode::decode('UTF-8', $self->{body}));
my $desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . $settings->{entry_size} . 'px');
$layout->set_font_description($desc);
my ($wid, $h) = $layout->get_pixel_size();
if ($height) {
$cr->save();
$cr->set_source_rgb($self->{r} / 255,
$self->{g} / 255,
$self->{b} / 255);
$cr->move_to($x1 + $settings->{border_size}, $so_far);
Pango::Cairo::show_layout($cr, $layout);
$cr->restore();
}
return $h;
}
package Remind::PDF::Entry::html;
use base 'Remind::PDF::Entry';
sub render {}
package Remind::PDF::Entry::htmlclass;
use base 'Remind::PDF::Entry';
sub render {}
package Remind::PDF::Entry::week;
use base 'Remind::PDF::Entry';
sub render
{
my ($self, $pdf, $cr, $settings, $so_far, $day, $col, $height) = @_;
# Do nothing in pre-render mode
return 0 unless $height;
# Render in small text at bottom-right
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
my $layout = Pango::Cairo::create_layout($cr);
$layout->set_text(Encode::decode('UTF-8', $self->{body}));
my $desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . int(0.75 * $settings->{entry_size}) . 'px');
$layout->set_font_description($desc);
my ($wid, $h) = $layout->get_pixel_size();
$cr->save();
$cr->move_to($x2 - $settings->{border_size}/4 - $wid, $y2 - $settings->{border_size}/4 - $h);
Pango::Cairo::show_layout($cr, $layout);
$cr->restore();
return 0;
}
package Remind::PDF::Entry::moon;
use base 'Remind::PDF::Entry';
sub _adjust {
my ($self) = @_;
my ($phase, $size, $fontsize, $msg) = split(/\s+/, $self->{body}, 4);
$phase = '' unless defined($phase);
$size = -1 unless defined($size);
$fontsize = -1 unless defined($fontsize);
$msg = '' unless defined($msg);
$self->{phase} = $phase;
$self->{size} = $size;
$self->{fontsize} = $fontsize;
$self->{body} = $msg;
}
sub render
{
my ($self, $pdf, $cr, $settings, $so_far, $day, $col, $height) = @_;
# Do nothing in pre-render mode
return 0 unless $height;
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
my $layout;
my $bodywidth = 0;
if ($self->{fontsize} <= 0) {
$self->{fontsize} = $settings->{entry_size};
}
if ($self->{size} <= 0) {
$self->{size} = $settings->{daynum_size};
}
if ($self->{phase} !~ /^[0123]$/) {
# Invalid phase
return 0;
}
if ($self->{body} ne '') {
$layout = Pango::Cairo::create_layout($cr);
$layout->set_text(Encode::decode('UTF-8', $self->{body}));
my $desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . $self->{fontsize} . 'px');
$layout->set_font_description($desc);
($bodywidth, undef) = $layout->get_pixel_size();
}
my ($xc, $yc);
if ($settings->{numbers_on_left}) {
$yc = $so_far + $settings->{border_size} + ($self->{size} / 2);
$xc = $x2 - $settings->{border_size} - ($self->{size} / 2);
if ($bodywidth) {
$xc -= ($bodywidth + $settings->{border_size});
}
} else {
$xc = $x1 + $settings->{border_size} + ($self->{size} / 2);
$yc = $so_far + $settings->{border_size} + ($self->{size} / 2);
}
$self->draw_moon($xc, $yc, $cr);
if ($layout) {
$cr->save();
$cr->move_to ($xc + ($self->{size}/2) + $settings->{border_size},
$yc + ($self->{size}/2) - $self->{fontsize} );
Pango::Cairo::show_layout($cr, $layout);
$cr->restore();
}
}
sub draw_moon
{
my ($self, $xc, $yc, $cr) = @_;
$cr->save();
$cr->new_path();
$cr->arc($xc, $yc, $self->{size}/2, 0, 2*3.1415926535);
if ($self->{phase} == 0) {
$cr->stroke_preserve();
$cr->fill();
} elsif ($self->{phase} == 1) {
$cr->stroke();
$cr->arc($xc, $yc, $self->{size}/2, 3.1415926535/2, 3 * 3.1415926535/2);
$cr->stroke_preserve();
$cr->fill();
} elsif ($self->{phase} == 2) {
$cr->stroke();
} elsif ($self->{phase} == 3) {
$cr->stroke();
$cr->arc($xc, $yc, $self->{size}/2, 3 * 3.1415926535/2, 3.1415926535/2);
$cr->stroke_preserve();
$cr->fill();
}
$cr->restore();
}
package Remind::PDF::Entry::shade;
use base 'Remind::PDF::Entry';
sub _adjust
{
my ($self) = @_;
if ($self->{body} =~ /^(\d+)\s+(\d+)\s+(\d+)/) {
$self->{r} = $1;
$self->{g} = $2;
$self->{b} = $3;
}
}
package Remind::PDF::Entry::color;
use base 'Remind::PDF::Entry';
# Strip the RGB prefix from body
sub _adjust
{
my ($self) = @_;
$self->{body} =~ s/^\d+\s+\d+\s+\d+\s+//;
}
package Remind::PDF::Entry::postscript;
use base 'Remind::PDF::Entry';
sub render {}
package Remind::PDF::Entry::psfile;
use base 'Remind::PDF::Entry';
sub render {}
package Remind::PDF::Entry::pango;
use base 'Remind::PDF::Entry';
sub _adjust
{
my ($self) = @_;
if ($self->{body} =~ /^@([-0-9.]+),\s*([-0-9.]+)\s*(.*)/) {
$self->{atx} = $1;
$self->{aty} = $2;
$self->{body} = $3;
}
}
sub render
{
my ($self, $pdf, $cr, $settings, $so_far, $day, $col, $height) = @_;
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
my $layout = Pango::Cairo::create_layout($cr);
$layout->set_width(1024 * ($x2 - $x1 - 2 * $settings->{border_size}));
$layout->set_wrap('word-char');
$layout->set_markup(Encode::decode('UTF-8', $self->{body}));
if (($layout->get_text() // '') eq '') {
# Invalid markup
return 0;
}
my $desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . $settings->{entry_size} . 'px');
$layout->set_font_description($desc);
my ($wid, $h) = $layout->get_pixel_size();
if ($height) {
$cr->save();
if (defined($self->{atx}) && defined($self->{aty})) {
my ($x, $y);
if ($self->{atx} < 0) {
$x = $x2 + $self->{atx} - $wid;
} else {
$x = $x1 + $self->{atx};
}
if ($self->{aty} < 0) {
$y = $y2 + $self->{aty} - $h;
} else {
$y = $y1 + $self->{aty};
}
$cr->move_to($x, $y);
} else {
$cr->move_to($x1 + $settings->{border_size}, $so_far);
}
Pango::Cairo::show_layout($cr, $layout);
$cr->restore();
}
return $h;
}
package Remind::PDF::Entry::UNKNOWN;
use base 'Remind::PDF::Entry';
sub render {}
1;

View File

@@ -127,6 +127,12 @@ set OptDescr(BackgroundColor) "Default background color of calendar boxes"
set Option(TextColor) "#000000"
set OptDescr(TextColor) "Default text color in calendar boxes"
set Option(TodayColor) "#00C0C0"
set OptDescr(TodayColor) "Background color for today heading"
set Option(LineColor) "#000000"
set OptDescr(LineColor) "Color of gridlines on calendar"
set Option(LabelColor) "#000000"
set OptDescr(LabelColor) "Default label color for headings"
@@ -141,6 +147,18 @@ set Remind "remind"
# Rem2PS program to execute -- supply full path if you want
set Rem2PS "rem2ps"
# Rem2PDF program to execute -- supply full path if you want
set Rem2PDF "rem2pdf"
# Check if we have Rem2PDF
set HaveRem2PDF 0
set a [exec sh -c "$Rem2PDF < /dev/null 2>&1 || true"]
if {[string match "rem2pdf:*" "$a"]} {
set HaveRem2PDF 1
}
# Reminder file to source -- default
set ReminderFile {NOSUCHFILE}
set ReminderFile [file nativename "~/.reminders"]
@@ -172,12 +190,12 @@ set MondayFirst 0
# Month names in English
set MonthNames {January February March April May June July August September October November December}
# Day names in Remind's pre-selected language
set DayNames {}
# Day name in English
set EnglishDayNames {Sunday Monday Tuesday Wednesday Thursday Friday Saturday}
# Day names in Remind's pre-selected language - will be overwritten
set DayNames $EnglishDayNames
# Current month and year -- will be set by Initialize procedure
set CurMonth -1
set CurYear -1
@@ -186,9 +204,13 @@ set CurYear -1
set BgCounter 0
# Absolutely today -- unlike the CurMonth and CurYear, these won't change
set TodayMonth -1
set TodayYear -1
set TodayDay -1
set now [clock seconds]
set TodayMonth [expr [string trim [clock format $now -format %N]] - 1]
set TodayYear [clock format $now -format %Y]
set TodayDay [string trim [clock format $now -format %e]]
set CurMonth $TodayMonth
set CurYear $TodayYear
# Reminder option types and skip types
set OptionType 1
@@ -223,6 +245,9 @@ set Option(PrintMargins) 36pt
set OptDescr(PrintSmallCalendars) "(0/1) If 1, print small calendars in PostScript output"
set Option(PrintSmallCalendars) 1
set OptDescr(PrintFormat) "Print format: pdf or ps"
set Option(PrintFormat) ps
set WarningHeaders [list "# Lines staring with REM TAG TKTAGnnn ... were created by tkremind" "# Do not edit them by hand or results may be unpredictable."]
# Highest tag seen so far. Array of tags is stored in ReminderTags()
@@ -261,10 +286,19 @@ proc is_warning_header { line } {
# MondayFirst flag, current date, etc.
#***********************************************************************
proc Initialize {} {
global DayNames argc argv CommandLine ReminderFile AppendFile Remind PSCmd
global MondayFirst TwentyFourHourMode ReminderFileModTime
global TodayDay TodayMonth TodayYear
global Option ConfigFile
# In case date has rolled over, recalculate Today* values
set now [clock seconds]
set TodayMonth [expr [string trim [clock format $now -format %N]] - 1]
set TodayYear [clock format $now -format %Y]
set TodayDay [string trim [clock format $now -format %e]]
set CommandLine "|$Remind -itkremind=1 -pp -y -l EXTRA"
set PSCmd "$Remind -itkremind=1 -itkprint=1 -pp -l EXTRA"
set i 0
@@ -340,7 +374,6 @@ proc Initialize {} {
append CommandLine " $ReminderFile"
append PSCmd " $ReminderFile"
set DayNames [GetWeekdayNames]
# Get modification time of ReminderFile
set ReminderFileModTime -1
@@ -383,40 +416,6 @@ proc MonitorReminderFile {} {
ScheduleUpdateForChanges
}
}
#---------------------------------------------------------------------------
# GetWeekdayNames - Spawn a remind process and get the names of the weekdays
# Also sets CurMonth and CurYear.
#---------------------------------------------------------------------------
proc GetWeekdayNames {} {
global CurMonth CurYear TodayYear TodayMonth TodayDay Remind
set f [open "|$Remind - 2>/dev/null" r+]
puts $f "banner %"
set i 0
while { $i < 7 } {
puts $f "msg \[wkday($i)\]%"
incr i
}
# Get current month and year as long as we're running Remind
puts $f "msg %n%"
puts $f "msg %y%"
puts $f "msg %d%"
puts $f "FLUSH"
flush $f
set ans {}
set i 0
while { $i < 7 } {
lappend ans [gets $f]
incr i
}
set CurMonth [expr [gets $f] - 1]
set CurYear [gets $f]
set TodayDay [gets $f]
set TodayMonth $CurMonth
set TodayYear $CurYear
close $f
return $ans
}
#***********************************************************************
# %PROCEDURE: CalEntryOffset
@@ -466,7 +465,7 @@ proc CreateCalFrame { w dayNames } {
}
global MondayFirst
frame $w -background $Option(WinBackground)
frame $w -background $Option(LineColor)
for {set i 0} {$i < 7} {incr i} {
if {$MondayFirst} {
set index [expr ($i+1)%7]
@@ -474,28 +473,31 @@ proc CreateCalFrame { w dayNames } {
set index $i
}
label $w.day$i -border 1 -text [lindex $dayNames $index] -justify center -font HeadingFont -foreground $Option(LabelColor) -background $Option(WinBackground)
grid configure $w.day$i -row 0 -column $i -sticky ew
label $w.day$i -bd 0 -text [lindex $dayNames $index] -justify center -font HeadingFont -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
grid configure $w.day$i -row 0 -column $i -sticky ew -padx 1 -pady 1
}
for {set i 0} {$i < 6} {incr i} {
set n [expr $i*7]
for {set j 0} {$j < 7} {incr j} {
set f [expr $n+$j]
button $w.l$f -text "" -justify center -command "" \
-state disabled -relief flat -border 0 -padx 0 -pady 0 -font HeadingFont
text $w.t$f -width 12 -height $h -border 1 -spacing3 3 -wrap word -relief flat \
-state disabled -takefocus 0 -cursor {} -font CalboxFont -foreground $Option(TextColor) -background $Option(BackgroundColor)
-state disabled -relief flat -bd 0 -padx 0 -pady 0 -font HeadingFont -highlightthickness 1
text $w.t$f -width 12 -height $h -bd 0 -spacing3 3 -wrap word -relief flat \
-state disabled -takefocus 0 -cursor {} -font CalboxFont -foreground $Option(TextColor) -background $Option(BackgroundColor) \
-highlightthickness 0
frame $w.f$f -padx 0 -pady 0 -highlightthickness 0 -relief flat -bd 0
$w.t$f tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$f"
$w.t$f tag bind REM <ButtonPress-3> "FireEditor $w.t$f"
grid configure $w.l$f -row [expr $i*2+1] -column $j -sticky ew
grid configure $w.t$f -row [expr $i*2+2] -column $j -sticky nsew
pack $w.l$f -in $w.f$f -side top -expand 0 -fill x
pack $w.t$f -in $w.f$f -side top -expand 1 -fill both
grid configure $w.f$f -row [expr $i+1] -column $j -sticky nsew -padx 1 -pady 1
}
}
for {set i 0} {$i < 7} {incr i} {
grid columnconfigure $w $i -weight 1
}
for {set i 2} {$i < 14} {incr i 2} {
for {set i 1} {$i < 7} {incr i} {
grid rowconfigure $w $i -weight 1
}
}
@@ -521,8 +523,12 @@ proc ConfigureCalFrame { w firstDay numDays } {
set last [expr $offset+$numDays]
for {set i 0} {$i < $first} {incr i} {
grid $w.l$i $w.t$i
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground)
grid $w.f$i
pack $w.l$i -in $w.f$i -side top -expand 0 -fill x
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
raise $w.l$i
raise $w.t$i
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
$w.l$i configure -state disabled
balloon_add_help $w.l$i ""
$w.t$i configure -relief flat -takefocus 0 -state normal -background $Option(WinBackground)
@@ -532,13 +538,17 @@ proc ConfigureCalFrame { w firstDay numDays } {
}
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
$w.t$i configure -state disabled
$w.t$i configure -state disabled -takefocus 0
}
for {set i $first} {$i <= $last} {incr i} {
grid $w.l$i $w.t$i
grid $w.f$i
pack $w.l$i -in $w.f$i -side top -expand 0 -fill x
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
raise $w.l$i
raise $w.t$i
set d [expr $i-$first+1]
$w.l$i configure -text $d -state normal -relief flat \
-command "ModifyDay $d $firstDay" -foreground $Option(LabelColor) -background $Option(WinBackground)
-command "ModifyDay $d $firstDay" -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help $w.l$i "Add a reminder..."
$w.t$i configure -relief sunken -takefocus 1 -state normal -foreground $Option(TextColor) -background $Option(BackgroundColor)
$w.t$i delete 1.0 end
@@ -547,23 +557,27 @@ proc ConfigureCalFrame { w firstDay numDays } {
}
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
$w.t$i configure -state disabled
$w.t$i configure -state disabled -takefocus 0
}
set forgetIt 0
for {set i [expr $last+1]} {$i < 42} {incr i} {
if {$i%7 == 0} {
set forgetIt 1
}
set row [expr ($i/7)*2+1]
set row [expr ($i/7)+1]
if {$forgetIt} {
grid remove $w.l$i $w.t$i
grid remove $w.f$i
grid rowconfigure $w $row -weight 0
grid rowconfigure $w [expr $row+1] -weight 0
} else {
grid $w.l$i $w.t$i
grid $w.f$i
pack $w.l$i -in $w.f$i -side top -expand 0 -fill x
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
raise $w.l$i
raise $w.t$i
grid rowconfigure $w [expr $row+1] -weight 1
}
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground)
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
$w.l$i configure -state disabled
balloon_add_help $w.l$i ""
$w.t$i configure -relief flat -takefocus 0 -state normal -background $Option(WinBackground)
@@ -573,11 +587,11 @@ proc ConfigureCalFrame { w firstDay numDays } {
}
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
$w.t$i configure -state disabled
$w.t$i configure -state disabled -takefocus 0
}
if { $CurMonth == $TodayMonth && $CurYear == $TodayYear } {
set n [expr $TodayDay + $offset]
$w.l$n configure -background "#00c0c0"
$w.l$n configure -background $Option(TodayColor)
}
}
@@ -594,36 +608,36 @@ proc DoQueue {} {
#---------------------------------------------------------------------------
proc CreateCalWindow { dayNames } {
global Option
frame .h -background $Option(WinBackground);
label .h.title -text "" -justify center -pady 1 -border 1 -relief raised -font HeadingFont -background $Option(WinBackground) -foreground $Option(LabelColor)
pack .h.title -side top -fill x
frame .h -background $Option(LineColor)
label .h.title -text "" -justify center -pady 2 -bd 0 -relief flat -font HeadingFont -background $Option(WinBackground) -foreground $Option(LabelColor)
pack .h.title -side top -fill x -pady 1 -padx 1
pack .h -side top -expand 0 -fill x
. configure -background $Option(LineColor)
CreateCalFrame .cal $dayNames
frame .b -background $Option(WinBackground);
button .b.prev -text "\u2b9c" -command {MoveMonth -1} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
frame .b -background $Option(LineColor)
button .b.prev -text "\u2b9c" -command {MoveMonth -1} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.prev "Go to previous month"
button .b.this -text {Today} -command {ThisMonth} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
button .b.this -text {Today} -command {ThisMonth} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.this "Go to this month"
button .b.next -text "\u2b9e" -command {MoveMonth 1} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
button .b.next -text "\u2b9e" -command {MoveMonth 1} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.next "Go to next month"
button .b.goto -text {Go To Date...} -command {GotoDialog} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
button .b.goto -text {Go To Date...} -command {GotoDialog} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.goto "Go to a specific date"
button .b.print -text {Print...} -command {DoPrint} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
balloon_add_help .b.print "Print a PostScript calendar"
button .b.queue -text {Queue...} -command {DoQueue} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
balloon_add_help .b.queue "See the queue of pending reminders (debugging purposes only)"
button .b.quit -text {Quit} -command {Quit} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
balloon_add_help .b.quit "Quit TkRemind"
button .b.options -text {Options...} -command EditOptions -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
button .b.print -text {Print...} -command {DoPrint} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.print "Print a PostScript or PDF calendar"
button .b.options -text {Options...} -command EditOptions -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.options "Set TkRemind options"
label .b.status -text "" -width 25 -relief sunken -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
label .b.nqueued -text "" -width 20 -relief sunken -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
pack .b.prev .b.this .b.next .b.goto .b.print .b.options .b.queue .b.quit -side left -fill both
pack .b.status -side left -fill both -expand 1
pack .b.nqueued -side left -fill both
pack .b -side bottom -fill x -expand 0
button .b.queue -text {Queue...} -command {DoQueue} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.queue "See the queue of pending reminders (debugging purposes only)"
button .b.quit -text {Quit} -command {Quit} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.quit "Quit TkRemind"
label .b.status -text "" -width 25 -relief flat -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
label .b.nqueued -text "" -width 20 -relief flat -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
pack .b.prev .b.this .b.next .b.goto .b.print .b.options .b.queue .b.quit -side left -fill both -padx 1
pack .b.status -side left -fill both -expand 1 -padx 1
pack .b.nqueued -side left -fill both -padx 1
pack .b -side bottom -fill x -expand 0 -pady 1
pack .cal -side top -fill both -expand 1
wm title . "TkRemind"
wm iconname . ""
@@ -706,7 +720,7 @@ proc EditOptions {} {
pack $w.cmd -in $w.rf -side left -expand 1 -fill x
$w.cmd insert 0 $tmpOpt(RunCmd)
frame $w.sep3 -border 1 -relief sunken
frame $w.sep3 -bd 1 -relief sunken
# E-mail reminder if popup not dismissed
frame $w.eml
label $w.lab_email_address -text "E-mail reminders here if popup not dismissed:" -anchor w -justify left
@@ -751,6 +765,12 @@ proc EditOptions {} {
label $w.bgcolor -text " Background color:"
button $w.bbgcolor -background $Option(BackgroundColor) -command [list PickColor BackgroundColor $w.bbgcolor] -text ...
label $w.tbgcolor -text "Color for highlighting \"today\":"
button $w.tbbgcolor -background $Option(TodayColor) -command [list PickColor TodayColor $w.tbbgcolor] -text ...
label $w.gridcolor -text " Gridline color:"
button $w.gridbcolor -background $Option(LineColor) -command [list PickColor LineColor $w.gridbcolor] -text ...
grid $w.textcolor $w.btextcolor $w.bgcolor $w.bbgcolor -in $w.colors1
grid $w.bgcolor $w.bbgcolor -in $w.colors1
@@ -759,11 +779,12 @@ proc EditOptions {} {
label $w.wincolor -text " Window color:"
button $w.bwincolor -background $Option(WinBackground) -command [list PickColor WinBackground $w.bwincolor] -text ...
grid $w.headcolor $w.bheadcolor $w.wincolor $w.bwincolor -in $w.colors1
grid $w.tbgcolor $w.tbbgcolor $w.gridcolor $w.gridbcolor -in $w.colors1
grid columnconfigure $w.colors1 0 -weight 1
grid columnconfigure $w.colors1 2 -weight 1
frame $w.sep1 -border 1 -relief sunken
frame $w.sep2 -border 1 -relief sunken
frame $w.sep1 -bd 1 -relief sunken
frame $w.sep2 -bd 1 -relief sunken
checkbutton $w.feed \
-text "Feed popped-up reminder to command's standard input" \
@@ -787,10 +808,12 @@ proc EditOptions {} {
pack $w.colors1 -in $w.f -side top -expand 0 -fill x
pack $w.sep2 -in $w.f -side top -expand 0 -fill x -ipady 1
button $w.default -text "Light Theme" -command [list set_default_colors $w]
button $w.dark -text "Dark Theme" -command [list set_dark_colors $w]
button $w.save -text "Save Options" -command "SaveOptions $w; destroy $w"
button $w.cancel -text "Cancel" -command "CancelOptions; destroy $w"
wm protocol $w WM_DELETE_WINDOW "CancelOptions; destroy $w"
pack $w.save $w.cancel -in $w.b -side left -expand 0 -fill x
pack $w.default $w.dark $w.save $w.cancel -in $w.b -side left -expand 0 -fill x
CenterWindow $w .
}
@@ -862,6 +885,10 @@ proc SaveOptions { w } {
.b.queue configure -foreground $Option(LabelColor) -background $Option(WinBackground)
.b.quit configure -foreground $Option(LabelColor) -background $Option(WinBackground)
.b.options configure -foreground $Option(LabelColor) -background $Option(WinBackground)
. configure -background $Option(LineColor);
.h configure -background $Option(LineColor);
.cal configure -background $Option(LineColor)
.b configure -background $Option(LineColor)
}
proc WriteOptionsToFile {} {
@@ -981,9 +1008,21 @@ proc FillCalWindow {} {
gets $file line
regexp {^([^ ]*) ([0-9][0-9][0-9][0-9]) ([0-9][0-9]?) ([0-9]) ([0-9])} $line dummy monthName year daysInMonth firstWkday mondayFirst
# Skip day names -- we already have them
set monthName [regsub -all {_} $monthName " "]
# Get the day names
gets $file line
set DayNames {}
foreach day $line {
set day [regsub -all {_} $day " "];
lappend DayNames $day
}
ConfigureCalWindow $monthName $year $firstWkday $daysInMonth
# Update the day names in the calendar window
for {set i 0} {$i < 7} {incr i} {
.cal.day$i configure -text [lindex $DayNames $i]
}
set offset [CalEntryOffset $firstWkday]
while { [gets $file line] >= 0 } {
@@ -1037,7 +1076,7 @@ proc FillCalWindow {} {
continue
}
"MOON" {
DoMoonSpecial $n $stuff $fntag
DoMoonSpecial $n $stuff $fntag $day
continue
}
"COLOUR" -
@@ -1062,7 +1101,7 @@ proc FillCalWindow {} {
set extratags "clr$color"
.cal.t$n configure -state normal
.cal.t$n tag configure $extratags -foreground "#$color"
.cal.t$n configure -state disabled
.cal.t$n configure -state disabled -takefocus 0
set stuff $rest
set type "COLOR"
}
@@ -1088,7 +1127,7 @@ proc FillCalWindow {} {
}
}
.cal.t$n insert end "\n"
.cal.t$n configure -state disabled
.cal.t$n configure -state disabled -takefocus 0
}
set problem [catch { close $file } errmsg]
@@ -1150,19 +1189,20 @@ proc Status { stuff } {
# None
#---------------------------------------------------------------------------
proc DoPrint {} {
global Rem2PS PSCmd Option PrintStatus
global Rem2PS Rem2PDF HaveRem2PDF PSCmd Option PrintStatus
global CurMonth CurYear MonthNames
catch {destroy .p}
toplevel .p
wm title .p "TkRemind Print..."
wm iconname .p "Print..."
frame .p.f1 -relief sunken -border 2
frame .p.f1 -relief sunken -bd 2
frame .p.f11
frame .p.f12
frame .p.f2 -relief sunken -border 2
frame .p.f2a -relief sunken -border 2
frame .p.f3 -relief sunken -border 2
frame .p.f3a -relief sunken -border 2
frame .p.f2 -relief sunken -bd 2
frame .p.f2a -relief sunken -bd 2
frame .p.f3 -relief sunken -bd 2
frame .p.f3a -relief sunken -bd 2
frame .p.f4
radiobutton .p.tofile -text "To file: " -variable Option(PrintDest) -value file
@@ -1172,6 +1212,13 @@ proc DoPrint {} {
entry .p.command
.p.command insert end "lpr"
if { $HaveRem2PDF } {
frame .p.ff -relief sunken -bd 2
label .p.format -text "Output Format:"
radiobutton .p.pdf -text "PDF" -variable Option(PrintFormat) -value pdf
radiobutton .p.ps -text "PostScript" -variable Option(PrintFormat) -value ps
}
label .p.size -text "Paper Size:"
radiobutton .p.letter -text "Letter" -variable Option(PrintSize) -value letter
radiobutton .p.a4 -text "A4" -variable Option(PrintSize) -value a4
@@ -1193,14 +1240,22 @@ proc DoPrint {} {
button .p.print -text "Print" -command {set PrintStatus print}
button .p.cancel -text "Cancel" -command {set PrintStatus cancel}
pack .p.f1 .p.f2 .p.f2a .p.f3 .p.f3a \
-side top -fill both -expand 1 -anchor w
if {$HaveRem2PDF} {
pack .p.f1 .p.ff .p.f2 .p.f2a .p.f3 .p.f3a \
-side top -fill both -expand 1 -anchor w
} else {
pack .p.f1 .p.f2 .p.f2a .p.f3 .p.f3a \
-side top -fill both -expand 1 -anchor w
}
pack .p.fill .p.right .p.encoding .p.calendars -in .p.f3a \
-side top -anchor w -fill none -expand 0
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.tofile .p.filename .p.browse -in .p.f11 -side left -fill none -expand 0 -anchor w
pack .p.tocmd .p.command -in .p.f12 -side left -fill none -expand 0 -anchor w
if { $HaveRem2PDF } {
pack .p.format .p.pdf .p.ps -in .p.ff -side top -fill none -expand 0 -anchor w
}
pack .p.size .p.letter .p.a4 -in .p.f2 -side top -fill none -expand 0 -anchor w
pack .p.margin .p.24pt .p.36pt .p.48pt -in .p.f2a -side top -anchor w -fill none -expand 0
pack .p.orient .p.landscape .p.portrait -in .p.f3 -side top -fill none -expand 0 -anchor w
@@ -1243,21 +1298,47 @@ proc DoPrint {} {
set fname "| $cmd"
}
# Build the command line
set p [regsub EXTRA $PSCmd $Option(ExtraRemindArgs)]
set cmd "$p 1 [lindex $MonthNames $CurMonth] $CurYear | $Rem2PS"
if {$Option(PrintSize) == "letter"} {
append cmd " -m Letter"
if {$HaveRem2PDF && $Option(PrintFormat) == "pdf"} {
set p [regsub EXTRA $PSCmd "-itkpdf=1 $Option(ExtraRemindArgs)"]
set cmd "$p 1 [lindex $MonthNames $CurMonth] $CurYear | $Rem2PDF"
} else {
append cmd " -m A4"
set p [regsub EXTRA $PSCmd $Option(ExtraRemindArgs)]
set cmd "$p 1 [lindex $MonthNames $CurMonth] $CurYear | $Rem2PS"
set Option(PrintFormat) ps
}
if {$Option(PrintSize) == "letter"} {
if {$Option(PrintFormat) == "ps"} {
append cmd " -m Letter"
} else {
append cmd " --media=Letter"
}
} else {
if {$Option(PrintFormat) == "ps"} {
append cmd " -m A4"
} else {
append cmd " --media=A4"
}
}
if {$Option(PrintMargins) == "24pt"} {
append cmd " -or 24 -ol 24 -ot 24 -ob 24"
if {$Option(PrintFormat) == "ps"} {
append cmd " -or 24 -ol 24 -ot 24 -ob 24"
} else {
append cmd " --margin-right=24 --margin-left=24 --margin-top=24 --margin-bottom=24"
}
} elseif {$Option(PrintMargins) == "36pt"} {
append cmd " -or 36 -ol 36 -ot 36 -ob 36"
if {$Option(PrintFormat) == "ps"} {
append cmd " -or 36 -ol 36 -ot 36 -ob 36"
} else {
append cmd " --margin-right=36 --margin-left=36 --margin-top=36 --margin-bottom=36"
}
} else {
append cmd " -or 48 -ol 48 -ot 48 -ob 48"
if {$Option(PrintFormat) == "ps"} {
append cmd " -or 48 -ol 48 -ot 48 -ob 48"
} else {
append cmd " --margin-right=48 --margin-left=48 --margin-top=48 --margin-bottom=48"
}
}
if {$Option(PrintOrient) == "landscape"} {
@@ -1272,7 +1353,9 @@ proc DoPrint {} {
append cmd " -x"
}
if {$Option(PrintEncoding)} {
append cmd " -i"
if {$Option(PrintFormat) == "ps"} {
append cmd " -i"
}
}
if {$Option(PrintSmallCalendars)} {
@@ -1412,16 +1495,16 @@ proc CreateModifyDialog {w day firstDay args} {
set month [lindex $MonthNames $CurMonth]
set wkday [lindex $EnglishDayNames [expr ($day+$firstDay-1) % 7]]
frame $w.o -border 4 -relief ridge
frame $w.o1 -border 4
frame $w.o2 -border 4
frame $w.o3 -border 4
frame $w.exp -border 4
frame $w.adv -border 4
frame $w.weekend -border 4
frame $w.durationbox -border 4
frame $w.time -border 4
frame $w.hol -border 4
frame $w.o -bd 4 -relief ridge
frame $w.o1 -bd 4
frame $w.o2 -bd 4
frame $w.o3 -bd 4
frame $w.exp -bd 4
frame $w.adv -bd 4
frame $w.weekend -bd 4
frame $w.durationbox -bd 4
frame $w.time -bd 4
frame $w.hol -bd 4
frame $w.msg
frame $w.buttons
pack $w.o1 $w.o2 $w.o3 -side top -anchor w -in $w.o
@@ -3491,7 +3574,7 @@ proc DoShadeSpecial { n r g b } {
# %DESCRIPTION:
# Handles the "MOON" special -- draws a moon symbol
#***********************************************************************
proc DoMoonSpecial { n stuff fntag } {
proc DoMoonSpecial { n stuff fntag day } {
set msg ""
set num [scan $stuff "%d %d %d %s" phase junk1 junk2 msg]
if {$num < 1} {
@@ -3500,11 +3583,27 @@ proc DoMoonSpecial { n stuff fntag } {
if {$phase < 0 || $phase > 3} {
return
}
switch -exact -- $phase {
0 { set win .moon_new }
1 { set win .moon_first }
2 { set win .moon_full }
3 { set win .moon_last }
# We need two sets of moon phase windows. There can be
# two of a given phase in the same month, but Tk does
# not allow the same embedded window in two separate
# text boxes. So we use this hack to make sure
# we use a different window if the same moon phase
# happens twice in a month.
if { $day < 16 } {
switch -exact -- $phase {
0 { set win .moon_new }
1 { set win .moon_first }
2 { set win .moon_full }
3 { set win .moon_last }
}
} else {
switch -exact -- $phase {
0 { set win .moon_new2 }
1 { set win .moon_first2 }
2 { set win .moon_full2 }
3 { set win .moon_last2 }
}
}
.cal.t$n configure -state normal
.cal.t$n window create 1.0 -window $win
@@ -3530,7 +3629,7 @@ proc DoMoonSpecial { n stuff fntag } {
.cal.t$n tag bind $fntag <ButtonPress-1> "FireEditor .cal.t$n $fntag"
}
}
.cal.t$n configure -state disabled
.cal.t$n configure -state disabled -takefocus 0
}
#***********************************************************************
# %PROCEDURE: DisplayTime
@@ -3568,6 +3667,11 @@ proc CreateMoonWindows {} {
catch { destroy .moon_full }
catch { destroy .moon_last }
catch { destroy .moon_new2 }
catch { destroy .moon_first2}
catch { destroy .moon_full2 }
catch { destroy .moon_last2 }
set extra 1
#set wid [font measure CalboxFont 0]
set wid [font metrics CalboxFont -ascent]
@@ -3594,10 +3698,29 @@ proc CreateMoonWindows {} {
.moon_last create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
.moon_last create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 270 -extent 180 -outline {}
canvas .moon_new2 -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
.moon_new2 create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
canvas .moon_first2 -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
.moon_first2 create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
.moon_first2 create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 90 -extent 180 -outline {}
canvas .moon_full2 -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
.moon_full2 create oval $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -width 1
canvas .moon_last2 -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
.moon_last2 create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
.moon_last2 create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 270 -extent 180 -outline {}
balloon_add_help .moon_new "New Moon"
balloon_add_help .moon_first "First Quarter"
balloon_add_help .moon_full "Full Moon"
balloon_add_help .moon_last "Last Quarter"
balloon_add_help .moon_new2 "New Moon"
balloon_add_help .moon_first2 "First Quarter"
balloon_add_help .moon_full2 "Full Moon"
balloon_add_help .moon_last2 "Last Quarter"
}
#***********************************************************************
@@ -3957,4 +4080,38 @@ proc FindConfigFile {} {
set ConfigFile "~/.tkremindrc"
}
proc set_default_colors { w } {
global tmpOpt
set tmpOpt(BackgroundColor) "#d9d9d9"
set tmpOpt(LabelColor) "#000000"
set tmpOpt(LineColor) "#000000"
set tmpOpt(TextColor) "#000000"
set tmpOpt(TodayColor) "#00C0C0"
set tmpOpt(WinBackground) "#d9d9d9"
update_color_buttons $w
}
proc set_dark_colors { w } {
global tmpOpt
set tmpOpt(BackgroundColor) "#000000"
set tmpOpt(LabelColor) "#00ffff"
set tmpOpt(LineColor) "#0080fc"
set tmpOpt(TextColor) "#ffffff"
set tmpOpt(TodayColor) "#b000b6"
set tmpOpt(WinBackground) "#000000"
update_color_buttons $w
}
proc update_color_buttons { w } {
global tmpOpt
$w.bbgcolor configure -background $tmpOpt(BackgroundColor)
$w.bheadcolor configure -background $tmpOpt(LabelColor)
$w.gridbcolor configure -background $tmpOpt(LineColor)
$w.btextcolor configure -background $tmpOpt(TextColor)
$w.tbbgcolor configure -background $tmpOpt(TodayColor)
$w.bwincolor configure -background $tmpOpt(WinBackground)
}
# Rem2PS program to execute -- supply full path if you want
main

View File

@@ -11,6 +11,7 @@
#define _XOPEN_SOURCE
#include "config.h"
#include "custom.h"
#include <stdio.h>
#include <string.h>
@@ -247,6 +248,28 @@ static void WriteBottomCalLine (void);
static void WriteIntermediateCalLine (void);
static void WriteCalDays (void);
static char const *
despace(char const *s)
{
static char buf[256];
char *t = buf;
if (strlen(s) > sizeof(buf)-1) {
/* Punt. :( */
return s;
}
while (*s) {
if (isspace(*s)) {
*t++ = '_';
} else {
*t++ = *s;
}
s++;
}
*t = 0;
return buf;
}
void PrintJSONString(char const *s)
{
while (*s) {
@@ -346,6 +369,41 @@ static void PutWideChar(wchar_t const wc)
}
#endif
static char const *
get_month_abbrev(char const *mon)
{
static char buf[80];
#ifndef REM_USE_WCHAR
sprintf(buf, "%.3s", mon);
return buf;
#else
char *s;
wchar_t tmp_buf[128];
wchar_t *ws;
int i;
int len;
*buf = 0;
(void) mbstowcs(tmp_buf, mon, 127);
ws = tmp_buf;
s = buf;
for (i=0; i<3; i++) {
if (*ws) {
len = wctomb(s, *ws);
s += len;
if (wcwidth(*ws) == 0) {
i--;
}
ws++;
} else {
break;
}
}
*s = 0;
return buf;
#endif
}
static int make_wchar_versions(CalEntry *e)
{
#ifdef REM_USE_WCHAR
@@ -543,9 +601,11 @@ void ProduceCalendar(void)
ColSpaces = (CalWidth - 9) / 7;
CalWidth = 7*ColSpaces + 8;
/* Run the file once to get potentially-overridden day names */
if (CalMonths) {
FromJulian(JulianToday, &y, &m, &d);
JulianToday = Julian(y, m, 1);
FromJulian(JulianToday, &y, &m, &d);
JulianToday = Julian(y, m, 1);
GenerateCalEntries(-1);
DidAMonth = 0;
if (PsCal == PSCAL_LEVEL3) {
printf("[\n");
@@ -562,6 +622,8 @@ void ProduceCalendar(void)
if (MondayFirst) JulianToday -= (JulianToday%7);
else JulianToday -= ((JulianToday+1)%7);
GenerateCalEntries(-1);
if (!DoSimpleCalendar) {
WriteWeekHeaderLine();
WriteCalDays();
@@ -584,7 +646,7 @@ void ProduceCalendar(void)
static void DoCalendarOneWeek(int nleft)
{
int y, m, d, done, i, l, wd;
char buf[81];
char buf[128];
int LinesWritten = 0;
int OrigJul = JulianToday;
@@ -612,8 +674,8 @@ static void DoCalendarOneWeek(int nleft)
goff();
for (i=0; i<7; i++) {
FromJulian(OrigJul+i, &y, &m, &d);
sprintf(buf, "%d %c%c%c ", d, MonthName[m][0], MonthName[m][1],
MonthName[m][2]);
char const *mon = get_month_name(m);
snprintf(buf, sizeof(buf), "%d %s ", d, get_month_abbrev(mon));
if (OrigJul+i == RealToday)
PrintLeft(buf, ColSpaces, '*');
else
@@ -622,7 +684,7 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
}
PutChar('\n');
putchar('\n');
for (l=0; l<CalPad; l++) {
gon();
DRAW(tb);
@@ -633,7 +695,7 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
}
PutChar('\n');
putchar('\n');
}
/* Write the body lines */
@@ -654,7 +716,7 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
}
PutChar('\n');
putchar('\n');
}
/* Write the final line */
@@ -674,7 +736,7 @@ static void DoCalendarOneWeek(int nleft)
/***************************************************************/
static void DoCalendarOneMonth(void)
{
int y, m, d, mm, yy;
int y, m, d, mm, yy, i, j;
if (!DoSimpleCalendar) WriteCalHeader();
@@ -694,20 +756,26 @@ static void DoCalendarOneMonth(void)
}
if (PsCal < PSCAL_LEVEL3) {
printf("%s %d %d %d %d\n",
MonthName[m], y, DaysInMonth(m, y), (JulianToday+1) % 7,
despace(get_month_name(m)), y, DaysInMonth(m, y), (JulianToday+1) % 7,
MondayFirst);
printf("%s %s %s %s %s %s %s\n",
DayName[6], DayName[0], DayName[1], DayName[2],
DayName[3], DayName[4], DayName[5]);
for (i=0; i<7; i++) {
j=(i+6)%7;
if (i) {
printf(" %s", despace(get_day_name(j)));
} else {
printf("%s", despace(get_day_name(j)));
}
}
printf("\n");
} else {
PrintJSONKeyPairString("monthname", MonthName[m]);
PrintJSONKeyPairString("monthname", get_month_name(m));
PrintJSONKeyPairInt("year", y);
PrintJSONKeyPairInt("daysinmonth", DaysInMonth(m, y));
PrintJSONKeyPairInt("firstwkday", (JulianToday+1) % 7);
PrintJSONKeyPairInt("mondayfirst", MondayFirst);
printf("\"daynames\":[\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"],",
DayName[6], DayName[0], DayName[1], DayName[2],
DayName[3], DayName[4], DayName[5]);
get_day_name(6), get_day_name(0), get_day_name(1), get_day_name(2),
get_day_name(3), get_day_name(4), get_day_name(5));
}
mm = m-1;
if (mm<0) {
@@ -715,9 +783,9 @@ static void DoCalendarOneMonth(void)
} else yy=y;
if (PsCal < PSCAL_LEVEL3) {
printf("%s %d\n", MonthName[mm], DaysInMonth(mm,yy));
printf("%s %d\n", despace(get_month_name(mm)), DaysInMonth(mm,yy));
} else {
PrintJSONKeyPairString("prevmonthname", MonthName[mm]);
PrintJSONKeyPairString("prevmonthname", get_month_name(mm));
PrintJSONKeyPairInt("daysinprevmonth", DaysInMonth(mm, yy));
PrintJSONKeyPairInt("prevmonthyear", yy);
}
@@ -726,9 +794,9 @@ static void DoCalendarOneMonth(void)
mm = 0; yy = y+1;
} else yy=y;
if (PsCal < PSCAL_LEVEL3) {
printf("%s %d\n", MonthName[mm], DaysInMonth(mm,yy));
printf("%s %d\n", despace(get_month_name(mm)), DaysInMonth(mm,yy));
} else {
PrintJSONKeyPairString("nextmonthname", MonthName[mm]);
PrintJSONKeyPairString("nextmonthname", get_month_name(mm));
PrintJSONKeyPairInt("daysinnextmonth", DaysInMonth(mm, yy));
PrintJSONKeyPairInt("nextmonthyear", yy);
printf("\"entries\":[\n");
@@ -799,7 +867,7 @@ static int WriteCalendarRow(void)
sprintf(buf, "%d ", d+i-wd);
if (Julian(y, m, d+i-wd) == RealToday) {
PrintLeft(buf, ColSpaces-1, '*');
PutChar(' ');
putchar(' ');
} else {
PrintLeft(buf, ColSpaces, ' ');
}
@@ -808,7 +876,7 @@ static int WriteCalendarRow(void)
DRAW(tb);
goff();
}
PutChar('\n');
putchar('\n');
for (l=0; l<CalPad; l++) {
gon();
DRAW(tb);
@@ -819,7 +887,7 @@ static int WriteCalendarRow(void)
DRAW(tb);
goff();
}
PutChar('\n');
putchar('\n');
}
/* Write the body lines */
@@ -840,7 +908,7 @@ static int WriteCalendarRow(void)
DRAW(tb);
goff();
}
PutChar('\n');
putchar('\n');
}
moreleft = (d+7-wd <= DaysInMonth(m, y));
@@ -863,9 +931,54 @@ static int WriteCalendarRow(void)
/***************************************************************/
static void PrintLeft(char const *s, int width, char pad)
{
#ifndef REM_USE_WCHAR
int len = strlen(s);
printf("%s", s);
while (len++ < width) PutChar(pad);
while (len++ < width) putchar(pad);
#else
size_t len = mbstowcs(NULL, s, 0);
int i;
wchar_t static_buf[128];
wchar_t *buf;
wchar_t *ws;
int display_len;
if (!len) {
for (i=0; i<width; i++) {
fputc(pad, stdout);
}
return;
}
if (len + 1 <= 128) {
buf = static_buf;
} else {
buf = calloc(len+1, sizeof(wchar_t));
if (!buf) {
/* Uh-oh... cannot recover */
fprintf(stderr, "%s\n", ErrMsg[E_NO_MEM]);
exit(1);
}
}
(void) mbstowcs(buf, s, len+1);
display_len = wcswidth(buf, len+1);
ws = buf;
for (i=0; i<width;) {
if (*ws) {
PutWideChar(*ws++);
i+= wcwidth(*ws);
} else {
break;
}
}
/* Mop up any potential combining characters */
while (*ws && wcwidth(*ws) == 0) {
PutWideChar(*ws++);
}
for (i=display_len; i<width; i++) fputc(pad, stdout);
if (buf != static_buf) free(buf);
#endif
}
/***************************************************************/
@@ -886,10 +999,10 @@ static void PrintCentered(char const *s, int width, char *pad)
for (i=0; i<width; i++) {
if (*s) {
if (isspace(*s)) {
PutChar(' ');
putchar(' ');
s++;
} else {
PutChar(*s++);
putchar(*s++);
}
} else {
break;
@@ -942,7 +1055,7 @@ static void PrintCentered(char const *s, int width, char *pad)
while (*ws && wcwidth(*ws) == 0) {
PutWideChar(*ws++);
}
for (i=d+len; i<width; i++) fputs(pad, stdout);
for (i=d+display_len; i<width; i++) fputs(pad, stdout);
if (buf != static_buf) free(buf);
#endif
}
@@ -971,7 +1084,7 @@ static int WriteOneCalLine(void)
DRAW(tb);
goff();
}
PutChar('\n');
putchar('\n');
return done;
}
@@ -1044,7 +1157,7 @@ static int WriteOneColLine(int col)
for (ws = e->wc_pos; ws - e->wc_pos < ColSpaces; ws++) {
if (!*ws) break;
if (iswspace(*ws)) {
PutChar(' ');
putchar(' ');
numwritten++;
} else {
if (wcwidth(*ws) > 0) {
@@ -1059,7 +1172,7 @@ static int WriteOneColLine(int col)
for (ws = e->wc_pos; ws<wspace; ws++) {
if (!*ws) break;
if (iswspace(*ws)) {
PutChar(' ');
putchar(' ');
numwritten++;
} else {
if (wcwidth(*ws) > 0) {
@@ -1076,7 +1189,7 @@ static int WriteOneColLine(int col)
}
/* Flesh out the rest of the column */
while(numwritten++ < ColSpaces) PutChar(' ');
while(numwritten++ < ColSpaces) putchar(' ');
/* Skip any spaces before next word */
while (iswspace(*ws)) ws++;
@@ -1131,9 +1244,9 @@ static int WriteOneColLine(int col)
if (!*s) break;
numwritten++;
if (isspace(*s)) {
PutChar(' ');
putchar(' ');
} else {
PutChar(*s);
putchar(*s);
}
}
e->pos = s;
@@ -1143,9 +1256,9 @@ static int WriteOneColLine(int col)
if (!*s) break;
numwritten++;
if (isspace(*s)) {
PutChar(' ');
putchar(' ');
} else {
PutChar(*s);
putchar(*s);
}
}
}
@@ -1156,7 +1269,7 @@ static int WriteOneColLine(int col)
}
/* Flesh out the rest of the column */
while(numwritten++ < ColSpaces) PutChar(' ');
while(numwritten++ < ColSpaces) putchar(' ');
/* Skip any spaces before next word */
while (isspace(*s)) s++;
@@ -1299,7 +1412,7 @@ static void WriteCalHeader(void)
int y, m, d;
FromJulian(JulianToday, &y, &m, &d);
sprintf(buf, "%s %d", MonthName[m], y);
sprintf(buf, "%s %d", get_month_name(m), y);
WriteTopCalLine();
@@ -1310,7 +1423,7 @@ static void WriteCalHeader(void)
gon();
DRAW(tb);
goff();
PutChar('\n');
putchar('\n');
WritePostHeaderLine();
WriteCalDays();
@@ -1324,7 +1437,7 @@ static void WriteCalHeader(void)
/***************************************************************/
static void WriteCalTrailer(void)
{
PutChar('\f');
putchar('\f');
}
/***************************************************************/
@@ -1336,13 +1449,13 @@ static void WriteCalTrailer(void)
/***************************************************************/
static int DoCalRem(ParsePtr p, int col)
{
int oldLen;
size_t oldLen;
Trigger trig;
TimeTrig tim;
Value v;
int r, err;
int jul;
CalEntry *CurCol = CalColumn[col];
CalEntry *CurCol;
CalEntry *e;
char const *s, *s2;
DynamicBuffer buf, obuf, pre_buf, raw_buf;
@@ -1351,6 +1464,11 @@ static int DoCalRem(ParsePtr p, int col)
int is_color, col_r, col_g, col_b;
if (col >= 0) {
CurCol = CalColumn[col];
} else {
CurCol = NULL;
}
is_color = 0;
DBufInit(&buf);
DBufInit(&pre_buf);
@@ -1447,6 +1565,12 @@ static int DoCalRem(ParsePtr p, int col)
}
}
/* If we're not actually generating any calendar entries, we're done */
if (col < 0) {
FreeTrig(&trig);
return OK;
}
/* Don't include timed reminders in calendar if -a option supplied. */
if (DontIssueAts && tim.ttime != NO_TIME) {
FreeTrig(&trig);
@@ -1927,7 +2051,7 @@ static void WriteTopCalLine(void)
PrintCentered("", CalWidth-2, linestruct->lr);
DRAW(bl);
goff();
PutChar('\n');
putchar('\n');
}
static void WriteBottomCalLine(void)
@@ -1944,7 +2068,7 @@ static void WriteBottomCalLine(void)
}
}
goff();
PutChar('\n');
putchar('\n');
}
static void WritePostHeaderLine(void)
@@ -1961,7 +2085,7 @@ static void WritePostHeaderLine(void)
}
}
goff();
PutChar('\n');
putchar('\n');
}
static void WriteWeekHeaderLine(void)
@@ -1978,7 +2102,7 @@ static void WriteWeekHeaderLine(void)
}
}
goff();
PutChar('\n');
putchar('\n');
}
static void WriteIntermediateCalLine(void)
@@ -1996,7 +2120,7 @@ static void WriteIntermediateCalLine(void)
}
}
goff();
PutChar('\n');
putchar('\n');
}
static void WriteCalDays(void)
@@ -2007,14 +2131,14 @@ static void WriteCalDays(void)
goff();
for (i=0; i<7; i++) {
if (!MondayFirst)
PrintCentered(DayName[(i+6)%7], ColSpaces, " ");
PrintCentered(get_day_name((i+6)%7), ColSpaces, " ");
else
PrintCentered(DayName[i%7], ColSpaces, " ");
PrintCentered(get_day_name(i%7), ColSpaces, " ");
gon();
DRAW(tb);
goff();
}
PutChar('\n');
putchar('\n');
}
/***************************************************************/

View File

@@ -38,7 +38,4 @@
/* The number of bytes in a unsigned long. */
#undef SIZEOF_UNSIGNED_LONG
/* The number of bytes in a unsigned short. */
#undef SIZEOF_UNSIGNED_SHORT
#include "custom.h"

View File

@@ -11,22 +11,18 @@
/***************************************************************/
/*---------------------------------------------------------------------*/
/* LAT_DEG, LAT_MIN and LAT_SEC: Latitude of your location */
/* LON_DEG, LON_MIN and LON_SEC: Longitude of your location */
/* DEFAULT_LATITUDE: Latitude of your location */
/* DEFAULT_LONGITUDE: Longitude of your location */
/* LOCATION: A string identifying your location. */
/* All latitude and longitude numbers should be positive for the */
/* northern and western hemisphere. If you live in the southern */
/* hemisphere, ALL latitude values should be negative. If you live */
/* in the eastern hemisphere, ALL longitude values should be negative. */
/* Latitude and longitude should be positive for the */
/* northern and eastern hemisphere and negative for the southern and */
/* western hemisphere. */
/* */
/* The default values are initially set to Ottawa, Ontario, Canada. */
/* The default values are initially set to the city hall in Ottawa, */
/* Ontario, Canada. */
/*---------------------------------------------------------------------*/
#define LAT_DEG 45
#define LAT_MIN 25
#define LAT_SEC 30
#define LON_DEG 75
#define LON_MIN 41
#define LON_SEC 59
#define DEFAULT_LATITUDE 45.42055555555555
#define DEFAULT_LONGITUDE -75.68972222222223
#define LOCATION "Ottawa"
/*---------------------------------------------------------------------*/
@@ -58,45 +54,6 @@
#define DATETIMESEP '@'
/* #define DATETIMESEP '/' */
/*---------------------------------------------------------------------*/
/* ISOLATIN1: define it to 1 if you use the */
/* ISO 8859-1 character set instead of ASCII. */
/*---------------------------------------------------------------------*/
#define ISOLATIN1 1
/*---------------------------------------------------------------------*/
/* ISOLATIN2: define it to 1 if you use the */
/* ISO 8859-2 character set instead of ASCII. */
/* NOT ALL LANGUAGE MODULES SUPPORT THIS. Note that at most one of */
/* ISOLATIN1, ISOLATIN2, IBMEXTENDED and IBM852 should be 1; if more */
/* then one are defined as 1, the results are unspecified. */
/*---------------------------------------------------------------------*/
#define ISOLATIN2 0
/*---------------------------------------------------------------------*/
/* IBMEXTENDED: define as 1 if your system uses the IBM extended */
/* character set. */
/* NOT ALL LANGUAGE MODULES SUPPORT THIS. Note that at most one of */
/* ISOLATIN1, ISOLATIN2, IBMEXTENDED and IBM852 should be 1; if more */
/* then one are defined as 1, the results are unspecified. */
/*---------------------------------------------------------------------*/
#define IBMEXTENDED 0
/*---------------------------------------------------------------------*/
/* IBM852: define as 1 if your system uses the IBM CPI-852 extended */
/* character set. */
/* NOT ALL LANGUAGE MODULES SUPPORT THIS. Note that at most one of */
/* ISOLATIN1, ISOLATIN2, IBMEXTENDED and IBM852 should be 1; if more */
/* then one are defined as 1, the results are unspecified. */
/*---------------------------------------------------------------------*/
#define IBM852 0
/*---------------------------------------------------------------------*/
/* WANT_U_OPTION: Comment out the next define to permanently disable */
/* the -u option. */
/*---------------------------------------------------------------------*/
#define WANT_U_OPTION 1
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
@@ -114,16 +71,7 @@
/* WANT_SHELL_ESCAPING: Define this if you want special shell */
/* characters to be escaped with a backslash for the -k option. */
/*---------------------------------------------------------------------*/
#if defined(UNIX)
#define WANT_SHELL_ESCAPING 1
#endif
/*---------------------------------------------------------------------*/
/* Some implementations have a broken 'putc' and 'putchar'. */
/*---------------------------------------------------------------------*/
#ifdef __SASC_60
#define BROKEN_PUTC
#endif
/*---------------------------------------------------------------------*/
/* BASE: The base year for date calculation. NOTE! January 1 of the */
@@ -168,7 +116,7 @@
/*---------------------------------------------------------------------*/
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
/*---------------------------------------------------------------------*/
#define VAL_STACK_SIZE 500
#define VAL_STACK_SIZE 1000
/*---------------------------------------------------------------------*/
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */
@@ -189,7 +137,7 @@
/*---------------------------------------------------------------------*/
/* How many global omits of the form YYYY MM DD do we handle? */
/*---------------------------------------------------------------------*/
#define MAX_FULL_OMITS 500
#define MAX_FULL_OMITS 1000
/*---------------------------------------------------------------------*/
/* How many global omits of the form MM DD do we handle? */
@@ -223,14 +171,6 @@
#define PSBEGIN2 "# rem2ps2 begin"
#define PSEND2 "# rem2ps2 end"
#ifdef BROKEN_PUTC
#define Putc SafePutc
#define PutChar SafePutChar
#else
#define Putc putc
#define PutChar putchar
#endif
#if defined(HAVE_MBSTOWCS) && defined(HAVE_WCTYPE_H)
#define REM_USE_WCHAR 1
#else

View File

@@ -11,22 +11,18 @@
/***************************************************************/
/*---------------------------------------------------------------------*/
/* LAT_DEG, LAT_MIN and LAT_SEC: Latitude of your location */
/* LON_DEG, LON_MIN and LON_SEC: Longitude of your location */
/* DEFAULT_LATITUDE: Latitude of your location */
/* DEFAULT_LONGITUDE: Longitude of your location */
/* LOCATION: A string identifying your location. */
/* All latitude and longitude numbers should be positive for the */
/* northern and western hemisphere. If you live in the southern */
/* hemisphere, ALL latitude values should be negative. If you live */
/* in the eastern hemisphere, ALL longitude values should be negative. */
/* Latitude and longitude should be positive for the */
/* northern and eastern hemisphere and negative for the southern and */
/* western hemisphere. */
/* */
/* The default values are initially set to Ottawa, Ontario, Canada. */
/* The default values are initially set to the city hall in Ottawa, */
/* Ontario, Canada. */
/*---------------------------------------------------------------------*/
#define LAT_DEG 45
#define LAT_MIN 25
#define LAT_SEC 30
#define LON_DEG 75
#define LON_MIN 41
#define LON_SEC 59
#define DEFAULT_LATITUDE 45.42055555555555
#define DEFAULT_LONGITUDE -75.68972222222223
#define LOCATION "Ottawa"
/*---------------------------------------------------------------------*/
@@ -58,45 +54,6 @@
#define DATETIMESEP '@'
/* #define DATETIMESEP '/' */
/*---------------------------------------------------------------------*/
/* ISOLATIN1: define it to 1 if you use the */
/* ISO 8859-1 character set instead of ASCII. */
/*---------------------------------------------------------------------*/
#define ISOLATIN1 1
/*---------------------------------------------------------------------*/
/* ISOLATIN2: define it to 1 if you use the */
/* ISO 8859-2 character set instead of ASCII. */
/* NOT ALL LANGUAGE MODULES SUPPORT THIS. Note that at most one of */
/* ISOLATIN1, ISOLATIN2, IBMEXTENDED and IBM852 should be 1; if more */
/* then one are defined as 1, the results are unspecified. */
/*---------------------------------------------------------------------*/
#define ISOLATIN2 0
/*---------------------------------------------------------------------*/
/* IBMEXTENDED: define as 1 if your system uses the IBM extended */
/* character set. */
/* NOT ALL LANGUAGE MODULES SUPPORT THIS. Note that at most one of */
/* ISOLATIN1, ISOLATIN2, IBMEXTENDED and IBM852 should be 1; if more */
/* then one are defined as 1, the results are unspecified. */
/*---------------------------------------------------------------------*/
#define IBMEXTENDED 0
/*---------------------------------------------------------------------*/
/* IBM852: define as 1 if your system uses the IBM CPI-852 extended */
/* character set. */
/* NOT ALL LANGUAGE MODULES SUPPORT THIS. Note that at most one of */
/* ISOLATIN1, ISOLATIN2, IBMEXTENDED and IBM852 should be 1; if more */
/* then one are defined as 1, the results are unspecified. */
/*---------------------------------------------------------------------*/
#define IBM852 0
/*---------------------------------------------------------------------*/
/* WANT_U_OPTION: Comment out the next define to permanently disable */
/* the -u option. */
/*---------------------------------------------------------------------*/
#define WANT_U_OPTION 1
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
@@ -114,16 +71,7 @@
/* WANT_SHELL_ESCAPING: Define this if you want special shell */
/* characters to be escaped with a backslash for the -k option. */
/*---------------------------------------------------------------------*/
#if defined(UNIX)
#define WANT_SHELL_ESCAPING 1
#endif
/*---------------------------------------------------------------------*/
/* Some implementations have a broken 'putc' and 'putchar'. */
/*---------------------------------------------------------------------*/
#ifdef __SASC_60
#define BROKEN_PUTC
#endif
/*---------------------------------------------------------------------*/
/* BASE: The base year for date calculation. NOTE! January 1 of the */
@@ -168,7 +116,7 @@
/*---------------------------------------------------------------------*/
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
/*---------------------------------------------------------------------*/
#define VAL_STACK_SIZE 500
#define VAL_STACK_SIZE 1000
/*---------------------------------------------------------------------*/
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */
@@ -189,7 +137,7 @@
/*---------------------------------------------------------------------*/
/* How many global omits of the form YYYY MM DD do we handle? */
/*---------------------------------------------------------------------*/
#define MAX_FULL_OMITS 500
#define MAX_FULL_OMITS 1000
/*---------------------------------------------------------------------*/
/* How many global omits of the form MM DD do we handle? */
@@ -223,14 +171,6 @@
#define PSBEGIN2 "# rem2ps2 begin"
#define PSEND2 "# rem2ps2 end"
#ifdef BROKEN_PUTC
#define Putc SafePutc
#define PutChar SafePutChar
#else
#define Putc putc
#define PutChar putchar
#endif
#if defined(HAVE_MBSTOWCS) && defined(HAVE_WCTYPE_H)
#define REM_USE_WCHAR 1
#else

View File

@@ -28,7 +28,7 @@ static int ParseTimeTrig (ParsePtr s, TimeTrig *tim, int save_in_globals);
static int ParseLocalOmit (ParsePtr s, Trigger *t);
static int ParseScanFrom (ParsePtr s, Trigger *t, int type);
static int ParsePriority (ParsePtr s, Trigger *t);
static int ParseUntil (ParsePtr s, Trigger *t);
static int ParseUntil (ParsePtr s, Trigger *t, int type);
static int ShouldTriggerBasedOnWarn (Trigger *t, int jul, int *err);
static int ComputeTrigDuration(TimeTrig *t);
@@ -237,11 +237,15 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
tim->delta = DefaultTDelta;
tim->rep = NO_REP;
tim->duration = NO_TIME;
trig->need_wkday = 0;
trig->adj_for_last = 0;
if (save_in_globals) {
LastTriggerTime = NO_TIME;
}
while(1) {
int parsing = 1;
while(parsing) {
/* Read space-delimited string */
r = ParseToken(s, &buf);
if (r) return r;
@@ -249,6 +253,25 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
/* Figure out what we've got */
FindToken(DBufValue(&buf), &tok);
switch(tok.type) {
case T_In:
/* Completely ignored */
DBufFree(&buf);
break;
case T_Ordinal:
DBufFree(&buf);
if (trig->d != NO_DAY) return E_DAY_TWICE;
if (tok.val < 0) {
if (trig->back != NO_BACK) return E_BACK_TWICE;
trig->back = -7;
trig->d = 1;
trig->adj_for_last = 1;
} else {
trig->d = 1 + 7 * tok.val;
}
trig->need_wkday = 1;
break;
case T_Date:
DBufFree(&buf);
if (trig->d != NO_DAY) return E_DAY_TWICE;
@@ -322,7 +345,6 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
DBufFree(&buf);
trig->typ = tok.val;
if (s->isnested) return E_CANT_NEST_RTYPE;
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
if (trig->typ == PASSTHRU_TYPE) {
r = ParseToken(s, &buf);
if (r) return r;
@@ -332,19 +354,20 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
}
StrnCpy(trig->passthru, DBufValue(&buf), PASSTHRU_LEN);
}
return OK;
parsing = 0;
break;
case T_Through:
DBufFree(&buf);
if (trig->rep != NO_REP) return E_REP_TWICE;
trig->rep = 1;
r = ParseUntil(s, trig);
r = ParseUntil(s, trig, tok.type);
if (r) return r;
break;
case T_Until:
DBufFree(&buf);
r=ParseUntil(s, trig);
r=ParseUntil(s, trig, tok.type);
if (r) return r;
break;
@@ -378,6 +401,15 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
trig->back = tok.val;
break;
case T_BackAdj:
DBufFree(&buf);
if (trig->back != NO_BACK) return E_BACK_TWICE;
if (trig->d != NO_DAY) return E_DAY_TWICE;
trig->back = tok.val;
trig->d = 1;
trig->adj_for_last = 1;
break;
case T_Once:
DBufFree(&buf);
if (trig->once != NO_ONCE) return E_ONCE_TWICE;
@@ -401,8 +433,8 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
case T_Empty:
DBufFree(&buf);
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
return OK;
parsing = 0;
break;
case T_OmitFunc:
if (trig->localomit) {
@@ -474,10 +506,58 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
DBufFree(&buf);
trig->typ = MSG_TYPE;
if (s->isnested) return E_CANT_NEST_RTYPE;
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
return OK;
parsing = 0;
break;
}
}
if (trig->need_wkday && trig->wd == NO_WD) {
Eprint("Weekday name(s) required");
return E_PARSE_ERR;
}
/* Adjust month and possibly year */
if (trig->adj_for_last) {
if (trig->m != NO_MON) {
trig->m++;
if (trig->m >= 12) {
trig->m = 0;
if (trig->y != NO_YR) {
trig->y++;
}
}
}
trig->adj_for_last = 0;
}
/* Check for some warning conditions */
if (!s->nonconst_expr) {
if (trig->y != NO_YR && trig->m != NO_MON && trig->d != NO_DAY && trig->until != NO_UNTIL) {
if (Julian(trig->y, trig->m, trig->d) > trig->until) {
Eprint("Warning: UNTIL/THROUGH date earlier than start date");
}
}
if (trig->from != NO_DATE) {
if (trig->until != NO_UNTIL && trig->until < trig->from) {
Eprint("Warning: UNTIL/THROUGH date earlier than FROM date");
}
} else if (trig->scanfrom != NO_DATE) {
if (trig->until != NO_UNTIL && trig->until < trig->scanfrom) {
Eprint("Warning: UNTIL/THROUGH date earlier than SCANFROM date");
}
}
}
if (trig->y != NO_YR && trig->m != NO_MON && trig->d != NO_DAY && trig->until != NO_UNTIL && trig->rep == NO_REP) {
Eprint("Warning: Useless use of UNTIL with fully-specified date and no *rep");
}
/* Set scanfrom to default if not set explicitly */
if (trig->scanfrom == NO_DATE) {
trig->scanfrom = JulianToday;
}
return OK;
}
/***************************************************************/
@@ -568,12 +648,18 @@ static int ParseLocalOmit(ParsePtr s, Trigger *t)
/* ParseUntil - parse the UNTIL portion of a reminder */
/* */
/***************************************************************/
static int ParseUntil(ParsePtr s, Trigger *t)
static int ParseUntil(ParsePtr s, Trigger *t, int type)
{
int y = NO_YR,
m = NO_MON,
d = NO_DAY;
char const *which;
if (type == T_Until) {
which = "UNTIL";
} else {
which = "THROUGH";
}
Token tok;
int r;
DynamicBuffer buf;
@@ -589,7 +675,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
case T_Year:
DBufFree(&buf);
if (y != NO_YR) {
Eprint("UNTIL: %s", ErrMsg[E_YR_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_YR_TWICE]);
return E_YR_TWICE;
}
y = tok.val;
@@ -598,7 +684,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
case T_Month:
DBufFree(&buf);
if (m != NO_MON) {
Eprint("UNTIL: %s", ErrMsg[E_MON_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_MON_TWICE]);
return E_MON_TWICE;
}
m = tok.val;
@@ -607,7 +693,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
case T_Day:
DBufFree(&buf);
if (d != NO_DAY) {
Eprint("UNTIL: %s", ErrMsg[E_DAY_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
return E_DAY_TWICE;
}
d = tok.val;
@@ -616,15 +702,15 @@ static int ParseUntil(ParsePtr s, Trigger *t)
case T_Date:
DBufFree(&buf);
if (y != NO_YR) {
Eprint("UNTIL: %s", ErrMsg[E_YR_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_YR_TWICE]);
return E_YR_TWICE;
}
if (m != NO_MON) {
Eprint("UNTIL: %s", ErrMsg[E_MON_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_MON_TWICE]);
return E_MON_TWICE;
}
if (d != NO_DAY) {
Eprint("UNTIL: %s", ErrMsg[E_DAY_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
return E_DAY_TWICE;
}
FromJulian(tok.val, &y, &m, &d);
@@ -632,7 +718,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
default:
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
Eprint("UNTIL: %s", ErrMsg[E_INCOMPLETE]);
Eprint("%s: %s", which, ErrMsg[E_INCOMPLETE]);
DBufFree(&buf);
return E_INCOMPLETE;
}
@@ -1159,9 +1245,9 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
FromJulian(LastTriggerDate, &y, &m, &d);
fprintf(ErrFp, "%s(%d): Trig(satisfied) = %s, %d %s, %d",
FileName, LineNo,
DayName[LastTriggerDate % 7],
get_day_name(LastTriggerDate % 7),
d,
MonthName[m],
get_month_name(m),
y);
if (tt->ttime != NO_TIME) {
fprintf(ErrFp, " AT %02d:%02d",

View File

@@ -219,11 +219,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_A_OVER
#else
if (altmode == '*') {
sprintf(s, "%s, %d %s, %d", DayName[jul%7], d,
MonthName[m], y);
sprintf(s, "%s, %d %s, %d", get_day_name(jul%7), d,
get_month_name(m), y);
} else {
sprintf(s, "%s %s, %d %s, %d", L_ON, DayName[jul%7], d,
MonthName[m], y);
sprintf(s, "%s %s, %d %s, %d", L_ON, get_day_name(jul%7), d,
get_month_name(m), y);
}
#endif
SHIP_OUT(s);
@@ -243,9 +243,9 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_C_OVER
#else
if (altmode == '*') {
sprintf(s, "%s", DayName[jul%7]);
sprintf(s, "%s", get_day_name(jul%7));
} else {
sprintf(s, "%s %s", L_ON, DayName[jul%7]);
sprintf(s, "%s %s", L_ON, get_day_name(jul%7));
}
#endif
SHIP_OUT(s);
@@ -293,9 +293,9 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_G_OVER
#else
if (altmode == '*') {
sprintf(s, "%s, %d %s", DayName[jul%7], d, MonthName[m]);
sprintf(s, "%s, %d %s", get_day_name(jul%7), d, get_month_name(m));
} else {
sprintf(s, "%s %s, %d %s", L_ON, DayName[jul%7], d, MonthName[m]);
sprintf(s, "%s %s, %d %s", L_ON, get_day_name(jul%7), d, get_month_name(m));
}
#endif
SHIP_OUT(s);
@@ -332,11 +332,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_J_OVER
#else
if (altmode == '*') {
sprintf(s, "%s, %s %d%s, %d", DayName[jul%7],
MonthName[m], d, plu, y);
sprintf(s, "%s, %s %d%s, %d", get_day_name(jul%7),
get_month_name(m), d, plu, y);
} else {
sprintf(s, "%s %s, %s %d%s, %d", L_ON, DayName[jul%7],
MonthName[m], d, plu, y);
sprintf(s, "%s %s, %s %d%s, %d", L_ON, get_day_name(jul%7),
get_month_name(m), d, plu, y);
}
#endif
SHIP_OUT(s);
@@ -347,11 +347,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_K_OVER
#else
if (altmode == '*') {
sprintf(s, "%s, %s %d%s", DayName[jul%7],
MonthName[m], d, plu);
sprintf(s, "%s, %s %d%s", get_day_name(jul%7),
get_month_name(m), d, plu);
} else {
sprintf(s, "%s %s, %s %d%s", L_ON, DayName[jul%7],
MonthName[m], d, plu);
sprintf(s, "%s %s, %s %d%s", L_ON, get_day_name(jul%7),
get_month_name(m), d, plu);
}
#endif
SHIP_OUT(s);
@@ -374,7 +374,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_M_OVER
L_M_OVER
#else
sprintf(s, "%s", MonthName[m]);
sprintf(s, "%s", get_month_name(m));
#endif
SHIP_OUT(s);
break;
@@ -448,11 +448,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_U_OVER
#else
if (altmode == '*') {
sprintf(s, "%s, %d%s %s, %d", DayName[jul%7], d,
plu, MonthName[m], y);
sprintf(s, "%s, %d%s %s, %d", get_day_name(jul%7), d,
plu, get_month_name(m), y);
} else {
sprintf(s, "%s %s, %d%s %s, %d", L_ON, DayName[jul%7], d,
plu, MonthName[m], y);
sprintf(s, "%s %s, %d%s %s, %d", L_ON, get_day_name(jul%7), d,
plu, get_month_name(m), y);
}
#endif
SHIP_OUT(s);
@@ -463,11 +463,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_V_OVER
#else
if (altmode == '*') {
sprintf(s, "%s, %d%s %s", DayName[jul%7], d, plu,
MonthName[m]);
sprintf(s, "%s, %d%s %s", get_day_name(jul%7), d, plu,
get_month_name(m));
} else {
sprintf(s, "%s %s, %d%s %s", L_ON, DayName[jul%7], d, plu,
MonthName[m]);
sprintf(s, "%s %s, %d%s %s", L_ON, get_day_name(jul%7), d, plu,
get_month_name(m));
}
#endif
SHIP_OUT(s);
@@ -477,7 +477,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_W_OVER
L_W_OVER
#else
sprintf(s, "%s", DayName[jul%7]);
sprintf(s, "%s", get_day_name(jul%7));
#endif
SHIP_OUT(s);
break;
@@ -657,13 +657,8 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
break;
case '"':
if (PsCal != PSCAL_LEVEL3) {
if (DBufPutc(dbuf, QUOTE_MARKER) != OK) return E_NO_MEM;
has_quote = 1;
} else {
if (DBufPutc(dbuf, '%') != OK) return E_NO_MEM;
if (DBufPutc(dbuf, c) != OK) return E_NO_MEM;
}
if (DBufPutc(dbuf, QUOTE_MARKER) != OK) return E_NO_MEM;
has_quote = 1;
break;
default:

View File

@@ -27,11 +27,11 @@
Doubles the size of dynamic buffer until it has room for at least
'n' characters, not including trailing '\0'
**********************************************************************/
static int DBufMakeRoom(DynamicBuffer *dbuf, int n)
static int DBufMakeRoom(DynamicBuffer *dbuf, size_t n)
{
/* Double size until it's greater than n (strictly > to leave room
for trailing '\0' */
int size = dbuf->allocatedLen;
size_t size = dbuf->allocatedLen;
char *buf;
if (size > n) return OK;

View File

@@ -17,8 +17,8 @@
#define DBUF_STATIC_SIZE 128
typedef struct {
char *buffer;
int len;
int allocatedLen;
size_t len;
size_t allocatedLen;
char staticBuf[DBUF_STATIC_SIZE];
} DynamicBuffer;

View File

@@ -44,21 +44,32 @@ static int MakeValue (char const *s, Value *v, Var *locals, ParsePtr p);
/* Binary operators - all left-associative */
/* Operator precedence:
* Highest: Unary - Unary !
* / %
* + -
* < <= > >=
* == !=
* &&
* Lowest: ||
*
*/
/* Make SURE they are sorted lexically... this may die on an EBCDIC
system... */
Operator BinOp[] = {
{ "!=", 15, BIN_OP, NotEqual },
{ "%", 20, BIN_OP, Mod },
{ "%", 20, BIN_OP, Mod },
{ "&&", 14, BIN_OP, LogAND },
{ "*", 20, BIN_OP, Multiply },
{ "+", 18, BIN_OP, Add },
{ "-", 18, BIN_OP, Subtract },
{ "/", 20, BIN_OP, Divide },
{ "<", 16, BIN_OP, LessThan },
{ "*", 20, BIN_OP, Multiply },
{ "+", 18, BIN_OP, Add },
{ "-", 18, BIN_OP, Subtract },
{ "/", 20, BIN_OP, Divide },
{ "<", 16, BIN_OP, LessThan },
{ "<=", 16, BIN_OP, LessOrEqual },
{ "==", 15, BIN_OP, EqualTo },
{ ">", 16, BIN_OP, GreaterThan },
{ ">", 16, BIN_OP, GreaterThan },
{ ">=", 16, BIN_OP, GreaterOrEqual },
{ "||", 12, BIN_OP, LogOR },
};
@@ -66,8 +77,8 @@ Operator BinOp[] = {
/* These ones must be sorted too. */
Operator UnOp[] = {
{ "!", 22, UN_OP, LogNot },
{ "-", 22, UN_OP, UnMinus },
{ "!", 22, UN_OP, LogNot },
{ "-", 22, UN_OP, UnMinus },
};
#define NUM_UN_OPS (sizeof(UnOp) / sizeof(Operator))
@@ -75,7 +86,8 @@ extern BuiltinFunc Func[];
Operator OpStack[OP_STACK_SIZE];
Value ValStack[VAL_STACK_SIZE];
int OpStackPtr, ValStackPtr;
int OpStackPtr = 0;
int ValStackPtr = 0;
/***************************************************************/
/* */
@@ -101,7 +113,7 @@ static int DebugPerform(Operator *op)
fprintf(ErrFp, " => ");
if (!r) {
PrintValue(&ValStack[ValStackPtr-1], ErrFp);
Putc('\n', ErrFp);
putc('\n', ErrFp);
} else {
fprintf(ErrFp, "%s\n", ErrMsg[r]);
}
@@ -115,12 +127,13 @@ static int DebugPerform(Operator *op)
/* Clean the stack after an error occurs. */
/* */
/***************************************************************/
static void CleanStack(void)
static void CleanStack(int old_op_stack_ptr, int old_val_stack_ptr)
{
int i;
for (i=0; i<ValStackPtr; i++) DestroyValue(ValStack[i]);
ValStackPtr = 0;
for (i=old_val_stack_ptr; i<ValStackPtr; i++) DestroyValue(ValStack[i]);
ValStackPtr = old_val_stack_ptr;
OpStackPtr = old_op_stack_ptr;
}
/***************************************************************/
@@ -306,8 +319,8 @@ int EvalExpr(char const **e, Value *v, ParsePtr p)
{
int r;
OpStackPtr = 0;
ValStackPtr = 0;
int old_op_stack_ptr = OpStackPtr;
int old_val_stack_ptr = ValStackPtr;
r = Evaluate(e, NULL, p);
@@ -316,11 +329,15 @@ int EvalExpr(char const **e, Value *v, ParsePtr p)
DBufFree(&ExprBuf);
if (r) {
CleanStack();
CleanStack(old_op_stack_ptr, old_val_stack_ptr);
/* fprintf(stderr, "O=%d V=%d\n", OpStackPtr, ValStackPtr); */
return r;
}
*v = *ValStack;
ValStack[0].type = ERR_TYPE;
OpStackPtr = old_op_stack_ptr;
ValStackPtr = old_val_stack_ptr;
*v = ValStack[old_val_stack_ptr];
ValStack[old_val_stack_ptr].type = ERR_TYPE;
/* fprintf(stderr, "O=%d V=%d\n", OpStackPtr, ValStackPtr); */
return r;
}
@@ -580,7 +597,7 @@ static int MakeValue(char const *s, Value *v, Var *locals, ParsePtr p)
if (! (DebugFlag & DB_PRTEXPR)) return r;
if (r == OK) {
PrintValue(v, ErrFp);
Putc('\n', ErrFp);
putc('\n', ErrFp);
}
return r;
} else { /* Must be a symbol */
@@ -591,7 +608,7 @@ static int MakeValue(char const *s, Value *v, Var *locals, ParsePtr p)
if (! (DebugFlag & DB_PRTEXPR)) return r;
if (r == OK) {
PrintValue(v, ErrFp);
Putc('\n', ErrFp);
putc('\n', ErrFp);
}
return r;
}
@@ -828,7 +845,7 @@ static int Add(void)
v3.type = STR_TYPE;
l1 = strlen(v1.v.str);
l2 = strlen(v2.v.str);
if (MaxStringLen && (l1 + l2 > (size_t) MaxStringLen)) {
if (MaxStringLen > 0 && (l1 + l2 > (size_t) MaxStringLen)) {
DestroyValue(v1); DestroyValue(v2);
return E_STRING_TOO_LONG;
}
@@ -1108,13 +1125,16 @@ static int LogOR(void)
return r;
}
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
v1.v.val = (v1.v.val || v2.v.val) ? 1 : 0;
PushValStack(v1);
return OK;
if (v1.type != v2.type || v1.type == STR_TYPE || v2.type == STR_TYPE) {
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
}
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
if (v1.v.val == 0) {
v1.v.val = v2.v.val;
}
PushValStack(v1);
return OK;
}
/***************************************************************/
@@ -1135,13 +1155,15 @@ static int LogAND(void)
return r;
}
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
v1.v.val = (v1.v.val && v2.v.val) ? 1 : 0;
PushValStack(v1);
return OK;
if (v1.type != v2.type || v1.type == STR_TYPE || v2.type == STR_TYPE) {
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
}
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
if (v1.v.val != 0) {
v1.v.val = v2.v.val;
}
PushValStack(v1);
return OK;
}
/***************************************************************/
@@ -1232,9 +1254,9 @@ void PrintValue (Value *v, FILE *fp)
if (v->type == STR_TYPE) {
s=v->v.str;
Putc('"', fp);
for (y=0; y<MAX_PRT_LEN && *s; y++) Putc(*s++, fp);
Putc('"',fp);
putc('"', fp);
for (y=0; y<MAX_PRT_LEN && *s; y++) putc(*s++, fp);
putc('"',fp);
if (*s) fprintf(fp, "...");
}
else if (v->type == INT_TYPE) fprintf(fp, "%d", v->v.val);

View File

@@ -58,6 +58,7 @@ static int FADusk (func_info *);
static int FAbs (func_info *);
static int FAccess (func_info *);
static int FAmpm (func_info *);
static int FTrig (func_info *);
static int FIsAny (func_info *);
static int FArgs (func_info *);
static int FAsc (func_info *);
@@ -126,6 +127,7 @@ static int FSunset (func_info *);
static int FTime (func_info *);
static int FTimepart (func_info *);
static int FToday (func_info *);
static int FTrig (func_info *);
static int FTrigback (func_info *);
static int FTrigdate (func_info *);
static int FTrigdatetime (func_info *);
@@ -279,6 +281,7 @@ BuiltinFunc Func[] = {
{ "time", 2, 2, 1, FTime },
{ "timepart", 1, 1, 1, FTimepart },
{ "today", 0, 0, 0, FToday },
{ "trig", 0, NO_MAX, 0, FTrig },
{ "trigback", 0, 0, 0, FTrigback },
{ "trigdate", 0, 0, 0, FTrigdate },
{ "trigdatetime", 0, 0, 0, FTrigdatetime },
@@ -433,7 +436,9 @@ static int FStrlen(func_info *info)
Value *v = &ARG(0);
if (v->type != STR_TYPE) return E_BAD_TYPE;
RetVal.type = INT_TYPE;
RETVAL = strlen(v->v.str);
size_t l = strlen(v->v.str);
if (l > INT_MAX) return E_2HIGH;
RETVAL = (int) l;
return OK;
}
@@ -789,8 +794,8 @@ static int FWkday(func_info *info)
/* Convert 0=Sun to 0=Mon */
ARGV(0)--;
if (ARGV(0) < 0) ARGV(0) = 6;
s = DayName[ARGV(0)];
} else s = DayName[DATEPART(ARG(0)) % 7];
s = get_day_name(ARGV(0));
} else s = get_day_name(DATEPART(ARG(0)) % 7);
return RetStrVal(s, info);
}
@@ -817,7 +822,7 @@ static int FMon(func_info *info)
CacheDay = d;
}
}
s = MonthName[m];
s = get_month_name(m);
return RetStrVal(s, info);
}
@@ -1572,6 +1577,15 @@ static int FShell(func_info *info)
ASSERT_TYPE(1, INT_TYPE);
maxlen = ARGV(1);
}
/* Don't allow maxlen to exceed the maximum length of
a string variable */
if (MaxStringLen > 0) {
if (maxlen <= 0 || maxlen > MaxStringLen) {
maxlen = MaxStringLen;
}
}
fp = popen(ARGSTR(0), "r");
if (!fp) return E_IO_ERR;
while (1) {
@@ -1585,7 +1599,7 @@ static int FShell(func_info *info)
DBufFree(&buf);
return E_NO_MEM;
}
if (maxlen > 0 && DBufLen(&buf) >= maxlen) {
if (maxlen > 0 && DBufLen(&buf) >= (size_t) maxlen) {
break;
}
}
@@ -2960,8 +2974,12 @@ FEvalTrig(func_info *info)
CreateParser(ARGSTR(0), &p);
p.allownested = 0;
r = ParseRem(&p, &trig, &tim, 0);
if (r) return r;
if (r) {
DestroyParser(&p);
return r;
}
if (trig.typ != NO_TYPE) {
DestroyParser(&p);
FreeTrig(&trig);
return E_PARSE_ERR;
}
@@ -2979,6 +2997,7 @@ FEvalTrig(func_info *info)
jul = -1;
}
FreeTrig(&trig);
DestroyParser(&p);
if (r) return r;
if (jul < 0) {
RetVal.type = INT_TYPE;
@@ -2992,3 +3011,59 @@ FEvalTrig(func_info *info)
}
return OK;
}
static int LastTrig = 0;
static int
FTrig(func_info *info)
{
Parser p;
Trigger trig;
TimeTrig tim;
int jul;
int r;
int i;
RetVal.type = DATE_TYPE;
if (Nargs == 0) {
RETVAL = LastTrig;
return OK;
}
for (i=0; i<Nargs; i++) {
ASSERT_TYPE(i, STR_TYPE);
}
RETVAL = 0;
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;
}
jul = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
if (r == E_CANT_TRIG) {
DestroyParser(&p);
FreeTrig(&trig);
continue;
}
if (ShouldTriggerReminder(&trig, &tim, jul, &r)) {
LastTrig = jul;
RETVAL = jul;
DestroyParser(&p);
FreeTrig(&trig);
return OK;
}
DestroyParser(&p);
FreeTrig(&trig);
}
return OK;
}

View File

@@ -17,6 +17,6 @@
#include <stdio.h> /* For defintion of FILE - sigh! */
#include "types.h"
#include "custom.h"
#define MK_GLOBALS
#define MK_GLOBALS 1
#include "globals.h"
#include "err.h"

View File

@@ -88,7 +88,7 @@ EXTERN INIT( int DefaultColorB, -1);
EXTERN INIT( int DefaultColorG, -1);
EXTERN INIT( int SynthesizeTags, 0);
EXTERN INIT( int ScFormat, SC_AMPM);
EXTERN INIT( int MaxSatIter, 150);
EXTERN INIT( int MaxSatIter, 1000);
EXTERN INIT( int MaxStringLen, MAX_STR_LEN);
EXTERN INIT( char *FileName, NULL);
EXTERN INIT( int UseStdin, 0);
@@ -118,14 +118,14 @@ EXTERN INIT( int UseTrueColors, 0);
EXTERN INIT( int TerminalBackground, TERMINAL_BACKGROUND_UNKNOWN);
/* Latitude and longitude */
EXTERN INIT( int LatDeg, LAT_DEG);
EXTERN INIT( int LatMin, LAT_MIN);
EXTERN INIT( int LatSec, LAT_SEC);
EXTERN INIT( int LongDeg, LON_DEG);
EXTERN INIT( int LongMin, LON_MIN);
EXTERN INIT( int LongSec, LON_SEC);
EXTERN INIT( double Longitude, -999.0);
EXTERN INIT( double Latitude, -999.0);
EXTERN INIT( int LatDeg, 0);
EXTERN INIT( int LatMin, 0);
EXTERN INIT( int LatSec, 0);
EXTERN INIT( int LongDeg, 0);
EXTERN INIT( int LongMin, 0);
EXTERN INIT( int LongSec, 0);
EXTERN INIT( double Longitude, DEFAULT_LONGITUDE);
EXTERN INIT( double Latitude, DEFAULT_LATITUDE);
EXTERN INIT( char *Location, LOCATION);
@@ -168,6 +168,17 @@ EXTERN char *MonthName[]
;
#endif
EXTERN char *DynamicMonthName[]
#ifdef MK_GLOBALS
#if LANG == ENGLISH
= {"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"}
#else
= {L_JAN, L_FEB, L_MAR, L_APR, L_MAY, L_JUN,
L_JUL, L_AUG, L_SEP, L_OCT, L_NOV, L_DEC}
#endif
#endif
;
EXTERN char *EnglishDayName[]
#ifdef MK_GLOBALS
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
@@ -186,6 +197,18 @@ EXTERN char *DayName[]
;
#endif
EXTERN char *DynamicDayName []
#ifdef MK_GLOBALS
#if LANG == ENGLISH
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
"Saturday", "Sunday"}
#else
= {L_MONDAY, L_TUESDAY, L_WEDNESDAY, L_THURSDAY, L_FRIDAY,
L_SATURDAY, L_SUNDAY}
#endif
#endif
;
EXTERN int MonthDays[]
#ifdef MK_GLOBALS
= {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

View File

@@ -185,7 +185,7 @@ void InitRemind(int argc, char const *argv[])
FromJulian(JulianToday, &CurYear, &CurMon, &CurDay);
/* Initialize Latitude and Longitude */
set_lat_and_long_from_components();
set_components_from_lat_and_long();
/* See if we were invoked as "rem" rather than "remind" */
if (argv[0]) {
@@ -198,6 +198,9 @@ void InitRemind(int argc, char const *argv[])
if (!strcmp(s, "rem")) {
InvokedAsRem = 1;
}
} else {
fprintf(stderr, "Invoked with a NULL argv[0]; bailing because that's just plain bizarre.\n");
exit(1);
}
/* Parse the command-line options */
@@ -695,7 +698,7 @@ void Usage(void)
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline f=tracefiles\n");
fprintf(ErrFp, " -e Divert messages normally sent to stderr to stdout\n");
fprintf(ErrFp, " -b[n] Time format for cal: 0=am/pm, 1=24hr, 2=none\n");
fprintf(ErrFp, " -x[n] Iteration limit for SATISFY clause (def=150)\n");
fprintf(ErrFp, " -x[n] Iteration limit for SATISFY clause (def=1000)\n");
fprintf(ErrFp, " -kcmd Run `cmd' for MSG-type reminders\n");
fprintf(ErrFp, " -g[dddd] Sort reminders by date, time, priority, and 'timedness'\n");
fprintf(ErrFp, " -ivar=val Initialize var to val and preserve var\n");

View File

@@ -15,21 +15,13 @@
#define L_LANGNAME "Danish"
/* Day names */
#if ISOLATIN1
# define L_SUNDAY "S\370ndag"
#else
# define L_SUNDAY "Soendag"
#endif
#define L_SUNDAY "Søndag"
#define L_MONDAY "Mandag"
#define L_TUESDAY "Tirsdag"
#define L_WEDNESDAY "Onsdag"
#define L_THURSDAY "Torsdag"
#define L_FRIDAY "Fredag"
#if ISOLATIN1
# define L_SATURDAY "L\370rdag"
#else
# define L_SATURDAY "Loerdag"
#endif
#define L_SATURDAY "Lørdag"
/* Month names */
#define L_JAN "Januar"
@@ -50,11 +42,7 @@
#define L_TOMORROW "i morgen"
/* The default banner */
#if ISOLATIN1
# define L_BANNER "P\345mindelse for %w, %d. %m, %y%o:"
#else
# define L_BANNER "Paamindelse for %w, %d. %m, %y%o:"
#endif
#define L_BANNER "Påmindelse for %w, %d. %m, %y%o:"
/* "am" and "pm" */
#define L_AM "am"
@@ -71,11 +59,7 @@
#define L_INXDAYS "om %d dage"
/* "on" as in "on date..." */
#if ISOLATIN1
# define L_ON "p\345"
#else
# define L_ON "paa"
#endif
#define L_ON "på"
/* Pluralizing - this is a problem for many languages and may require
a more drastic fix */

View File

@@ -33,16 +33,8 @@
#define L_MAR "maaliskuu"
#define L_APR "huhtikuu"
#define L_MAY "toukokuu"
#if ISOLATIN1
#define L_JUN "kes\xE4kuu"
#define L_JUL "hein\xE4kuu"
#elif IBMEXTENDED
#define L_JUN "kes\x84kuu"
#define L_JUL "hein\x84kuu"
#else
#define L_JUN "kes{kuu"
#define L_JUL "hein{kuu"
#endif
#define L_JUN "kesäkuu"
#define L_JUL "heinäkuu"
#define L_AUG "elokuu"
#define L_SEP "syyskuu"
#define L_OCT "lokakuu"
@@ -50,13 +42,7 @@
#define L_DEC "joulukuu"
/* Today and tomorrow */
#if ISOLATIN1
#define L_TODAY "t\xE4n\xE4\xE4n"
#elif IBMEXTENDED
#define L_TODAY "t\x84n\x84\x84n"
#else
#define L_TODAY "t{n{{n"
#endif
#define L_TODAY "tänään"
#define L_TOMORROW "huomenna"
/* The default banner */
@@ -74,13 +60,7 @@
#define L_FROMNOW "kuluttua"
/* "in %d days' time" */
#if ISOLATIN1
#define L_INXDAYS "%d p\xE4iv\xE4n kuluttua"
#elif IBMEXTENDED
#define L_INXDAYS "%d p\x84iv\x84n kuluttua"
#else
#define L_INXDAYS "%d p{iv{n kuluttua"
#endif
#define L_INXDAYS "%d päivän kuluttua"
/* "on" as in "on date...", but in Finnish it is a case ending;
L_PARTIT is the partitive ending appended to -kuu and -tai */
@@ -90,13 +70,7 @@
/* Pluralizing - this is a problem for many languages and may require
a more drastic fix */
/* The partitive ending of "day" */
#if ISOLATIN1
#define L_PLURAL "\xE4"
#elif IBMEXTENDED
#define L_PLURAL "\x84"
#else
#define L_PLURAL "{"
#endif
#define L_PLURAL "ä"
/* Minutes, hours, at, etc */
#define L_NOW "nyt"
@@ -120,9 +94,8 @@
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
See the file dosubst.c for more info. */
#if ISOLATIN1
#define L_ORDINAL_OVERRIDE switch(d) { \
case 1: plu = ":sen\xE4"; break; \
case 1: plu = ":senä"; break; \
case 2: plu = ":sena"; break; \
default: \
switch(d%10) { \
@@ -130,36 +103,9 @@
case 3: \
case 6: \
case 8: plu = ":ntena"; break; \
default: plu = ":nten\xE4"; break; \
default: plu = ":ntenä"; break; \
} \
}
#elif IBMEXTENDED
#define L_ORDINAL_OVERRIDE switch(d) { \
case 1: plu = ":sen\x84"; break; \
case 2: plu = ":sena"; break; \
default: \
switch(d%10) { \
case 2: \
case 3: \
case 6: \
case 8: plu = ":ntena"; break; \
default: plu = ":nten\x84"; break; \
} \
}
#else
#define L_ORDINAL_OVERRIDE switch(d) { \
case 1: plu = ":sen{"; break; \
case 2: plu = ":sena"; break; \
default: \
switch(d%10) { \
case 2: \
case 3: \
case 6: \
case 8: plu = ":ntena"; break; \
default: plu = ":nten{"; break; \
} \
}
#endif
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s%s %d. %s%s %d", DayName[jul%7], L_ON, d, MonthName[m], L_PARTIT, y); }
#define L_C_OVER if (altmode == '*') { sprintf(s, "%s", DayName[jul%7]); } else { sprintf(s, "%s%s", DayName[jul%7], L_ON); }
#define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DateSep, m+1, DateSep, y);
@@ -199,104 +145,103 @@ else { \
#define L_ERR_OVERRIDE 1
EXTERN char *ErrMsg[] =
{
#if ISOLATIN1
"Ok",
"Puuttuva ']'",
"Puuttuva lainausmerkki",
"Liian monimutkainen lauseke - liikaa operaattoreita",
"Liian monimutkainen lauseke - liikaa operandeja",
"Puuttuva ')'",
"M\xE4\xE4rittelem\xE4t\xF6n funktio",
"Määrittelemätön funktio",
"Virheellinen merkki",
"Kaksipaikkainen operaattori puuttuu",
"Muisti loppui",
"Virheellinen luku",
"Operaattoripino tyhj\xE4 - sis\xE4inen virhe",
"Muuttujapino tyhj\xE4 - sis\xE4inen virhe",
"Operaattoripino tyhjä - sisäinen virhe",
"Muuttujapino tyhjä - sisäinen virhe",
"Tyyppimuunnos ei onnistu",
"Virheellinen tyyppi",
"Liian suuri p\xE4iv\xE4ys",
"Pinovirhe - sis\xE4inen virhe",
"Liian suuri päiväys",
"Pinovirhe - sisäinen virhe",
"Jako nollalla",
"M\xE4\xE4rittelem\xE4t\xF6n funktio",
"Määrittelemätön funktio",
"Odottamaton rivin loppu",
"Odottamaton tiedoston loppu",
"Sy\xF6tt\xF6- tai tulostusvirhe",
"Liian pitk\xE4 rivi",
"Sis\xE4inen virhe",
"Virheellinen p\xE4iv\xE4ys",
"Liian v\xE4h\xE4n argumentteja",
"Syöttö- tai tulostusvirhe",
"Liian pitkä rivi",
"Sisäinen virhe",
"Virheellinen päiväys",
"Liian vähän argumentteja",
"Liian paljon argumentteja",
"Virheellinen aika",
"Liian suuri luku",
"Liian pieni luku",
"Tiedoston avaus ei onnistu",
"Liian monta sis\xE4kk\xE4ist\xE4 INCLUDEa",
"J\xE4sennysvirhe",
"Liian monta sisäkkäistä INCLUDEa",
"Jäsennysvirhe",
"Laukaisuhetken laskenta ei onnistu",
"Liian monta sis\xE4kk\xE4ist\xE4 IF-lausetta",
"Liian monta sisäkkäistä IF-lausetta",
"ELSE ilman IF-lausetta",
"ENDIF ilman IF-lausetta",
"Kaikkia viikonp\xE4ivi\xE4 ei voi j\xE4tt\xE4\xE4 pois",
"Ylim\xE4\xE4r\xE4isi\xE4 merkkej\xE4 rivill\xE4",
"Kaikkia viikonpäiviä ei voi jättää pois",
"Ylimääräisiä merkkejä rivillä",
"POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia",
"RUN-lauseen k\xE4ytt\xF6 estetty",
"RUN-lauseen käyttö estetty",
"Arvoaluevirhe",
"Virheellinen tunniste",
"Rekursiivinen funktiokutsu havaittu",
"",
"J\xE4rjestelm\xE4muuttujan muuttaminen ei onnistu",
"C-kirjastofunktio ei pysty esitt\xE4m\xE4\xE4n p\xE4iv\xE4yst\xE4 tai aikaa",
"Sis\xE4isen funktion m\xE4\xE4ritelm\xE4\xE4 yritettiin muuttaa",
"Lausekkeessa ei voi olla sis\xE4kk\xE4isi\xE4 funktiom\xE4\xE4ritelmi\xE4",
"P\xE4iv\xE4yksen t\xE4ytyy olla t\xE4ydellinen toistokertoimessa",
"Järjestelmämuuttujan muuttaminen ei onnistu",
"C-kirjastofunktio ei pysty esittämään päiväystä tai aikaa",
"Sisäisen funktion määritelmää yritettiin muuttaa",
"Lausekkeessa ei voi olla sisäkkäisiä funktiomääritelmiä",
"Päiväyksen täytyy olla täydellinen toistokertoimessa",
"Vuosi annettu kahdesti",
"Kuukausi annettu kahdesti",
"P\xE4iv\xE4 annettu kahdesti",
"Päivä annettu kahdesti",
"Tuntematon sana tai merkki",
"OMIT-komennossa on annettava kuukausi ja p\xE4iv\xE4",
"OMIT-komennossa on annettava kuukausi ja päivä",
"Liian monta osittaista OMIT-komentoa",
"Liian monta t\xE4ydellist\xE4 OMIT-komentoa",
"Liian monta täydellistä OMIT-komentoa",
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
"Virhe tiedoston luvussa",
"Pilkku puuttuu",
"Virheellinen juutalainen p\xE4iv\xE4ys",
"IIF vaatii parittoman m\xE4\xE4r\xE4n argumentteja",
"Virheellinen juutalainen päiväys",
"IIF vaatii parittoman määrän argumentteja",
"Varoitus: puuttuva ENDIF",
"Pilkku puuttuu",
"Viikonp\xE4iv\xE4 annettu kahdesti",
"K\xE4yt\xE4 vain yht\xE4 komennoista BEFORE, AFTER ja SKIP",
"Sis\xE4kk\xE4isi\xE4 MSG-, MSF- ja RUN-lauseita ei voi k\xE4ytt\xE4\xE4 lausekkeessa",
"Viikonpäivä annettu kahdesti",
"Käytä vain yhtä komennoista BEFORE, AFTER ja SKIP",
"Sisäkkäisiä MSG-, MSF- ja RUN-lauseita ei voi käyttää lausekkeessa",
"Toistokerroin annettu kahdesti",
"Delta-arvo annettu kahdesti",
"Peruutusarvo annettu kahdesti",
"ONCE-avainsanaa k\xE4ytetty kahdesti. (Hah.)",
"AT-sanan per\xE4st\xE4 puuttuu aika",
"THROUGH/UNTIL-sanaa k\xE4ytetty kahdesti",
"Ep\xE4t\xE4ydellinen p\xE4iv\xE4ys",
"FROM/SCANFROM-sanaa k\xE4ytetty kahdesti",
"ONCE-avainsanaa käytetty kahdesti. (Hah.)",
"AT-sanan perästä puuttuu aika",
"THROUGH/UNTIL-sanaa käytetty kahdesti",
"Epätäydellinen päiväys",
"FROM/SCANFROM-sanaa käytetty kahdesti",
"Muuttuja",
"Arvo",
"*M\xC4\xC4RITTELEM\xC4T\xD6N*",
"Siirryt\xE4\xE4n funktioon",
"*MÄÄRITTELEMÄTÖN*",
"Siirrytään funktioon",
"Poistutaan funktiosta",
"Vanhentunut",
"fork() ep\xE4onnistui - jonomuistutukset eiv\xE4t toimi",
"fork() epäonnistui - jonomuistutukset eivät toimi",
"Tiedoston avaus ei onnistu",
"Virheellinen j\xE4rjestelm\xE4p\xE4iv\xE4ys: vuosi on v\xE4hemm\xE4n kuin %d\n",
"Tuntematon virheenetsint\xE4tarkenne '%c'\n",
"Virheellinen järjestelmäpäiväys: vuosi on vähemmän kuin %d\n",
"Tuntematon virheenetsintätarkenne '%c'\n",
"Tuntematon tarkenne '%c'\n",
"Tuntematon k\xE4ytt\xE4j\xE4 '%s'\n",
"Ryhm\xE4numeron vaihto %d:ksi ei onnistunut\n",
"K\xE4ytt\xE4j\xE4numeron vaihto %d:ksi ei onnistunut\n",
"Muisti ei riit\xE4 ymp\xE4rist\xF6lle\n",
"Tuntematon käyttäjä '%s'\n",
"Ryhmänumeron vaihto %d:ksi ei onnistunut\n",
"Käyttäjänumeron vaihto %d:ksi ei onnistunut\n",
"Muisti ei riitä ympäristölle\n",
"Puuttuva '='-merkki",
"Puuttuva muuttujanimi",
"Puuttuva lauseke",
"P\xE4iv\xE4n asetus %s:ksi ei onnitus\n",
"Päivän asetus %s:ksi ei onnitus\n",
"Remind: tarkenne '-i': %s\n",
"Ei viestej\xE4.",
"%d viesti(\xE4) t\xE4m\xE4n p\xE4iv\xE4n jonossa.\n",
"Ei viestejä.",
"%d viesti(ä) tämän päivän jonossa.\n",
"Numero puuttuu",
"Virheellinen funktio WARN-lausekkeessa",
"Can't convert between time zones",
@@ -304,221 +249,6 @@ EXTERN char *ErrMsg[] =
"String too long",
"Time specified twice",
"Cannot specify DURATION without specifying AT"
#elif IBMEXTENDED
"Ok",
"Puuttuva ']'",
"Puuttuva lainausmerkki",
"Liian monimutkainen lauseke - liikaa operaattoreita",
"Liian monimutkainen lauseke - liikaa operandeja",
"Puuttuva ')'",
"M\x84\x84rittelem\x84t\x94n funktio",
"Virheellinen merkki",
"Kaksipaikkainen operaattori puuttuu",
"Muisti loppui",
"Virheellinen luku",
"Operaattoripino tyhj\x84 - sis\x84inen virhe",
"Muuttujapino tyhj\x84 - sis\x84inen virhe",
"Tyyppimuunnos ei onnistu",
"Virheellinen tyyppi",
"Liian suuri p\x84iv\x84ys",
"Pinovirhe - sis\x84inen virhe",
"Jako nollalla",
"M\x84\x84rittelem\x84t\x94n funktio",
"Odottamaton rivin loppu",
"Odottamaton tiedoston loppu",
"Sy\x94tt\x94- tai tulostusvirhe",
"Liian pitk\x84 rivi",
"Sis\x84inen virhe",
"Virheellinen p\x84iv\x84ys",
"Liian v\x84h\x84n argumentteja",
"Liian paljon argumentteja",
"Virheellinen aika",
"Liian suuri luku",
"Liian pieni luku",
"Tiedoston avaus ei onnistu",
"Liian monta sis\x84kk\x84ist\x84 INCLUDEa",
"J\x84sennysvirhe",
"Laukaisuhetken laskenta ei onnistu",
"Liian monta sis\x84kk\x84ist\x84 IF-lausetta",
"ELSE ilman IF-lausetta",
"ENDIF ilman IF-lausetta",
"Kaikkia viikonp\x84ivi\x84 ei voi j\x84tt\x84\x84 pois",
"Ylim\x84\x84r\x84isi\x84 merkkej\x84 rivill\x84",
"POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia",
"RUN-lauseen k\x84ytt\x94 estetty",
"Arvoaluevirhe",
"Virheellinen tunniste",
"Rekursiivinen funktiokutsu havaittu",
"",
"J\x84rjestelm\x84muuttujan muuttaminen ei onnistu",
"C-kirjastofunktio ei pysty esitt\x84m\x84\x84n p\x84iv\x84yst\x84 tai aikaa",
"Sis\x84isen funktion m\x84\x84ritelm\x84\x84 yritettiin muuttaa",
"Lausekkeessa ei voi olla sis\x84kk\x84isi\x84 funktiom\x84\x84ritelmi\x84",
"P\x84iv\x84yksen t\x84ytyy olla t\x84ydellinen toistokertoimessa",
"Vuosi annettu kahdesti",
"Kuukausi annettu kahdesti",
"P\x84iv\x84 annettu kahdesti",
"Tuntematon sana tai merkki",
"OMIT-komennossa on annettava kuukausi ja p\x84iv\x84",
"Liian monta osittaista OMIT-komentoa",
"Liian monta t\x84ydellist\x84 OMIT-komentoa",
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
"Virhe tiedoston luvussa",
"Pilkku puuttuu",
"Virheellinen juutalainen p\x84iv\x84ys",
"IIF vaatii parittoman m\x84\x84r\x84n argumentteja",
"Varoitus: puuttuva ENDIF",
"Pilkku puuttuu",
"Viikonp\x84iv\x84 annettu kahdesti",
"K\x84yt\x84 vain yht\x84 komennoista BEFORE, AFTER ja SKIP",
"Sis\x84kk\x84isi\x84 MSG-, MSF- ja RUN-lauseita ei voi k\x84ytt\x84\x84 lausekkeessa",
"Toistokerroin annettu kahdesti",
"Delta-arvo annettu kahdesti",
"Peruutusarvo annettu kahdesti",
"ONCE-avainsanaa k\x84ytetty kahdesti. (Hah.)",
"AT-sanan per\x84st\x84 puuttuu aika",
"THROUGH/UNTIL-sanaa k\x84ytetty kahdesti",
"Ep\x84t\x84ydellinen p\x84iv\x84ys",
"FROM/SCANFROM-sanaa k\x84ytetty kahdesti",
"Muuttuja",
"Arvo",
"*M\x8E\x8ERITTELEM\x8ET\x99N*",
"Siirryt\x84\x84n funktioon",
"Poistutaan funktiosta",
"Vanhentunut",
"fork() ep\x84onnistui - jonomuistutukset eiv\x84t toimi",
"Tiedoston avaus ei onnistu",
"Virheellinen j\x84rjestelm\x84p\x84iv\x84ys: vuosi on v\x84hemm\x84n kuin %d\n",
"Tuntematon virheenetsint\x84tarkenne '%c'\n",
"Tuntematon tarkenne '%c'\n",
"Tuntematon k\x84ytt\x84j\x84 '%s'\n",
"Ryhm\x84numeron vaihto %d:ksi ei onnistunut\n",
"K\x84ytt\x84j\x84numeron vaihto %d:ksi ei onnistunut\n",
"Muisti ei riit\x84 ymp\x84rist\x94lle\n",
"Puuttuva '='-merkki",
"Puuttuva muuttujanimi",
"Puuttuva lauseke",
"P\x84iv\x84n asetus %s:ksi ei onnitus\n",
"Remind: tarkenne '-i': %s\n",
"Ei viestej\x84.",
"%d viesti(\x84) t\x84m\x84n p\x84iv\x84n jonossa.\n",
"Numero puuttuu"
"Virheellinen funktio WARN-lausekkeessa",
"Can't convert between time zones",
"No files matching *.rem",
"String too long",
"Time specified twice",
"Cannot specify DURATION without specifying AT"
#else
"Ok",
"Puuttuva ']'",
"Puuttuva lainausmerkki",
"Liian monimutkainen lauseke - liikaa operaattoreita",
"Liian monimutkainen lauseke - liikaa operandeja",
"Puuttuva ')'",
"M{{rittelem{t|n funktio",
"Virheellinen merkki",
"Kaksipaikkainen operaattori puuttuu",
"Muisti loppui",
"Virheellinen luku",
"Operaattoripino tyhj{ - sis{inen virhe",
"Muuttujapino tyhj{ - sis{inen virhe",
"Tyyppimuunnos ei onnistu",
"Virheellinen tyyppi",
"Liian suuri p{iv{ys",
"Pinovirhe - sis{inen virhe",
"Jako nollalla",
"M{{rittelem{t|n funktio",
"Odottamaton rivin loppu",
"Odottamaton tiedoston loppu",
"Sy|tt|- tai tulostusvirhe",
"Liian pitk{ rivi",
"Sis{inen virhe",
"Virheellinen p{iv{ys",
"Liian v{h{n argumentteja",
"Liian paljon argumentteja",
"Virheellinen aika",
"Liian suuri luku",
"Liian pieni luku",
"Tiedoston avaus ei onnistu",
"Liian monta sis{kk{ist{ INCLUDEa",
"J{sennysvirhe",
"Laukaisuhetken laskenta ei onnistu",
"Liian monta sis{kk{ist{ IF-lausetta",
"ELSE ilman IF-lausetta",
"ENDIF ilman IF-lausetta",
"Kaikkia viikonp{ivi{ ei voi j{tt{{ pois",
"Ylim{{r{isi{ merkkej{ rivill{",
"POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia",
"RUN-lauseen k{ytt| estetty",
"Arvoaluevirhe",
"Virheellinen tunniste",
"Rekursiivinen funktiokutsu havaittu",
"",
"J{rjestelm{muuttujan muuttaminen ei onnistu",
"C-kirjastofunktio ei pysty esitt{m{{n p{iv{yst{ tai aikaa",
"Sis{isen funktion m{{ritelm{{ yritettiin muuttaa",
"Lausekkeessa ei voi olla sis{kk{isi{ funktiom{{ritelmi{",
"P{iv{yksen t{ytyy olla t{ydellinen toistokertoimessa",
"Vuosi annettu kahdesti",
"Kuukausi annettu kahdesti",
"P{iv{ annettu kahdesti",
"Tuntematon sana tai merkki",
"OMIT-komennossa on annettava kuukausi ja p{iv{",
"Liian monta osittaista OMIT-komentoa",
"Liian monta t{ydellist{ OMIT-komentoa",
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
"Virhe tiedoston luvussa",
"Pilkku puuttuu",
"Virheellinen juutalainen p{iv{ys",
"IIF vaatii parittoman m{{r{n argumentteja",
"Varoitus: puuttuva ENDIF",
"Pilkku puuttuu",
"Viikonp{iv{ annettu kahdesti",
"K{yt{ vain yht{ komennoista BEFORE, AFTER ja SKIP",
"Sis{kk{isi{ MSG-, MSF- ja RUN-lauseita ei voi k{ytt{{ lausekkeessa",
"Toistokerroin annettu kahdesti",
"Delta-arvo annettu kahdesti",
"Peruutusarvo annettu kahdesti",
"ONCE-avainsanaa k{ytetty kahdesti. (Hah.)",
"AT-sanan per{st{ puuttuu aika",
"THROUGH/UNTIL-sanaa k{ytetty kahdesti",
"Ep{t{ydellinen p{iv{ys",
"FROM/SCANFROM-sanaa k{ytetty kahdesti",
"Muuttuja",
"Arvo",
"*M[[RITTELEM[T\\N*",
"Siirryt{{n funktioon",
"Poistutaan funktiosta",
"Vanhentunut",
"fork() ep{onnistui - jonomuistutukset eiv{t toimi",
"Tiedoston avaus ei onnistu",
"Virheellinen j{rjestelm{p{iv{ys: vuosi on v{hemm{n kuin %d\n",
"Tuntematon virheenetsint{tarkenne '%c'\n",
"Tuntematon tarkenne '%c'\n",
"Tuntematon k{ytt{j{ '%s'\n",
"Ryhm{numeron vaihto %d:ksi ei onnistunut\n",
"K{ytt{j{numeron vaihto %d:ksi ei onnistunut\n",
"Muisti ei riit{ ymp{rist|lle\n",
"Puuttuva '='-merkki",
"Puuttuva muuttujanimi",
"Puuttuva lauseke",
"P{iv{n asetus %s:ksi ei onnitus\n",
"Remind: tarkenne '-i': %s\n",
"Ei viestej{.",
"%d viesti({) t{m{n p{iv{n jonossa.\n",
"Numero puuttuu",
"Virheellinen funktio WARN-lausekkeessa",
"Can't convert between time zones",
"No files matching *.rem",
"String too long",
"Time specified twice",
"Cannot specify DURATION without specifying AT"
#endif
};
#endif /* MK_GLOBALS */
@@ -531,93 +261,33 @@ void Usage(void)
#ifdef BETA
fprintf(ErrFp, ">>>> BETAVERSIO <<<<\n");
#endif
#if ISOLATIN1
fprintf(ErrFp, "K\xE4ytt\xF6: remind [tarkenteet] tiedosto [p\xE4iv\xE4ys] [aika] [*toisto]\n");
fprintf(ErrFp, "Käyttö: remind [tarkenteet] tiedosto [päiväys] [aika] [*toisto]\n");
fprintf(ErrFp, "Tarkenteet:\n");
fprintf(ErrFp, " -n Tulosta viestien seuraavat esiintymiskerrat yksink. muodossa\n");
fprintf(ErrFp, " -r Est\xE4 RUN-lauseiden k\xE4ytt\xF6\n");
fprintf(ErrFp, " -r Estä RUN-lauseiden käyttö\n");
fprintf(ErrFp, " -c[n] Tulosta n:n kuukauden kalenteri (oletus 1)\n");
fprintf(ErrFp, " -c+[n] Tulosta n:n viikon kalenteri (oletus 1)\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja v\xE4lit\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja välit\n");
fprintf(ErrFp, " -s[+][n] Tulosta n:n kuukauden (viikon) 'yksink. kalenteri' (oletus 1)\n");
fprintf(ErrFp, " -p[n] Kuten -s, mutta tulosta rem2ps:lle sopivassa muodossa\n");
fprintf(ErrFp, " -v Laveat tulostukset\n");
fprintf(ErrFp, " -o \xC4l\xE4 noudata ONCE-lauseita\n");
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta v\xE4litt\xE4m\xE4tt\xE4\n");
fprintf(ErrFp, " -o Älä noudata ONCE-lauseita\n");
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta välittämättä\n");
fprintf(ErrFp, " -h Suppeat tulostukset\n");
#ifdef HAVE_QUEUED
fprintf(ErrFp, " -a \xC4l\xE4 laukaise viestej\xE4 heti - lis\xE4\xE4 ne jonoon\n");
fprintf(ErrFp, " -q \xC4l\xE4 lis\xE4\xE4 viestej\xE4 jonoon\n");
fprintf(ErrFp, " -a Älä laukaise viestejä heti - lisää ne jonoon\n");
fprintf(ErrFp, " -q Älä lisää viestejä jonoon\n");
fprintf(ErrFp, " -f Laukaise viestit, pysy etualalla\n");
fprintf(ErrFp, " -z[n] K\xE4ynnisty demonina, her\xE4tys n:n (5:n) minuutin v\xE4lein\n");
fprintf(ErrFp, " -z[n] Käynnisty demonina, herätys n:n (5:n) minuutin välein\n");
#endif
fprintf(ErrFp, " -d... Virheenetsint\xE4: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -d... Virheenetsintä: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Ohjaa virhetulostus stdout-vuohon\n");
fprintf(ErrFp, " -b[n] Ajan ilmaisu: 0=ap/ip, 1=24 tuntia, 2=ei aikoja\n");
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 150)\n");
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 1000)\n");
fprintf(ErrFp, " -kcmd Suorita 'cmd' MSG-tyyppisille viesteille\n");
fprintf(ErrFp, " -g[ddd] Lajittele viestit p\xE4iv\xE4yksen, ajan ja t\xE4rkeyden mukaan\n");
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja s\xE4ilyt\xE4 var\n");
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eik\xE4 sunnuntaista\n");
fprintf(ErrFp, " -g[ddd] Lajittele viestit päiväyksen, ajan ja tärkeyden mukaan\n");
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja säilytä var\n");
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eikä sunnuntaista\n");
exit(1);
#elif IBMEXTENDED
fprintf(ErrFp, "K\x84ytt\x94: remind [tarkenteet] tiedosto [p\x84iv\x84ys] [aika] [*toisto]\n");
fprintf(ErrFp, "Tarkenteet:\n");
fprintf(ErrFp, " -n Tulosta viestien seuraavat esiintymiskerrat yksink. muodossa\n");
fprintf(ErrFp, " -r Est\x84 RUN-lauseiden k\x84ytt\x94\n");
fprintf(ErrFp, " -c[n] Tulosta n:n kuukauden kalenteri (oletus 1)\n");
fprintf(ErrFp, " -c+[n] Tulosta n:n viikon kalenteri (oletus 1)\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja v\x84lit\n");
fprintf(ErrFp, " -s[+][n] Tulosta n:n kuukauden (viikon) 'yksink. kalenteri' (oletus 1)\n");
fprintf(ErrFp, " -p[n] Kuten -s, mutta tulosta rem2ps:lle sopivassa muodossa\n");
fprintf(ErrFp, " -v Laveat tulostukset\n");
fprintf(ErrFp, " -o \x8El\x84 noudata ONCE-lauseita\n");
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta v\x84litt\x84m\x84tt\x84\n");
fprintf(ErrFp, " -h Suppeat tulostukset\n");
#ifdef HAVE_QUEUED
fprintf(ErrFp, " -a \x8El\x84 laukaise viestej\x84 heti - lis\x84\x84 ne jonoon\n");
fprintf(ErrFp, " -q \x8El\x84 lis\x84\x84 viestej\x84 jonoon\n");
fprintf(ErrFp, " -f Laukaise viestit, pysy etualalla\n");
fprintf(ErrFp, " -z[n] K\x84ynnisty demonina, her\x84tys n:n (5:n) minuutin v\x84lein\n");
#endif
fprintf(ErrFp, " -d... Virheenetsint\x84: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Ohjaa virhetulostus stdout-vuohon\n");
fprintf(ErrFp, " -b[n] Ajan ilmaisu: 0=ap/ip, 1=24 tuntia, 2=ei aikoja\n");
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 150)\n");
fprintf(ErrFp, " -kcmd Suorita 'cmd' MSG-tyyppisille viesteille\n");
fprintf(ErrFp, " -g[ddd] Lajittele viestit p\x84iv\x84yksen, ajan ja t\x84rkeyden mukaan\n");
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja s\x84ilyt\x84 var\n");
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eik\x84 sunnuntaista\n");
exit(1);
#else
fprintf(ErrFp, "K{ytt|: remind [tarkenteet] tiedosto [p{iv{ys] [aika] [*toisto]\n");
fprintf(ErrFp, "Tarkenteet:\n");
fprintf(ErrFp, " -n Tulosta viestien seuraavat esiintymiskerrat yksink. muodossa\n");
fprintf(ErrFp, " -r Est{ RUN-lauseiden k{ytt|\n");
fprintf(ErrFp, " -c[n] Tulosta n:n kuukauden kalenteri (oletus 1)\n");
fprintf(ErrFp, " -c+[n] Tulosta n:n viikon kalenteri (oletus 1)\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja v{lit\n");
fprintf(ErrFp, " -s[+][n] Tulosta n:n kuukauden (viikon) 'yksink. kalenteri' (oletus 1)\n");
fprintf(ErrFp, " -p[n] Kuten -s, mutta tulosta rem2ps:lle sopivassa muodossa\n");
fprintf(ErrFp, " -v Laveat tulostukset\n");
fprintf(ErrFp, " -o [l{ noudata ONCE-lauseita\n");
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta v{litt{m{tt{\n");
fprintf(ErrFp, " -h Suppeat tulostukset\n");
#ifdef HAVE_QUEUED
fprintf(ErrFp, " -a [l{ laukaise viestej{ heti - lis{{ ne jonoon\n");
fprintf(ErrFp, " -q [l{ lis{{ viestej{ jonoon\n");
fprintf(ErrFp, " -f Laukaise viestit, pysy etualalla\n");
fprintf(ErrFp, " -z[n] K{ynnisty demonina, her{tys n:n (5:n) minuutin v{lein\n");
#endif
fprintf(ErrFp, " -d... Virheenetsint{: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Ohjaa virhetulostus stdout-vuohon\n");
fprintf(ErrFp, " -b[n] Ajan ilmaisu: 0=ap/ip, 1=24 tuntia, 2=ei aikoja\n");
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 150)\n");
fprintf(ErrFp, " -kcmd Suorita 'cmd' MSG-tyyppisille viesteille\n");
fprintf(ErrFp, " -g[ddd] Lajittele viestit p{iv{yksen, ajan ja t{rkeyden mukaan\n");
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja s{ilyt{ var\n");
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eik{ sunnuntaista\n");
exit(1);
#endif
}
#endif /* L_IN_INIT */

View File

@@ -28,29 +28,18 @@
/* Month names */
#define L_JAN "janvier"
#if ISOLATIN1
#define L_FEB "f\351vrier"
#else
#define L_FEB "fevrier"
#endif
#define L_FEB "février"
#define L_MAR "mars"
#define L_APR "avril"
#define L_MAY "mai"
#define L_JUN "juin"
#define L_JUL "juillet"
#if ISOLATIN1
#define L_AUG "ao\373t"
#else
#define L_AUG "aout"
#endif
#define L_AUG "août"
#define L_SEP "septembre"
#define L_OCT "octobre"
#define L_NOV "novembre"
#if ISOLATIN1
#define L_DEC "d\351cembre"
#else
#define L_DEC "decembre"
#endif
#define L_DEC "décembre"
/* Today and tomorrow */
#define L_TODAY "aujourd'hui"
#define L_TOMORROW "demain"
@@ -81,22 +70,14 @@
/* Minutes, hours, at, etc */
#define L_NOW "maintenant"
#if ISOLATIN1
#define L_AT "\340"
#else
#define L_AT "a"
#endif
#define L_AT "à"
#define L_MINUTE "minute"
#define L_HOUR "heure"
#define L_IS "est"
#if ISOLATIN1
#define L_WAS "\351tait"
#else
#define L_WAS "etait"
#endif
#define L_WAS "était"
#define L_AND "et"
/* What to add to make "hour" plural */
#define L_HPLU "s"
#define L_HPLU "s"
/* What to add to make "minute" plural */
#define L_MPLU "s"
@@ -139,218 +120,110 @@ else if (tdiff < 0) { \
#define L_ERR_OVERRIDE 1
EXTERN char *ErrMsg[] =
{
#if ISOLATIN1
"Ok",
"']' manquant",
"Apostrophe manquant",
"Expression trop complexe - trop d'op\351rateurs",
"Expression trop complexe - trop d'op\351randes",
"Expression trop complexe - trop d'opérateurs",
"Expression trop complexe - trop d'opérandes",
"')' manquante",
"Fonction non-d\351finie",
"Caract\350re ill\351gal",
"Op\351rateur binaire attendu",
"Manque de m\351moire",
"Nombre mal form\351",
"Erreur interne - 'underflow' de la pile d'op\351rateurs",
"Fonction non-définie",
"Caractère illégal",
"Opérateur binaire attendu",
"Manque de mémoire",
"Nombre mal formé",
"Erreur interne - 'underflow' de la pile d'opérateurs",
"Erreur interne - 'underflow' de la pile de variables",
"Impossible de convertir",
"Types non-\351quivalents",
"D\351bordement de date",
"Types non-équivalents",
"Débordement de date",
"Erreur interne - erreur de pile",
"Division par z\351ro",
"Variable non d\351finie",
"Division par zéro",
"Variable non définie",
"Fin de ligne non attendue",
"Fin de fichier non attendue",
"Erreur I/O",
"Ligne trop longue",
"Erreur interne",
"Mauvaise date sp\351cifi\351e",
"Mauvaise date spécifiée",
"Pas assez d'arguments",
"Trop d'arguments",
"Heure mal form\351e",
"Nombre trop \351lev\351",
"Heure mal formée",
"Nombre trop élevé",
"Nombre trop bas",
"Impossible d'ouvrir le fichier",
"Trop d'INCLUDE imbriqu\351s",
"Trop d'INCLUDE imbriqués",
"Erreur d'analyse",
"Impossible de calculer le d\351clenchement",
"Trop de IF imbriqu\351s",
"Impossible de calculer le déclenchement",
"Trop de IF imbriqués",
"ELSE sans IF correspondant",
"ENDIF sans IF correspondant",
"Impossible d'omettre (OMIT) tous les jours",
"El\351ment(s) \351tranger(s) sur la ligne",
"Elément(s) étranger(s) sur la ligne",
"POP-OMIT-CONTEXT sans PUSH-OMIT-CONTEXT correspondant",
"RUN d\351activ\351",
"RUN déactivé",
"Erreur de domaine",
"Identificateur invalide",
"Appel r\351cursif d\351tect\351",
"Appel récursif détecté",
"",
"Impossible de modifier une variable syst\350me",
"Fonction de la librairie C ne peut repr\351senter la date/l'heure",
"Tentative de red\351finition d'une fonction intrins\350que",
"Impossible d'imbriquer une d\351finition de fonction dans une expression",
"Pour utiliser le facteur de r\351p\351tition la date doit \352tre sp\351cifi\351e au complet",
"Ann\351e sp\351cifi\351e deux fois",
"Mois sp\351cifi\351 deux fois",
"Jour sp\351cifi\351 deux fois",
"El\351ment inconnu",
"Mois et jour doivent \352tre sp\351cifi\351s dans commande OMIT",
"Impossible de modifier une variable système",
"Fonction de la librairie C ne peut représenter la date/l'heure",
"Tentative de redéfinition d'une fonction intrinsèque",
"Impossible d'imbriquer une définition de fonction dans une expression",
"Pour utiliser le facteur de répétition la date doit être spécifiée au complet",
"Année spécifiée deux fois",
"Mois spécifié deux fois",
"Jour spécifié deux fois",
"Elément inconnu",
"Mois et jour doivent être spécifiés dans commande OMIT",
"Trop de OMITs partiels",
"Trop de OMITs complets",
"Attention: PUSH-OMIT-CONTEXT sans POP-OMIT-CONTEXT correspondant",
"Erreur \340 la lecture du fichier",
"Erreur à la lecture du fichier",
"Fin de ligne attendue",
"Date h\351breuse invalide",
"Date hébreuse invalide",
"IIF demande nombre d'arguments impair",
"Attention: ENDIF manquant",
"Virgule attendue",
"Jour de la semaine sp\351cifi\351 deux fois",
"Jour de la semaine spécifié deux fois",
"Utiliser un seul parmi BEFORE, AFTER ou SKIP",
"Impossible d'imbriquer MSG, MSF, RUN, etc. dans une expression",
"Valeur de r\351p\351tition sp\351cifi\351e deux fois",
"Valeur delta sp\351cifi\351e deux fois",
"Valeur de retour sp\351cifi\351e deux fois",
"Mot-cl\351 ONCE utilis\351 deux fois. (Hah.)",
"Heure attendue apr\350s AT",
"Mot-cl\351 THROUGH/UNTIL utilis\351 deux fois",
"Sp\351cification de date incompl\350te",
"Mot-cl\351 FROM/SCANFROM utilis\351 deux fois",
"Valeur de répétition spécifiée deux fois",
"Valeur delta spécifiée deux fois",
"Valeur de retour spécifiée deux fois",
"Mot-clé ONCE utilisé deux fois. (Hah.)",
"Heure attendue après AT",
"Mot-clé THROUGH/UNTIL utilisé deux fois",
"Spécification de date incomplète",
"Mot-clé FROM/SCANFROM utilisé deux fois",
"Variable",
"Valeur",
"*NON-DEFINI*",
"Entr\351e dans UserFN",
"Entrée dans UserFN",
"Sortie de UserFN",
"Expir\351",
"fork() \351chou\351 - impossible de faire les appels en queue",
"Impossible d'acc\351der au fichier",
"Date syst\350me ill\351gale: Ann\351e est inf\351rieure \340 %d\n",
"Option de d\351verminage inconnue '%c'\n",
"Expiré",
"fork() échoué - impossible de faire les appels en queue",
"Impossible d'accéder au fichier",
"Date système illégale: Année est inférieure à %d\n",
"Option de déverminage inconnue '%c'\n",
"Option inconnue '%c'\n",
"Usager inconnu '%s'\n",
"Impossible de changer gid pour %d\n",
"Impossible de changer uid pour %d\n",
"Manque de m\351moire pour environnement\n",
"Manque de mémoire pour environnement\n",
"Signe '=' manquant",
"Nom de variable absent",
"Expression absente",
"Impossible de changer la date d'acc\350s de %s\n",
"Impossible de changer la date d'accès de %s\n",
"Remind: '-i' option: %s\n",
"Pas de rappels.",
"%d rappel(s) en file pour aujourd'hui.\n",
"Nombre attendu",
"Fonction ill\351gale apr\350s WARN",
"Fonction illégale après WARN",
"Can't convert between time zones",
"No files matching *.rem",
"String too long",
"Time specified twice",
"Cannot specify DURATION without specifying AT"
#else /* ISOLATIN1 */
"Ok",
"']' manquant",
"Apostrophe manquant",
"Expression trop complexe - trop d'operateurs",
"Expression trop complexe - trop d'operandes",
"')' manquante",
"Fonction non-definie",
"Caractere illegal",
"Operateur binaire attendu",
"Manque de memoire",
"Nombre mal forme",
"Erreur interne - 'underflow' de la pile d'operateurs",
"Erreur interne - 'underflow' de la pile de variables",
"Impossible de convertir",
"Types non-equivalents",
"Debordement de date",
"Erreur interne - erreur de pile",
"Division par zero",
"Variable non definie",
"Fin de ligne non attendue",
"Fin de fichier non attendue",
"Erreur I/O",
"Ligne trop longue",
"Erreur interne",
"Mauvaise date specifiee",
"Pas assez d'arguments",
"Trop d'arguments",
"Heure mal formee",
"Nombre trop eleve",
"Nombre trop bas",
"Impossible d'ouvrir le fichier",
"Trop d'INCLUDE imbriques",
"erreur d'analyse",
"Impossible de calculer le declenchement",
"Trop de IF imbriques",
"ELSE sans IF correspondant",
"ENDIF sans IF correspondant",
"Impossible d'omettre (OMIT) tous les jours",
"Element(s) etranger(s) sur la ligne",
"POP-OMIT-CONTEXT sans PUSH-OMIT-CONTEXT correspondant",
"RUN desactive",
"Erreur de domaine",
"Identificateur invalide",
"Appel recursif detecte",
"",
"Impossible de modifier une variable systeme",
"Fonction de la librairie C ne peut representer la date/l'heure",
"Tentative de redefinition d'une fonction intrinseque",
"Impossible d'imbriquer une definition de fonction dans une expression",
"Pour utiliser le facteur de repetition la date doit etre specifiee au complet",
"Annee specifiee deux fois",
"Mois specifie deux fois",
"Jour specifie deux fois",
"Element inconnu",
"Mois et jour doivent etre specifies dans commande OMIT",
"Trop de OMITs partiels",
"Trop de OMITs complets",
"Attention: PUSH-OMIT-CONTEXT sans POP-OMIT-CONTEXT correspondant",
"Erreur a la lecture du fichier",
"Fin de ligne attendue",
"Date hebreuse invalide",
"IIF demande nombre d'arguments impair",
"Attention: ENDIF manquant",
"Virgule attendue",
"Jour de la semaine specifie deux fois",
"Utiliser un seul parmi BEFORE, AFTER ou SKIP",
"Impossible d'imbriquer MSG, MSF, RUN, etc. dans une expression",
"Valeur de repetition specifiee deux fois",
"Valeur delta specifiee deux fois",
"Valeur de retour specifiee deux fois",
"Mot-cle ONCE utilise deux fois. (Hah.)",
"Heure attendue apres AT",
"Mot-cle THROUGH/UNTIL utilise deux fois",
"Specification de date incomplete",
"Mot-cle FROM/SCANFROM utilise deux fois",
"Variable",
"Valeur",
"*NON-DEFINI*",
"Entree dans UserFN",
"Sortie de UserFN",
"Expire",
"fork() echoue - impossible de faire les appels en queue",
"Impossible d'acceder au fichier",
"Date systeme illegale: Annee est inferieure a %d\n",
"Option de deverminage inconnue '%c'\n",
"Option inconnue '%c'\n",
"Usager inconnu '%s'\n",
"Impossible de changer gid pour %d\n",
"Impossible de changer uid pour %d\n",
"Manque de memoire pour environnement\n",
"Signe '=' manquant",
"Nom de variable absent",
"Expression absente",
"Impossible de changer la date d'acces de %s\n",
"Remind: '-i' option: %s\n",
"Pas de rappels.",
"%d rappel(s) en file pour aujourd'hui.\n",
"Nombre attendu",
"Fonction illegale apres WARN",
"Can't convert between time zones",
"No files matching *.rem",
"String too long",
"Time specified twice",
"Cannot specify DURATION without specifying AT"
#endif /* ISOLATIN1 */
};
#endif /* MK_GLOBALS */
@@ -363,63 +236,33 @@ void Usage(void)
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif
#if ISOLATIN1
fprintf(ErrFp, "\nUtilisation: remind [options] fichier [date] [heure] [*r\351p\351tition]\n");
fprintf(ErrFp, "\nUtilisation: remind [options] fichier [date] [heure] [*répétition]\n");
fprintf(ErrFp, "Options:\n");
fprintf(ErrFp, " -n Afficher la prochaine occurence des rappels en format simple\n");
fprintf(ErrFp, " -r D\351sactiver les instructions RUN\n");
fprintf(ErrFp, " -c[n] Produire un calendrier pour n (d\351faut 1) mois\n");
fprintf(ErrFp, " -c+[n] Produire un calendrier pour n (d\351faut 1) semaines\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Sp\351cifier largeur, remplissage et espacement du calendrier\n");
fprintf(ErrFp, " -r Désactiver les instructions RUN\n");
fprintf(ErrFp, " -c[n] Produire un calendrier pour n (défaut 1) mois\n");
fprintf(ErrFp, " -c+[n] Produire un calendrier pour n (défaut 1) semaines\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Spécifier largeur, remplissage et espacement du calendrier\n");
fprintf(ErrFp, " -s[+][n] Produire un 'calendrier simple' pour n (1) mois (semaines)\n");
fprintf(ErrFp, " -p[n] Comme -s, mais avec entr\351e compatible avec rem2ps\n");
fprintf(ErrFp, " -p[n] Comme -s, mais avec entrée compatible avec rem2ps\n");
fprintf(ErrFp, " -v Mode verbeux\n");
fprintf(ErrFp, " -o Ignorer instructions ONCE\n");
fprintf(ErrFp, " -t D\351clencher tous les rappels peu importe le delta\n");
fprintf(ErrFp, " -t Déclencher tous les rappels peu importe le delta\n");
fprintf(ErrFp, " -h Mode silencieux\n");
#ifdef HAVE_QUEUED
fprintf(ErrFp, " -a Ne pas d\351clencher les rappels minut\351s imm\351diatement - les mettre en file\n");
fprintf(ErrFp, " -q Ne pas mettre les rappels minut\351s en file\n");
fprintf(ErrFp, " -f D\351clencher les rappels minut\351s imm\351diatement en restant en avant-plan\n");
fprintf(ErrFp, " -z[n] Entrer en mode 'daemon', r\351veil chaque n (5) minutes\n");
fprintf(ErrFp, " -a Ne pas déclencher les rappels minutés immédiatement - les mettre en file\n");
fprintf(ErrFp, " -q Ne pas mettre les rappels minutés en file\n");
fprintf(ErrFp, " -f Déclencher les rappels minutés immédiatement en restant en avant-plan\n");
fprintf(ErrFp, " -z[n] Entrer en mode 'daemon', réveil chaque n (5) minutes\n");
#endif
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Envoyer les messages de stderr \340 stdout\n");
fprintf(ErrFp, " -e Envoyer les messages de stderr à stdout\n");
fprintf(ErrFp, " -b[n] Formats de l'heure pour le calendrier: 0=am/pm, 1=24hr, 2=aucun\n");
fprintf(ErrFp, " -x[n] Limite d'it\351rations pour la clause SATISFY (def=150)\n");
fprintf(ErrFp, " -kcmd Ex\351cuter 'cmd' pour les rappels de type MSG\n");
fprintf(ErrFp, " -g[ddd] Trier les rappels par date, heure et priorit\351 avant d'\351mettre\n");
fprintf(ErrFp, " -ivar=val Initialiser var \340 val et conserver var\n");
fprintf(ErrFp, " -m Commencer le calendrier avec lundi plut\364t que dimanche\n");
#else /* ISOLATIN1 */
fprintf(ErrFp, "\nUtilisation: remind [options] fichier [date] [heure] [*repetition]\n");
fprintf(ErrFp, "Options:\n");
fprintf(ErrFp, " -n Afficher la prochaine occurence des rappels en format simple\n");
fprintf(ErrFp, " -r Desactiver les instructions RUN\n");
fprintf(ErrFp, " -c[n] Produire un calendrier pour n (defaut 1) mois\n");
fprintf(ErrFp, " -c+[n] Produire un calendrier pour n (defaut 1) semaines\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Specifier largeur, remplissage et espacement du calendrier\n");
fprintf(ErrFp, " -s[+][n] Produire un 'calendrier simple' pour n (1) mois (semaines)\n");
fprintf(ErrFp, " -p[n] Comme -s, mais avec entree compatible avec rem2ps\n");
fprintf(ErrFp, " -v Mode verbeux\n");
fprintf(ErrFp, " -o Ignorer instructions ONCE\n");
fprintf(ErrFp, " -t Declencher tous les rappels peu importe le delta\n");
fprintf(ErrFp, " -h Mode silencieux\n");
#ifdef HAVE_QUEUED
fprintf(ErrFp, " -a Ne pas declencher les rappels minutes immediatement - les mettre en file\n");
fprintf(ErrFp, " -q Ne pas mettre les rappels minutes en file\n");
fprintf(ErrFp, " -f Declencher les rappels minutes immediatement en restant en avant-plan\n");
fprintf(ErrFp, " -z[n] Entrer en mode 'daemon', reveil chaque n (5) minutes\n");
#endif
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Envoyer les messages de stderr a stdout\n");
fprintf(ErrFp, " -b[n] Formats de l'heure pour le calendrier: 0=am/pm, 1=24hr, 2=aucun\n");
fprintf(ErrFp, " -x[n] Limite d'iterations pour la clause SATISFY (def=150)\n");
fprintf(ErrFp, " -kcmd Executer 'cmd' pour les rappels de type MSG\n");
fprintf(ErrFp, " -g[ddd] Trier les rappels par date, heure et priorite avant d'emettre\n");
fprintf(ErrFp, " -ivar=val Initialiser var a val et conserver var\n");
fprintf(ErrFp, " -m Commencer le calendrier avec lundi plutot que dimanche\n");
#endif /* ISOLATIN1 */
fprintf(ErrFp, " -x[n] Limite d'itérations pour la clause SATISFY (def=1000)\n");
fprintf(ErrFp, " -kcmd Exécuter 'cmd' pour les rappels de type MSG\n");
fprintf(ErrFp, " -g[ddd] Trier les rappels par date, heure et priorité avant d'émettre\n");
fprintf(ErrFp, " -ivar=val Initialiser var à val et conserver var\n");
fprintf(ErrFp, " -m Commencer le calendrier avec lundi plutôt que dimanche\n");
exit(1);
}
#endif /* L_IN_INIT */

View File

@@ -28,11 +28,7 @@
/* Month names */
#define L_JAN "Januar"
#define L_FEB "Februar"
#if ISOLATIN1
# define L_MAR "M\344rz"
#else
# define L_MAR "Maerz"
#endif
#define L_MAR "März"
#define L_APR "April"
#define L_MAY "Mai"
#define L_JUN "Juni"
@@ -48,11 +44,7 @@
#define L_TOMORROW "morgen"
/* The default banner */
#if ISOLATIN1
# define L_BANNER "Termine f\374r %w, den %d. %m %y%o:"
#else
# define L_BANNER "Termine fuer %w, den %d. %m %y%o:"
#endif
#define L_BANNER "Termine für %w, den %d. %m %y%o:"
/* "am" and "pm" */
#define L_AM "am"

View File

@@ -15,23 +15,13 @@
#define L_LANGNAME "Italian"
/* Day names */
#if ISOLATIN1
#define L_SUNDAY "Domenica"
#define L_MONDAY "Luned\354"
#define L_TUESDAY "Marted\354"
#define L_WEDNESDAY "Mercoled\354"
#define L_THURSDAY "Gioved\354"
#define L_FRIDAY "Venerd\354"
#define L_MONDAY "Lunedí"
#define L_TUESDAY "Martedí"
#define L_WEDNESDAY "Mercoledí"
#define L_THURSDAY "Giovedí"
#define L_FRIDAY "Venerdí"
#define L_SATURDAY "Sabato"
#else /* ISOLATIN1 */
#define L_SUNDAY "Domenica"
#define L_MONDAY "Lunedi`"
#define L_TUESDAY "Martedi`"
#define L_WEDNESDAY "Mercoledi`"
#define L_THURSDAY "Giovedi`"
#define L_FRIDAY "Venerdi`"
#define L_SATURDAY "Sabato"
#endif /* ISOLATIN */
/* Month names */
#define L_JAN "Gennaio"
@@ -76,58 +66,54 @@
a more drastic fix */
/* Minutes, hours, at, etc */
#define L_NOW "ora"
#define L_NOW "ora"
#define L_AT "alle"
#define L_MINUTE "minut"
#define L_HOUR "or"
#if ISOLATIN1
#define L_IS "\350"
#else /* ISOLATIN1 */
#define L_IS "e`"
#endif/* ISOLATIN1 */
#define L_IS "é"
#define L_WAS "era"
#define L_AND "e"
/* What to add to make "hour" plural */
#define L_HPLU "s"
#define L_HPLU "s"
/* What to add to make "minute" plural */
#define L_MPLU "s"
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
See the file dosubst.c for more info. */
#define L_P_OVER sprintf(s, (diff == 1 ? "o" : "i"));
#define L_Q_OVER sprintf(s, (diff == 1 ? "a" : "e"));
#define L_P_OVER sprintf(s, (diff == 1 ? "o" : "i"));
#define L_Q_OVER sprintf(s, (diff == 1 ? "a" : "e"));
#define L_HPLU_OVER hplu = (hdiff == 1 ? "a" : "e");
#define L_MPLU_OVER mplu = (mdiff == 1 ? "o" : "i");
#define L_A_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d,\
MonthName[m], y);
#define L_C_OVER sprintf(s, "%s", DayName[jul%7]);
MonthName[m], y);
#define L_C_OVER sprintf(s, "%s", DayName[jul%7]);
#define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DateSep,\
m+1, DateSep, y);
m+1, DateSep, y);
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
#define L_G_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, MonthName[m]);
#define L_G_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, MonthName[m]);
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DateSep, m+1);
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DateSep, m+1);
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DateSep, d);
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DateSep, d);
#define L_J_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, \
MonthName[m], y);
MonthName[m], y);
#define L_K_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, \
MonthName[m]);
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
MonthName[m]);
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
#define L_U_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, \
MonthName[m], y);
MonthName[m], y);
#define L_V_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, \
MonthName[m]);
MonthName[m]);
#endif /* L_IN_DOSUBST */

View File

@@ -14,21 +14,13 @@
#define L_LANGNAME "Norwegian"
/* Day names */
#if ISOLATIN1
# define L_SUNDAY "S\370ndag"
#else
# define L_SUNDAY "Soendag"
#endif
#define L_SUNDAY "Søndag"
#define L_MONDAY "Mandag"
#define L_TUESDAY "Tirsdag"
#define L_WEDNESDAY "Onsdag"
#define L_THURSDAY "Torsdag"
#define L_FRIDAY "Fredag"
#if ISOLATIN1
# define L_SATURDAY "L\370rdag"
#else
# define L_SATURDAY "Loerdag"
#endif
#define L_SATURDAY "Lørdag"
/* Month names */
#define L_JAN "Januar"
@@ -49,11 +41,7 @@
#define L_TOMORROW "i morgen"
/* The default banner */
#if ISOLATIN1
# define L_BANNER "P\345minnelse for %w, %d. %m, %y%o:"
#else
# define L_BANNER "Paaminnelse for %w, %d. %m, %y%o:"
#endif
#define L_BANNER "Påminnelse for %w, %d. %m, %y%o:"
/* "am" and "pm" */
#define L_AM "am"
@@ -64,11 +52,7 @@
/* Ago and from now */
#define L_AGO "siden"
#if ISOLATIN1
# define L_FROMNOW "fra n\345"
#else
# define L_FROMNOW "fra naa"
#endif
#define L_FROMNOW "fra nå"
/* "in %d days' time" */
#define L_INXDAYS "om %d dager"
@@ -81,11 +65,7 @@
#define L_PLURAL "er"
/* Minutes, hours, at, etc */
#if ISOLATIN1
# define L_NOW "n\345"
#else
# define L_NOW "naa"
#endif
#define L_NOW "nå"
#define L_AT "kl."
#define L_MINUTE "minutt"
#define L_HOUR "time"
@@ -93,7 +73,7 @@
#define L_WAS "var"
#define L_AND "og"
/* What to add to make "hour" plural */
#define L_HPLU "r"
#define L_HPLU "r"
/* What to add to make "minute" plural */
#define L_MPLU "er"

View File

@@ -17,52 +17,27 @@
#define L_LANGNAME "Polish"
/* Day names */
#if ISOLATIN1
# define L_SUNDAY "Niedziela"
# define L_MONDAY "Poniedzia\263ek"
# define L_MONDAY "Poniedziałek"
# define L_TUESDAY "Wtorek"
# define L_WEDNESDAY "\246roda"
# define L_WEDNESDAY "Środa"
# define L_THURSDAY "Czwartek"
# define L_FRIDAY "Pi\261tek"
# define L_FRIDAY "Piątek"
# define L_SATURDAY "Sobota"
#else
# define L_SUNDAY "Niedziela"
# define L_MONDAY "Poniedzialek"
# define L_TUESDAY "Wtorek"
# define L_WEDNESDAY "Sroda"
# define L_THURSDAY "Czwartek"
# define L_FRIDAY "Piatek"
# define L_SATURDAY "Sobota"
#endif
/* Month names */
#if ISOLATIN1
# define L_JAN "Stycze\361"
# define L_JAN "Styczeń"
# define L_FEB "Luty"
# define L_MAR "Marzec"
# define L_APR "Kwiecie\361"
# define L_APR "Kwiecień"
# define L_MAY "Maj"
# define L_JUN "Czerwiec"
# define L_JUL "Lipiec"
# define L_AUG "Sierpie\361"
# define L_SEP "Wrzesie\361"
# define L_OCT "Pa\274dziernik"
# define L_AUG "Sierpień"
# define L_SEP "Wrzesień"
# define L_OCT "Październik"
# define L_NOV "Listopad"
# define L_DEC "Grudzie\361"
#else
# define L_JAN "Styczen"
# define L_FEB "Luty"
# define L_MAR "Marzec"
# define L_APR "Kwiecien"
# define L_MAY "Maj"
# define L_JUN "Czerwiec"
# define L_JUL "Lipiec"
# define L_AUG "Sierpien"
# define L_SEP "Wrzesien"
# define L_OCT "Pazdziernik"
# define L_NOV "Listopad"
# define L_DEC "Grudzien"
#endif
# define L_DEC "Grudzień"
/* Today and tomorrow */
#define L_TODAY "dzisiaj"
@@ -97,22 +72,12 @@
#define L_AT "o"
#define L_MINUTE "minut"
#define L_HOUR "godzin"
#if ISOLATIN1
# define L_IS "b\352dzie"
# define L_WAS "by\263o"
#else
# define L_IS "bedzie"
# define L_WAS "bylo"
#endif
# define L_IS "będzie"
# define L_WAS "było"
#define L_AND "i"
/* What to add to make "hour" or "minute" plural */
#if ISOLATIN1
#define L_NPLU( N ) ((N == 1) ? "\352" : ((N==12) || (N==13) || (N==14)) ? "" : \
#define L_NPLU( N ) ((N == 1) ? "ę" : ((N==12) || (N==13) || (N==14)) ? "" : \
((N%10==2) || (N%10==3) || (N%10==4)) ? "y" : "" )
#else
#define L_NPLU( N ) ((N == 1) ? "e" : ((N==12) || (N==13) || (N==14)) ? "" : \
((N%10==2) || (N%10==3) || (N%10==4)) ? "y" : "" )
#endif
/* What to add to make "hour" plural */
#define L_HPLU L_NPLU( hdiff )
/* What to add to make "minute" plural */
@@ -120,25 +85,14 @@
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
See the file dosubst.c for more info. */
#if ISOLATIN1
#define L_AMPM_OVERRIDE(ampm, hour) \
ampm = (hour<12) ? \
(hour<5) ? " w nocy" \
: (hour<10) ? " rano" \
: " przed po\263udniem" \
: (hour<18) ? " po po\263udniu" \
: " przed południem" \
: (hour<18) ? " po południu" \
: (hour<22) ? " wieczorem" \
: " w nocy";
#else
#define L_AMPM_OVERRIDE(ampm, hour) \
ampm = (hour<12) ? \
(hour<5) ? " w nocy" \
: (hour<10) ? " rano" \
: " przed poludniem" \
: (hour<18) ? " po poludniu" \
: (hour<22) ? " wieczorem" \
: " w nocy";
#endif
#define L_ORDINAL_OVERRIDE plu = "";
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); }
@@ -178,104 +132,103 @@ else \
#define L_ERR_OVERRIDE 1
EXTERN char *ErrMsg[] =
{
#if ISOLATIN1
"OK",
"Brakuj\261cy ']'",
"Brakuj\261cy nawias",
"Zbyt skomplikowane wyra\277enie - za du\277o operator\363w",
"Zbyt skomplikowane wyra\277enie - za du\277o argument\363w",
"Brakuj\261cy ')'",
"Brakujący ']'",
"Brakujący nawias",
"Zbyt skomplikowane wyrażenie - za dużo operatorów",
"Zbyt skomplikowane wyrażenie - za dużo argumentów",
"Brakujący ')'",
"Nie zdefiniowana funkcja",
"Nielegalny znak",
"Spodziewany operator binarny",
"Brak pami\352ci",
"Brak pamięci",
"Niepoprawny numer",
"Pusty stos operator\363w - b\263\261d wewn\352trzny",
"Pusty stos zmiennych - b\263\261d wewn\352trzny",
"Niemo\277liwa konwersja",
"B\263\261d typu",
"Pusty stos operatorów - błąd wewnętrzny",
"Pusty stos zmiennych - błąd wewnętrzny",
"Niemożliwa konwersja",
"Błąd typu",
"Nadmiar daty",
"B\263\261d stosu - b\263\261d wewn\352trzny",
"Błąd stosu - błąd wewnętrzny",
"Dzielenie przez zero",
"Niezdefiniowana zmienna",
"Niespodziewany koniec linii",
"Niespodziewany koniec pliku",
"B\263\261d wejscia/wyjscia",
"Za d\263uga linia",
"B\263\261d wewn\352trzny",
"Z\263a specyfikacja daty",
"Za ma\263o argument\363w",
"Za du\277o argument\363w",
"Nieprawid\263owy czas",
"Liczba za du\277a",
"Liczba za ma\263a",
"Nie mog\352 otworzy\346 pliku",
"Zbyt zagnie\277d\277one INCLUDE",
"B\263\261d sk\263adniowy",
"Nie mog\352 obliczy\346 przypomnienia",
"Zbyt zagnie\277d\277one IF",
"Błąd wejscia/wyjscia",
"Za długa linia",
"Błąd wewnętrzny",
"Zła specyfikacja daty",
"Za mało argumentów",
"Za dużo argumentów",
"Nieprawidłowy czas",
"Liczba za duża",
"Liczba za mała",
"Nie mogę otworzyć pliku",
"Zbyt zagnieżdżone INCLUDE",
"Błąd składniowy",
"Nie mogę obliczyć przypomnienia",
"Zbyt zagnieżdżone IF",
"ELSE bez IF do pary",
"ENDIF bez IF do pary",
"Nie mog\352 omin\261\346 (OMIT) wszystkich dni",
"Nie mogę ominąć (OMIT) wszystkich dni",
"Niespodziewany wyraz w lini",
"POP-OMIT-CONTEXT bez PUSH-OMIT-CONTEXT",
"Komenda RUN zablokowana",
"B\263\261d dziedziny",
"Błąd dziedziny",
"Niepoprawny identyfikator",
"Wykryto rekursywne wywo\263anie funkcji",
"Wykryto rekursywne wywołanie funkcji",
"",
"Nie mog\352 zmieni\346 zmiennej systemowej",
"Funkcja biblioteki C nie mo\277e reprezentowac daty/czasu",
"Pr\363ba redefinicji funkcji wbudowanej",
"Nie wolno zagnie\277d\277a\346 definicji funkcji w wyra\277eniu",
"Aby u\277yc powt\363rzenia trzeba w pe\263ni wyspecyfikowa\346 dat\352",
"Rok podany dw\363krotnie",
"Miesi\261c podany dw\363krotnie",
"Dzie\361 podany dw\363krotnie",
"Nieznane s\263owo",
"W komendzie OMIT trzeba poda\346 miesi\261c i dzie\361",
"Za du\277o cz\352\266ciowych komend OMIT",
"Za du\277o pe\263nych komend OMIT",
"Ostrze\277enie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT",
"B\263\261d odczytu pliku",
"Nie mogę zmienić zmiennej systemowej",
"Funkcja biblioteki C nie może reprezentowac daty/czasu",
"Próba redefinicji funkcji wbudowanej",
"Nie wolno zagnieżdżać definicji funkcji w wyrażeniu",
"Aby użyc powtórzenia trzeba w pełni wyspecyfikować datę",
"Rok podany dwókrotnie",
"Miesiąc podany dwókrotnie",
"Dzień podany dwókrotnie",
"Nieznane słowo",
"W komendzie OMIT trzeba podać miesiąc i dzień",
"Za dużo częściowych komend OMIT",
"Za dużo pełnych komend OMIT",
"Ostrzeżenie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT",
"Błąd odczytu pliku",
"Oczekiwany koniec linii",
"B\263\352dna data hebrajska",
"IIF wymaga nieparzystej liczby argument\363w",
"Ostrze\277enie: Brakujacy ENDIF",
"Błędna data hebrajska",
"IIF wymaga nieparzystej liczby argumentów",
"Ostrzeżenie: Brakujacy ENDIF",
"Oczekiwany przecinek",
"Dzie\361 tygodnia podany dw\363krotnie",
"Dzień tygodnia podany dwókrotnie",
"Dozwolone tylko jedno z: BEFORE, AFTER i SKIP",
"Nie mo\277na zagnie\277d\277a\346 MSG, MSF, RUN, itp. w wyra\277eniu",
"Warto\266\346 powtorzenia podana dw\363krotnie",
"Warto\266\346 r\363\277nicy podana dw\363krotnie",
"Warto\266\346 cofni\352cia podana dw\363krotnie",
"S\263owo ONCE u\277yte dw\363krotnie.",
"Nie można zagnieżdżać MSG, MSF, RUN, itp. w wyrażeniu",
"Wartość powtorzenia podana dwókrotnie",
"Wartość różnicy podana dwókrotnie",
"Wartość cofnięcia podana dwókrotnie",
"Słowo ONCE użyte dwókrotnie.",
"Po AT oczekiwany jest czas",
"S\263owo THROUGH/UNTIL u\277yte dw\363krotnie",
"Słowo THROUGH/UNTIL użyte dwókrotnie",
"Niekompletna specyfikacja daty",
"S\263owo FROM/SCANFROM u\277yte dw\363krotnie",
"Słowo FROM/SCANFROM użyte dwókrotnie",
"Zmienna",
"Warto\266\346",
"Wartość",
"*NIE ZDEFINIOWANE*",
"Pocz\261tek UserFN",
"Początek UserFN",
"Koniec UserFN",
"Przemine\263o",
"Niepowodzenie w funkcji fork() - nie mog\352 kolejkowa\346 przypomnie\361",
"Nie ma dost\352pu do pliku",
"B\263\352dna data systemowa: Rok mniejszy ni\277 %d\n",
"Przemineło",
"Niepowodzenie w funkcji fork() - nie mogę kolejkować przypomnień",
"Nie ma dostępu do pliku",
"Błędna data systemowa: Rok mniejszy niż %d\n",
"Nieznana flaga odpluskwiania '%c'\n",
"Nieznana opcja '%c'\n",
"Nieznany u\277ytkownik '%s'\n",
"Nie mog\352 zmieni\346 gid na %d\n",
"Nie mog\352 zmieni\346 uid na %d\n",
"Brak pami\352ci na zmienne \266rodowiska\n",
"Nieznany użytkownik '%s'\n",
"Nie mogę zmienić gid na %d\n",
"Nie mogę zmienić uid na %d\n",
"Brak pamięci na zmienne środowiska\n",
"Brak znaku '='",
"Brak nazwy zmiennej",
"Brak wyra\277enia",
"Nie mog\352 zmieni\346 daty dost\352pu pliku %s\n",
"Brak wyrażenia",
"Nie mogę zmienić daty dostępu pliku %s\n",
"Remind: '-i' option: %s\n",
"Brak przypomnie\361.",
"%d Przypomnienia zakolejkowane na p\363\274niej.\n",
"Brak przypomnień.",
"%d Przypomnienia zakolejkowane na później.\n",
"Spodziewana liczba",
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)",
"Can't convert between time zones",
@@ -283,112 +236,6 @@ EXTERN char *ErrMsg[] =
"String too long",
"Time specified twice",
"Cannot specify DURATION without specifying AT"
#else /* ISOLATIN1 */
"OK",
"Brakujacy ']'",
"Brakujacy nawias",
"Zbyt skomplikowane wyrazenie - za duzo operatorow",
"Zbyt skomplikowane wyrazenie - za duzo argumentow",
"Brakujacy ')'",
"Niezdefiniowana funkcja",
"Nielegalny znak",
"Spodziewany operator binarny",
"Brak pamieci",
"Niepoprawny numer",
"Pusty stos operatorow - blad wewnetrzny",
"Pusty stos zmiennych - blad wewnetrzny",
"Niemozliwa konwersja",
"Blad typu",
"Nadmiar daty",
"Blad stosu - blad wewnetrzny",
"Dzielenie przez zero",
"Niezdefiniowana zmienna",
"Niespodziewany koniec linii",
"Niespodziewany koniec pliku",
"Blad wejscia/wyjscia",
"Za dluga linia",
"Blad wewnetrzny",
"Zla specyfikacja daty",
"Za malo argumentow",
"Za duzo argumentow",
"Nieprawidlowy czas",
"Liczba za duza",
"Liczba za mala",
"Nie moge otworzyc pliku",
"INCLUDE zbyt zagniezdzone",
"Blad skladniowy",
"Nie moge obliczyc przypomnienia",
"Zbyt zagniezdzone IF",
"ELSE bez IF do pary",
"ENDIF bez IF do pary",
"Nie moge ominac (OMIT) wszystkich dni",
"Niespodziewany wyraz w lini",
"POP-OMIT-CONTEXT bez PUSH-OMIT-CONTEXT",
"Komenda RUN zablokowana",
"Blad dziedziny",
"Niepoprawny identyfikator",
"Wykryto rekursywne wywolanie funkcji",
"",
"Nie moga zmienic zmiennej systemowej",
"Funkcja biblioteki C nie moze reprezentowac daty/czasu",
"Proba redefinicji funkcji wbudowanej",
"Nie wolno zagniezdzac definicji funkcji w wyrazeniu",
"Aby uzyc powtorzenia trzeba w pelni wyspecyfikowac date",
"Rok podany dwokrotnie",
"Miesiac podany dwokrotnie",
"Dzien podany dwokrotnie",
"Nieznane slowo",
"W komendzie OMIT trzeba podac miesiac i dzien",
"Za duzo czesciowych komend OMIT",
"Za duzo pelnych komend OMIT",
"ostrzezenie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT",
"Blad odczytu pliku",
"Oczekiwany koniec linii",
"Bledna data hebrajska",
"IIF wymaga nieparzystej liczby argumentow",
"Ostrzezenie: Brakujacy ENDIF",
"Oczekiwany przecinek",
"Dzien tygodnia podany dwokrotnie",
"Dozwolone tylko jedno z: BEFORE, AFTER i SKIP",
"Nie mozna zagniezdzac MSG, MSF, RUN, itp. w wyrazeniu",
"Wartosc powtorzenia podana dwokrotnie",
"Wartosc roznicy podana dwokrotnie",
"Wartosc cofniecia podana dwokrotnie",
"Slowo ONCE uzyte dwokrotnie.",
"Po AT oczekiwany jest czas",
"Slowo THROUGH/UNTIL uzyte dwokrotnie",
"Niekompletna specyfikacja daty",
"Slowo FROM/SCANFROM uzyte dwokrotnie",
"Zmienna",
"Wartosc",
"*UNDEFINED*",
"Poczatek UserFN",
"Koniec UserFN",
"Przeminelo",
"niepowodzenie w funkcji fork() - nie moge kolejkowac przypomnien",
"Nie ma dostepu do pliku",
"Bledna data systemowa: Rok mniejszy niz %d\n",
"Nieznana flaga odpluskwiania '%c'\n",
"Nieznana opcja '%c'\n",
"Nieznany uzytkownik '%s'\n",
"Nie moge zmienic gid na %d\n",
"Nie moge zmienic uid na %d\n",
"Brak pamieci na zmienne srodowiska\n",
"Brak znaku '='",
"Brak nazwy zmiennej",
"Brak wyrazenia",
"Nie moge zmienic daty dostepu pliku %s\n",
"Remind: '-i' option: %s\n",
"Brak przypomnien.",
"%d Przypomnienia zakolejkowane na pozniej.\n",
"Spodziewana liczba",
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)",
"Can't convert between time zones",
"No files matching *.rem",
"String too long",
"Time specified twice",
"Cannot specify DURATION without specifying AT"
#endif /* ISOLATIN1 */
};
#endif /* MK_GLOBALS */
@@ -401,63 +248,33 @@ void Usage(void)
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif
#if ISOLATIN1
fprintf(ErrFp, "\nSpos\363b u\277ycia: remind [opcje] plik [data] [czas] [*powt\363rzenie]\n");
fprintf(ErrFp, "\nSposób użycia: remind [opcje] plik [data] [czas] [*powtórzenie]\n");
fprintf(ErrFp, "Opcje:\n");
fprintf(ErrFp, " -n Wypisz nast\352pne przypomnienia w prostym formacie\n");
fprintf(ErrFp, " -n Wypisz następne przypomnienia w prostym formacie\n");
fprintf(ErrFp, " -r Zablokuj dyrektywy RUN\n");
fprintf(ErrFp, " -c[n] Wypisz kalendarz na n (domy\266lnie 1) miesi\352cy\n");
fprintf(ErrFp, " -c+[n] Wypisz kalendarz na n (domy\266lnie 1) tygodni\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Ustaw szeroko\266\346, wype\263nienie i odst\352py w kalendarzu\n");
fprintf(ErrFp, " -s[+][n] Wypisz uproszczony kalendarz na n (1) miesi\352cy (tygodni)\n");
fprintf(ErrFp, " -c[n] Wypisz kalendarz na n (domyślnie 1) miesięcy\n");
fprintf(ErrFp, " -c+[n] Wypisz kalendarz na n (domyślnie 1) tygodni\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Ustaw szerokość, wypełnienie i odstępy w kalendarzu\n");
fprintf(ErrFp, " -s[+][n] Wypisz uproszczony kalendarz na n (1) miesięcy (tygodni)\n");
fprintf(ErrFp, " -p[n] To samo co -s, ale kompatybilne z rem2ps\n");
fprintf(ErrFp, " -v Obszerniejsze komentarze\n");
fprintf(ErrFp, " -o Ignoruj instrukcje ONCE\n");
fprintf(ErrFp, " -t Odpal wszystkie przysz\263e przypomnienia niezale\277nie od delty\n");
fprintf(ErrFp, " -t Odpal wszystkie przyszłe przypomnienia niezależnie od delty\n");
fprintf(ErrFp, " -h Praca bezszmerowa\n");
#ifdef HAVE_QUEUED
fprintf(ErrFp, " -a Nie odpalaj przyponie\361 czasowych - kolejkuj je\n");
fprintf(ErrFp, " -q Nie kolejkuj przyponie\361 czasowych\n");
fprintf(ErrFp, " -f Nie przechod\274 do pracy w tle\n");
fprintf(ErrFp, " -z[n] Pracuj jako demon, budz\261c si\352 co n (5) minut\n");
fprintf(ErrFp, " -a Nie odpalaj przyponień czasowych - kolejkuj je\n");
fprintf(ErrFp, " -q Nie kolejkuj przyponień czasowych\n");
fprintf(ErrFp, " -f Nie przechodź do pracy w tle\n");
fprintf(ErrFp, " -z[n] Pracuj jako demon, budząc się co n (5) minut\n");
#endif
fprintf(ErrFp, " -d... Odpluskwianie: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Komunikaty o b\263\352dach skieruj na stdout\n");
fprintf(ErrFp, " -b[n] Format czasu: 0=am/pm, 1=24godz., 2=\277aden\n");
fprintf(ErrFp, " -x[n] Limit powt\363rze\361 klauzuli SATISFY (domy\266lnie=150)\n");
fprintf(ErrFp, " -kcmd Wywo\263aj 'cmd' dla przypomnie\361 typu MSG\n");
fprintf(ErrFp, " -g[ddd] Sortuj przypomnienia wed\263ug daty, czasu i priorytetu\n");
fprintf(ErrFp, " -ivar=val Zainicjuj zmienn\261 var warto\266cia val i zachowaj ja\n");
fprintf(ErrFp, " -m Rozpocznij kalendarz od poniedzia\263ku zamiast od niedzieli\n");
#else /* ISOLATIN1 */
fprintf(ErrFp, "\nSposob uzycia: remind [opcje] plik [data] [czas] [*powtorzenie]\n");
fprintf(ErrFp, "Opcje:\n");
fprintf(ErrFp, " -n Wypisz nastepne przypomnienia w prostym formacie\n");
fprintf(ErrFp, " -r Zablokuj dyrektywy RUN\n");
fprintf(ErrFp, " -c[n] Wypisz kalendarz na n (domyslnie 1) miesiecy\n");
fprintf(ErrFp, " -c+[n] Wypisz kalendarz na n (domyslnie 1) tygodni\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Ustaw szerokosc, wypelnienie i odstepy w kalendarzu\n");
fprintf(ErrFp, " -s[+][n] Wypisz uproszczony kalendarz na n (1) miesiecy (tygodni)\n");
fprintf(ErrFp, " -p[n] To samo co -s, ale kompatybilne z rem2ps\n");
fprintf(ErrFp, " -v Obszerniejsze komentarze\n");
fprintf(ErrFp, " -o Ignoruj instrukcje ONCE\n");
fprintf(ErrFp, " -t Odpal wszystkie przyszle przypomnienia niezaleznie od delty\n");
fprintf(ErrFp, " -h Praca bezszmerowa\n");
#ifdef HAVE_QUEUED
fprintf(ErrFp, " -a Nie odpalaj przyponien czasowych - kolejkuj je\n");
fprintf(ErrFp, " -q Nie kolejkuj przyponien czasowych\n");
fprintf(ErrFp, " -f Nie przechodz do pracy w tle\n");
fprintf(ErrFp, " -z[n] Pracuj jako demon, budzac sie co n (5) minut\n");
#endif
fprintf(ErrFp, " -d... Odpluskwianie: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Komunikaty o bledach skieruj na stdout\n");
fprintf(ErrFp, " -b[n] Format czasu: 0=am/pm, 1=24godz., 2=zaden\n");
fprintf(ErrFp, " -x[n] Limit powtorzen klauzuli SATISFY (domyslnie=150)\n");
fprintf(ErrFp, " -kcmd Wywolaj 'cmd' dla przypomnien typu MSG\n");
fprintf(ErrFp, " -g[ddd] Sortuj przypomnienia wedlug daty, czasu i priorytetu\n");
fprintf(ErrFp, " -ivar=val Zainicjuj zmienna var wartoscia val i zachowaj ja\n");
fprintf(ErrFp, " -m Rozpocznij kalendarz od poniedzialku zamiast od niedzieli\n");
#endif /* ISOLATIN1 */
fprintf(ErrFp, " -e Komunikaty o błędach skieruj na stdout\n");
fprintf(ErrFp, " -b[n] Format czasu: 0=am/pm, 1=24godz., 2=żaden\n");
fprintf(ErrFp, " -x[n] Limit powtórzeń klauzuli SATISFY (domyślnie=1000)\n");
fprintf(ErrFp, " -kcmd Wywołaj 'cmd' dla przypomnień typu MSG\n");
fprintf(ErrFp, " -g[ddd] Sortuj przypomnienia według daty, czasu i priorytetu\n");
fprintf(ErrFp, " -ivar=val Zainicjuj zmienną var wartościa val i zachowaj ja\n");
fprintf(ErrFp, " -m Rozpocznij kalendarz od poniedziałku zamiast od niedzieli\n");
exit(1);
}
#endif /* L_IN_INIT */

View File

@@ -283,7 +283,7 @@ void Usage(void)
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trigger v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Desvia mensagens normalmente enviadas a stderr para stdout\n");
fprintf(ErrFp, " -b[n] Formato da hora para o cal: 0=am/pm, 1=24hr, 2=nenhum\n");
fprintf(ErrFp, " -x[n] Limite de iteracoes para a clausula SATISFY (default=150)\n");
fprintf(ErrFp, " -x[n] Limite de iteracoes para a clausula SATISFY (default=1000)\n");
fprintf(ErrFp, " -kcmd Executa `cmd' para os compromissos com MSG\n");
fprintf(ErrFp, " -g[ddd] Classifica compromissos por data, hora e prioridade antes de exibir\n");
fprintf(ErrFp, " -ivar=val Inicializa (e preserva) variavel var com val\n");

View File

@@ -17,39 +17,13 @@
#define L_LANGNAME "Romanian"
/* Day names */
#if ISOLATIN1
# define L_SUNDAY "Duminica"
# define L_SUNDAY "Duminică"
# define L_MONDAY "Luni"
# define L_TUESDAY "Marti"
# define L_TUESDAY "Marți"
# define L_WEDNESDAY "Miercuri"
# define L_THURSDAY "Joi"
# define L_FRIDAY "Vineri"
# define L_SATURDAY "S\342mbata"
#elif ISOLATIN2
# define L_SUNDAY "Duminic\343"
# define L_MONDAY "Luni"
# define L_TUESDAY "Mar\376i"
# define L_WEDNESDAY "Miercuri"
# define L_THURSDAY "Joi"
# define L_FRIDAY "Vineri"
# define L_SATURDAY "S\342mb\343t\343"
#elif IBM852
# define L_SUNDAY "Duminic\307"
# define L_MONDAY "Luni"
# define L_TUESDAY "Mar\316i"
# define L_WEDNESDAY "Miercuri"
# define L_THURSDAY "Joi"
# define L_FRIDAY "Vineri"
# define L_SATURDAY "S\203mb\307t\307"
#else
# define L_SUNDAY "Duminica"
# define L_MONDAY "Luni"
# define L_TUESDAY "Marti"
# define L_WEDNESDAY "Miercuri"
# define L_THURSDAY "Joi"
# define L_FRIDAY "Vineri"
# define L_SATURDAY "Sambata"
#endif
# define L_SATURDAY "Sâmbătă"
/* Month names */
#define L_JAN "Ianuarie"
@@ -66,19 +40,8 @@
#define L_DEC "Decembrie"
/* Today and tomorrow */
#if ISOLATIN1
# define L_TODAY "astazi"
# define L_TOMORROW "m\342ine"
#elif ISOLATIN2
# define L_TODAY "ast\343zi"
# define L_TOMORROW "m\342ine"
#elif IBM852
# define L_TODAY "ast\307zi"
# define L_TOMORROW "m\203ine"
#else
# define L_TODAY "astazi"
# define L_TOMORROW "maine"
#endif
# define L_TODAY "astăzi"
# define L_TOMORROW "mâine"
/* The default banner */
#define L_BANNER "Reamintiri pentru %w, %d %m %y%o:"
@@ -114,30 +77,13 @@
/* What to add to make "minute" plural */
#define L_MPLU "e"
#if ISOLATIN2
/* What to add to make "hour" plural */
# define L_HPLU_OVER hplu = (hdiff == 1 ? "\343" : "e");
# define L_AND "\272i"
#elif IBM852
/* What to add to make "hour" plural */
# define L_HPLU_OVER hplu = (hdiff == 1 ? "\307" : "e");
# define L_AND "\255i"
#else
/* What to add to make "hour" plural */
# define L_HPLU_OVER hplu = (hdiff == 1 ? "a" : "e");
# define L_AND "si"
#endif
/* What to add to make "hour" plural */
#define L_HPLU_OVER hplu = (hdiff == 1 ? "ă" : "e");
#define L_AND "şi"
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
See the file dosubst.c for more info. */
#if ISOLATIN2
# define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<4) ? " noaptea" : " diminea\376a" : (hour > 17) ? " seara" : " dup\343-amiaza";
#elif IBM852
# define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<4) ? " noaptea" : " diminea\316a" : (hour > 17) ? " seara" : " dup\307-amiaza";
#else
# define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<4) ? " noaptea" : " dimineata" : (hour > 17) ? " seara" : " dupa-amiaza";
#endif
#define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<4) ? " noaptea" : " dimineaţa" : (hour > 17) ? " seara" : " după-amiaza";
#define L_ORDINAL_OVERRIDE plu = "";
#define L_A_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, MonthName[m], y);

View File

@@ -17,19 +17,10 @@
#define L_SUNDAY "Domingo"
#define L_MONDAY "Lunes"
#define L_TUESDAY "Martes"
#if ISOLATIN1
#define L_WEDNESDAY "Mi\351rcoles"
#else
#define L_WEDNESDAY "Miercoles"
#endif
#define L_WEDNESDAY "Miércoles"
#define L_THURSDAY "Jueves"
#define L_FRIDAY "Viernes"
#if ISOLATIN1
#define L_SATURDAY "S\341bado"
#else
#define L_SATURDAY "Sabado"
#endif
#define L_SATURDAY "Sábado"
/* Nombres de los meses */
#define L_JAN "Enero"
@@ -47,11 +38,7 @@
/* Hoy y man~ana */
#define L_TODAY "hoy"
#if ISOLATIN1
#define L_TOMORROW "ma\361ana"
#else
#define L_TOMORROW "manana"
#endif
#define L_TOMORROW "mañana"
/* El titular habitual */
#define L_BANNER "Agenda para el %w, %d%s %m, %y%o:"
@@ -68,13 +55,8 @@
#define L_FROMNOW "desde hoy"
/* "dentro de %d di'as" */
#if ISOLATIN1
#define L_INXDAYS "dentro de %d d\355as"
#define L_ON "el d\355a"
#else
#define L_INXDAYS "dentro de %d di'as"
#define L_ON "el di'a"
#endif
#define L_INXDAYS "dentro de %d días"
#define L_ON "el día"
/* "el di'a..." */

View File

@@ -44,10 +44,6 @@
static void DoReminders(void);
/* Whooo... the putchar/Putchar/PutChar macros are a mess...
my apologies... */
#define Putchar(c) PutChar(c)
/***************************************************************/
/***************************************************************/
/** **/
@@ -616,11 +612,11 @@ void OutputLine(FILE *fp)
char c = 0;
while (*s) {
if (*s == '\n') Putc('\\', fp);
Putc(*s, fp);
if (*s == '\n') putc('\\', fp);
putc(*s, fp);
c = *s++;
}
if (c != '\n') Putc('\n', fp);
if (c != '\n') putc('\n', fp);
}
/***************************************************************/
@@ -1212,7 +1208,7 @@ void FillParagraph(char const *s)
/* If it's a carriage return, output it and start new paragraph */
if (*s == '\n') {
Putchar('\n');
putchar('\n');
s++;
line = 0;
while(ISBLANK(*s)) s++;
@@ -1225,7 +1221,7 @@ void FillParagraph(char const *s)
number of spaces */
j = line ? SubsIndent : FirstIndent;
for (i=0; i<j; i++) {
Putchar(' ');
putchar(' ');
}
/* Calculate the amount of room left on this line */
@@ -1244,17 +1240,17 @@ void FillParagraph(char const *s)
}
if (!pendspace || len+pendspace <= roomleft) {
for (i=0; i<pendspace; i++) {
Putchar(' ');
putchar(' ');
}
while(t < s) {
Putchar(*t);
putchar(*t);
if (strchr(EndSent, *t)) doublespace = 2;
else if (!strchr(EndSentIg, *t)) doublespace = 1;
t++;
}
} else {
s = t;
Putchar('\n');
putchar('\n');
line++;
break;
}
@@ -1415,3 +1411,23 @@ System(char const *cmd)
r = 1;
}
}
char const *
get_day_name(int wkday)
{
if (wkday < 0 || wkday > 6) {
return "INVALID_WKDAY";
}
if (DynamicDayName[wkday]) return DynamicDayName[wkday];
return DayName[wkday];
}
char const *
get_month_name(int mon)
{
if (mon < 0 || mon > 11) {
return "INVALID_MON";
}
if (DynamicMonthName[mon]) return DynamicMonthName[mon];
return MonthName[mon];
}

View File

@@ -166,3 +166,6 @@ int ShellEscape(char const *in, DynamicBuffer *out);
int AddGlobalOmit(int jul);
void set_lat_and_long_from_components(void);
void set_components_from_lat_and_long(void);
char const *get_day_name(int wkday);
char const *get_month_name(int mon);

View File

@@ -146,9 +146,9 @@ put_escaped_string(char const *s)
{
while(*s) {
if (*s == '\\' || *s == '(' || *s == ')') {
PutChar('\\');
putchar('\\');
}
PutChar(*s);
putchar(*s);
s++;
}
}
@@ -383,6 +383,7 @@ void DoPsCal(void)
int firstcol;
DynamicBuffer buf;
CalEntry *c, *d, *p;
char *s;
/* Read the month and year name, followed by # days in month and 1st day of
month */
@@ -391,12 +392,28 @@ void DoPsCal(void)
sscanf(DBufValue(&buf), "%s %s %d %d %d", month, year, &days, &wkday,
&MondayFirst);
/* Replace underscores in month name with spaces */
s = month;
while(*s) {
if (*s == '_') *s = ' ';
s++;
}
/* Get day names */
DBufGets(&buf, stdin);
sscanf(DBufValue(&buf), "%32s %32s %32s %32s %32s %32s %32s",
DayName[0], DayName[1], DayName[2], DayName[3],
DayName[4], DayName[5], DayName[6]);
/* Replace underscores in day names with spaces */
for (i=0; i<7; i++) {
s = DayName[i];
while(*s) {
if (*s == '_') *s = ' ';
s++;
}
}
/* We write the prolog here because it's only at this point that
MondayFirst is set correctly. */
if (validfile == 1) {
@@ -407,6 +424,19 @@ void DoPsCal(void)
sscanf(DBufValue(&buf), "%s %d", prevm, &prevdays);
DBufGets(&buf, stdin);
sscanf(DBufValue(&buf), "%s %d", nextm, &nextdays);
/* Replace underscores with spaces in names of next/prev month */
s = prevm;
while(*s) {
if (*s == '_') *s = ' ';
s++;
}
s = nextm;
while(*s) {
if (*s == '_') *s = ' ';
s++;
}
DBufFree(&buf);
MaxDay = days;
FirstWkDay = wkday;
@@ -595,7 +625,7 @@ void WriteProlog(void)
strcmp(SmallFont, DayFont) &&
strcmp(TitleFont, SmallFont) &&
strcmp(SmallFont, EntryFont)) printf(" %s", SmallFont);
PutChar('\n');
putchar('\n');
printf("%%%%Creator: Rem2PS\n");
printf("%%%%Pages: (atend)\n");
printf("%%%%Orientation: %s\n", PortraitMode ? "Portrait" : "Landscape");
@@ -775,20 +805,20 @@ void WriteOneEntry(CalEntry *c)
}
}
PutChar('(');
putchar('(');
while(*s) {
/* Use the "unsigned char" cast to fix problem on Solaris 2.5 */
/* which treated some latin1 characters as white space. */
ch = (unsigned char) *s++;
if (ch == '\\' || ch == '(' || ch == ')') PutChar('\\');
if (!isspace(ch)) PutChar(ch);
if (ch == '\\' || ch == '(' || ch == ')') putchar('\\');
if (!isspace(ch)) putchar(ch);
else {
PutChar(')');
putchar(')');
while(isspace((unsigned char)*s)) s++;
if (!*s) {
goto finish;
}
PutChar('(');
putchar('(');
}
}
printf(")\n");

View File

@@ -5,7 +5,8 @@
ALL=`grep ^#define lang.h | grep -v '#define LANG' | awk '{print $2}'`
for i in $ALL ; do
make clean all LANGDEF=-DLANG=$i || exit 1
make clean
make -j`nproc` all LANGDEF=-DLANG=$i || exit 1
./remind -q -r ../tests/tstlang.rem
done
exit 0

View File

@@ -43,30 +43,36 @@ Token TokArray[] = {
{ "at", 2, T_At, 0 },
{ "august", 3, T_Month, 7 },
{ "banner", 3, T_Banner, 0 },
{ "before", 3, T_Skip, BEFORE_SKIP },
{ "before", 3, T_Skip, BEFORE_SKIP },
{ "cal", 3, T_RemType, CAL_TYPE },
{ "clear-omit-context", 5, T_Clr, 0 },
{ "debug", 5, T_Debug, 0 },
{ "debug", 5, T_Debug, 0 },
{ "december", 3, T_Month, 11 },
{ "do", 2, T_IncludeR, 0 },
{ "dumpvars", 4, T_Dumpvars, 0 },
{ "dumpvars", 4, T_Dumpvars, 0 },
{ "duration", 3, T_Duration, 0 },
{ "else", 4, T_Else, 0 },
{ "else", 4, T_Else, 0 },
{ "endif", 5, T_EndIf, 0 },
{ "errmsg", 6, T_ErrMsg, 0 },
{ "errmsg", 6, T_ErrMsg, 0 },
{ "exit", 4, T_Exit, 0 },
{ "february", 3, T_Month, 1 },
{ "first", 5, T_Ordinal, 0 },
{ "flush", 5, T_Flush, 0 },
{ "fourth", 6, T_Ordinal, 3 },
{ "friday", 3, T_WkDay, 4 },
{ "from", 4, T_Scanfrom, FROM_TYPE },
{ "fset", 4, T_Fset, 0 },
{ "if", 2, T_If, 0 },
{ "iftrig", 6, T_IfTrig, 0 },
{ "in", 2, T_In, 0 },
{ "include", 3, T_Include, 0 },
{ "includecmd", 10, T_IncludeCmd, 0 },
{ "january", 3, T_Month, 0 },
{ "july", 3, T_Month, 6 },
{ "june", 3, T_Month, 5 },
{ "last", 4, T_Ordinal, -1 },
{ "lastday", 7, T_BackAdj, -1 },
{ "lastworkday", 11, T_BackAdj, 1 },
{ "march", 3, T_Month, 2 },
{ "may", 3, T_Month, 4 },
{ "maybe-uncomputable", 5, T_MaybeUncomputable, 0},
@@ -90,12 +96,14 @@ Token TokArray[] = {
{ "saturday", 3, T_WkDay, 5 },
{ "scanfrom", 4, T_Scanfrom, SCANFROM_TYPE },
{ "sched", 5, T_Sched, 0 },
{ "second", 6, T_Ordinal, 1 },
{ "september", 3, T_Month, 8 },
{ "set", 3, T_Set, 0 },
{ "skip", 3, T_Skip, SKIP_SKIP },
{ "special", 7, T_RemType, PASSTHRU_TYPE },
{ "sunday", 3, T_WkDay, 6 },
{ "tag", 3, T_Tag, 0 },
{ "third", 5, T_Ordinal, 2 },
{ "through", 7, T_Through, 0 },
{ "thursday", 3, T_WkDay, 3 },
{ "tuesday", 3, T_WkDay, 1 },
@@ -105,33 +113,6 @@ Token TokArray[] = {
{ "wednesday", 3, T_WkDay, 2 }
};
/* If language != English, we must also search the following... */
#if LANG != ENGLISH
Token NonEnglishToks[] = {
/* NAME MINLEN TYPE VALUE */
{ L_MONDAY, 3, T_WkDay, 0 },
{ L_TUESDAY, 3, T_WkDay, 1 },
{ L_WEDNESDAY, 3, T_WkDay, 2 },
{ L_THURSDAY, 3, T_WkDay, 3 },
{ L_FRIDAY, 3, T_WkDay, 4 },
{ L_SATURDAY, 3, T_WkDay, 5 },
{ L_SUNDAY, 3, T_WkDay, 6 },
{ L_JAN, 3, T_Month, 0 },
{ L_FEB, 3, T_Month, 1 },
{ L_MAR, 3, T_Month, 2 },
{ L_APR, 3, T_Month, 3 },
{ L_MAY, 3, T_Month, 4 },
{ L_JUN, 3, T_Month, 5 },
{ L_JUL, 3, T_Month, 6 },
{ L_AUG, 3, T_Month, 7 },
{ L_SEP, 3, T_Month, 8 },
{ L_OCT, 3, T_Month, 9 },
{ L_NOV, 3, T_Month, 10 },
{ L_DEC, 3, T_Month, 11 }
};
#endif
static int TokStrCmp (Token const *t, char const *s);
/***************************************************************/
@@ -232,19 +213,6 @@ void FindToken(char const *s, Token *tok)
if (r > 0) top = mid-1; else bot=mid+1;
}
/* If language is other than English, search the DayNames[] and MonthNames[]
array. */
#if LANG != ENGLISH
for (i=0; i<(sizeof(NonEnglishToks) / sizeof(Token)); i++) {
if (l >= NonEnglishToks[i].MinLen &&
!TokStrCmp(&NonEnglishToks[i], s)) {
tok->type = NonEnglishToks[i].type;
tok->val = NonEnglishToks[i].val;
return;
}
}
#endif
return;
}
@@ -365,6 +333,14 @@ void FindNumericToken(char const *s, Token *t)
t->type = T_Back;
t->val *= mult;
return;
} else if (*s == '~') {
s++;
if (*s == '~') { mult = -1; s++; }
PARSENUM(t->val, s);
if (*s) return; /* Illegal token if followed by non-numeric char */
t->type = T_BackAdj;
t->val *= mult;
return;
}
return; /* Unknown token type */
}

View File

@@ -442,9 +442,9 @@ AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int sav
FromJulian(r, &y, &m, &d);
fprintf(ErrFp, "%s(%d): Trig(adj) = %s, %d %s, %d",
FileName, LineNo,
DayName[r % 7],
get_day_name(r % 7),
d,
MonthName[m],
get_month_name(m),
y);
if (tim->ttime != NO_TIME) {
fprintf(ErrFp, " AT %02d:%02d",
@@ -593,9 +593,9 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
FromJulian(result, &y, &m, &d);
fprintf(ErrFp, "%s(%d): Trig = %s, %d %s, %d",
FileName, LineNo,
DayName[result % 7],
get_day_name(result % 7),
d,
MonthName[m],
get_month_name(m),
y);
if (tim->ttime != NO_TIME) {
fprintf(ErrFp, " AT %02d:%02d",

View File

@@ -69,6 +69,8 @@ typedef struct {
int once;
int scanfrom;
int from;
int adj_for_last; /* Adjust month/year for use of LAST */
int need_wkday; /* Set if we *need* a weekday */
int priority;
int duration_days; /* Duration converted to days to search */
int eventstart; /* Original event start (datetime) */
@@ -157,7 +159,8 @@ enum TokTypes
T_AddOmit,
T_WkDay,
T_Month, T_Time, T_Date, T_DateTime,
T_Skip, T_At, T_RemType, T_Until, T_Year, T_Day, T_Rep, T_Delta, T_Back,
T_Skip, T_At, T_RemType, T_Until, T_Year, T_Day, T_Rep, T_Delta,
T_Back, T_BackAdj,
T_Once,
T_Empty,
T_Comment,
@@ -175,7 +178,10 @@ enum TokTypes
T_LongTime,
T_OmitFunc,
T_Through,
T_MaybeUncomputable
T_MaybeUncomputable,
T_Ordinal,
T_In,
T_LastBack
};
/* The structure of a token */

173
src/var.c
View File

@@ -728,6 +728,7 @@ typedef struct {
void *value;
int min;
int max;
int (*validate)(void const *newvalue);
} SysVar;
/* If the type of a sys variable is STR_TYPE, then min is redefined
@@ -739,64 +740,83 @@ typedef struct {
/* All of the system variables sorted alphabetically */
static SysVar SysVarArr[] = {
/* name mod type value min/mal max */
{"CalcUTC", 1, INT_TYPE, &CalculateUTC, 0, 1 },
{"CalMode", 0, INT_TYPE, &DoCalendar, 0, 0 },
{"Daemon", 0, INT_TYPE, &Daemon, 0, 0 },
{"DateSep", 1, SPECIAL_TYPE, date_sep_func, 0, 0 },
{"DateTimeSep", 1, SPECIAL_TYPE, datetime_sep_func, 0, 0 },
{"DefaultColor", 1, SPECIAL_TYPE, default_color_func, 0, 0 },
{"DefaultPrio", 1, INT_TYPE, &DefaultPrio, 0, 9999},
{"DefaultTDelta", 1, INT_TYPE, &DefaultTDelta, 0, 1440},
{"DeltaOffset", 0, INT_TYPE, &DeltaOffset, 0, 0 },
{"DontFork", 0, INT_TYPE, &DontFork, 0, 0 },
{"DontQueue", 0, INT_TYPE, &DontQueue, 0, 0 },
{"DontTrigAts", 0, INT_TYPE, &DontIssueAts, 0, 0 },
{"EndSent", 1, STR_TYPE, &EndSent, 0, 0 },
{"EndSentIg", 1, STR_TYPE, &EndSentIg, 0, 0 },
{"FirstIndent", 1, INT_TYPE, &FirstIndent, 0, 132 },
{"FoldYear", 1, INT_TYPE, &FoldYear, 0, 1 },
{"FormWidth", 1, INT_TYPE, &FormWidth, 20, 500 },
{"HushMode", 0, INT_TYPE, &Hush, 0, 0 },
{"IgnoreOnce", 0, INT_TYPE, &IgnoreOnce, 0, 0 },
{"InfDelta", 0, INT_TYPE, &InfiniteDelta, 0, 0 },
{"IntMax", 0, INT_TYPE, &IntMax, 0, 0 },
{"IntMin", 0, INT_TYPE, &IntMin, 0, 0 },
{"LatDeg", 1, SPECIAL_TYPE, latdeg_func, 0, 0 },
{"Latitude", 1, SPECIAL_TYPE, latitude_func, 0, 0 },
{"LatMin", 1, SPECIAL_TYPE, latmin_func, 0, 0 },
{"LatSec", 1, SPECIAL_TYPE, latsec_func, 0, 0 },
{"Location", 1, STR_TYPE, &Location, 0, 0 },
{"LongDeg", 1, SPECIAL_TYPE, longdeg_func, 0, 0 },
{"Longitude", 1, SPECIAL_TYPE, longitude_func, 0, 0 },
{"LongMin", 1, SPECIAL_TYPE, longmin_func, 0, 0 },
{"LongSec", 1, SPECIAL_TYPE, longsec_func, 0, 0 },
{"MaxSatIter", 1, INT_TYPE, &MaxSatIter, 10, ANY },
{"MaxStringLen", 1, INT_TYPE, &MaxStringLen, -1, ANY },
{"MinsFromUTC", 1, INT_TYPE, &MinsFromUTC, -780, 780 },
{"NextMode", 0, INT_TYPE, &NextMode, 0, 0 },
{"NumQueued", 0, INT_TYPE, &NumQueued, 0, 0 },
{"NumTrig", 0, INT_TYPE, &NumTriggered, 0, 0 },
{"PrefixLineNo", 0, INT_TYPE, &DoPrefixLineNo, 0, 0 },
{"PSCal", 0, INT_TYPE, &PsCal, 0, 0 },
{"RunOff", 0, INT_TYPE, &RunDisabled, 0, 0 },
{"SimpleCal", 0, INT_TYPE, &DoSimpleCalendar, 0, 0 },
{"SortByDate", 0, INT_TYPE, &SortByDate, 0, 0 },
{"SortByPrio", 0, INT_TYPE, &SortByPrio, 0, 0 },
{"SortByTime", 0, INT_TYPE, &SortByTime, 0, 0 },
{"SubsIndent", 1, INT_TYPE, &SubsIndent, 0, 132 },
{"T", 0, SPECIAL_TYPE, trig_date_func, 0, 0 },
{"Td", 0, SPECIAL_TYPE, trig_day_func, 0, 0 },
{"TimeSep", 1, SPECIAL_TYPE, time_sep_func, 0, 0 },
{"Tm", 0, SPECIAL_TYPE, trig_mon_func, 0, 0 },
{"Tw", 0, SPECIAL_TYPE, trig_wday_func, 0, 0 },
{"Ty", 0, SPECIAL_TYPE, trig_year_func, 0, 0 },
{"U", 0, SPECIAL_TYPE, today_date_func, 0, 0 },
{"Ud", 0, SPECIAL_TYPE, today_day_func, 0, 0 },
{"Um", 0, SPECIAL_TYPE, today_mon_func, 0, 0 },
{"UntimedFirst", 0, INT_TYPE, &UntimedBeforeTimed, 0, 0 },
{"Uw", 0, SPECIAL_TYPE, today_wday_func, 0, 0 },
{"Uy", 0, SPECIAL_TYPE, today_year_func, 0, 0 }
/* name mod type value min/mal max validate*/
{"April", 1, STR_TYPE, &DynamicMonthName[3], 0, 0, NULL },
{"August", 1, STR_TYPE, &DynamicMonthName[7], 0, 0, NULL },
{"CalcUTC", 1, INT_TYPE, &CalculateUTC, 0, 1, NULL },
{"CalMode", 0, INT_TYPE, &DoCalendar, 0, 0, NULL },
{"Daemon", 0, INT_TYPE, &Daemon, 0, 0, NULL },
{"DateSep", 1, SPECIAL_TYPE, date_sep_func, 0, 0, NULL },
{"DateTimeSep", 1, SPECIAL_TYPE, datetime_sep_func, 0, 0, NULL },
{"December", 1, STR_TYPE, &DynamicMonthName[11],0, 0, NULL },
{"DefaultColor", 1, SPECIAL_TYPE, default_color_func, 0, 0, NULL },
{"DefaultPrio", 1, INT_TYPE, &DefaultPrio, 0, 9999, NULL },
{"DefaultTDelta", 1, INT_TYPE, &DefaultTDelta, 0, 1440, NULL },
{"DeltaOffset", 0, INT_TYPE, &DeltaOffset, 0, 0, NULL },
{"DontFork", 0, INT_TYPE, &DontFork, 0, 0, NULL },
{"DontQueue", 0, INT_TYPE, &DontQueue, 0, 0, NULL },
{"DontTrigAts", 0, INT_TYPE, &DontIssueAts, 0, 0, NULL },
{"EndSent", 1, STR_TYPE, &EndSent, 0, 0, NULL },
{"EndSentIg", 1, STR_TYPE, &EndSentIg, 0, 0, NULL },
{"February", 1, STR_TYPE, &DynamicMonthName[1], 0, 0, NULL },
{"FirstIndent", 1, INT_TYPE, &FirstIndent, 0, 132, NULL },
{"FoldYear", 1, INT_TYPE, &FoldYear, 0, 1, NULL },
{"FormWidth", 1, INT_TYPE, &FormWidth, 20, 500, NULL },
{"Friday", 1, STR_TYPE, &DynamicDayName[4], 0, 0, NULL },
{"HushMode", 0, INT_TYPE, &Hush, 0, 0, NULL },
{"IgnoreOnce", 0, INT_TYPE, &IgnoreOnce, 0, 0, NULL },
{"InfDelta", 0, INT_TYPE, &InfiniteDelta, 0, 0, NULL },
{"IntMax", 0, INT_TYPE, &IntMax, 0, 0, NULL },
{"IntMin", 0, INT_TYPE, &IntMin, 0, 0, NULL },
{"January", 1, STR_TYPE, &DynamicMonthName[0], 0, 0, NULL },
{"July", 1, STR_TYPE, &DynamicMonthName[6], 0, 0, NULL },
{"June", 1, STR_TYPE, &DynamicMonthName[5], 0, 0, NULL },
{"LatDeg", 1, SPECIAL_TYPE, latdeg_func, 0, 0, NULL },
{"Latitude", 1, SPECIAL_TYPE, latitude_func, 0, 0, NULL },
{"LatMin", 1, SPECIAL_TYPE, latmin_func, 0, 0, NULL },
{"LatSec", 1, SPECIAL_TYPE, latsec_func, 0, 0, NULL },
{"Location", 1, STR_TYPE, &Location, 0, 0, NULL },
{"LongDeg", 1, SPECIAL_TYPE, longdeg_func, 0, 0, NULL },
{"Longitude", 1, SPECIAL_TYPE, longitude_func, 0, 0, NULL },
{"LongMin", 1, SPECIAL_TYPE, longmin_func, 0, 0, NULL },
{"LongSec", 1, SPECIAL_TYPE, longsec_func, 0, 0, NULL },
{"March", 1, STR_TYPE, &DynamicMonthName[2], 0, 0, NULL },
{"MaxSatIter", 1, INT_TYPE, &MaxSatIter, 10, ANY, NULL },
{"MaxStringLen", 1, INT_TYPE, &MaxStringLen, -1, ANY, NULL },
{"May", 1, STR_TYPE, &DynamicMonthName[4], 0, 0, NULL },
{"MinsFromUTC", 1, INT_TYPE, &MinsFromUTC, -780, 780, NULL },
{"Monday", 1, STR_TYPE, &DynamicDayName[0], 0, 0, NULL },
{"NextMode", 0, INT_TYPE, &NextMode, 0, 0, NULL },
{"November", 1, STR_TYPE, &DynamicMonthName[10],0, 0, NULL },
{"NumQueued", 0, INT_TYPE, &NumQueued, 0, 0, NULL },
{"NumTrig", 0, INT_TYPE, &NumTriggered, 0, 0, NULL },
{"October", 1, STR_TYPE, &DynamicMonthName[9], 0, 0, NULL },
{"PrefixLineNo", 0, INT_TYPE, &DoPrefixLineNo, 0, 0, NULL },
{"PSCal", 0, INT_TYPE, &PsCal, 0, 0, NULL },
{"RunOff", 0, INT_TYPE, &RunDisabled, 0, 0, NULL },
{"Saturday", 1, STR_TYPE, &DynamicDayName[5], 0, 0, NULL },
{"September", 1, STR_TYPE, &DynamicMonthName[8], 0, 0, NULL },
{"SimpleCal", 0, INT_TYPE, &DoSimpleCalendar, 0, 0, NULL },
{"SortByDate", 0, INT_TYPE, &SortByDate, 0, 0, NULL },
{"SortByPrio", 0, INT_TYPE, &SortByPrio, 0, 0, NULL },
{"SortByTime", 0, INT_TYPE, &SortByTime, 0, 0, NULL },
{"SubsIndent", 1, INT_TYPE, &SubsIndent, 0, 132, NULL },
{"Sunday", 1, STR_TYPE, &DynamicDayName[6], 0, 0, NULL },
{"T", 0, SPECIAL_TYPE, trig_date_func, 0, 0, NULL },
{"Td", 0, SPECIAL_TYPE, trig_day_func, 0, 0, NULL },
{"Thursday", 1, STR_TYPE, &DynamicDayName[3], 0, 0, NULL },
{"TimeSep", 1, SPECIAL_TYPE, time_sep_func, 0, 0, NULL },
{"Tm", 0, SPECIAL_TYPE, trig_mon_func, 0, 0, NULL },
{"Tuesday", 1, STR_TYPE, &DynamicDayName[1], 0, 0, NULL },
{"Tw", 0, SPECIAL_TYPE, trig_wday_func, 0, 0, NULL },
{"Ty", 0, SPECIAL_TYPE, trig_year_func, 0, 0, NULL },
{"U", 0, SPECIAL_TYPE, today_date_func, 0, 0, NULL },
{"Ud", 0, SPECIAL_TYPE, today_day_func, 0, 0, NULL },
{"Um", 0, SPECIAL_TYPE, today_mon_func, 0, 0, NULL },
{"UntimedFirst", 0, INT_TYPE, &UntimedBeforeTimed, 0, 0, NULL },
{"Uw", 0, SPECIAL_TYPE, today_wday_func, 0, 0, NULL },
{"Uy", 0, SPECIAL_TYPE, today_year_func, 0, 0, NULL },
{"Wednesday", 1, STR_TYPE, &DynamicDayName[2], 0, 0, NULL }
};
#define NUMSYSVARS ( sizeof(SysVarArr) / sizeof(SysVar) )
@@ -826,7 +846,24 @@ int SetSysVar(char const *name, Value *value)
r = f(1, value);
DestroyValue(*value);
return r;
} else if (v->type == STR_TYPE) {
}
if (v->validate) {
if (v->type == STR_TYPE) {
r = (v->validate)((void *) value->v.str);
} else {
r = (v->validate)((void *) &(value->v.val));
}
if (r != OK) {
return r;
}
}
if (v->type == STR_TYPE) {
/* If it's already the same, don't bother doing anything */
if (!strcmp(value->v.str, (char const *) v->value)) {
DestroyValue(*value);
return OK;
}
/* If it's a string variable, special measures must be taken */
if (v->been_malloced) free(*((char **)(v->value)));
v->been_malloced = 1;
@@ -857,7 +894,11 @@ int GetSysVar(char const *name, Value *val)
SysVarFunc f = (SysVarFunc) v->value;
return f(0, val);
} else if (v->type == STR_TYPE) {
val->v.str = StrDup(*((char **) v->value));
if (! * (char **) v->value) {
val->v.str = StrDup("");
} else {
val->v.str = StrDup(*((char **) v->value));
}
if (!val->v.str) return E_NO_MEM;
} else {
val->v.val = *((int *) v->value);
@@ -948,29 +989,29 @@ static void DumpSysVar(char const *name, const SysVar *v)
SysVarFunc f = (SysVarFunc) v->value;
f(0, &val);
PrintValue(&val, ErrFp);
Putc('\n', ErrFp);
putc('\n', ErrFp);
DestroyValue(val);
} else if (v->type == STR_TYPE) {
char const *s = *((char **)v->value);
int y;
Putc('"', ErrFp);
putc('"', ErrFp);
for (y=0; y<MAX_PRT_LEN && *s; y++) {
if (*s == '"') {
fprintf(ErrFp, "\" + char(34) + \"");
s++;
} else {
Putc(*s++, ErrFp);
putc(*s++, ErrFp);
}
}
Putc('"', ErrFp);
putc('"', ErrFp);
if (*s) fprintf(ErrFp, "...");
Putc('\n', ErrFp);
putc('\n', ErrFp);
} else if (v->type == DATE_TYPE) {
Value val;
val.type = DATE_TYPE;
val.v.val = * (int *) v->value;
PrintValue(&val, ErrFp);
Putc('\n', ErrFp);
putc('\n', ErrFp);
} else {
if (!v->modifiable) fprintf(ErrFp, "%d\n", *((int *)v->value));
else {

70
tests/scripts.rem Normal file
View File

@@ -0,0 +1,70 @@
# This is a test file that tests the
# rendering of various Unicode characters.
# It also tests some of the features of
# the Pango/Cairo-based rem2pdf program.
SET $Sunday "እሁድ"
SET $Monday "一"
SET $Tuesday "mardi"
SET $Wednesday "水曜日"
SET $Thursday "четвер"
SET $Friday "piątek"
SET $Saturday "יום שבת"
SET $January "January"
SET $February "février"
SET $March "März"
SET $April "אַפּרִיל"
SET $May "ግንቦት"
SET $June "Чэрвень"
SET $July "تموز"
SET $August "Наймдугаар сар"
SET $September "Вересень"
SET $October "październik"
SET $November "נאוועמבער"
SET $December "दिसंबर"
REM 1 MSG Përkujtues
REM 2 SPECIAL SHADE 192 192 255
REM 2 MSG تذكير
REM 3 MSG 提醒
REM 4 MSG રીમાઇન્ડર
REM 5 MSG Emlékeztető
REM 6 MSG Áminning
REM 7 SPECIAL PANGO <u>תִזכּוֹרֶת</u>
REM 8 MSG अनुस्मारक
REM 9 SPECIAL COLOR 0 0 192 Эскертүү
REM 10 SPECIAL COLOR 0 192 0 Напоминание
REM 11 SPECIAL COLOR 192 0 0 Υπενθύμιση
REM 12 SPECIAL PANGO <b>Bold</b> <small>and</small> <i>Italic</i> <big>and</big> <span bgcolor="#C0C0C0" foreground="red"><u>underline</u></span>
REM 12 MSG Hello
REM 28 SPECIAL PANGO <span face="zapf chancery" size="10000">Very Fancy</span>
REM 13 SPECIAL PANGO <bad>Invalid
REM 13 MSG Hello Again
REM 15 SPECIAL PANGO @1,-1 <small><small>[hebday($U)] [hebmon($U)] Rise [sunrise($U)] Set [sunset($U)]</small></small>
REM 16 MSG یادآور
REM 17 MSG Lời nhắc nhở
REM 18 MSG Påminnelse
REM 19 MSG דערמאָנונג
REM 20 MSG Hatırlatma
REM 21 SPECIAL PANGO <big><big> Нагадування</big></big>
REM 22 MSG შეხსენება
REM 23 MSG เตือนความจำ
REM 24 MSG リマインダー
REM 25 MSG Искә төшерү
REM 26 MSG Напомняне
REM 27 MSG ഓർമ്മപ്പെടുത്തൽ
REM 1 SPECIAL SHADE 192 255 192
REM 14 SPECIAL SHADE 255 192 192
REM 14 SPECIAL PANGO <span face="Zapf Chancery" size="15000">This is so <span foreground="blue">fancy</span></span>
REM [moondate(0)] SPECIAL MOON 0
REM [moondate(1)] SPECIAL MOON 1
REM [moondate(2)] SPECIAL MOON 2 -1 -1 [moontime(2)]
REM [moondate(3)] SPECIAL MOON 3 -1 -1 [moontime(3)]
REM Mon SPECIAL WEEK (W[weekno(today())])
REM SATISFY [$Td != 15] SPECIAL PANGO @1,-1 <span size="4800"><i>Rise [sunrise($U)] Set [sunset($U)]</i></span>

File diff suppressed because it is too large Load Diff

View File

@@ -447,6 +447,99 @@ REM MAYBE-UNCOMPUTABLE Mon SATISFY [wkdaynum($T) == 3] MSG Nope nope...
dump
dump $
msg [$April]%
msg [$August]%
msg [$CalcUTC]%
msg [$CalMode]%
msg [$Daemon]%
msg [$DateSep]%
msg [$DateTimeSep]%
msg [$December]%
msg [$DefaultColor]%
msg [$DefaultPrio]%
msg [$DefaultTDelta]%
msg [$DeltaOffset]%
msg [$DontFork]%
msg [$DontQueue]%
msg [$DontTrigAts]%
msg [$EndSent]%
msg [$EndSentIg]%
msg [$February]%
msg [$FirstIndent]%
msg [$FoldYear]%
msg [$FormWidth]%
msg [$Friday]%
msg [$HushMode]%
msg [$IgnoreOnce]%
msg [$InfDelta]%
msg [$IntMax]%
msg [$IntMin]%
msg [$January]%
msg [$July]%
msg [$June]%
msg [$LatDeg]%
msg [$Latitude]%
msg [$LatMin]%
msg [$LatSec]%
msg [$Location]%
msg [$LongDeg]%
msg [$Longitude]%
msg [$LongMin]%
msg [$LongSec]%
msg [$March]%
msg [$MaxSatIter]%
msg [$MaxStringLen]%
msg [$May]%
msg [$MinsFromUTC]%
msg [$Monday]%
msg [$NextMode]%
msg [$November]%
msg [$NumQueued]%
msg [$NumTrig]%
msg [$October]%
msg [$PrefixLineNo]%
msg [$PSCal]%
msg [$RunOff]%
msg [$Saturday]%
msg [$September]%
msg [$SimpleCal]%
msg [$SortByDate]%
msg [$SortByPrio]%
msg [$SortByTime]%
msg [$SubsIndent]%
msg [$Sunday]%
msg [$T]%
msg [$Td]%
msg [$Thursday]%
msg [$TimeSep]%
msg [$Tm]%
msg [$Tuesday]%
msg [$Tw]%
msg [$Ty]%
msg [$U]%
msg [$Ud]%
msg [$Um]%
msg [$UntimedFirst]%
msg [$Uw]%
msg [$Uy]%
msg [$Wednesday]%
# Diagnose until before start date, only for non-constant expressions and
# fully-specified start date
REM Mon 1992 UNTIL 1991-01-01 MSG Not diagnosed - not fully-specified start
REM 1992-01-01 *1 UNTIL 1991-12-31 MSG Diagnosed
set x '1992-01-01'
REM [x] *1 UNTIL 1991-12-31 MSG Not diagnosed - nonconst expression
REM MON FROM 1992-01-01 UNTIL 1991-12-31 Diagnosed
REM MON SCANFROM 1992-01-01 UNTIL 1991-12-31 Diagnosed
REM MON FROM [x] UNTIL 1991-12-31 Not diagnosed
REM MON SCANFROM [x] UNTIL 1991-12-31 Not diagnosed
REM 1992-01-01 UNTIL 1992-02-02 MSG Diagnosed
REM [x] UNTIL 1992-02-02 MSG Diagnosed
dump $aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
OMIT 2010-09-03 THROUGH 2010-09-15
OMIT December 25 MSG X
@@ -637,6 +730,66 @@ msg [a]
set x psshade(50)
set x psmoon(0)
# Trig
IF trig("sun +1") || trig("thu +1")
REM [trig()] +1 MSG Foo %b
ENDIF
# Trig with a bad warnfunc
FSET w(x) x/0
IF trig("sun warn w") || trig("thu warn w")
REM [trig()] +1 MSG Foo %b
ENDIF
# Trig with a good warnfunc
FSET w(x) choose(x, 5, 3, 1, 0)
# Ugh. This is where short-circuit logical operators
# would really come in handy.
IF trig("sun warn w") || trig("thu warn w")
REM [trig()] +5 MSG Foo %b
ENDIF
REM [trig("Mon", "Tue", "Wed", "Sat")] MSG foo
REM [trig("Mon", "Tue", "Wed")] MSG bar
# The new syntactic sugar
REM First Monday January MSG x
REM Second Tuesday in April MSG x
REM Third Wednesday in October MSG x
REM Fourth Friday in July MSG x
REM Last Tuesday in August MSG x
REM Last Sunday in December MSG x
REM First Monday January 2000 MSG x
REM Second Tuesday in April 2000 MSG x
REM Third Wednesday in October 2000 MSG x
REM Fourth Friday in July 2000 MSG x
REM Last Tuesday in August 2000 MSG x
REM Last Sunday in December 2000 MSG x
REM January ~~1 MSG y
REM February ~~1 MSG y
REM February ~~2 MSG y
REM February ~~3 MSG y
REM February ~~8 MSG y
REM February ~~20 MSG y
PUSH
OMIT 31 March
REM March ~1 MSG y
REM March ~~1 MSG y
REM Lastday March MSG y
REM Lastworkday March MSG y
POP
REM Dec 2000 ~~1 MSG y
REM Dec 2000 ~~2 MSG y
REM Dec 2000 ~~3 MSG y
REM Dec 2000 ~~7 MSG y
REM Jan 2001 ~~1 MSG y
REM Lastday April 2022 OMIT SAT SUN MSG foo
REM Lastworkday April 2022 OMIT SAT SUN MSG foo
# Don't want Remind to queue reminders
EXIT