muse-journal: Make custom RSS heading regexps possible.
[muse-el.git] / lisp / muse-journal.el
blobb7a0685b3f086764a8d88f8f1ae445387dfb0ffd
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 ;;; 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[^>\n]*>" 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-rss-heading-regexp
112 (concat "^\\* " muse-journal-heading-regexp "$")
113 "A regexp that matches a journal heading from an HTML document.
114 Paren group 1 is the ISO date, group 2 is the optional category,
115 and group 3 is the optional heading for the entry."
116 :type 'regexp
117 :group 'muse-journal)
119 (defcustom muse-journal-html-entry-template
120 "<div class=\"entry\">
121 <a name=\"%anchor%\" style=\"text-decoration: none\">&nbsp;</a>
122 <div class=\"entry-body\">
123 <div class=\"entry-head\">
124 <div class=\"entry-date\">
125 <span class=\"date\">%date%</span>
126 </div>
127 <div class=\"entry-title\">
128 <h2>%title%</h2>
129 </div>
130 </div>
131 <div class=\"entry-text\">
132 <div class=\"entry-qotd\">
133 <p>%qotd%</p>
134 </div>
135 %text%
136 </div>
137 </div>
138 </div>\n\n"
139 "Template used to publish individual journal entries as HTML."
140 :type 'string
141 :group 'muse-journal)
143 (defcustom muse-journal-latex-section
144 "\\section*{%title% \\hfill {\\normalsize %date%}}
145 \\addcontentsline{toc}{chapter}{%title%}"
146 "Template used to publish a LaTeX section."
147 :type 'string
148 :group 'muse-journal)
150 (defcustom muse-journal-latex-subsection
151 "\\subsection*{%title%}
152 \\addcontentsline{toc}{section}{%title%}"
153 "Template used to publish a LaTeX subsection."
154 :type 'string
155 :group 'muse-journal)
157 (defcustom muse-journal-latex-markup-tags
158 '(("qotd" t nil muse-journal-latex-qotd-tag))
159 "A list of tag specifications, for specially marking up LaTeX.
160 See `muse-publish-markup-tags' for more info."
161 :type '(repeat (list (string :tag "Markup tag")
162 (boolean :tag "Expect closing tag" :value t)
163 (boolean :tag "Parse attributes" :value nil)
164 function))
165 :group 'muse-journal)
167 ;; FIXME: This doesn't appear to be used.
168 (defun muse-journal-generate-pages ()
169 (let ((output-dir (muse-style-element :path)))
170 (goto-char (point-min))
171 (while (re-search-forward muse-journal-heading-regexp nil t)
172 (let* ((date (match-string 1))
173 (category (match-string 1))
174 (category-file (concat output-dir category "/index.html"))
175 (heading (match-string 1)))
176 t))))
178 (defcustom muse-journal-rdf-extension ".rdf"
179 "Default file extension for publishing RDF (RSS 1.0) files."
180 :type 'string
181 :group 'muse-journal)
183 (defcustom muse-journal-rdf-base-url ""
184 "The base URL of the website referenced by the RDF file."
185 :type 'string
186 :group 'muse-journal)
188 (defcustom muse-journal-rdf-header
189 "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"
190 xmlns=\"http://purl.org/rss/1.0/\"
191 xmlns:dc=\"http://purl.org/dc/elements/1.1/\">
192 <channel rdf:about=\"<lisp>(concat (muse-style-element :base-url)
193 (muse-publish-link-name))</lisp>\">
194 <title><lisp>(muse-publishing-directive \"title\")</lisp></title>
195 <link><lisp>(concat (muse-style-element :base-url)
196 (concat (muse-page-name)
197 muse-html-extension))</lisp></link>
198 <description><lisp>(muse-publishing-directive \"desc\")</lisp></description>
199 <items>
200 <rdf:Seq>
201 <rdf:li resource=\"<lisp>
202 (concat (muse-style-element :base-url)
203 (concat (muse-page-name)
204 muse-html-extension))</lisp>\"/>
205 </rdf:Seq>
206 </items>
207 </channel>\n"
208 "Header used for publishing RDF (RSS 1.0) files.
209 This may be text or a filename."
210 :type 'string
211 :group 'muse-journal)
213 (defcustom muse-journal-rdf-footer
214 "</rdf:RDF>\n"
215 "Footer used for publishing RDF (RSS 1.0) files.
216 This may be text or a filename."
217 :type 'string
218 :group 'muse-journal)
220 (defcustom muse-journal-rdf-date-format
221 "%Y-%m-%dT%H:%M:%S"
222 "Date format to use for RDF entries."
223 :type 'string
224 :group 'muse-journal)
226 (defcustom muse-journal-rdf-entry-template
227 " <item rdf:about=\"%link%#%anchor%\">
228 <title>%title%</title>
229 <description>
230 %desc%
231 </description>
232 <link>%link%#%anchor%</link>
233 <dc:date>%date%</dc:date>
234 <dc:creator>%maintainer%</dc:creator>
235 </item>\n"
236 "Template used to publish individual journal entries as RDF."
237 :type 'string
238 :group 'muse-journal)
240 (defcustom muse-journal-rdf-summarize-entries t
241 "If non-nil, include only summaries in the RDF file, not the full data."
242 :type 'boolean
243 :group 'muse-journal)
245 (defcustom muse-journal-rss-extension ".xml"
246 "Default file extension for publishing RSS 2.0 files."
247 :type 'string
248 :group 'muse-journal)
250 (defcustom muse-journal-rss-base-url ""
251 "The base URL of the website referenced by the RSS file."
252 :type 'string
253 :group 'muse-journal)
255 (defcustom muse-journal-rss-header
256 "<\?xml version=\"1.0\" encoding=\"<lisp>
257 (muse-html-encoding)</lisp>\"?>
258 <rss version=\"2.0\">
259 <channel>
260 <title><lisp>(muse-publishing-directive \"title\")</lisp></title>
261 <link><lisp>(concat (muse-style-element :base-url)
262 (concat (muse-page-name)
263 muse-html-extension))</lisp></link>
264 <description><lisp>(muse-publishing-directive \"desc\")</lisp></description>
265 <language>en-us</language>
266 <generator>Emacs Muse</generator>"
267 "Header used for publishing RSS 2.0 files. This may be text or a filename."
268 :type 'string
269 :group 'muse-journal)
271 (defcustom muse-journal-rss-footer
272 " </channel>
273 </rss>\n"
274 "Footer used for publishing RSS 2.0 files. This may be text or a filename."
275 :type 'string
276 :group 'muse-journal)
278 (defcustom muse-journal-rss-date-format
279 "%a, %d %b %Y %H:%M:%S %Z"
280 "Date format to use for RSS 2.0 entries."
281 :type 'string
282 :group 'muse-journal)
284 (defcustom muse-journal-rss-entry-template
285 " <item>
286 <title>%title%</title>
287 <link>%link%#%anchor%</link>
288 <description>%desc%</description>
289 <author><lisp>(muse-publishing-directive \"author\")</lisp></author>
290 <pubDate>%date%</pubDate>
291 <guid>%link%#%anchor%</guid>
292 %enclosure%
293 </item>\n"
294 "Template used to publish individual journal entries as RSS 2.0."
295 :type 'string
296 :group 'muse-journal)
298 (defcustom muse-journal-rss-enclosure-types-alist
299 '(("mp3" . "audio/mpeg"))
300 "File types that are accepted as RSS enclosures.
301 This is an alist that maps file extension to content type.
302 Useful for podcasting."
303 :type '(alist :key-type string :value-type string)
304 :group 'muse-journal)
306 (defcustom muse-journal-rss-summarize-entries nil
307 "If non-nil, include only summaries in the RSS file, not the full data.
308 Many RSS subscribers find this annoying."
309 :type 'boolean
310 :group 'muse-journal)
312 (defcustom muse-journal-rss-markup-regexps
313 '((10000 muse-explicit-link-regexp 0 "\\2"))
314 "List of markup rules for publishing a Muse journal page to RSS 2.0.
315 For more information on the structure of this list, see
316 `muse-publish-markup-regexps'."
317 :type '(repeat (choice
318 (list :tag "Markup rule"
319 integer
320 (choice regexp symbol)
321 integer
322 (choice string function symbol))
323 function))
324 :group 'muse-journal)
326 (defcustom muse-journal-rss-markup-functions
327 '((email . ignore)
328 (link . ignore)
329 (url . ignore))
330 "An alist of style types to custom functions for that kind of text.
331 For more on the structure of this list, see
332 `muse-publish-markup-functions'."
333 :type '(alist :key-type symbol :value-type function)
334 :group 'muse-journal)
336 (defun muse-journal-anchorize-title (title)
337 (save-match-data
338 (if (string-match "(" title)
339 (setq title (substring title 0 (match-beginning 0))))
340 (if (string-match "<[^>]+>" title)
341 (setq title (replace-match "" nil nil title)))
342 (downcase (muse-replace-regexp-in-string "[^a-zA-Z0-9_]" "" title))))
344 (defun muse-journal-sort-entries (&optional direction)
345 (interactive "P")
346 (sort-subr
347 direction
348 (function
349 (lambda ()
350 (if (re-search-forward "^\\* [0-9]+" nil t)
351 (goto-char (match-beginning 0))
352 (goto-char (point-max)))))
353 (function
354 (lambda ()
355 (if (re-search-forward "^\\* [0-9]+" nil t)
356 (goto-char (1- (match-beginning 0)))
357 (goto-char (point-max)))))
358 (function
359 (lambda ()
360 (forward-char 2)))
361 (function
362 (lambda ()
363 (end-of-line)))))
365 (defun muse-journal-html-munge-buffer ()
366 (goto-char (point-min))
367 (let ((heading-regexp muse-journal-html-heading-regexp)
368 (inhibit-read-only t))
369 (while (re-search-forward heading-regexp nil t)
370 (let* ((date (match-string 1))
371 (orig-date date)
372 (title (match-string 2))
373 (clean-title title)
374 datestamp qotd text)
375 (delete-region (match-beginning 0) (match-end 0))
376 (if clean-title
377 (save-match-data
378 (while (string-match "\\(^<[^>]+>\\|<[^>]+>$\\)" clean-title)
379 (setq clean-title (replace-match "" nil nil clean-title)))))
380 (save-match-data
381 (when (and date
382 (string-match
383 (concat "\\`\\([1-9][0-9][0-9][0-9]\\)[./]?"
384 "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date))
385 (setq datestamp
386 (encode-time
387 0 0 0
388 (string-to-number (match-string 3 date))
389 (string-to-number (match-string 2 date))
390 (string-to-number (match-string 1 date))
391 (current-time-zone))
392 date (concat (format-time-string
393 muse-journal-date-format datestamp)
394 (substring date (match-end 0))))))
395 (save-restriction
396 (narrow-to-region
397 (point) (if (re-search-forward
398 (concat "\\(^<hr>$\\|"
399 heading-regexp "\\)") nil t)
400 (match-beginning 0)
401 (point-max)))
402 (goto-char (point-max))
403 (while (and (not (bobp))
404 (eq ?\ (char-syntax (char-before))))
405 (delete-char -1))
406 (goto-char (point-min))
407 (while (and (not (eobp))
408 (eq ?\ (char-syntax (char-after))))
409 (delete-char 1))
410 (save-excursion
411 (when (search-forward "<qotd>" nil t)
412 (let ((tag-beg (match-beginning 0))
413 (beg (match-end 0)))
414 (re-search-forward "</qotd>\n*")
415 (setq qotd (buffer-substring-no-properties
416 beg (match-beginning 0)))
417 (delete-region tag-beg (match-end 0)))))
418 (setq text (buffer-string))
419 (delete-region (point-min) (point-max))
420 (let ((entry muse-journal-html-entry-template))
421 (muse-insert-markup entry)
422 (goto-char (point-min))
423 (while (search-forward "%date%" nil t)
424 (replace-match (or date "") nil t))
425 (goto-char (point-min))
426 (while (search-forward "%title%" nil t)
427 (replace-match (or title "&nbsp;") nil t))
428 (goto-char (point-min))
429 (while (search-forward "%anchor%" nil t)
430 (replace-match (muse-journal-anchorize-title
431 (or clean-title orig-date))
432 nil t))
433 (goto-char (point-min))
434 (while (search-forward "%qotd%" nil t)
435 (replace-match (or qotd "") nil t))
436 (goto-char (point-min))
437 (while (search-forward "%text%" nil t)
438 (replace-match text nil t))
439 (when (null qotd)
440 (goto-char (point-min))
441 (when (search-forward "<div class=\"entry-qotd\">" nil t)
442 (let ((beg (match-beginning 0)))
443 (re-search-forward "</div>\n*" nil t)
444 (delete-region beg (point)))))))))))
446 (defun muse-journal-latex-munge-buffer ()
447 (goto-char (point-min))
448 (let ((heading-regexp
449 (concat "^" (regexp-quote (muse-markup-text 'section))
450 muse-journal-heading-regexp
451 (regexp-quote (muse-markup-text 'section-end)) "$"))
452 (inhibit-read-only t))
453 (when (re-search-forward heading-regexp nil t)
454 (goto-char (match-beginning 0))
455 (sort-subr nil
456 (function
457 (lambda ()
458 (if (re-search-forward heading-regexp nil t)
459 (goto-char (match-beginning 0))
460 (goto-char (point-max)))))
461 (function
462 (lambda ()
463 (if (re-search-forward heading-regexp nil t)
464 (goto-char (1- (match-beginning 0)))
465 (goto-char (point-max)))))
466 (function
467 (lambda ()
468 (forward-char 2)))
469 (function
470 (lambda ()
471 (end-of-line)))))
472 (while (re-search-forward heading-regexp nil t)
473 (let ((date (match-string 1))
474 (title (match-string 2))
475 ;; FIXME: Nothing is done with qotd
476 qotd section)
477 (save-match-data
478 (when (and date
479 (string-match
480 (concat "\\([1-9][0-9][0-9][0-9]\\)[./]?"
481 "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date))
482 (setq date (encode-time
483 0 0 0
484 (string-to-number (match-string 3 date))
485 (string-to-number (match-string 2 date))
486 (string-to-number (match-string 1 date))
487 (current-time-zone))
488 date (format-time-string
489 muse-journal-date-format date))))
490 (save-restriction
491 (narrow-to-region (match-beginning 0) (match-end 0))
492 (delete-region (point-min) (point-max))
493 (muse-insert-markup muse-journal-latex-section)
494 (goto-char (point-min))
495 (while (search-forward "%title%" nil t)
496 (replace-match (or title "Untitled") nil t))
497 (goto-char (point-min))
498 (while (search-forward "%date%" nil t)
499 (replace-match (or date "") nil t))))))
500 (goto-char (point-min))
501 (let ((subheading-regexp
502 (concat "^" (regexp-quote (muse-markup-text 'subsection))
503 "\\([^\n}]+\\)"
504 (regexp-quote (muse-markup-text 'subsection-end)) "$"))
505 (inhibit-read-only t))
506 (while (re-search-forward subheading-regexp nil t)
507 (let ((title (match-string 1)))
508 (save-restriction
509 (narrow-to-region (match-beginning 0) (match-end 0))
510 (delete-region (point-min) (point-max))
511 (muse-insert-markup muse-journal-latex-subsection)
512 (goto-char (point-min))
513 (while (search-forward "%title%" nil t)
514 (replace-match title nil t)))))))
516 (defun muse-journal-latex-qotd-tag (beg end)
517 (goto-char beg)
518 (muse-insert-markup (muse-markup-text 'begin-quote))
519 (goto-char end)
520 (muse-insert-markup (muse-markup-text 'end-quote)))
522 (defun muse-journal-rss-munge-buffer ()
523 (goto-char (point-min))
524 (let ((heading-regexp muse-journal-rss-heading-regexp)
525 (inhibit-read-only t))
526 (while (re-search-forward heading-regexp nil t)
527 (let* ((date (match-string 1))
528 (orig-date date)
529 (title (match-string 2))
530 ;; FIXME: Nothing is done with qotd
531 enclosure qotd desc)
532 (if title
533 (save-match-data
534 (if (string-match muse-explicit-link-regexp title)
535 (setq enclosure (muse-get-link title)
536 title (muse-get-link-desc title)))))
537 (save-match-data
538 (when (and date
539 (string-match
540 (concat "\\([1-9][0-9][0-9][0-9]\\)[./]?"
541 "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date))
542 (setq date (encode-time 0 0 0
543 (string-to-number (match-string 3 date))
544 (string-to-number (match-string 2 date))
545 (string-to-number (match-string 1 date))
546 (current-time-zone))
547 date (format-time-string
548 (muse-style-element :date-format) date))))
549 (save-restriction
550 (narrow-to-region
551 (match-beginning 0)
552 (if (re-search-forward heading-regexp nil t)
553 (match-beginning 0)
554 (if (re-search-forward "^Footnotes:" nil t)
555 (match-beginning 0)
556 (point-max))))
557 (goto-char (point-min))
558 (delete-region (point) (muse-line-end-position))
559 (re-search-forward "</qotd>\n+" nil t)
560 (while (and (char-after)
561 (eq ?\ (char-syntax (char-after))))
562 (delete-char 1))
563 (let ((beg (point)))
564 (if (muse-style-element :summarize)
565 (progn
566 (forward-sentence 2)
567 (setq desc (concat (buffer-substring beg (point)) "...")))
568 (save-restriction
569 (muse-publish-markup-buffer "rss-entry" "html")
570 (goto-char (point-min))
571 (if (re-search-forward "Page published by Emacs Muse" nil t)
572 (goto-char (muse-line-end-position))
573 (muse-display-warning
574 (concat
575 "Cannot find 'Page published by Emacs Muse begins here'.\n"
576 "You will probably need this text in your header."))
577 (goto-char (point-min)))
578 (setq beg (point))
579 (if (re-search-forward "Page published by Emacs Muse" nil t)
580 (goto-char (muse-line-beginning-position))
581 (muse-display-warning
582 (concat
583 "Cannot find 'Page published by Emacs Muse ends here'.\n"
584 "You will probably need this text in your footer."))
585 (goto-char (point-max)))
586 (setq desc (concat "<![CDATA[" (buffer-substring beg (point))
587 "]]>")))))
588 (delete-region (point-min) (point-max))
589 (let ((entry (muse-style-element :entry-template)))
590 (muse-insert-markup entry)
591 (goto-char (point-min))
592 (while (search-forward "%date%" nil t)
593 (replace-match (or date "") nil t))
594 (goto-char (point-min))
595 (while (search-forward "%title%" nil t)
596 (replace-match (or title "Untitled") nil t))
597 (goto-char (point-min))
598 (while (search-forward "%desc%" nil t)
599 (replace-match desc nil t))
600 (goto-char (point-min))
601 (while (search-forward "%enclosure%" nil t)
602 (replace-match
603 (if (null enclosure)
605 (save-match-data
606 (format
607 "<enclosure url=\"%s\" %stype=\"%s\"/>"
608 (if (string-match "//" enclosure)
609 enclosure
610 (concat (muse-style-element :base-url)
611 enclosure))
612 (let ((file
613 (expand-file-name enclosure
614 (muse-style-element :path))))
615 (if (file-readable-p file)
616 (format "length=\"%d\" "
617 (nth 7 (file-attributes file)))
618 ""))
619 (if (string-match "\\.\\([^.]+\\)$" enclosure)
620 (let* ((ext (match-string 1 enclosure))
621 (type
622 (assoc
623 ext muse-journal-rss-enclosure-types-alist)))
624 (if type
625 (cdr type)
626 "application/octet-stream"))))))
627 nil t))
628 (goto-char (point-min))
629 (while (search-forward "%link%" nil t)
630 (replace-match
631 (concat (muse-style-element :base-url)
632 (concat (muse-page-name)
633 muse-html-extension))
634 nil t))
635 (goto-char (point-min))
636 (while (search-forward "%anchor%" nil t)
637 (replace-match
638 (muse-journal-anchorize-title (or title orig-date))
639 nil t))
640 (goto-char (point-min))
641 (while (search-forward "%maintainer%" nil t)
642 (replace-match
643 (or (muse-style-element :maintainer)
644 (concat "webmaster@" (system-name)))
645 nil t))))))
646 (unless (eobp)
647 (delete-region (point) (point-max)))))
649 (unless (assoc "journal-html" muse-publishing-styles)
650 (muse-derive-style "journal-html" "html"
651 :before-end 'muse-journal-html-munge-buffer)
653 (muse-derive-style "journal-xhtml" "xhtml"
654 :before-end 'muse-journal-html-munge-buffer)
656 (muse-derive-style "journal-latex" "latex"
657 :tags 'muse-journal-latex-markup-tags
658 :before-end 'muse-journal-latex-munge-buffer)
660 (muse-derive-style "journal-pdf" "pdf"
661 :tags 'muse-journal-latex-markup-tags
662 :before-end 'muse-journal-latex-munge-buffer)
664 (muse-derive-style "journal-book-latex" "book-latex"
665 ;;:nochapters
666 :tags 'muse-journal-latex-markup-tags
667 :before-end 'muse-journal-latex-munge-buffer)
669 (muse-derive-style "journal-book-pdf" "book-pdf"
670 ;;:nochapters
671 :tags 'muse-journal-latex-markup-tags
672 :before-end 'muse-journal-latex-munge-buffer)
674 (muse-define-style "journal-rdf"
675 :suffix 'muse-journal-rdf-extension
676 :regexps 'muse-journal-rss-markup-regexps
677 :functions 'muse-journal-rss-markup-functions
678 :before 'muse-journal-rss-munge-buffer
679 :header 'muse-journal-rdf-header
680 :footer 'muse-journal-rdf-footer
681 :date-format 'muse-journal-rdf-date-format
682 :entry-template 'muse-journal-rdf-entry-template
683 :base-url 'muse-journal-rdf-base-url
684 :summarize 'muse-journal-rdf-summarize-entries)
686 (muse-define-style "journal-rss"
687 :suffix 'muse-journal-rss-extension
688 :regexps 'muse-journal-rss-markup-regexps
689 :functions 'muse-journal-rss-markup-functions
690 :before 'muse-journal-rss-munge-buffer
691 :header 'muse-journal-rss-header
692 :footer 'muse-journal-rss-footer
693 :date-format 'muse-journal-rss-date-format
694 :entry-template 'muse-journal-rss-entry-template
695 :base-url 'muse-journal-rss-base-url
696 :summarize 'muse-journal-rss-summarize-entries))
698 (provide 'muse-journal)
700 ;;; muse-journal.el ends here