Merged from mwolson@gnu.org--2006 (patch 51-52)
[muse-el.git] / lisp / muse-blosxom.el
blob8c1d2b0bfb86210ac56b46a4b880d324393bcd6d
1 ;;; muse-blosxom.el --- publish a document tree for serving by (py)Blosxom
3 ;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
5 ;; Date: Wed, 23 March 2005
6 ;; Author: Michael Olson (mwolson AT gnu DOT org)
7 ;; Maintainer: Michael Olson (mwolson AT gnu DOT org)
9 ;; This file is not part of GNU Emacs.
11 ;; This is free software; you can redistribute it and/or modify it under
12 ;; the terms of the GNU General Public License as published by the Free
13 ;; Software Foundation; either version 2, or (at your option) any later
14 ;; version.
16 ;; This is distributed in the hope that it will be useful, but WITHOUT
17 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 ;; for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, USA.
26 ;;; Commentary:
28 ;; The Blosxom publishing style publishes a tree of categorised files
29 ;; to a mirrored tree of stories to be served by blosxom.cgi or
30 ;; pyblosxom.cgi.
32 ;; Serving entries with (py)blosxom
33 ;; --------------------------------
35 ;; Each Blosxom file must include `#date yyyy-mm-dd', or optionally
36 ;; the longer `#date yyyy-mm-dd-hh-mm', a title (using the `#title'
37 ;; directive) plus whatever normal content is desired.
39 ;; The date directive is not used directly by (py)blosxom or this
40 ;; program. You need to find two additional items to make use of this
41 ;; feature.
43 ;; 1. A script to gather date directives from the entire blog tree
44 ;; into a single file. The file must associate a blog entry with
45 ;; a date.
47 ;; 2. A plugin for (py)blosxom that reads this file.
49 ;; These 2 things are provided for pyblosxom in the contrib/pyblosxom
50 ;; subdirectory. `getstamps.py' provides the 1st service, while
51 ;; `hardcodedates.py' provides the second service. Eventually it is
52 ;; hoped that a blosxom plugin and script will be found/written.
54 ;; Generating a Muse project entry
55 ;; -------------------------------
57 ;; Muse-blosxom has some helper functions to make specifying
58 ;; muse-blosxom projects a lot easier. An example follows.
60 ;; (setq muse-project-alist
61 ;; `(("blog"
62 ;; (,@(muse-project-alist-dirs "~/path/to/blog-entries")
63 ;; :default "index")
64 ;; ,@(muse-project-alist-styles "~/path/to/blog-entries"
65 ;; "~/public_html/blog"
66 ;; "blosxom-xhtml")
67 ;; )))
69 ;; Note that we need a backtick instead of a single quote on the
70 ;; second line of this example.
72 ;; Creating new blog entries
73 ;; -------------------------
75 ;; There is a function called `muse-blosxom-new-entry' that will
76 ;; automate the process of making a new blog entry. To make use of
77 ;; it, do the following.
79 ;; - Customize `muse-blosxom-base-directory' to the location that
80 ;; your blog entries are stored.
82 ;; - Assign the `muse-blosxom-new-entry' function to a key sequence.
83 ;; I use the following code to assign this function to `C-c p l'.
85 ;; (global-set-key "\C-cpl" 'muse-blosxom-new-entry)
87 ;; - You should create your directory structure ahead of time under
88 ;; your base directory. These directories, which correspond with
89 ;; category names, may be nested.
91 ;; - When you enter this key sequence, you will be prompted for the
92 ;; category of your entry and its title. Upon entering this
93 ;; information, a new file will be created that corresponds with
94 ;; the title, but in lowercase letters and having special
95 ;; characters converted to underscores. The title and date
96 ;; directives will be inserted automatically.
98 ;; Using tags
99 ;; ----------
101 ;; If you wish to keep all of your blog entries in one directory and
102 ;; use tags to classify your entries, set `muse-blosxom-use-tags' to
103 ;; non-nil.
105 ;; For this to work, you will need to be using the PyBlosxom plugin at
106 ;; http://pyblosxom.sourceforge.net/blog/registry/meta/Tags.
108 ;;; Contributors:
110 ;; Gary Vaughan (gary AT gnu DOT org) is the original author of
111 ;; `emacs-wiki-blosxom.el', which is the ancestor of this file.
113 ;; Brad Collins (brad AT chenla DOT org) ported this file to Muse.
115 ;; Michael Olson (mwolson AT gnu DOT org) further adapted this file to
116 ;; Muse and continues to maintain it.
118 ;; Björn Lindström (bkhl AT elektrubadur DOT se) made many valuable
119 ;; suggestions.
121 ;;; Code:
123 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
125 ;; Muse Blosxom Publishing
127 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
129 (require 'muse-project)
130 (require 'muse-publish)
131 (require 'muse-html)
133 (defgroup muse-blosxom nil
134 "Options controlling the behavior of Muse Blosxom publishing.
135 See `muse-blosxom' for more information."
136 :group 'muse-publish)
138 (defcustom muse-blosxom-extension ".txt"
139 "Default file extension for publishing Blosxom files."
140 :type 'string
141 :group 'muse-blosxom)
143 (defcustom muse-blosxom-header
144 "<lisp>(muse-publishing-directive \"title\")</lisp>
145 <lisp>(when muse-blosxom-use-tags
146 (let ((tags (muse-publishing-directive \"tags\")))
147 (when tags (concat \"#tags \" tags \"\\n\"))))</lisp>"
148 "Header used for publishing Blosxom files. This may be text or a filename."
149 :type 'string
150 :group 'muse-blosxom)
152 (defcustom muse-blosxom-footer ""
153 "Footer used for publishing Blosxom files. This may be text or a filename."
154 :type 'string
155 :group 'muse-blosxom)
157 (defcustom muse-blosxom-base-directory "~/Blog"
158 "Base directory of blog entries.
159 This is the top-level directory where your Muse blog entries may be found."
160 :type 'directory
161 :group 'muse-blosxom)
163 (defcustom muse-blosxom-use-tags nil
164 "Determine whether or not to enable use of the #tags directive.
166 If you wish to keep all of your blog entries in one directory and
167 use tags to classify your entries, set `muse-blosxom-use-tags' to
168 non-nil.
170 For this to work, you will need to be using the PyBlosxom plugin
171 at http://pyblosxom.sourceforge.net/blog/registry/meta/Tags."
172 :type 'boolean
173 :group 'muse-blosxom)
175 ;; Maintain (published-file . date) alist, which will later be written
176 ;; to a timestamps file; not implemented yet.
178 (defvar muse-blosxom-page-date-alist nil)
180 (defun muse-blosxom-update-page-date-alist ()
181 "Add a date entry to `muse-blosxom-page-date-alist' for this page."
182 ;; Make current file be relative to base directory
183 (let ((rel-file
184 (concat
185 (file-name-as-directory
186 (or (muse-publishing-directive "category")
187 (file-relative-name
188 (file-name-directory
189 (expand-file-name muse-publishing-current-file))
190 (file-truename muse-blosxom-base-directory))))
191 (file-name-nondirectory muse-publishing-current-file))))
192 ;; Strip the file extension
193 (when muse-ignored-extensions-regexp
194 (setq rel-file (save-match-data
195 (and (string-match muse-ignored-extensions-regexp
196 rel-file)
197 (replace-match "" t t rel-file)))))
198 ;; Add to page-date alist
199 (add-to-list
200 'muse-blosxom-page-date-alist
201 `(,rel-file . ,(muse-publishing-directive "date")))))
203 ;; Enter a new blog entry
205 (defun muse-blosxom-title-to-file (title)
206 "Derive a file name from the given TITLE.
208 Feel free to overwrite this if you have a different concept of what
209 should be allowed in a filename."
210 (muse-replace-regexp-in-string (concat "[^-." muse-regexp-alnum "]")
211 "_" (downcase title)))
213 ;;;###autoload
214 (defun muse-blosxom-new-entry (category title)
215 "Start a new blog entry with given CATEGORY.
216 The filename of the blog entry is derived from TITLE.
217 The page will be initialized with the current date and TITLE."
218 (interactive
219 (list
220 (if muse-blosxom-use-tags
221 (let ((tag "foo")
222 (tags nil))
223 (while (progn (setq tag (read-string "Tag (RET to continue): "))
224 (not (string= tag "")))
225 (add-to-list 'tags tag t))
226 tags)
227 (completing-read "Category: "
228 (mapcar 'list (muse-project-recurse-directory
229 muse-blosxom-base-directory))))
230 (read-string "Title: ")))
231 (let ((file (muse-blosxom-title-to-file title)))
232 (muse-project-find-file
233 file "blosxom" nil
234 (if muse-blosxom-use-tags
235 (directory-file-name muse-blosxom-base-directory)
236 (concat (directory-file-name muse-blosxom-base-directory)
237 "/" category))))
238 (goto-char (point-min))
239 (insert "#date " (format-time-string "%4Y-%2m-%2d-%2H-%2M")
240 (if muse-blosxom-use-tags
241 (concat "\n#tags " (mapconcat #'identity category ","))
242 (concat "\n#category " category))
243 "\n#title " title
244 "\n\n")
245 (forward-line 2))
247 ;; Register the Blosxom Publisher
249 (unless (assoc "blosxom-html" muse-publishing-styles)
250 (muse-derive-style "blosxom-html" "html"
251 :suffix 'muse-blosxom-extension
252 :link-suffix 'muse-html-extension
253 :header 'muse-blosxom-header
254 :footer 'muse-blosxom-footer
255 :after 'muse-blosxom-update-page-date-alist)
257 (muse-derive-style "blosxom-xhtml" "xhtml"
258 :suffix 'muse-blosxom-extension
259 :link-suffix 'muse-xhtml-extension
260 :header 'muse-blosxom-header
261 :footer 'muse-blosxom-footer
262 :after 'muse-blosxom-update-page-date-alist))
264 (provide 'muse-blosxom)
266 ;;; muse-blosxom.el ends here