Merged from mwolson@gnu.org--2006-muse-el (patch 92)
[muse-el.git] / lisp / muse-journal.el
blob0611927b1b4e323c61bee5ba07335d8a5951f0c9
1 ;;; muse-journal.el --- keep and publish a journal
3 ;; Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
5 ;; This file is part of Emacs Muse. It is not part of GNU Emacs.
7 ;; Emacs Muse is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 2, or (at your
10 ;; option) any later version.
12 ;; Emacs Muse is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with Emacs Muse; see the file COPYING. If not, write to the
19 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 ;; Boston, MA 02110-1301, USA.
22 ;;; Commentary:
24 ;; The module facilitates the keeping and publication of a journal.
25 ;; When publishing to HTML, it assumes the form of a web log, or blog.
27 ;; The input format for each entry is as follows:
29 ;; * 20040317: Title of entry
31 ;; Text for the entry.
33 ;; <qotd>
34 ;; "You know who you are. It comes down to a simple gut check: You
35 ;; either love what you do or you don't. Period." -- P. Bronson
36 ;; </qotd>
38 ;; The "qotd", or Quote of the Day, is entirely optional. When
39 ;; generated to HTML, this entry is rendered as:
41 ;; <div class="entry">
42 ;; <div class="entry-qotd">
43 ;; <h3>Quote of the Day:</h3>
44 ;; <p>"You know who you are. It comes down to a simple gut
45 ;; check: You either love what you do or you don't. Period."
46 ;; -- P. Bronson</p>
47 ;; </div>
48 ;; <div class="entry-body">
49 ;; <div class="entry-head">
50 ;; <div class="entry-date">
51 ;; <span class="date">March 17, 2004</span>
52 ;; </div>
53 ;; <div class="entry-title">
54 ;; <h2>Title of entry</h2>
55 ;; </div>
56 ;; </div>
57 ;; <div class="entry-text">
58 ;; <p>Text for the entry.</p>
59 ;; </div>
60 ;; </div>
61 ;; </div>
63 ;; The plurality of "div" tags makes it possible to display the
64 ;; entries in any form you wish, using a CSS style.
66 ;; Also, an .RDF file can be generated from your journal by publishing
67 ;; it with the "rdf" style. It uses the first two sentences of the
68 ;; first paragraph of each entry as its "description", and
69 ;; autogenerates tags for linking to the various entries.
71 ;;; Contributors:
73 ;; René Stadler (mail AT renestadler DOT de) provided a patch that
74 ;; causes dates in RSS feeds to be generated in a format that RSS
75 ;; readers can parse.
77 ;;; Code:
79 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
81 ;; Muse Journal Publishing
83 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
85 (require 'muse-publish)
86 (require 'muse-html)
87 (require 'muse-latex)
88 (require 'muse-book)
90 (defgroup muse-journal nil
91 "Rules for transforming a journal into its final form."
92 :group 'muse-publish)
94 (defcustom muse-journal-heading-regexp
95 "\\(?:\\([0-9]+\\)\\(?:: \\)?\\)?\\(.+?\\)?"
96 "A regexp that matches a journal heading.
97 Paren group 1 is the ISO date, group 2 is the optional category,
98 and group 3 is the optional heading for the entry."
99 :type 'regexp
100 :group 'muse-journal)
102 (defcustom muse-journal-date-format "%a, %e %b %Y"
103 "Date format to use for journal entries."
104 :type 'string
105 :group 'muse-journal)
107 (defcustom muse-journal-html-heading-regexp
108 (concat "^<h2[^>\n]*>" muse-journal-heading-regexp "</h2>$")
109 "A regexp that matches a journal heading from an HTML document.
110 Paren group 1 is the ISO date, group 2 is the optional category,
111 and group 3 is the optional heading for the entry."
112 :type 'regexp
113 :group 'muse-journal)
115 (defcustom muse-journal-rss-heading-regexp
116 (concat "^\\* " muse-journal-heading-regexp "$")
117 "A regexp that matches a journal heading from an HTML document.
118 Paren group 1 is the ISO date, group 2 is the optional category,
119 and group 3 is the optional heading for the entry."
120 :type 'regexp
121 :group 'muse-journal)
123 (defcustom muse-journal-html-entry-template
124 "<div class=\"entry\">
125 <a name=\"%anchor%\" style=\"text-decoration: none\">&nbsp;</a>
126 <div class=\"entry-body\">
127 <div class=\"entry-head\">
128 <div class=\"entry-date\">
129 <span class=\"date\">%date%</span>
130 </div>
131 <div class=\"entry-title\">
132 <h2>%title%</h2>
133 </div>
134 </div>
135 <div class=\"entry-text\">
136 <div class=\"entry-qotd\">
137 <p>%qotd%</p>
138 </div>
139 %text%
140 </div>
141 </div>
142 </div>\n\n"
143 "Template used to publish individual journal entries as HTML."
144 :type 'string
145 :group 'muse-journal)
147 (defcustom muse-journal-latex-section
148 "\\section*{%title% \\hfill {\\normalsize %date%}}
149 \\addcontentsline{toc}{chapter}{%title%}"
150 "Template used to publish a LaTeX section."
151 :type 'string
152 :group 'muse-journal)
154 (defcustom muse-journal-latex-subsection
155 "\\subsection*{%title%}
156 \\addcontentsline{toc}{section}{%title%}"
157 "Template used to publish a LaTeX subsection."
158 :type 'string
159 :group 'muse-journal)
161 (defcustom muse-journal-latex-markup-tags
162 '(("qotd" t nil muse-journal-latex-qotd-tag))
163 "A list of tag specifications, for specially marking up LaTeX.
164 See `muse-publish-markup-tags' for more info."
165 :type '(repeat (list (string :tag "Markup tag")
166 (boolean :tag "Expect closing tag" :value t)
167 (boolean :tag "Parse attributes" :value nil)
168 function))
169 :group 'muse-journal)
171 ;; FIXME: This doesn't appear to be used.
172 (defun muse-journal-generate-pages ()
173 (let ((output-dir (muse-style-element :path)))
174 (goto-char (point-min))
175 (while (re-search-forward muse-journal-heading-regexp nil t)
176 (let* ((date (match-string 1))
177 (category (match-string 1))
178 (category-file (concat output-dir category "/index.html"))
179 (heading (match-string 1)))
180 t))))
182 (defcustom muse-journal-rdf-extension ".rdf"
183 "Default file extension for publishing RDF (RSS 1.0) files."
184 :type 'string
185 :group 'muse-journal)
187 (defcustom muse-journal-rdf-base-url ""
188 "The base URL of the website referenced by the RDF file."
189 :type 'string
190 :group 'muse-journal)
192 (defcustom muse-journal-rdf-header
193 "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"
194 xmlns=\"http://purl.org/rss/1.0/\"
195 xmlns:dc=\"http://purl.org/dc/elements/1.1/\">
196 <channel rdf:about=\"<lisp>(concat (muse-style-element :base-url)
197 (muse-publish-link-name))</lisp>\">
198 <title><lisp>(muse-publishing-directive \"title\")</lisp></title>
199 <link><lisp>(concat (muse-style-element :base-url)
200 (concat (muse-page-name)
201 muse-html-extension))</lisp></link>
202 <description><lisp>(muse-publishing-directive \"desc\")</lisp></description>
203 <items>
204 <rdf:Seq>
205 <rdf:li resource=\"<lisp>
206 (concat (muse-style-element :base-url)
207 (concat (muse-page-name)
208 muse-html-extension))</lisp>\"/>
209 </rdf:Seq>
210 </items>
211 </channel>\n"
212 "Header used for publishing RDF (RSS 1.0) files.
213 This may be text or a filename."
214 :type 'string
215 :group 'muse-journal)
217 (defcustom muse-journal-rdf-footer
218 "</rdf:RDF>\n"
219 "Footer used for publishing RDF (RSS 1.0) files.
220 This may be text or a filename."
221 :type 'string
222 :group 'muse-journal)
224 (defcustom muse-journal-rdf-date-format
225 "%Y-%m-%dT%H:%M:%S"
226 "Date format to use for RDF entries."
227 :type 'string
228 :group 'muse-journal)
230 (defcustom muse-journal-rdf-entry-template
231 " <item rdf:about=\"%link%#%anchor%\">
232 <title>%title%</title>
233 <description>
234 %desc%
235 </description>
236 <link>%link%#%anchor%</link>
237 <dc:date>%date%</dc:date>
238 <dc:creator>%maintainer%</dc:creator>
239 </item>\n"
240 "Template used to publish individual journal entries as RDF."
241 :type 'string
242 :group 'muse-journal)
244 (defcustom muse-journal-rdf-summarize-entries t
245 "If non-nil, include only summaries in the RDF file, not the full data."
246 :type 'boolean
247 :group 'muse-journal)
249 (defcustom muse-journal-rss-extension ".xml"
250 "Default file extension for publishing RSS 2.0 files."
251 :type 'string
252 :group 'muse-journal)
254 (defcustom muse-journal-rss-base-url ""
255 "The base URL of the website referenced by the RSS file."
256 :type 'string
257 :group 'muse-journal)
259 (defcustom muse-journal-rss-header
260 "<\?xml version=\"1.0\" encoding=\"<lisp>
261 (muse-html-encoding)</lisp>\"?>
262 <rss version=\"2.0\">
263 <channel>
264 <title><lisp>(muse-publishing-directive \"title\")</lisp></title>
265 <link><lisp>(concat (muse-style-element :base-url)
266 (concat (muse-page-name)
267 muse-html-extension))</lisp></link>
268 <description><lisp>(muse-publishing-directive \"desc\")</lisp></description>
269 <language>en-us</language>
270 <generator>Emacs Muse</generator>"
271 "Header used for publishing RSS 2.0 files. This may be text or a filename."
272 :type 'string
273 :group 'muse-journal)
275 (defcustom muse-journal-rss-footer
276 " </channel>
277 </rss>\n"
278 "Footer used for publishing RSS 2.0 files. This may be text or a filename."
279 :type 'string
280 :group 'muse-journal)
282 (defcustom muse-journal-rss-date-format
283 "%a, %d %b %Y %H:%M:%S %Z"
284 "Date format to use for RSS 2.0 entries."
285 :type 'string
286 :group 'muse-journal)
288 (defcustom muse-journal-rss-entry-template
289 " <item>
290 <title>%title%</title>
291 <link>%link%#%anchor%</link>
292 <description>%desc%</description>
293 <author><lisp>(muse-publishing-directive \"author\")</lisp></author>
294 <pubDate>%date%</pubDate>
295 <guid>%link%#%anchor%</guid>
296 %enclosure%
297 </item>\n"
298 "Template used to publish individual journal entries as RSS 2.0."
299 :type 'string
300 :group 'muse-journal)
302 (defcustom muse-journal-rss-enclosure-types-alist
303 '(("mp3" . "audio/mpeg"))
304 "File types that are accepted as RSS enclosures.
305 This is an alist that maps file extension to content type.
306 Useful for podcasting."
307 :type '(alist :key-type string :value-type string)
308 :group 'muse-journal)
310 (defcustom muse-journal-rss-summarize-entries nil
311 "If non-nil, include only summaries in the RSS file, not the full data.
312 Many RSS subscribers find this annoying."
313 :type 'boolean
314 :group 'muse-journal)
316 (defcustom muse-journal-rss-markup-regexps
317 '((10000 muse-explicit-link-regexp 0 "\\2"))
318 "List of markup rules for publishing a Muse journal page to RSS 2.0.
319 For more information on the structure of this list, see
320 `muse-publish-markup-regexps'."
321 :type '(repeat (choice
322 (list :tag "Markup rule"
323 integer
324 (choice regexp symbol)
325 integer
326 (choice string function symbol))
327 function))
328 :group 'muse-journal)
330 (defcustom muse-journal-rss-markup-functions
331 '((email . ignore)
332 (link . ignore)
333 (url . ignore))
334 "An alist of style types to custom functions for that kind of text.
335 For more on the structure of this list, see
336 `muse-publish-markup-functions'."
337 :type '(alist :key-type symbol :value-type function)
338 :group 'muse-journal)
340 (defun muse-journal-anchorize-title (title)
341 (save-match-data
342 (if (string-match "(" title)
343 (setq title (substring title 0 (match-beginning 0))))
344 (if (string-match "<[^>]+>" title)
345 (setq title (replace-match "" nil nil title)))
346 (downcase (muse-replace-regexp-in-string "[^a-zA-Z0-9_]" "" title))))
348 (defun muse-journal-sort-entries (&optional direction)
349 (interactive "P")
350 (sort-subr
351 direction
352 (function
353 (lambda ()
354 (if (re-search-forward "^\\* [0-9]+" nil t)
355 (goto-char (match-beginning 0))
356 (goto-char (point-max)))))
357 (function
358 (lambda ()
359 (if (re-search-forward "^\\* [0-9]+" nil t)
360 (goto-char (1- (match-beginning 0)))
361 (goto-char (point-max)))))
362 (function
363 (lambda ()
364 (forward-char 2)))
365 (function
366 (lambda ()
367 (end-of-line)))))
369 (defun muse-journal-html-munge-buffer ()
370 (goto-char (point-min))
371 (let ((heading-regexp muse-journal-html-heading-regexp)
372 (inhibit-read-only t))
373 (while (re-search-forward heading-regexp nil t)
374 (let* ((date (match-string 1))
375 (orig-date date)
376 (title (match-string 2))
377 (clean-title title)
378 datestamp qotd text)
379 (delete-region (match-beginning 0) (match-end 0))
380 (if clean-title
381 (save-match-data
382 (while (string-match "\\(^<[^>]+>\\|<[^>]+>$\\)" clean-title)
383 (setq clean-title (replace-match "" nil nil clean-title)))))
384 (save-match-data
385 (when (and date
386 (string-match
387 (concat "\\`\\([1-9][0-9][0-9][0-9]\\)[./]?"
388 "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date))
389 (setq datestamp
390 (encode-time
391 0 0 0
392 (string-to-number (match-string 3 date))
393 (string-to-number (match-string 2 date))
394 (string-to-number (match-string 1 date))
395 (current-time-zone))
396 date (concat (format-time-string
397 muse-journal-date-format datestamp)
398 (substring date (match-end 0))))))
399 (save-restriction
400 (narrow-to-region
401 (point) (if (re-search-forward
402 (concat "\\(^<hr>$\\|"
403 heading-regexp "\\)") nil t)
404 (match-beginning 0)
405 (point-max)))
406 (goto-char (point-max))
407 (while (and (not (bobp))
408 (eq ?\ (char-syntax (char-before))))
409 (delete-char -1))
410 (goto-char (point-min))
411 (while (and (not (eobp))
412 (eq ?\ (char-syntax (char-after))))
413 (delete-char 1))
414 (save-excursion
415 (when (search-forward "<qotd>" nil t)
416 (let ((tag-beg (match-beginning 0))
417 (beg (match-end 0)))
418 (re-search-forward "</qotd>\n*")
419 (setq qotd (buffer-substring-no-properties
420 beg (match-beginning 0)))
421 (delete-region tag-beg (match-end 0)))))
422 (setq text (buffer-string))
423 (delete-region (point-min) (point-max))
424 (let ((entry muse-journal-html-entry-template))
425 (muse-insert-markup entry)
426 (goto-char (point-min))
427 (while (search-forward "%date%" nil t)
428 (replace-match (or date "") nil t))
429 (goto-char (point-min))
430 (while (search-forward "%title%" nil t)
431 (replace-match (or title "&nbsp;") nil t))
432 (goto-char (point-min))
433 (while (search-forward "%anchor%" nil t)
434 (replace-match (muse-journal-anchorize-title
435 (or clean-title orig-date))
436 nil t))
437 (goto-char (point-min))
438 (while (search-forward "%qotd%" nil t)
439 (replace-match (or qotd "") nil t))
440 (goto-char (point-min))
441 (while (search-forward "%text%" nil t)
442 (replace-match text nil t))
443 (when (null qotd)
444 (goto-char (point-min))
445 (when (search-forward "<div class=\"entry-qotd\">" nil t)
446 (let ((beg (match-beginning 0)))
447 (re-search-forward "</div>\n*" nil t)
448 (delete-region beg (point)))))))))))
450 (defun muse-journal-latex-munge-buffer ()
451 (goto-char (point-min))
452 (let ((heading-regexp
453 (concat "^" (regexp-quote (muse-markup-text 'section))
454 muse-journal-heading-regexp
455 (regexp-quote (muse-markup-text 'section-end)) "$"))
456 (inhibit-read-only t))
457 (when (re-search-forward heading-regexp nil t)
458 (goto-char (match-beginning 0))
459 (sort-subr nil
460 (function
461 (lambda ()
462 (if (re-search-forward heading-regexp nil t)
463 (goto-char (match-beginning 0))
464 (goto-char (point-max)))))
465 (function
466 (lambda ()
467 (if (re-search-forward heading-regexp nil t)
468 (goto-char (1- (match-beginning 0)))
469 (goto-char (point-max)))))
470 (function
471 (lambda ()
472 (forward-char 2)))
473 (function
474 (lambda ()
475 (end-of-line)))))
476 (while (re-search-forward heading-regexp nil t)
477 (let ((date (match-string 1))
478 (title (match-string 2))
479 ;; FIXME: Nothing is done with qotd
480 qotd section)
481 (save-match-data
482 (when (and date
483 (string-match
484 (concat "\\([1-9][0-9][0-9][0-9]\\)[./]?"
485 "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date))
486 (setq date (encode-time
487 0 0 0
488 (string-to-number (match-string 3 date))
489 (string-to-number (match-string 2 date))
490 (string-to-number (match-string 1 date))
491 (current-time-zone))
492 date (format-time-string
493 muse-journal-date-format date))))
494 (save-restriction
495 (narrow-to-region (match-beginning 0) (match-end 0))
496 (delete-region (point-min) (point-max))
497 (muse-insert-markup muse-journal-latex-section)
498 (goto-char (point-min))
499 (while (search-forward "%title%" nil t)
500 (replace-match (or title "Untitled") nil t))
501 (goto-char (point-min))
502 (while (search-forward "%date%" nil t)
503 (replace-match (or date "") nil t))))))
504 (goto-char (point-min))
505 (let ((subheading-regexp
506 (concat "^" (regexp-quote (muse-markup-text 'subsection))
507 "\\([^\n}]+\\)"
508 (regexp-quote (muse-markup-text 'subsection-end)) "$"))
509 (inhibit-read-only t))
510 (while (re-search-forward subheading-regexp nil t)
511 (let ((title (match-string 1)))
512 (save-restriction
513 (narrow-to-region (match-beginning 0) (match-end 0))
514 (delete-region (point-min) (point-max))
515 (muse-insert-markup muse-journal-latex-subsection)
516 (goto-char (point-min))
517 (while (search-forward "%title%" nil t)
518 (replace-match title nil t)))))))
520 (defun muse-journal-latex-qotd-tag (beg end)
521 (goto-char beg)
522 (muse-insert-markup (muse-markup-text 'begin-quote))
523 (goto-char end)
524 (muse-insert-markup (muse-markup-text 'end-quote)))
526 (defun muse-journal-rss-munge-buffer ()
527 (goto-char (point-min))
528 (let ((heading-regexp muse-journal-rss-heading-regexp)
529 (inhibit-read-only t))
530 (while (re-search-forward heading-regexp nil t)
531 (let* ((date (match-string 1))
532 (orig-date date)
533 (title (match-string 2))
534 ;; FIXME: Nothing is done with qotd
535 enclosure qotd desc)
536 (if title
537 (save-match-data
538 (if (string-match muse-explicit-link-regexp title)
539 (setq enclosure (muse-get-link title)
540 title (muse-get-link-desc title)))))
541 (save-match-data
542 (when (and date
543 (string-match
544 (concat "\\([1-9][0-9][0-9][0-9]\\)[./]?"
545 "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date))
546 (setq date (encode-time 0 0 0
547 (string-to-number (match-string 3 date))
548 (string-to-number (match-string 2 date))
549 (string-to-number (match-string 1 date))
550 (current-time-zone))
551 ;; make sure that date is in a format that RSS
552 ;; readers can handle
553 date (let ((system-time-locale "C"))
554 (format-time-string
555 (muse-style-element :date-format) date)))))
556 (save-restriction
557 (narrow-to-region
558 (match-beginning 0)
559 (if (re-search-forward heading-regexp nil t)
560 (match-beginning 0)
561 (if (re-search-forward "^Footnotes:" nil t)
562 (match-beginning 0)
563 (point-max))))
564 (goto-char (point-min))
565 (delete-region (point) (muse-line-end-position))
566 (re-search-forward "</qotd>\n+" nil t)
567 (while (and (char-after)
568 (eq ?\ (char-syntax (char-after))))
569 (delete-char 1))
570 (let ((beg (point)))
571 (if (muse-style-element :summarize)
572 (progn
573 (forward-sentence 2)
574 (setq desc (concat (buffer-substring beg (point)) "...")))
575 (save-restriction
576 (muse-publish-markup-buffer "rss-entry" "html")
577 (goto-char (point-min))
578 (if (re-search-forward "Page published by Emacs Muse" nil t)
579 (goto-char (muse-line-end-position))
580 (muse-display-warning
581 (concat
582 "Cannot find 'Page published by Emacs Muse begins here'.\n"
583 "You will probably need this text in your header."))
584 (goto-char (point-min)))
585 (setq beg (point))
586 (if (re-search-forward "Page published by Emacs Muse" nil t)
587 (goto-char (muse-line-beginning-position))
588 (muse-display-warning
589 (concat
590 "Cannot find 'Page published by Emacs Muse ends here'.\n"
591 "You will probably need this text in your footer."))
592 (goto-char (point-max)))
593 (setq desc (concat "<![CDATA[" (buffer-substring beg (point))
594 "]]>")))))
595 (delete-region (point-min) (point-max))
596 (let ((entry (muse-style-element :entry-template)))
597 (muse-insert-markup entry)
598 (goto-char (point-min))
599 (while (search-forward "%date%" nil t)
600 (replace-match (or date "") nil t))
601 (goto-char (point-min))
602 (while (search-forward "%title%" nil t)
603 (replace-match (or title "Untitled") nil t))
604 (goto-char (point-min))
605 (while (search-forward "%desc%" nil t)
606 (replace-match desc nil t))
607 (goto-char (point-min))
608 (while (search-forward "%enclosure%" nil t)
609 (replace-match
610 (if (null enclosure)
612 (save-match-data
613 (format
614 "<enclosure url=\"%s\" %stype=\"%s\"/>"
615 (if (string-match "//" enclosure)
616 enclosure
617 (concat (muse-style-element :base-url)
618 enclosure))
619 (let ((file
620 (expand-file-name enclosure
621 (muse-style-element :path))))
622 (if (file-readable-p file)
623 (format "length=\"%d\" "
624 (nth 7 (file-attributes file)))
625 ""))
626 (if (string-match "\\.\\([^.]+\\)$" enclosure)
627 (let* ((ext (match-string 1 enclosure))
628 (type
629 (assoc
630 ext muse-journal-rss-enclosure-types-alist)))
631 (if type
632 (cdr type)
633 "application/octet-stream"))))))
634 nil t))
635 (goto-char (point-min))
636 (while (search-forward "%link%" nil t)
637 (replace-match
638 (concat (muse-style-element :base-url)
639 (concat (muse-page-name)
640 muse-html-extension))
641 nil t))
642 (goto-char (point-min))
643 (while (search-forward "%anchor%" nil t)
644 (replace-match
645 (muse-journal-anchorize-title (or title orig-date))
646 nil t))
647 (goto-char (point-min))
648 (while (search-forward "%maintainer%" nil t)
649 (replace-match
650 (or (muse-style-element :maintainer)
651 (concat "webmaster@" (system-name)))
652 nil t))))))
653 (unless (eobp)
654 (delete-region (point) (point-max)))))
656 (unless (assoc "journal-html" muse-publishing-styles)
657 (muse-derive-style "journal-html" "html"
658 :before-end 'muse-journal-html-munge-buffer)
660 (muse-derive-style "journal-xhtml" "xhtml"
661 :before-end 'muse-journal-html-munge-buffer)
663 (muse-derive-style "journal-latex" "latex"
664 :tags 'muse-journal-latex-markup-tags
665 :before-end 'muse-journal-latex-munge-buffer)
667 (muse-derive-style "journal-pdf" "pdf"
668 :tags 'muse-journal-latex-markup-tags
669 :before-end 'muse-journal-latex-munge-buffer)
671 (muse-derive-style "journal-book-latex" "book-latex"
672 ;;:nochapters
673 :tags 'muse-journal-latex-markup-tags
674 :before-end 'muse-journal-latex-munge-buffer)
676 (muse-derive-style "journal-book-pdf" "book-pdf"
677 ;;:nochapters
678 :tags 'muse-journal-latex-markup-tags
679 :before-end 'muse-journal-latex-munge-buffer)
681 (muse-define-style "journal-rdf"
682 :suffix 'muse-journal-rdf-extension
683 :regexps 'muse-journal-rss-markup-regexps
684 :functions 'muse-journal-rss-markup-functions
685 :before 'muse-journal-rss-munge-buffer
686 :header 'muse-journal-rdf-header
687 :footer 'muse-journal-rdf-footer
688 :date-format 'muse-journal-rdf-date-format
689 :entry-template 'muse-journal-rdf-entry-template
690 :base-url 'muse-journal-rdf-base-url
691 :summarize 'muse-journal-rdf-summarize-entries)
693 (muse-define-style "journal-rss"
694 :suffix 'muse-journal-rss-extension
695 :regexps 'muse-journal-rss-markup-regexps
696 :functions 'muse-journal-rss-markup-functions
697 :before 'muse-journal-rss-munge-buffer
698 :header 'muse-journal-rss-header
699 :footer 'muse-journal-rss-footer
700 :date-format 'muse-journal-rss-date-format
701 :entry-template 'muse-journal-rss-entry-template
702 :base-url 'muse-journal-rss-base-url
703 :summarize 'muse-journal-rss-summarize-entries))
705 (provide 'muse-journal)
707 ;;; muse-journal.el ends here