1 ;;; planner-publish.el --- planner-specific publishing
3 ;; Copyright (C) 2005, 2006 Peter K. Lee
4 ;; Parts copyright (C) 2005 Chris McMahan
5 ;; Parts copyright (C) 2005, 2006 Free Software Foundation, Inc.
6 ;; Parts copyright (C) 2005 Dale P. Smith
8 ;; Author: Peter K. Lee <saint@ c o r e n o v a .com>
9 ;; Keywords: planner publish
10 ;; Timestamp: 20 Jul 2005 10:05:29
11 ;; X-URL: http://www.corenova.com/...
13 ;; This file is part of Planner. It is not part of GNU Emacs.
15 ;; Planner is free software; you can redistribute it and/or modify it
16 ;; under the terms of the GNU General Public License as published by
17 ;; the Free Software Foundation; either version 2, or (at your option)
20 ;; Planner is distributed in the hope that it will be useful, but
21 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 ;; General Public License for more details.
25 ;; You should have received a copy of the GNU General Public License
26 ;; along with Planner; see the file COPYING. If not, write to the
27 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
28 ;; Boston, MA 02110-1301, USA.
32 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
36 ;; Muse Styles for Planner: planner-xml, planner-html, planner-xhtml, etc.
38 ;; Handles publishing of planner files. Works with Muse to generate
43 ;; 2005-07-15 (0.1) : creation date
44 ;; 2005-07-20 (0.2) : first public release
45 ;; 2005-07-21 (0.3) : added planner-html-style-sheet customize option
46 ;; 2005-08-09 : added to Planner, see ChangeLog for further changes
50 ;; add support for various PLANNER specific sections such as Diary,
51 ;; Accomplishments, Timeclock, etc.
55 ;; Chris McMahan (cmcmahan AT one.net) helped notes to publish correctly.
57 ;; Jim Ottaway fixed several bugs.
59 ;; David Smith fixed a few bugs.
61 ;; Dale Smith implemented a new version of the "notes" tag and
62 ;; provided several patches.
64 ;; Andrew J. Korty enabled multiple links with the "categories"
70 (require 'muse-publish
)
71 (require 'muse-html
) ;;; allow derive style from "html" and "xhtml"
72 (require 'muse-xml
) ;;; allow derive style from "xml"
74 (defgroup planner-publish nil
75 "Options controlling the behavior of PLANNER publishing.
76 See `planner-publish' for more information."
79 (defcustom planner-publish-markup-regexps
80 '((1275 "^#\\([A-C]\\)\\([0-9]*\\)\\s-*\\([_oXDCP]\\)\\s-*\\(.+\\)" 0 task
)
81 (1280 "^\\.#[0-9]+\\s-*" 0 note
)
82 (3200 planner-date-regexp
0 link
))
83 "List of markup rules for publishing PLANNER.
84 For more on the structure of this list, see `muse-publish-markup-regexps'."
85 :type
'(repeat (choice
86 (list :tag
"Markup rule"
88 (choice regexp symbol
)
90 (choice string function symbol
))
94 (defcustom planner-publish-markup-functions
95 '((task . planner-publish-markup-task
)
96 (note . planner-publish-markup-note
))
97 "An alist of style types to custom functions for that kind of text.
98 For more on the structure of this list, see
99 `muse-publish-markup-functions'."
100 :type
'(alist :key-type symbol
:value-type function
)
101 :group
'planner-publish
)
103 (defcustom planner-publish-markup-tags
104 '(("nested-section" t nil planner-publish-nested-section-tag
)
105 ("title" t nil planner-publish-title-tag
)
106 ("content" t nil planner-publish-content-tag
)
107 ("tasks-section" t nil planner-publish-tasks-section-tag
)
108 ("notes-section" t nil planner-publish-notes-section-tag
)
109 ("notes" nil nil planner-publish-notes-tag
)
110 ("past-notes" nil t planner-publish-past-notes-tag
)
111 ("task" t t planner-publish-task-tag
)
112 ("note" t t planner-publish-note-tag
))
113 "A list of tag specifications, for specially marking up PLANNER.
114 See `muse-publish-markup-tags' for more information."
115 :type
'(repeat (list (string :tag
"Markup tag")
116 (boolean :tag
"Expect closing tag" :value t
)
117 (boolean :tag
"Parse attributes" :value nil
)
119 :group
'planner-publish
)
121 ;;;_ + XML specific customizations
123 (defcustom planner-xml-markup-strings
124 '((planner-begin-nested-section .
"<section>")
125 (planner-end-nested-section .
"</section>")
126 (planner-begin-title .
"<title>")
127 (planner-end-title .
"</title>")
128 (planner-begin-content .
"")
129 (planner-end-content .
"")
130 (planner-begin-body .
"")
131 (planner-end-body .
"")
132 (planner-begin-task-section .
"<tasks>")
133 (planner-end-task-section .
"</tasks>")
134 (planner-begin-task-body .
"")
135 (planner-end-task-body .
"")
136 (planner-begin-note-section .
"<notes>")
137 (planner-end-note-section .
"</notes>")
138 (planner-begin-task .
"<task status=\"%s\" priority=\"%s\">")
139 (planner-end-task .
"</task>")
140 (planner-begin-note .
"<note number=\"%s\">")
141 (planner-end-note .
"</note>")
142 (planner-begin-note-details .
"<details><timestamp>%s</timestamp>")
143 (planner-end-note-details .
"</details>")
144 (planner-begin-note-link .
"<references>")
145 (planner-end-note-link .
"</references>")
146 (planner-begin-note-categories .
"<categories>")
147 (planner-end-note-categories .
"</categories>"))
148 "Strings used for marking up text as XML.
149 These cover the most basic kinds of markup, the handling of which
150 differs little between the various styles.
152 If a markup rule is not found here, `muse-xml-markup-strings' is
154 :type
'(alist :key-type symbol
:value-type string
)
155 :group
'planner-publish
)
157 (defcustom planner-xml-header
158 "<?xml version=\"1.0\" encoding=\"<lisp>(muse-xml-encoding)</lisp>\"?>
161 <title><lisp>(muse-publishing-directive \"title\")</lisp></title>
162 <author><lisp>(muse-publishing-directive \"author\")</lisp></author>
163 <maintainer><lisp>(muse-style-element :maintainer)</lisp></maintainer>
164 <pubdate><lisp>(muse-publishing-directive \"date\")</lisp></pubdate>
166 <!-- Page published by Emacs Muse begins here -->\n"
167 "Header used for publishing PLANNER XML files.
168 This may be text or a filename."
170 :group
'planner-publish
)
172 (defcustom planner-xml-footer
"
173 <!-- Page published by Emacs Muse ends here -->
175 "Footer used for publishing PLANNER XML files.
176 This may be text or a filename."
178 :group
'planner-publish
)
180 ;;;_ + HTML specific customizations
182 (defcustom planner-html-markup-strings
183 '((planner-begin-nested-section .
"<div class=\"section\">")
184 (planner-end-nested-section .
"</div>")
185 (planner-begin-title .
"<div class=\"title\">")
186 (planner-end-title .
"</div>")
187 (planner-begin-content .
"<div class=\"content\">")
188 (planner-end-content .
"</div>")
189 (planner-begin-body .
"<div class=\"body\">")
190 (planner-end-body .
"</div>")
191 (planner-begin-task-section .
"<div id=\"tasks\" class=\"section\">")
192 (planner-end-task-section .
"</div>")
193 (planner-begin-task-body .
"<ul class=\"body\">")
194 (planner-end-task-body .
"</ul>")
195 (planner-begin-note-section .
"<div id=\"notes\" class=\"section\">")
196 (planner-end-note-section .
"</div>")
197 (planner-begin-task .
"<li class=\"task\"><span class=\"%s\"><span class=\"%s\">%s</span>")
198 (planner-end-task .
"</span></li>")
199 (planner-begin-note .
"<div class=\"note\"><a name=\"%s\"></a><span class=\"anchor\">%s</span>")
200 (planner-end-note .
"</div>")
201 (planner-begin-note-details .
"<div class=\"details\"><span class=\"timestamp\">%s</span>")
202 (planner-end-note-details .
"</div>")
203 (planner-begin-note-link .
" <span class=\"link\">")
204 (planner-end-note-link .
"</span>")
205 (planner-begin-note-categories .
" <span class=\"categories\">")
206 (planner-end-note-categories .
"</span>\n"))
207 "Strings used for marking up text as HTML.
208 These cover the most basic kinds of markup, the handling of which
209 differs little between the various styles.
211 If a markup rule is not found here, `muse-html-markup-strings' is
213 :type
'(alist :key-type symbol
:value-type string
)
214 :group
'planner-publish
)
216 (defcustom planner-html-style-sheet
217 "<style type=\"text/css\">
219 background: white; color: black;
220 margin-left: 3%; margin-right: 3%;
223 p { margin-top: 3px; margin-bottom: 3px; }
224 p.verse { margin-left: 3% }
226 h1,h2,h3,h4,h5 { margin:0; padding:0; }
228 h1 { padding: 10px; margin-bottom: 10px; }
230 table.muse-table { margin: 0; font-size: 11px;
231 border-collapse: collapse;
233 border: 1px solid #aadeed; }
235 table.muse-table tbody td { border: 1px solid #ccdeed; }
237 .example { margin-left: 5px; padding: 3px;
239 border: 1px solid #ccdeed; }
241 /* enabled with planner-sectionalize.el */
242 .section { margin: 0; padding: 10px;
246 .section .section { margin: 0; margin-left: 5px;
249 .title { margin: 0; padding; 0 }
251 .section .title { font-size: 14px; }
252 .section .section .title { font-size: 12px; }
253 .section .section .section .title { font-size: 11px; }
256 .task .A { color: red }
257 .task .B { color: green }
258 .task .C { color: navy }
259 .task .done { color: gray; text-decoration: line-through; }
260 .task .cancelled { color: gray; text-decoration: italic; }
263 "Store your stylesheet definitions here. The provided default
264 is for reference only. You definitely want to customize this for
265 your particular needs & wants. This is used in
266 `planner-html-header' and `planner-xhtml-header'. Refer to
267 `muse-html-style-sheet' for details on usage. You may simply
268 override the above by specifying an explicit link to a CSS file."
270 :group
'planner-publish
)
272 (defcustom planner-html-header
273 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">
277 (concat (muse-publishing-directive \"title\")
278 (let ((author (muse-publishing-directive \"author\")))
279 (if (not (string= author (user-full-name)))
280 (concat \" (by \" author \")\"))))</lisp></title>
281 <meta name=\"generator\" content=\"muse.el\">
282 <meta http-equiv=\"<lisp>muse-html-meta-http-equiv</lisp>\"
283 content=\"<lisp>muse-html-meta-content-type</lisp>\">
285 (let ((maintainer (muse-style-element :maintainer)))
287 (concat \"<link rev=\\\"made\\\" href=\\\"\" maintainer \"\\\">\")))
289 <lisp>planner-html-style-sheet</lisp>
294 (concat (muse-publishing-directive \"title\")
295 (let ((author (muse-publishing-directive \"author\")))
296 (if (not (string= author (user-full-name)))
297 (concat \" (by \" author \")\"))))</lisp></span></h1>
298 <div id=\"inner-header\">
299 <lisp>planner-html-inner-header</lisp>
301 <div id=\"muse-sections\">
302 <!-- Page published by Emacs Muse begins here -->\n"
303 "Header used for publishing PLANNER HTML files.
304 This may be text or a filename."
306 :group
'planner-publish
)
308 (defcustom planner-html-footer
"
309 <!-- Page published by Emacs Muse ends here -->
311 <div id=\"inner-footer\">
312 <lisp>planner-html-inner-footer</lisp>
317 "Footer used for publishing PLANNER HTML files.
318 This may be text or a filename."
320 :group
'planner-publish
)
322 (defcustom planner-xhtml-header
323 "<?xml version=\"1.0\" encoding=\"<lisp>
324 (muse-html-encoding)</lisp>\"?>
325 <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
326 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
327 <html xmlns=\"http://www.w3.org/1999/xhtml\">
330 (concat (muse-publishing-directive \"title\")
331 (let ((author (muse-publishing-directive \"author\")))
332 (if (not (string= author (user-full-name)))
333 (concat \" (by \" author \")\"))))</lisp></title>
334 <meta name=\"generator\" content=\"muse.el\" />
335 <meta http-equiv=\"<lisp>muse-html-meta-http-equiv</lisp>\"
336 content=\"<lisp>muse-html-meta-content-type</lisp>\" />
338 (let ((maintainer (muse-style-element :maintainer)))
340 (concat \"<link rev=\\\"made\\\" href=\\\"\" maintainer \"\\\" />\")))
342 <lisp>planner-html-style-sheet</lisp>
347 (concat (muse-publishing-directive \"title\")
348 (let ((author (muse-publishing-directive \"author\")))
349 (if (not (string= author (user-full-name)))
350 (concat \" (by \" author \")\"))))</lisp></span></h1>
351 <div id=\"inner-header\">
352 <lisp>planner-html-inner-header</lisp>
354 <div id=\"muse-sections\">
355 <!-- Page published by Emacs Muse begins here -->\n"
356 "Header used for publishing PLANNER XHTML files.
357 This may be text or a filename."
359 :group
'planner-publish
)
361 (defcustom planner-xhtml-footer
"
362 <!-- Page published by Emacs Muse ends here -->
364 <div id=\"inner-footer\">
365 <lisp>planner-html-inner-footer</lisp>
370 "Footer used for publishing PLANNER XHTML files.
371 This may be text or a filename."
373 :group
'planner-publish
)
375 (defcustom planner-html-inner-header
""
376 "Extra header section that can be embedded w/in existing
377 `planner-html-header'. This may be text or a filename."
379 :group
'planner-publish
)
381 (defcustom planner-html-inner-footer
""
382 "Extra footer section that can be embedded w/in existing
383 `planner-html-footer'. This may be text or a filename."
385 :group
'planner-publish
)
387 ;;;_ + Publishing hooks
389 (defun planner-publish-prepare-buffer ()
390 "Return nil to allow hook to continue"
391 (planner-sectionalize-page)
396 (defun planner-publish-markup-task ()
397 "Replace tasks with XML representation of task data."
400 (planner-line-beginning-position)
401 (planner-line-end-position))
402 (muse-publish-escape-specials (point-min) (point-max))
403 (let ((info (planner-current-task-info)))
404 (delete-region (point-min) (point-max))
407 (format (concat "<task id=\"%s\" priority=\"%s\" status=\"%s\""
408 " link=\"%s\" plan=\"%s\" date=\"%s\">")
409 (or (planner-task-number info
) "")
410 (or (planner-task-priority info
) "")
411 (or (planner-publish-task-status-expand
412 (planner-task-status info
)) "")
413 (or (planner-task-link-text info
) "")
414 (or (planner-task-plan info
) "")
415 (or (planner-task-date info
) ""))
416 (planner-task-description info
) ; mark this area read only
419 (defun planner-publish-markup-note ()
420 "Replace note with XML representation of note data. Borrowed
421 heavily from Sacha's personal configs."
424 (save-excursion (beginning-of-line) (point))
426 (and (re-search-forward "^\\(\\.#\\|* \\|</notes-section>\\)" nil t
)
427 (match-beginning 0)))
429 (let ((info (planner-current-note-info t
)))
430 (delete-region (point-min) (point-max))
431 (insert (format (concat "<note anchor=\"%s\" timestamp=\"%s\""
432 " link=\"%s\" categories=\"%s\">")
433 (planner-note-anchor info
)
434 (or (planner-note-timestamp info
) "")
435 (or (planner-note-link info
) "")
436 (or (planner-note-link-text info
) ""))
437 "<title>" (planner-note-title info
) "</title>\n"
438 "<content>\n" (planner-note-body info
) "\n\n</content>\n"
444 (defun planner-insert-markup (&rest args
)
445 (if (fboundp 'muse-insert-markup
)
446 (apply 'muse-insert-markup args
)
447 (apply 'insert args
)))
449 (defun planner-publish-nested-section-tag (beg end
)
450 "Generated by `sectionalize', the nested section tag now takes
451 in TITLE and LEVEL attributes. Do not get this confused with
452 MUSE specific `section', `subsection', etc. tags. The MUSE
453 specific sections are more like title/heading tags than this
454 nested section block version."
457 (planner-insert-markup (muse-markup-text 'planner-begin-nested-section
))
459 (planner-insert-markup (muse-markup-text 'planner-end-nested-section
))))
461 (defun planner-publish-title-tag (beg end
)
464 (planner-insert-markup (muse-markup-text 'planner-begin-title
))
466 (planner-insert-markup (muse-markup-text 'planner-end-title
))))
468 (defun planner-publish-content-tag (beg end
)
471 (planner-insert-markup (muse-markup-text 'planner-end-content
))
473 (planner-insert-markup (muse-markup-text 'planner-begin-content
))))
475 (defun planner-publish-tasks-section-tag (beg end
)
478 (planner-insert-markup (muse-markup-text 'planner-begin-task-section
))
480 (planner-insert-markup (muse-markup-text 'planner-begin-task-body
))
482 (planner-insert-markup (muse-markup-text 'planner-end-task-body
))
483 (planner-insert-markup (muse-markup-text 'planner-end-task-section
))))
485 (defun planner-publish-task-tag (beg end attrs
)
487 (let ((number (cdr (assoc "id" attrs
)))
488 (status (cdr (assoc "status" attrs
)))
489 (priority (cdr (assoc "priority" attrs
)))
490 (link (cdr (assoc "link" attrs
)))
491 (plan (cdr (assoc "plan" attrs
)))
492 (date (cdr (assoc "date" attrs
))))
494 (planner-insert-markup
495 (muse-markup-text 'planner-begin-task
498 (concat priority number
" "
499 (planner-publish-task-status-collapse status
)
503 (insert " (" (planner-make-link link
) ")"))
504 (planner-insert-markup (muse-markup-text 'planner-end-task
)))))
506 (defun planner-publish-notes-section-tag (beg end
)
507 "Replace the region BEG to END with the notes for this page."
509 (planner-insert-markup (muse-markup-text 'planner-begin-note-section
))
511 (planner-insert-markup (muse-markup-text 'planner-begin-body
))
513 (planner-insert-markup (muse-markup-text 'planner-end-body
))
514 (planner-insert-markup (muse-markup-text 'planner-end-note-section
))))
516 (defun planner-publish-notes-tag (beg end
)
517 "Replace the region BEG to END with an index of the notes for this page."
518 (delete-region beg end
)
522 (insert (format " - [[%s%s][%s]]\n"
525 (planner-remove-links (cdr item
)))))
527 (find-file muse-publishing-current-file
)
528 (planner-notes-get-headlines)))
531 (defun planner-publish-past-notes-tag (beg end attrs
)
532 "Replace the region BEG to END with an index of past notes.
533 If ATTRS is non-nil, it is an alist containing values for
534 DIRECTORY and START."
535 (let ((files (save-excursion
536 (find-file muse-publishing-current-file
)
537 (planner-get-day-pages nil nil t
)))
538 (earliest (cdr (assoc "start" attrs
))))
540 (when (or (null earliest
)
541 (not (string-lessp (caar files
) earliest
)))
542 (let ((title-lines (list t
)))
544 (insert-file-contents (cdar files
))
545 (while (re-search-forward "^\\.#\\([0-9]+\\)\\s-+\\(.+\\)" nil t
)
546 (nconc title-lines
(list (cons (match-string 1)
547 (match-string 2))))))
548 (setq title-lines
(cdr title-lines
))
550 (insert (planner-make-link (planner-page-name (caar files
)))
552 (planner-insert-markup " <dl class=\"contents\">\n")
554 (planner-insert-markup " <dt class=\"contents\">")
555 (insert (format "[[%s#%s][%s]]"
556 (planner-page-name (caar files
))
557 (caar title-lines
) (cdar title-lines
)))
558 (planner-insert-markup "</dt>\n")
559 (setq title-lines
(cdr title-lines
)))
560 (planner-insert-markup " </dl>\n\n"))))
561 (setq files
(cdr files
)))))
563 (defun planner-publish-note-tag (beg end attrs
)
565 (let ((anchor (or (cdr (assoc "anchor" attrs
)) ""))
566 (timestamp (or (cdr (assoc "timestamp" attrs
)) ""))
567 (link (or (cdr (assoc "link" attrs
)) ""))
568 (categories (or (cdr (assoc "categories" attrs
)) "")))
571 (planner-insert-markup (muse-markup-text 'planner-begin-note
573 (concat "#" anchor
)))
575 (planner-insert-markup (muse-markup-text 'planner-begin-note-details
577 (muse-markup-text 'planner-begin-note-link
))
579 (planner-insert-markup (muse-markup-text 'planner-end-note-link
)
580 (muse-markup-text 'planner-begin-note-categories
))
582 (planner-insert-markup (muse-markup-text 'planner-end-note-categories
)
583 (muse-markup-text 'planner-end-note-details
))
584 (planner-insert-markup (muse-markup-text 'planner-end-note
)))))
586 ;;;_ + helper routine
588 (defun planner-publish-task-status-expand (status)
590 ((string= status
"_") "open")
591 ((string= status
"o") "in-progress")
592 ((string= status
"D") "delegated")
593 ((string= status
"P") "pending")
594 ((string= status
"X") "done")
595 ((string= status
"C") "cancelled")
598 (defun planner-publish-task-status-collapse (status)
600 ((string= status
"open") "_")
601 ((string= status
"in-progress") "o")
602 ((string= status
"delegated") "D")
603 ((string= status
"pending") "P")
604 ((string= status
"done") "X")
605 ((string= status
"cancelled") "C")
608 (defvar planner-sectionalize-delimiter
"*"
609 "The delimiter used to sectionalize.")
611 (defun planner-sectionalize-page ()
612 "A wrapper around `sectionalize' that calls it on the
613 entire page. Uses the `planner-sectionalize-delimiter'
614 variable value. Should not have to call directly. Should be a
615 part of before-publish-hook."
617 (let ((delim planner-sectionalize-delimiter
))
619 (goto-char (point-min))
623 (defvar sectionalize-markup-tagname
624 '(("* Tasks" .
"tasks-section")
625 ("* Notes" .
"notes-section")))
627 (defun sectionalize-markup-tagname (text)
628 "A routine that checks `sectionalize-markup-tagname' for tagname."
629 (let ((tagname (cdr (assoc text sectionalize-markup-tagname
))))
634 (defun sectionalize (delim &optional n
)
635 "A routine that envelops regions of the buffer based on areas
636 bound by the DELIM character.
638 optional parameter N is used *internally* to denote the current
640 (unless n
(setq n
0))
641 (let ((regexp (concat "^\\(\\" delim
"+\\)\\s-+")))
642 (while (and regexp
(re-search-forward regexp nil t
))
643 (let ((depth (length (match-string 1)))
644 (title (buffer-substring (match-end 0) (point-at-eol)))
645 (tagname (sectionalize-markup-tagname
646 (buffer-substring (match-beginning 0) (point-at-eol)))))
648 (delete-region (match-beginning 0) (point-at-eol))
649 (when (not (string= title
""))
650 (insert (format "<%s level=\"%s\"><title>%s</title>"
651 tagname depth title
))
652 (sectionalize delim depth
)
653 (insert (format "</%s>\n" tagname
))))
655 (goto-char (match-beginning 0))))))
656 (if regexp
(goto-char (point-max)))))
658 ;;;_ + Planner Style Definitions
660 (unless (assoc "planner-xml" muse-publishing-styles
)
661 (muse-derive-style "planner-xml" "xml"
662 :regexps
'planner-publish-markup-regexps
663 :functions
'planner-publish-markup-functions
664 :tags
'planner-publish-markup-tags
665 :strings
'planner-xml-markup-strings
666 :before
'planner-publish-prepare-buffer
667 :header
'planner-xml-header
668 :footer
'planner-xml-footer
)
669 (muse-derive-style "planner-html" "html"
670 :regexps
'planner-publish-markup-regexps
671 :functions
'planner-publish-markup-functions
672 :tags
'planner-publish-markup-tags
673 :strings
'planner-html-markup-strings
674 :before
'planner-publish-prepare-buffer
675 :header
'planner-html-header
676 :footer
'planner-html-footer
)
677 (muse-derive-style "planner-xhtml" "xhtml"
678 :regexps
'planner-publish-markup-regexps
679 :functions
'planner-publish-markup-functions
680 :tags
'planner-publish-markup-tags
681 :strings
'planner-html-markup-strings
682 :before
'planner-publish-prepare-buffer
683 :header
'planner-xhtml-header
684 :footer
'planner-xhtml-footer
))
686 (provide 'planner-publish
)
688 ;;; planner-publish.el ends here