1 ;;; cal-tex.el --- calendar functions for printing calendars with LaTeX
3 ;; Copyright (C) 1995, 2001-2012 Free Software Foundation, Inc.
5 ;; Author: Steve Fisk <fisk@bowdoin.edu>
6 ;; Edward M. Reingold <reingold@cs.uiuc.edu>
7 ;; Maintainer: Glenn Morris <rgm@gnu.org>
9 ;; Human-Keywords: Calendar, LaTeX
12 ;; This file is part of GNU Emacs.
14 ;; GNU Emacs is free software: you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation, either version 3 of the License, or
17 ;; (at your option) any later version.
19 ;; GNU Emacs is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ;; GNU General Public License for more details.
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
29 ;; This collection of functions implements the creation of LaTeX calendars
30 ;; based on the user's holiday choices and diary file.
32 ;; The user commands are:
33 ;; cal-tex-cursor-year
34 ;; cal-tex-cursor-year-landscape
35 ;; cal-tex-cursor-filofax-year
36 ;; cal-tex-cursor-month-landscape
37 ;; cal-tex-cursor-month
38 ;; cal-tex-cursor-week
39 ;; cal-tex-cursor-week2
40 ;; cal-tex-cursor-week-iso
41 ;; cal-tex-cursor-week-monday
42 ;; cal-tex-cursor-filofax-2week
43 ;; cal-tex-cursor-filofax-week
44 ;; cal-tex-cursor-filofax-daily
49 ;; (*) Add holidays and diary entries to daily calendar.
51 ;; (*) Add diary entries to weekly calendar functions.
53 ;; (*) Make calendar styles for A4 paper.
55 ;; (*) Make monthly styles Filofax paper.
62 ;;; Customizable variables
65 (defgroup calendar-tex nil
66 "Options for printing calendar with LaTeX."
70 (defcustom cal-tex-which-days '(0 1 2 3 4 5 6)
71 "The days of the week that are displayed on the portrait monthly calendar.
72 Sunday is 0, Monday is 1, and so on. The default is to print from Sunday to
73 Saturday. For example, use '(1 3 5) to only print Monday, Wednesday, Friday."
74 :type '(repeat integer)
77 (defcustom cal-tex-holidays t
78 "Non-nil means holidays are printed in the LaTeX calendars that support it.
79 Setting this to nil may speed up calendar generation."
83 (defcustom cal-tex-diary nil
84 "Non-nil means diary entries are printed in LaTeX calendars that support it.
85 At present, this only affects the monthly, filofax, and iso-week
86 calendars (i.e. not the yearly, plain weekly, or daily calendars).
87 Setting this to nil may speed up calendar generation."
91 (defcustom cal-tex-rules nil
92 "Non-nil means pages will be ruled in some LaTeX calendar styles.
93 At present, this only affects the daily filofax calendar."
97 (defcustom cal-tex-daily-string
98 '(let* ((year (calendar-extract-year date))
99 (day (calendar-day-number date))
100 (days-remaining (- (calendar-day-number (list 12 31 year)) day)))
101 (format "%d/%d" day days-remaining))
102 "Lisp expression giving the date format to use in the LaTeX calendars.
103 This should be an expression involving the variable `date'. When
104 this expression is called, `date' is a list of the form '(MONTH DAY YEAR)'.
106 The string resulting from evaluating this expression is placed at
107 the bottom center of each date in monthly calendars, next to the
108 date in the weekly calendars, and in the top center of daily calendars.
110 The default is ordinal day number of the year and the number of
111 days remaining. As an example, setting this to
113 '(calendar-hebrew-date-string date)
115 will put the Hebrew date at the bottom of each day."
117 :group 'calendar-tex)
119 (defcustom cal-tex-buffer "calendar.tex"
120 "The name for the output LaTeX calendar buffer."
122 :group 'calendar-tex)
124 (defcustom cal-tex-24 nil
125 "Non-nil means use a 24 hour clock in the daily calendar."
127 :group 'calendar-tex)
129 (defcustom cal-tex-daily-start 8
130 "The first hour of the daily LaTeX calendar page.
131 At present, this only affects `cal-tex-cursor-day'."
133 :group 'calendar-tex)
135 (defcustom cal-tex-daily-end 20
136 "The last hour of the daily LaTeX calendar page.
137 At present, this only affects `cal-tex-cursor-day'."
139 :group 'calendar-tex)
141 (defcustom cal-tex-preamble-extra nil
142 "A string giving extra LaTeX commands to insert in the calendar preamble.
143 For example, to include extra packages:
144 \"\\\\usepackage{foo}\\n\\\\usepackage{bar}\\n\"."
145 :type '(choice (const nil)
146 ;; An example to help people format things in custom.
147 (string :value "\\usepackage{foo}\n\\usepackage{bar}\n"))
151 (defcustom cal-tex-hook nil
152 "List of functions called after any LaTeX calendar buffer is generated.
153 You can use this to do post-processing on the buffer. For example, to change
154 characters with diacritical marks to their LaTeX equivalents, use
155 (add-hook 'cal-tex-hook
156 (lambda () (iso-iso2tex (point-min) (point-max))))"
158 :group 'calendar-tex)
160 (defcustom cal-tex-year-hook nil
161 "List of functions called after a LaTeX year calendar buffer is generated."
163 :group 'calendar-tex)
165 (defcustom cal-tex-month-hook nil
166 "List of functions called after a LaTeX month calendar buffer is generated."
168 :group 'calendar-tex)
170 (defcustom cal-tex-week-hook nil
171 "List of functions called after a LaTeX week calendar buffer is generated."
173 :group 'calendar-tex)
175 (defcustom cal-tex-daily-hook nil
176 "List of functions called after a LaTeX daily calendar buffer is generated."
178 :group 'calendar-tex)
181 ;;; Definitions for LaTeX code
184 (defconst cal-tex-day-prefix "\\caldate{%s}{%s}"
185 "The initial LaTeX code for a day.
186 The holidays, diary entries, bottom string, and the text follow.")
188 (defconst cal-tex-day-name-format "\\myday{%s}%%"
189 "The format for LaTeX code for a day name.
190 The names are taken from `calendar-day-name-array'.")
192 (defconst cal-tex-cal-one-month
193 "\\def\\calmonth#1#2%
195 \\Huge\\bf\\uppercase{#1} #2 \\\\[1cm]%
200 "LaTeX code for the month header, for a single month calendar.")
202 (defconst cal-tex-cal-multi-month
203 "\\def\\calmonth#1#2#3#4%
205 \\Huge\\bf #1 #2---#3 #4\\\\[1cm]%
210 "LaTeX code for the month header, for a multi-month calendar.")
212 (defconst cal-tex-myday
213 "\\renewcommand{\\myday}[1]%
214 {\\makebox[\\cellwidth]{\\hfill\\large\\bf#1\\hfill}}
217 "LaTeX code for a day heading.")
219 (defconst cal-tex-caldate
221 \\long\\def\\caldate#1#2#3#4#5#6{%
222 \\fbox{\\hbox to\\cellwidth{%
223 \\vbox to\\cellheight{%
224 \\hbox to\\cellwidth{%
225 {\\hspace*{1mm}\\Large \\bf \\strut #2}\\hspace{.05\\cellwidth}%
226 \\raisebox{\\holidaymult\\cellheight}%
227 {\\parbox[t]{.75\\cellwidth}{\\tiny \\raggedright #4}}}
228 \\hbox to\\cellwidth{%
229 \\hspace*{1mm}\\parbox{.95\\cellwidth}{\\tiny \\raggedright #3}}
231 \\hbox to\\cellwidth{#6}%
233 \\hbox to\\cellwidth{\\hfill \\tiny #5 \\hfill}%
237 "LaTeX code to insert one box with date info in calendar.
238 This definition is the heart of the calendar!")
240 (defconst cal-tex-lefthead
241 "\\def\\lefthead#1{\\noindent {\\normalsize \\bf #1}\\hfill\\\\[-6pt]}\n"
242 "LaTeX code for left header.")
244 (defconst cal-tex-righthead
245 "\\def\\righthead#1{\\hfill {\\normalsize \\bf #1}\\\\[-6pt]}\n"
246 "LaTeX code for right header.")
248 (autoload 'holiday-in-range "holidays")
250 (define-obsolete-function-alias 'cal-tex-list-holidays 'holiday-in-range "24.3")
252 (autoload 'diary-list-entries "diary-lib")
254 (defun cal-tex-list-diary-entries (d1 d2)
255 "Generate a list of all diary-entries from absolute date D1 to D2."
256 (let (diary-list-include-blanks)
257 (diary-list-entries (calendar-gregorian-from-absolute d1)
260 (defun cal-tex-preamble (&optional args)
261 "Insert the LaTeX calendar preamble into `cal-tex-buffer'.
262 Preamble includes initial definitions for various LaTeX commands.
263 Optional string ARGS are included as options for the article document class."
264 (set-buffer (generate-new-buffer cal-tex-buffer))
265 (insert (format "\\documentclass%s{article}\n"
269 (if (stringp cal-tex-preamble-extra)
270 (insert cal-tex-preamble-extra "\n"))
271 ;; FIXME boxwidth and boxheight unused?
272 (insert "\\hbadness 20000
278 \\evensidemargin -2cm
283 \\newlength{\\cellwidth}
284 \\newlength{\\cellheight}
285 \\newlength{\\boxwidth}
286 \\newlength{\\boxheight}
287 \\newlength{\\cellsize}
288 \\newcommand{\\myday}[1]{}
289 \\newcommand{\\caldate}[6]{}
290 \\newcommand{\\nocaldate}[6]{}
291 \\newcommand{\\calsmall}[6]{}
300 (defun cal-tex-cursor-year (&optional n event)
301 "Make a buffer with LaTeX commands for the year cursor is on.
302 Optional prefix argument N specifies number of years.
303 Optional EVENT indicates a buffer position to use instead of point."
304 (interactive (list (prefix-numeric-value current-prefix-arg)
306 (cal-tex-year (calendar-extract-year (calendar-cursor-to-date t event))
310 (defun cal-tex-cursor-year-landscape (&optional n event)
311 "Make a buffer with LaTeX commands for the year cursor is on.
312 Optional prefix argument N specifies number of years.
313 Optional EVENT indicates a buffer position to use instead of point."
314 (interactive (list (prefix-numeric-value current-prefix-arg)
316 (cal-tex-year (calendar-extract-year (calendar-cursor-to-date t event))
319 (defun cal-tex-year (year n &optional landscape)
320 "Make a one page yearly calendar of YEAR; do this for N years.
321 There are four rows of three months each, unless optional
322 LANDSCAPE is non-nil, in which case the calendar is printed in
323 landscape mode with three rows of four months each."
324 (cal-tex-insert-preamble 1 landscape "12pt")
326 (cal-tex-vspace "-.6cm")
327 (cal-tex-vspace "-3.1cm"))
329 (insert "\\vfill%\n")
331 (cal-tex-Huge (number-to-string year))
333 (cal-tex-vspace "1cm")
335 (cal-tex-b-parbox "l" (if landscape "5.9in" "4.3in"))
340 (insert (cal-tex-mini-calendar (1+ i) year "month" "1.1in" "1in"))
342 (cal-tex-hspace "0.5in")
343 (if (zerop (mod (1+ i) (if landscape 4 3)))
344 (cal-tex-nl "0.5in")))
347 (insert "\\vfill%\n")
348 (setq year (1+ year))
350 (cal-tex-end-document)
352 (run-hooks 'cal-tex-year-hook))
353 (run-hooks 'cal-tex-hook))
356 (defun cal-tex-filofax-paper (&optional year)
357 "Insert some page size settings for filofax layouts."
358 (insert "\\textwidth 3.25in
360 \\headheight -0.875in
364 ;; Why is this one subtly different? Who knows...
365 (if year "\\oddsidemargin 1.675in
366 \\evensidemargin 1.675in
368 "\\oddsidemargin 1.75in
369 \\evensidemargin 1.5in
374 (defun cal-tex-leftday (height)
375 "Insert LaTeX code for leftday function."
376 (insert "\\long\\def\\leftday#1#2#3#4#5{%
377 \\rule{\\textwidth}{0.3pt}\\\\%
378 \\hbox to \\textwidth{%
379 \\vbox to " height "{%
381 \\hbox to \\textwidth{\\noindent {\\normalsize \\bf #2} \\small #1 \\hfill #5}%
382 \\hbox to \\textwidth{\\vbox {\\noindent \\footnotesize \\em #4}}%
383 \\hbox to \\textwidth{\\vbox to 0pt {\\noindent \\footnotesize #3}}}}\\\\}\n"))
385 (defun cal-tex-rightday (height &optional funcname)
386 "Insert LaTeX code for rightday function."
387 (insert "\\long\\def\\" (or funcname "rightday") "#1#2#3#4#5{%
388 \\rule{\\textwidth}{0.3pt}\\\\%
389 \\hbox to \\textwidth{%
390 \\vbox to " height "{%
392 \\hbox to \\textwidth{\\small #5 \\hfill #1 {\\normalsize \\bf #2}}%
393 \\hbox to \\textwidth{\\vbox {\\raggedleft \\footnotesize \\em #4}}%
394 \\hbox to \\textwidth{\\vbox to 0pt {\\noindent \\footnotesize #3}}}}\\\\}\n"))
396 (defun cal-tex-shortday (funcname)
397 "Insert LaTeX code for a short day function."
398 (insert "\\long\\def\\" funcname "#1#2#3{%
399 \\rule{\\textwidth}{0.3pt}\\\\%
400 \\hbox to \\textwidth{%
403 \\hbox to \\textwidth{\\hfill \\small #3 \\hfill}%
404 \\hbox to \\textwidth{\\vbox {\\"
405 (if (string-equal funcname "rightday") "raggedleft" "noindent")
407 \\hbox to \\textwidth{\\vbox {\\noindent \\footnotesize #1}}}}}\n"))
410 (defun cal-tex-cursor-filofax-year (&optional n event)
411 "Make a Filofax one page yearly calendar of year indicated by cursor.
412 Optional prefix argument N specifies number of years.
413 Optional EVENT indicates a buffer position to use instead of point."
414 (interactive (list (prefix-numeric-value current-prefix-arg)
417 (let ((year (calendar-extract-year (calendar-cursor-to-date t event))))
418 (cal-tex-preamble "twoside")
419 (cal-tex-filofax-paper 'year)
420 (cal-tex-cmd "\\fboxsep 0.5mm")
421 (cal-tex-cmd "\\pagestyle" "empty")
423 (cal-tex-vspace "0.25in")
425 (insert (format "\\hfil \\textbf{\\Large %s} \\hfil\\\\\n" year))
427 (cal-tex-b-parbox "l" "\\textwidth")
431 (let ((month-names; don't use default in case user changed it
432 ;; These are only used to define the command names, not
433 ;; the names of the months they insert.
434 ["January" "February" "March" "April" "May" "June"
435 "July" "August" "September" "October" "November" "December"]))
437 (insert (cal-tex-mini-calendar (1+ i) year (aref month-names i)
438 "1in" ".9in" "tiny" "0.6mm"))))
440 "\\noindent\\fbox{\\January}\\fbox{\\February}\\fbox{\\March}\\\\
441 \\noindent\\fbox{\\April}\\fbox{\\May}\\fbox{\\June}\\\\
442 \\noindent\\fbox{\\July}\\fbox{\\August}\\fbox{\\September}\\\\
443 \\noindent\\fbox{\\October}\\fbox{\\November}\\fbox{\\December}
447 (setq year (1+ year))
449 (cal-tex-end-document)
451 (cal-tex-vspace "0.25in"))
452 (run-hooks 'cal-tex-year-hook))
453 (run-hooks 'cal-tex-hook)))
456 ;;; Monthly calendars
460 (defun cal-tex-cursor-month-landscape (&optional n event)
461 "Make a LaTeX calendar buffer for the month the cursor is on.
462 Optional prefix argument N specifies number of months to be
463 produced (default 1). The output is in landscape format, one
464 month to a page. It shows holiday and diary entries if
465 `cal-tex-holidays' and `cal-tex-diary', respectively, are non-nil.
466 Optional EVENT indicates a buffer position to use instead of point."
467 (interactive (list (prefix-numeric-value current-prefix-arg)
470 (let* ((date (calendar-cursor-to-date t event))
471 (month (calendar-extract-month date))
472 (year (calendar-extract-year date))
475 (cal-tex-which-days '(0 1 2 3 4 5 6))
476 (d1 (calendar-absolute-from-gregorian (list month 1 year)))
478 (calendar-increment-month end-month end-year (1- n))
479 (calendar-absolute-from-gregorian
481 (calendar-last-day-of-month end-month end-year)
483 (diary-list (if cal-tex-diary (cal-tex-list-diary-entries d1 d2)))
484 (holidays (if cal-tex-holidays (holiday-in-range d1 d2)))
485 other-month other-year small-months-at-start)
486 (cal-tex-insert-preamble (cal-tex-number-weeks month year 1) t "12pt")
487 (cal-tex-cmd cal-tex-cal-one-month)
489 (setq other-month month
491 (calendar-increment-month other-month other-year -1)
492 (insert (cal-tex-mini-calendar other-month other-year "lastmonth"
493 "\\cellwidth" "\\cellheight"))
494 (calendar-increment-month other-month other-year 2)
495 (insert (cal-tex-mini-calendar other-month other-year "nextmonth"
496 "\\cellwidth" "\\cellheight"))
497 (cal-tex-insert-month-header 1 month year month year)
498 (cal-tex-insert-day-names)
500 (if (setq small-months-at-start
501 (< 1 (mod (- (calendar-day-of-week (list month 1 year))
502 calendar-week-start-day)
504 (insert "\\lastmonth\\nextmonth\\hspace*{-2\\cellwidth}"))
505 (cal-tex-insert-blank-days month year cal-tex-day-prefix)
506 (cal-tex-insert-days month year diary-list holidays
508 (cal-tex-insert-blank-days-at-end month year cal-tex-day-prefix)
509 (if (and (not small-months-at-start)
510 (< 1 (mod (- (1- calendar-week-start-day)
511 (calendar-day-of-week
513 (calendar-last-day-of-month month year)
516 (insert "\\vspace*{-\\cellwidth}\\hspace*{-2\\cellwidth}"
517 "\\lastmonth\\nextmonth%
520 (run-hooks 'cal-tex-month-hook)
522 (calendar-increment-month month year 1)
523 (cal-tex-vspace "-2cm")
524 (cal-tex-insert-preamble
525 (cal-tex-number-weeks month year 1) t "12pt" t))))
526 (cal-tex-end-document)
527 (run-hooks 'cal-tex-hook))
530 (defun cal-tex-cursor-month (&optional n event)
531 "Make a LaTeX calendar buffer for the month the cursor is on.
532 Optional prefix argument N specifies number of months to be
533 produced (default 1). The calendar is condensed onto one page.
534 It shows holiday and diary entries if `cal-tex-holidays' and
535 `cal-tex-diary', respectively, are non-nil. Optional EVENT
536 indicates a buffer position to use instead of point."
537 (interactive (list (prefix-numeric-value current-prefix-arg)
540 (let* ((date (calendar-cursor-to-date t event))
541 (month (calendar-extract-month date))
542 (year (calendar-extract-year date))
545 ;; FIXME -landscape sets cal-tex-which-days?
546 (d1 (calendar-absolute-from-gregorian (list month 1 year)))
548 (calendar-increment-month end-month end-year (1- n))
549 (calendar-absolute-from-gregorian
551 (calendar-last-day-of-month end-month end-year)
553 (diary-list (if cal-tex-diary (cal-tex-list-diary-entries d1 d2)))
554 (holidays (if cal-tex-holidays (holiday-in-range d1 d2))))
555 (cal-tex-insert-preamble (cal-tex-number-weeks month year n) nil "12pt")
557 (cal-tex-cmd cal-tex-cal-multi-month)
558 (cal-tex-cmd cal-tex-cal-one-month))
559 (cal-tex-insert-month-header n month year end-month end-year)
560 (cal-tex-insert-day-names)
562 (cal-tex-insert-blank-days month year cal-tex-day-prefix)
564 (cal-tex-insert-days month year diary-list holidays cal-tex-day-prefix)
565 (when (= (calendar-week-end-day)
566 (calendar-day-of-week
568 (calendar-last-day-of-month month year)
569 year))) ; last day of month was last day of week
572 (calendar-increment-month month year 1))
573 (cal-tex-insert-blank-days-at-end end-month end-year cal-tex-day-prefix))
574 (cal-tex-end-document)
575 (run-hooks 'cal-tex-hook))
577 (defun cal-tex-insert-days (month year diary-list holidays day-format)
578 "Insert LaTeX commands for a range of days in monthly calendars.
579 LaTeX commands are inserted for the days of the MONTH in YEAR.
580 Diary entries on DIARY-LIST are included. Holidays on HOLIDAYS
581 are included. Each day is formatted using format DAY-FORMAT."
582 (let ((blank-days ; at start of month
584 (- (calendar-day-of-week (list month 1 year))
585 calendar-week-start-day)
587 (last (calendar-last-day-of-month month year))
590 (setq j (1+ i) ; 1-last, incl
591 date (list month j year))
592 (when (memq (calendar-day-of-week date) cal-tex-which-days)
593 (insert (format day-format (cal-tex-month-name month) j))
594 (cal-tex-arg (cal-tex-latexify-list diary-list date))
595 (cal-tex-arg (cal-tex-latexify-list holidays date))
596 (cal-tex-arg (eval cal-tex-daily-string))
599 (when (and (zerop (mod (+ j blank-days) 7))
604 (defun cal-tex-insert-day-names ()
605 "Insert the names of the days at top of a monthly calendar."
608 (if (memq (setq j (mod (+ calendar-week-start-day i) 7))
610 (insert (format cal-tex-day-name-format
611 (cal-tex-LaTeXify-string
612 (aref calendar-day-name-array j)))))
615 (defun cal-tex-insert-month-header (n month year end-month end-year)
616 "Create a title for a calendar.
617 A title is inserted for a calendar with N months starting with
618 MONTH YEAR and ending with END-MONTH END-YEAR."
619 (let ((month-name (cal-tex-month-name month))
620 (end-month-name (cal-tex-month-name end-month)))
622 (insert (format "\\calmonth{%s}{%s}\n\\vspace*{-0.5cm}"
624 (insert (format "\\calmonth{%s}{%s}{%s}{%s}\n\\vspace*{-0.5cm}"
625 month-name year end-month-name end-year))))
628 (defun cal-tex-insert-blank-days (month year day-format)
629 "Insert code for initial days not in calendar.
630 Insert LaTeX code for the blank days at the beginning of the MONTH in
631 YEAR. The entry is formatted using DAY-FORMAT. If the entire week is
632 blank, no days are inserted."
633 (if (cal-tex-first-blank-p month year)
634 (let ((blank-days ; at start of month
636 (- (calendar-day-of-week (list month 1 year))
637 calendar-week-start-day)
639 (dotimes (i blank-days)
640 (if (memq (mod (+ calendar-week-start-day i) 7) cal-tex-which-days)
641 (insert (format day-format " " " ") "{}{}{}{}%\n"))))))
643 (defun cal-tex-insert-blank-days-at-end (month year day-format)
644 "Insert code for final days not in calendar.
645 Insert LaTeX code for the blank days at the end of the MONTH in YEAR.
646 The entry is formatted using DAY-FORMAT."
647 (if (cal-tex-last-blank-p month year)
648 (let* ((last-day (calendar-last-day-of-month month year))
649 (blank-days ; at end of month
651 (- (calendar-day-of-week (list month last-day year))
652 calendar-week-start-day)
655 (while (<= (setq i (1+ i)) 6)
656 (if (memq (mod (+ calendar-week-start-day i) 7) cal-tex-which-days)
657 (insert (format day-format "" "") "{}{}{}{}%\n"))))))
659 (defun cal-tex-first-blank-p (month year)
660 "Determine if any days of the first week will be printed.
661 Return t if there will there be any days of the first week printed
662 in the calendar starting in MONTH YEAR."
663 ;; Check days 1-7 of the month, until we find the last day of the week.
667 (if (memq (setq dow (calendar-day-of-week (list month (1+ i) year)))
670 (if (= dow (calendar-week-end-day)) (throw 'found nil)))))))
672 (defun cal-tex-last-blank-p (month year)
673 "Determine if any days of the last week will be printed.
674 Return t if there will there be any days of the last week printed
675 in the calendar starting in MONTH YEAR."
676 ;; Check backwards from the last day of the month, until we find the
677 ;; start of the last week in the month.
679 (let ((last-day (calendar-last-day-of-month month year))
682 (if (memq (setq dow (calendar-day-of-week
683 (list month (- last-day i) year)))
686 (if (= dow calendar-week-start-day) (throw 'found nil)))))))
688 (defun cal-tex-number-weeks (month year n)
689 "Determine the number of weeks in a range of dates.
690 Compute the number of weeks in the calendar starting with MONTH and YEAR,
691 and lasting N months, including only the days in WHICH-DAYS. As it stands,
692 this is only an upper bound."
693 (let ((d (list month 1 year)))
694 (calendar-increment-month month year (1- n))
695 (/ (- (calendar-dayname-on-or-before
696 calendar-week-start-day
697 (+ 7 (calendar-absolute-from-gregorian
698 (list month (calendar-last-day-of-month month year) year))))
699 (calendar-dayname-on-or-before
700 calendar-week-start-day
701 (calendar-absolute-from-gregorian d)))
708 (defconst cal-tex-LaTeX-hourbox
709 "\\newcommand{\\hourbox}[2]%
710 {\\makebox[2em]{\\rule{0cm}{#2ex}#1}\\rule{3in}{.15mm}}\n"
711 "One hour and a line on the right.")
713 (defun cal-tex-weekly-paper (&optional nomargins)
714 "Insert some page size settings for weekly layouts."
715 (insert "\\textwidth 6.5in
718 (or nomargins (insert "\\oddsidemargin 0in
722 ;; TODO cal-tex-diary-support.
723 ;; TODO respect cal-tex-daily-start,end (see cal-tex-week-hours).
725 (defun cal-tex-cursor-week (&optional n event)
726 "Make a LaTeX calendar buffer for a two-page one-week calendar.
727 It applies to the week that point is in. The optional prefix
728 argument N specifies number of weeks (default 1). The calendar
729 shows holidays if `cal-tex-holidays' is non-nil (note that diary
730 entries are not shown). The calendar shows the hours 8-12am, 1-5pm."
731 (interactive (list (prefix-numeric-value current-prefix-arg)
734 (let* ((date (calendar-gregorian-from-absolute
735 (calendar-dayname-on-or-before
736 calendar-week-start-day
737 (calendar-absolute-from-gregorian
738 (calendar-cursor-to-date t event)))))
739 (month (calendar-extract-month date))
740 (year (calendar-extract-year date))
741 (d1 (calendar-absolute-from-gregorian date))
743 (holidays (if cal-tex-holidays
744 (holiday-in-range d1 d2))))
745 (cal-tex-preamble "11pt")
746 (cal-tex-weekly-paper)
747 (insert cal-tex-LaTeX-hourbox)
749 (cal-tex-cmd "\\pagestyle" "empty")
751 (cal-tex-vspace "-1.5in")
753 (cal-tex-Huge-bf (format "\\uppercase{%s}"
754 (cal-tex-month-name month)))
755 (cal-tex-hspace "2em")
756 (cal-tex-Huge-bf (number-to-string year))
759 (cal-tex-hspace "-.2in")
760 (cal-tex-b-parbox "l" "7in")
762 (cal-tex-week-hours date holidays "3.1")
763 (setq date (cal-tex-incr-date date)))
765 (setq month (calendar-extract-month date)
766 year (calendar-extract-year date))
768 (run-hooks 'cal-tex-week-hook)
770 (cal-tex-end-document)
771 (run-hooks 'cal-tex-hook)))
773 ;; TODO cal-tex-diary support.
774 ;; TODO respect cal-tex-daily-start,end (see cal-tex-week-hours).
776 (defun cal-tex-cursor-week2 (&optional n event)
777 "Make a LaTeX calendar buffer for a two-page one-week calendar.
778 It applies to the week that point is in. Optional prefix
779 argument N specifies number of weeks (default 1). The calendar
780 shows holidays if `cal-tex-holidays' is non-nil (note that diary
781 entries are not shown). The calendar shows the hours 8-12am, 1-5pm.
782 Optional EVENT indicates a buffer position to use instead of point."
783 (interactive (list (prefix-numeric-value current-prefix-arg)
786 (let* ((date (calendar-gregorian-from-absolute
787 (calendar-dayname-on-or-before
788 calendar-week-start-day
789 (calendar-absolute-from-gregorian
790 (calendar-cursor-to-date t event)))))
791 (month (calendar-extract-month date))
792 (year (calendar-extract-year date))
793 (d1 (calendar-absolute-from-gregorian date))
795 (holidays (if cal-tex-holidays
796 (holiday-in-range d1 d2))))
797 (cal-tex-preamble "12pt")
798 (cal-tex-weekly-paper)
799 (insert cal-tex-LaTeX-hourbox)
801 (cal-tex-cmd "\\pagestyle" "empty")
803 (cal-tex-vspace "-1.5in")
805 (cal-tex-Huge-bf (format "\\uppercase{%s}"
806 (cal-tex-month-name month)))
807 (cal-tex-hspace "2em")
808 (cal-tex-Huge-bf (number-to-string year))
811 (cal-tex-hspace "-.2in")
812 (cal-tex-b-parbox "l" "\\textwidth")
814 (cal-tex-week-hours date holidays "5")
815 (setq date (cal-tex-incr-date date)))
818 (insert (cal-tex-mini-calendar
819 (calendar-extract-month (cal-tex-previous-month date))
820 (calendar-extract-year (cal-tex-previous-month date))
821 "lastmonth" "1.1in" "1in"))
822 (insert (cal-tex-mini-calendar
823 (calendar-extract-month date)
824 (calendar-extract-year date)
825 "thismonth" "1.1in" "1in"))
826 (insert (cal-tex-mini-calendar
827 (calendar-extract-month (cal-tex-next-month date))
828 (calendar-extract-year (cal-tex-next-month date))
829 "nextmonth" "1.1in" "1in"))
830 (insert "\\hbox to \\textwidth{")
832 (insert "\\lastmonth")
834 (insert "\\thismonth")
836 (insert "\\nextmonth")
840 (cal-tex-b-parbox "l" "\\textwidth")
842 (cal-tex-week-hours date holidays "5")
843 (setq date (cal-tex-incr-date date)))
845 (setq month (calendar-extract-month date)
846 year (calendar-extract-year date))
848 (run-hooks 'cal-tex-week-hook)
850 (cal-tex-end-document)
851 (run-hooks 'cal-tex-hook)))
853 (autoload 'calendar-iso-from-absolute "cal-iso")
856 (defun cal-tex-cursor-week-iso (&optional n event)
857 "Make a LaTeX calendar buffer for a one page ISO-style weekly calendar.
858 Optional prefix argument N specifies number of weeks (default 1).
859 The calendar shows holiday and diary entries if
860 `cal-tex-holidays' and `cal-tex-diary', respectively, are non-nil.
861 It does not show hours of the day. Optional EVENT indicates a buffer
862 position to use instead of point."
863 (interactive (list (prefix-numeric-value current-prefix-arg)
866 (let* ((date (calendar-gregorian-from-absolute
867 (calendar-dayname-on-or-before
869 (calendar-absolute-from-gregorian
870 (calendar-cursor-to-date t event)))))
871 (month (calendar-extract-month date))
872 (year (calendar-extract-year date))
873 (day (calendar-extract-day date))
874 (d1 (calendar-absolute-from-gregorian date))
876 (holidays (if cal-tex-holidays
877 (holiday-in-range d1 d2)))
878 (diary-list (if cal-tex-diary
879 (cal-tex-list-diary-entries d1 d2)))
881 (cal-tex-preamble "11pt")
882 (cal-tex-weekly-paper)
884 (cal-tex-cmd "\\pagestyle" "empty")
886 (cal-tex-vspace "-1.5in")
889 (let ((d (calendar-iso-from-absolute
890 (calendar-absolute-from-gregorian date))))
891 (format "Week %d of %d"
892 (calendar-extract-month d)
893 (calendar-extract-year d))))
896 (cal-tex-b-parbox "l" "\\textwidth")
898 (cal-tex-b-parbox "t" "\\textwidth")
899 (cal-tex-b-parbox "t" "\\textwidth")
900 (cal-tex-rule "0pt" "\\textwidth" ".2mm")
902 (cal-tex-b-parbox "t" "\\textwidth")
903 (cal-tex-large-bf (cal-tex-LaTeXify-string (calendar-day-name date)))
905 (cal-tex-large-bf (cal-tex-month-name month))
907 (cal-tex-large-bf (number-to-string day))
908 (unless (string-equal "" (setq s (cal-tex-latexify-list
909 holidays date "; ")))
911 (cal-tex-large-bf s))
913 (insert " " (eval cal-tex-daily-string))
917 (cal-tex-b-parbox "t" "\\textwidth")
918 (unless (string-equal "" (setq s (cal-tex-latexify-list
920 (insert "\\vbox to 0pt{")
925 (setq date (cal-tex-incr-date date)
926 month (calendar-extract-month date)
927 day (calendar-extract-day date))
929 (cal-tex-e-parbox "2cm")
931 (setq month (calendar-extract-month date)
932 year (calendar-extract-year date)))
935 (run-hooks 'cal-tex-week-hook)
937 (cal-tex-end-document)
938 (run-hooks 'cal-tex-hook)))
940 ;; TODO respect cal-tex-daily-start,end?
941 ;; Using different numbers of hours will probably break some layouts.
942 (defun cal-tex-week-hours (date holidays height)
943 "Insert hourly entries for DATE with HOLIDAYS, with line height HEIGHT.
944 Uses the 24-hour clock if `cal-tex-24' is non-nil. Note that the hours
945 shown are hard-coded to 8-12, 13-17."
946 (let ((month (calendar-extract-month date))
947 (day (calendar-extract-day date))
948 (year (calendar-extract-year date))
950 (cal-tex-comment "begin cal-tex-week-hours")
951 (cal-tex-cmd "\\ \\\\[-.2cm]")
952 (cal-tex-cmd "\\noindent")
953 (cal-tex-b-parbox "l" "6.8in")
954 (cal-tex-large-bf (cal-tex-LaTeXify-string (calendar-day-name date)))
956 (cal-tex-large-bf (cal-tex-month-name month))
958 (cal-tex-large-bf (number-to-string day))
959 (unless (string-equal "" (setq s (cal-tex-latexify-list
960 holidays date "; ")))
962 (cal-tex-large-bf s))
964 (insert " " (eval cal-tex-daily-string))
967 (cal-tex-rule "0pt" "6.8in" ".2mm")
970 (setq morning (+ i 8) ; 8-12 incl
971 afternoon (if cal-tex-24
972 (+ i 13) ; 13-17 incl
974 (cal-tex-cmd "\\hourbox" (number-to-string morning))
976 (cal-tex-hspace ".4cm")
977 (cal-tex-cmd "\\hourbox" (number-to-string afternoon))
981 ;; TODO cal-tex-diary support.
982 ;; TODO respect cal-tex-daily-start,end (see cal-tex-weekly4-box).
984 (defun cal-tex-cursor-week-monday (&optional n event)
985 "Make a LaTeX calendar buffer for a two-page one-week calendar.
986 It applies to the week that point is in, and starts on Monday.
987 Optional prefix argument N specifies number of weeks (default 1).
988 The calendar shows holidays if `cal-tex-holidays' is
989 non-nil (note that diary entries are not shown). The calendar shows
990 the hours 8-12am, 1-5pm. Optional EVENT indicates a buffer position
991 to use instead of point."
992 (interactive (list (prefix-numeric-value current-prefix-arg)
995 (let ((date (calendar-gregorian-from-absolute
996 (calendar-dayname-on-or-before
998 (calendar-absolute-from-gregorian
999 (calendar-cursor-to-date t event))))))
1000 (cal-tex-preamble "11pt")
1001 (cal-tex-weekly-paper)
1002 (cal-tex-b-document)
1004 (cal-tex-vspace "-1cm")
1005 (insert "\\noindent ")
1006 (cal-tex-weekly4-box (cal-tex-incr-date date) nil)
1007 (cal-tex-weekly4-box (cal-tex-incr-date date 4) nil)
1009 (cal-tex-weekly4-box (cal-tex-incr-date date 2) nil)
1010 (cal-tex-weekly4-box (cal-tex-incr-date date 5) nil)
1012 (cal-tex-weekly4-box (cal-tex-incr-date date 3) nil)
1013 (cal-tex-weekly4-box (cal-tex-incr-date date 6) t)
1014 (unless (= i (1- n))
1015 (run-hooks 'cal-tex-week-hook)
1016 (setq date (cal-tex-incr-date date 7))
1018 (cal-tex-end-document)
1019 (run-hooks 'cal-tex-hook)))
1021 ;; TODO respect cal-tex-daily-start,end?
1022 ;; Using different numbers of hours will probably break some layouts.
1023 (defun cal-tex-weekly4-box (date weekend)
1024 "Make one box for DATE, different if WEEKEND.
1025 Uses the 24-hour clock if `cal-tex-24' is non-nil. Note that the hours
1026 shown are hard-coded to 8-12, 13-17."
1027 (let* ((day (calendar-extract-day date))
1028 (month (calendar-extract-month date))
1029 (year (calendar-extract-year date))
1030 (dayname (cal-tex-LaTeXify-string (calendar-day-name date)))
1031 (date1 (cal-tex-incr-date date))
1032 (day1 (calendar-extract-day date1))
1033 (month1 (calendar-extract-month date1))
1034 (year1 (calendar-extract-year date1))
1035 (dayname1 (cal-tex-LaTeXify-string (calendar-day-name date1))))
1036 (cal-tex-b-framebox "8cm" "l")
1037 (cal-tex-b-parbox "b" "7.5cm")
1038 (insert (format "\\textbf{\\Large %s,} %s/%s/%s\\\\\n"
1039 dayname month day year))
1040 (cal-tex-rule "0pt" "7.5cm" ".5mm")
1044 (insert (format "\\textsf{\\large %d}\\\\\n" (+ i 8))))
1046 (insert (format "\\textsf{\\large %d}\\\\\n"
1048 (+ i 13) ; 13-17 incl
1049 (1+ i)))))) ; 1-5 incl
1052 (cal-tex-vspace "1cm")
1053 (insert "\\ \\vfill")
1054 (insert (format "\\textbf{\\Large %s,} %s/%s/%s\\\\\n"
1055 dayname1 month1 day1 year1))
1056 (cal-tex-rule "0pt" "7.5cm" ".5mm")
1057 (cal-tex-nl "1.5cm")
1058 (cal-tex-vspace "1cm"))
1060 (cal-tex-e-framebox)
1061 (cal-tex-hspace "1cm")))
1063 (defun cal-tex-weekly-common (n event &optional filofax)
1064 "Common code for weekly calendars."
1066 (let* ((date (calendar-gregorian-from-absolute
1067 (calendar-dayname-on-or-before
1069 (calendar-absolute-from-gregorian
1070 (calendar-cursor-to-date t event)))))
1071 (month (calendar-extract-month date))
1072 (year (calendar-extract-year date))
1073 (day (calendar-extract-day date))
1074 (d1 (calendar-absolute-from-gregorian date))
1076 (holidays (if cal-tex-holidays
1077 (holiday-in-range d1 d2)))
1078 (diary-list (if cal-tex-diary
1079 (cal-tex-list-diary-entries d1 d2))))
1082 (cal-tex-preamble "twoside")
1083 (cal-tex-filofax-paper)
1084 (insert cal-tex-righthead)
1085 (cal-tex-rightday "1.85in")
1086 (cal-tex-rightday "0.8in" "weekend")
1087 (insert cal-tex-lefthead)
1088 (cal-tex-leftday "1.85in"))
1089 (cal-tex-preamble "twoside,12pt")
1090 (insert "\\textwidth 7in
1093 \\evensidemargin 0in
1095 \\headheight -0.875in
1099 (insert cal-tex-righthead)
1100 (cal-tex-rightday "2.75in")
1101 (cal-tex-rightday "1.8in" "weekend")
1102 (insert cal-tex-lefthead)
1103 (cal-tex-leftday "2.75in"))
1104 (cal-tex-b-document)
1105 (cal-tex-cmd "\\pagestyle" "empty")
1107 (insert "\\lefthead")
1109 (let ((d (cal-tex-incr-date date 2)))
1110 (if (= (calendar-extract-month date)
1111 (calendar-extract-month d))
1113 (cal-tex-month-name (calendar-extract-month date))
1114 (calendar-extract-year date))
1115 (if (= (calendar-extract-year date)
1116 (calendar-extract-year d))
1117 (format "%s---%s %s"
1118 (cal-tex-month-name (calendar-extract-month date))
1119 (cal-tex-month-name (calendar-extract-month d))
1120 (calendar-extract-year date))
1121 (format "%s %s---%s %s"
1122 (cal-tex-month-name (calendar-extract-month date))
1123 (calendar-extract-year date)
1124 (cal-tex-month-name (calendar-extract-month d))
1125 (calendar-extract-year d))))))
1127 (dotimes (_jdummy 3)
1128 (insert "\\leftday")
1129 (cal-tex-arg (cal-tex-LaTeXify-string (calendar-day-name date)))
1130 (cal-tex-arg (number-to-string (calendar-extract-day date)))
1131 (cal-tex-arg (cal-tex-latexify-list diary-list date))
1132 (cal-tex-arg (cal-tex-latexify-list holidays date))
1133 (cal-tex-arg (eval cal-tex-daily-string))
1135 (setq date (cal-tex-incr-date date)))
1136 (insert "\\noindent\\rule{\\textwidth}{0.3pt}\\\\%\n")
1139 (insert (cal-tex-mini-calendar
1140 (calendar-extract-month (cal-tex-previous-month date))
1141 (calendar-extract-year (cal-tex-previous-month date))
1142 "lastmonth" "1.1in" "1in"))
1143 (insert (cal-tex-mini-calendar
1144 (calendar-extract-month date)
1145 (calendar-extract-year date)
1146 "thismonth" "1.1in" "1in"))
1147 (insert (cal-tex-mini-calendar
1148 (calendar-extract-month (cal-tex-next-month date))
1149 (calendar-extract-year (cal-tex-next-month date))
1150 "nextmonth" "1.1in" "1in"))
1151 (insert "\\hbox to \\textwidth{")
1153 (insert "\\lastmonth")
1155 (insert "\\thismonth")
1157 (insert "\\nextmonth")
1161 (insert "\\righthead")
1163 (let ((d (cal-tex-incr-date date 3)))
1164 (if (= (calendar-extract-month date)
1165 (calendar-extract-month d))
1167 (cal-tex-month-name (calendar-extract-month date))
1168 (calendar-extract-year date))
1169 (if (= (calendar-extract-year date)
1170 (calendar-extract-year d))
1171 (format "%s---%s %s"
1172 (cal-tex-month-name (calendar-extract-month date))
1173 (cal-tex-month-name (calendar-extract-month d))
1174 (calendar-extract-year date))
1175 (format "%s %s---%s %s"
1176 (cal-tex-month-name (calendar-extract-month date))
1177 (calendar-extract-year date)
1178 (cal-tex-month-name (calendar-extract-month d))
1179 (calendar-extract-year d))))))
1181 (dotimes (_jdummy 2)
1182 (insert "\\rightday")
1183 (cal-tex-arg (cal-tex-LaTeXify-string (calendar-day-name date)))
1184 (cal-tex-arg (number-to-string (calendar-extract-day date)))
1185 (cal-tex-arg (cal-tex-latexify-list diary-list date))
1186 (cal-tex-arg (cal-tex-latexify-list holidays date))
1187 (cal-tex-arg (eval cal-tex-daily-string))
1189 (setq date (cal-tex-incr-date date)))
1190 (dotimes (_jdummy 2)
1191 (insert "\\weekend")
1192 (cal-tex-arg (cal-tex-LaTeXify-string (calendar-day-name date)))
1193 (cal-tex-arg (number-to-string (calendar-extract-day date)))
1194 (cal-tex-arg (cal-tex-latexify-list diary-list date))
1195 (cal-tex-arg (cal-tex-latexify-list holidays date))
1196 (cal-tex-arg (eval cal-tex-daily-string))
1198 (setq date (cal-tex-incr-date date)))
1199 (unless (= i (1- n))
1200 (run-hooks 'cal-tex-week-hook)
1202 (cal-tex-end-document)
1203 (run-hooks 'cal-tex-hook)))
1206 (defun cal-tex-cursor-week-at-a-glance (&optional n event)
1207 "One-week-at-a-glance full page calendar for week indicated by cursor.
1208 Optional prefix argument N specifies number of weeks (default 1),
1209 starting on Mondays. The calendar shows holiday and diary entries
1210 if `cal-tex-holidays' and `cal-tex-diary', respectively, are non-nil.
1211 It does not show hours of the day. Optional EVENT indicates a buffer
1212 position to use instead of point."
1213 (interactive (list (prefix-numeric-value current-prefix-arg)
1214 last-nonmenu-event))
1215 (cal-tex-weekly-common n event))
1218 (defun cal-tex-cursor-filofax-2week (&optional n event)
1219 "Two-weeks-at-a-glance Filofax style calendar for week cursor is in.
1220 Optional prefix argument N specifies number of weeks (default 1).
1221 The calendar shows holiday and diary entries if
1222 `cal-tex-holidays' and `cal-tex-diary', respectively, are non-nil.
1223 Optional EVENT indicates a buffer position to use instead of point."
1224 (interactive (list (prefix-numeric-value current-prefix-arg)
1225 last-nonmenu-event))
1227 (let* ((date (calendar-gregorian-from-absolute
1228 (calendar-dayname-on-or-before
1229 calendar-week-start-day
1230 (calendar-absolute-from-gregorian
1231 (calendar-cursor-to-date t event)))))
1232 (month (calendar-extract-month date))
1233 (year (calendar-extract-year date))
1234 (day (calendar-extract-day date))
1235 (d1 (calendar-absolute-from-gregorian date))
1237 (holidays (if cal-tex-holidays
1238 (holiday-in-range d1 d2)))
1239 (diary-list (if cal-tex-diary
1240 (cal-tex-list-diary-entries d1 d2))))
1241 (cal-tex-preamble "twoside")
1242 (cal-tex-filofax-paper)
1243 (insert cal-tex-righthead)
1244 (cal-tex-rightday "0.7in")
1245 (insert cal-tex-lefthead)
1246 (cal-tex-leftday "0.7in")
1247 (cal-tex-b-document)
1248 (cal-tex-cmd "\\pagestyle" "empty")
1250 (if (zerop (mod i 2))
1251 (insert "\\righthead")
1252 (insert "\\lefthead"))
1254 (let ((d (cal-tex-incr-date date 6)))
1255 (if (= (calendar-extract-month date)
1256 (calendar-extract-month d))
1258 (cal-tex-month-name (calendar-extract-month date))
1259 (calendar-extract-year date))
1260 (if (= (calendar-extract-year date)
1261 (calendar-extract-year d))
1262 (format "%s---%s %s"
1263 (cal-tex-month-name (calendar-extract-month date))
1264 (cal-tex-month-name (calendar-extract-month d))
1265 (calendar-extract-year date))
1266 (format "%s %s---%s %s"
1267 (cal-tex-month-name (calendar-extract-month date))
1268 (calendar-extract-year date)
1269 (cal-tex-month-name (calendar-extract-month d))
1270 (calendar-extract-year d))))))
1272 (dotimes (_jdummy 7)
1273 (if (zerop (mod i 2))
1274 (insert "\\rightday")
1275 (insert "\\leftday"))
1276 (cal-tex-arg (cal-tex-LaTeXify-string (calendar-day-name date)))
1277 (cal-tex-arg (number-to-string (calendar-extract-day date)))
1278 (cal-tex-arg (cal-tex-latexify-list diary-list date))
1279 (cal-tex-arg (cal-tex-latexify-list holidays date))
1280 (cal-tex-arg (eval cal-tex-daily-string))
1282 (setq date (cal-tex-incr-date date)))
1283 (unless (= i (1- n))
1284 (run-hooks 'cal-tex-week-hook)
1286 (cal-tex-end-document)
1287 (run-hooks 'cal-tex-hook)))
1290 (defun cal-tex-cursor-filofax-week (&optional n event)
1291 "One-week-at-a-glance Filofax style calendar for week indicated by cursor.
1292 Optional prefix argument N specifies number of weeks (default 1),
1293 starting on Mondays. The calendar shows holiday and diary entries
1294 if `cal-tex-holidays' and `cal-tex-diary', respectively, are non-nil.
1295 Optional EVENT indicates a buffer position to use instead of point."
1296 (interactive (list (prefix-numeric-value current-prefix-arg)
1297 last-nonmenu-event))
1298 (cal-tex-weekly-common n event t))
1301 (defun cal-tex-cursor-filofax-daily (&optional n event)
1302 "Day-per-page Filofax style calendar for week indicated by cursor.
1303 Optional prefix argument N specifies number of weeks (default 1),
1304 starting on Mondays. The calendar shows holiday and diary
1305 entries if `cal-tex-holidays' and `cal-tex-diary', respectively,
1306 are non-nil. Pages are ruled if `cal-tex-rules' is non-nil.
1307 Optional EVENT indicates a buffer position to use instead of point."
1308 (interactive (list (prefix-numeric-value current-prefix-arg)
1309 last-nonmenu-event))
1311 (let* ((date (calendar-gregorian-from-absolute
1312 (calendar-dayname-on-or-before
1314 (calendar-absolute-from-gregorian
1315 (calendar-cursor-to-date t event)))))
1316 (month (calendar-extract-month date))
1317 (year (calendar-extract-year date))
1318 (day (calendar-extract-day date))
1319 (d1 (calendar-absolute-from-gregorian date))
1321 (holidays (if cal-tex-holidays
1322 (holiday-in-range d1 d2)))
1323 (diary-list (if cal-tex-diary
1324 (cal-tex-list-diary-entries d1 d2))))
1325 (cal-tex-preamble "twoside")
1326 (cal-tex-filofax-paper)
1327 (insert cal-tex-righthead)
1328 (cal-tex-shortday "rightday")
1329 (cal-tex-shortday "weekend")
1330 (insert cal-tex-lefthead)
1331 (cal-tex-shortday "leftday")
1332 (insert "\\newbox\\LineBox
1333 \\setbox\\LineBox=\\hbox to\\textwidth{%
1334 \\vrule height.2in width0pt\\leaders\\hrule\\hfill}
1335 \\def\\linesfill{\\par\\leaders\\copy\\LineBox\\vfill}
1337 (cal-tex-b-document)
1338 (cal-tex-cmd "\\pagestyle" "empty")
1341 (let ((even (zerop (% j 2))))
1345 (cal-tex-arg (calendar-date-string date))
1350 (cal-tex-arg (cal-tex-latexify-list diary-list date))
1351 (cal-tex-arg (cal-tex-latexify-list holidays date "\\\\" t))
1352 (cal-tex-arg (eval cal-tex-daily-string))
1355 (insert "\\linesfill\n")
1356 (insert "\\vfill\\noindent\\rule{\\textwidth}{0.3pt}\\\\%\n"))
1358 (setq date (cal-tex-incr-date date)))
1360 (dotimes (_jdummy 2)
1361 (insert "\\lefthead")
1362 (cal-tex-arg (calendar-date-string date))
1363 (insert "\\weekend")
1364 (cal-tex-arg (cal-tex-latexify-list diary-list date))
1365 (cal-tex-arg (cal-tex-latexify-list holidays date "\\\\" t))
1366 (cal-tex-arg (eval cal-tex-daily-string))
1369 (insert "\\linesfill\n")
1371 (setq date (cal-tex-incr-date date)))
1373 (insert "\\noindent\\rule{\\textwidth}{0.3pt}\\\\%\n"))
1374 (unless (= i (1- n))
1375 (run-hooks 'cal-tex-week-hook)
1377 (cal-tex-end-document)
1378 (run-hooks 'cal-tex-hook)))
1386 (defun cal-tex-cursor-day (&optional n event)
1387 "Make a buffer with LaTeX commands for the day cursor is on.
1388 Optional prefix argument N specifies number of days. The calendar shows
1389 the hours between `cal-tex-daily-start' and `cal-tex-daily-end', using
1390 the 24-hour clock if `cal-tex-24' is non-nil. Optional EVENT indicates
1391 a buffer position to use instead of point."
1392 (interactive (list (prefix-numeric-value current-prefix-arg)
1393 last-nonmenu-event))
1395 (let ((date (calendar-absolute-from-gregorian
1396 (calendar-cursor-to-date t event))))
1397 (cal-tex-preamble "12pt")
1398 (cal-tex-weekly-paper 'nomargins)
1399 (cal-tex-b-document)
1400 (cal-tex-cmd "\\pagestyle" "empty")
1402 (cal-tex-vspace "-1.7in")
1403 (cal-tex-daily-page (calendar-gregorian-from-absolute date))
1404 (setq date (1+ date))
1405 (unless (= i (1- n))
1407 (run-hooks 'cal-tex-daily-hook)))
1408 (cal-tex-end-document)
1409 (run-hooks 'cal-tex-hook)))
1411 (defun cal-tex-daily-page (date)
1412 "Make a calendar page for Gregorian DATE on 8.5 by 11 paper.
1413 Uses the 24-hour clock if `cal-tex-24' is non-nil. Produces
1414 hourly sections for the period specified by `cal-tex-daily-start'
1415 and `cal-tex-daily-end'."
1416 (let ((month-name (cal-tex-month-name (calendar-extract-month date)))
1417 (i (1- cal-tex-daily-start))
1419 (cal-tex-banner "cal-tex-daily-page")
1420 (cal-tex-b-makebox "4cm" "l")
1421 (cal-tex-b-parbox "b" "3.8cm")
1422 (cal-tex-rule "0mm" "0mm" "2cm")
1423 (cal-tex-Huge (number-to-string (calendar-extract-day date)))
1425 (cal-tex-bf month-name )
1427 (cal-tex-hspace "1cm")
1428 (cal-tex-scriptsize (eval cal-tex-daily-string))
1429 (cal-tex-hspace "3.5cm")
1432 (cal-tex-b-makebox "4cm" "r")
1433 (cal-tex-bf (cal-tex-LaTeXify-string (calendar-day-name date)))
1436 (cal-tex-hspace ".4cm")
1437 (cal-tex-rule "0mm" "16.1cm" "1mm")
1439 (while (<= (setq i (1+ i)) cal-tex-daily-end)
1440 (cal-tex-cmd "\\noindent")
1441 (setq hour (if cal-tex-24
1444 (if (zerop hour) (setq hour 12))
1445 (cal-tex-b-makebox "1cm" "c")
1446 (cal-tex-arg (number-to-string hour))
1448 (cal-tex-rule "0mm" "15.5cm" ".2mm")
1450 (cal-tex-b-makebox "1cm" "c")
1451 (cal-tex-arg "$\\diamond$" )
1453 (cal-tex-rule "0mm" "15.5cm" ".2mm")
1454 (cal-tex-nl ".2cm"))
1456 (insert (cal-tex-mini-calendar
1457 (calendar-extract-month (cal-tex-previous-month date))
1458 (calendar-extract-year (cal-tex-previous-month date))
1459 "lastmonth" "1.1in" "1in"))
1460 (insert (cal-tex-mini-calendar
1461 (calendar-extract-month date)
1462 (calendar-extract-year date)
1463 "thismonth" "1.1in" "1in"))
1464 (insert (cal-tex-mini-calendar
1465 (calendar-extract-month (cal-tex-next-month date))
1466 (calendar-extract-year (cal-tex-next-month date))
1467 "nextmonth" "1.1in" "1in"))
1468 (insert "\\hbox to \\textwidth{")
1470 (insert "\\lastmonth")
1472 (insert "\\thismonth")
1474 (insert "\\nextmonth")
1477 (cal-tex-banner "end of cal-tex-daily-page")))
1483 (defun cal-tex-mini-calendar (month year name width height &optional ptsize colsep)
1484 "Produce mini-calendar for MONTH, YEAR in macro NAME with WIDTH and HEIGHT.
1485 Optional string PTSIZE gives the point size (default \"scriptsize\").
1486 Optional string COLSEP gives the column separation (default \"1mm\")."
1487 (or colsep (setq colsep "1mm"))
1488 (or ptsize (setq ptsize "scriptsize"))
1489 (let ((blank-days ; at start of month
1491 (- (calendar-day-of-week (list month 1 year))
1492 calendar-week-start-day)
1494 (last( calendar-last-day-of-month month year))
1495 (str (concat "\\def\\" name "{\\hbox to" width "{%\n"
1496 "\\vbox to" height "{%\n"
1497 "\\vfil \\hbox to" width "{%\n"
1500 "{@{\\hspace{0mm}}r@{\\hspace{" colsep
1501 "}}r@{\\hspace{" colsep "}}r@{\\hspace{" colsep
1502 "}}r@{\\hspace{" colsep "}}r@{\\hspace{" colsep
1503 "}}r@{\\hspace{" colsep "}}r@{\\hspace{0mm}}}%\n"
1504 "\\multicolumn{7}{c}{"
1505 (cal-tex-month-name month)
1507 (number-to-string year)
1512 (cal-tex-LaTeXify-string
1513 (substring (aref calendar-day-name-array
1514 (mod (+ calendar-week-start-day i) 7))
1520 (dotimes (_idummy blank-days)
1521 (setq str (concat str " & ")))
1523 (setq str (concat str (number-to-string (1+ i)))
1524 str (concat str (if (zerop (mod (+ i 1 blank-days) 7))
1529 (setq str (concat str "\n\\end{tabular}\\hfil}\\vfil}}}%\n"))
1533 ;;; Various calendar functions
1536 (defun cal-tex-incr-date (date &optional n)
1537 "The date of the day following DATE.
1538 If optional N is given, the date of N days after DATE."
1539 (calendar-gregorian-from-absolute
1540 (+ (or n 1) (calendar-absolute-from-gregorian date))))
1542 (defun cal-tex-latexify-list (date-list date &optional separator final-separator)
1543 "Return string with concatenated, LaTeX-ified entries in DATE-LIST for DATE.
1544 Use double backslash as a separator unless optional SEPARATOR is given.
1545 If resulting string is not empty, put separator at end if optional
1546 FINAL-SEPARATOR is non-nil."
1547 (or separator (setq separator "\\\\"))
1550 (mapconcat (lambda (x) (cal-tex-LaTeXify-string x))
1551 (dolist (d date-list (reverse result))
1553 (calendar-date-equal date (car d))
1554 (setq result (cons (cadr d) result))))
1556 (if (and final-separator
1557 (not (string-equal result "")))
1558 (concat result separator)
1561 (defun cal-tex-previous-month (date)
1562 "Return the date of the first day in the month previous to DATE."
1563 (let ((month (calendar-extract-month date))
1564 (year (calendar-extract-year date)))
1565 (calendar-increment-month month year -1)
1566 (list month 1 year)))
1568 (defun cal-tex-next-month (date)
1569 "Return the date of the first day in the month following DATE."
1570 (let ((month (calendar-extract-month date))
1571 (year (calendar-extract-year date)))
1572 (calendar-increment-month month year 1)
1573 (list month 1 year)))
1579 (defun cal-tex-end-document ()
1580 "Finish the LaTeX document.
1581 Insert the trailer to LaTeX document, pop to LaTeX buffer, add
1582 informative header, and run HOOK."
1583 (cal-tex-e-document)
1584 (or (and cal-tex-preamble-extra
1585 (string-match "inputenc" cal-tex-preamble-extra))
1586 (when (re-search-backward "[^[:ascii:]]" nil 'move)
1587 (goto-char (point-min))
1588 (when (search-forward "documentclass" nil t)
1590 ;; Eg for some Bahai holidays.
1591 ;; FIXME latin1 might not always be right.
1592 (insert "\\usepackage[latin1]{inputenc}\n"))))
1594 (pop-to-buffer (current-buffer))
1595 (goto-char (point-min))
1596 ;; FIXME auctex equivalents?
1598 (format "\tThis buffer was produced by cal-tex.el.
1599 \tTo print a calendar, type
1600 \t\tM-x tex-buffer RET
1601 \t\tM-x tex-print RET")))
1603 (defun cal-tex-insert-preamble (weeks landscape size &optional append)
1604 "Initialize the output LaTeX calendar buffer, `cal-tex-buffer'.
1605 Select the output buffer, and insert the preamble for a calendar
1606 of WEEKS weeks. Insert code for landscape mode if LANDSCAPE is
1607 non-nil. Use point-size SIZE. Optional argument APPEND, if
1608 non-nil, means add to end of buffer without erasing current contents."
1609 (let ((width "18cm")
1615 (cal-tex-preamble size)
1618 (cal-tex-cmd "\\oddsidemargin -1.75cm")
1619 (cal-tex-cmd "\\def\\holidaymult" ".06"))
1620 (cal-tex-cmd "\\special" "landscape")
1621 (cal-tex-cmd "\\textwidth 9.5in")
1622 (cal-tex-cmd "\\textheight 7in")
1624 (cal-tex-cmd "\\def\\holidaymult" ".08"))
1625 (cal-tex-cmd cal-tex-caldate)
1626 (cal-tex-cmd cal-tex-myday)
1627 (cal-tex-b-document)
1628 (cal-tex-cmd "\\pagestyle" "empty"))
1629 (cal-tex-cmd "\\setlength{\\cellwidth}" width)
1630 (insert (format "\\setlength{\\cellwidth}{%f\\cellwidth}\n"
1631 (/ 1.1 (length cal-tex-which-days))))
1632 (cal-tex-cmd "\\setlength{\\cellheight}" height)
1633 (insert (format "\\setlength{\\cellheight}{%f\\cellheight}\n"
1635 (cal-tex-cmd "\\ \\par")
1636 (cal-tex-vspace "-3cm")))
1638 (defconst cal-tex-LaTeX-subst-list
1640 ("\"". "''") ; quote changes meaning when list is reversed
1641 ;; Don't think this is necessary, and in any case, does not work:
1642 ;; "LaTeX Error: \verb illegal in command argument".
1643 ;;; ("@" . "\\verb|@|")
1653 ("\n" . "\\ \\\\")) ; \\ needed for e.g \begin{center}\n AA\end{center}
1654 "Alist of symbols and their LaTeX replacements.")
1656 (defun cal-tex-LaTeXify-string (string)
1657 "Protect special characters in STRING from LaTeX."
1662 (list cal-tex-LaTeX-subst-list)
1664 (while (not (string-equal tail ""))
1665 (setq ch (substring-no-properties tail 0 1)
1666 pair (assoc ch list))
1667 (if (and pair (string-equal ch "\""))
1668 (setq list (reverse list))) ; quote changes meaning each time
1669 (setq tail (substring-no-properties tail 1)
1670 head (concat head (if pair (cdr pair) ch))))
1673 (defun cal-tex-month-name (month)
1674 "The name of MONTH, LaTeX-ified."
1675 (cal-tex-LaTeXify-string (calendar-month-name month)))
1677 (defun cal-tex-hfill ()
1681 (defun cal-tex-newpage ()
1683 (insert "\\newpage%\n"))
1685 (defun cal-tex-noindent ()
1687 (insert "\\noindent"))
1689 (defun cal-tex-vspace (space)
1690 "Insert vspace command to move SPACE vertically."
1691 (cal-tex-cmd "\\vspace*" space))
1693 (defun cal-tex-hspace (space)
1694 "Insert hspace command to move SPACE horizontally."
1695 (cal-tex-cmd "\\hspace*" space))
1697 (defun cal-tex-comment (&optional comment)
1698 "Insert `% ', followed by optional string COMMENT, followed by newline.
1699 COMMENT may contain newlines, which are prefixed by `% ' in the output."
1700 (insert (format "%% %s\n"
1702 (replace-regexp-in-string "\n" "\n% " comment)
1705 (defun cal-tex-banner (comment)
1706 "Insert string COMMENT, separated by blank lines."
1707 (cal-tex-comment (format "\n\n\n\t\t\t%s\n" comment)))
1709 (defun cal-tex-nl (&optional skip comment)
1710 "End a line with \\. If SKIP, then add that much spacing.
1711 Add trailing COMMENT if present."
1712 (insert (format "\\\\%s"
1714 (format "[%s]" skip)
1716 (cal-tex-comment comment))
1718 (defun cal-tex-arg (&optional text)
1719 "Insert a brace {} pair containing the optional string TEXT."
1720 (insert (format "{%s}" (or text ""))))
1722 (defun cal-tex-cmd (cmd &optional arg)
1723 "Insert LaTeX CMD, with optional argument ARG, and end with %."
1732 (defun cal-tex-b-document ()
1733 "Insert beginning of document."
1734 (cal-tex-cmd "\\begin" "document"))
1736 (defun cal-tex-e-document ()
1737 "Insert end of document."
1738 (cal-tex-cmd "\\end" "document"))
1740 (defun cal-tex-b-center ()
1741 "Insert beginning of centered block."
1742 (cal-tex-cmd "\\begin" "center"))
1744 (defun cal-tex-e-center ()
1745 "Insert end of centered block."
1747 (cal-tex-cmd "\\end" "center"))
1755 (defun cal-tex-b-parbox (position width)
1756 "Insert parbox with parameters POSITION and WIDTH."
1757 (insert "\\parbox[" position "]{" width "}{")
1760 (defun cal-tex-e-parbox (&optional height)
1761 "Insert end of parbox. Optionally, force it to be a given HEIGHT."
1764 (cal-tex-rule "0mm" "0mm" height))
1766 (cal-tex-comment "end parbox"))
1768 (defun cal-tex-b-framebox (width position)
1769 "Insert framebox with parameters WIDTH and POSITION (clr)."
1770 (insert "\\framebox[" width "][" position "]{" )
1773 (defun cal-tex-e-framebox ()
1774 "Insert end of framebox."
1777 (cal-tex-comment "end framebox"))
1780 (defun cal-tex-b-makebox (width position)
1781 "Insert makebox with parameters WIDTH and POSITION (clr)."
1782 (insert "\\makebox[" width "][" position "]{" )
1785 (defun cal-tex-e-makebox ()
1786 "Insert end of makebox."
1789 (cal-tex-comment "end makebox"))
1792 (defun cal-tex-rule (lower width height)
1793 "Insert a rule with parameters LOWER WIDTH HEIGHT."
1794 (insert "\\rule[" lower "]{" width "}{" height "}"))
1800 (defun cal-tex-em (string)
1801 "Insert STRING in italic font."
1802 (cal-tex-cmd "\\textit" string))
1804 (defun cal-tex-bf (string)
1805 "Insert STRING in bf font."
1806 (cal-tex-cmd "\\textbf" string))
1808 (defun cal-tex-scriptsize (string)
1809 "Insert STRING in scriptsize font."
1810 (cal-tex-arg (concat "\\scriptsize " string)))
1812 (defun cal-tex-huge (string)
1813 "Insert STRING in huge font."
1814 (cal-tex-arg (concat "\\huge " string)))
1816 (defun cal-tex-Huge (string)
1817 "Insert STRING in Huge font."
1818 (cal-tex-arg (concat "\\Huge " string)))
1820 (defun cal-tex-Huge-bf (string)
1821 "Insert STRING in Huge bf font."
1822 (cal-tex-cmd "\\textbf" (concat "\\Huge " string)))
1824 (defun cal-tex-large (string)
1825 "Insert STRING in large font."
1826 (cal-tex-arg (concat "\\large " string)))
1828 (defun cal-tex-large-bf (string)
1829 "Insert STRING in large bf font."
1830 (cal-tex-cmd "\\textbf" (concat "\\large " string)))
1835 ;;; cal-tex.el ends here