Add specified Muse file extension to auto-mode-alist.
[muse-el.git] / lisp / muse-journal.el
blobe484002e2dcf0f4843a03ed0f7043daaa3a6f6ee
1 ;;; muse-journal.el --- Keep and publish a journal.
3 ;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
5 ;; This file is not part of GNU Emacs.
7 ;; This is free software; you can redistribute it and/or modify it under
8 ;; the terms of the GNU General Public License as published by the Free
9 ;; Software Foundation; either version 2, or (at your option) any later
10 ;; version.
12 ;; This is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 ;; for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU Emacs; 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 id="entry">
42 ;; <div id="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 id="entry-body">
49 ;; <div id="entry-head">
50 ;; <div id="entry-date">
51 ;; <span class="date">March 17, 2004</span>
52 ;; </div>
53 ;; <div id="entry-title">
54 ;; <h2>Title of entry</h2>
55 ;; </div>
56 ;; </div>
57 ;; <div id="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 ;;; Code:
75 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
77 ;; Muse Journal Publishing
79 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
81 (require 'muse-publish)
82 (require 'muse-html)
83 (require 'muse-latex)
84 (require 'muse-book)
86 (defgroup muse-journal nil
87 "Rules for transforming a journal into its final form."
88 :group 'muse-publish)
90 (defcustom muse-journal-heading-regexp
91 "\\(?:\\([0-9]+\\)\\(?:: \\)?\\)?\\(.+?\\)?"
92 "A regexp that matches a journal heading.
93 Paren group 1 is the ISO date, group 2 is the optional category,
94 and group 3 is the optional heading for the entry."
95 :type 'regexp
96 :group 'muse-journal)
98 (defcustom muse-journal-date-format "%a, %e %b %Y"
99 "Date format to use for journal entries."
100 :type 'string
101 :group 'muse-journal)
103 (defcustom muse-journal-html-heading-regexp
104 (concat "^<h2[^>]*>" muse-journal-heading-regexp "</h2>$")
105 "A regexp that matches a journal heading from an HTML document.
106 Paren group 1 is the ISO date, group 2 is the optional category,
107 and group 3 is the optional heading for the entry."
108 :type 'regexp
109 :group 'muse-journal)
111 (defcustom muse-journal-html-entry-template
112 "<div id=\"entry\">
113 <a name=\"%anchor%\" style=\"text-decoration: none\">&nbsp;</a>
114 <div id=\"entry-body\">
115 <div id=\"entry-head\">
116 <div id=\"entry-date\">
117 <span class=\"date\">%date%</span>
118 </div>
119 <div id=\"entry-title\">
120 <h2>%title%</h2>
121 </div>
122 </div>
123 <div id=\"entry-text\">
124 <div id=\"entry-qotd\">
125 <p>%qotd%</p>
126 </div>
127 %text%
128 </div>
129 </div>
130 </div>\n\n"
131 "Template used to publish individual journal entries as HTML."
132 :type 'string
133 :group 'muse-journal)
135 (defcustom muse-journal-latex-section
136 "\\section*{%title% \\hfill {\\normalsize %date%}}
137 \\addcontentsline{toc}{chapter}{%title%}"
138 "Template used to publish a LaTeX section."
139 :type 'string
140 :group 'muse-journal)
142 (defcustom muse-journal-latex-subsection
143 "\\subsection*{%title%}
144 \\addcontentsline{toc}{section}{%title%}"
145 "Template used to publish a LaTeX subsection."
146 :type 'string
147 :group 'muse-journal)
149 (defcustom muse-journal-latex-markup-tags
150 '(("qotd" t nil muse-journal-latex-qotd-tag))
151 "A list of tag specifications, for specially marking up LaTeX.
152 See `muse-publish-markup-tags' for more info."
153 :type '(repeat (list (string :tag "Markup tag")
154 (boolean :tag "Expect closing tag" :value t)
155 (boolean :tag "Parse attributes" :value nil)
156 function))
157 :group 'muse-journal)
159 ;; FIXME: This doesn't appear to be used.
160 (defun muse-journal-generate-pages ()
161 (let ((output-dir (muse-style-element :path)))
162 (goto-char (point-min))
163 (while (re-search-forward muse-journal-heading-regexp nil t)
164 (let* ((date (match-string 1))
165 (category (match-string 1))
166 (category-file (concat output-dir category "/index.html"))
167 (heading (match-string 1)))
168 t))))
170 (defcustom muse-journal-rdf-extension ".rdf"
171 "Default file extension for publishing RDF (RSS 1.0) files."
172 :type 'string
173 :group 'muse-journal)
175 (defcustom muse-journal-rdf-base-url ""
176 "The base URL of the website referenced by the RDF file."
177 :type 'string
178 :group 'muse-journal)
180 (defcustom muse-journal-rdf-header
181 "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"
182 xmlns=\"http://purl.org/rss/1.0/\"
183 xmlns:dc=\"http://purl.org/dc/elements/1.1/\">
184 <channel rdf:about=\"<lisp>(concat (muse-style-element :base-url)
185 (muse-publish-output-name))</lisp>\">
186 <title><lisp>(muse-publishing-directive \"title\")</lisp></title>
187 <link><lisp>(concat (muse-style-element :base-url)
188 (concat (muse-page-name)
189 muse-html-extension))</lisp></link>
190 <description><lisp>(muse-publishing-directive \"desc\")</lisp></description>
191 <items>
192 <rdf:Seq>
193 <rdf:li resource=\"<lisp>
194 (concat (muse-style-element :base-url)
195 (concat (muse-page-name)
196 muse-html-extension))</lisp>\"/>
197 </rdf:Seq>
198 </items>
199 </channel>\n"
200 "Header used for publishing RDF (RSS 1.0) files."
201 :type '(choice string file)
202 :group 'muse-journal)
204 (defcustom muse-journal-rdf-footer
205 "</rdf:RDF>\n"
206 "Footer used for publishing RDF (RSS 1.0) files."
207 :type '(choice string file)
208 :group 'muse-journal)
210 (defcustom muse-journal-rdf-date-format
211 "%Y-%m-%dT%H:%M:%S"
212 "Date format to use for RDF entries."
213 :type 'string
214 :group 'muse-journal)
216 (defcustom muse-journal-rdf-entry-template
217 " <item rdf:about=\"%link%#%anchor%\">
218 <title>%title%</title>
219 <description>
220 %desc%
221 </description>
222 <link>%link%#%anchor%</link>
223 <dc:date>%date%</dc:date>
224 <dc:creator>%maintainer%</dc:creator>
225 </item>\n"
226 "Template used to publish individual journal entries as RDF."
227 :type 'string
228 :group 'muse-journal)
230 (defcustom muse-journal-rdf-summarize-entries t
231 "If non-nil, include only summaries in the RDF file, not the full data."
232 :type 'boolean
233 :group 'muse-journal)
235 (defcustom muse-journal-rss-extension ".xml"
236 "Default file extension for publishing RSS 2.0 files."
237 :type 'string
238 :group 'muse-journal)
240 (defcustom muse-journal-rss-base-url ""
241 "The base URL of the website referenced by the RSS file."
242 :type 'string
243 :group 'muse-journal)
245 (defcustom muse-journal-rss-header
246 "<\?xml version=\"1.0\" encoding=\"<lisp>
247 (muse-html-encoding)</lisp>\"?>
248 <rss version=\"2.0\">
249 <channel>
250 <title><lisp>(muse-publishing-directive \"title\")</lisp></title>
251 <link><lisp>(concat (muse-style-element :base-url)
252 (concat (muse-page-name)
253 muse-html-extension))</lisp></link>
254 <description><lisp>(muse-publishing-directive \"desc\")</lisp></description>
255 <language>en-us</language>
256 <generator>Emacs Muse</generator>"
257 "Header used for publishing RSS 2.0 files."
258 :type '(choice string file)
259 :group 'muse-journal)
261 (defcustom muse-journal-rss-footer
262 " </channel>
263 </rss>\n"
264 "Footer used for publishing RSS 2.0 files."
265 :type '(choice string file)
266 :group 'muse-journal)
268 (defcustom muse-journal-rss-date-format
269 "%a, %d %b %Y %H:%M:%S %Z"
270 "Date format to use for RSS 2.0 entries."
271 :type 'string
272 :group 'muse-journal)
274 (defcustom muse-journal-rss-entry-template
275 " <item>
276 <title>%title%</title>
277 <link>%link%#%anchor%</link>
278 <description>%desc%</description>
279 <author><lisp>(muse-publishing-directive \"author\")</lisp></author>
280 <pubDate>%date%</pubDate>
281 <guid>%link%#%anchor%</guid>
282 %enclosure%
283 </item>\n"
284 "Template used to publish individual journal entries as RSS 2.0."
285 :type 'string
286 :group 'muse-journal)
288 (defcustom muse-journal-rss-enclosure-types-alist
289 '(("mp3" . "audio/mpeg"))
290 "File types that are accepted as RSS enclosures.
291 This is an alist that maps file extension to content type.
292 Useful for podcasting."
293 :type '(alist :key-type string :value-type string)
294 :group 'muse-journal)
296 (defcustom muse-journal-rss-summarize-entries nil
297 "If non-nil, include only summaries in the RSS file, not the full data.
298 Many RSS subscribers find this annoying."
299 :type 'boolean
300 :group 'muse-journal)
302 (defcustom muse-journal-rss-markup-regexps
303 '((10000 muse-explicit-link-regexp 0 "\\2"))
304 "List of markup rules for publishing a Muse journal page to RSS 2.0.
305 For more information on the structure of this list, see
306 `muse-publish-markup-regexps'."
307 :type '(repeat (choice
308 (list :tag "Markup rule"
309 integer
310 (choice regexp symbol)
311 integer
312 (choice string function symbol))
313 function))
314 :group 'muse-journal)
316 (defcustom muse-journal-rss-markup-functions
317 '((email . ignore)
318 (link . ignore)
319 (url . ignore))
320 "An alist of style types to custom functions for that kind of text.
321 For more on the structure of this list, see
322 `muse-publish-markup-functions'."
323 :type '(alist :key-type symbol :value-type function)
324 :group 'muse-journal)
326 (defun muse-journal-anchorize-title (title)
327 (save-match-data
328 (if (string-match "(" title)
329 (setq title (substring title 0 (match-beginning 0))))
330 (if (string-match "<[^>]+>" title)
331 (setq title (replace-match "" nil nil title)))
332 (downcase (muse-replace-regexp-in-string "[^a-zA-Z0-9_]" "" title))))
334 (defun muse-journal-sort-entries (&optional direction)
335 (interactive "P")
336 (sort-subr
337 direction
338 (function
339 (lambda ()
340 (if (re-search-forward "^\\* [0-9]+" nil t)
341 (goto-char (match-beginning 0))
342 (goto-char (point-max)))))
343 (function
344 (lambda ()
345 (if (re-search-forward "^\\* [0-9]+" nil t)
346 (goto-char (1- (match-beginning 0)))
347 (goto-char (point-max)))))
348 (function
349 (lambda ()
350 (forward-char 2)))
351 (function
352 (lambda ()
353 (end-of-line)))))
355 (defun muse-journal-html-munge-buffer ()
356 (goto-char (point-min))
357 (let ((heading-regexp muse-journal-html-heading-regexp)
358 (inhibit-read-only t))
359 (while (re-search-forward heading-regexp nil t)
360 (let* ((date (match-string 1))
361 (orig-date date)
362 (title (match-string 2))
363 (clean-title title)
364 datestamp qotd text)
365 (delete-region (match-beginning 0) (match-end 0))
366 (if clean-title
367 (save-match-data
368 (while (string-match "\\(^<[^>]+>\\|<[^>]+>$\\)" clean-title)
369 (setq clean-title (replace-match "" nil nil clean-title)))))
370 (save-match-data
371 (when (and date
372 (string-match
373 (concat "\\`\\([1-9][0-9][0-9][0-9]\\)[./]?"
374 "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date))
375 (setq datestamp
376 (encode-time
377 0 0 0
378 (string-to-number (match-string 3 date))
379 (string-to-number (match-string 2 date))
380 (string-to-number (match-string 1 date))
381 (current-time-zone))
382 date (concat (format-time-string
383 muse-journal-date-format datestamp)
384 (substring date (match-end 0))))))
385 (save-restriction
386 (narrow-to-region
387 (point) (if (re-search-forward
388 (concat "\\(^<hr>$\\|"
389 heading-regexp "\\)") nil t)
390 (match-beginning 0)
391 (point-max)))
392 (goto-char (point-max))
393 (while (and (not (bobp))
394 (eq ?\ (char-syntax (char-before))))
395 (delete-char -1))
396 (goto-char (point-min))
397 (while (and (not (eobp))
398 (eq ?\ (char-syntax (char-after))))
399 (delete-char 1))
400 (save-excursion
401 (when (search-forward "<qotd>" nil t)
402 (let ((tag-beg (match-beginning 0))
403 (beg (match-end 0)))
404 (re-search-forward "</qotd>\n*")
405 (setq qotd (buffer-substring-no-properties
406 beg (match-beginning 0)))
407 (delete-region tag-beg (match-end 0)))))
408 (setq text (buffer-string))
409 (delete-region (point-min) (point-max))
410 (let ((entry muse-journal-html-entry-template))
411 (while (string-match "%date%" entry)
412 (setq entry (replace-match (or date "") nil t entry)))
413 (while (string-match "%title%" entry)
414 (setq entry (replace-match (or title "&nbsp;") nil t entry)))
415 (while (string-match "%anchor%" entry)
416 (setq entry (replace-match
417 (muse-journal-anchorize-title
418 (or clean-title orig-date))
419 nil t entry)))
420 (while (string-match "%qotd%" entry)
421 (setq entry (replace-match (or qotd "") nil t entry)))
422 (while (string-match "%text%" entry)
423 (setq entry (replace-match text nil t entry)))
424 (insert entry)
425 (when (null qotd)
426 (goto-char (point-min))
427 (search-forward "<div id=\"entry-qotd\">")
428 (let ((beg (match-beginning 0)))
429 (re-search-forward "</div>\n*")
430 (delete-region beg (point))))))))))
432 (defun muse-journal-latex-munge-buffer ()
433 (goto-char (point-min))
434 (let ((heading-regexp
435 (concat "^" (regexp-quote (muse-markup-text 'section))
436 muse-journal-heading-regexp
437 (regexp-quote (muse-markup-text 'section-end)) "$"))
438 (inhibit-read-only t))
439 (when (re-search-forward heading-regexp nil t)
440 (goto-char (match-beginning 0))
441 (sort-subr nil
442 (function
443 (lambda ()
444 (if (re-search-forward heading-regexp nil t)
445 (goto-char (match-beginning 0))
446 (goto-char (point-max)))))
447 (function
448 (lambda ()
449 (if (re-search-forward heading-regexp nil t)
450 (goto-char (1- (match-beginning 0)))
451 (goto-char (point-max)))))
452 (function
453 (lambda ()
454 (forward-char 2)))
455 (function
456 (lambda ()
457 (end-of-line)))))
458 (while (re-search-forward heading-regexp nil t)
459 (let ((date (match-string 1))
460 (title (match-string 2))
461 ;; FIXME: Nothing is done with qotd
462 qotd section)
463 (save-match-data
464 (when (and date
465 (string-match
466 (concat "\\([1-9][0-9][0-9][0-9]\\)[./]?"
467 "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date))
468 (setq date (encode-time
469 0 0 0
470 (string-to-number (match-string 3 date))
471 (string-to-number (match-string 2 date))
472 (string-to-number (match-string 1 date))
473 (current-time-zone))
474 date (format-time-string
475 muse-journal-date-format date))))
476 (save-match-data
477 (setq section muse-journal-latex-section)
478 (while (string-match "%title%" section)
479 (setq section (replace-match (or title "Untitled")
480 nil t section)))
481 (while (string-match "%date%" section)
482 (setq section (replace-match (or date "") nil t section))))
483 (replace-match section nil t))))
484 (goto-char (point-min))
485 (let ((subheading-regexp
486 (concat "^" (regexp-quote (muse-markup-text 'subsection))
487 "\\([^\n}]+\\)"
488 (regexp-quote (muse-markup-text 'subsection-end)) "$"))
489 (inhibit-read-only t))
490 (while (re-search-forward subheading-regexp nil t)
491 (let ((subsection muse-journal-latex-subsection))
492 (save-match-data
493 (let ((title (match-string 1)))
494 (while (string-match "%title%" subsection)
495 (setq subsection (replace-match title nil t subsection)))))
496 (replace-match subsection nil t)))))
498 (defun muse-journal-latex-qotd-tag (beg end)
499 (goto-char beg)
500 (insert (muse-markup-text 'begin-quote))
501 (goto-char end)
502 (insert (muse-markup-text 'end-quote)))
504 (defun muse-journal-rss-munge-buffer ()
505 (goto-char (point-min))
506 (let ((heading-regexp (concat "^\\* " muse-journal-heading-regexp "$"))
507 (inhibit-read-only t))
508 (while (re-search-forward heading-regexp nil t)
509 (let* ((date (match-string 1))
510 (orig-date date)
511 (title (match-string 2))
512 ;; FIXME: Nothing is done with qotd
513 enclosure qotd desc)
514 (if title
515 (save-match-data
516 (if (string-match muse-explicit-link-regexp title)
517 (setq enclosure (match-string 1 title)
518 title (match-string 2 title)))))
519 (save-match-data
520 (when (and date
521 (string-match
522 (concat "\\([1-9][0-9][0-9][0-9]\\)[./]?"
523 "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date))
524 (setq date (encode-time 0 0 0
525 (string-to-number (match-string 3 date))
526 (string-to-number (match-string 2 date))
527 (string-to-number (match-string 1 date))
528 (current-time-zone))
529 date (format-time-string
530 (muse-style-element :date-format) date))))
531 (save-restriction
532 (narrow-to-region
533 (match-beginning 0)
534 (if (re-search-forward heading-regexp nil t)
535 (match-beginning 0)
536 (if (re-search-forward "^Footnotes:" nil t)
537 (match-beginning 0)
538 (point-max))))
539 (goto-char (point-min))
540 (delete-region (point) (muse-line-end-position))
541 (re-search-forward "</qotd>\n+" nil t)
542 (while (and (char-after)
543 (eq ?\ (char-syntax (char-after))))
544 (delete-char 1))
545 (let ((beg (point)))
546 (if (muse-style-element :summarize)
547 (progn
548 (forward-sentence 2)
549 (setq desc (concat (buffer-substring beg (point)) "...")))
550 (save-restriction
551 (muse-publish-markup-buffer "rss-entry" "html")
552 (goto-char (point-min))
553 (re-search-forward "Page published by Emacs Muse")
554 (goto-char (muse-line-end-position))
555 (setq beg (point))
556 (re-search-forward "Page published by Emacs Muse")
557 (goto-char (muse-line-beginning-position))
558 (setq desc (concat "<![CDATA[" (buffer-substring beg (point))
559 "]]>")))))
560 (delete-region (point-min) (point-max))
561 (let ((entry (muse-style-element :entry-template)))
562 (while (string-match "%date%" entry)
563 (setq entry (replace-match (or date "") nil t entry)))
564 (while (string-match "%title%" entry)
565 (setq entry (replace-match (or title "Untitled") nil t entry)))
566 (while (string-match "%desc%" entry)
567 (setq entry (replace-match desc nil t entry)))
568 (while (string-match "%enclosure%" entry)
569 (setq
570 entry
571 (replace-match
572 (if (null enclosure)
574 (save-match-data
575 (format
576 "<enclosure url=\"%s\" %stype=\"%s\"/>"
577 (if (string-match "//" enclosure)
578 enclosure
579 (concat (muse-style-element :base-url)
580 enclosure))
581 (let ((file
582 (expand-file-name enclosure
583 (muse-style-element :path))))
584 (if (file-readable-p file)
585 (format "length=\"%d\" "
586 (nth 7 (file-attributes file)))
587 ""))
588 (if (string-match "\\.\\([^.]+\\)$" enclosure)
589 (let* ((ext (match-string 1 enclosure))
590 (type
591 (assoc
592 ext muse-journal-rss-enclosure-types-alist)))
593 (if type
594 (cdr type)
595 "application/octet-stream"))))))
596 nil t entry)))
597 (while (string-match "%link%" entry)
598 (setq entry (replace-match
599 (concat (muse-style-element :base-url)
600 (concat (muse-page-name)
601 muse-html-extension))
602 nil t entry)))
603 (while (string-match "%anchor%" entry)
604 (setq entry (replace-match
605 (muse-journal-anchorize-title (or title orig-date))
606 nil t entry)))
607 (while (string-match "%maintainer%" entry)
608 (setq entry (replace-match
609 (or (muse-style-element :maintainer)
610 (concat "webmaster@" (system-name)))
611 nil t entry)))
612 (insert entry)))))
613 (unless (eobp)
614 (delete-region (point) (point-max)))))
616 (unless (assoc "journal-html" muse-publishing-styles)
617 (muse-derive-style "journal-html" "html"
618 :before-end 'muse-journal-html-munge-buffer)
620 (muse-derive-style "journal-xhtml" "xhtml"
621 :before-end 'muse-journal-html-munge-buffer)
623 (muse-derive-style "journal-latex" "latex"
624 :tags 'muse-journal-latex-markup-tags
625 :before-end 'muse-journal-latex-munge-buffer)
627 (muse-derive-style "journal-pdf" "pdf"
628 :tags 'muse-journal-latex-markup-tags
629 :before-end 'muse-journal-latex-munge-buffer)
631 (muse-derive-style "journal-book-latex" "book-latex"
632 ;;:nochapters
633 :tags 'muse-journal-latex-markup-tags
634 :before-end 'muse-journal-latex-munge-buffer)
636 (muse-derive-style "journal-book-pdf" "book-pdf"
637 ;;:nochapters
638 :tags 'muse-journal-latex-markup-tags
639 :before-end 'muse-journal-latex-munge-buffer)
641 (muse-define-style "journal-rdf"
642 :suffix 'muse-journal-rdf-extension
643 :regexps 'muse-journal-rss-markup-regexps
644 :functions 'muse-journal-rss-markup-functions
645 :before 'muse-journal-rss-munge-buffer
646 :header 'muse-journal-rdf-header
647 :footer 'muse-journal-rdf-footer
648 :date-format 'muse-journal-rdf-date-format
649 :entry-template 'muse-journal-rdf-entry-template
650 :base-url 'muse-journal-rdf-base-url
651 :summarize 'muse-journal-rdf-summarize-entries)
653 (muse-define-style "journal-rss"
654 :suffix 'muse-journal-rss-extension
655 :regexps 'muse-journal-rss-markup-regexps
656 :functions 'muse-journal-rss-markup-functions
657 :before 'muse-journal-rss-munge-buffer
658 :header 'muse-journal-rss-header
659 :footer 'muse-journal-rss-footer
660 :date-format 'muse-journal-rss-date-format
661 :entry-template 'muse-journal-rss-entry-template
662 :base-url 'muse-journal-rss-base-url
663 :summarize 'muse-journal-rss-summarize-entries))
665 (provide 'muse-journal)
667 ;;; muse-journal.el ends here