tag of mwolson@gnu.org--2006/planner--main--1.0--patch-7
[planner-el.git] / planner-publish.el
blobff0028a9aaa40907487e86615c4a63efb0896baa
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 *NOT* part of GNU Emacs.
15 ;; This program is free software; you can redistribute it and/or
16 ;; modify it under the terms of the GNU General Public License as
17 ;; published by the Free Software Foundation; either version 2, or (at
18 ;; your option) any later version.
20 ;; This program 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 GNU Emacs; 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.
30 ;;; Commentary:
32 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
34 ;;; Introduction
36 ;; Muse Styles for Planner: planner-xml, planner-html, planner-xhtml, etc.
38 ;; Handles publishing of planner files. Works with Muse to generate
39 ;; flexible markup.
41 ;;; History:
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
48 ;;; TODO:
50 ;; add support for various PLANNER specific sections such as Diary,
51 ;; Accomplishments, Timeclock, etc.
53 ;;; Contributors:
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 (require 'planner)
66 (require 'muse-mode)
67 (require 'muse-publish)
68 (require 'muse-html) ;;; allow derive style from "html" and "xhtml"
69 (require 'muse-xml) ;;; allow derive style from "xml"
71 (defgroup planner-publish nil
72 "Options controlling the behavior of PLANNER publishing.
73 See `planner-publish' for more information."
74 :group 'planner)
76 (defcustom planner-publish-markup-regexps
77 '((1275 "^#\\([A-C]\\)\\([0-9]*\\)\\s-*\\([_oXDCP]\\)\\s-*\\(.+\\)" 0 task)
78 (1280 "^\\.#[0-9]+\\s-*" 0 note)
79 (3200 planner-date-regexp 0 link))
80 "List of markup rules for publishing PLANNER.
81 For more on the structure of this list, see `muse-publish-markup-regexps'."
82 :type '(repeat (choice
83 (list :tag "Markup rule"
84 integer
85 (choice regexp symbol)
86 integer
87 (choice string function symbol))
88 function))
89 :group 'muse-html)
91 (defcustom planner-publish-markup-functions
92 '((task . planner-publish-markup-task)
93 (note . planner-publish-markup-note))
94 "An alist of style types to custom functions for that kind of text.
95 For more on the structure of this list, see
96 `muse-publish-markup-functions'."
97 :type '(alist :key-type symbol :value-type function)
98 :group 'planner-publish)
100 (defcustom planner-publish-markup-tags
101 '(("nested-section" t nil planner-publish-nested-section-tag)
102 ("title" t nil planner-publish-title-tag)
103 ("content" t nil planner-publish-content-tag)
104 ("tasks-section" t nil planner-publish-tasks-section-tag)
105 ("notes-section" t nil planner-publish-notes-section-tag)
106 ("notes" nil nil planner-publish-notes-tag)
107 ("past-notes" nil t planner-publish-past-notes-tag)
108 ("task" t t planner-publish-task-tag)
109 ("note" t t planner-publish-note-tag))
110 "A list of tag specifications, for specially marking up PLANNER.
111 See `muse-publish-markup-tags' for more information."
112 :type '(repeat (list (string :tag "Markup tag")
113 (boolean :tag "Expect closing tag" :value t)
114 (boolean :tag "Parse attributes" :value nil)
115 function))
116 :group 'planner-publish)
118 ;;;_ + XML specific customizations
120 (defcustom planner-xml-markup-strings
121 '((planner-begin-nested-section . "<section>")
122 (planner-end-nested-section . "</section>")
123 (planner-begin-title . "<title>")
124 (planner-end-title . "</title>")
125 (planner-begin-content . "")
126 (planner-end-content . "")
127 (planner-begin-body . "")
128 (planner-end-body . "")
129 (planner-begin-task-section . "<tasks>")
130 (planner-end-task-section . "</tasks>")
131 (planner-begin-task-body . "")
132 (planner-end-task-body . "")
133 (planner-begin-note-section . "<notes>")
134 (planner-end-note-section . "</notes>")
135 (planner-begin-task . "<task status=\"%s\" priority=\"%s\">")
136 (planner-end-task . "</task>")
137 (planner-begin-note . "<note number=\"%s\">")
138 (planner-end-note . "</note>")
139 (planner-begin-note-details . "<details><timestamp>%s</timestamp>")
140 (planner-end-note-details . "</details>")
141 (planner-begin-note-link . "<references>")
142 (planner-end-note-link . "</references>")
143 (planner-begin-note-categories . "<categories>")
144 (planner-end-note-categories . "</categories>"))
145 "Strings used for marking up text as XML.
146 These cover the most basic kinds of markup, the handling of which
147 differs little between the various styles.
149 If a markup rule is not found here, `muse-xml-markup-strings' is
150 searched."
151 :type '(alist :key-type symbol :value-type string)
152 :group 'planner-publish)
154 (defcustom planner-xml-header
155 "<?xml version=\"1.0\" encoding=\"<lisp>(muse-xml-encoding)</lisp>\"?>
156 <PLANNER>
157 <pageinfo>
158 <title><lisp>(muse-publishing-directive \"title\")</lisp></title>
159 <author><lisp>(muse-publishing-directive \"author\")</lisp></author>
160 <maintainer><lisp>(muse-style-element :maintainer)</lisp></maintainer>
161 <pubdate><lisp>(muse-publishing-directive \"date\")</lisp></pubdate>
162 </pageinfo>
163 <!-- Page published by Emacs Muse begins here -->\n"
164 "Header used for publishing PLANNER XML files.
165 This may be text or a filename."
166 :type 'string
167 :group 'planner-publish)
169 (defcustom planner-xml-footer "
170 <!-- Page published by Emacs Muse ends here -->
171 </PLANNER>\n"
172 "Footer used for publishing PLANNER XML files.
173 This may be text or a filename."
174 :type 'string
175 :group 'planner-publish)
177 ;;;_ + HTML specific customizations
179 (defcustom planner-html-markup-strings
180 '((planner-begin-nested-section . "<div class=\"section\">")
181 (planner-end-nested-section . "</div>")
182 (planner-begin-title . "<div class=\"title\">")
183 (planner-end-title . "</div>")
184 (planner-begin-content . "<div class=\"content\">")
185 (planner-end-content . "</div>")
186 (planner-begin-body . "<div class=\"body\">")
187 (planner-end-body . "</div>")
188 (planner-begin-task-section . "<div id=\"tasks\" class=\"section\">")
189 (planner-end-task-section . "</div>")
190 (planner-begin-task-body . "<ul class=\"body\">")
191 (planner-end-task-body . "</ul>")
192 (planner-begin-note-section . "<div id=\"notes\" class=\"section\">")
193 (planner-end-note-section . "</div>")
194 (planner-begin-task . "<li class=\"task\"><span class=\"%s\"><span class=\"%s\">%s</span>")
195 (planner-end-task . "</span></li>")
196 (planner-begin-note . "<div class=\"note\"><a name=\"%s\"></a><span class=\"anchor\">%s</span>")
197 (planner-end-note . "</div>")
198 (planner-begin-note-details . "<div class=\"details\"><span class=\"timestamp\">%s</span>")
199 (planner-end-note-details . "</div>")
200 (planner-begin-note-link . " <span class=\"link\">")
201 (planner-end-note-link . "</span>")
202 (planner-begin-note-categories . " <span class=\"categories\">")
203 (planner-end-note-categories . "</span>\n"))
204 "Strings used for marking up text as HTML.
205 These cover the most basic kinds of markup, the handling of which
206 differs little between the various styles.
208 If a markup rule is not found here, `muse-html-markup-strings' is
209 searched."
210 :type '(alist :key-type symbol :value-type string)
211 :group 'planner-publish)
213 (defcustom planner-html-style-sheet
214 "<style type=\"text/css\">
215 body {
216 background: white; color: black;
217 margin-left: 3%; margin-right: 3%;
220 p { margin-top: 3px; margin-bottom: 3px; }
221 p.verse { margin-left: 3% }
223 h1,h2,h3,h4,h5 { margin:0; padding:0; }
225 h1 { padding: 10px; margin-bottom: 10px; }
227 table.muse-table { margin: 0; font-size: 11px;
228 border-collapse: collapse;
229 background: #e2effa;
230 border: 1px solid #aadeed; }
232 table.muse-table tbody td { border: 1px solid #ccdeed; }
234 .example { margin-left: 5px; padding: 3px;
235 background: #fffffc;
236 border: 1px solid #ccdeed; }
238 /* enabled with planner-sectionalize.el */
239 .section { margin: 0; padding: 10px;
240 margin-bottom: 15px;
241 font-size: 12px; }
243 .section .section { margin: 0; margin-left: 5px;
244 font-size: 11px; }
246 .title { margin: 0; padding; 0 }
248 .section .title { font-size: 14px; }
249 .section .section .title { font-size: 12px; }
250 .section .section .section .title { font-size: 11px; }
252 /* Tasks section */
253 .task .A { color: red }
254 .task .B { color: green }
255 .task .C { color: navy }
256 .task .done { color: gray; text-decoration: line-through; }
257 .task .cancelled { color: gray; text-decoration: italic; }
259 </style>"
260 "Store your stylesheet definitions here. The provided default
261 is for reference only. You definitely want to customize this for
262 your particular needs & wants. This is used in
263 `planner-html-header' and `planner-xhtml-header'. Refer to
264 `muse-html-style-sheet' for details on usage. You may simply
265 override the above by specifying an explicit link to a CSS file."
266 :type 'string
267 :group 'planner-publish)
269 (defcustom planner-html-header
270 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">
271 <html>
272 <head>
273 <title><lisp>
274 (concat (muse-publishing-directive \"title\")
275 (let ((author (muse-publishing-directive \"author\")))
276 (if (not (string= author (user-full-name)))
277 (concat \" (by \" author \")\"))))</lisp></title>
278 <meta name=\"generator\" content=\"muse.el\">
279 <meta http-equiv=\"<lisp>muse-html-meta-http-equiv</lisp>\"
280 content=\"<lisp>muse-html-meta-content-type</lisp>\">
281 <lisp>
282 (let ((maintainer (muse-style-element :maintainer)))
283 (when maintainer
284 (concat \"<link rev=\\\"made\\\" href=\\\"\" maintainer \"\\\">\")))
285 </lisp>
286 <lisp>planner-html-style-sheet</lisp>
287 </head>
288 <body>
289 <div id=\"content\">
290 <h1><span><lisp>
291 (concat (muse-publishing-directive \"title\")
292 (let ((author (muse-publishing-directive \"author\")))
293 (if (not (string= author (user-full-name)))
294 (concat \" (by \" author \")\"))))</lisp></span></h1>
295 <div id=\"inner-header\">
296 <lisp>planner-html-inner-header</lisp>
297 </div>
298 <div id=\"muse-sections\">
299 <!-- Page published by Emacs Muse begins here -->\n"
300 "Header used for publishing PLANNER HTML files.
301 This may be text or a filename."
302 :type 'string
303 :group 'planner-publish)
305 (defcustom planner-html-footer "
306 <!-- Page published by Emacs Muse ends here -->
307 </div>
308 <div id=\"inner-footer\">
309 <lisp>planner-html-inner-footer</lisp>
310 </div>
311 </div>
312 </body>
313 </html>\n"
314 "Footer used for publishing PLANNER HTML files.
315 This may be text or a filename."
316 :type 'string
317 :group 'planner-publish)
319 (defcustom planner-xhtml-header
320 "<?xml version=\"1.0\" encoding=\"<lisp>
321 (muse-html-encoding)</lisp>\"?>
322 <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
323 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
324 <html xmlns=\"http://www.w3.org/1999/xhtml\">
325 <head>
326 <title><lisp>
327 (concat (muse-publishing-directive \"title\")
328 (let ((author (muse-publishing-directive \"author\")))
329 (if (not (string= author (user-full-name)))
330 (concat \" (by \" author \")\"))))</lisp></title>
331 <meta name=\"generator\" content=\"muse.el\" />
332 <meta http-equiv=\"<lisp>muse-html-meta-http-equiv</lisp>\"
333 content=\"<lisp>muse-html-meta-content-type</lisp>\" />
334 <lisp>
335 (let ((maintainer (muse-style-element :maintainer)))
336 (when maintainer
337 (concat \"<link rev=\\\"made\\\" href=\\\"\" maintainer \"\\\" />\")))
338 </lisp>
339 <lisp>planner-html-style-sheet</lisp>
340 </head>
341 <body>
342 <div id=\"content\">
343 <h1><span><lisp>
344 (concat (muse-publishing-directive \"title\")
345 (let ((author (muse-publishing-directive \"author\")))
346 (if (not (string= author (user-full-name)))
347 (concat \" (by \" author \")\"))))</lisp></span></h1>
348 <div id=\"inner-header\">
349 <lisp>planner-html-inner-header</lisp>
350 </div>
351 <div id=\"muse-sections\">
352 <!-- Page published by Emacs Muse begins here -->\n"
353 "Header used for publishing PLANNER XHTML files.
354 This may be text or a filename."
355 :type 'string
356 :group 'planner-publish)
358 (defcustom planner-xhtml-footer "
359 <!-- Page published by Emacs Muse ends here -->
360 </div>
361 <div id=\"inner-footer\">
362 <lisp>planner-html-inner-footer</lisp>
363 </div>
364 </div>
365 </body>
366 </html>\n"
367 "Footer used for publishing PLANNER XHTML files.
368 This may be text or a filename."
369 :type 'string
370 :group 'planner-publish)
372 (defcustom planner-html-inner-header ""
373 "Extra header section that can be embedded w/in existing
374 `planner-html-header'. This may be text or a filename."
375 :type 'string
376 :group 'planner-publish)
378 (defcustom planner-html-inner-footer ""
379 "Extra footer section that can be embedded w/in existing
380 `planner-html-footer'. This may be text or a filename."
381 :type 'string
382 :group 'planner-publish)
384 ;;;_ + Publishing hooks
386 (defun planner-publish-prepare-buffer ()
387 "Return nil to allow hook to continue"
388 (planner-sectionalize-page)
389 nil)
391 ;;;_ + Markup
393 (defun planner-publish-markup-task ()
394 "Replace tasks with XML representation of task data."
395 (save-restriction
396 (narrow-to-region
397 (planner-line-beginning-position)
398 (planner-line-end-position))
399 (muse-publish-escape-specials (point-min) (point-max))
400 (let ((info (planner-current-task-info)))
401 (delete-region (point-min) (point-max))
402 (forward-line 1)
403 (insert
404 (format (concat "<task id=\"%s\" priority=\"%s\" status=\"%s\""
405 " link=\"%s\" plan=\"%s\" date=\"%s\">")
406 (or (planner-task-number info) "")
407 (or (planner-task-priority info) "")
408 (or (planner-publish-task-status-expand
409 (planner-task-status info)) "")
410 (or (planner-task-link-text info) "")
411 (or (planner-task-plan info) "")
412 (or (planner-task-date info) ""))
413 (planner-task-description info) ; mark this area read only
414 "</task>"))))
416 (defun planner-publish-markup-note ()
417 "Replace note with XML representation of note data. Borrowed
418 heavily from Sacha's personal configs."
419 (save-restriction
420 (narrow-to-region
421 (save-excursion (beginning-of-line) (point))
422 (or (save-excursion
423 (and (re-search-forward "^\\(\\.#\\|* \\|</notes-section>\\)" nil t)
424 (match-beginning 0)))
425 (point-max)))
426 (let ((info (planner-current-note-info t)))
427 (delete-region (point-min) (point-max))
428 (insert (format (concat "<note anchor=\"%s\" timestamp=\"%s\""
429 " link=\"%s\" categories=\"%s\">")
430 (planner-note-anchor info)
431 (or (planner-note-timestamp info) "")
432 (or (planner-note-link info) "")
433 (or (planner-note-link-text info) ""))
434 "<title>" (planner-note-title info) "</title>\n"
435 "<content>\n" (planner-note-body info) "\n\n</content>\n"
436 "</note>\n"))))
439 ;;;_ + Tags
441 (defun planner-insert-markup (&rest args)
442 (if (fboundp 'muse-insert-markup)
443 (apply 'muse-insert-markup args)
444 (apply 'insert args)))
446 (defun planner-publish-nested-section-tag (beg end)
447 "Generated by `sectionalize', the nested section tag now takes
448 in TITLE and LEVEL attributes. Do not get this confused with
449 MUSE specific `section', `subsection', etc. tags. The MUSE
450 specific sections are more like title/heading tags than this
451 nested section block version."
452 (save-excursion
453 (goto-char beg)
454 (planner-insert-markup (muse-markup-text 'planner-begin-nested-section))
455 (goto-char end)
456 (planner-insert-markup (muse-markup-text 'planner-end-nested-section))))
458 (defun planner-publish-title-tag (beg end)
459 (save-excursion
460 (goto-char beg)
461 (planner-insert-markup (muse-markup-text 'planner-begin-title))
462 (goto-char end)
463 (planner-insert-markup (muse-markup-text 'planner-end-title))))
465 (defun planner-publish-content-tag (beg end)
466 (save-excursion
467 (goto-char end)
468 (planner-insert-markup (muse-markup-text 'planner-end-content))
469 (goto-char beg)
470 (planner-insert-markup (muse-markup-text 'planner-begin-content))))
472 (defun planner-publish-tasks-section-tag (beg end)
473 (save-excursion
474 (goto-char beg)
475 (planner-insert-markup (muse-markup-text 'planner-begin-task-section))
476 (forward-line 1)
477 (planner-insert-markup (muse-markup-text 'planner-begin-task-body))
478 (goto-char end)
479 (planner-insert-markup (muse-markup-text 'planner-end-task-body))
480 (planner-insert-markup (muse-markup-text 'planner-end-task-section))))
482 (defun planner-publish-task-tag (beg end attrs)
483 (save-excursion
484 (let ((number (cdr (assoc "id" attrs)))
485 (status (cdr (assoc "status" attrs)))
486 (priority (cdr (assoc "priority" attrs)))
487 (link (cdr (assoc "link" attrs)))
488 (plan (cdr (assoc "plan" attrs)))
489 (date (cdr (assoc "date" attrs))))
490 (goto-char beg)
491 (planner-insert-markup
492 (muse-markup-text 'planner-begin-task
493 status
494 priority
495 (concat priority number " "
496 (planner-publish-task-status-collapse status)
497 " ")))
498 (goto-char end)
499 (when link
500 (insert " (" (planner-make-link link) ")"))
501 (planner-insert-markup (muse-markup-text 'planner-end-task)))))
503 (defun planner-publish-notes-section-tag (beg end)
504 "Replace the region BEG to END with the notes for this page."
505 (save-excursion
506 (planner-insert-markup (muse-markup-text 'planner-begin-note-section))
507 (forward-line 1)
508 (planner-insert-markup (muse-markup-text 'planner-begin-body))
509 (goto-char end)
510 (planner-insert-markup (muse-markup-text 'planner-end-body))
511 (planner-insert-markup (muse-markup-text 'planner-end-note-section))))
513 (defun planner-publish-notes-tag (beg end)
514 "Replace the region BEG to END with an index of the notes for this page."
515 (delete-region beg end)
516 (insert "\n")
517 (mapcar
518 (lambda (item)
519 (insert (format " - [[%s%s][%s]]\n"
520 (planner-page-name)
521 (car item)
522 (planner-remove-links (cdr item)))))
523 (save-excursion
524 (find-file muse-publishing-current-file)
525 (planner-notes-get-headlines)))
526 (insert "\n"))
528 (defun planner-publish-past-notes-tag (beg end attrs)
529 "Replace the region BEG to END with an index of past notes.
530 If ATTRS is non-nil, it is an alist containing values for
531 DIRECTORY and START."
532 (let ((files (save-excursion
533 (find-file muse-publishing-current-file)
534 (planner-get-day-pages nil nil t)))
535 (earliest (cdr (assoc "start" attrs))))
536 (while files
537 (when (or (null earliest)
538 (not (string-lessp (caar files) earliest)))
539 (let ((title-lines (list t)))
540 (with-temp-buffer
541 (insert-file-contents (cdar files))
542 (while (re-search-forward "^\\.#\\([0-9]+\\)\\s-+\\(.+\\)" nil t)
543 (nconc title-lines (list (cons (match-string 1)
544 (match-string 2))))))
545 (setq title-lines (cdr title-lines))
546 (when title-lines
547 (insert (planner-make-link (planner-page-name (caar files)))
548 " ::\n")
549 (planner-insert-markup " <dl class=\"contents\">\n")
550 (while title-lines
551 (planner-insert-markup " <dt class=\"contents\">")
552 (insert (format "[[%s#%s][%s]]"
553 (planner-page-name (caar files))
554 (caar title-lines) (cdar title-lines)))
555 (planner-insert-markup "</dt>\n")
556 (setq title-lines (cdr title-lines)))
557 (planner-insert-markup " </dl>\n\n"))))
558 (setq files (cdr files)))))
560 (defun planner-publish-note-tag (beg end attrs)
561 (save-excursion
562 (let ((anchor (or (cdr (assoc "anchor" attrs)) ""))
563 (timestamp (or (cdr (assoc "timestamp" attrs)) ""))
564 (link (or (cdr (assoc "link" attrs)) ""))
565 (categories (or (cdr (assoc "categories" attrs)) "")))
567 (setq categories "") ; categories broken for now
568 (goto-char beg)
569 (planner-insert-markup (muse-markup-text 'planner-begin-note
570 anchor
571 (concat "#" anchor)))
572 (goto-char end)
573 (planner-insert-markup (muse-markup-text 'planner-begin-note-details
574 timestamp)
575 (muse-markup-text 'planner-begin-note-link))
576 (insert link)
577 (planner-insert-markup (muse-markup-text 'planner-end-note-link)
578 (muse-markup-text 'planner-begin-note-categories))
579 (insert categories)
580 (planner-insert-markup (muse-markup-text 'planner-end-note-categories)
581 (muse-markup-text 'planner-end-note-details))
582 (planner-insert-markup (muse-markup-text 'planner-end-note)))))
584 ;;;_ + helper routine
586 (defun planner-publish-task-status-expand (status)
587 (cond
588 ((string= status "_") "open")
589 ((string= status "o") "in-progress")
590 ((string= status "D") "delegated")
591 ((string= status "P") "pending")
592 ((string= status "X") "done")
593 ((string= status "C") "cancelled")
594 (t "unknown")))
596 (defun planner-publish-task-status-collapse (status)
597 (cond
598 ((string= status "open") "_")
599 ((string= status "in-progress") "o")
600 ((string= status "delegated") "D")
601 ((string= status "pending") "P")
602 ((string= status "done") "X")
603 ((string= status "cancelled") "C")
604 (t "?")))
606 (defvar planner-sectionalize-delimiter "*"
607 "The delimiter used to sectionalize.")
609 (defun planner-sectionalize-page ()
610 "A wrapper around `sectionalize' that calls it on the
611 entire page. Uses the `planner-sectionalize-delimiter'
612 variable value. Should not have to call directly. Should be a
613 part of before-publish-hook."
614 (interactive)
615 (let ((delim planner-sectionalize-delimiter))
616 (save-excursion
617 (goto-char (point-min))
618 (sectionalize delim)
619 t)))
621 (defvar sectionalize-markup-tagname
622 '(("* Tasks" . "tasks-section")
623 ("* Notes" . "notes-section")))
625 (defun sectionalize-markup-tagname (text)
626 "A routine that checks `sectionalize-markup-tagname' for tagname."
627 (let ((tagname (cdr (assoc text sectionalize-markup-tagname))))
628 (if tagname
629 tagname
630 "nested-section")))
632 (defun sectionalize (delim &optional n)
633 "A routine that envelops regions of the buffer based on areas
634 bound by the DELIM character.
636 optional parameter N is used *internally* to denote the current
637 recursion depth."
638 (unless n (setq n 0))
639 (let ((regexp (concat "^\\(\\" delim "+\\)\\s-+")))
640 (while (and regexp (re-search-forward regexp nil t))
641 (let ((depth (length (match-string 1)))
642 (title (buffer-substring (match-end 0) (point-at-eol)))
643 (tagname (sectionalize-markup-tagname
644 (buffer-substring (match-beginning 0) (point-at-eol)))))
645 (cond ((> depth n)
646 (delete-region (match-beginning 0) (point-at-eol))
647 (when (not (string= title ""))
648 (insert (format "<%s level=\"%s\"><title>%s</title>"
649 tagname depth title))
650 (sectionalize delim depth)
651 (insert (format "</%s>\n" tagname))))
652 (t (setq regexp nil)
653 (goto-char (match-beginning 0))))))
654 (if regexp (goto-char (point-max)))))
656 ;;;_ + Planner Style Definitions
658 (unless (assoc "planner-xml" muse-publishing-styles)
659 (muse-derive-style "planner-xml" "xml"
660 :regexps 'planner-publish-markup-regexps
661 :functions 'planner-publish-markup-functions
662 :tags 'planner-publish-markup-tags
663 :strings 'planner-xml-markup-strings
664 :before 'planner-publish-prepare-buffer
665 :header 'planner-xml-header
666 :footer 'planner-xml-footer)
667 (muse-derive-style "planner-html" "html"
668 :regexps 'planner-publish-markup-regexps
669 :functions 'planner-publish-markup-functions
670 :tags 'planner-publish-markup-tags
671 :strings 'planner-html-markup-strings
672 :before 'planner-publish-prepare-buffer
673 :header 'planner-html-header
674 :footer 'planner-html-footer)
675 (muse-derive-style "planner-xhtml" "xhtml"
676 :regexps 'planner-publish-markup-regexps
677 :functions 'planner-publish-markup-functions
678 :tags 'planner-publish-markup-tags
679 :strings 'planner-html-markup-strings
680 :before 'planner-publish-prepare-buffer
681 :header 'planner-xhtml-header
682 :footer 'planner-xhtml-footer))
684 (provide 'planner-publish)
686 ;;; planner-publish.el ends here