diff --git a/elpa/muse-3.20.signed b/elpa/muse-3.20.signed new file mode 100644 index 0000000..65375d2 --- /dev/null +++ b/elpa/muse-3.20.signed @@ -0,0 +1 @@ +Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent (trust undefined) created at 2014-09-24T16:20:17+0200 using DSA \ No newline at end of file diff --git a/elpa/muse-3.20/ChangeLog b/elpa/muse-3.20/ChangeLog new file mode 100644 index 0000000..d5560a7 --- /dev/null +++ b/elpa/muse-3.20/ChangeLog @@ -0,0 +1,40 @@ +2012-10-30 Stefan Monnier + + Clean up copyright notices. + +2011-07-30 Chong Yidong + + Add Texinfo files for muse package. + +2011-07-01 Chong Yidong + + Remove version numbers from filenames in packages/ dir. + +2011-06-30 Chong Yidong + + Remove version numbers in packages/ directory + +2011-01-09 Chong Yidong + + Make Muse's *-link faces inherit from the basic link face. + + * packages/muse-3.20/muse-colors.el (muse-link, muse-bad-link): + Inherit from link face. + +2010-11-20 Ted Zlatanov + + * COPYING, ChangeLog, README, admin/org-synch.el, + admin/org-synch.sh, admin/package-update.sh: Initial import. + + * packages/archive-contents, packages/auctex-11.86, + packages/auctex-readme.txt, packages/company-0.5/, + packages/company-readme.txt, packages/elpa.rss, + packages/js2-mode-20090814.el, packages/js2-mode-readme.txt, + packages/muse-3.20/, packages/muse-readme.txt, + packages/org-readme.txt, packages/rainbow-mode-0.1.el, + packages/rainbow-mode-readme.txt: Renamed from the root directory. + +2010-11-18 ELPA admin + + Initial repository contents + diff --git a/elpa/muse-3.20/README b/elpa/muse-3.20/README new file mode 100644 index 0000000..5f6e20e --- /dev/null +++ b/elpa/muse-3.20/README @@ -0,0 +1,7 @@ +Muse is a tool for easily authoring and publishing documents. It +allows for rapid prototyping of hyperlinked text, which may then be +exported to multiple output formats, such as HTML, LaTeX, and Texinfo. + +The markup rules used by Muse are intended to be very friendly to +people familiar with Emacs. See the included manual for more +information. diff --git a/elpa/muse-3.20/cgi.el b/elpa/muse-3.20/cgi.el new file mode 100644 index 0000000..936b33f --- /dev/null +++ b/elpa/muse-3.20/cgi.el @@ -0,0 +1,217 @@ +;;; cgi.el -- Using Emacs for CGI scripting + +;; Copyright (C) 2000, 2006, 2012 Free Software Foundation, Inc. + +;; Author: Eric Marsden +;; Michael Olson (slight modifications) +;; Keywords: CGI web scripting slow +;; Version: 0.3 +;; Time-stamp: <2001-08-24 emarsden> + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3 of +;; the License, or (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public +;; License along with this program; if not, write to the Free +;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +;; MA 02111-1307, USA. + +;;; Commentary: + +;; People who like this sort of thing will find this the sort of +;; thing they like. -- Abraham Lincoln +;; +;; +;; Overview ========================================================== +;; +;; A simple library for the Common Gateway Interface for Emacs, +;; allowing you to service requests for non static web pages in elisp. +;; Provides routines for decoding arguments to GET- and POST-type CGI +;; requests. +;; +;; Usage: place a shell script such as the following in your web +;; server's CGI directory (typically called something like +;; /var/www/cgi-bin/): +;; +;; ,------------------------------------------------------------------- +;; | #!/bin/sh +;; | +;; | emacs -batch -l cgi.el -f cgi-calendar +;; `------------------------------------------------------------------- +;; +;; (`cgi-calendar' is a sample elisp CGI script provided at the end of +;; this file). +;; +;; Alternatively, if you're running version 2.x of the linux kernel +;; you could make .elc files directly executable via the binfmt_misc +;; mechanism and run them straight from the cgi-bin directory. +;; +;; Efficiency would be improved by having Emacs bind to the http +;; service port and spawn a thread per connection. Extending Emacs to +;; support server sockets and multithreading is left as an exercise +;; for the reader. +;; +;; References: +;; * rfc1738 "Uniform Resource Locators" +;; * rfc1630 "Universal Resource Identifiers in WWW" +;; +;; Thanks to Christoph Conrad for pointing +;; out a bug in the URI-decoding. + +;;; Code: + +(eval-when-compile + (require 'cl) + (require 'calendar)) + +(defconst cgi-url-unreserved-chars '( + ?a ?b ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l ?m + ?n ?o ?p ?q ?r ?s ?t ?u ?v ?w ?x ?y ?z + ?A ?B ?C ?D ?E ?F ?G ?H ?I ?J ?K ?L ?M + ?N ?O ?P ?Q ?R ?S ?T ?U ?V ?W ?X ?Y ?Z + ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 + ?\$ ?\- ?\_ ?\. ?\! ?\~ ?\* ?\' ?\( ?\) ?\,)) + +(defun cgi-int-char (i) + (if (fboundp 'int-char) (int-char i) i)) + +(defun cgi-hex-char-p (ch) + (declare (character ch)) + (let ((hexchars '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 + ?A ?B ?C ?D ?E ?F))) + (member (upcase ch) hexchars))) + +;; decode %xx to the corresponding character and + to ' ' +(defun cgi-decode-string (str) + (do ((i 0) + (len (length str)) + (decoded '())) + ((>= i len) (concat (nreverse decoded))) + (let ((ch (aref str i))) + (cond ((eq ?+ ch) + (push ?\ decoded) + (incf i)) + ((and (eq ?% ch) + (< (+ i 2) len) + (cgi-hex-char-p (aref str (+ i 1))) + (cgi-hex-char-p (aref str (+ i 2)))) + (let ((hex (string-to-number (substring str (+ i 1) (+ i 3)) 16))) + (push (cgi-int-char hex) decoded) + (incf i 3))) + (t (push ch decoded) + (incf i)))))) + +(defun cgi-position (item seq &optional start end) + (or start (setq start 0)) + (or end (setq end (length seq))) + (while (and (< start end) + (not (equal item (aref seq start)))) + (setq start (1+ start))) + (and (< start end) start)) + +;; Parse "foo=x&bar=y+re" into (("foo" . "x") ("bar" . "y re")) +;; Substrings are plus-decoded and then URI-decoded. +(defun cgi-decode (q) + (when q + (flet ((split-= (str) + (let ((pos (or (cgi-position ?= str) 0))) + (cons (cgi-decode-string (substring str 0 pos)) + (cgi-decode-string (substring str (+ pos 1))))))) + (mapcar #'split-= (split-string q "&"))))) + +(defun cgi-lose (fmt &rest args) + (let ((why (apply #'format fmt args))) + (message "Script error: %s" why) ; to error_log + (princ "Content-type: text/html\n\n") ; to browser + (princ "Script error\r\n") + (princ "

Script error

\r\n

\r\n") + (princ why) + (princ "\r\n\r\n") + (kill-emacs 0))) + +(defmacro cgi-evaluate (&rest forms) + `(condition-case why + (princ (with-output-to-string ,@forms)) + (error (cgi-lose "Emacs Lisp error: %s" why)))) + +(defun cgi-arguments () + (let ((method (getenv "REQUEST_METHOD")) + req buf) + (cond ((null method) + (cgi-lose "No request method specified")) + ((string= "GET" method) + (unless (getenv "QUERY_STRING") + (cgi-lose "No query string for GET request")) + (cgi-decode (getenv "QUERY_STRING"))) + ((string= "POST" method) + (setq req (getenv "CONTENT_LENGTH")) + (unless req + (cgi-lose "No content-length for POST request")) + (setq buf (get-buffer-create " *cgi*")) + (set-buffer buf) + (erase-buffer) + (loop for i from 1 to (string-to-number req) + do (insert (read-event))) + (cgi-decode (buffer-string))) + (t + (cgi-lose "Can't handle request method %s" method))))) + +;; ==================================================================== +;; a sample application: calendar via the web. If invoked without +;; arguments, presents a calendar for the three months around the +;; current date. You can request a calendar for a specific period by +;; specifying the year and the month in the query string: +;; +;; ~$ lynx -dump 'http://localhost/cgi-bin/cal?year=1975&month=6' +;; +;; When run in batch mode, text normally displayed in the echo area +;; (via `princ' for example) goes to stdout, and thus to the browser. +;; Text output using `message' goes to stderr, and thus normally to +;; your web server's error_log. +;; ==================================================================== + +(eval-and-compile + (if (fboundp 'calendar-extract-month) + (defalias 'cgi-calendar-extract-month 'calendar-extract-month) + (defalias 'cgi-calendar-extract-month 'extract-calendar-month)) + + (if (fboundp 'calendar-extract-year) + (defalias 'cgi-calendar-extract-year 'calendar-extract-year) + (defalias 'cgi-calendar-extract-year 'extract-calendar-year)) + + (if (fboundp 'calendar-generate) + (defalias 'cgi-calendar-generate 'calendar-generate) + (defalias 'cgi-calendar-generate 'generate-calendar))) + +(defun cgi-calendar-string () + (require 'calendar) + (let* ((args (cgi-arguments)) + (now (calendar-current-date)) + (mnth (cdr (assoc "month" args))) + (month (if mnth (string-to-number mnth) + (cgi-calendar-extract-month now))) + (yr (cdr (assoc "year" args))) + (year (if yr (string-to-number yr) + (cgi-calendar-extract-year now)))) + (with-temp-buffer + (cgi-calendar-generate month year) + (buffer-string)))) + +(defun cgi-calendar () + (cgi-evaluate + (princ "Content-type: text/html\n\n") + (princ "Emacs calendar\r\n") + (princ "

Emacs calendar

\r\n") + (princ "
\r\n")
+   (princ (cgi-calendar-string))
+   (princ "\r\n
\r\n"))) + +(provide 'cgi) +;;; cgi.el ends here diff --git a/elpa/muse-3.20/dir b/elpa/muse-3.20/dir new file mode 100644 index 0000000..22af354 --- /dev/null +++ b/elpa/muse-3.20/dir @@ -0,0 +1,18 @@ +This is the file .../info/dir, which contains the +topmost node of the Info hierarchy, called (dir)Top. +The first time you invoke Info you start off looking at this node. + +File: dir, Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "?" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs" visits the Emacs manual, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: + +Emacs +* Muse: (muse). Authoring and publishing environment for Emacs. diff --git a/elpa/muse-3.20/htmlize-hack.el b/elpa/muse-3.20/htmlize-hack.el new file mode 100644 index 0000000..4c9e5e8 --- /dev/null +++ b/elpa/muse-3.20/htmlize-hack.el @@ -0,0 +1,19 @@ +;; This file provides a fix for htmlize.el and Emacs 23. +;; To use it, add the path to this directory to your load path and +;; add (require 'htmlize-hack) to your Emacs init file. + +(require 'htmlize) + +(when (equal htmlize-version "1.34") + (defun htmlize-face-size (face) + ;; The size (height) of FACE, taking inheritance into account. + ;; Only works in Emacs 21 and later. + (let ((size-list + (loop + for f = face then (face-attribute f :inherit) + until (or (null f) (eq f 'unspecified)) + for h = (face-attribute f :height) + collect (if (eq h 'unspecified) nil h)))) + (reduce 'htmlize-merge-size (cons nil size-list))))) + +(provide 'htmlize-hack) diff --git a/elpa/muse-3.20/httpd.el b/elpa/muse-3.20/httpd.el new file mode 100644 index 0000000..1fb64a4 --- /dev/null +++ b/elpa/muse-3.20/httpd.el @@ -0,0 +1,288 @@ +;;; httpd.el -- A web server in Emacs Lisp + +;; Copyright (C) 2001, 2003, 2006, 2012 Free Software Foundation, Inc. + +;; Author: Eric Marsden +;; John Wiegley +;; Michael Olson (slight modifications) +;; Version: 1.1 +;; Keywords: games + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3 of +;; the License, or (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public +;; License along with this program; if not, write to the Free +;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +;; MA 02111-1307, USA. +;; +;; The latest version of this package should be available from +;; +;; + +;;; Commentary: + +;; httpd.el is an HTTP server embedded in the Emacs. It can handle GET +;; and HEAD requests; adding support for POST should not be too +;; difficult. By default, httpd.el will listen on server side Emacs +;; sockets for HTTP requests. +;; +;; I have only tested this code with Emacs; it may need modifications +;; to work with XEmacs. +;; +;; This version has been modified to work with GNU Emacs 21 and 22. +;; +;;; Acknowledgements: +;; +;; httpd.el was inspired by pshttpd, an HTTP server written in +;; Postscript by Anders Karlsson . +;; +;; Thanks to John Wiegley and Cyprian Adam Laskowski. + +;;; Code: + +(defvar httpd-document-root "/var/www") + +(defvar httpd-path-handlers '() + "Alist of (path-regexp . handler) forms. +If a GET request is made for an URL whose path component matches +a PATH-REGEXP, the corresponding handler is called to generate +content.") + +(defvar httpd-mime-types-alist + '(("html" . "text/html; charset=iso-8859-1") + ("txt" . "text/plain; charset=iso-8859-1") + ("jpg" . "image/jpeg") + ("jpeg" . "image/jpeg") + ("gif" . "image/gif") + ("png" . "image/png") + ("tif" . "image/tiff") + ("tiff" . "image/tiff") + ("css" . "text/css") + ("gz" . "application/octet-stream") + ("ps" . "application/postscript") + ("pdf" . "application/pdf") + ("eps" . "application/postscript") + ("tar" . "application/x-tar") + ("rpm" . "application/x-rpm") + ("zip" . "application/zip") + ("mp3" . "audio/mpeg") + ("mp2" . "audio/mpeg") + ("mid" . "audio/midi") + ("midi" . "audio/midi") + ("wav" . "audio/x-wav") + ("au" . "audio/basic") + ("ram" . "audio/pn-realaudio") + ("ra" . "audio/x-realaudio") + ("mpg" . "video/mpeg") + ("mpeg" . "video/mpeg") + ("qt" . "video/quicktime") + ("mov" . "video/quicktime") + ("avi" . "video/x-msvideo"))) + +(defun httpd-mime-type (filename) + (or (cdr (assoc (file-name-extension filename) httpd-mime-types-alist)) + "text/plain")) + +(put 'httpd-exception 'error-conditions '(httpd-exception error)) + +(defun defhttpd-exception (name code msg) + (put name 'error-conditions (list name 'httpd-exception 'error)) + (put name 'httpd-code code) + (put name 'httpd-msg msg)) + +(defhttpd-exception 'httpd-moved/perm 301 "Moved permanently") +(defhttpd-exception 'httpd-moved/temp 302 "Moved temporarily") +(defhttpd-exception 'httpd-bad-request 400 "Bad request") +(defhttpd-exception 'httpd-forbidden 403 "Forbidden") +(defhttpd-exception 'httpd-file-not-found 404 "Not found") +(defhttpd-exception 'httpd-method-forbidden 405 "Method not allowed") +(defhttpd-exception 'httpd-unimplemented 500 "Internal server error") +(defhttpd-exception 'httpd-unimplemented 501 "Not implemented") +(defhttpd-exception 'httpd-unimplemented 503 "Service unavailable") + +(defvar httpd-endl "\r\n") + +(defvar httpd-process nil) +(defvar httpd-bytes-sent nil) ; only used with `httpd-process' +(defvar httpd-log-accesses t) + +(defun httpd-add-handler (path-regexp handler) + (push (cons path-regexp handler) httpd-path-handlers)) + +(defun httpd-try-internal-handler (path &optional cont) + (catch 'result + (dolist (elem httpd-path-handlers) + (let ((regexp (car elem)) + (handler (cdr elem))) + (if (string-match regexp path) + (throw 'result (funcall handler path cont))))))) + +(defun httpd-date-stamp () + (format-time-string "[%d/%b/%Y %H:%M:%S %z]")) + +(defun httpd-log (&rest strings) + (if httpd-log-accesses + (save-excursion + (goto-char (point-max)) + (with-current-buffer (get-buffer-create "*httpd access_log*") + (mapc 'insert strings))))) + +(defun httpd-send-data (&rest strings) + (dolist (s strings) + (send-string httpd-process s) + (if httpd-bytes-sent + (setq httpd-bytes-sent (+ httpd-bytes-sent (length s)))))) + +(defun httpd-send (code msg &rest strings) + (httpd-log (number-to-string code) " ") + (apply 'httpd-send-data + "HTTP/1.0 " (number-to-string code) " " msg httpd-endl + strings)) + +(defun httpd-send-eof () + (httpd-log (number-to-string httpd-bytes-sent) "\n") + (process-send-eof httpd-process)) + +(defun httpd-send-file (filename) + (with-temp-buffer + (insert-file-contents filename) + (httpd-send-data (buffer-string)))) + +(defun httpd-lose (code msg) + (httpd-send code msg + "Content-Type: text/html" httpd-endl + "Connection: close" httpd-endl + httpd-endl + "Error" httpd-endl + "

" msg "

" httpd-endl + "

" msg httpd-endl + "" httpd-endl) + (httpd-send-eof)) + +(defun httpd-handle-redirect (req where) + "Redirect the client to new location WHERE." + (httpd-send 301 "Moved permanently" + "Location: " where httpd-endl + "URI: " where httpd-endl + "Connection: close" httpd-endl + httpd-endl) + (httpd-send-eof)) + +(defun httpd-handle-GET+HEAD (path &optional want-data req) + (if (zerop (length path)) + (setq path "index.html")) + + ;; could use `expand-file-name' here instead of `concat', but we + ;; don't want tilde expansion, etc. + (let ((filename (concat httpd-document-root "/" path)) + modified-since) + (cond ((httpd-try-internal-handler path) t) + ((file-directory-p filename) + (httpd-handle-redirect path (concat "http://" (system-name) "/" + path "/"))) + ((file-readable-p filename) + (let ((attrs (file-attributes filename))) + (if (and (string-match "^If-Modified-Since:\\s-+\\(.+\\)" req) + (setq modified-since + (apply 'encode-time + (parse-time-string (match-string 1 req)))) + (time-less-p (nth 5 attrs) modified-since)) + (httpd-send 304 "Not modified" + "Server: Emacs/httpd.el" httpd-endl + "Connection: close" httpd-endl + httpd-endl) + (httpd-send 200 "OK" + "Server: Emacs/httpd.el" httpd-endl + "Connection: close" httpd-endl + "MIME-Version: 1.0" httpd-endl + "Content-Type: " + (httpd-mime-type filename) httpd-endl + "Content-Length: " + (number-to-string (nth 7 attrs)) httpd-endl + httpd-endl) + (if want-data + (httpd-send-file filename))) + (httpd-send-eof))) + + (t (signal 'httpd-file-not-found path))))) + +(defun httpd-handle-request (req &optional cont) + (httpd-log (car (process-contact httpd-process)) " - - " + (httpd-date-stamp) " \"") + (if (not (string-match ".+" req)) + (progn + (httpd-log "\"") + (error "HTTP request was empty")) + (let ((request (match-string 0 req))) + (httpd-log request "\" ") + (cond + ((string-match "\\.\\." request) + ;; reject requests containing ".." in the path. Should really + ;; URI-decode first. + (signal 'httpd-forbidden request)) + + ((string-match "\\`\\(GET\\|HEAD\\|POST\\)\\s-/\\(\\S-*\\)" request) + (let ((kind (match-string 1 request)) + (arg (match-string 2 request))) + (if (string= kind "POST") + (unless (httpd-try-internal-handler arg cont) + (signal 'httpd-unimplemented arg)) + (httpd-handle-GET+HEAD arg (string= kind "GET") req)))) + + (t (signal 'httpd-bad-request request)))))) + +(defun httpd-serve (proc string) + (let ((httpd-process proc) + (httpd-bytes-sent 0)) + (condition-case why + (httpd-handle-request string) + (httpd-exception + (httpd-lose (get (car why) 'httpd-code) + (get (car why) 'httpd-msg))) + ;; Comment out these two lines if you want to catch errors + ;; inside Emacs itself. + (error + (httpd-lose 500 (format "Emacs Lisp error: %s" why))) + ))) + +(defun httpd-start (&optional port) + (interactive (list (read-string "Serve Web requests on port: " "8080"))) + (if (null port) + (setq port 8080) + (if (stringp port) + (setq port (string-to-number port)))) + (if httpd-process + (delete-process httpd-process)) + (setq httpd-process + (if (fboundp 'make-network-process) + (make-network-process :name "httpd" + :buffer (generate-new-buffer "httpd") + :host 'local :service port + :server t :noquery t + :filter 'httpd-serve) + (and (fboundp 'open-network-stream-server) + (open-network-stream-server "httpd" + (generate-new-buffer "httpd") + port nil 'httpd-serve)))) + (if (and (processp httpd-process) + (eq (process-status httpd-process) 'listen)) + (message "httpd.el is listening on port %d" port))) + +(defun httpd-stop () + (interactive) + (when httpd-process + (message "httpd.el server on port %d has stopped" + (cadr (process-contact httpd-process))) + (delete-process httpd-process) + (setq httpd-process nil))) + +(provide 'httpd) +;;; httpd.el ends here diff --git a/elpa/muse-3.20/muse-autoloads.el b/elpa/muse-3.20/muse-autoloads.el new file mode 100644 index 0000000..86f3b0a --- /dev/null +++ b/elpa/muse-3.20/muse-autoloads.el @@ -0,0 +1,277 @@ +;;; muse-autoloads.el --- automatically extracted autoloads +;; +;;; Code: +(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) + +;;;### (autoloads nil "muse" "muse.el" (21705 22861 643843 136000)) +;;; Generated autoloads from muse.el + (add-to-list 'auto-mode-alist '("\\.muse\\'" . muse-mode-choose-mode)) + +;;;*** + +;;;### (autoloads nil "muse-blosxom" "muse-blosxom.el" (21705 22862 +;;;;;; 348828 281000)) +;;; Generated autoloads from muse-blosxom.el + +(autoload 'muse-blosxom-new-entry "muse-blosxom" "\ +Start a new blog entry with given CATEGORY. +The filename of the blog entry is derived from TITLE. +The page will be initialized with the current date and TITLE. + +\(fn CATEGORY TITLE)" t nil) + +;;;*** + +;;;### (autoloads nil "muse-colors" "muse-colors.el" (21705 22862 +;;;;;; 65834 245000)) +;;; Generated autoloads from muse-colors.el + +(autoload 'muse-colors-toggle-inline-images "muse-colors" "\ +Toggle display of inlined images on/off. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil "muse-import-docbook" "muse-import-docbook.el" +;;;;;; (21705 22862 962815 340000)) +;;; Generated autoloads from muse-import-docbook.el + +(autoload 'muse-import-docbook "muse-import-docbook" "\ +Convert the Docbook buffer SRC to Muse, writing output in the DEST buffer. + +\(fn SRC DEST)" t nil) + +(autoload 'muse-import-docbook-files "muse-import-docbook" "\ +Convert the Docbook file SRC to Muse, writing output to the DEST file. + +\(fn SRC DEST)" t nil) + +;;;*** + +;;;### (autoloads nil "muse-import-latex" "muse-import-latex.el" +;;;;;; (21705 22861 560844 887000)) +;;; Generated autoloads from muse-import-latex.el + +(autoload 'muse-import-latex "muse-import-latex" "\ + + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil "muse-mode" "muse-mode.el" (21705 22863 3814 +;;;;;; 476000)) +;;; Generated autoloads from muse-mode.el + +(autoload 'muse-mode "muse-mode" "\ +Muse is an Emacs mode for authoring and publishing documents. +\\{muse-mode-map} + +\(fn)" t nil) + +(autoload 'muse-mode-choose-mode "muse-mode" "\ +Turn the proper Emacs Muse related mode on for this file. + +\(fn)" nil nil) + +(autoload 'muse-insert-list-item "muse-mode" "\ +Insert a list item at the current point, taking into account +your current list type and indentation level. + +\(fn)" t nil) + +(autoload 'muse-increase-list-item-indentation "muse-mode" "\ +Increase the indentation of the current list item. + +\(fn)" t nil) + +(autoload 'muse-decrease-list-item-indentation "muse-mode" "\ +Decrease the indentation of the current list item. + +\(fn)" t nil) + +(autoload 'muse-insert-relative-link-to-file "muse-mode" "\ +Insert a relative link to a file, with optional description, at point. + +\(fn)" t nil) + +(autoload 'muse-edit-link-at-point "muse-mode" "\ +Edit the current link. +Do not rename the page originally referred to. + +\(fn)" t nil) + +(autoload 'muse-browse-result "muse-mode" "\ +Visit the current page's published result. + +\(fn STYLE &optional OTHER-WINDOW)" t nil) + +(autoload 'muse-follow-name-at-point "muse-mode" "\ +Visit the link at point. + +\(fn &optional OTHER-WINDOW)" t nil) + +(autoload 'muse-follow-name-at-point-other-window "muse-mode" "\ +Visit the link at point in other window. + +\(fn)" t nil) + +(autoload 'muse-next-reference "muse-mode" "\ +Move forward to next Muse link or URL, cycling if necessary. + +\(fn)" t nil) + +(autoload 'muse-previous-reference "muse-mode" "\ +Move backward to the next Muse link or URL, cycling if necessary. +In case of Emacs x <= 21 and ignoring of intangible properties (see +`muse-mode-intangible-links'). + +This function is not entirely accurate, but it's close enough. + +\(fn)" t nil) + +(autoload 'muse-what-changed "muse-mode" "\ +Show the unsaved changes that have been made to the current file. + +\(fn)" t nil) + +(autoload 'muse-search-with-command "muse-mode" "\ +Search for the given TEXT string in the project directories +using the specified command. + +\(fn TEXT)" t nil) + +(autoload 'muse-search "muse-mode" "\ +Search for the given TEXT using the default grep command. + +\(fn)" t nil) + +(autoload 'muse-find-backlinks "muse-mode" "\ +Grep for the current pagename in all the project directories. + +\(fn)" t nil) + +(autoload 'muse-index "muse-mode" "\ +Display an index of all known Muse pages. + +\(fn)" t nil) + +(autoload 'muse-insert-tag "muse-mode" "\ +Insert a tag interactively with a blank line after it. + +\(fn TAG)" t nil) + +(autoload 'muse-list-edit-minor-mode "muse-mode" "\ +This is a global minor mode for editing files with lists. +It is meant to be used with other major modes, and not with Muse mode. + +Interactively, with no prefix argument, toggle the mode. +With universal prefix ARG turn mode on. +With zero or negative ARG turn mode off. + +This minor mode provides the Muse keybindings for editing lists, +and support for filling lists properly. + +It recognizes not only Muse-style lists, which use the \"-\" +character or numbers, but also lists that use asterisks or plus +signs. This should make the minor mode generally useful. + +Definition lists and footnotes are also recognized. + +Note that list items may omit leading spaces, for compatibility +with modes that set `left-margin', such as +`debian-changelog-mode'. + +\\{muse-list-edit-minor-mode-map} + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads nil "muse-project" "muse-project.el" (21705 22862 +;;;;;; 680821 283000)) +;;; Generated autoloads from muse-project.el + +(autoload 'muse-project-find-file "muse-project" "\ +Open the Muse page given by NAME in PROJECT. +If COMMAND is non-nil, it is the function used to visit the file. +If DIRECTORY is non-nil, it is the directory in which the page +will be created if it does not already exist. Otherwise, the +first directory within the project's fileset is used. + +\(fn NAME PROJECT &optional COMMAND DIRECTORY)" t nil) + +(autoload 'muse-project-publish-this-file "muse-project" "\ +Publish the currently-visited file according to `muse-project-alist', +prompting if more than one style applies. + +If FORCE is given, publish the file even if it is up-to-date. + +If STYLE is given, use that publishing style rather than +prompting for one. + +\(fn &optional FORCE STYLE)" t nil) + +(autoload 'muse-project-publish "muse-project" "\ +Publish the pages of PROJECT that need publishing. + +\(fn PROJECT &optional FORCE)" t nil) + +;;;*** + +;;;### (autoloads nil "muse-protocols" "muse-protocols.el" (21705 +;;;;;; 22862 389827 417000)) +;;; Generated autoloads from muse-protocols.el + +(autoload 'muse-browse-url "muse-protocols" "\ +Handle URL with the function specified in `muse-url-protocols'. +If OTHER-WINDOW is non-nil, open in a different window. + +\(fn URL &optional OTHER-WINDOW)" t nil) + +;;;*** + +;;;### (autoloads nil "muse-publish" "muse-publish.el" (21705 22862 +;;;;;; 730820 230000)) +;;; Generated autoloads from muse-publish.el + +(autoload 'muse-publish-region "muse-publish" "\ +Apply the given STYLE's markup rules to the given region. +The result is placed in a new buffer that includes TITLE in its name. + +\(fn BEG END &optional TITLE STYLE)" t nil) + +(autoload 'muse-publish-file "muse-publish" "\ +Publish the given FILE in a particular STYLE to OUTPUT-DIR. +If the argument FORCE is nil, each file is only published if it is +newer than the published version. If the argument FORCE is non-nil, +the file is published no matter what. + +\(fn FILE STYLE &optional OUTPUT-DIR FORCE)" t nil) + +(autoload 'muse-publish-this-file "muse-publish" "\ +Publish the currently-visited file. +Prompt for both the STYLE and OUTPUT-DIR if they are not +supplied. + +\(fn STYLE OUTPUT-DIR &optional FORCE)" t nil) + +;;;*** + +;;;### (autoloads nil nil ("cgi.el" "htmlize-hack.el" "httpd.el" +;;;;;; "muse-backlink.el" "muse-book.el" "muse-context.el" "muse-docbook.el" +;;;;;; "muse-groff.el" "muse-html.el" "muse-http.el" "muse-ikiwiki.el" +;;;;;; "muse-import-xml.el" "muse-ipc.el" "muse-journal.el" "muse-latex.el" +;;;;;; "muse-latex2png.el" "muse-pkg.el" "muse-poem.el" "muse-regexps.el" +;;;;;; "muse-texinfo.el" "muse-wiki.el" "muse-xml-common.el" "muse-xml.el") +;;;;;; (21705 22863 153833 598000)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; End: +;;; muse-autoloads.el ends here diff --git a/elpa/muse-3.20/muse-backlink.el b/elpa/muse-3.20/muse-backlink.el new file mode 100644 index 0000000..bc21ddd --- /dev/null +++ b/elpa/muse-3.20/muse-backlink.el @@ -0,0 +1,327 @@ +;;; muse-backlink.el --- backlinks for Muse + +;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; Author: Jim Ottaway +;; Keywords: + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; Hierarchical backlink insertion into new muse pages. +;; +;; To add: +;; +;; (require 'muse-backlink) +;; (muse-backlink-install) +;; +;; To control what gets backlinked, modify +;; `muse-backlink-exclude-backlink-regexp' and +;; `muse-backlink-exclude-backlink-parent-regexp'. +;; +;; To stop backlinking temporarily: +;; (setq muse-backlink-create-backlinks nil) +;; +;; To remove the backlink functionality completely: +;; +;; (muse-backlink-remove) + +;;; Contributors: + +;;; Code: + +(require 'muse) +(require 'muse-project) + +(eval-when-compile (require 'muse-mode)) + +(eval-and-compile + (if (< emacs-major-version 22) + (progn + ;; Swiped from Emacs 22.0.50.4 + (defvar muse-backlink-split-string-default-separators "[ \f\t\n\r\v]+" + "The default value of separators for `split-string'. + +A regexp matching strings of whitespace. May be locale-dependent +\(as yet unimplemented). Should not match non-breaking spaces. + +Warning: binding this to a different value and using it as default is +likely to have undesired semantics.") + + (defun muse-backlink-split-string (string &optional separators omit-nulls) + "Split STRING into substrings bounded by matches for SEPARATORS. + +The beginning and end of STRING, and each match for SEPARATORS, are +splitting points. The substrings matching SEPARATORS are removed, and +the substrings between the splitting points are collected as a list, +which is returned. + +If SEPARATORS is non-nil, it should be a regular expression matching text +which separates, but is not part of, the substrings. If nil it defaults to +`split-string-default-separators', normally \"[ \\f\\t\\n\\r\\v]+\", and +OMIT-NULLS is forced to t. + +If OMIT-NULLS is t, zero-length substrings are omitted from the list \(so +that for the default value of SEPARATORS leading and trailing whitespace +are effectively trimmed). If nil, all zero-length substrings are retained, +which correctly parses CSV format, for example. + +Note that the effect of `(split-string STRING)' is the same as +`(split-string STRING split-string-default-separators t)'). In the rare +case that you wish to retain zero-length substrings when splitting on +whitespace, use `(split-string STRING split-string-default-separators)'. + +Modifies the match data; use `save-match-data' if necessary." + (let ((keep-nulls (not (if separators omit-nulls t))) + (rexp (or separators muse-backlink-split-string-default-separators)) + (start 0) + notfirst + (list nil)) + (while (and (string-match rexp string + (if (and notfirst + (= start (match-beginning 0)) + (< start (length string))) + (1+ start) start)) + (< start (length string))) + (setq notfirst t) + (if (or keep-nulls (< start (match-beginning 0))) + (setq list + (cons (substring string start (match-beginning 0)) + list))) + (setq start (match-end 0))) + (if (or keep-nulls (< start (length string))) + (setq list + (cons (substring string start) + list))) + (nreverse list)))) + (defalias 'muse-backlink-split-string 'split-string))) + +(defgroup muse-backlink nil + "Hierarchical backlinking for Muse." + :group 'muse) + +(defcustom muse-backlink-create-backlinks t + "When non-nil, create hierarchical backlinks in new Muse pages. +For control over which pages will receive backlinks, see +`muse-backlink-exclude-backlink-parent-regexp' and +`muse-backlink-exclude-backlink-regexp'." + :type 'boolean + :group 'muse-backlink) + +(defcustom muse-backlink-avoid-bad-links t + "When non-nil, avoid bad links when backlinking." + :type 'boolean + :group 'muse-backlink) + +;; The default for exclusion stops backlinks from being added to and +;; from planner day pages. +(defcustom muse-backlink-exclude-backlink-parent-regexp + "^[0-9][0-9][0-9][0-9]\\.[0-9][0-9]\\.[0-9][0-9]$" + "Regular expression matching pages whose children should not have backlinks." + :type 'regexp + :group 'muse-backlink) + +(defcustom muse-backlink-exclude-backlink-regexp + "^[0-9][0-9][0-9][0-9]\\.[0-9][0-9]\\.[0-9][0-9]$" + "Regular expression matching pages that should not have backlinks." + :type 'regexp + :group 'muse-backlink) + +(defcustom muse-backlink-separator "/" + "String that separates backlinks. +Should be something that will not appear as a substring in an explicit +link that has no description." + :type 'string + :group 'muse-backlink) + +(defcustom muse-backlink-before-string "backlinks: " + "String to come before the backlink list." + :type 'string + :group 'muse-backlink) + +(defcustom muse-backlink-after-string "" + "String to come after the backlink list." + :type 'string + :group 'muse-backlink) + +(defcustom muse-backlink-separator "/" + "String that separates backlinks. +Should be something that will not appear as a substring in an explicit +link that has no description." + :type 'string + :group 'muse-backlink) + +(defcustom muse-backlink-regexp + (concat "^" + (regexp-quote muse-backlink-before-string) + "\\(" + (regexp-quote muse-backlink-separator) + ".+\\)" + (regexp-quote muse-backlink-after-string)) + ;; Really, I want something like this, but I can't make it work: + ;; (concat "^\\(" + ;; (regexp-quote muse-backlink-separator) + ;; "\\(?:" + ;; muse-explicit-link-regexp + ;; "\\)\\)+") + "Regular expression to match backlinks in a buffer. +Match 1 is the list of backlinks without `muse-backlink-before-string' +and `muse-backlink-after-string'." + :type 'regexp + :group 'muse-backlink) + +(defun muse-backlink-goto-insertion-point () + "Find the right place to add backlinks." + (goto-char (point-min)) + (when (looking-at "\\(?:^#.+[ \t]*\n\\)+") + (goto-char (match-end 0)))) + +(defun muse-backlink-get-current () + "Return a list of backlinks in the current buffer." + (save-excursion + (goto-char (point-min)) + (when (re-search-forward muse-backlink-regexp nil t) + (muse-backlink-split-string + (match-string 1) + (regexp-quote muse-backlink-separator) t)))) + +(defun muse-backlink-format-link-list (links) + "Format the list of LINKS as backlinks." + (concat muse-backlink-separator + (mapconcat #'identity links muse-backlink-separator))) + +(defun muse-backlink-insert-links (links) + "Insert backlinks to LINKS into the current page. +LINKS is a list of links ordered by ancestry, with the parent as the +last element." + (muse-backlink-goto-insertion-point) + (insert muse-backlink-before-string + (muse-backlink-format-link-list links) + muse-backlink-after-string + ;; Could have this in the after string, but they might get + ;; deleted. + "\n\n")) + +(defun muse-backlink-unsaved-page-p (page project) + "Return non-nil if PAGE is in PROJECT but has not been saved." + (member + page + (mapcar + #'(lambda (b) + (with-current-buffer b + (and (derived-mode-p 'muse-mode) + (equal muse-current-project project) + (not (muse-project-page-file + (muse-page-name) + muse-current-project)) + (muse-page-name)))) + (buffer-list)))) + +(defvar muse-backlink-links nil + "Internal variable. +The links to insert in the forthcomingly visited muse page.") + +(defvar muse-backlink-pending nil + "Internal variable.") + +(defvar muse-backlink-parent-buffer nil + "Internal variable. +The parent buffer of the forthcomingly visited muse page.") + + +;;; Attach hook to the derived mode hook, to avoid problems such as +;;; planner-prepare-file thinking that the buffer needs no template. +(defun muse-backlink-get-mode-hook () + (derived-mode-hook-name major-mode)) + +(defun muse-backlink-insert-hook-func () + "Insert backlinks into the current buffer and clean up." + (when (and muse-backlink-links + muse-backlink-pending + (string= (car muse-backlink-links) (muse-page-name))) + (muse-backlink-insert-links (cdr muse-backlink-links)) + (when muse-backlink-avoid-bad-links + (save-buffer) + (when muse-backlink-parent-buffer + (with-current-buffer muse-backlink-parent-buffer + (font-lock-fontify-buffer)))) + (setq muse-backlink-links nil + muse-backlink-parent-buffer nil + muse-backlink-pending nil) + (remove-hook (muse-backlink-get-mode-hook) #'muse-backlink-insert-hook-func))) + +(defun muse-backlink-handle-link (link) + "When appropriate, arrange for backlinks on visiting LINK." + (when (and muse-backlink-create-backlinks + (not muse-backlink-pending) + (memq this-command + '(muse-follow-name-at-point muse-follow-name-at-mouse)) + (not muse-publishing-p) + (not (and (boundp 'muse-colors-fontifying-p) + muse-colors-fontifying-p))) + (require 'muse-mode) + (setq + muse-backlink-links + (save-match-data + (let* ((orig-link (or link (match-string 1))) + (link (if (string-match "#" orig-link) + (substring orig-link 0 (match-beginning 0)) + orig-link))) + (unless + (or (not muse-current-project) + (string-match muse-url-regexp orig-link) + (string-match muse-image-regexp orig-link) + (and (boundp 'muse-wiki-interwiki-regexp) + (string-match muse-wiki-interwiki-regexp + orig-link)) + ;; Don't add a backlink if the page already + ;; exists, whether it has been saved or not. + (or (muse-project-page-file link muse-current-project) + (muse-backlink-unsaved-page-p link muse-current-project)) + (string-match muse-backlink-exclude-backlink-parent-regexp + (muse-page-name)) + (string-match muse-backlink-exclude-backlink-regexp link)) + ;; todo: Hmm. This will only work if the child page is the + ;; same mode as the parent page. + (add-hook (muse-backlink-get-mode-hook) #'muse-backlink-insert-hook-func) + (setq muse-backlink-pending t) + (when muse-backlink-avoid-bad-links + (setq muse-backlink-parent-buffer (current-buffer)) + (unless (muse-project-page-file + (muse-page-name) muse-current-project) + ;; It must be modified... + (save-buffer))) + (cons link + (append (muse-backlink-get-current) + (list (muse-make-link (muse-page-name)))))))))) + ;; Make sure we always return nil + nil) + +(defun muse-backlink-install () + "Add backlinking functionality to muse-mode." + (add-to-list 'muse-explicit-link-functions #'muse-backlink-handle-link)) + +(defun muse-backlink-remove () + "Remove backlinking functionality from muse-mode." + (setq muse-explicit-link-functions + (delq #'muse-backlink-handle-link muse-explicit-link-functions))) + +(provide 'muse-backlink) +;;; muse-backlink.el ends here diff --git a/elpa/muse-3.20/muse-blosxom.el b/elpa/muse-3.20/muse-blosxom.el new file mode 100644 index 0000000..78038d7 --- /dev/null +++ b/elpa/muse-3.20/muse-blosxom.el @@ -0,0 +1,306 @@ +;;; muse-blosxom.el --- publish a document tree for serving by (py)Blosxom + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; Author: Michael Olson +;; Date: Wed, 23 March 2005 + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; The Blosxom publishing style publishes a tree of categorised files +;; to a mirrored tree of stories to be served by blosxom.cgi or +;; pyblosxom.cgi. +;; +;; Serving entries with (py)blosxom +;; -------------------------------- +;; +;; Each Blosxom file must include `#date yyyy-mm-dd', or optionally +;; the longer `#date yyyy-mm-dd-hh-mm', a title (using the `#title' +;; directive) plus whatever normal content is desired. +;; +;; The date directive is not used directly by (py)blosxom or this +;; program. You need to find two additional items to make use of this +;; feature. +;; +;; 1. A script to gather date directives from the entire blog tree +;; into a single file. The file must associate a blog entry with +;; a date. +;; +;; 2. A plugin for (py)blosxom that reads this file. +;; +;; These 2 things are provided for pyblosxom in the contrib/pyblosxom +;; subdirectory. `getstamps.py' provides the 1st service, while +;; `hardcodedates.py' provides the second service. Eventually it is +;; hoped that a blosxom plugin and script will be found/written. +;; +;; Alternately, the pyblosxom metadate plugin may be used. On the +;; plus side, there is no need to run a script to gather the date. On +;; the downside, each entry is read twice rather than once when the +;; page is rendered. Set the value of muse-blosxom-use-metadate to +;; non-nil to enable adding a #postdate directive to all published +;; files. You can do this by: +;; +;; M-x customize-variable RET muse-blosxom-use-metadate RET +;; +;; With the metadate plugin installed in pyblosxom, the date set in +;; this directive will be used instead of the file's modification +;; time. The plugin is included with Muse at +;; contrib/pyblosxom/metadate.py. +;; +;; Generating a Muse project entry +;; ------------------------------- +;; +;; Muse-blosxom has some helper functions to make specifying +;; muse-blosxom projects a lot easier. An example follows. +;; +;; (setq muse-project-alist +;; `(("blog" +;; (,@(muse-project-alist-dirs "~/path/to/blog-entries") +;; :default "index") +;; ,@(muse-project-alist-styles "~/path/to/blog-entries" +;; "~/public_html/blog" +;; "blosxom-xhtml") +;; ))) +;; +;; Note that we need a backtick instead of a single quote on the +;; second line of this example. +;; +;; Creating new blog entries +;; ------------------------- +;; +;; There is a function called `muse-blosxom-new-entry' that will +;; automate the process of making a new blog entry. To make use of +;; it, do the following. +;; +;; - Customize `muse-blosxom-base-directory' to the location that +;; your blog entries are stored. +;; +;; - Assign the `muse-blosxom-new-entry' function to a key sequence. +;; I use the following code to assign this function to `C-c p l'. +;; +;; (global-set-key "\C-cpl" 'muse-blosxom-new-entry) +;; +;; - You should create your directory structure ahead of time under +;; your base directory. These directories, which correspond with +;; category names, may be nested. +;; +;; - When you enter this key sequence, you will be prompted for the +;; category of your entry and its title. Upon entering this +;; information, a new file will be created that corresponds with +;; the title, but in lowercase letters and having special +;; characters converted to underscores. The title and date +;; directives will be inserted automatically. +;; +;; Using tags +;; ---------- +;; +;; If you wish to keep all of your blog entries in one directory and +;; use tags to classify your entries, set `muse-blosxom-use-tags' to +;; non-nil. +;; +;; For this to work, you will need to be using the PyBlosxom plugin at +;; http://pyblosxom.sourceforge.net/blog/registry/meta/Tags. + +;;; Contributors: + +;; Gary Vaughan (gary AT gnu DOT org) is the original author of +;; `emacs-wiki-blosxom.el', which is the ancestor of this file. + +;; Brad Collins (brad AT chenla DOT org) ported this file to Muse. + +;; Björn Lindström (bkhl AT elektrubadur DOT se) made many valuable +;; suggestions. + +;; Sasha Kovar (sasha AT arcocene DOT org) fixed +;; muse-blosxom-new-entry when using tags and also implemented support +;; for the #postdate directive. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse Blosxom Publishing +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'muse-project) +(require 'muse-publish) +(require 'muse-html) + +(defgroup muse-blosxom nil + "Options controlling the behavior of Muse Blosxom publishing. +See `muse-blosxom' for more information." + :group 'muse-publish) + +(defcustom muse-blosxom-extension ".txt" + "Default file extension for publishing Blosxom files." + :type 'string + :group 'muse-blosxom) + +(defcustom muse-blosxom-header + "(concat (muse-publishing-directive \"title\") \"\\n\" + (when muse-blosxom-use-metadate + (let ((date (muse-publishing-directive \"date\"))) + (when date (concat \"#postdate \" + (muse-blosxom-format-date date) \"\\n\")))) + (when muse-blosxom-use-tags + (let ((tags (muse-publishing-directive \"tags\"))) + (when tags (concat \"#tags \" tags \"\\n\")))))" + "Header used for publishing Blosxom files. This may be text or a filename." + :type 'string + :group 'muse-blosxom) + +(defcustom muse-blosxom-footer "" + "Footer used for publishing Blosxom files. This may be text or a filename." + :type 'string + :group 'muse-blosxom) + +(defcustom muse-blosxom-base-directory "~/Blog" + "Base directory of blog entries. +This is the top-level directory where your Muse blog entries may be found." + :type 'directory + :group 'muse-blosxom) + +(defcustom muse-blosxom-use-tags nil + "Determine whether or not to enable use of the #tags directive. + +If you wish to keep all of your blog entries in one directory and +use tags to classify your entries, set `muse-blosxom-use-tags' to +non-nil. + +For this to work, you will need to be using the PyBlosxom plugin +at http://pyblosxom.sourceforge.net/blog/registry/meta/Tags." + :type 'boolean + :group 'muse-blosxom) + +(defcustom muse-blosxom-use-metadate nil + "Determine whether or not to use the #postdate directive. + +If non-nil, published entries include the original date (as specified +in the muse #date line) which can be read by the metadate PyBlosxom +plugin. + +For this to work, you will need to be using the PyBlosxom plugin +at http://pyblosxom.sourceforge.net/blog/registry/date/metadate." + :type 'boolean + :group 'muse-blosxom) + +;; Maintain (published-file . date) alist, which will later be written +;; to a timestamps file; not implemented yet. + +(defvar muse-blosxom-page-date-alist nil) + +(defun muse-blosxom-update-page-date-alist () + "Add a date entry to `muse-blosxom-page-date-alist' for this page." + (when muse-publishing-current-file + ;; Make current file be relative to base directory + (let ((rel-file + (concat + (file-name-as-directory + (or (muse-publishing-directive "category") + (file-relative-name + (file-name-directory + (expand-file-name muse-publishing-current-file)) + (file-truename muse-blosxom-base-directory)))) + (file-name-nondirectory muse-publishing-current-file)))) + ;; Strip the file extension + (when muse-ignored-extensions-regexp + (setq rel-file (save-match-data + (and (string-match muse-ignored-extensions-regexp + rel-file) + (replace-match "" t t rel-file))))) + ;; Add to page-date alist + (add-to-list + 'muse-blosxom-page-date-alist + `(,rel-file . ,(muse-publishing-directive "date")))))) + +;; Enter a new blog entry + +(defun muse-blosxom-title-to-file (title) + "Derive a file name from the given TITLE. + +Feel free to overwrite this if you have a different concept of what +should be allowed in a filename." + (muse-replace-regexp-in-string (concat "[^-." muse-regexp-alnum "]") + "_" (downcase title))) + +(defun muse-blosxom-format-date (date) + "Convert a date string to PyBlosxom metadate plugin format." + (apply #'format "%s-%s-%s %s:%s" (split-string date "-"))) + +;;;###autoload +(defun muse-blosxom-new-entry (category title) + "Start a new blog entry with given CATEGORY. +The filename of the blog entry is derived from TITLE. +The page will be initialized with the current date and TITLE." + (interactive + (list + (if muse-blosxom-use-tags + (let ((tag "foo") + (tags nil)) + (while (progn (setq tag (read-string "Tag (RET to continue): ")) + (not (string= tag ""))) + (add-to-list 'tags tag t)) + tags) + (funcall muse-completing-read-function + "Category: " + (mapcar 'list (muse-project-recurse-directory + muse-blosxom-base-directory)))) + (read-string "Title: "))) + (let ((file (muse-blosxom-title-to-file title))) + (muse-project-find-file + file "blosxom" nil + (if muse-blosxom-use-tags + (directory-file-name muse-blosxom-base-directory) + (concat (directory-file-name muse-blosxom-base-directory) + "/" category)))) + (goto-char (point-min)) + (insert "#date " (format-time-string "%Y-%m-%d-%H-%M") + "\n#title " title) + (if muse-blosxom-use-tags + (if (> (length category) 0) + (insert (concat "\n#tags " (mapconcat #'identity category ",")))) + (unless (string= category "") + (insert (concat "\n#category " category)))) + (insert "\n\n") + (forward-line 2)) + +;;; Register the Muse Blosxom Publisher + +(muse-derive-style "blosxom-html" "html" + :suffix 'muse-blosxom-extension + :link-suffix 'muse-html-extension + :header 'muse-blosxom-header + :footer 'muse-blosxom-footer + :after 'muse-blosxom-update-page-date-alist + :browser 'find-file) + +(muse-derive-style "blosxom-xhtml" "xhtml" + :suffix 'muse-blosxom-extension + :link-suffix 'muse-xhtml-extension + :header 'muse-blosxom-header + :footer 'muse-blosxom-footer + :after 'muse-blosxom-update-page-date-alist + :browser 'find-file) + +(provide 'muse-blosxom) + +;;; muse-blosxom.el ends here diff --git a/elpa/muse-3.20/muse-book.el b/elpa/muse-3.20/muse-book.el new file mode 100644 index 0000000..213a64e --- /dev/null +++ b/elpa/muse-3.20/muse-book.el @@ -0,0 +1,284 @@ +;;; muse-book.el --- publish entries into a compilation + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Contributors: + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse Book Publishing +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'muse-publish) +(require 'muse-project) +(require 'muse-latex) +(require 'muse-regexps) + +(defgroup muse-book nil + "Module for publishing a series of Muse pages as a complete book. +Each page will become a separate chapter in the book, unless the +style keyword :nochapters is used, in which case they are all run +together as if one giant chapter." + :group 'muse-publish) + +(defcustom muse-book-before-publish-hook nil + "A hook run in the book buffer before it is marked up." + :type 'hook + :group 'muse-book) + +(defcustom muse-book-after-publish-hook nil + "A hook run in the book buffer after it is marked up." + :type 'hook + :group 'muse-book) + +(defcustom muse-book-latex-header + "\\documentclass{book} + +\\usepackage[english]{babel} +\\usepackage[latin1]{inputenc} +\\usepackage[T1]{fontenc} + +\\begin{document} + +\\title{(muse-publishing-directive \"title\")} +\\author{(muse-publishing-directive \"author\")} +\\date{(muse-publishing-directive \"date\")} + +\\maketitle + +\\tableofcontents\n" + "Header used for publishing books to LaTeX. This may be text or a filename." + :type 'string + :group 'muse-book) + +(defcustom muse-book-latex-footer + "(muse-latex-bibliography) +\\end{document}" + "Footer used for publishing books to LaTeX. This may be text or a filename." + :type 'string + :group 'muse-book) + +(defun muse-book-publish-chapter (title entry style &optional nochapters) + "Publish the chapter TITLE for the file ENTRY using STYLE. +TITLE is a string, ENTRY is a cons of the form (PAGE-NAME . +FILE), and STYLE is a Muse style list. + +This routine does the same basic work as `muse-publish-markup-buffer', +but treating the page as if it were a single chapter within a book." + (let ((muse-publishing-directives (list (cons "title" title))) + (muse-publishing-current-file (cdr entry)) + (beg (point)) end) + (muse-insert-file-contents (cdr entry)) + (setq end (copy-marker (point-max) t)) + (muse-publish-markup-region beg end (car entry) style) + (goto-char beg) + (unless (or nochapters + (muse-style-element :nochapters style)) + (insert "\n") + (muse-insert-markup (muse-markup-text 'chapter)) + (insert (let ((chap (muse-publishing-directive "title"))) + (if (string= chap title) + (car entry) + chap))) + (muse-insert-markup (muse-markup-text 'chapter-end)) + (insert "\n\n")) + (save-restriction + (narrow-to-region beg end) + (muse-publish-markup (or title "") + '((100 "<\\(lisp\\)>" 0 + muse-publish-markup-tag))) + (muse-style-run-hooks :after style)) + (goto-char end))) + +(defun muse-book-publish-p (project target) + "Determine whether the book in PROJECT is out-of-date." + (let ((pats (cadr project))) + (catch 'publish + (while pats + (if (symbolp (car pats)) + (if (eq :book-end (car pats)) + (throw 'publish nil) + ;; skip past symbol-value pair + (setq pats (cddr pats))) + (dolist (entry (muse-project-file-entries (car pats))) + (when (and (not (muse-project-private-p (cdr entry))) + (file-newer-than-file-p (cdr entry) target)) + (throw 'publish t))) + (setq pats (cdr pats))))))) + +(defun muse-book-get-directives (file) + "Interpret any publishing directives contained in FILE. +This is meant to be called in a temp buffer that will later be +used for publishing." + (save-restriction + (narrow-to-region (point) (point)) + (unwind-protect + (progn + (muse-insert-file-contents file) + (muse-publish-markup + "attributes" + `(;; Remove leading and trailing whitespace from the file + (100 "\\(\\`\n+\\|\n+\\'\\)" 0 "") + ;; Remove trailing whitespace from all lines + (200 ,(concat "[" muse-regexp-blank "]+$") 0 "") + ;; Handle any leading #directives + (300 "\\`#\\([a-zA-Z-]+\\)\\s-+\\(.+\\)\n+" + 0 muse-publish-markup-directive)))) + (delete-region (point-min) (point-max))))) + +(defun muse-book-publish-project + (project book title style &optional output-dir force) + "Publish PROJECT under the name BOOK with the given TITLE and STYLE. +BOOK should be a page name, i.e., letting the style determine the +prefix and/or suffix. The book is published to OUTPUT-DIR. If FORCE +is nil, the book is only published if at least one of its component +pages has changed since it was last published." + (interactive + (let ((project (muse-read-project "Publish project as book: " nil t))) + (append (list project + (read-string "Basename of book (without extension): ") + (read-string "Title of book: ")) + (muse-publish-get-info)))) + (setq project (muse-project project)) + (let ((muse-current-project project)) + ;; See if any of the project's files need saving first + (muse-project-save-buffers project) + ;; Publish the book + (muse-book-publish book style output-dir force title))) + +(defun muse-book-publish (file style &optional output-dir force title) + "Publish FILE as a book with the given TITLE and STYLE. +The book is published to OUTPUT-DIR. If FORCE is nil, the book +is only published if at least one of its component pages has +changed since it was last published." + ;; Cleanup some of the arguments + (let ((style-name style)) + (setq style (muse-style style)) + (unless style + (error "There is no style '%s' defined" style-name))) + ;; Publish each page in the project as a chapter in one large book + (let* ((output-path (muse-publish-output-file file output-dir style)) + (output-suffix (muse-style-element :osuffix style)) + (target output-path) + (project muse-current-project) + (published nil)) + (when output-suffix + (setq target (concat (muse-path-sans-extension target) + output-suffix))) + ;; Unless force is non-nil, determine if the book needs publishing + (if (and (not force) + (not (muse-book-publish-p project target))) + (message "The book \"%s\" is up-to-date." file) + ;; Create the book from all its component parts + (muse-with-temp-buffer + (let ((style-final (muse-style-element :final style t)) + (style-header (muse-style-element :header style)) + (style-footer (muse-style-element :footer style)) + (muse-publishing-current-style style) + (muse-publishing-directives + (list (cons "title" (or title (muse-page-name file))) + (cons "date" (format-time-string "%B %e, %Y")))) + (muse-publishing-p t) + (muse-current-project project) + (pats (cadr project)) + (nochapters nil)) + (run-hooks 'muse-before-book-publish-hook) + (let ((style-final style-final) + (style-header style-header) + (style-footer style-footer)) + (unless title + (muse-book-get-directives file) + (setq title (muse-publishing-directive "title"))) + (while pats + (if (symbolp (car pats)) + (cond + ((eq :book-part (car pats)) + (insert "\n") + (muse-insert-markup (muse-markup-text 'part)) + (insert (cadr pats)) + (muse-insert-markup (muse-markup-text 'part-end)) + (insert "\n") + (setq pats (cddr pats))) + ((eq :book-chapter (car pats)) + (insert "\n") + (muse-insert-markup (muse-markup-text 'chapter)) + (insert (cadr pats)) + (muse-insert-markup (muse-markup-text 'chapter-end)) + (insert "\n") + (setq pats (cddr pats))) + ((eq :nochapters (car pats)) + (setq nochapters t + pats (cddr pats))) + ((eq :book-style (car pats)) + (setq style (muse-style (cadr pats))) + (setq style-final (muse-style-element :final style t) + style-header (muse-style-element :header style) + style-footer (muse-style-element :footer style) + muse-publishing-current-style style) + (setq pats (cddr pats))) + ((eq :book-funcall (car pats)) + (funcall (cadr pats)) + (setq pats (cddr pats))) + ((eq :book-end (car pats)) + (setq pats nil)) + (t + (setq pats (cddr pats)))) + (let ((entries (muse-project-file-entries (car pats)))) + (while (and entries (car entries) (caar entries)) + (unless (muse-project-private-p (cdar entries)) + (muse-book-publish-chapter title (car entries) + style nochapters) + (setq published t)) + (setq entries (cdr entries)))) + (setq pats (cdr pats))))) + (goto-char (point-min)) + (if style-header (muse-insert-file-or-string style-header file)) + (goto-char (point-max)) + (if style-footer (muse-insert-file-or-string style-footer file)) + (run-hooks 'muse-after-book-publish-hook) + (if (muse-write-file output-path) + (if style-final + (funcall style-final file output-path target)) + (setq published nil))))) + (if published + (message "The book \"%s\" has been published." file)) + published)) + +;;; Register the Muse BOOK Publishers + +(muse-derive-style "book-latex" "latex" + :header 'muse-book-latex-header + :footer 'muse-book-latex-footer + :publish 'muse-book-publish) + +(muse-derive-style "book-pdf" "pdf" + :header 'muse-book-latex-header + :footer 'muse-book-latex-footer + :publish 'muse-book-publish) + +(provide 'muse-book) + +;;; muse-book.el ends here diff --git a/elpa/muse-3.20/muse-colors.el b/elpa/muse-3.20/muse-colors.el new file mode 100644 index 0000000..132310d --- /dev/null +++ b/elpa/muse-3.20/muse-colors.el @@ -0,0 +1,1019 @@ +;;; muse-colors.el --- coloring and highlighting used by Muse + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; Author: John Wiegley (johnw AT gnu DOT org) +;; Keywords: hypermedia +;; Date: Thu 11-Mar-2004 + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Contributors: + +;; Lan Yufeng (nlany DOT web AT gmail DOT com) found an error where +;; headings were being given the wrong face, contributing a patch to +;; fix this. + +;; Sergey Vlasov (vsu AT altlinux DOT ru) fixed an issue with coloring +;; links that are in consecutive lines. + +;; Jim Ottaway ported the tag from emacs-wiki. + +;; Per B. Sederberg (per AT med DOT upenn DOT edu) contributed the +;; viewing of inline images. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Emacs Muse Highlighting +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'muse-mode) +(require 'muse-regexps) +(require 'font-lock) + +(defgroup muse-colors nil + "Options controlling the behavior of Emacs Muse highlighting. +See `muse-colors-buffer' for more information." + :group 'muse-mode) + +(defcustom muse-colors-autogen-headings t + "Specify whether the heading faces should be auto-generated. +The default is to scale them. + +Choosing 'outline will copy the colors from the outline-mode +headings. + +If you want to customize each of the headings individually, set +this to nil." + :type '(choice (const :tag "Default (scaled) headings" t) + (const :tag "Use outline-mode headings" outline) + (const :tag "Don't touch the headings" nil)) + :group 'muse-colors) + +(defcustom muse-colors-evaluate-lisp-tags t + "Specify whether to evaluate the contents of tags at +display time. If nil, don't evaluate them. If non-nil, evaluate +them. + +The actual contents of the buffer are not changed, only the +displayed text." + :type 'boolean + :group 'muse-colors) + +(defcustom muse-colors-inline-images t + "Specify whether to inline images inside the Emacs buffer. If +nil, don't inline them. If non-nil, an image link will be +replaced by the image. + +The actual contents of the buffer are not changed, only whether +an image is displayed." + :type 'boolean + :group 'muse-colors) + +(defcustom muse-colors-inline-image-method 'default-directory + "Determine how to locate inline images. +Setting this to 'default-directory uses the current directory of +the current Muse buffer. + +Setting this to a function calls that function with the filename +of the image to be inlined. The value that is returned will be +used as the filename of the image." + :type '(choice (const :tag "Current directory" default-directory) + (const :tag "Publishing directory" + muse-colors-use-publishing-directory) + (function :tag "Custom function")) + :group 'muse-colors) + +(defvar muse-colors-region-end nil + "Indicate the end of the region that is currently being font-locked.") +(make-variable-buffer-local 'muse-colors-region-end) + +;;;###autoload +(defun muse-colors-toggle-inline-images () + "Toggle display of inlined images on/off." + (interactive) + ;; toggle the custom setting + (if (not muse-colors-inline-images) + (setq muse-colors-inline-images t) + (setq muse-colors-inline-images nil)) + ;; reprocess the buffer + (muse-colors-buffer) + ;; display informative message + (if muse-colors-inline-images + (message "Images are now displayed inline") + (message "Images are now displayed as links"))) + +(defvar muse-colors-outline-faces-list + (if (facep 'outline-1) + '(outline-1 outline-2 outline-3 outline-4 outline-5) + ;; these are equivalent in coloring to the outline faces + '(font-lock-function-name-face + font-lock-variable-name-face + font-lock-keyword-face + font-lock-builtin-face + font-lock-comment-face)) + "Outline faces to use when assigning Muse header faces.") + +(defun muse-make-faces-default (&optional later) + "Generate the default face definitions for headers." + (dolist (num '(1 2 3 4 5)) + (let ((newsym (intern (concat "muse-header-" (int-to-string num)))) + (docstring (concat + "Muse header face. See " + "`muse-colors-autogen-headings' before changing it."))) + ;; put in the proper group and give documentation + (if later + (unless (featurep 'xemacs) + (muse-copy-face 'variable-pitch newsym) + (set-face-attribute newsym nil :height (1+ (* 0.1 (- 5 num))) + :weight 'bold)) + (if (featurep 'xemacs) + (eval `(defface ,newsym + '((t (:size + ,(nth (1- num) + '("24pt" "18pt" "14pt" "12pt" "11pt")) + :bold t))) + ,docstring + :group 'muse-colors)) + (eval `(defface ,newsym + '((t (:height ,(1+ (* 0.1 (- 5 num))) + :inherit variable-pitch + :weight bold))) + ,docstring + :group 'muse-colors))))))) + +(progn (muse-make-faces-default)) + +(defun muse-make-faces (&optional frame) + "Generate face definitions for headers based the user's preferences." + (cond + ((not muse-colors-autogen-headings) + nil) + ((eq muse-colors-autogen-headings t) + (muse-make-faces-default t)) + (t + (dolist (num '(1 2 3 4 5)) + (let ((newsym (intern (concat "muse-header-" (int-to-string num))))) + ;; copy the desired face definition + (muse-copy-face (nth (1- num) muse-colors-outline-faces-list) + newsym)))))) + +;; after displaying the Emacs splash screen, the faces are wiped out, +;; so recover from that +(add-hook 'window-setup-hook #'muse-make-faces) +;; ditto for when a new frame is created +(when (boundp 'after-make-frame-functions) + (add-hook 'after-make-frame-functions #'muse-make-faces)) + +(defface muse-link + '((t :inherit link)) + "Face for Muse cross-references." + :group 'muse-colors) + +(defface muse-bad-link + '((default :inherit link) + (((class color) (background light)) + (:foreground "red" :underline "red" :bold t)) + (((class color) (background dark)) + (:foreground "coral" :underline "coral" :bold t)) + (t (:bold t))) + "Face for bad Muse cross-references." + :group 'muse-colors) + +(defface muse-verbatim + '((((class color) (background light)) + (:foreground "slate gray")) + (((class color) (background dark)) + (:foreground "gray"))) + "Face for verbatim text." + :group 'muse-colors) + +(defface muse-emphasis-1 + '((t (:italic t))) + "Face for italic emphasized text." + :group 'muse-colors) + +(defface muse-emphasis-2 + '((t (:bold t))) + "Face for bold emphasized text." + :group 'muse-colors) + +(defface muse-emphasis-3 + '((t (:bold t :italic t))) + "Face for bold italic emphasized text." + :group 'muse-colors) + +(muse-copy-face 'italic 'muse-emphasis-1) +(muse-copy-face 'bold 'muse-emphasis-2) +(muse-copy-face 'bold-italic 'muse-emphasis-3) + +(defcustom muse-colors-buffer-hook nil + "A hook run after a region is highlighted. +Each function receives three arguments: BEG END VERBOSE. +BEG and END mark the range being highlighted, and VERBOSE specifies +whether progress messages should be displayed to the user." + :type 'hook + :group 'muse-colors) + +(defvar muse-colors-highlighting-registry nil + "The rules for highlighting Muse and Muse-derived buffers. +This is automatically generated when using font-lock in Muse buffers. + +This an alist of major-mode symbols to `muse-colors-rule' objects.") + +(defun muse-colors-make-highlighting-struct () + (list nil nil nil)) +(defconst muse-colors-highlighting.regexp 0 + "Regexp matching each car of the markup of the current rule.") +(defconst muse-colors-highlighting.vector 1 + "Vector of all characters that are part of the markup of the current rule. +This is composed of the 2nd element of each markup entry.") +(defconst muse-colors-highlighting.remaining 2 + "Expressions for highlighting a buffer which have no corresponding +entry in the vector.") + +(defsubst muse-colors-highlighting-entry (mode) + "Return the highlighting rules for MODE." + (assq mode muse-colors-highlighting-registry)) + +(defun muse-colors-find-highlighting (mode) + "Return the highlighting rules to be used for MODE. +If MODE does not have highlighting rules, check its parent modes." + (let ((seen nil)) + (catch 'rules + (while (and mode (not (memq mode seen))) + (let ((entry (muse-colors-highlighting-entry mode))) + (when entry (throw 'rules (cdr entry)))) + (setq seen (cons mode seen)) + (setq mode (get mode 'derived-mode-parent))) + nil))) + +(defun muse-colors-define-highlighting (mode markup) + "Create or update the markup rules for MODE, using MARKUP. + +See `muse-colors-markup' for an explanation of the format that MARKUP +should take." + (unless (and (symbolp mode) mode (consp markup)) + (error "Invalid arguments")) + (let* ((highlighting-entry (muse-colors-highlighting-entry mode)) + (struct (cdr highlighting-entry)) + (regexp nil) + (vector nil) + (remaining nil)) + ;; Initialize struct + (if struct + (setq vector (nth muse-colors-highlighting.vector struct)) + (setq struct (muse-colors-make-highlighting-struct))) + ;; Initialize vector + (if vector + (let ((i 0)) + (while (< i 128) + (aset vector i nil) + (setq i (1+ i)))) + (setq vector (make-vector 128 nil))) + ;; Determine vector, regexp, remaining + (let ((regexps nil) + (rules nil)) + (dolist (rule markup) + (let ((value (cond ((symbolp (car rule)) + (symbol-value (car rule))) + ((stringp (car rule)) + (car rule)) + (t nil)))) + (when value + (setq rules (cons rule rules)) + (setq regexps (cons value regexps))))) + (setq regexps (nreverse regexps)) + (setq regexp (concat "\\(" (mapconcat #'identity regexps "\\|") "\\)")) + (dolist (rule rules) + (if (eq (nth 1 rule) t) + (setq remaining (cons (cons (nth 0 rule) (nth 2 rule)) + remaining)) + (aset vector (nth 1 rule) + (cons (cons (nth 0 rule) (nth 2 rule)) + (aref vector (nth 1 rule))))))) + ;; Update the struct + (setcar (nthcdr muse-colors-highlighting.regexp struct) regexp) + (setcar (nthcdr muse-colors-highlighting.vector struct) vector) + (setcar (nthcdr muse-colors-highlighting.remaining struct) remaining) + ;; Update entry for mode in muse-colors-highlighting-registry + (if highlighting-entry + (setcdr highlighting-entry struct) + (setq muse-colors-highlighting-registry + (cons (cons mode struct) + muse-colors-highlighting-registry))))) + +(defun muse-configure-highlighting (sym val) + "Extract color markup information from VAL and set to SYM. +This is usually called with `muse-colors-markup' as both arguments." + (muse-colors-define-highlighting 'muse-mode val) + (set sym val)) + +(defun muse-colors-emphasized () + "Color emphasized text and headings." + ;; Here we need to check four different points - the start and end + ;; of the leading *s, and the start and end of the trailing *s. We + ;; allow the outsides to be surrounded by whitespace or punctuation, + ;; but no word characters, and the insides must not be surrounded by + ;; whitespace or punctuation. Thus the following are valid: + ;; + ;; " *foo bar* " + ;; "**foo**," + ;; and the following is invalid: + ;; "** testing **" + (let* ((beg (match-beginning 0)) + (e1 (match-end 0)) + (leader (- e1 beg)) + b2 e2 multiline) + (unless (or (eq (get-text-property beg 'invisible) 'muse) + (get-text-property beg 'muse-comment) + (get-text-property beg 'muse-directive)) + ;; check if it's a header + (if (eq (char-after e1) ?\ ) + (when (or (= beg (point-min)) + (eq (char-before beg) ?\n)) + (add-text-properties + (muse-line-beginning-position) (muse-line-end-position) + (list 'face (intern (concat "muse-header-" + (int-to-string leader)))))) + ;; beginning of line or space or symbol + (when (or (= beg (point-min)) + (eq (char-syntax (char-before beg)) ?\ ) + (memq (char-before beg) + '(?\- ?\[ ?\< ?\( ?\' ?\` ?\" ?\n))) + (save-excursion + (skip-chars-forward "^*<>\n" muse-colors-region-end) + (when (eq (char-after) ?\n) + (setq multiline t) + (skip-chars-forward "^*<>" muse-colors-region-end)) + (setq b2 (point)) + (skip-chars-forward "*" muse-colors-region-end) + (setq e2 (point)) + ;; Abort if space exists just before end + ;; or bad leader + ;; or no '*' at end + ;; or word constituent follows + (unless (or (> leader 5) + (not (eq leader (- e2 b2))) + (eq (char-syntax (char-before b2)) ?\ ) + (not (eq (char-after b2) ?*)) + (and (not (eobp)) + (eq (char-syntax (char-after (1+ b2))) ?w))) + (add-text-properties beg e1 '(invisible muse)) + (add-text-properties + e1 b2 (list 'face (cond ((= leader 1) 'muse-emphasis-1) + ((= leader 2) 'muse-emphasis-2) + ((= leader 3) 'muse-emphasis-3)))) + (add-text-properties b2 e2 '(invisible muse)) + (when multiline + (add-text-properties + beg e2 '(font-lock-multiline t)))))))))) + +(defun muse-colors-underlined () + "Color underlined text." + (let ((start (match-beginning 0)) + multiline) + (unless (or (eq (get-text-property start 'invisible) 'muse) + (get-text-property start 'muse-comment) + (get-text-property start 'muse-directive)) + ;; beginning of line or space or symbol + (when (or (= start (point-min)) + (eq (char-syntax (char-before start)) ?\ ) + (memq (char-before start) + '(?\- ?\[ ?\< ?\( ?\' ?\` ?\" ?\n))) + (save-excursion + (skip-chars-forward "^_<>\n" muse-colors-region-end) + (when (eq (char-after) ?\n) + (setq multiline t) + (skip-chars-forward "^_<>" muse-colors-region-end)) + ;; Abort if space exists just before end + ;; or no '_' at end + ;; or word constituent follows + (unless (or (eq (char-syntax (char-before (point))) ?\ ) + (not (eq (char-after (point)) ?_)) + (and (not (eobp)) + (eq (char-syntax (char-after (1+ (point)))) ?w))) + (add-text-properties start (1+ start) '(invisible muse)) + (add-text-properties (1+ start) (point) '(face underline)) + (add-text-properties (point) + (min (1+ (point)) (point-max)) + '(invisible muse)) + (when multiline + (add-text-properties + start (min (1+ (point)) (point-max)) + '(font-lock-multiline t))))))))) + +(defun muse-colors-verbatim () + "Render in teletype and suppress further parsing." + (let ((start (match-beginning 0)) + multiline) + (unless (or (eq (get-text-property start 'invisible) 'muse) + (get-text-property start 'muse-comment) + (get-text-property start 'muse-directive)) + ;; beginning of line or space or symbol + (when (or (= start (point-min)) + (eq (char-syntax (char-before start)) ?\ ) + (memq (char-before start) + '(?\- ?\[ ?\< ?\( ?\' ?\` ?\" ?\n))) + (let ((pos (point))) + (skip-chars-forward "^=\n" muse-colors-region-end) + (when (eq (char-after) ?\n) + (setq multiline t) + (skip-chars-forward "^=" muse-colors-region-end)) + ;; Abort if space exists just before end + ;; or no '=' at end + ;; or word constituent follows + (unless (or (eq (char-syntax (char-before (point))) ?\ ) + (not (eq (char-after (point)) ?=)) + (and (not (eobp)) + (eq (char-syntax (char-after (1+ (point)))) ?w))) + (setq pos (min (1+ (point)) (point-max))) + (add-text-properties start (1+ start) '(invisible muse)) + (add-text-properties (1+ start) (point) '(face muse-verbatim)) + (add-text-properties (point) + (min (1+ (point)) (point-max)) + '(invisible muse)) + (when multiline + (add-text-properties + start (min (1+ (point)) (point-max)) + '(font-lock-multiline t)))) + (goto-char pos)))))) + +(defcustom muse-colors-markup + `(;; make emphasized text appear emphasized + ("\\*\\{1,5\\}" ?* muse-colors-emphasized) + + ;; make underlined text appear underlined + (,(concat "_[^" muse-regexp-blank "_\n]") + ?_ muse-colors-underlined) + + ("^#title " ?\# muse-colors-title) + + (muse-explicit-link-regexp ?\[ muse-colors-explicit-link) + + ;; render in teletype and suppress further parsing + (,(concat "=[^" muse-regexp-blank "=\n]") ?= muse-colors-verbatim) + + ;; highlight any markup tags encountered + (muse-tag-regexp ?\< muse-colors-custom-tags) + + ;; display comments + (,(concat "^;[" muse-regexp-blank "]") ?\; muse-colors-comment) + + ;; this has to come later since it doesn't have a special + ;; character in the second cell + (muse-url-regexp t muse-colors-implicit-link) + ) + "Expressions to highlight an Emacs Muse buffer. +These are arranged in a rather special fashion, so as to be as quick as +possible. + +Each element of the list is itself a list, of the form: + + (LOCATE-REGEXP TEST-CHAR MATCH-FUNCTION) + +LOCATE-REGEXP is a partial regexp, and should be the smallest possible +regexp to differentiate this rule from other rules. It may also be a +symbol containing such a regexp. The buffer region is scanned only +once, and LOCATE-REGEXP indicates where the scanner should stop to +look for highlighting possibilities. + +TEST-CHAR is a char or t. The character should match the beginning +text matched by LOCATE-REGEXP. These chars are used to build a vector +for fast MATCH-FUNCTION calling. + +MATCH-FUNCTION is the function called when a region has been +identified. It is responsible for adding the appropriate text +properties to change the appearance of the buffer. + +This markup is used to modify the appearance of the original text to +make it look more like the published HTML would look (like making some +markup text invisible, inlining images, etc). + +font-lock is used to apply the markup rules, so that they can happen +on a deferred basis. They are not always accurate, but you can use +\\[font-lock-fontifty-block] near the point of error to force +fontification in that area." + :type '(repeat + (list :tag "Highlight rule" + (choice (regexp :tag "Locate regexp") + (symbol :tag "Regexp symbol")) + (choice (character :tag "Confirm character") + (const :tag "Default rule" t)) + function)) + :set 'muse-configure-highlighting + :group 'muse-colors) + +;; XEmacs users don't have `font-lock-multiline'. +(unless (boundp 'font-lock-multiline) + (defvar font-lock-multiline nil)) + +(defun muse-use-font-lock () + "Set up font-locking for Muse." + (muse-add-to-invisibility-spec 'muse) + (set (make-local-variable 'font-lock-multiline) 'undecided) + (set (make-local-variable 'font-lock-defaults) + `(nil t nil nil beginning-of-line + (font-lock-fontify-region-function . muse-colors-region) + (font-lock-unfontify-region-function + . muse-unhighlight-region))) + (set (make-local-variable 'font-lock-fontify-region-function) + 'muse-colors-region) + (set (make-local-variable 'font-lock-unfontify-region-function) + 'muse-unhighlight-region) + (muse-make-faces) + (muse-colors-define-highlighting 'muse-mode muse-colors-markup) + (font-lock-mode t)) + +(defun muse-colors-buffer () + "Re-highlight the entire Muse buffer." + (interactive) + (muse-colors-region (point-min) (point-max) t)) + +(defvar muse-colors-fontifying-p nil + "Indicate whether Muse is fontifying the current buffer.") +(make-variable-buffer-local 'muse-colors-fontifying-p) + +(defvar muse-colors-delayed-commands nil + "Commands to be run immediately after highlighting a region. + +This is meant to accommodate highlighting in #title +directives after everything else. + +It may be modified by Muse functions during highlighting, but not +the user.") +(make-variable-buffer-local 'muse-colors-delayed-commands) + +(defun muse-colors-region (beg end &optional verbose) + "Apply highlighting according to `muse-colors-markup'. +Note that this function should NOT change the buffer, nor should any +of the functions listed in `muse-colors-markup'." + (let ((buffer-undo-list t) + (inhibit-read-only t) + (inhibit-point-motion-hooks t) + (inhibit-modification-hooks t) + (modified-p (buffer-modified-p)) + (muse-colors-fontifying-p t) + (muse-colors-region-end (muse-line-end-position end)) + (muse-colors-delayed-commands nil) + (highlighting (muse-colors-find-highlighting major-mode)) + regexp vector remaining + deactivate-mark) + (unless highlighting + (error "No highlighting found for this mode")) + (setq regexp (nth muse-colors-highlighting.regexp highlighting) + vector (nth muse-colors-highlighting.vector highlighting) + remaining (nth muse-colors-highlighting.remaining highlighting)) + (unwind-protect + (save-excursion + (save-restriction + (widen) + ;; check to see if we should expand the beg/end area for + ;; proper multiline matches + (when (and font-lock-multiline + (> beg (point-min)) + (get-text-property (1- beg) 'font-lock-multiline)) + ;; We are just after or in a multiline match. + (setq beg (or (previous-single-property-change + beg 'font-lock-multiline) + (point-min))) + (goto-char beg) + (setq beg (muse-line-beginning-position))) + (when font-lock-multiline + (setq end (or (text-property-any end (point-max) + 'font-lock-multiline nil) + (point-max)))) + (goto-char end) + (setq end (muse-line-beginning-position 2)) + ;; Undo any fontification in the area. + (font-lock-unfontify-region beg end) + ;; And apply fontification based on `muse-colors-markup' + (let ((len (float (- end beg))) + (case-fold-search nil) + markup-list) + (goto-char beg) + (while (and (< (point) end) + (re-search-forward regexp end t)) + (if verbose + (message "Highlighting buffer...%d%%" + (* (/ (float (- (point) beg)) len) 100))) + (let ((ch (char-after (match-beginning 0)))) + (when (< ch 128) + (setq markup-list (aref vector ch)))) + (unless markup-list + (setq markup-list remaining)) + (let ((prev (point))) + ;; backtrack and figure out which rule matched + (goto-char (match-beginning 0)) + (catch 'done + (dolist (entry markup-list) + (let ((value (cond ((symbolp (car entry)) + (symbol-value (car entry))) + ((stringp (car entry)) + (car entry)) + (t nil)))) + (when (and (stringp value) (looking-at value)) + (goto-char (match-end 0)) + (when (cdr entry) + (funcall (cdr entry))) + (throw 'done t)))) + ;; if no rule matched, which should never happen, + ;; return to previous position so that forward + ;; progress is ensured + (goto-char prev)))) + (dolist (command muse-colors-delayed-commands) + (apply (car command) (cdr command))) + (run-hook-with-args 'muse-colors-buffer-hook + beg end verbose) + (if verbose (message "Highlighting buffer...done"))))) + (set-buffer-modified-p modified-p)))) + +(defcustom muse-colors-tags + '(("example" t nil nil muse-colors-example-tag) + ("code" t nil nil muse-colors-example-tag) + ("verbatim" t nil nil muse-colors-literal-tag) + ("lisp" t t nil muse-colors-lisp-tag) + ("literal" t nil nil muse-colors-literal-tag)) + "A list of tag specifications for specially highlighting text. +XML-style tags are the best way to add custom highlighting to Muse. +This is easily accomplished by customizing this list of markup tags. + +For each entry, the name of the tag is given, whether it expects +a closing tag and/or an optional set of attributes, whether it is +nestable, and a function that performs whatever action is desired +within the delimited region. + +The function is called with three arguments, the beginning and +end of the region surrounded by the tags. If properties are +allowed, they are passed as a third argument in the form of an +alist. The `end' argument to the function is the last character +of the enclosed tag or region. + +Functions should not modify the contents of the buffer." + :type '(repeat (list (string :tag "Markup tag") + (boolean :tag "Expect closing tag" :value t) + (boolean :tag "Parse attributes" :value nil) + (boolean :tag "Nestable" :value nil) + function)) + :group 'muse-colors) + +(defvar muse-colors-inhibit-tags-in-directives t + "If non-nil, don't allow tags to be interpreted in directives. +This is used to delay highlighting of tags in #title until later.") +(make-variable-buffer-local 'muse-colors-inhibit-tags-in-directives) + +(defsubst muse-colors-tag-info (tagname &rest args) + "Get tag info associated with TAGNAME, ignoring ARGS." + (assoc tagname muse-colors-tags)) + +(defun muse-colors-custom-tags () + "Highlight `muse-colors-tags'." + (let ((tag-info (muse-colors-tag-info (match-string 1)))) + (unless (or (not tag-info) + (get-text-property (match-beginning 0) 'muse-comment) + (and muse-colors-inhibit-tags-in-directives + (get-text-property (match-beginning 0) 'muse-directive))) + (let ((closed-tag (match-string 3)) + (start (match-beginning 0)) + end attrs) + (when (nth 2 tag-info) + (let ((attrstr (match-string 2))) + (while (and attrstr + (string-match (concat "\\([^" + muse-regexp-blank + "=\n]+\\)\\(=\"" + "\\([^\"]+\\)\"\\)?") + attrstr)) + (let ((attr (cons (downcase + (muse-match-string-no-properties 1 attrstr)) + (muse-match-string-no-properties 3 attrstr)))) + (setq attrstr (replace-match "" t t attrstr)) + (if attrs + (nconc attrs (list attr)) + (setq attrs (list attr))))))) + (if (and (cadr tag-info) (not closed-tag)) + (if (muse-goto-tag-end (car tag-info) (nth 3 tag-info)) + (setq end (match-end 0)) + (setq tag-info nil))) + (when tag-info + (let ((args (list start end))) + (if (nth 2 tag-info) + (nconc args (list attrs))) + (apply (nth 4 tag-info) args))))))) + +(defun muse-unhighlight-region (begin end &optional verbose) + "Remove all visual highlights in the buffer (except font-lock)." + (let ((buffer-undo-list t) + (inhibit-read-only t) + (inhibit-point-motion-hooks t) + (inhibit-modification-hooks t) + (modified-p (buffer-modified-p)) + deactivate-mark) + (unwind-protect + (remove-text-properties + begin end '(face nil font-lock-multiline nil end-glyph nil + invisible nil intangible nil display nil + mouse-face nil keymap nil help-echo nil + muse-link nil muse-directive nil muse-comment nil + muse-no-implicit-link nil muse-no-flyspell nil)) + (set-buffer-modified-p modified-p)))) + +(defun muse-colors-example-tag (beg end) + "Strip properties and colorize with `muse-verbatim'." + (muse-unhighlight-region beg end) + (let ((multi (save-excursion + (goto-char beg) + (forward-line 1) + (> end (point))))) + (add-text-properties beg end `(face muse-verbatim + font-lock-multiline ,multi)))) + +(defun muse-colors-literal-tag (beg end) + "Strip properties and mark as literal." + (muse-unhighlight-region beg end) + (let ((multi (save-excursion + (goto-char beg) + (forward-line 1) + (> end (point))))) + (add-text-properties beg end `(font-lock-multiline ,multi)))) + +(defun muse-colors-lisp-tag (beg end attrs) + "Color the region enclosed by a tag." + (if (not muse-colors-evaluate-lisp-tags) + (muse-colors-literal-tag beg end) + (muse-unhighlight-region beg end) + (let (beg-lisp end-lisp) + (save-match-data + (goto-char beg) + (setq beg-lisp (and (looking-at "<[^>]+>") + (match-end 0))) + (goto-char end) + (setq end-lisp (and (muse-looking-back "]+>") + (match-beginning 0)))) + (add-text-properties + beg end + (list 'font-lock-multiline t + 'display (muse-eval-lisp + (concat + "(progn " + (buffer-substring-no-properties beg-lisp end-lisp) + ")")) + 'intangible t))))) + +(defvar muse-mode-local-map + (let ((map (make-sparse-keymap))) + (define-key map [return] 'muse-follow-name-at-point) + (define-key map [(control ?m)] 'muse-follow-name-at-point) + (define-key map [(shift return)] 'muse-follow-name-at-point-other-window) + (if (featurep 'xemacs) + (progn + (define-key map [(button2)] 'muse-follow-name-at-mouse) + (define-key map [(shift button2)] + 'muse-follow-name-at-mouse-other-window)) + (define-key map [(shift control ?m)] + 'muse-follow-name-at-point-other-window) + (define-key map [mouse-2] 'muse-follow-name-at-mouse) + (define-key map [(shift mouse-2)] + 'muse-follow-name-at-mouse-other-window) + (unless (eq emacs-major-version 21) + (set-keymap-parent map muse-mode-map))) + map) + "Local keymap used by Muse while on a link.") + +(defvar muse-keymap-property + (if (or (featurep 'xemacs) + (>= emacs-major-version 21)) + 'keymap + 'local-map) + "The name of the keymap or local-map property.") + +(defsubst muse-link-properties (help-str &optional face) + "Determine text properties to use for a link." + (append (if face + (list 'face face 'mouse-face 'highlight 'muse-link t) + (list 'invisible 'muse 'intangible t)) + (list 'help-echo help-str 'rear-nonsticky t + muse-keymap-property muse-mode-local-map))) + +(defun muse-link-face (link-name &optional explicit) + "Return the type of LINK-NAME as a face symbol. +For EXPLICIT links, this is either a normal link or a bad-link +face. For implicit links, it is either colored normally or +ignored." + (save-match-data + (let ((link (if explicit + (muse-handle-explicit-link link-name) + (muse-handle-implicit-link link-name)))) + (when link + (cond ((string-match muse-url-regexp link) + 'muse-link) + ((muse-file-remote-p link) + 'muse-link) + ((string-match muse-file-regexp link) + (when (string-match "/[^/]+#[^#./]+\\'" link) + ;; strip anchor from the end of a path + (setq link (substring link 0 (match-beginning 0)))) + (if (file-exists-p link) + 'muse-link + 'muse-bad-link)) + ((not (featurep 'muse-project)) + 'muse-link) + (t + (if (string-match "#" link) + (setq link (substring link 0 (match-beginning 0)))) + (if (or (and (muse-project-of-file) + (muse-project-page-file + link muse-current-project t)) + (file-exists-p link)) + 'muse-link + 'muse-bad-link))))))) + +(defun muse-colors-use-publishing-directory (link) + "Make LINK relative to the directory where we will publish the +current file." + (let ((style (car (muse-project-applicable-styles + link (cddr (muse-project))))) + path) + (when (and style + (setq path (muse-style-element :path style))) + (expand-file-name link path)))) + +(defun muse-colors-resolve-image-file (link) + "Determine if we can create images and see if the link is an image +file." + (save-match-data + (and (or (fboundp 'create-image) + (fboundp 'make-glyph)) + (not (string-match "\\`[uU][rR][lL]:" link)) + (string-match muse-image-regexp link)))) + +(defun muse-make-file-glyph (filename) + "Given a file name, return a newly-created image glyph. +This is a hack for supporting inline images in XEmacs." + (let ((case-fold-search nil)) + ;; Scan filename to determine image type + (when (fboundp 'make-glyph) + (save-match-data + (cond ((string-match "jpe?g" filename) + (make-glyph (vector 'jpeg :file filename) 'buffer)) + ((string-match "gif" filename) + (make-glyph (vector 'gif :file filename) 'buffer)) + ((string-match "png" filename) + (make-glyph (vector 'png :file filename) 'buffer))))))) + +(defun muse-colors-insert-image (link beg end invis-props) + "Create an image using create-image or make-glyph and insert it +in place of an image link defined by BEG and END." + (setq link (expand-file-name link)) + (let ((image-file (cond + ((eq muse-colors-inline-image-method 'default-directory) + link) + ((functionp muse-colors-inline-image-method) + (funcall muse-colors-inline-image-method link)))) + glyph) + (when (stringp image-file) + (if (fboundp 'create-image) + ;; use create-image and display property + (let ((display-stuff (condition-case nil + (create-image image-file) + (error nil)))) + (when display-stuff + (add-text-properties beg end (list 'display display-stuff)))) + ;; use make-glyph and invisible property + (and (setq glyph (muse-make-file-glyph image-file)) + (progn + (add-text-properties beg end invis-props) + (add-text-properties beg end (list + 'end-glyph glyph + 'help-echo link)))))))) + +(defun muse-colors-explicit-link () + "Color explicit links." + (when (and (eq ?\[ (char-after (match-beginning 0))) + (not (get-text-property (match-beginning 0) 'muse-comment)) + (not (get-text-property (match-beginning 0) 'muse-directive))) + ;; remove flyspell overlays + (when (fboundp 'flyspell-unhighlight-at) + (let ((cur (match-beginning 0))) + (while (> (match-end 0) cur) + (flyspell-unhighlight-at cur) + (setq cur (1+ cur))))) + (let* ((unesc-link (muse-get-link)) + (unesc-desc (muse-get-link-desc)) + (link (muse-link-unescape unesc-link)) + (desc (muse-link-unescape unesc-desc)) + (props (muse-link-properties desc (muse-link-face link t))) + (invis-props (append props (muse-link-properties desc)))) + ;; see if we should try and inline an image + (if (and muse-colors-inline-images + (or (muse-colors-resolve-image-file link) + (and desc + (muse-colors-resolve-image-file desc) + (setq link desc)))) + ;; we found an image, so inline it + (muse-colors-insert-image + link + (match-beginning 0) (match-end 0) invis-props) + (if desc + (progn + ;; we put the normal face properties on the invisible + ;; portion too, since emacs sometimes will position + ;; the cursor on an intangible character + (add-text-properties (match-beginning 0) + (match-beginning 2) invis-props) + (add-text-properties (match-beginning 2) (match-end 2) props) + (add-text-properties (match-end 2) (match-end 0) invis-props) + ;; in case specials were escaped, cause the unescaped + ;; text to be displayed + (unless (string= desc unesc-desc) + (add-text-properties (match-beginning 2) (match-end 2) + (list 'display desc)))) + (add-text-properties (match-beginning 0) + (match-beginning 1) invis-props) + (add-text-properties (match-beginning 1) (match-end 0) props) + (add-text-properties (match-end 1) (match-end 0) invis-props) + (unless (string= link unesc-link) + (add-text-properties (match-beginning 1) (match-end 1) + (list 'display link)))) + (goto-char (match-end 0)) + (add-text-properties + (match-beginning 0) (match-end 0) + (muse-link-properties (muse-match-string-no-properties 0) + (muse-link-face link t))))))) + +(defun muse-colors-implicit-link () + "Color implicit links." + (unless (or (eq (get-text-property (match-beginning 0) 'invisible) 'muse) + (get-text-property (match-beginning 0) 'muse-comment) + (get-text-property (match-beginning 0) 'muse-directive) + (get-text-property (match-beginning 0) 'muse-no-implicit-link) + (eq (char-before (match-beginning 0)) ?\") + (eq (char-after (match-end 0)) ?\")) + ;; remove flyspell overlays + (when (fboundp 'flyspell-unhighlight-at) + (let ((cur (match-beginning 0))) + (while (> (match-end 0) cur) + (flyspell-unhighlight-at cur) + (setq cur (1+ cur))))) + ;; colorize link + (let ((link (muse-match-string-no-properties 0)) + (face (muse-link-face (match-string 0)))) + (when face + (add-text-properties (match-beginning 0) (match-end 0) + (muse-link-properties + (muse-match-string-no-properties 0) face)))))) + +(defun muse-colors-title () + "Color #title directives." + (let ((beg (+ 7 (match-beginning 0)))) + (add-text-properties beg (muse-line-end-position) '(muse-directive t)) + ;; colorize tags in #title after other tags have had a + ;; chance to run, so that we can have behavior that is consistent + ;; with how the document is published + (setq muse-colors-delayed-commands + (cons (list 'muse-colors-title-lisp beg (muse-line-end-position)) + muse-colors-delayed-commands)))) + +(defun muse-colors-title-lisp (beg end) + "Called after other highlighting is done for a region in order to handle + tags that exist in #title directives." + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (let ((muse-colors-inhibit-tags-in-directives nil) + (muse-colors-tags '(("lisp" t t nil muse-colors-lisp-tag)))) + (while (re-search-forward muse-tag-regexp nil t) + (muse-colors-custom-tags)))) + (add-text-properties beg end '(face muse-header-1))) + +(defun muse-colors-comment () + "Color comments." + (add-text-properties (match-beginning 0) (muse-line-end-position) + (list 'face 'font-lock-comment-face + 'muse-comment t))) + + +(provide 'muse-colors) + +;;; muse-colors.el ends here diff --git a/elpa/muse-3.20/muse-context.el b/elpa/muse-3.20/muse-context.el new file mode 100644 index 0000000..45968b0 --- /dev/null +++ b/elpa/muse-3.20/muse-context.el @@ -0,0 +1,458 @@ +;;; muse-context.el --- publish entries in ConTeXt or PDF format + +;; Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + +;; Author: Jean Magnan de Bornier (jean@bornier.net) +;; Created: 16-Apr-2007 + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; This file when loaded allows you to publish .muse files as ConTeXt +;; files or as pdf files, using respectively the "context" and +;; "context-pdf" styles. It is far from being perfect, so any feedback +;; will be welcome and any mistake hopefully fixed. + +;;; Author: + +;; Jean Magnan de Bornier, who based this file on muse-latex.el and +;; made the context, context-pdf, context-slides, and +;; context-slides-pdf Muse publishing styles. + +;; 16 Avril 2007 + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse ConTeXt Publishing +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'muse-publish) + +(defgroup muse-context nil + "Rules for marking up a Muse file as a ConTeXt article." + :group 'muse-publish) + +(defcustom muse-context-extension ".tex" + "Default file extension for publishing ConTeXt files." + :type 'string + :group 'muse-context) + +(defcustom muse-context-pdf-extension ".pdf" + "Default file extension for publishing ConTeXt files to PDF." + :type 'string + :group 'muse-context) + +(defcustom muse-context-pdf-program "texexec --pdf" + "The program that is called to generate PDF content from ConTeXt content." + :type 'string + :group 'muse-context) + +(defcustom muse-context-pdf-cruft '(".pgf" ".tmp" ".tui" ".tuo" ".toc" ".log") + "Extensions of files to remove after generating PDF output successfully." + :type 'string + :group 'muse-context) + +(defcustom muse-context-header + "\\setupinteraction [state=start] +\\usemodule[tikz] +\\usemodule[bib]\n +(muse-context-setup-bibliography) + \\setuppublications[]\n +\\setuppublicationlist[]\n\\setupcite[]\n +\\starttext +\\startalignment[center] + \\blank[2*big] + {\\tfd (muse-publishing-directive \"title\")} + \\blank[3*medium] + {\\tfa (muse-publishing-directive \"author\")} + \\blank[2*medium] + {\\tfa (muse-publishing-directive \"date\")} + \\blank[3*medium] +\\stopalignment + +(and muse-publish-generate-contents + (not muse-context-permit-contents-tag) + \"\\\\placecontent\n\\\\page[yes]\")\n\n" + "Header used for publishing ConTeXt files. This may be text or a filename." + :type 'string + :group 'muse-context) + +(defcustom muse-context-footer "(muse-context-bibliography) +\\stoptext\n" + "Footer used for publishing ConTeXt files. This may be text or a filename." + :type 'string + :group 'muse-context) + +(defcustom muse-context-markup-regexps + `(;; numeric ranges + (10000 "\\([0-9]+\\)-\\([0-9]+\\)" 0 "\\1--\\2") + + ;; be careful of closing quote pairs + (10100 "\"'" 0 "\"\\\\-'")) + "List of markup regexps for identifying regions in a Muse page. +For more on the structure of this list, see `muse-publish-markup-regexps'." + :type '(repeat (choice + (list :tag "Markup rule" + integer + (choice regexp symbol) + integer + (choice string function symbol)) + function)) + :group 'muse-context) + +(defcustom muse-context-markup-functions + '((table . muse-context-markup-table)) + "An alist of style types to custom functions for that kind of text. +For more on the structure of this list, see +`muse-publish-markup-functions'." + :type '(alist :key-type symbol :value-type function) + :group 'muse-context) + +(defcustom muse-context-markup-strings + '((image-with-desc . "\\placefigure[][]{%3%}{\\externalfigure[%1%.%2%]}") + (image . "\\placefigure[][]{}{\\externalfigure[%s.%s]}") + (image-link . "\\useURL[aa][%s][][%1%] \\from[aa]") + (anchor-ref . "\\goto{%2%}{}[%1%]") + (url . "\\useURL[aa][%s][][%s] \\from[aa]") + (url-and-desc . "\\useURL[bb][%s][][%s]\\from[bb]\\footnote{%1%}") + (link . "\\goto{%2%}[program(%1%)]\\footnote{%1%}") + (link-and-anchor . "\\useexternaldocument[%4%][%4%][] \\at{%3%, page}{}[%4%::%2%]\\footnote{%1%}") + (email-addr . "\\useURL[mail][mailto:%s][][%s]\\from[mail]") + (anchor . "\\reference[%s] ") + (emdash . "---") + (comment-begin . "\\doifmode{comment}{") + (comment-end . "}") + (rule . "\\blank[medium]\\hrule\\blank[medium]") + (no-break-space . "~") + (enddots . "\\ldots ") + (dots . "\\dots ") + (part . "\\part{") + (part-end . "}") + (chapter . "\\chapter{") + (chapter-end . "}") + (section . "\\section{") + (section-end . "}") + (subsection . "\\subsection{") + (subsection-end . "}") + (subsubsection . "\\subsubsection{") + (subsubsection-end . "}") + (section-other . "\\subsubsubject{") + (section-other-end . "}") + (footnote . "\\footnote{") + (footnote-end . "}") + (footnotetext . "\\footnotetext[%d]{") + (begin-underline . "\\underbar{") + (end-underline . "}") + (begin-literal . "\\type{") + (end-literal . "}") + (begin-emph . "{\\em ") + (end-emph . "}") + (begin-more-emph . "{\\bf ") + (end-more-emph . "}") + (begin-most-emph . "{\\bf {\\em ") + (end-most-emph . "}}") + (begin-example . "\\starttyping") + (end-example . "\\stoptyping") + (begin-center . "\\startalignment[center]\n") + (end-center . "\n\\stopalignment") + (begin-quote . "\\startquotation\n") + (end-quote . "\n\\stopquotation") + (begin-cite . "\\cite[authoryear][") + (begin-cite-author . "\\cite[author][") + (begin-cite-year . "\\cite[year][") + (end-cite . "]") + (begin-uli . "\\startitemize\n") + (end-uli . "\n\\stopitemize") + (begin-uli-item . "\\item ") + (begin-oli . "\\startitemize[n]\n") + (end-oli . "\n\\stopitemize") + (begin-oli-item . "\\item ") + (begin-dl . "\\startitemize\n") + (end-dl . "\n\\stopitemize") + (begin-ddt . "\\head ") + (end-ddt . "\n") + (begin-verse . "\\blank[big]") + (end-verse-line . "\\par") + (verse-space . "\\fixedspaces ~~") + (end-verse . "\\blank[big]")) + "Strings used for marking up text. +These cover the most basic kinds of markup, the handling of which +differs little between the various styles." + :type '(alist :key-type symbol :value-type string) + :group 'muse-context) + +(defcustom muse-context-slides-header + "\\usemodule[(if (string-equal (muse-publishing-directive \"module\") nil) \"pre-01\" (muse-publishing-directive \"module\"))] +\\usemodule[tikz] +\\usemodule[newmat] +\\setupinteraction [state=start] +\\starttext +\\TitlePage { (muse-publishing-directive \"title\") +\\blank[3*medium] +\\tfa (muse-publishing-directive \"author\") + \\blank[2*medium] + \\tfa (muse-publishing-directive \"date\")}" + "Header for publishing a presentation (slides) using ConTeXt. +Any of the predefined modules, which are available in the +tex/context/base directory, can be used by writing a \"module\" +directive at the top of the muse file; if no such directive is +provided, module pre-01 is used. Alternatively, you can use your +own style (\"mystyle\", in this example) by replacing +\"\\usemodule[]\" with \"\\input mystyle\". + +This may be text or a filename." + :type 'string + :group 'muse-context) + +(defcustom muse-context-slides-markup-strings + '((section . "\\Topic {") + (subsection . "\\page \n{\\bf ") + (subsubsection . "{\\em ")) + "Strings used for marking up text in ConTeXt slides." + :type '(alist :key-type symbol :value-type string) + :group 'muse-context) + +(defcustom muse-context-markup-specials-document + '((?\\ . "\\textbackslash{}") + (?\_ . "\\textunderscore{}") + (?\< . "\\switchtobodyfont[small]") + (?\> . "\\switchtobodyfont[big]") + (?^ . "\\^") + (?\~ . "\\~") + (?\@ . "\\@") + (?\$ . "\\$") + (?\% . "\\%") + (?\{ . "\\{") + (?\} . "\\}") + (?\& . "\\&") + (?\# . "\\#")) + "A table of characters which must be represented specially. +These are applied to the entire document, sans already-escaped +regions." + :type '(alist :key-type character :value-type string) + :group 'muse-context) + +(defcustom muse-context-markup-specials-example + '() + "A table of characters which must be represented specially. +These are applied to regions. + +With the default interpretation of regions, no specials +need to be escaped." + :type '(alist :key-type character :value-type string) + :group 'muse-context) + +(defcustom muse-context-markup-specials-literal + '() + "A table of characters which must be represented specially. +This applies to =monospaced text= and regions." + :type '(alist :key-type character :value-type string) + :group 'muse-context) + +(defcustom muse-context-markup-specials-url + '((?\\ . "\\textbackslash") + (?\_ . "\\_") + (?\< . "\\<") + (?\> . "\\>") + (?\$ . "\\$") + (?\% . "\\%") + (?\{ . "\\{") + (?\} . "\\}") + (?\& . "\\&") + (?\# . "\\#")) + "A table of characters which must be represented specially. +These are applied to URLs." + :type '(alist :key-type character :value-type string) + :group 'muse-context) + +(defcustom muse-context-markup-specials-image + '((?\\ . "\\textbackslash") ; cannot find suitable replacement + (?\< . "\\<") + (?\> . "\\>") + (?\$ . "\\$") + (?\% . "\\%") + (?\{ . "\\{") + (?\} . "\\}") + (?\& . "\\&") + (?\# . "\\#") ; cannot find suitable replacement + ) + "A table of characters which must be represented specially. +These are applied to image filenames." + :type '(alist :key-type character :value-type string) + :group 'muse-context) + +(defun muse-context-decide-specials (context) + "Determine the specials to escape, depending on the CONTEXT argument." + (cond ((memq context '(underline emphasis document url-desc verbatim + footnote)) + muse-context-markup-specials-document) + ((eq context 'image) + muse-context-markup-specials-image) + ((memq context '(email url)) + muse-context-markup-specials-url) + ((eq context 'literal) + muse-context-markup-specials-literal) + ((eq context 'example) + muse-context-markup-specials-example) + (t (error "Invalid context argument '%s' in muse-context" context)))) + +(defun muse-context-markup-table () + (let* ((table-info (muse-publish-table-fields (match-beginning 0) + (match-end 0))) + (row-len (car table-info)) + (field-list (cdr table-info))) + (when table-info + (muse-insert-markup "\\starttable[|" + (mapconcat 'symbol-name (make-vector row-len 'l) + "|") "|]\n \\HL\n \\VL ") + (dolist (fields field-list) + (let ((type (car fields))) + (setq fields (cdr fields)) + (when (= type 3) + (muse-insert-markup "")) + (insert (car fields)) + (setq fields (cdr fields)) + (dolist (field fields) + (muse-insert-markup " \\VL ") + (insert field)) + (muse-insert-markup "\\VL\\NR\n \\HL\n \\VL ") + (when (= type 2) + (muse-insert-markup " ")))) + (muse-insert-markup "\\stoptable\n") + (while (search-backward "VL \\stoptable" nil t) + (replace-match "stoptable" nil t))))) + +(defun muse-context-fixup-dquotes () + "Fixup double quotes." + (goto-char (point-min)) + (let ((open t)) + (while (search-forward "\"" nil t) + (unless (get-text-property (match-beginning 0) 'read-only) + (when (or (bobp) + (eq (char-before) ?\n)) + (setq open t)) + (if open + (progn + (replace-match "``") + (setq open nil)) + (replace-match "''") + (setq open t)))))) + +(defcustom muse-context-permit-contents-tag nil + "If nil, ignore tags. Otherwise, insert table of contents. + +Most of the time, it is best to have a table of contents on the +first page, with a new page immediately following. To make this +work with documents published in both HTML and ConTeXt, we need to +ignore the tag. + +If you don't agree with this, then set this option to non-nil, +and it will do what you expect." + :type 'boolean + :group 'muse-context) + +(defun muse-context-fixup-citations () + "Replace semicolons in multi-head citations with colons." + (goto-char (point-min)) + (while (re-search-forward "\\\\cite.?\\[" nil t) + (let ((start (point)) + (end (re-search-forward "]"))) + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (while (re-search-forward ";" nil t) + (replace-match ",")))))) + +(defun muse-context-munge-buffer () + (muse-context-fixup-dquotes) + (muse-context-fixup-citations) + (when (and muse-context-permit-contents-tag + muse-publish-generate-contents) + (goto-char (car muse-publish-generate-contents)) + (muse-insert-markup "\\placecontent"))) + +(defun muse-context-bibliography () + (save-excursion + (goto-char (point-min)) + (if (re-search-forward "\\\\cite.?\\[" nil t) + "\\completepublications[criterium=all]" + ""))) + +(defun muse-context-setup-bibliography () + (save-excursion + (goto-char (point-min)) + (if (re-search-forward "\\\\cite.?\\[" nil t) + (concat + "\\usemodule[bibltx]\n\\setupbibtex [database=" + (muse-publishing-directive "bibsource") "]") + ""))) + +(defun muse-context-pdf-browse-file (file) + (shell-command (concat "open " file))) + +(defun muse-context-pdf-generate (file output-path final-target) + (apply + #'muse-publish-transform-output + file output-path final-target "PDF" + (function + (lambda (file output-path) + (let* ((fnd (file-name-directory output-path)) + (command (format "%s \"%s\"" + muse-context-pdf-program + (file-relative-name file fnd))) + (times 0) + (default-directory fnd) + result) + ;; XEmacs can sometimes return a non-number result. We'll err + ;; on the side of caution by continuing to attempt to generate + ;; the PDF if this happens and treat the final result as + ;; successful. + (while (and (< times 2) + (or (not (numberp result)) + (not (eq result 0)) + ;; table of contents takes 2 passes +;; (file-readable-p +;; (muse-replace-regexp-in-string +;; "\\.tex\\'" ".toc" file t t)) + )) + (setq result (shell-command command) + times (1+ times))) + (if (or (not (numberp result)) + (eq result 0)) + t + nil)))) + muse-context-pdf-cruft)) + +(muse-define-style "context" + :suffix 'muse-context-extension + :regexps 'muse-context-markup-regexps + :functions 'muse-context-markup-functions + :strings 'muse-context-markup-strings + :specials 'muse-context-decide-specials + :after 'muse-context-munge-buffer + :header 'muse-context-header + :footer 'muse-context-footer + :browser 'find-file) + +(muse-derive-style "context-pdf" "context" + :final 'muse-context-pdf-generate + :browser 'muse-context-pdf-browse-file + :link-suffix 'muse-context-pdf-extension + :osuffix 'muse-context-pdf-extension) + +(muse-derive-style "context-slides" "context" + :header 'muse-context-slides-header + :strings 'muse-context-slides-markup-strings) + +(muse-derive-style "context-slides-pdf" "context-pdf" + :header 'muse-context-slides-header + :strings 'muse-context-slides-markup-strings) + +(provide 'muse-context) + +;;; muse-context.el ends here diff --git a/elpa/muse-3.20/muse-docbook.el b/elpa/muse-3.20/muse-docbook.el new file mode 100644 index 0000000..a54089f --- /dev/null +++ b/elpa/muse-3.20/muse-docbook.el @@ -0,0 +1,352 @@ +;;; muse-docbook.el --- publish DocBook files + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Contributors: + +;; Dale P. Smith (dpsm AT en DOT com) improved the markup +;; significantly and made many valuable suggestions. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse DocBook XML Publishing +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'muse-publish) +(require 'muse-regexps) +(require 'muse-xml-common) + +(defgroup muse-docbook nil + "Options controlling the behavior of Muse DocBook XML publishing. +See `muse-docbook' for more information." + :group 'muse-publish) + +(defcustom muse-docbook-extension ".xml" + "Default file extension for publishing DocBook XML files." + :type 'string + :group 'muse-docbook) + +(defcustom muse-docbook-header + " + (muse-docbook-encoding)\"?> +(muse-docbook-entities)> +

+ + <lisp>(muse-publishing-directive \"title\")</lisp> + (muse-docbook-get-author + (muse-publishing-directive \"author\")) + (muse-publishing-directive \"date\") + + \n" + "Header used for publishing DocBook XML files. +This may be text or a filename." + :type 'string + :group 'muse-docbook) + +(defcustom muse-docbook-footer " + +(muse-docbook-bibliography)
\n" + "Footer used for publishing DocBook XML files. +This may be text or a filename." + :type 'string + :group 'muse-docbook) + +(defcustom muse-docbook-markup-regexps + `(;; Beginning of doc, end of doc, or plain paragraph separator + (10000 ,(concat "\\(\\(\n\\(?:[" muse-regexp-blank "]*\n\\)*" + "\\([" muse-regexp-blank "]*\n\\)\\)" + "\\|\\`\\s-*\\|\\s-*\\'\\)") + 3 muse-docbook-markup-paragraph)) + "List of markup rules for publishing a Muse page to DocBook XML. +For more on the structure of this list, see `muse-publish-markup-regexps'." + :type '(repeat (choice + (list :tag "Markup rule" + integer + (choice regexp symbol) + integer + (choice string function symbol)) + function)) + :group 'muse-docbook) + +(defcustom muse-docbook-markup-functions + '((anchor . muse-xml-markup-anchor) + (table . muse-xml-markup-table)) + "An alist of style types to custom functions for that kind of text. +For more on the structure of this list, see +`muse-publish-markup-functions'." + :type '(alist :key-type symbol :value-type function) + :group 'muse-docbook) + +(defcustom muse-docbook-markup-strings + '((image-with-desc . " + + + +%3% +") + (image . " + +") + (image-link . " + +") + (anchor-ref . "%s") + (url . "%s") + (link . "%s") + (link-and-anchor . "%s") + (email-addr . "%s") + (anchor . "\n") + (emdash . "%s—%s") + (comment-begin . "") + (rule . "") + (no-break-space . " ") + (enddots . "....") + (dots . "...") + (section . "
") + (section-end . "") + (subsection . "
") + (subsection-end . "") + (subsubsection . "
") + (subsubsection-end . "") + (section-other . "
") + (section-other-end . "") + (section-close . "
") + (footnote . "") + (footnote-end . "") + (begin-underline . "") + (end-underline . "") + (begin-literal . "") + (end-literal . "") + (begin-emph . "") + (end-emph . "") + (begin-more-emph . "") + (end-more-emph . "") + (begin-most-emph . "") + (end-most-emph . "") + (begin-verse . "\n") + (verse-space . " ") + (end-verse . "") + (begin-example . "") + (end-example . "") + (begin-center . "\n") + (end-center . "\n") + (begin-quote . "
\n") + (end-quote . "\n
") + (begin-cite . "") + (begin-cite-author . "A:") + (begin-cite-year . "Y:") + (end-cite . "") + (begin-quote-item . "") + (end-quote-item . "") + (begin-uli . "\n") + (end-uli . "\n") + (begin-uli-item . "") + (end-uli-item . "") + (begin-oli . "\n") + (end-oli . "\n") + (begin-oli-item . "") + (end-oli-item . "") + (begin-dl . "\n") + (end-dl . "\n") + (begin-dl-item . "\n") + (end-dl-item . "\n") + (begin-ddt . "") + (end-ddt . "") + (begin-dde . "") + (end-dde . "") + (begin-table . "\n") + (end-table . "") + (begin-table-group . " \n") + (end-table-group . " \n") + (begin-table-row . " \n") + (end-table-row . " \n") + (begin-table-entry . " ") + (end-table-entry . "\n")) + "Strings used for marking up text. +These cover the most basic kinds of markup, the handling of which +differs little between the various styles." + :type '(alist :key-type symbol :value-type string) + :group 'muse-docbook) + +(defcustom muse-docbook-encoding-default 'utf-8 + "The default Emacs buffer encoding to use in published files. +This will be used if no special characters are found." + :type 'symbol + :group 'muse-docbook) + +(defcustom muse-docbook-charset-default "utf-8" + "The default DocBook XML charset to use if no translation is +found in `muse-docbook-encoding-map'." + :type 'string + :group 'muse-docbook) + +(defun muse-docbook-encoding () + (muse-xml-transform-content-type + (or (and (boundp 'buffer-file-coding-system) + buffer-file-coding-system) + muse-docbook-encoding-default) + muse-docbook-charset-default)) + +(defun muse-docbook-markup-paragraph () + (catch 'bail-out + (let ((end (copy-marker (match-end 0) t))) + (goto-char (match-beginning 0)) + (when (save-excursion + (save-match-data + (and (not (get-text-property (max (point-min) (1- (point))) + 'muse-no-paragraph)) + (re-search-backward + "<\\(/?\\)\\(para\\|footnote\\|literallayout\\)[ >]" + nil t) + (cond ((string= (match-string 2) "literallayout") + (and (not (string= (match-string 1) "/")) + (throw 'bail-out t))) + ((string= (match-string 2) "para") + (and + (not (string= (match-string 1) "/")) + ;; don't mess up nested lists + (not (and (muse-looking-back "") + (throw 'bail-out t))))) + ((string= (match-string 2) "footnote") + (string= (match-string 1) "/")) + (t nil))))) + (when (get-text-property (1- (point)) 'muse-end-list) + (goto-char (previous-single-property-change (1- (point)) + 'muse-end-list))) + (muse-insert-markup "")) + (goto-char end)) + (cond + ((eobp) + (unless (bolp) + (insert "\n"))) + ((get-text-property (point) 'muse-no-paragraph) + (forward-char 1) + nil) + ((eq (char-after) ?\<) + (when (looking-at (concat "<\\(emphasis\\|systemitem\\|inlinemediaobject" + "\\|u?link\\|anchor\\|email\\)[ >]")) + (muse-insert-markup ""))) + (t + (muse-insert-markup ""))))) + +(defun muse-docbook-get-author (&optional author) + "Split the AUTHOR directive into separate fields. +AUTHOR should be of the form: \"Firstname Other Names Lastname\", +and anything after `Firstname' is optional." + (setq author (save-match-data (split-string author))) + (let ((num-el (length author))) + (cond ((eq num-el 1) + (concat "" (car author) "")) + ((eq num-el 2) + (concat "" (nth 0 author) "" + "" (nth 1 author) "")) + ((eq num-el 3) + (concat "" (nth 0 author) "" + "" (nth 1 author) "" + "" (nth 2 author) "")) + (t + (let (first last) + (setq first (car author)) + (setq author (nreverse (cdr author))) + (setq last (car author)) + (setq author (nreverse (cdr author))) + (concat "" first "" + "" + (mapconcat 'identity author " ") + "" + "" last "")))))) + +(defun muse-docbook-fixup-images () + (goto-char (point-min)) + (while (re-search-forward (concat "$") + nil t) + (replace-match (upcase (match-string 1)) t t nil 1))) + +(defun muse-docbook-fixup-citations () + ;; remove the role attribute if there is no role + (goto-char (point-min)) + (while (re-search-forward "<\\(citation role=\"nil\"\\)>" nil t) + (replace-match "citation" t t nil 1)) + ;; replace colons in multi-head citations with semicolons + (goto-char (point-min)) + (while (re-search-forward "" nil t) + (let ((start (point)) + (end (re-search-forward ""))) + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (while (re-search-forward "," nil t) + (replace-match ";")))))) + +(defun muse-docbook-munge-buffer () + (muse-docbook-fixup-images) + (muse-docbook-fixup-citations)) + +(defun muse-docbook-entities () + (save-excursion + (goto-char (point-min)) + (if (re-search-forward "\n]") + ""))) + +(defun muse-docbook-bibliography () + (save-excursion + (goto-char (point-min)) + (if (re-search-forward "(muse-publishing-directive \"title\")\" +.SUBTITLE \"(muse-publishing-directive \"date\")\" +.AUTHOR \"(muse-publishing-directive \"author\")\" +.PRINTSTYLE TYPESET +.de list +. LIST \\$1 +. SHIFT_LIST \\$2 +.. +.PARA_INDENT 0 +.START +(and muse-publish-generate-contents \".TOC\n\")\n" + "Header used for publishing groff -mom -mwww files." + :type '(choice string file) + :group 'muse-groff) + +(defcustom muse-groff-footer " " + "Footer used for publishing groff -mom -mwww files." + :type '(choice string file) + :group 'muse-groff) + +(defcustom muse-groff-markup-regexps + `((10400 ,(concat "\\(\n\\)?\n" + "\\([" + muse-regexp-blank + "]*\n\\)+\\(<\\(blockquote\\|center\\)>\n\\)?") + 0 muse-groff-markup-paragraph)) +"List of markup regexps for identifying regions in a Muse page. +For more on the structure of this list, see `muse-publish-markup-regexps'." + :type '(repeat (choice + (list :tag "Markup rule" + integer + (choice regexp symbol) + integer + (choice string function symbol)) + function)) + :group 'muse-groff) + +(defcustom muse-groff-markup-functions + '((table . muse-groff-markup-table)) + "An alist of style types to custom functions for that kind of text. +For more on the structure of this list, see +`muse-publish-markup-functions'." + :type '(alist :key-type symbol :value-type function) + :group 'muse-groff) + +(defcustom muse-groff-markup-tags + '() + "A list of tag specifications, for specially marking up GROFF." + :type '(repeat (list (string :tag "Markup tag") + (boolean :tag "Expect closing tag" :value t) + (boolean :tag "Parse attributes" :value nil) + (boolean :tag "Nestable" :value nil) + function)) + :group 'muse-groff) + +(defcustom muse-groff-markup-strings + `((image-with-desc . "\n.MPIMG -R %s.%s\n") + (image . "\n.MPIMG -R %s.%s\n") + (image-link . "\n.\\\" %s\n.MPIMG -R %s.%s") + (url . "\n.URL %s %s\n\\z") + (link . "\n.URL %s %s\n\\z") + (email-addr . "\f[C]%s\f[]") + (emdash . "\\(em") + (rule . "\n.RULE\n") + (no-break-space . "\\h") + (line-break . "\\p") + (enddots . "....") + (dots . "...") +;; (part . "\\part{") +;; (part-end . "}") +;; (chapter . "\\chapter{") +;; (chapter-end . "}") + (section . ".HEAD \"") + (section-end . "\"") + (subsection . ".SUBHEAD \"") + (subsection-end . "\"") + (subsubsection . ".PARAHEAD \"") + (subsubsection-end . "\"") +;; (footnote . "\\c\n.FOOTNOTE\n") +;; (footnote-end . "\n.FOOTNOTE OFF\n") +;; (footnotemark . "\\footnotemark[%d]") +;; (footnotetext . "\\footnotetext[%d]{") +;; (footnotetext-end . "}") + (begin-underline . "\n.UNDERSCORE \"") + (end-underline . "\"\n") + (begin-literal . "\\fC") + (end-literal . "\\fP") + (begin-emph . "\\fI") + (end-emph . "\\fP") + (begin-more-emph . "\\fB") + (end-more-emph . "\\fP") + (begin-most-emph . "\\f(BI") + (end-most-emph . "\\fP") + (begin-verse . ".QUOTE") + (end-verse . ".QUOTE OFF") + (begin-center . "\n.CENTER\n") + (end-center . "\n.QUAD L\n") + (begin-example . ,(concat + ".QUOTE_FONT CR\n.QUOTE_INDENT 1\n"".QUOTE_SIZE -2\n" + ".UNDERLINE_QUOTES OFF\n.QUOTE")) + (end-example . ".QUOTE OFF") + (begin-quote . ".BLOCKQUOTE") + (end-quote . ".BLOCKQUOTE OFF") + (begin-cite . "") + (begin-cite-author . "") + (begin-cite-year . "") + (end-cite . "") + (begin-uli . ".list BULLET\n.SHIFT_LIST 2m\n.ITEM\n") + (end-uli . "\n.LIST OFF") + (begin-oli . ".list DIGIT\n.SHIFT_LIST 2m\n.ITEM\n") + (end-oli . "\n.LIST OFF") + (begin-ddt . "\\fB") + (begin-dde . "\\fP\n.IR 4P\n") + (end-ddt . ".IRX CLEAR")) + "Strings used for marking up text. +These cover the most basic kinds of markup, the handling of which +differs little between the various styles." + :type '(alist :key-type symbol :value-type string) + :group 'muse-groff) + +(defcustom muse-groff-markup-specials + '((?\\ . "\\e")) + "A table of characters which must be represented specially." + :type '(alist :key-type character :value-type string) + :group 'muse-groff) + +(defun muse-groff-markup-paragraph () + (let ((end (copy-marker (match-end 0) t))) + (goto-char (1+ (match-beginning 0))) + (delete-region (point) end) + (unless (looking-at "\.\\(\\(\\(SUB\\|PARA\\)?HEAD \\)\\|RULE$\\)") + (muse-insert-markup ".ALD .5v\n.PP\n.ne 2\n")))) + +(defun muse-groff-protect-leading-chars () + "Protect leading periods and apostrophes from being interpreted as +command characters." + (while (re-search-forward "^[.']" nil t) + (replace-match "\\\\&\\&" t))) + +(defun muse-groff-concat-lists () + "Join like lists." + (let ((type "") + arg begin) + (while (re-search-forward "^\.LIST[ \t]+\\(.*\\)\n" nil t) + (setq arg (match-string 1)) + (if (string= arg "OFF") + (setq begin (match-beginning 0)) + (if (and begin (string= type arg)) + (delete-region begin (match-end 0)) + (setq type arg + begin 0)))))) + +(defun muse-groff-fixup-dquotes () + "Fixup double quotes." + (let ((open t)) + (while (search-forward "\"" nil t) + (unless (get-text-property (match-beginning 0) 'read-only) + (if (and (bolp) (eq (char-before) ?\n)) + (setq open t)) + (if open + (progn + (replace-match "``") + (setq open nil)) + (replace-match "''") + (setq open t)))))) + +(defun muse-groff-prepare-buffer () + (goto-char (point-min)) + (muse-groff-protect-leading-chars)) + +(defun muse-groff-munge-buffer () + (goto-char (point-min)) + (muse-groff-concat-lists)) + +(defun muse-groff-pdf-browse-file (file) + (shell-command (concat "open " file))) + +(defun muse-groff-pdf-generate (file output-path final-target) + (muse-publish-transform-output + file output-path final-target "PDF" + (function + (lambda (file output-path) + (let ((command + (format + (concat "file=%s; ext=%s; cd %s && cp $file$ext $file.ref && " + "groff -mom -mwww -t $file$ext > $file.ps && " + "pstopdf $file.ps") + (file-name-sans-extension file) + muse-groff-extension + (file-name-directory output-path)))) + (shell-command command)))) + ".ps")) + +;;; Register the Muse GROFF Publisher + +(muse-define-style "groff" + :suffix 'muse-groff-extension + :regexps 'muse-groff-markup-regexps +;;; :functions 'muse-groff-markup-functions + :strings 'muse-groff-markup-strings + :tags 'muse-groff-markup-tags + :specials 'muse-groff-markup-specials + :before 'muse-groff-prepare-buffer + :before-end 'muse-groff-munge-buffer + :header 'muse-groff-header + :footer 'muse-groff-footer + :browser 'find-file) + +(muse-derive-style "groff-pdf" "groff" + :final 'muse-groff-pdf-generate + :browser 'muse-groff-pdf-browse-file + :osuffix 'muse-groff-pdf-extension) + +(provide 'muse-groff) + +;;; muse-groff.el ends here +;; +;; Local Variables: +;; indent-tabs-mode: nil +;; End: diff --git a/elpa/muse-3.20/muse-html.el b/elpa/muse-3.20/muse-html.el new file mode 100644 index 0000000..6a9356b --- /dev/null +++ b/elpa/muse-3.20/muse-html.el @@ -0,0 +1,754 @@ +;;; muse-html.el --- publish to HTML and XHTML + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Contributors: + +;; Zhiqiang Ye (yezq AT mail DOT cbi DOT pku DOT edu DOT cn) suggested +;; appending an 'encoding="..."' fragment to the first line of the +;; sample publishing header so that when editing the resulting XHTML +;; file, Emacs would use the proper encoding. + +;; Sun Jiyang (sunyijiang AT gmail DOT com) came up with the idea for +;; the tag and provided an implementation for emacs-wiki. + +;; Charles Wang (wcy123 AT gmail DOT com) provided an initial +;; implementation of the tag for Muse. + +;; Clinton Ebadi (clinton AT unknownlamer DOT org) provided further +;; ideas for the implementation of the tag. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse HTML Publishing +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'muse-publish) +(require 'muse-regexps) +(require 'muse-xml-common) + +(defgroup muse-html nil + "Options controlling the behavior of Muse HTML publishing." + :group 'muse-publish) + +(defcustom muse-html-extension ".html" + "Default file extension for publishing HTML files." + :type 'string + :group 'muse-html) + +(defcustom muse-xhtml-extension ".html" + "Default file extension for publishing XHTML files." + :type 'string + :group 'muse-html) + +(defcustom muse-html-style-sheet + "" + "Store your stylesheet definitions here. +This is used in `muse-html-header'. +You can put raw CSS in here or a tag to an external stylesheet. +This text may contain markup tags. + +An example of using is as follows. + +" + :type 'string + :group 'muse-html) + +(defcustom muse-xhtml-style-sheet + "" + "Store your stylesheet definitions here. +This is used in `muse-xhtml-header'. +You can put raw CSS in here or a tag to an external stylesheet. +This text may contain markup tags. + +An example of using is as follows. + +" + :type 'string + :group 'muse-html) + +(defcustom muse-html-header + " + + + <lisp> + (concat (muse-publishing-directive \"title\") + (let ((author (muse-publishing-directive \"author\"))) + (if (not (string= author (user-full-name))) + (concat \" (by \" author \")\"))))</lisp> + + muse-html-meta-http-equiv\" + content=\"muse-html-meta-content-type\"> + + (let ((maintainer (muse-style-element :maintainer))) + (when maintainer + (concat \"\"))) + + (muse-style-element :style-sheet muse-publishing-current-style) + + + +

+ (concat (muse-publishing-directive \"title\") + (let ((author (muse-publishing-directive \"author\"))) + (if (not (string= author (user-full-name))) + (concat \" (by \" author \")\"))))

+ \n" + "Header used for publishing HTML files. This may be text or a filename." + :type 'string + :group 'muse-html) + +(defcustom muse-html-footer " + + +\n" + "Footer used for publishing HTML files. This may be text or a filename." + :type 'string + :group 'muse-html) + +(defcustom muse-xhtml-header + " + (muse-html-encoding)
\"?> + + + + <lisp> + (concat (muse-publishing-directive \"title\") + (let ((author (muse-publishing-directive \"author\"))) + (if (not (string= author (user-full-name))) + (concat \" (by \" author \")\"))))</lisp> + + muse-html-meta-http-equiv\" + content=\"muse-html-meta-content-type\" /> + + (let ((maintainer (muse-style-element :maintainer))) + (when maintainer + (concat \"\"))) + + (muse-style-element :style-sheet muse-publishing-current-style) + + + +

+ (concat (muse-publishing-directive \"title\") + (let ((author (muse-publishing-directive \"author\"))) + (if (not (string= author (user-full-name))) + (concat \" (by \" author \")\"))))

+ \n" + "Header used for publishing XHTML files. This may be text or a filename." + :type 'string + :group 'muse-html) + +(defcustom muse-xhtml-footer " + + +\n" + "Footer used for publishing XHTML files. This may be text or a filename." + :type 'string + :group 'muse-html) + +(defcustom muse-html-anchor-on-word nil + "When true, anchors surround the closest word. This allows you +to select them in a browser (i.e. for pasting), but has the +side-effect of marking up headers in multiple colors if your +header style is different from your link style." + :type 'boolean + :group 'muse-html) + +(defcustom muse-html-table-attributes + " class=\"muse-table\" border=\"2\" cellpadding=\"5\"" + "The attribute to be used with HTML tags. +Note that Muse supports insertion of raw HTML tags, as long +as you wrap the region in ." + :type 'string + :group 'muse-html) + +(defcustom muse-html-markup-regexps + `(;; Beginning of doc, end of doc, or plain paragraph separator + (10000 ,(concat "\\(\\(\n\\(?:[" muse-regexp-blank "]*\n\\)*" + "\\([" muse-regexp-blank "]*\n\\)\\)" + "\\|\\`\\s-*\\|\\s-*\\'\\)") + ;; this is somewhat repetitive because we only require the + ;; line just before the paragraph beginning to be not + ;; read-only + 3 muse-html-markup-paragraph)) + "List of markup rules for publishing a Muse page to HTML. +For more on the structure of this list, see `muse-publish-markup-regexps'." + :type '(repeat (choice + (list :tag "Markup rule" + integer + (choice regexp symbol) + integer + (choice string function symbol)) + function)) + :group 'muse-html) + +(defcustom muse-html-markup-functions + '((anchor . muse-html-markup-anchor) + (table . muse-html-markup-table) + (footnote . muse-html-markup-footnote)) + "An alist of style types to custom functions for that kind of text. +For more on the structure of this list, see +`muse-publish-markup-functions'." + :type '(alist :key-type symbol :value-type function) + :group 'muse-html) + +(defcustom muse-html-markup-strings + '((image-with-desc . "
+ + +
\"%3%\"
%3%
") + (image . "\"\"") + (image-link . " +") + (anchor-ref . "%s") + (url . "%s") + (link . "%s") + (link-and-anchor . "%s") + (email-addr . "%s") + (anchor . "") + (emdash . "%s—%s") + (comment-begin . "") + (rule . "
") + (fn-sep . "
\n") + (no-break-space . " ") + (line-break . "
") + (enddots . "....") + (dots . "...") + (section . "

") + (section-end . "

") + (subsection . "

") + (subsection-end . "

") + (subsubsection . "

") + (subsubsection-end . "

") + (section-other . "
") + (section-other-end . "
") + (begin-underline . "") + (end-underline . "") + (begin-literal . "") + (end-literal . "") + (begin-cite . "") + (begin-cite-author . "") + (begin-cite-year . "") + (end-cite . "") + (begin-emph . "") + (end-emph . "") + (begin-more-emph . "") + (end-more-emph . "") + (begin-most-emph . "") + (end-most-emph . "") + (begin-verse . "

\n") + (verse-space . "  ") + (end-verse-line . "
") + (end-last-stanza-line . "
") + (empty-verse-line . "
") + (end-verse . "

") + (begin-example . "
")
+    (end-example     . "
") + (begin-center . "
\n

") + (end-center . "

\n
") + (begin-quote . "
\n") + (end-quote . "\n
") + (begin-quote-item . "

") + (end-quote-item . "

") + (begin-uli . "
    \n") + (end-uli . "\n
") + (begin-uli-item . "
  • ") + (end-uli-item . "
  • ") + (begin-oli . "
      \n") + (end-oli . "\n
    ") + (begin-oli-item . "
  • ") + (end-oli-item . "
  • ") + (begin-dl . "
    \n") + (end-dl . "\n
    ") + (begin-ddt . "
    ") + (end-ddt . "
    ") + (begin-dde . "
    ") + (end-dde . "
    ") + (begin-table . "\n") + (end-table . "") + (begin-table-row . " \n") + (end-table-row . " \n") + (begin-table-entry . " <%s>") + (end-table-entry . "\n")) + "Strings used for marking up text as HTML. +These cover the most basic kinds of markup, the handling of which +differs little between the various styles." + :type '(alist :key-type symbol :value-type string) + :group 'muse-html) + +(defcustom muse-xhtml-markup-strings + '((image-with-desc . " + + +
    \"%3%\"
    %3%
    ") + (image . "\"\"") + (image-link . "
    +\"\"") + (rule . "
    ") + (fn-sep . "
    \n") + (line-break . "
    ") + (begin-underline . "") + (end-underline . "") + (begin-center . "

    \n") + (end-center . "\n

    ") + (end-verse-line . "
    ") + (end-last-stanza-line . "
    ") + (empty-verse-line . "
    ")) + "Strings used for marking up text as XHTML. +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +If a markup rule is not found here, `muse-html-markup-strings' is +searched." + :type '(alist :key-type symbol :value-type string) + :group 'muse-html) + +(defcustom muse-xhtml1.1-markup-strings + '((anchor . "")) + "Strings used for marking up text as XHTML 1.1. +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +If a markup rule is not found here, `muse-xhtml-markup-strings' +and `muse-html-markup-strings' are searched." + :type '(alist :key-type symbol :value-type string) + :group 'muse-html) + +(defcustom muse-html-markup-tags + '(("class" t t t muse-html-class-tag) + ("div" t t t muse-html-div-tag) + ("src" t t nil muse-html-src-tag)) + "A list of tag specifications, for specially marking up HTML." + :type '(repeat (list (string :tag "Markup tag") + (boolean :tag "Expect closing tag" :value t) + (boolean :tag "Parse attributes" :value nil) + (boolean :tag "Nestable" :value nil) + function)) + :group 'muse-html) + +(defcustom muse-html-meta-http-equiv "Content-Type" + "The http-equiv attribute used for the HTML tag." + :type 'string + :group 'muse-html) + +(defcustom muse-html-meta-content-type "text/html" + "The content type used for the HTML tag. +If you are striving for XHTML 1.1 compliance, you may want to +change this to \"application/xhtml+xml\"." + :type 'string + :group 'muse-html) + +(defcustom muse-html-meta-content-encoding (if (featurep 'mule) + 'detect + "iso-8859-1") + "The charset to append to the HTML tag. +If set to the symbol 'detect, use `muse-html-encoding-map' to try +and determine the HTML charset from emacs's coding. If set to a +string, this string will be used to force a particular charset" + :type '(choice string symbol) + :group 'muse-html) + +(defcustom muse-html-encoding-default 'iso-8859-1 + "The default Emacs buffer encoding to use in published files. +This will be used if no special characters are found." + :type 'symbol + :group 'muse-html) + +(defcustom muse-html-charset-default "iso-8859-1" + "The default HTML meta charset to use if no translation is found in +`muse-html-encoding-map'." + :type 'string + :group 'muse-html) + +(defcustom muse-html-src-allowed-modes t + "Modes that we allow the tag to colorize. +If t, permit the tag to colorize any mode. + +If a list of mode names, such as '(\"html\" \"latex\"), and the +lang argument to is not in the list, then use fundamental +mode instead." + :type '(choice (const :tag "Any" t) + (repeat (string :tag "Mode"))) + :group 'muse-html) + +(defun muse-html-insert-anchor (anchor) + "Insert an anchor, either around the word at point, or within a tag." + (skip-chars-forward (concat muse-regexp-blank "\n")) + (if (looking-at (concat "<\\([^" muse-regexp-blank "/>\n]+\\)>")) + (let ((tag (match-string 1))) + (goto-char (match-end 0)) + (muse-insert-markup (muse-markup-text 'anchor anchor)) + (when muse-html-anchor-on-word + (or (and (search-forward (format "" tag) + (muse-line-end-position) t) + (goto-char (match-beginning 0))) + (forward-word 1))) + (muse-insert-markup "")) + (muse-insert-markup (muse-markup-text 'anchor anchor)) + (when muse-html-anchor-on-word + (forward-word 1)) + (muse-insert-markup "\n"))) + +(defun muse-html-markup-anchor () + (unless (get-text-property (match-end 1) 'muse-link) + (save-match-data + (muse-html-insert-anchor (match-string 2))) + (match-string 1))) + +(defun muse-html-markup-paragraph () + (let ((end (copy-marker (match-end 0) t))) + (goto-char (match-beginning 0)) + (when (save-excursion + (save-match-data + (and (not (get-text-property (max (point-min) (1- (point))) + 'muse-no-paragraph)) + (re-search-backward "<\\(/?\\)p[ >]" nil t) + (not (string-equal (match-string 1) "/"))))) + (when (get-text-property (1- (point)) 'muse-end-list) + (goto-char (previous-single-property-change (1- (point)) + 'muse-end-list))) + (muse-insert-markup "

    ")) + (goto-char end)) + (cond + ((eobp) + (unless (bolp) + (insert "\n"))) + ((get-text-property (point) 'muse-no-paragraph) + (forward-char 1) + nil) + ((eq (char-after) ?\<) + (cond + ((looking-at "<\\(em\\|strong\\|code\\|span\\)[ >]") + (muse-insert-markup "

    ")) + ((looking-at "\n]+>") + (muse-insert-markup "

    "))) + ((looking-at "]") + (muse-insert-markup "

    ")) + (t + (forward-char 1) + nil))) + ((muse-looking-back "\\(\\|


    \\)\n\n") + (muse-insert-markup "

    ")) + (t + (muse-insert-markup "

    ")))) + +(defun muse-html-markup-footnote () + (cond + ((get-text-property (match-beginning 0) 'muse-link) + nil) + ((= (muse-line-beginning-position) (match-beginning 0)) + (prog1 + (let ((text (match-string 1))) + (muse-insert-markup + (concat "

    " + "" + text "."))) + (save-excursion + (save-match-data + (let* ((beg (goto-char (match-end 0))) + (end (and (search-forward "\n\n" nil t) + (prog1 + (copy-marker (match-beginning 0)) + (goto-char beg))))) + (while (re-search-forward (concat "^[" + muse-regexp-blank + "]+\\([^\n]\\)") + end t) + (replace-match "\\1" t))))) + (replace-match ""))) + (t (let ((text (match-string 1))) + (muse-insert-markup + (concat "" + text ""))) + (replace-match "")))) + +(defun muse-html-markup-table () + (muse-xml-markup-table muse-html-table-attributes)) + +;; Handling of tags for HTML + +(defun muse-html-strip-links (string) + "Remove all HTML links from STRING." + (muse-replace-regexp-in-string "\\(\\|\\)" "" string nil t)) + +(defun muse-html-insert-contents (depth) + "Scan the current document and generate a table of contents at point. +DEPTH indicates how many levels of headings to include. The default is 2." + (let ((max-depth (or depth 2)) + (index 1) + base contents l end) + (save-excursion + (goto-char (point-min)) + (search-forward "Page published by Emacs Muse begins here" nil t) + (catch 'done + (while (re-search-forward "\\(.+?\\)$" nil t) + (unless (and (get-text-property (point) 'read-only) + (not (get-text-property (match-beginning 0) + 'muse-contents))) + (remove-text-properties (match-beginning 0) (match-end 0) + '(muse-contents nil)) + (setq l (1- (string-to-number (match-string 1)))) + (if (null base) + (setq base l) + (if (< l base) + (throw 'done t))) + (when (<= l max-depth) + ;; escape specials now before copying the text, so that we + ;; can deal sanely with both emphasis in titles and + ;; special characters + (goto-char (match-end 2)) + (setq end (point-marker)) + (muse-publish-escape-specials (match-beginning 2) end + nil 'document) + (muse-publish-mark-read-only (match-beginning 2) end) + (setq contents (cons (cons l (buffer-substring-no-properties + (match-beginning 2) end)) + contents)) + (set-marker end nil) + (goto-char (match-beginning 2)) + (muse-html-insert-anchor (concat "sec" (int-to-string index))) + (setq index (1+ index))))))) + (setq index 1 contents (nreverse contents)) + (let ((depth 1) (sub-open 0) (p (point))) + (muse-insert-markup "

    \n
    \n") + (while contents + (muse-insert-markup "
    \n" + "" + (muse-html-strip-links (cdar contents)) + "\n" + "
    \n") + (setq index (1+ index) + depth (caar contents) + contents (cdr contents)) + (when contents + (cond + ((< (caar contents) depth) + (let ((idx (caar contents))) + (while (< idx depth) + (muse-insert-markup "
    \n\n") + (setq sub-open (1- sub-open) + idx (1+ idx))))) + ((> (caar contents) depth) ; can't jump more than one ahead + (muse-insert-markup "
    \n
    \n") + (setq sub-open (1+ sub-open)))))) + (while (> sub-open 0) + (muse-insert-markup "
    \n
    \n") + (setq sub-open (1- sub-open))) + (muse-insert-markup "\n
    \n") + (muse-publish-mark-read-only p (point))))) + +(defun muse-html-denote-headings () + "Place a text property on any headings in the current buffer. +This allows the headings to be picked up later on if publishing a +table of contents." + (save-excursion + (goto-char (point-min)) + (search-forward "Page published by Emacs Muse begins here" nil t) + (while (re-search-forward "\\(.+?\\)$" nil t) + (unless (get-text-property (point) 'read-only) + (add-text-properties (match-beginning 0) (match-end 0) + '(muse-contents t)))))) + +(defun muse-html-class-tag (beg end attrs) + (let ((name (cdr (assoc "name" attrs)))) + (when name + (goto-char beg) + (muse-insert-markup "") + (save-excursion + (goto-char end) + (muse-insert-markup ""))))) + +(defun muse-html-div-tag (beg end attrs) + "Publish a
    tag for HTML." + (let ((id (cdr (assoc "id" attrs))) + (style (cdr (assoc "style" attrs)))) + (when (or id style) + (goto-char beg) + (if (null id) + (muse-insert-markup "
    ") + (muse-insert-markup "
    ")) + (save-excursion + (goto-char end) + (muse-insert-markup "
    "))))) + +(defun muse-html-src-tag (beg end attrs) + "Publish the region using htmlize. +The language to use may be specified by the \"lang\" attribute. + +Muse will look for a function named LANG-mode, where LANG is the +value of the \"lang\" attribute. + +This tag requires htmlize 1.34 or later in order to work." + (if (condition-case nil + (progn + (require 'htmlize) + (if (fboundp 'htmlize-region-for-paste) + nil + (muse-display-warning + (concat "The `htmlize-region-for-paste' function was not" + " found.\nThis is available in htmlize.el 1.34" + " or later.")) + t)) + (error nil t)) + ;; if htmlize.el was not found, treat this like an example tag + (muse-publish-example-tag beg end) + (muse-publish-ensure-block beg end) + (let* ((lang (cdr (assoc "lang" attrs))) + (mode (or (and (not (eq muse-html-src-allowed-modes t)) + (not (member lang muse-html-src-allowed-modes)) + 'fundamental-mode) + (intern-soft (concat lang "-mode")))) + (text (muse-delete-and-extract-region beg end)) + (htmltext + (with-temp-buffer + (insert text) + (if (functionp mode) + (funcall mode) + (fundamental-mode)) + (font-lock-fontify-buffer) + ;; silence the byte-compiler + (when (fboundp 'htmlize-region-for-paste) + ;; transform the region to HTML + (htmlize-region-for-paste (point-min) (point-max)))))) + (save-restriction + (narrow-to-region (point) (point)) + (insert htmltext) + (goto-char (point-min)) + (re-search-forward "]*\\)>\n?" nil t) + (replace-match "
    ")
    +        (goto-char (point-max))
    +        (muse-publish-mark-read-only (point-min) (point-max))))))
    +
    +;; Register the Muse HTML Publisher
    +
    +(defun muse-html-browse-file (file)
    +  (browse-url (concat "file:" file)))
    +
    +(defun muse-html-encoding ()
    +  (if (stringp muse-html-meta-content-encoding)
    +      muse-html-meta-content-encoding
    +    (muse-xml-transform-content-type
    +     (or (and (boundp 'buffer-file-coding-system)
    +              buffer-file-coding-system)
    +         muse-html-encoding-default)
    +     muse-html-charset-default)))
    +
    +(defun muse-html-prepare-buffer ()
    +  (make-local-variable 'muse-html-meta-http-equiv)
    +  (set (make-local-variable 'muse-html-meta-content-type)
    +       (if (save-match-data
    +             (string-match "charset=" muse-html-meta-content-type))
    +           muse-html-meta-content-type
    +         (concat muse-html-meta-content-type "; charset="
    +                 (muse-html-encoding)))))
    +
    +(defun muse-html-munge-buffer ()
    +  (if muse-publish-generate-contents
    +      (progn
    +        (goto-char (car muse-publish-generate-contents))
    +        (muse-html-insert-contents (cdr muse-publish-generate-contents))
    +        (setq muse-publish-generate-contents nil))
    +    (muse-html-denote-headings)))
    +
    +(defun muse-html-finalize-buffer ()
    +  (when (and (boundp 'buffer-file-coding-system)
    +             (memq buffer-file-coding-system '(no-conversion undecided-unix)))
    +    ;; make it agree with the default charset
    +    (setq buffer-file-coding-system muse-html-encoding-default)))
    +
    +;;; Register the Muse HTML and XHTML Publishers
    +
    +(muse-define-style "html"
    +                   :suffix    'muse-html-extension
    +                   :regexps   'muse-html-markup-regexps
    +                   :functions 'muse-html-markup-functions
    +                   :strings   'muse-html-markup-strings
    +                   :tags      'muse-html-markup-tags
    +                   :specials  'muse-xml-decide-specials
    +                   :before    'muse-html-prepare-buffer
    +                   :before-end 'muse-html-munge-buffer
    +                   :after     'muse-html-finalize-buffer
    +                   :header    'muse-html-header
    +                   :footer    'muse-html-footer
    +                   :style-sheet 'muse-html-style-sheet
    +                   :browser   'muse-html-browse-file)
    +
    +(muse-derive-style "xhtml" "html"
    +                   :suffix    'muse-xhtml-extension
    +                   :strings   'muse-xhtml-markup-strings
    +                   :header    'muse-xhtml-header
    +                   :footer    'muse-xhtml-footer
    +                   :style-sheet 'muse-xhtml-style-sheet)
    +
    +;; xhtml1.0 is an alias for xhtml
    +(muse-derive-style "xhtml1.0" "xhtml")
    +
    +;; xhtml1.1 has some quirks that need attention from us
    +(muse-derive-style "xhtml1.1" "xhtml"
    +                   :strings   'muse-xhtml1.1-markup-strings)
    +
    +(provide 'muse-html)
    +
    +;;; muse-html.el ends here
    diff --git a/elpa/muse-3.20/muse-http.el b/elpa/muse-3.20/muse-http.el
    new file mode 100644
    index 0000000..40bd1cb
    --- /dev/null
    +++ b/elpa/muse-3.20/muse-http.el
    @@ -0,0 +1,239 @@
    +;;; muse-http.el --- publish HTML files over HTTP
    +
    +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
    +;;   Free Software Foundation, Inc.
    +
    +;; This file is part of Emacs Muse.  It is not part of GNU Emacs.
    +
    +;; Emacs Muse is free software; you can redistribute it and/or modify
    +;; it under the terms of the GNU General Public License as published
    +;; by the Free Software Foundation; either version 3, or (at your
    +;; option) any later version.
    +
    +;; Emacs Muse is distributed in the hope that it will be useful, but
    +;; WITHOUT ANY WARRANTY; without even the implied warranty of
    +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    +;; General Public License for more details.
    +
    +;; You should have received a copy of the GNU General Public License
    +;; along with Emacs Muse; see the file COPYING.  If not, write to the
    +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    +;; Boston, MA 02110-1301, USA.
    +
    +;;; Commentary:
    +
    +;;; Contributors:
    +
    +;;; Code:
    +
    +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    +;;
    +;; Publishing HTML over HTTP (using httpd.el)
    +;;
    +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    +
    +(require 'muse-html)
    +(require 'muse-project)
    +(require 'httpd)
    +(require 'cgi)
    +
    +(defgroup muse-http nil
    +  "Options controlling the behavior of Emacs Muse over HTTP."
    +  :group 'press)
    +
    +(defcustom muse-http-maintainer (concat "webmaster@" (system-name))
    +  "The maintainer address to use for the HTTP 'From' field."
    +  :type 'string
    +  :group 'muse-http)
    +
    +(defcustom muse-http-publishing-style "html"
    +  "The style to use when publishing projects over http."
    +  :type 'string
    +  :group 'muse-http)
    +
    +(defcustom muse-http-max-cache-size 64
    +  "The number of pages to cache when serving over HTTP.
    +This only applies if set while running the persisted invocation
    +server.  See main documentation for the `muse-http'
    +customization group."
    +  :type 'integer
    +  :group 'muse-http)
    +
    +(defvar muse-buffer-mtime nil)
    +(make-variable-buffer-local 'muse-buffer-mtime)
    +
    +(defun muse-sort-buffers (l r)
    +  (let ((l-mtime (with-current-buffer l muse-buffer-mtime))
    +        (r-mtime (with-current-buffer r muse-buffer-mtime)))
    +    (cond
    +     ((and (null l-mtime) (null r-mtime)) l)
    +     ((null l-mtime) r)
    +     ((null r-mtime) l)
    +     (t (muse-time-less-p r-mtime l-mtime)))))
    +
    +(defun muse-winnow-list (entries &optional predicate)
    +  "Return only those ENTRIES for which PREDICATE returns non-nil."
    +  (let ((flist (list t)))
    +    (let ((entry entries))
    +      (while entry
    +        (if (funcall predicate (car entry))
    +            (nconc flist (list (car entry))))
    +        (setq entry (cdr entry))))
    +    (cdr flist)))
    +
    +(defun muse-http-prune-cache ()
    +  "If the page cache has become too large, prune it."
    +  (let* ((buflist
    +          (sort (muse-winnow-list (buffer-list)
    +                                  (function
    +                                   (lambda (buf)
    +                                     (with-current-buffer buf
    +                                       muse-buffer-mtime))))
    +                'muse-sort-buffers))
    +         (len (length buflist)))
    +    (while (> len muse-http-max-cache-size)
    +      (kill-buffer (car buflist))
    +      (setq len (1- len)))))
    +
    +(defvar muse-http-serving-p nil)
    +
    +(defun muse-http-send-buffer (&optional modified code msg)
    +  "Markup and send the contents of the current buffer via HTTP."
    +  (httpd-send (or code 200) (or msg "OK")
    +              "Server: muse.el/" muse-version httpd-endl
    +              "Connection: close" httpd-endl
    +              "MIME-Version: 1.0" httpd-endl
    +              "Date: " (format-time-string "%a, %e %b %Y %T %Z")
    +              httpd-endl
    +              "From: " muse-http-maintainer httpd-endl)
    +  (when modified
    +    (httpd-send-data "Last-Modified: "
    +                     (format-time-string "%a, %e %b %Y %T %Z" modified)
    +                     httpd-endl))
    +  (httpd-send-data "Content-Type: text/html; charset=iso-8859-1" httpd-endl
    +                   "Content-Length: " (number-to-string (1- (point-max)))
    +                   httpd-endl httpd-endl
    +                   (buffer-string))
    +  (httpd-send-eof))
    +
    +(defun muse-http-reject (title msg &optional annotation)
    +  (muse-with-temp-buffer
    +    (insert msg ".\n")
    +    (if annotation
    +        (insert annotation "\n"))
    +    (muse-publish-markup-buffer title muse-http-publishing-style)
    +    (muse-http-send-buffer nil 404 msg)))
    +
    +(defun muse-http-prepare-url (target explicit)
    +  (save-match-data
    +    (unless (or (not explicit)
    +                (string-match muse-url-regexp target)
    +                (string-match muse-image-regexp target)
    +                (string-match muse-file-regexp target))
    +      (setq target (concat "page?" target
    +                           "&project=" muse-http-serving-p))))
    +  (muse-publish-read-only target))
    +
    +(defun muse-http-render-page (name)
    +  "Render the Muse page identified by NAME.
    +When serving from a dedicated Emacs process (see the httpd-serve
    +script), a maximum of `muse-http-max-cache-size' pages will be
    +cached in memory to speed up serving time."
    +  (let ((file (muse-project-page-file name muse-http-serving-p))
    +        (muse-publish-url-transforms
    +         (cons 'muse-http-prepare-url muse-publish-url-transforms))
    +        (inhibit-read-only t))
    +    (when file
    +      (with-current-buffer (get-buffer-create file)
    +        (let ((modified-time (nth 5 (file-attributes file)))
    +              (muse-publishing-current-file file)
    +              muse-publishing-current-style)
    +          (when (or (null muse-buffer-mtime)
    +                    (muse-time-less-p muse-buffer-mtime modified-time))
    +            (erase-buffer)
    +            (setq muse-buffer-mtime modified-time))
    +          (goto-char (point-max))
    +          (when (bobp)
    +            (muse-insert-file-contents file t)
    +            (let ((styles (cddr (muse-project muse-http-serving-p)))
    +                  style)
    +              (while (and styles (null style))
    +                (let ((include-regexp
    +                       (muse-style-element :include (car styles)))
    +                      (exclude-regexp
    +                       (muse-style-element :exclude (car styles))))
    +                  (when (and (or (and (null include-regexp)
    +                                      (null exclude-regexp))
    +                                 (if include-regexp
    +                                     (string-match include-regexp file)
    +                                   (not (string-match exclude-regexp file))))
    +                             (not (muse-project-private-p file)))
    +                    (setq style (car styles))
    +                    (while (muse-style-element :base style)
    +                      (setq style
    +                            (muse-style (muse-style-element :base style))))
    +                    (if (string= (car style) muse-http-publishing-style)
    +                        (setq style (car styles))
    +                      (setq style nil))))
    +                (setq styles (cdr styles)))
    +              (muse-publish-markup-buffer
    +               name (or style muse-http-publishing-style))))
    +          (set-buffer-modified-p nil)
    +          (muse-http-prune-cache)
    +          (current-buffer))))))
    +
    +(defun muse-http-transmit-page (name)
    +  "Render the Muse page identified by NAME.
    +When serving from a dedicated Emacs process (see the httpd-serve
    +script), a maximum of `muse-http-max-cache-size' pages will be
    +cached in memory to speed up serving time."
    +  (let ((inhibit-read-only t)
    +        (buffer (muse-http-render-page name)))
    +    (if buffer
    +        (with-current-buffer buffer
    +          (muse-http-send-buffer muse-buffer-mtime)))))
    +
    +(defvar httpd-vars nil)
    +
    +(defsubst httpd-var (var)
    +  "Return value of VAR as a URL variable.  If VAR doesn't exist, nil."
    +  (cdr (assoc var httpd-vars)))
    +
    +(defsubst httpd-var-p (var)
    +  "Return non-nil if VAR was passed as a URL variable."
    +  (not (null (assoc var httpd-vars))))
    +
    +(defun muse-http-serve (page &optional content)
    +  "Serve the given PAGE from this press server."
    +  ;; index.html is really a reference to the project home page
    +  (if (and muse-project-alist
    +           (string-match "\\`index.html?\\'" page))
    +      (setq page (concat "page?"
    +                         (muse-get-keyword :default
    +                                           (cadr (car muse-project-alist))))))
    +  ;; handle the actual request
    +  (let ((vc-follow-symlinks t)
    +        (muse-publish-report-threshhold nil)
    +        muse-http-serving-p
    +        httpd-vars)
    +    (save-excursion
    +      ;; process any CGI variables, if cgi.el is available
    +      (if (string-match "\\`\\([^&]+\\)&" page)
    +          (setq httpd-vars (cgi-decode (substring page (match-end 0)))
    +                page (match-string 1 page)))
    +      (unless (setq muse-http-serving-p (httpd-var "project"))
    +        (let ((project (car muse-project-alist)))
    +          (setq muse-http-serving-p (car project))
    +          (setq httpd-vars (cons (cons "project" (car project))
    +                                 httpd-vars))))
    +      (if (and muse-http-serving-p
    +               (string-match "\\`page\\?\\(.+\\)" page))
    +          (muse-http-transmit-page (match-string 1 page))))))
    +
    +(if (featurep 'httpd)
    +    (httpd-add-handler "\\`\\(index\\.html?\\|page\\(\\?\\|\\'\\)\\)"
    +                       'muse-http-serve))
    +
    +(provide 'muse-http)
    +
    +;;; muse-http.el ends here
    diff --git a/elpa/muse-3.20/muse-ikiwiki.el b/elpa/muse-3.20/muse-ikiwiki.el
    new file mode 100644
    index 0000000..a664880
    --- /dev/null
    +++ b/elpa/muse-3.20/muse-ikiwiki.el
    @@ -0,0 +1,219 @@
    +;;; muse-ikiwiki.el --- integrate with Ikiwiki
    +
    +;; Copyright (C) 2008, 2009, 2010  Free Software Foundation, Inc.
    +
    +;; This file is part of Emacs Muse.  It is not part of GNU Emacs.
    +
    +;; Emacs Muse is free software; you can redistribute it and/or modify
    +;; it under the terms of the GNU General Public License as published
    +;; by the Free Software Foundation; either version 3, or (at your
    +;; option) any later version.
    +
    +;; Emacs Muse is distributed in the hope that it will be useful, but
    +;; WITHOUT ANY WARRANTY; without even the implied warranty of
    +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    +;; General Public License for more details.
    +
    +;; You should have received a copy of the GNU General Public License
    +;; along with Emacs Muse; see the file COPYING.  If not, write to the
    +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    +;; Boston, MA 02110-1301, USA.
    +
    +;;; Commentary:
    +
    +;;; Contributors:
    +
    +;;; Code:
    +
    +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    +;;
    +;; Muse Ikiwiki Integration
    +;;
    +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    +
    +(require 'muse)
    +(require 'muse-html)
    +(require 'muse-ipc)
    +(require 'muse-publish)
    +
    +(eval-when-compile
    +  (require 'muse-colors))
    +
    +(defgroup muse-ikiwiki nil
    +  "Options controlling the behavior of Muse integration with Ikiwiki."
    +  :group 'muse-publish)
    +
    +(defcustom muse-ikiwiki-header ""
    +  "Header used for publishing Ikiwiki output files.
    +This may be text or a filename."
    +  :type 'string
    +  :group 'muse-ikiwiki)
    +
    +(defcustom muse-ikiwiki-footer ""
    +  "Footer used for publishing Ikiwiki output files.
    +This may be text or a filename."
    +  :type 'string
    +  :group 'muse-ikiwiki)
    +
    +(defcustom muse-ikiwiki-markup-regexps
    +  `(;; Ikiwiki directives
    +    (1350 ,(concat "\\(\\\\?\\)\\[\\[!""\\(?:-\\|\\w\\)+"
    +                   "\\([" muse-regexp-blank "\n]+"
    +                   "\\(?:\\(?:\\(?:-\\|\\w\\)+=\\)?"
    +                   "\\(?:\"\"\".*?\"\"\"\\|\"[^\"]+\""
    +                   "\\|[^]" muse-regexp-blank "\n]+\\)"
    +                   "[" muse-regexp-blank "\n]*\\)*\\)?\\]\\]")
    +          0 muse-ikiwiki-markup-directive))
    +  "List of markup rules for publishing Ikiwiki markup on Muse pages.
    +For more on the structure of this list, see `muse-publish-markup-regexps'."
    +  :type '(repeat (choice
    +                  (list :tag "Markup rule"
    +                        integer
    +                        (choice regexp symbol)
    +                        integer
    +                        (choice string function symbol))
    +                  function))
    +  :group 'muse-ikiwiki)
    +
    +;;; Publishing
    +
    +(defun muse-ikiwiki-markup-directive ()
    +  "Handle publishing of an Ikiwiki directive."
    +  (unless (get-text-property (match-beginning 0) 'read-only)
    +    (add-text-properties (match-beginning 0) (match-end 0)
    +                         '(muse-no-paragraph t))
    +    (muse-publish-mark-read-only (match-beginning 0) (match-end 0))))
    +
    +(defun muse-ikiwiki-publish-buffer (name title &optional style)
    +  "Publish a buffer for Ikiwki.
    +The name of the corresponding file is NAME.
    +The name of the style is given by STYLE.  It defaults to \"ikiwiki\"."
    +  (unless style (setq style "ikiwiki"))
    +  (unless title (setq title (muse-page-name name)))
    +  (let ((muse-batch-publishing-p t)
    +        (muse-publishing-current-file name)
    +        (muse-publishing-current-output-path name)
    +        (muse-publishing-current-style style)
    +        (font-lock-verbose nil)
    +        (vc-handled-backends nil)) ; don't activate VC when publishing files
    +    (run-hooks 'muse-before-publish-hook)
    +    (let ((muse-inhibit-before-publish-hook t))
    +      (muse-publish-markup-buffer title style))))
    +
    +(defun muse-ikiwiki-publish-file (file name &optional style)
    +  "Publish a single file for Ikiwiki.
    +The name of the real file is NAME, and the name of the temporary
    +file containing the content is FILE.
    +The name of the style is given by STYLE.  It defaults to \"ikiwiki\"."
    +  (if (not (stringp file))
    +      (message "Error: No file given to publish")
    +    (unless style
    +      (setq style "ikiwiki"))
    +    (let ((output-path file)
    +          (target file)
    +          (vc-handled-backends nil) ; don't activate VC when publishing files
    +          auto-mode-alist
    +          muse-current-output-style)
    +      (setq auto-mode-alist
    +            (delete (cons (concat "\\." muse-file-extension "\\'")
    +                          'muse-mode-choose-mode)
    +                    auto-mode-alist))
    +      (setq muse-current-output-style (list :base style :path file))
    +      (muse-with-temp-buffer
    +        (muse-insert-file-contents file)
    +        (muse-ikiwiki-publish-buffer name nil style)
    +        (when (muse-write-file output-path t)
    +          (muse-style-run-hooks :final style file output-path target))))))
    +
    +(defun muse-ikiwiki-start-server (port)
    +  "Start Muse IPC server, initializing with the client on PORT."
    +  (muse-ipc-start "foo" #'muse-ikiwiki-publish-buffer port))
    +
    +;;; Colors
    +
    +(defface muse-ikiwiki-directive
    +  '((((class color) (background light))
    +     (:foreground "dark green"))
    +    (((class color) (background dark))
    +     (:foreground "green")))
    +  "Face for Ikiwiki directives."
    +  :group 'muse-ikiwiki)
    +
    +(defun muse-colors-ikiwiki-directive ()
    +  "Color ikiwiki directives."
    +  (let ((start (match-beginning 0)))
    +    (unless (or (eq (get-text-property start 'invisible) 'muse)
    +                (get-text-property start 'muse-comment)
    +                (get-text-property start 'muse-directive))
    +      ;; beginning of line or space or symbol
    +      (save-excursion
    +        (and
    +         (catch 'valid
    +           (while t
    +             (skip-chars-forward "^\"]" muse-colors-region-end)
    +             (cond ((eq (point) (point-max))
    +                    (throw 'valid nil))
    +                   ((> (point) muse-colors-region-end)
    +                    (throw 'valid nil))
    +                   ((eq (char-after) ?\")
    +                    (if (and (< (1+ (point)) muse-colors-region-end)
    +                             (eq (char-after (1+ (point))) ?\"))
    +                        (if (and (< (+ 2 (point)) muse-colors-region-end)
    +                                 (eq (char-after (+ 2 (point))) ?\"))
    +                            ;; triple-quote
    +                            (progn
    +                              (forward-char 3)
    +                              (or (and (looking-at "\"\"\"")
    +                                       (goto-char (match-end 0)))
    +                                  (re-search-forward
    +                                   "\"\"\"" muse-colors-region-end t)
    +                                  (throw 'valid nil)))
    +                          ;; empty quotes (""), which are invalid
    +                          (throw 'valid nil))
    +                      ;; quote with content
    +                      (forward-char 1)
    +                      (skip-chars-forward "^\"" muse-colors-region-end)
    +                      (when (eq (char-after) ?\")
    +                        (forward-char 1))))
    +                   ((eq (char-after) ?\])
    +                    (forward-char 1)
    +                    (when (and (< (point) muse-colors-region-end)
    +                               (eq (char-after (point)) ?\]))
    +                      (forward-char 1)
    +                      (throw 'valid t)))
    +                   (t (throw 'valid nil)))))
    +         ;; found a valid directive
    +         (let ((end (point)))
    +           ;; remove flyspell overlays
    +           (when (fboundp 'flyspell-unhighlight-at)
    +             (let ((cur start))
    +               (while (> end cur)
    +                 (flyspell-unhighlight-at cur)
    +                 (setq cur (1+ cur)))))
    +           (add-text-properties start end
    +                                '(face muse-ikiwiki-directive
    +                                  muse-directive t muse-no-flyspell t))
    +           (when (progn
    +                   (goto-char start)
    +                   (skip-chars-forward "^\n" end)
    +                   (and (eq (char-after) ?\n)
    +                        (not (= (point) end))))
    +             (add-text-properties start end
    +                                  '(font-lock-multiline t)))))))))
    +
    +(defun muse-ikiwiki-insinuate-colors ()
    +  (add-to-list 'muse-colors-markup
    +               '("\\[\\[!" ?\[ muse-colors-ikiwiki-directive)
    +               nil))
    +
    +(eval-after-load "muse-colors" '(muse-ikiwiki-insinuate-colors))
    +
    +;; Styles
    +(muse-derive-style "ikiwiki" "xhtml"
    +                   :header  'muse-ikiwiki-header
    +                   :footer  'muse-ikiwiki-footer
    +                   :regexps 'muse-ikiwiki-markup-regexps)
    +
    +(provide 'muse-ikiwiki)
    +
    +;;; muse-ikiwiki.el ends here
    diff --git a/elpa/muse-3.20/muse-import-docbook.el b/elpa/muse-3.20/muse-import-docbook.el
    new file mode 100644
    index 0000000..ed1b22b
    --- /dev/null
    +++ b/elpa/muse-3.20/muse-import-docbook.el
    @@ -0,0 +1,137 @@
    +;;; muse-import-docbook.el --- convert Docbook XML into Muse format
    +
    +;; Copyright (C) 2006, 2007, 2008, 2009, 2010
    +;;   Free Software Foundation, Inc.
    +
    +;; Author: Elena Pomohaci 
    +
    +;; This file is part of Emacs Muse.  It is not part of GNU Emacs.
    +
    +;; Emacs Muse is free software; you can redistribute it and/or modify
    +;; it under the terms of the GNU General Public License as published
    +;; by the Free Software Foundation; either version 3, or (at your
    +;; option) any later version.
    +
    +;; Emacs Muse is distributed in the hope that it will be useful, but
    +;; WITHOUT ANY WARRANTY; without even the implied warranty of
    +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    +;; General Public License for more details.
    +
    +;; You should have received a copy of the GNU General Public License
    +;; along with Emacs Muse; see the file COPYING.  If not, write to the
    +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    +;; Boston, MA 02110-1301, USA.
    +
    +;;; Commentary:
    +
    +;; It works only for article type docbook docs and recognize
    +;; followings elements: article, sect1, sect2, sect3, title,
    +
    +;;; Contributors:
    +
    +;;; Code:
    +
    +(require 'muse-import-xml)
    +
    +(defvar muse-import-docbook-prefix "muse-import-docbook-"
    +  "The name prefix for tag functions")
    +
    +(defvar muse-import-docbook-para-indent "\n\n"
    +  "Para elements indentation (0, less than 6 spaces, more than 6 spaces)")
    +
    +(defun muse-import-docbook-reset-para-indent ()
    +  (setq muse-import-docbook-para-indent "\n\n"))
    +
    +
    +;;;###autoload
    +(defun muse-import-docbook (src dest)
    +  "Convert the Docbook buffer SRC to Muse, writing output in the DEST buffer."
    +  (interactive "bDocbook buffer:\nBMuse buffer:")
    +  (setq muse-import-xml-prefix muse-import-docbook-prefix)
    +  (setq muse-import-xml-generic-function-name "muse-import-xml-node")
    +  (muse-import-xml src dest))
    +
    +;;;###autoload
    +(defun muse-import-docbook-files (src dest)
    +  "Convert the Docbook file SRC to Muse, writing output to the DEST file."
    +  (interactive "fDocbook file:\nFMuse file:")
    +  (with-temp-file dest
    +    (muse-import-docbook (find-file-noselect src) (current-buffer))))
    +
    +
    +;;; element specific functions
    +
    +(defun muse-import-docbook-get-title (node)
    +  (let ((tit (car (xml-get-children node 'title))))
    +    (insert (car (cddr tit)) ?\n ?\n)
    +    (muse-import-xml-parse-tree (xml-node-children (remove tit node)))))
    +
    +
    +(defun muse-import-docbook-article (node)
    +  "Article conversion function"
    +  (muse-import-xml-node node))
    +
    +(defun muse-import-docbook-articleinfo (node)
    +  "Article conversion function"
    +  (insert "#title ")
    +  (muse-import-docbook-get-title node)
    +  (insert ?\n))
    +
    +
    +(defalias 'muse-import-docbook-appendix 'muse-import-docbook-article)
    +
    +(defalias 'muse-import-docbook-appendixinfo 'muse-import-docbook-articleinfo)
    +
    +
    +(defun muse-import-docbook-sect1 (node)
    +  "Section 1 conversion function"
    +  (insert ?\n "* ")
    +  (muse-import-docbook-get-title node))
    +
    +(defun muse-import-docbook-sect2 (node)
    +  "Section 2 conversion function"
    +  (insert ?\n "** ")
    +  (muse-import-docbook-get-title node))
    +
    +(defun muse-import-docbook-sect3 (node)
    +  "Section 3 conversion function"
    +  (insert ?\n "*** ")
    +  (muse-import-docbook-get-title node))
    +
    +
    +(defun muse-import-docbook-graphic (node)
    +  "Graphic conversion function. Image format is forced to PNG"
    +  (let ((name (xml-get-attribute node 'fileref)))
    +  (insert "\n[[img/" name ".png][" name "]]")))
    +
    +(defun muse-import-docbook-para (node)
    +  (insert muse-import-docbook-para-indent)
    +  (muse-import-xml-node node))
    +
    +
    +(defun muse-import-docbook-emphasis (node)
    +  (insert "*")
    +  (muse-import-xml-node node)
    +  (insert "*"))
    +
    +(defun muse-import-docbook-quote (node)
    +  (insert "\"")
    +  (muse-import-xml-node node)
    +  (insert "\""))
    +
    +(defun muse-import-docbook-blockquote (node)
    +  (setq muse-import-docbook-para-indent "\n\n  ")
    +  (muse-import-xml-node node)
    +  (muse-import-docbook-reset-para-indent))
    +
    +(defun muse-import-docbook-member (node)
    +  (insert "\n> ")
    +  (muse-import-xml-node node))
    +
    +(defun muse-import-docbook-bridgehead (node)
    +  (insert "\n* ")
    +  (muse-import-xml-node node))
    +
    +(provide 'muse-import-docbook)
    +
    +;;; muse-import-docbook.el ends here
    diff --git a/elpa/muse-3.20/muse-import-latex.el b/elpa/muse-3.20/muse-import-latex.el
    new file mode 100644
    index 0000000..5297131
    --- /dev/null
    +++ b/elpa/muse-3.20/muse-import-latex.el
    @@ -0,0 +1,149 @@
    +;;; muse-import-latex.el --- convert a LaTex file into a Muse file
    +
    +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
    +;;   Free Software Foundation, Inc.
    +
    +;; This file is part of Emacs Muse.  It is not part of GNU Emacs.
    +
    +;; Emacs Muse is free software; you can redistribute it and/or modify
    +;; it under the terms of the GNU General Public License as published
    +;; by the Free Software Foundation; either version 3, or (at your
    +;; option) any later version.
    +
    +;; Emacs Muse is distributed in the hope that it will be useful, but
    +;; WITHOUT ANY WARRANTY; without even the implied warranty of
    +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    +;; General Public License for more details.
    +
    +;; You should have received a copy of the GNU General Public License
    +;; along with Emacs Muse; see the file COPYING.  If not, write to the
    +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    +;; Boston, MA 02110-1301, USA.
    +
    +;;; Commentary:
    +
    +;; Helper commands for converting a LaTeX file into a Muse file.
    +
    +;;; Contributors:
    +
    +;;; Code:
    +
    +(require 'muse)
    +(require 'muse-regexps)
    +
    +(defun muse-i-l-write-citation (note author citation pages)
    +  (save-excursion
    +    (goto-char (point-max))
    +    (if (= note 1)
    +        (insert "\nFootnotes:\n\n"))
    +    (let ((beg (point)))
    +      (insert "\n[" (number-to-string note) "]  " author)
    +      (if (and citation pages)
    +          (insert ", " citation ", " pages))
    +      (insert "\n")
    +      (goto-char beg)
    +      (while (re-search-forward (concat "p.\\\\[" muse-regexp-blank "\n]+")
    +                                nil t)
    +        (replace-match "p."))
    +      (goto-char beg)
    +      (while (re-search-forward "--" nil t)
    +        (replace-match "-")))))
    +
    +(defun muse-i-l-write-footnote (note text)
    +  (save-excursion
    +    (goto-char (point-max))
    +    (if (= note 1)
    +        (insert "\nFootnotes:\n\n"))
    +    (insert "\n[" (number-to-string note) "]  " text ?\n)))
    +
    +;;;###autoload
    +(defun muse-import-latex ()
    +  (interactive)
    +  (goto-char (point-min))
    +  (while (not (eobp))
    +    (cond
    +     ((or (looking-at "^\\\\documentclass")
    +          (looking-at "^\\\\input")
    +          (looking-at "^\\\\begin{document}")
    +          (looking-at "^\\\\end{document}")
    +          (looking-at "^\\\\author")
    +          (looking-at "^\\\\\\(med\\|big\\|small\\)skip")
    +          (looking-at "^\\\\maketitle"))
    +      (delete-region (point) (muse-line-end-position)))
    +     ((looking-at "^\\\\title{\\(.+\\)}")
    +      (delete-region (match-end 1) (muse-line-end-position))
    +      (delete-region (point) (match-beginning 1))
    +      (insert "#title ")))
    +    (forward-line))
    +  (goto-char (point-min))
    +  (while (re-search-forward "\\\\\\(l\\)?dots{}" nil t)
    +    (replace-match (concat (and (string= (match-string 1) "l") ".")
    +                           "...")))
    +  (goto-char (point-min))
    +  (while (re-search-forward "\\(``\\|''\\)" nil t)
    +    (replace-match "\""))
    +  (goto-char (point-min))
    +  (while (re-search-forward "---" nil t)
    +    (replace-match " -- "))
    +  (goto-char (point-min))
    +  (while (re-search-forward "\\\\tableofcontents" nil t)
    +    (replace-match ""))
    +  (goto-char (point-min))
    +  (while (re-search-forward "\\\\\\\\" nil t)
    +    (replace-match ""))
    +  (goto-char (point-min))
    +  (while (re-search-forward "\\\\\\(sub\\)?section{\\([^}]+\\)}" nil t)
    +    (replace-match (concat (if (string= (match-string 1) "sub")
    +                               "**" "*")
    +                           " " (match-string 2))))
    +  (goto-char (point-min))
    +  (while (re-search-forward "\\\\\\(begin\\|end\\){verse}" nil t)
    +    (replace-match (concat "<" (if (string= (match-string 1) "end") "/")
    +                           "verse>")))
    +  (goto-char (point-min))
    +  (while (re-search-forward "\\\\\\(begin\\|end\\){quote}\n" nil t)
    +    (replace-match ""))
    +  (goto-char (point-min))
    +  (while (re-search-forward
    +          "\\\\\\(emph\\|textbf\\){\\([^}]+?\\)\\(\\\\/\\)?}" nil t)
    +    (replace-match
    +     (if (string= (match-string 1) "emph") "*\\2*" "**\\2**")))
    +  (let ((footnote-index 1))
    +    (goto-char (point-min))
    +    (while (re-search-forward
    +            (concat "\\\\\\(q\\)?\\(footnote\\|excerpt\\)\\(np\\)?"
    +                    "\\({\\([^}]+\\)}\\)?"
    +                    "\\({\\([^}]+\\)}{\\([^}]+\\)}\\)?{\\([^}]+\\)}") nil t)
    +      (let ((beg (match-beginning 0))
    +            (end (match-end 0)))
    +        (unless (string= (match-string 2) "footnote")
    +          (if (null (match-string 1))
    +              (insert "  " (match-string 9))
    +            (let ((b (point)) e)
    +              (insert "\"" (match-string 9) "\"")
    +              (setq e (point-marker))
    +              (save-match-data
    +                (save-excursion
    +                  (goto-char b)
    +                  (while (< (point) e)
    +                    (if (looking-at "\\s-+")
    +                        (delete-region (match-beginning 0)
    +                                       (match-end 0)))
    +                    (forward-line))))
    +              (set-marker e nil))))
    +        (insert "[" (number-to-string footnote-index) "]")
    +        (if (string= (match-string 2) "footnote")
    +            (muse-i-l-write-footnote footnote-index (match-string 9))
    +          (muse-i-l-write-citation footnote-index (match-string 5)
    +                                   (match-string 7) (match-string 8)))
    +        (setq footnote-index (1+ footnote-index))
    +        (delete-region beg end))))
    +  (goto-char (point-min))
    +  (while (looking-at "\n") (delete-char 1))
    +  (goto-char (point-min))
    +  (while (re-search-forward "\n\n+" nil t)
    +    (replace-match "\n\n")))
    +
    +(provide 'muse-import-latex)
    +
    +;;; muse-import-latex.el ends here
    diff --git a/elpa/muse-3.20/muse-import-xml.el b/elpa/muse-3.20/muse-import-xml.el
    new file mode 100644
    index 0000000..2579ce8
    --- /dev/null
    +++ b/elpa/muse-3.20/muse-import-xml.el
    @@ -0,0 +1,88 @@
    +;;; muse-import-xml.el --- common to all from-xml converters
    +
    +;; Copyright (C) 2006, 2007, 2008, 2009, 2010
    +;;   Free Software Foundation, Inc.
    +
    +;; Author: Elena Pomohaci 
    +
    +;; This file is part of Emacs Muse.  It is not part of GNU Emacs.
    +
    +;; Emacs Muse is free software; you can redistribute it and/or modify
    +;; it under the terms of the GNU General Public License as published
    +;; by the Free Software Foundation; either version 3, or (at your
    +;; option) any later version.
    +
    +;; Emacs Muse is distributed in the hope that it will be useful, but
    +;; WITHOUT ANY WARRANTY; without even the implied warranty of
    +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    +;; General Public License for more details.
    +
    +;; You should have received a copy of the GNU General Public License
    +;; along with Emacs Muse; see the file COPYING.  If not, write to the
    +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    +;; Boston, MA 02110-1301, USA.
    +
    +;;; Commentary:
    +
    +;;; Contributors:
    +
    +;;; Code:
    +
    +(provide 'muse-import-xml)
    +
    +(require 'xml)
    +(require 'muse)
    +
    +(defvar muse-import-xml-prefix ""
    +  "The name prefix for tag functions")
    +
    +(defvar muse-import-xml-generic-function-name "muse-import-xml-generic"
    +  "The generic function name")
    +
    +(defun muse-import-xml-convert-to-list (buf)
    +  "Convert xml BUF in a xml-list"
    +  (with-temp-buffer
    +    (insert-buffer-substring buf)
    +    (goto-char (point-min))
    +    (while (re-search-forward ">[ \n\t]*<" nil t)
    +      (replace-match "><" nil nil)) ; clean all superfluous blank characters
    +    (xml-parse-region (point-min)
    +                      (point-max)
    +                      (current-buffer))))
    +
    +
    +(defun muse-import-xml-generic (node)
    +  "The generic function called when there is no node specific function."
    +  (let ((name (xml-node-name node)))
    +    (insert "<" (symbol-name name)  ">")
    +    (muse-import-xml-node node)
    +    (insert "")))
    +
    +(defun muse-import-xml-parse-tree (lst)
    +  "Parse an xml tree list"
    +  (mapc #'muse-import-xml-parse-node lst))
    +
    +(defun muse-import-xml-parse-node (node)
    +  "Parse a xml tree node"
    +  (if (stringp node)
    +      (insert (muse-replace-regexp-in-string "^[ \t]+" "" node))
    +    (let ((fname (intern-soft (concat muse-import-xml-prefix
    +                                      (symbol-name (xml-node-name node))))))
    +      (if (functionp fname)
    +          (funcall fname node)
    +        (funcall (intern muse-import-xml-generic-function-name) node)))))
    +
    +
    +(defun muse-import-xml-node (node)
    +  "Default node function"
    +  (muse-import-xml-parse-tree (xml-node-children node)))
    +
    +
    +(defun muse-import-xml (src dest)
    +  "Convert the xml SRC buffer in a muse DEST buffer"
    +  (set-buffer (get-buffer-create dest))
    +  (when (fboundp 'muse-mode)
    +    (muse-mode))
    +  (muse-import-xml-parse-tree (muse-import-xml-convert-to-list src)))
    +
    +;;; muse-import-xml.el ends here
    diff --git a/elpa/muse-3.20/muse-ipc.el b/elpa/muse-3.20/muse-ipc.el
    new file mode 100644
    index 0000000..9ce8eb1
    --- /dev/null
    +++ b/elpa/muse-3.20/muse-ipc.el
    @@ -0,0 +1,194 @@
    +;;; muse-ipc.el --- publish Muse documents from other processes
    +
    +;; Copyright (C) 2009, 2010  Free Software Foundation, Inc.
    +
    +;; This file is part of Emacs Muse.  It is not part of GNU Emacs.
    +
    +;; Emacs Muse is free software; you can redistribute it and/or modify
    +;; it under the terms of the GNU General Public License as published
    +;; by the Free Software Foundation; either version 3, or (at your
    +;; option) any later version.
    +
    +;; Emacs Muse is distributed in the hope that it will be useful, but
    +;; WITHOUT ANY WARRANTY; without even the implied warranty of
    +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    +;; General Public License for more details.
    +
    +;; You should have received a copy of the GNU General Public License
    +;; along with Emacs Muse; see the file COPYING.  If not, write to the
    +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    +;; Boston, MA 02110-1301, USA.
    +
    +;;; Commentary:
    +
    +;; This file is still in alpha state.  Not for production use!
    +
    +;;; Contributors:
    +
    +;;; Code:
    +
    +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    +;;
    +;; Muse Inter-Process Communication
    +;;
    +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    +
    +(eval-when-compile (require 'cl))
    +
    +(require 'muse)
    +(require 'muse-publish)
    +
    +(defgroup muse-ipc nil
    +  "Options controlling the behavior of Muse's IPC module."
    +  :group 'muse-publish)
    +
    +(defcustom muse-ipc-timeout 60
    +  "Maximum time to wait for a client to respond."
    +  :group 'muse-ipc
    +  :type 'number)
    +
    +(defcustom muse-ipc-ignore-done nil
    +  "If non-nil, ignore any 'done' messages that we get from clients."
    +  :group 'muse-ipc
    +  :type 'boolean)
    +
    +(defvar muse-ipc-server-port nil
    +  "Port of the Emacs server.")
    +
    +(defvar muse-ipc-server-process nil
    +  "Process of the Emacs server.")
    +
    +(defvar muse-ipc-server-registered nil
    +  "Whether we have successfully registered our port with the client.")
    +
    +(defun muse-ipc-init-filter (proc string)
    +  "Handle data from client while initiating a connection."
    +  (unless muse-ipc-server-registered
    +    (when (string-match "\\`ok$" string)
    +      (setq muse-ipc-server-registered t))))
    +
    +(defun muse-ipc-delete-client (proc)
    +  "Delete a client."
    +  (let ((buffer (process-get proc :buffer)))
    +    (when (and buffer (buffer-live-p buffer))
    +      (with-current-buffer buffer
    +        (set-buffer-modified-p nil))
    +      (kill-buffer buffer)))
    +  (when (eq (process-status proc) 'open)
    +    (delete-process proc)))
    +
    +(defun* muse-ipc-server-filter (proc string)
    +  "Handle data from a client after it connects."
    +  ;; Authenticate
    +  (unless (process-get proc :authenticated)
    +    (if (and (string-match "\\`begin \\(.+\\)$" string)
    +             (equal (match-string 1 string)
    +                    (process-get proc :shared-secret)))
    +        (progn
    +          (setq string (substring string (match-end 0)))
    +          (process-put proc :authenticated t)
    +          (process-send-string proc "ok\n"))
    +      (process-send-string proc "nok\n")
    +      (delete-process proc))
    +    (return-from muse-ipc-server-filter))
    +
    +  ;; Handle case where the client is sending data to be published
    +  (when (process-get proc :sending-data)
    +    (with-current-buffer (process-get proc :buffer)
    +      (insert string)
    +      (let ((buf-len (1- (point)))
    +            (expected-len (process-get proc :data-bytes)))
    +        (cond ((= buf-len expected-len)
    +               (process-put proc :sending-data nil))
    +              ((> buf-len expected-len)
    +               (process-send-string proc "nok\n")
    +               (muse-ipc-delete-client proc)))))
    +    (return-from muse-ipc-server-filter))
    +
    +  ;; Dispatch commands
    +  (cond
    +   ((string-match "\\`done$" string)
    +    ;; done, close the server
    +    (unless muse-ipc-ignore-done
    +      (muse-ipc-stop-server)))
    +
    +   ((string-match "\\`name \\(.+\\)$" string)
    +    ;; set name
    +    (process-put proc :file-name (match-string 1 string))
    +    (process-send-string proc "ok\n"))
    +
    +   ((string-match "\\`title \\(.+\\)$" string)
    +    ;; set title
    +    (process-put proc :title (match-string 1 string))
    +    (process-send-string proc "ok\n"))
    +
    +   (t
    +    ;; unrecognized command
    +    (process-send-string proc "nok\n"))))
    +
    +(defun muse-ipc-stop-server ()
    +  "Stop Muse IPC server and reset connection data."
    +  (stop-process muse-ipc-server-process)
    +  (delete-process muse-ipc-server-process)
    +  (setq muse-ipc-server-port nil)
    +  (setq muse-ipc-server-process nil))
    +
    +(defun muse-ipc-start (shared-secret publish-fn client-port &optional server-port)
    +  "Start an IPC connection and send a response to CLIENT-PORT.
    +If SERVER-PORT is provided, start the IPC server on that port, otherwise
    +choose a random port.
    +
    +SHARED-SECRET is used as a very minimal security measure to
    +authenticate the Muse IPC server during initialization, and also
    +any incoming clients once the server is started.
    +
    +PUBLISH-FN is the function which should be called in buffer of
    +the received contents.  It should transform the buffer into a
    +published state.  It must take at least two arguments.  The first
    +argument is the full path of the file that the contents
    +correspond with.  The second argument is the title to use when
    +publishing the file."
    +  (when (stringp client-port)
    +    (setq client-port (string-to-number client-port)))
    +  (when (stringp server-port)
    +    (setq server-port (string-to-number server-port)))
    +  (setq muse-ipc-server-process
    +        (make-network-process
    +         :name "muse-ipc"
    +         :buffer nil
    +         :host 'local :service (or server-port t)
    +         :server t :noquery t :nowait t
    +         :plist (list :authenticated nil :shared-secret shared-secret
    +                      :publish-fn publish-fn)
    +         :filter 'muse-ipc-server-filter))
    +  (unless muse-ipc-server-process
    +    (error "Error: Could not start Muse IPC Server process"))
    +  (set-process-coding-system muse-ipc-server-process
    +                             'raw-text-unix 'raw-text-unix)
    +  (setq muse-ipc-server-port
    +        (number-to-string
    +         (cadr (process-contact muse-ipc-server-process))))
    +  (let ((client-proc
    +         (make-network-process
    +          :name "muse-ipc-client"
    +          :buffer nil
    +          :host 'local :service client-port
    +          :noquery t
    +          :filter 'muse-ipc-init-filter)))
    +    (setq muse-ipc-server-registered nil)
    +    (process-send-string client-proc
    +                         (concat "begin " shared-secret "\n"))
    +    (accept-process-output client-proc muse-ipc-timeout nil t)
    +    (unless muse-ipc-server-registered
    +      (error "Error: Did not register listener"))
    +    (process-send-string client-proc
    +                         (concat "port " muse-ipc-server-port "\n"))
    +    (stop-process client-proc)
    +    (delete-process client-proc))
    +
    +  ;; Accept process output until the server dies
    +  (while muse-ipc-server-process (accept-process-output nil 1)))
    +
    +(provide 'muse-ipc)
    +
    +;;; muse-ipc.el ends here
    diff --git a/elpa/muse-3.20/muse-journal.el b/elpa/muse-3.20/muse-journal.el
    new file mode 100644
    index 0000000..e523b4c
    --- /dev/null
    +++ b/elpa/muse-3.20/muse-journal.el
    @@ -0,0 +1,774 @@
    +;;; muse-journal.el --- keep and publish a journal
    +
    +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
    +;;   Free Software Foundation, Inc.
    +
    +;; This file is part of Emacs Muse.  It is not part of GNU Emacs.
    +
    +;; Emacs Muse is free software; you can redistribute it and/or modify
    +;; it under the terms of the GNU General Public License as published
    +;; by the Free Software Foundation; either version 3, or (at your
    +;; option) any later version.
    +
    +;; Emacs Muse is distributed in the hope that it will be useful, but
    +;; WITHOUT ANY WARRANTY; without even the implied warranty of
    +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    +;; General Public License for more details.
    +
    +;; You should have received a copy of the GNU General Public License
    +;; along with Emacs Muse; see the file COPYING.  If not, write to the
    +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    +;; Boston, MA 02110-1301, USA.
    +
    +;;; Commentary:
    +
    +;; The module facilitates the keeping and publication of a journal.
    +;; When publishing to HTML, it assumes the form of a web log, or blog.
    +;;
    +;; The input format for each entry is as follows:
    +;;
    +;;   * 20040317: Title of entry
    +;;
    +;;   Text for the entry.
    +;;
    +;;   
    +;;   "You know who you are. It comes down to a simple gut check: You
    +;;   either love what you do or you don't. Period." -- P. Bronson
    +;;   
    +;;
    +;; The "qotd", or Quote of the Day, is entirely optional.  When
    +;; generated to HTML, this entry is rendered as:
    +;;
    +;;   
    +;;
    +;;

    Quote of the Day:

    +;;

    "You know who you are. It comes down to a simple gut +;; check: You either love what you do or you don't. Period." +;; -- P. Bronson

    +;;
    +;;
    +;;
    +;; +;;
    +;;

    Title of entry

    +;;
    +;;
    +;;
    +;;

    Text for the entry.

    +;;
    +;;
    +;;
    +;; +;; The plurality of "div" tags makes it possible to display the +;; entries in any form you wish, using a CSS style. +;; +;; Also, an .RDF file can be generated from your journal by publishing +;; it with the "rdf" style. It uses the first two sentences of the +;; first paragraph of each entry as its "description", and +;; autogenerates tags for linking to the various entries. + +;;; Contributors: + +;; René Stadler (mail AT renestadler DOT de) provided a patch that +;; causes dates in RSS feeds to be generated in a format that RSS +;; readers can parse. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse Journal Publishing +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'muse-publish) +(require 'muse-html) +(require 'muse-latex) +(require 'muse-book) + +(defgroup muse-journal nil + "Rules for transforming a journal into its final form." + :group 'muse-publish) + +(defcustom muse-journal-heading-regexp + "\\(?:\\([0-9]+\\)\\(?:: \\)?\\)?\\(.+?\\)?" + "A regexp that matches a journal heading. +Paren group 1 is the ISO date, group 2 is the optional category, +and group 3 is the optional heading for the entry." + :type 'regexp + :group 'muse-journal) + +(defcustom muse-journal-date-format "%a, %e %b %Y" + "Date format to use for journal entries." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-html-heading-regexp + (concat "^\n]*>" muse-journal-heading-regexp "$") + "A regexp that matches a journal heading from an HTML document. +Paren group 1 is the ISO date, group 2 is the optional category, +and group 3 is the optional heading for the entry." + :type 'regexp + :group 'muse-journal) + +(defcustom muse-journal-rss-heading-regexp + (concat "^\\* " muse-journal-heading-regexp "$") + "A regexp that matches a journal heading from an HTML document. +Paren group 1 is the ISO date, group 2 is the optional category, +and group 3 is the optional heading for the entry." + :type 'regexp + :group 'muse-journal) + +(defcustom muse-journal-html-entry-template + "
    +   +
    +
    +
    + %date% +
    +
    +

    %title%

    +
    +
    +
    +
    +

    %qotd%

    +
    +%text% +
    +
    +
    \n\n" + "Template used to publish individual journal entries as HTML. +This may be text or a filename." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-latex-section + "\\section*{%title% \\hfill {\\normalsize %date%}} +\\addcontentsline{toc}{chapter}{%title%}" + "Template used to publish a LaTeX section." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-latex-subsection + "\\subsection*{%title%} +\\addcontentsline{toc}{section}{%title%}" + "Template used to publish a LaTeX subsection." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-markup-tags + '(("qotd" t nil nil muse-journal-qotd-tag)) + "A list of tag specifications, for specially marking up Journal entries. +See `muse-publish-markup-tags' for more info. + +This is used by journal-latex and its related styles, as well as +the journal-rss-entry style, which both journal-rdf and +journal-rss use." + :type '(repeat (list (string :tag "Markup tag") + (boolean :tag "Expect closing tag" :value t) + (boolean :tag "Parse attributes" :value nil) + (boolean :tag "Nestable" :value nil) + function)) + :group 'muse-journal) + +;; FIXME: This doesn't appear to be used. +(defun muse-journal-generate-pages () + (let ((output-dir (muse-style-element :path))) + (goto-char (point-min)) + (while (re-search-forward muse-journal-heading-regexp nil t) + (let* ((date (match-string 1)) + (category (match-string 1)) + (category-file (concat output-dir category "/index.html")) + (heading (match-string 1))) + t)))) + +(defcustom muse-journal-rdf-extension ".rdf" + "Default file extension for publishing RDF (RSS 1.0) files." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-rdf-base-url "" + "The base URL of the website referenced by the RDF file." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-rdf-header + " + (concat (muse-style-element :base-url) + (muse-publish-link-name))\"> + <lisp>(muse-publishing-directive \"title\")</lisp> + (concat (muse-style-element :base-url) + (concat (muse-page-name) + muse-html-extension)) + (muse-publishing-directive \"desc\") + + + + (concat (muse-style-element :base-url) + (concat (muse-page-name) + muse-html-extension))\"/> + + + \n" + "Header used for publishing RDF (RSS 1.0) files. +This may be text or a filename." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-rdf-footer + "\n" + "Footer used for publishing RDF (RSS 1.0) files. +This may be text or a filename." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-rdf-date-format + "%Y-%m-%dT%H:%M:%S" + "Date format to use for RDF entries." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-rdf-entry-template + "\n + %title% + + %desc% + + %link%#%anchor% + %date% + %maintainer% + \n" + "Template used to publish individual journal entries as RDF. +This may be text or a filename." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-rdf-summarize-entries nil + "If non-nil, include only summaries in the RDF file, not the full data. + +The default is nil, because this annoys some subscribers." + :type 'boolean + :group 'muse-journal) + +(defcustom muse-journal-rss-extension ".xml" + "Default file extension for publishing RSS 2.0 files." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-rss-base-url "" + "The base URL of the website referenced by the RSS file." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-rss-header + "<\?xml version=\"1.0\" encoding=\" + (muse-html-encoding)\"?> + + + <lisp>(muse-publishing-directive \"title\")</lisp> + (concat (muse-style-element :base-url) + (concat (muse-page-name) + muse-html-extension)) + (muse-publishing-directive \"desc\") + en-us + Emacs Muse\n\n" + "Header used for publishing RSS 2.0 files. This may be text or a filename." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-rss-footer + "\n\n +\n" + "Footer used for publishing RSS 2.0 files. This may be text or a filename." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-rss-date-format + "%a, %d %b %Y %H:%M:%S %Z" + "Date format to use for RSS 2.0 entries." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-rss-entry-template + "\n + %title% + %link%#%anchor% + %desc% + (muse-publishing-directive \"author\") + %date% + %link%#%anchor% + %enclosure% + \n" + "Template used to publish individual journal entries as RSS 2.0. +This may be text or a filename." + :type 'string + :group 'muse-journal) + +(defcustom muse-journal-rss-enclosure-types-alist + '(("mp3" . "audio/mpeg")) + "File types that are accepted as RSS enclosures. +This is an alist that maps file extension to content type. +Useful for podcasting." + :type '(alist :key-type string :value-type string) + :group 'muse-journal) + +(defcustom muse-journal-rss-summarize-entries nil + "If non-nil, include only summaries in the RSS file, not the full data. + +The default is nil, because this annoys some subscribers." + :type 'boolean + :group 'muse-journal) + +(defcustom muse-journal-rss-markup-regexps + '((10000 muse-explicit-link-regexp 0 "\\2")) + "List of markup rules for publishing a Muse journal page to RSS 2.0. +For more information on the structure of this list, see +`muse-publish-markup-regexps'." + :type '(repeat (choice + (list :tag "Markup rule" + integer + (choice regexp symbol) + integer + (choice string function symbol)) + function)) + :group 'muse-journal) + +(defcustom muse-journal-rss-markup-functions + '((email . ignore) + (link . ignore) + (url . ignore)) + "An alist of style types to custom functions for that kind of text. +For more on the structure of this list, see +`muse-publish-markup-functions'." + :type '(alist :key-type symbol :value-type function) + :group 'muse-journal) + +(defun muse-journal-anchorize-title (title) + "This strips tags from TITLE, truncates TITLE at begin parenthesis, +and escapes any remaining non-alphanumeric characters." + (save-match-data + (if (string-match "(" title) + (setq title (substring title 0 (match-beginning 0)))) + (if (string-match "<[^>]+>" title) + (setq title (replace-match "" nil nil title))) + (let (pos code len ch) + (while (setq pos (string-match (concat "[^" muse-regexp-alnum "_]") + title pos)) + (setq ch (aref title pos) + code (format "%%%02X" (cond ((fboundp 'char-to-ucs) + (char-to-ucs ch)) + ((fboundp 'char-to-int) + (char-to-int ch)) + (t ch))) + len (length code) + title (concat (substring title 0 pos) + code + (when (< pos (length title)) + (substring title (1+ pos) nil))) + pos (+ len pos))) + title))) + +(defun muse-journal-sort-entries (&optional direction) + (interactive "P") + (sort-subr + direction + (function + (lambda () + (if (re-search-forward "^\\* [0-9]+" nil t) + (goto-char (match-beginning 0)) + (goto-char (point-max))))) + (function + (lambda () + (if (re-search-forward "^\\* [0-9]+" nil t) + (goto-char (1- (match-beginning 0))) + (goto-char (point-max))))) + (function + (lambda () + (forward-char 2))) + (function + (lambda () + (end-of-line))))) + +(defun muse-journal-qotd-tag (beg end) + (muse-publish-ensure-block beg end) + (muse-insert-markup (muse-markup-text 'begin-quote)) + (muse-insert-markup (muse-markup-text 'begin-quote-item)) + (goto-char end) + (muse-insert-markup (muse-markup-text 'end-quote-item)) + (muse-insert-markup (muse-markup-text 'end-quote))) + +(defun muse-journal-html-munge-buffer () + (goto-char (point-min)) + (let ((heading-regexp muse-journal-html-heading-regexp) + (inhibit-read-only t)) + (while (re-search-forward heading-regexp nil t) + (let* ((date (match-string 1)) + (orig-date date) + (title (match-string 2)) + (clean-title title) + datestamp qotd text) + (delete-region (match-beginning 0) (match-end 0)) + (if clean-title + (save-match-data + (while (string-match "\\(^<[^>]+>\\|<[^>]+>$\\)" clean-title) + (setq clean-title (replace-match "" nil nil clean-title))))) + (save-match-data + (when (and date + (string-match + (concat "\\`\\([1-9][0-9][0-9][0-9]\\)[./]?" + "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date)) + (setq datestamp + (encode-time + 0 0 0 + (string-to-number (match-string 3 date)) + (string-to-number (match-string 2 date)) + (string-to-number (match-string 1 date)) + nil) + date (concat (format-time-string + muse-journal-date-format datestamp) + (substring date (match-end 0)))))) + (save-restriction + (narrow-to-region + (point) (if (re-search-forward + (concat "\\(^
    $\\|" + heading-regexp "\\)") nil t) + (match-beginning 0) + (point-max))) + (goto-char (point-max)) + (while (and (not (bobp)) + (eq ?\ (char-syntax (char-before)))) + (delete-char -1)) + (goto-char (point-min)) + (while (and (not (eobp)) + (eq ?\ (char-syntax (char-after)))) + (delete-char 1)) + (save-excursion + (when (search-forward "" nil t) + (let ((tag-beg (match-beginning 0)) + (beg (match-end 0)) + end) + (re-search-forward "\n*") + (setq end (point-marker)) + (save-restriction + (narrow-to-region beg (match-beginning 0)) + (muse-publish-escape-specials (point-min) (point-max) + nil 'document) + (setq qotd (buffer-substring-no-properties + (point-min) (point-max)))) + (delete-region tag-beg end) + (set-marker end nil)))) + (setq text (buffer-string)) + (delete-region (point-min) (point-max)) + (let ((entry muse-journal-html-entry-template)) + (muse-insert-file-or-string entry) + (muse-publish-mark-read-only (point-min) (point-max)) + (goto-char (point-min)) + (while (search-forward "%date%" nil t) + (remove-text-properties (match-beginning 0) (match-end 0) + '(read-only nil rear-nonsticky nil)) + (replace-match (or date "") nil t)) + (goto-char (point-min)) + (while (search-forward "%title%" nil t) + (remove-text-properties (match-beginning 0) (match-end 0) + '(read-only nil rear-nonsticky nil)) + (replace-match (or title " ") nil t)) + (goto-char (point-min)) + (while (search-forward "%anchor%" nil t) + (replace-match (muse-journal-anchorize-title + (or clean-title orig-date)) + nil t)) + (goto-char (point-min)) + (while (search-forward "%qotd%" nil t) + (save-restriction + (narrow-to-region (match-beginning 0) (match-end 0)) + (delete-region (point-min) (point-max)) + (when qotd (muse-insert-markup qotd)))) + (goto-char (point-min)) + (while (search-forward "%text%" nil t) + (remove-text-properties (match-beginning 0) (match-end 0) + '(read-only nil rear-nonsticky nil)) + (replace-match text nil t)) + (when (null qotd) + (goto-char (point-min)) + (when (search-forward "
    " nil t) + (let ((beg (match-beginning 0))) + (re-search-forward "
    \n*" nil t) + (delete-region beg (point)))))))))) + ;; indicate that we are to continue the :before-end processing + nil) + +(defun muse-journal-latex-munge-buffer () + (goto-char (point-min)) + (let ((heading-regexp + (concat "^" (regexp-quote (muse-markup-text 'section)) + muse-journal-heading-regexp + (regexp-quote (muse-markup-text 'section-end)) "$")) + (inhibit-read-only t)) + (when (re-search-forward heading-regexp nil t) + (goto-char (match-beginning 0)) + (sort-subr nil + (function + (lambda () + (if (re-search-forward heading-regexp nil t) + (goto-char (match-beginning 0)) + (goto-char (point-max))))) + (function + (lambda () + (if (re-search-forward heading-regexp nil t) + (goto-char (1- (match-beginning 0))) + (goto-char (point-max))))) + (function + (lambda () + (forward-char 2))) + (function + (lambda () + (end-of-line))))) + (while (re-search-forward heading-regexp nil t) + (let ((date (match-string 1)) + (title (match-string 2)) + ;; FIXME: Nothing is done with qotd + qotd section) + (save-match-data + (when (and date + (string-match + (concat "\\([1-9][0-9][0-9][0-9]\\)[./]?" + "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date)) + (setq date (encode-time + 0 0 0 + (string-to-number (match-string 3 date)) + (string-to-number (match-string 2 date)) + (string-to-number (match-string 1 date)) + nil) + date (format-time-string + muse-journal-date-format date)))) + (save-restriction + (narrow-to-region (match-beginning 0) (match-end 0)) + (delete-region (point-min) (point-max)) + (muse-insert-markup muse-journal-latex-section) + (goto-char (point-min)) + (while (search-forward "%title%" nil t) + (replace-match (or title "Untitled") nil t)) + (goto-char (point-min)) + (while (search-forward "%date%" nil t) + (replace-match (or date "") nil t)))))) + (goto-char (point-min)) + (let ((subheading-regexp + (concat "^" (regexp-quote (muse-markup-text 'subsection)) + "\\([^\n}]+\\)" + (regexp-quote (muse-markup-text 'subsection-end)) "$")) + (inhibit-read-only t)) + (while (re-search-forward subheading-regexp nil t) + (let ((title (match-string 1))) + (save-restriction + (narrow-to-region (match-beginning 0) (match-end 0)) + (delete-region (point-min) (point-max)) + (muse-insert-markup muse-journal-latex-subsection) + (goto-char (point-min)) + (while (search-forward "%title%" nil t) + (replace-match title nil t)))))) + ;; indicate that we are to continue the :before-end processing + nil) + +(defun muse-journal-rss-munge-buffer () + (goto-char (point-min)) + (let ((heading-regexp muse-journal-rss-heading-regexp) + (inhibit-read-only t)) + (while (re-search-forward heading-regexp nil t) + (let* ((date (match-string 1)) + (orig-date date) + (title (match-string 2)) + ;; FIXME: Nothing is done with qotd + enclosure qotd desc) + (if title + (save-match-data + (if (string-match muse-explicit-link-regexp title) + (setq enclosure (muse-get-link title) + title (muse-get-link-desc title))))) + (save-match-data + (when (and date + (string-match + (concat "\\([1-9][0-9][0-9][0-9]\\)[./]?" + "\\([0-1][0-9]\\)[./]?\\([0-3][0-9]\\)") date)) + (setq date (encode-time 0 0 0 + (string-to-number (match-string 3 date)) + (string-to-number (match-string 2 date)) + (string-to-number (match-string 1 date)) + nil) + ;; make sure that date is in a format that RSS + ;; readers can handle + date (let ((system-time-locale "C")) + (format-time-string + (muse-style-element :date-format) date))))) + (save-restriction + (narrow-to-region + (match-beginning 0) + (if (re-search-forward heading-regexp nil t) + (match-beginning 0) + (if (re-search-forward "^Footnotes:" nil t) + (match-beginning 0) + (point-max)))) + (goto-char (point-min)) + (delete-region (point) (muse-line-end-position)) + (re-search-forward "\n+" nil t) + (while (and (char-after) + (eq ?\ (char-syntax (char-after)))) + (delete-char 1)) + (let ((beg (point))) + (if (muse-style-element :summarize) + (progn + (forward-sentence 2) + (setq desc (concat (buffer-substring beg (point)) "..."))) + (save-restriction + (muse-publish-markup-buffer "rss-entry" "journal-rss-entry") + (goto-char (point-min)) + (if (re-search-forward "Page published by Emacs Muse" nil t) + (goto-char (muse-line-end-position)) + (muse-display-warning + (concat + "Cannot find 'Page published by Emacs Muse begins here'.\n" + "You will probably need this text in your header.")) + (goto-char (point-min))) + (setq beg (point)) + (if (re-search-forward "Page published by Emacs Muse" nil t) + (goto-char (muse-line-beginning-position)) + (muse-display-warning + (concat + "Cannot find 'Page published by Emacs Muse ends here'.\n" + "You will probably need this text in your footer.")) + (goto-char (point-max))) + (setq desc (buffer-substring beg (point)))))) + (unless (string= desc "") + (setq desc (concat ""))) + (delete-region (point-min) (point-max)) + (let ((entry (muse-style-element :entry-template))) + (muse-insert-file-or-string entry) + (goto-char (point-min)) + (while (search-forward "%date%" nil t) + (replace-match (or date "") nil t)) + (goto-char (point-min)) + (while (search-forward "%title%" nil t) + (replace-match "") + (save-restriction + (narrow-to-region (point) (point)) + (insert (or title "Untitled")) + (remove-text-properties (match-beginning 0) (match-end 0) + '(read-only nil rear-nonsticky nil)) + (let ((muse-publishing-current-style (muse-style "html"))) + (muse-publish-escape-specials (point-min) (point-max) + nil 'document)))) + (goto-char (point-min)) + (while (search-forward "%desc%" nil t) + (replace-match desc nil t)) + (goto-char (point-min)) + (while (search-forward "%enclosure%" nil t) + (replace-match + (if (null enclosure) + "" + (save-match-data + (format + "" + (if (string-match "//" enclosure) + enclosure + (concat (muse-style-element :base-url) + enclosure)) + (let ((file + (expand-file-name enclosure + (muse-style-element :path)))) + (if (file-readable-p file) + (format "length=\"%d\" " + (nth 7 (file-attributes file))) + "")) + (if (string-match "\\.\\([^.]+\\)$" enclosure) + (let* ((ext (match-string 1 enclosure)) + (type + (assoc + ext muse-journal-rss-enclosure-types-alist))) + (if type + (cdr type) + "application/octet-stream")))))) + nil t)) + (goto-char (point-min)) + (while (search-forward "%link%" nil t) + (replace-match + (concat (muse-style-element :base-url) + (concat (muse-page-name) + muse-html-extension)) + nil t)) + (goto-char (point-min)) + (while (search-forward "%anchor%" nil t) + (replace-match + (muse-journal-anchorize-title (or title orig-date)) + nil t)) + (goto-char (point-min)) + (while (search-forward "%maintainer%" nil t) + (replace-match + (or (muse-style-element :maintainer) + (concat "webmaster@" (system-name))) + nil t))))))) + ;; indicate that we are to continue the :before-end processing + nil) + + +;;; Register the Muse Journal Publishers + +(muse-derive-style "journal-html" "html" + :before-end 'muse-journal-html-munge-buffer) + +(muse-derive-style "journal-xhtml" "xhtml" + :before-end 'muse-journal-html-munge-buffer) + +(muse-derive-style "journal-latex" "latex" + :tags 'muse-journal-markup-tags + :before-end 'muse-journal-latex-munge-buffer) + +(muse-derive-style "journal-pdf" "pdf" + :tags 'muse-journal-markup-tags + :before-end 'muse-journal-latex-munge-buffer) + +(muse-derive-style "journal-book-latex" "book-latex" + ;;:nochapters + :tags 'muse-journal-markup-tags + :before-end 'muse-journal-latex-munge-buffer) + +(muse-derive-style "journal-book-pdf" "book-pdf" + ;;:nochapters + :tags 'muse-journal-markup-tags + :before-end 'muse-journal-latex-munge-buffer) + +(muse-define-style "journal-rdf" + :suffix 'muse-journal-rdf-extension + :regexps 'muse-journal-rss-markup-regexps + :functions 'muse-journal-rss-markup-functions + :before 'muse-journal-rss-munge-buffer + :header 'muse-journal-rdf-header + :footer 'muse-journal-rdf-footer + :date-format 'muse-journal-rdf-date-format + :entry-template 'muse-journal-rdf-entry-template + :base-url 'muse-journal-rdf-base-url + :summarize 'muse-journal-rdf-summarize-entries) + +(muse-define-style "journal-rss" + :suffix 'muse-journal-rss-extension + :regexps 'muse-journal-rss-markup-regexps + :functions 'muse-journal-rss-markup-functions + :before 'muse-journal-rss-munge-buffer + :header 'muse-journal-rss-header + :footer 'muse-journal-rss-footer + :date-format 'muse-journal-rss-date-format + :entry-template 'muse-journal-rss-entry-template + :base-url 'muse-journal-rss-base-url + :summarize 'muse-journal-rss-summarize-entries) + +;; Used by `muse-journal-rss-munge-buffer' to mark up individual entries +(muse-derive-style "journal-rss-entry" "html" + :tags 'muse-journal-markup-tags) + +(provide 'muse-journal) + +;;; muse-journal.el ends here diff --git a/elpa/muse-3.20/muse-latex.el b/elpa/muse-3.20/muse-latex.el new file mode 100644 index 0000000..e416367 --- /dev/null +++ b/elpa/muse-3.20/muse-latex.el @@ -0,0 +1,669 @@ +;;; muse-latex.el --- publish entries in LaTex or PDF format + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Contributors: + +;; Li Daobing (lidaobing AT gmail DOT com) provided CJK support. + +;; Trent Buck (trentbuck AT gmail DOT com) gave valuable advice for +;; how to treat LaTeX specials and the like. + +;; Matthias Kegelmann (mathias DOT kegelmann AT sdm DOT de) provided a +;; scenario where we would need to respect the tag. + +;; Jean Magnan de Bornier (jean AT bornier DOT net) provided the +;; markup string for link-and-anchor. + +;; Jim Ottaway (j DOT ottaway AT lse DOT ac DOT uk) implemented slides +;; and lecture notes. + +;; Karl Berry (karl AT freefriends DOT org) suggested how to escape +;; additional special characters in image filenames. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse LaTeX Publishing +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'muse-publish) + +(defgroup muse-latex nil + "Rules for marking up a Muse file as a LaTeX article." + :group 'muse-publish) + +(defcustom muse-latex-extension ".tex" + "Default file extension for publishing LaTeX files." + :type 'string + :group 'muse-latex) + +(defcustom muse-latex-pdf-extension ".pdf" + "Default file extension for publishing LaTeX files to PDF." + :type 'string + :group 'muse-latex) + +(defcustom muse-latex-pdf-browser "open %s" + "The program to use when browsing a published PDF file. +This should be a format string." + :type 'string + :group 'muse-latex) + +(defcustom muse-latex-pdf-program "pdflatex" + "The program that is called to generate PDF content from LaTeX content." + :type 'string + :group 'muse-latex) + +(defcustom muse-latex-pdf-cruft + '(".aux" ".log" ".nav" ".out" ".snm" ".toc" ".vrb") + "Extensions of files to remove after generating PDF output successfully." + :type 'string + :group 'muse-latex) + +(defcustom muse-latex-header + "\\documentclass{article} + +\\usepackage[english]{babel} +\\usepackage{ucs} +\\usepackage[utf8x]{inputenc} +\\usepackage[T1]{fontenc} +\\usepackage{hyperref} +\\usepackage[pdftex]{graphicx} + +\\def\\museincludegraphics{% + \\begingroup + \\catcode`\\|=0 + \\catcode`\\\\=12 + \\catcode`\\#=12 + \\includegraphics[width=0.75\\textwidth] +} + +\\begin{document} + +\\title{(muse-publish-escape-specials-in-string + (muse-publishing-directive \"title\") 'document)} +\\author{(muse-publishing-directive \"author\")} +\\date{(muse-publishing-directive \"date\")} + +\\maketitle + +(and muse-publish-generate-contents + (not muse-latex-permit-contents-tag) + \"\\\\tableofcontents\n\\\\newpage\")\n\n" + "Header used for publishing LaTeX files. This may be text or a filename." + :type 'string + :group 'muse-latex) + +(defcustom muse-latex-footer "(muse-latex-bibliography) +\\end{document}\n" + "Footer used for publishing LaTeX files. This may be text or a filename." + :type 'string + :group 'muse-latex) + +(defcustom muse-latexcjk-header + "\\documentclass{article} + +\\usepackage{CJK} +\\usepackage{indentfirst} +\\usepackage[CJKbookmarks=true]{hyperref} +\\usepackage[pdftex]{graphicx} + +\\begin{document} +\\begin{CJK*}(muse-latexcjk-encoding) + +\\title{(muse-publish-escape-specials-in-string + (muse-publishing-directive \"title\") 'document)} +\\author{(muse-publishing-directive \"author\")} +\\date{(muse-publishing-directive \"date\")} + +\\maketitle + +(and muse-publish-generate-contents + (not muse-latex-permit-contents-tag) + \"\\\\tableofcontents\n\\\\newpage\")\n\n" + "Header used for publishing LaTeX files (CJK). This may be text or a +filename." + :type 'string + :group 'muse-latex) + +(defcustom muse-latexcjk-footer + "\n\\end{CJK*} +\\end{document}\n" + "Footer used for publishing LaTeX files (CJK). This may be text or a +filename." + :type 'string + :group 'muse-latex) + +(defcustom muse-latex-slides-header + "\\documentclass[ignorenonframetext]{beamer} + +\\usepackage[english]{babel} +\\usepackage{ucs} +\\usepackage[utf8x]{inputenc} +\\usepackage[T1]{fontenc} +\\usepackage{hyperref} + +\\def\\museincludegraphics{% + \\begingroup + \\catcode`\\|=0 + \\catcode`\\\\=12 + \\catcode`\\#=12 + \\includegraphics[width=0.50\\textwidth] +} + +\\title{(muse-publish-escape-specials-in-string + (muse-publishing-directive \"title\") 'document)} +\\author{(muse-publishing-directive \"author\")} +\\date{(muse-publishing-directive \"date\")} + +\\begin{document} + +\\frame{\\titlepage} + +(and muse-publish-generate-contents + \"\\\\frame{\\\\tableofcontents}\")\n\n" + "Header for publishing of slides using LaTeX. +This may be text or a filename. + +You must have the Beamer extension for LaTeX installed for this to work." + :type 'string + :group 'muse-latex) + +(defcustom muse-latex-lecture-notes-header + "\\documentclass{article} +\\usepackage{beamerarticle} + +\\usepackage[english]{babel} +\\usepackage{ucs} +\\usepackage[utf8x]{inputenc} +\\usepackage[T1]{fontenc} +\\usepackage{hyperref} +\\usepackage[pdftex]{graphicx} + +\\def\\museincludegraphics{% + \\begingroup + \\catcode`\\|=0 + \\catcode`\\\\=12 + \\catcode`\\#=12 + \\includegraphics[width=0.50\\textwidth] +} + +\\title{(muse-publish-escape-specials-in-string + (muse-publishing-directive \"title\") 'document)} +\\author{(muse-publishing-directive \"author\")} +\\date{(muse-publishing-directive \"date\")} + +\\begin{document} + +\\frame{\\titlepage} + +(and muse-publish-generate-contents + \"\\\\frame{\\\\tableofcontents}\")\n\n" + "Header for publishing of lecture notes using LaTeX. +This may be text or a filename. + +You must have the Beamer extension for LaTeX installed for this to work." + :type 'string + :group 'muse-latex) + +(defcustom muse-latex-markup-regexps + `(;; numeric ranges + (10000 "\\([0-9]+\\)-\\([0-9]+\\)" 0 "\\1--\\2") + + ;; be careful of closing quote pairs + (10100 "\"'" 0 "\"\\\\-'")) + "List of markup regexps for identifying regions in a Muse page. +For more on the structure of this list, see `muse-publish-markup-regexps'." + :type '(repeat (choice + (list :tag "Markup rule" + integer + (choice regexp symbol) + integer + (choice string function symbol)) + function)) + :group 'muse-latex) + +(defcustom muse-latex-markup-functions + '((table . muse-latex-markup-table)) + "An alist of style types to custom functions for that kind of text. +For more on the structure of this list, see +`muse-publish-markup-functions'." + :type '(alist :key-type symbol :value-type function) + :group 'muse-latex) + +(defcustom muse-latex-markup-strings + '((image-with-desc . "\\begin{figure}[h] +\\centering\\museincludegraphics{%s.%s}|endgroup +\\caption{%s} +\\end{figure}") + (image . "\\begin{figure}[h] +\\centering\\museincludegraphics{%s.%s}|endgroup +\\end{figure}") + (image-link . "%% %s +\\museincludegraphics{%s.%s}|endgroup") + (anchor-ref . "\\ref{%s}") + (url . "\\url{%s}") + (url-and-desc . "\\href{%s}{%s}\\footnote{%1%}") + (link . "\\href{%s}{%s}\\footnote{%1%}") + (link-and-anchor . "\\href{%1%}{%3%}\\footnote{%1%}") + (email-addr . "\\verb|%s|") + (anchor . "\\label{%s}") + (emdash . "---") + (comment-begin . "% ") + (rule . "\\vspace{.5cm}\\hrule\\vspace{.5cm}") + (no-break-space . "~") + (line-break . "\\\\") + (enddots . "\\ldots{}") + (dots . "\\dots{}") + (part . "\\part{") + (part-end . "}") + (chapter . "\\chapter{") + (chapter-end . "}") + (section . "\\section{") + (section-end . "}") + (subsection . "\\subsection{") + (subsection-end . "}") + (subsubsection . "\\subsubsection{") + (subsubsection-end . "}") + (section-other . "\\paragraph{") + (section-other-end . "}") + (footnote . "\\footnote{") + (footnote-end . "}") + (footnotetext . "\\footnotetext[%d]{") + (begin-underline . "\\underline{") + (end-underline . "}") + (begin-literal . "\\texttt{") + (end-literal . "}") + (begin-emph . "\\emph{") + (end-emph . "}") + (begin-more-emph . "\\textbf{") + (end-more-emph . "}") + (begin-most-emph . "\\textbf{\\emph{") + (end-most-emph . "}}") + (begin-verse . "\\begin{verse}\n") + (end-verse-line . " \\\\") + (verse-space . "~~~~") + (end-verse . "\n\\end{verse}") + (begin-example . "\\begin{quote}\n\\begin{verbatim}") + (end-example . "\\end{verbatim}\n\\end{quote}") + (begin-center . "\\begin{center}\n") + (end-center . "\n\\end{center}") + (begin-quote . "\\begin{quote}\n") + (end-quote . "\n\\end{quote}") + (begin-cite . "\\cite{") + (begin-cite-author . "\\citet{") + (begin-cite-year . "\\citet{") + (end-cite . "}") + (begin-uli . "\\begin{itemize}\n") + (end-uli . "\n\\end{itemize}") + (begin-uli-item . "\\item ") + (begin-oli . "\\begin{enumerate}\n") + (end-oli . "\n\\end{enumerate}") + (begin-oli-item . "\\item ") + (begin-dl . "\\begin{description}\n") + (end-dl . "\n\\end{description}") + (begin-ddt . "\\item[") + (end-ddt . "] \\mbox{}\n")) + "Strings used for marking up text. +These cover the most basic kinds of markup, the handling of which +differs little between the various styles." + :type '(alist :key-type symbol :value-type string) + :group 'muse-latex) + +(defcustom muse-latex-slides-markup-tags + '(("slide" t t nil muse-latex-slide-tag)) + "A list of tag specifications, for specially marking up LaTeX slides." + :type '(repeat (list (string :tag "Markup tag") + (boolean :tag "Expect closing tag" :value t) + (boolean :tag "Parse attributes" :value nil) + (boolean :tag "Nestable" :value nil) + function)) + :group 'muse-latex) + +(defcustom muse-latexcjk-encoding-map + '((utf-8 . "{UTF8}{song}") + (japanese-iso-8bit . "[dnp]{JIS}{min}") + (chinese-big5 . "{Bg5}{bsmi}") + (mule-utf-8 . "{UTF8}{song}") + (chinese-iso-8bit . "{GB}{song}") + (chinese-gbk . "{GBK}{song}")) + "An alist mapping emacs coding systems to appropriate CJK codings. +Use the base name of the coding system (ie, without the -unix)." + :type '(alist :key-type coding-system :value-type string) + :group 'muse-latex) + +(defcustom muse-latexcjk-encoding-default "{GB}{song}" + "The default Emacs buffer encoding to use in published files. +This will be used if no special characters are found." + :type 'string + :group 'muse-latex) + +(defun muse-latexcjk-encoding () + (when (boundp 'buffer-file-coding-system) + (muse-latexcjk-transform-content-type buffer-file-coding-system))) + +(defun muse-latexcjk-transform-content-type (content-type) + "Using `muse-cjklatex-encoding-map', try and resolve an emacs coding +system to an associated CJK coding system." + (let ((match (and (fboundp 'coding-system-base) + (assoc (coding-system-base content-type) + muse-latexcjk-encoding-map)))) + (if match + (cdr match) + muse-latexcjk-encoding-default))) + +(defcustom muse-latex-markup-specials-document + '((?\\ . "\\textbackslash{}") + (?\_ . "\\textunderscore{}") + (?\< . "\\textless{}") + (?\> . "\\textgreater{}") + (?^ . "\\^{}") + (?\~ . "\\~{}") + (?\@ . "\\@") + (?\$ . "\\$") + (?\% . "\\%") + (?\{ . "\\{") + (?\} . "\\}") + (?\& . "\\&") + (?\# . "\\#")) + "A table of characters which must be represented specially. +These are applied to the entire document, sans already-escaped +regions." + :type '(alist :key-type character :value-type string) + :group 'muse-latex) + +(defcustom muse-latex-markup-specials-example + '() + "A table of characters which must be represented specially. +These are applied to regions. + +With the default interpretation of regions, no specials +need to be escaped." + :type '(alist :key-type character :value-type string) + :group 'muse-latex) + +(defcustom muse-latex-markup-specials-literal + '((?\n . "\\\n") + (?\\ . "\\textbackslash{}") + (?_ . "\\textunderscore{}") + (?\< . "\\textless{}") + (?\> . "\\textgreater{}") + (?^ . "\\^{}") + (?\~ . "\\~{}") + (?\$ . "\\$") + (?\% . "\\%") + (?\{ . "\\{") + (?\} . "\\}") + (?\& . "\\&") + (?\# . "\\#")) + "A table of characters which must be represented specially. +This applies to =monospaced text= and regions." + :type '(alist :key-type character :value-type string) + :group 'muse-latex) + +(defcustom muse-latex-markup-specials-url + '((?\\ . "\\textbackslash{}") + (?\_ . "\\_") + (?\< . "\\<") + (?\> . "\\>") + (?\$ . "\\$") + (?\% . "\\%") + (?\{ . "\\{") + (?\} . "\\}") + (?\& . "\\&") + (?\# . "\\#")) + "A table of characters which must be represented specially. +These are applied to URLs." + :type '(alist :key-type character :value-type string) + :group 'muse-latex) + +(defcustom muse-latex-markup-specials-image + '((?\\ . "\\\\") + (?\< . "\\<") + (?\> . "\\>") + (?\$ . "\\$") + (?\% . "\\%") + (?\{ . "\\{") + (?\} . "\\}") + (?\& . "\\&") + (?\# . "\\#") + (?\| . "\\|")) + "A table of characters which must be represented specially. +These are applied to image filenames." + :type '(alist :key-type character :value-type string) + :group 'muse-latex) + +(defun muse-latex-decide-specials (context) + "Determine the specials to escape, depending on CONTEXT." + (cond ((memq context '(underline emphasis document url-desc verbatim + footnote)) + muse-latex-markup-specials-document) + ((eq context 'image) + muse-latex-markup-specials-image) + ((memq context '(email url)) + muse-latex-markup-specials-url) + ((eq context 'literal) + muse-latex-markup-specials-literal) + ((eq context 'example) + muse-latex-markup-specials-example) + (t (error "Invalid context '%s' in muse-latex" context)))) + +(defcustom muse-latex-permit-contents-tag nil + "If nil, ignore tags. Otherwise, insert table of contents. + +Most of the time, it is best to have a table of contents on the +first page, with a new page immediately following. To make this +work with documents published in both HTML and LaTeX, we need to +ignore the tag. + +If you don't agree with this, then set this option to non-nil, +and it will do what you expect." + :type 'boolean + :group 'muse-latex) + +(defun muse-latex-markup-table () + (let* ((table-info (muse-publish-table-fields (match-beginning 0) + (match-end 0))) + (row-len (car table-info)) + (field-list (cdr table-info))) + (when table-info + (muse-insert-markup "\\begin{tabular}{" (make-string row-len ?l) "}\n") + (dolist (fields field-list) + (let ((type (car fields))) + (setq fields (cdr fields)) + (if (eq type 'hline) + (muse-insert-markup "\\hline\n") + (when (= type 3) + (muse-insert-markup "\\hline\n")) + (insert (car fields)) + (setq fields (cdr fields)) + (dolist (field fields) + (muse-insert-markup " & ") + (insert field)) + (muse-insert-markup " \\\\\n") + (when (= type 2) + (muse-insert-markup "\\hline\n"))))) + (muse-insert-markup "\\end{tabular}")))) + +;;; Tags for LaTeX + +(defun muse-latex-slide-tag (beg end attrs) + "Publish the tag in LaTeX. +This is used by the slides and lecture-notes publishing styles." + (let ((title (cdr (assoc "title" attrs)))) + (goto-char beg) + (muse-insert-markup "\\begin{frame}[fragile]\n") + (when title + (muse-insert-markup "\\frametitle{") + (insert title) + (muse-insert-markup "}\n")) + (save-excursion + (goto-char end) + (muse-insert-markup "\n\\end{frame}")))) + +;;; Post-publishing functions + +(defun muse-latex-fixup-dquotes () + "Fixup double quotes." + (goto-char (point-min)) + (let ((open t)) + (while (search-forward "\"" nil t) + (unless (get-text-property (match-beginning 0) 'read-only) + (when (or (bobp) + (eq (char-before) ?\n)) + (setq open t)) + (if open + (progn + (replace-match "``") + (setq open nil)) + (replace-match "''") + (setq open t)))))) + +(defun muse-latex-fixup-citations () + "Replace semicolons in multi-head citations with colons." + (goto-char (point-min)) + (while (re-search-forward "\\\\cite.?{" nil t) + (let ((start (point)) + (end (re-search-forward "}"))) + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (while (re-search-forward ";" nil t) + (replace-match ",")))))) + +(defun muse-latex-fixup-headings () + "Remove footnotes in headings, since LaTeX does not permit them to exist. + +This can happen if there is a link in a heading, because by +default Muse will add a footnote for each link." + (goto-char (point-min)) + (while (re-search-forward "^\\\\section.?{" nil t) + (save-restriction + (narrow-to-region (match-beginning 0) (muse-line-end-position)) + (goto-char (point-min)) + (while (re-search-forward "\\\\footnote{[^}\n]+}" nil t) + (replace-match "")) + (forward-line 1)))) + +(defun muse-latex-munge-buffer () + (muse-latex-fixup-dquotes) + (muse-latex-fixup-citations) + (muse-latex-fixup-headings) + (when (and muse-latex-permit-contents-tag + muse-publish-generate-contents) + (goto-char (car muse-publish-generate-contents)) + (muse-insert-markup "\\tableofcontents"))) + +(defun muse-latex-bibliography () + (save-excursion + (goto-char (point-min)) + (if (re-search-forward "\\\\cite.?{" nil t) + (concat + "\\bibliography{" + (muse-publishing-directive "bibsource") + "}\n") + ""))) + +(defun muse-latex-pdf-browse-file (file) + (shell-command (format muse-latex-pdf-browser file))) + +(defun muse-latex-pdf-generate (file output-path final-target) + (apply + #'muse-publish-transform-output + file output-path final-target "PDF" + (function + (lambda (file output-path) + (let* ((fnd (file-name-directory output-path)) + (command (format "%s \"%s\"" + muse-latex-pdf-program + (file-relative-name file fnd))) + (times 0) + (default-directory fnd) + result) + ;; XEmacs can sometimes return a non-number result. We'll err + ;; on the side of caution by continuing to attempt to generate + ;; the PDF if this happens and treat the final result as + ;; successful. + (while (and (< times 2) + (or (not (numberp result)) + (not (eq result 0)) + ;; table of contents takes 2 passes + (file-readable-p + (muse-replace-regexp-in-string + "\\.tex\\'" ".toc" file t t)))) + (setq result (shell-command command) + times (1+ times))) + (if (or (not (numberp result)) + (eq result 0)) + t + nil)))) + muse-latex-pdf-cruft)) + +;;; Register the Muse LATEX Publishers + +(muse-define-style "latex" + :suffix 'muse-latex-extension + :regexps 'muse-latex-markup-regexps + :functions 'muse-latex-markup-functions + :strings 'muse-latex-markup-strings + :specials 'muse-latex-decide-specials + :before-end 'muse-latex-munge-buffer + :header 'muse-latex-header + :footer 'muse-latex-footer + :browser 'find-file) + +(muse-derive-style "pdf" "latex" + :final 'muse-latex-pdf-generate + :browser 'muse-latex-pdf-browse-file + :link-suffix 'muse-latex-pdf-extension + :osuffix 'muse-latex-pdf-extension) + +(muse-derive-style "latexcjk" "latex" + :header 'muse-latexcjk-header + :footer 'muse-latexcjk-footer) + +(muse-derive-style "pdfcjk" "latexcjk" + :final 'muse-latex-pdf-generate + :browser 'muse-latex-pdf-browse-file + :link-suffix 'muse-latex-pdf-extension + :osuffix 'muse-latex-pdf-extension) + +(muse-derive-style "slides" "latex" + :header 'muse-latex-slides-header + :tags 'muse-latex-slides-markup-tags) + +(muse-derive-style "slides-pdf" "pdf" + :header 'muse-latex-slides-header + :tags 'muse-latex-slides-markup-tags) + +(muse-derive-style "lecture-notes" "slides" + :header 'muse-latex-lecture-notes-header) + +(muse-derive-style "lecture-notes-pdf" "slides-pdf" + :header 'muse-latex-lecture-notes-header) + +(provide 'muse-latex) + +;;; muse-latex.el ends here diff --git a/elpa/muse-3.20/muse-latex2png.el b/elpa/muse-3.20/muse-latex2png.el new file mode 100644 index 0000000..2b4373d --- /dev/null +++ b/elpa/muse-3.20/muse-latex2png.el @@ -0,0 +1,277 @@ +;; muse-latex2png.el --- generate PNG images from inline LaTeX code + +;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; Author: Michael Olson +;; Created: 12-Oct-2005 + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; This was taken from latex2png.el, by Ganesh Swami , which was made for emacs-wiki. It has since +;; been extensively rewritten for Muse. + +;;; To do + +;; Remove stale image files. This could be done by making a function +;; for `muse-before-publish-hook' that deletes according to +;; (muse-page-name). + +;;; Code + +(require 'muse-publish) + +(defgroup muse-latex2png nil + "Publishing LaTeX formulas as PNG files." + :group 'muse-publish) + +(defcustom muse-latex2png-img-dest "./latex" + "The folder where the generated images will be placed. +This is relative to the current publishing directory." + :type 'string + :group 'muse-latex2png) + +(defcustom muse-latex2png-scale-factor 2.5 + "The scale factor to be used for sizing the resulting LaTeX output." + :type 'number + :group 'muse-latex2png) + +(defcustom muse-latex2png-fg "Black" + "The foreground color." + :type 'string + :group 'muse-latex2png) + +(defcustom muse-latex2png-bg "Transparent" + "The background color." + :type 'string + :group 'muse-latex2png) + +(defcustom muse-latex2png-template + "\\documentclass{article} +\\usepackage{fullpage} +\\usepackage{amssymb} +\\usepackage[usenames]{color} +\\usepackage{amsmath} +\\usepackage{latexsym} +\\usepackage[mathscr]{eucal} +%preamble% +\\pagestyle{empty} +\\begin{document} +{%code%} +\\end{document}\n" + "The LaTeX template to use." + :type 'string + :group 'muse-latex2png) + +(defun muse-latex2png-move2pubdir (file prefix pubdir) + "Move FILE to the PUBDIR folder. + +This is done so that the resulting images do not clutter your +main publishing directory. + +Old files with PREFIX in the name are deleted." + (when file + (if (file-exists-p file) + (progn + (unless (file-directory-p pubdir) + (message "Creating latex directory %s" pubdir) + (make-directory pubdir)) + (copy-file file (expand-file-name (file-name-nondirectory file) + pubdir) + t) + (delete-file file) + (concat muse-latex2png-img-dest "/" (file-name-nondirectory file))) + (message "Cannot find %s!" file)))) + +(defun muse-latex2png (code prefix preamble) + "Convert the LaTeX CODE into a png file beginning with PREFIX. +PREAMBLE indicates extra packages and definitions to include." + (unless preamble + (setq preamble "")) + (unless prefix + (setq prefix "muse-latex2png")) + (let* ((tmpdir (cond ((boundp 'temporary-file-directory) + temporary-file-directory) + ((fboundp 'temp-directory) + (temp-directory)) + (t "/tmp"))) + (texfile (expand-file-name + (concat prefix "__" (format "%d" (abs (sxhash code)))) + tmpdir)) + (defalt-directory default-directory)) + (with-temp-file (concat texfile ".tex") + (insert muse-latex2png-template) + (goto-char (point-min)) + (while (search-forward "%preamble%" nil t) + (replace-match preamble nil t)) + (goto-char (point-min)) + (while (search-forward "%code%" nil t) + (replace-match code nil t))) + (setq default-directory tmpdir) + (call-process "latex" nil nil nil texfile) + (if (file-exists-p (concat texfile ".dvi")) + (progn + (call-process + "dvipng" nil nil nil + "-E" + "-fg" muse-latex2png-fg + "-bg" muse-latex2png-bg + "-T" "tight" + "-x" (format "%s" (* muse-latex2png-scale-factor 1000)) + "-y" (format "%s" (* muse-latex2png-scale-factor 1000)) + "-o" (concat texfile ".png") + (concat texfile ".dvi")) + (if (file-exists-p (concat texfile ".png")) + (progn + (delete-file (concat texfile ".dvi")) + (delete-file (concat texfile ".tex")) + (delete-file (concat texfile ".aux")) + (delete-file (concat texfile ".log")) + (concat texfile ".png")) + (message "Failed to create png file") + nil)) + (message (concat "Failed to create dvi file " texfile)) + nil))) + +(defun muse-latex2png-region (beg end attrs) + "Generate an image for the Latex code between BEG and END. +If a Muse page is currently being published, replace the given +region with the appropriate markup that displays the image. +Otherwise, just return the path of the generated image. + +Valid keys for the ATTRS alist are as follows. + +prefix: The prefix given to the image file. +preamble: Extra text to add to the Latex preamble. +inline: Display image as inline, instead of a block." + (let ((end-marker (set-marker (make-marker) (1+ end))) + (pubdir (expand-file-name + muse-latex2png-img-dest + (file-name-directory muse-publishing-current-output-path)))) + (save-restriction + (narrow-to-region beg end) + (let* ((text (buffer-substring-no-properties beg end)) + ;; the prefix given to the image file. + (prefix (cdr (assoc "prefix" attrs))) + ;; preamble (for extra options) + (preamble (cdr (assoc "preamble" attrs))) + ;; display inline or as a block + (display (car (assoc "inline" attrs)))) + (when muse-publishing-p + (delete-region beg end) + (goto-char (point-min))) + (unless (file-directory-p pubdir) + (make-directory pubdir)) + (let ((path (muse-latex2png-move2pubdir + (muse-latex2png text prefix preamble) + prefix pubdir))) + (when path + (when muse-publishing-p + (muse-insert-markup + (if (muse-style-derived-p "html") + (concat "\"latex2png" + ">") + (muse-insert-markup "")) + (let ((ext (or (file-name-extension path) "")) + (path (muse-path-sans-extension path))) + (muse-markup-text 'image path ext)))) + (goto-char (point-max))) + path)))))) + +(defun muse-publish-latex-tag (beg end attrs) + "If the current style is not Latex-based, generate an image for the +given Latex code. Otherwise, don't do anything to the region. +See `muse-latex2png-region' for valid keys for ATTRS." + (unless (assoc "prefix" attrs) + (setq attrs (cons (cons "prefix" + (concat "latex2png-" (muse-page-name))) + attrs))) + (if (or (muse-style-derived-p "latex") (muse-style-derived-p "context")) + (muse-publish-mark-read-only beg end) + (muse-latex2png-region beg end attrs))) + +(put 'muse-publish-latex-tag 'muse-dangerous-tag t) + +(defun muse-publish-math-tag (beg end) + "Surround the given region with \"$\" characters. Then, if the +current style is not Latex-based, generate an image for the given +Latex math code. + +If 6 or more spaces come before the tag, and the end of the tag +is at the end of a line, then surround the region with the +equivalent of \"$$\" instead. This causes the region to be +centered in the published output, among other things." + (let* ((centered (and (re-search-backward + (concat "^[" muse-regexp-blank "]\\{6,\\}\\=") + nil t) + (save-excursion + (save-match-data + (goto-char end) + (looking-at (concat "[" muse-regexp-blank "]*$")))) + (prog1 t + (replace-match "") + (when (and (or (muse-style-derived-p "latex") + (muse-style-derived-p "context")) + (not (bobp))) + (backward-char 1) + (if (bolp) + (delete-char 1) + (forward-char 1))) + (setq beg (point))))) + (tag-beg (if centered + (if (muse-style-derived-p "context") + "\\startformula " "\\[ ") + "$")) + (tag-end (if centered + (if (muse-style-derived-p "context") + " \\stopformula" " \\]") + "$")) + (attrs (nconc (list (cons "prefix" + (concat "latex2png-" (muse-page-name)))) + (if centered nil + '(("inline" . t)))))) + (goto-char beg) + (muse-insert-markup tag-beg) + (goto-char end) + (muse-insert-markup tag-end) + (if (or (muse-style-derived-p "latex") (muse-style-derived-p "context")) + (muse-publish-mark-read-only beg (point)) + (muse-latex2png-region beg (point) attrs)))) + +(put 'muse-publish-math-tag 'muse-dangerous-tag t) + +;;; Insinuate with muse-publish + +(add-to-list 'muse-publish-markup-tags + '("latex" t t nil muse-publish-latex-tag) + t) + +(add-to-list 'muse-publish-markup-tags + '("math" t nil nil muse-publish-math-tag) + t) + +(provide 'muse-latex2png) +;;; muse-latex2png.el ends here diff --git a/elpa/muse-3.20/muse-mode.el b/elpa/muse-3.20/muse-mode.el new file mode 100644 index 0000000..9659843 --- /dev/null +++ b/elpa/muse-3.20/muse-mode.el @@ -0,0 +1,1013 @@ +;;; muse-mode.el --- mode for editing Muse files; has font-lock support + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; The Emacs Muse major mode is basically a hyped-up text-mode which +;; knows a lot more about the apparent structure of the document. + +;;; Contributors: + +;; Andrea Riciputi (ariciputi AT pito DOT com) gave an initial +;; implementation for tag completion by means of the `muse-insert-tag' +;; function. + +;; Per B. Sederberg (per AT med DOT upenn DOT edu) contributed the +;; insertion of relative links and list items, backlink searching, and +;; other things as well. + +;; Stefan Schlee (stefan_schlee AT yahoo DOT com) fixed a bug in +;; muse-next-reference and muse-previous-reference involving links +;; that begin at point 1. + +;; Gregory Collins (greg AT gregorycollins DOT net) fixed a bug with +;; paragraph separation and headings when filling. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Emacs Muse Major Mode +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'muse-mode) + +(require 'muse) +(require 'muse-regexps) +(require 'muse-project) + +(autoload 'muse-use-font-lock "muse-colors") +(autoload 'muse-publish-this-file "muse-publish") +(autoload 'muse-publish-get-style "muse-publish") +(autoload 'muse-publish-output-file "muse-publish") + +(require 'derived) +(eval-when-compile + (condition-case nil + (require 'pcomplete) ; load if available + (error nil))) + +;;; Options: + +(defgroup muse-mode nil + "Options controlling the behavior of the Muse editing Mode." + :group 'muse) + +(defcustom muse-mode-highlight-p t + "If non-nil, highlight the content of Muse buffers." + :type 'boolean + :require 'muse-colors + :group 'muse-mode) + +(defcustom muse-mode-auto-p nil + "If non-nil, automagically determine when Muse mode should be activated." + :type 'boolean + :set (function + (lambda (sym value) + (if value + (add-hook 'find-file-hooks 'muse-mode-maybe) + (remove-hook 'find-file-hooks 'muse-mode-maybe)) + (set sym value))) + :group 'muse-mode) + +(defun muse-mode-maybe-after-init () + (when muse-mode-auto-p + (add-hook 'find-file-hooks 'muse-mode-maybe))) + +;; If the user sets this value in their init file, make sure that +;; it takes effect +(add-hook 'after-init-hook 'muse-mode-maybe-after-init) + +(defcustom muse-mode-intangible-links nil + "If non-nil, use the intangible property on links. +This can cause problems with flyspell (and potentially fill-mode), +so only enable this if you don't use either of these." + :type 'boolean + :group 'muse-mode) + +(defcustom muse-mode-hook nil + "A hook that is run when Muse mode is entered." + :type 'hook + :options '(flyspell-mode footnote-mode turn-on-auto-fill + highlight-changes-mode) + :group 'muse-mode) + +(defcustom muse-grep-command + "find %D -type f ! -name '*~' | xargs -I {} echo \\\"{}\\\" | xargs egrep -n -e \"%W\"" + "The command to use when grepping for backlinks and other +searches through the muse projects. The string %D is replaced by +the directories from muse-project-alist, space-separated. The +string %W is replaced with the name of the muse page or whatever +else you are searching for. This command has been modified to +handle spaces in filenames, which were giving egrep a problem. + +Note: We highly recommend using glimpse to search large projects. +To use glimpse, install and edit a file called .glimpse_exclude +in your home directory. Put a list of glob patterns in that file +to exclude Emacs backup files, etc. Then, run the indexer using: + + glimpseindex -o + +Once that's completed, customize this variable to have the +following value: + + glimpse -nyi \"%W\" + +Your searches will go much, much faster, especially for very +large projects. Don't forget to add a user cronjob to update the +index at intervals." + :type 'string + :group 'muse-mode) + +(defvar muse-insert-map + (let ((map (make-sparse-keymap))) + (define-key map "l" 'muse-insert-relative-link-to-file) + (define-key map "t" 'muse-insert-tag) + (define-key map "u" 'muse-insert-url) + + map)) + +;;; Muse mode + +(defvar muse-mode-map + (let ((map (make-sparse-keymap))) + (define-key map [(control ?c) (control ?a)] 'muse-index) + (define-key map [(control ?c) (control ?e)] 'muse-edit-link-at-point) + (define-key map [(control ?c) (control ?l)] 'font-lock-mode) + (define-key map [(control ?c) (control ?t)] + 'muse-project-publish-this-file) + (define-key map [(control ?c) (control ?T)] 'muse-publish-this-file) + (define-key map [(control ?c) (meta control ?t)] 'muse-publish-this-file) + (define-key map [(control ?c) (control ?v)] 'muse-browse-result) + + (define-key map [(control ?c) ?=] 'muse-what-changed) + + (define-key map [tab] 'muse-next-reference) + (define-key map [(control ?i)] 'muse-next-reference) + + (if (featurep 'xemacs) + (progn + (define-key map [(button2)] 'muse-follow-name-at-mouse) + (define-key map [(shift button2)] + 'muse-follow-name-at-mouse-other-window)) + (define-key map [(shift control ?m)] + 'muse-follow-name-at-point-other-window) + (define-key map [mouse-2] 'muse-follow-name-at-mouse) + (define-key map [(shift mouse-2)] + 'muse-follow-name-at-mouse-other-window)) + + (define-key map [(shift tab)] 'muse-previous-reference) + (unless (featurep 'xemacs) + (define-key map [(shift iso-lefttab)] 'muse-previous-reference) + (define-key map [(shift control ?i)] 'muse-previous-reference)) + + (define-key map [(control ?c) (control ?f)] 'muse-project-find-file) + (define-key map [(control ?c) (control ?p)] 'muse-project-publish) + + (define-key map [(control ?c) (control ?i)] 'muse-insert-thing) + (define-key map [(control ?c) tab] 'muse-insert-thing) + + ;; Searching functions + (define-key map [(control ?c) (control ?b)] 'muse-find-backlinks) + (define-key map [(control ?c) (control ?s)] 'muse-search) + + ;; Enhanced list functions + (define-key map [(meta return)] 'muse-insert-list-item) + (define-key map [(control ?>)] 'muse-increase-list-item-indentation) + (define-key map [(control ?<)] 'muse-decrease-list-item-indentation) + + (when (featurep 'pcomplete) + (define-key map [(meta tab)] 'pcomplete) + (define-key map [(meta control ?i)] 'pcomplete)) + + map) + "Keymap used by Emacs Muse mode.") + +;;;###autoload +(define-derived-mode muse-mode text-mode "Muse" + "Muse is an Emacs mode for authoring and publishing documents. +\\{muse-mode-map}" + ;; Since we're not inheriting from normal-mode, we need to + ;; explicitly run file variables. + (condition-case err + (hack-local-variables) + (error (message "File local-variables error: %s" + (prin1-to-string err)))) + ;; Avoid lock-up caused by use of the 'intangible' text property + ;; with flyspell. + (unless muse-mode-intangible-links + (set (make-local-variable 'inhibit-point-motion-hooks) t)) + (setq muse-current-project (muse-project-of-file)) + (muse-project-set-variables) + ;; Make fill not split up links + (when (boundp 'fill-nobreak-predicate) + (make-local-variable 'fill-nobreak-predicate) + ;; Work around annoying inconsistency in fill handling between + ;; Emacs 21 and 22. + (if (< emacs-major-version 22) + (setq fill-nobreak-predicate 'muse-mode-fill-nobreak-p) + (add-to-list 'fill-nobreak-predicate + 'muse-mode-fill-nobreak-p))) + ;; Make fill work nicely with item lists + (let ((regexp (concat "\\s-+\\(-\\|[0-9]+\\.\\)\\s-+" + "\\|\\[[0-9]+\\]\\s-*" + "\\|.*\\s-*::\\s-+" + "\\|\\*+\\s-+"))) + (set (make-local-variable 'adaptive-fill-regexp) + (concat regexp "\\|\\s-*")) + (set (make-local-variable 'paragraph-start) + (concat paragraph-start "\\|" regexp)) + (set (make-local-variable 'paragraph-separate) + (concat paragraph-separate "\\|\\*+\\s-+"))) + (set (make-local-variable 'fill-paragraph-function) + 'muse-mode-fill-paragraph) + + ;; Comment syntax is `; comment' + (set (make-local-variable 'comment-start) + "; ") + (set (make-local-variable 'comment-start-skip) + "^;\\s-+") + (set (make-local-variable 'indent-line-function) + #'ignore) + ;; If we're using Emacs21, this makes flyspell work like it should + (when (boundp 'flyspell-generic-check-word-p) + (set (make-local-variable 'flyspell-generic-check-word-p) + 'muse-mode-flyspell-p)) + ;; If pcomplete is available, set it up + (when (featurep 'pcomplete) + (set (make-local-variable 'pcomplete-default-completion-function) + 'muse-mode-completions) + (set (make-local-variable 'pcomplete-command-completion-function) + 'muse-mode-completions) + (set (make-local-variable 'pcomplete-parse-arguments-function) + 'muse-mode-current-word)) + ;; Initialize any auto-generated variables + (run-hooks 'muse-update-values-hook) + (when muse-mode-highlight-p + (muse-use-font-lock))) + +(put 'muse-mode + 'flyspell-mode-predicate + 'muse-mode-flyspell-p) + +(defun muse-mode-fill-nobreak-p () + "Return nil if we should allow a fill to occur at point. +Otherwise return non-nil. + +This is used to keep long explicit links from being mangled by +fill mode." + (save-excursion + (save-match-data + (and (re-search-backward "\\[\\[\\|\\]\\]" + (line-beginning-position) t) + (string= (or (match-string 0) "") + "[["))))) + +(defun muse-mode-fill-paragraph (arg) + "If a definition list is at point, use special filling rules for it. +Otherwise return nil to let the normal filling function take care +of things. + +ARG is passed to `fill-paragraph'." + (let ((count 2)) + (and (not (muse-mode-fill-nobreak-p)) + (save-excursion + (beginning-of-line) + (and (looking-at muse-dl-term-regexp) + (prog1 t + ;; Take initial whitespace into account + (when (looking-at (concat "[" muse-regexp-blank "]+")) + (setq count (+ count (length (match-string 0)))))))) + (let ((fill-prefix (make-string count ?\ )) + (fill-paragraph-function nil)) + (prog1 t + (fill-paragraph arg)))))) + +(defun muse-mode-flyspell-p () + "Return non-nil if we should allow spell-checking to occur at point. +Otherwise return nil. + +This is used to keep links from being improperly colorized by flyspell." + (let ((pos (if (bobp) (point) (1- (point))))) + (and (not (get-text-property pos 'muse-no-flyspell)) + (not (get-text-property pos 'muse-link)) + (save-match-data + (null (muse-link-at-point)))))) + +;;;###autoload +(defun muse-mode-choose-mode () + "Turn the proper Emacs Muse related mode on for this file." + (let ((project (muse-project-of-file))) + (funcall (or (and project (muse-get-keyword :major-mode (cadr project) t)) + 'muse-mode)))) + +(defun muse-mode-maybe () + "Maybe turn Emacs Muse mode on for this file." + (let ((project (muse-project-of-file))) + (and project + (funcall (or (muse-get-keyword :major-mode (cadr project) t) + 'muse-mode))))) + +;;; Enhanced list editing + +(defun muse-on-blank-line () + "See if point is on a blank line" + (save-excursion + (beginning-of-line) + (looking-at (concat "[" muse-regexp-blank "]*$")))) + +(defun muse-get-paragraph-start () + "Return the start of the current paragraph. This function will +return nil if there are no prior paragraphs and the beginning of +the line if point is on a blank line." + (let ((para-start (concat "^[" muse-regexp-blank "]*$"))) + ;; search back to start of paragraph + (save-excursion + (save-match-data + (if (not (muse-on-blank-line)) + (re-search-backward para-start nil t) + (line-beginning-position)))))) + +(defun muse-insert-thing () + "Prompt for something to insert into the current buffer." + (interactive) + (message "Insert:\nl link\nt Muse tag\nu URL") + (let (key cmd) + (let ((overriding-local-map muse-insert-map)) + (setq key (read-key-sequence nil))) + (if (commandp (setq cmd (lookup-key muse-insert-map key))) + (progn (message "") + (call-interactively cmd)) + (message "Not inserting anything")))) + +;;;###autoload +(defun muse-insert-list-item () + "Insert a list item at the current point, taking into account +your current list type and indentation level." + (interactive) + (let ((newitem " - ") + (itemno nil) + (pstart (muse-get-paragraph-start)) + (list-item (format muse-list-item-regexp + (concat "[" muse-regexp-blank "]*")))) + ;; search backwards for start of current item + (save-excursion + (when (re-search-backward list-item pstart t) + ;; save the matching item + (setq newitem (match-string 0)) + ;; see what type it is + (if (string-match "::" (match-string 0)) + ;; is a definition, replace the term + (setq newitem (concat " " + (read-string "Term: ") + " :: ")) + ;; see if it's a numbered list + (when (string-match "[0-9]+" newitem) + ;; is numbered, so increment + (setq itemno (1+ + (string-to-number + (match-string 0 newitem)))) + (setq newitem (replace-match + (number-to-string itemno) + nil nil newitem)))))) + ;; insert the new item + (insert (concat "\n" newitem)))) + +(defun muse-alter-list-item-indentation (operation) + "Alter the indentation of the current list item. +Valid values of OPERATION are 'increase and 'decrease." + (let ((pstart (muse-get-paragraph-start)) + (list-item (format muse-list-item-regexp + (concat "[" muse-regexp-blank "]*"))) + beg move-func indent) + ;; search backwards until start of paragraph to see if we are on a + ;; current item + (save-excursion + (if (or (progn (goto-char (muse-line-beginning-position)) + ;; we are on an item + (looking-at list-item)) + ;; not on item, so search backwards + (re-search-backward list-item pstart t)) + (let ((beg (point))) + ;; we are on an item + (setq indent (buffer-substring (match-beginning 0) + (match-beginning 1))) + (muse-forward-list-item (muse-list-item-type (match-string 1)) + (concat "[" muse-regexp-blank "]*") + t) + (save-restriction + (narrow-to-region beg (point)) + (goto-char (point-min)) + (let ((halt nil)) + (while (< (point) (point-max)) + ;; increase or decrease the indentation + (unless halt + (cond ((eq operation 'increase) + (insert " ")) + ((eq operation 'decrease) + (if (looking-at " ") + ;; we have enough space, so delete it + (delete-region (match-beginning 0) + (match-end 0)) + (setq halt t))))) + (forward-line 1))))) + ;; we are not on an item, so warn + (message "You are not on a list item."))))) + +;;;###autoload +(defun muse-increase-list-item-indentation () + "Increase the indentation of the current list item." + (interactive) + (muse-alter-list-item-indentation 'increase)) + +;;;###autoload +(defun muse-decrease-list-item-indentation () + "Decrease the indentation of the current list item." + (interactive) + (muse-alter-list-item-indentation 'decrease)) + +;;; Support page name completion using pcomplete + +(defun muse-mode-completions () + "Return a list of possible completions names for this buffer." + (let ((project (muse-project-of-file))) + (if project + (while (pcomplete-here + (mapcar 'car (muse-project-file-alist project))))))) + +(defun muse-mode-current-word () + (let ((end (point))) + (save-excursion + (save-restriction + (skip-chars-backward (concat "^\\[\n" muse-regexp-blank)) + (narrow-to-region (point) end)) + (pcomplete-parse-buffer-arguments)))) + +;;; Navigate/visit links or URLs. Use TAB, S-TAB and RET (or mouse-2). + +(defun muse-link-at-point (&optional pos) + "Return link text if a URL or link is at point." + (let ((case-fold-search nil) + (inhibit-point-motion-hooks t) + (here (or pos (point)))) + ;; if we are using muse-colors, we can just use link properties to + ;; determine whether we are on a link + (if (featurep 'muse-colors) + (when (get-text-property here 'muse-link) + (save-excursion + (when (and (not (bobp)) + (get-text-property (1- here) 'muse-link)) + (goto-char (or (previous-single-property-change here 'muse-link) + (point-min)))) + (if (looking-at muse-explicit-link-regexp) + (progn + (goto-char (match-beginning 1)) + (muse-handle-explicit-link)) + (muse-handle-implicit-link)))) + ;; use fallback method to find a link + (when (or (null pos) + (and (char-after pos) + (not (eq (char-syntax (char-after pos)) ?\ )))) + (save-excursion + (goto-char here) + ;; check for explicit link here or before point + (if (or (looking-at muse-explicit-link-regexp) + (and + (re-search-backward "\\[\\[\\|\\]\\]" + (muse-line-beginning-position) + t) + (string= (or (match-string 0) "") "[[") + (looking-at muse-explicit-link-regexp))) + (progn + (goto-char (match-beginning 1)) + (muse-handle-explicit-link)) + (goto-char here) + ;; check for bare URL or other link type + (skip-chars-backward (concat "^'\"<>{}(\n" muse-regexp-blank)) + (and (looking-at muse-implicit-link-regexp) + (muse-handle-implicit-link)))))))) + +(defun muse-make-link (link &optional desc) + "Return a link to LINK with DESC as the description." + (when (string-match muse-explicit-link-regexp link) + (unless desc (setq desc (muse-get-link-desc link))) + (setq link (muse-get-link link))) + (if (and desc + link + (not (string= desc "")) + (not (string= link desc))) + (concat "[[" (muse-link-escape link) "][" (muse-link-escape desc) "]]") + (concat "[[" (or (muse-link-escape link) "") "]]"))) + +;;;###autoload +(defun muse-insert-relative-link-to-file () + "Insert a relative link to a file, with optional description, at point." + ;; Perhaps the relative location should be configurable, so that the + ;; file search would start in the publishing directory and then + ;; insert the link relative to the publishing directory + (interactive) + (insert + (muse-make-link (file-relative-name (read-file-name "Link: ")) + (read-string "Text: ")))) + +(defcustom muse-insert-url-initial-input "http://" + "The string to insert before reading a URL interactively. +This is used by the `muse-insert-url' command." + :type 'string + :group 'muse-mode) + +(defun muse-insert-url () + "Insert a URL, with optional description, at point." + (interactive) + (insert + (muse-make-link (read-string "URL: " muse-insert-url-initial-input) + (read-string "Text: ")))) + +;;;###autoload +(defun muse-edit-link-at-point () + "Edit the current link. +Do not rename the page originally referred to." + (interactive) + (if (muse-link-at-point) + (let ((link (muse-link-unescape (muse-get-link))) + (desc (muse-link-unescape (muse-get-link-desc)))) + (replace-match + (save-match-data + (muse-make-link + (read-string "Link: " link) + (read-string "Text: " desc))) + t t)) + (error "There is no valid link at point"))) + +(defun muse-visit-link-default (link &optional other-window) + "Visit the URL or link named by LINK. +If ANCHOR is specified, search for it after opening LINK. + +This is the default function to call when visiting links; it is +used by `muse-visit-link' if you have not specified :visit-link +in `muse-project-alist'." + (if (string-match muse-url-regexp link) + (muse-browse-url link) + (let (anchor + base-buffer) + (when (string-match "#" link) + (setq anchor (substring link (match-beginning 0)) + link (if (= (match-beginning 0) 0) + ;; If there is an anchor but no link, default + ;; to the current page. + nil + (substring link 0 (match-beginning 0))))) + (when link + (setq base-buffer (get-buffer link)) + (if (and base-buffer (not (buffer-file-name base-buffer))) + ;; If file is temporary (no associated file), just switch to + ;; the buffer + (if other-window + (switch-to-buffer-other-window base-buffer) + (switch-to-buffer base-buffer)) + (let ((project (muse-project-of-file))) + (if project + (muse-project-find-file link project + (and other-window + 'find-file-other-window)) + (if other-window + (find-file-other-window link) + (find-file link)))))) + (when anchor + (let ((pos (point)) + (regexp (concat "^\\W*" (regexp-quote anchor) "\\b")) + last) + (goto-char (point-min)) + (while (and (setq last (re-search-forward regexp nil t)) + (muse-link-at-point))) + (unless last + (goto-char pos) + (message "Could not find anchor `%s'" anchor))))))) + +(defun muse-visit-link (link &optional other-window) + "Visit the URL or link named by LINK." + (let ((visit-link-function + (muse-get-keyword :visit-link (cadr (muse-project-of-file)) t))) + (if visit-link-function + (funcall visit-link-function link other-window) + (muse-visit-link-default link other-window)))) + +;;;###autoload +(defun muse-browse-result (style &optional other-window) + "Visit the current page's published result." + (interactive + (list (muse-project-get-applicable-style buffer-file-name + (cddr muse-current-project)) + current-prefix-arg)) + (setq style (muse-style style)) + (muse-project-publish-this-file nil style) + (let* ((output-dir (muse-style-element :path style)) + (output-suffix (muse-style-element :osuffix style)) + (output-path (muse-publish-output-file buffer-file-name output-dir + style)) + (target (if output-suffix + (concat (muse-path-sans-extension output-path) + output-suffix) + output-path)) + (muse-current-output-style (list :base (car style) + :path output-dir))) + (if (not (file-readable-p target)) + (error "Cannot open output file '%s'" target) + (if other-window + (find-file-other-window target) + (let ((func (muse-style-element :browser style t))) + (if func + (funcall func target) + (message "The %s publishing style does not support browsing." + style))))))) + +;;;###autoload +(defun muse-follow-name-at-point (&optional other-window) + "Visit the link at point." + (interactive "P") + (let ((link (muse-link-at-point))) + (if link + (muse-visit-link link other-window) + (error "There is no valid link at point")))) + +;;;###autoload +(defun muse-follow-name-at-point-other-window () + "Visit the link at point in other window." + (interactive) + (muse-follow-name-at-point t)) + +(defun muse-follow-name-at-mouse (event &optional other-window) + "Visit the link at point, or yank text if none is found." + (interactive "eN") + (unless + (save-excursion + (cond ((fboundp 'event-window) ; XEmacs + (set-buffer (window-buffer (event-window event))) + (and (funcall (symbol-function 'event-point) event) + (goto-char (funcall (symbol-function 'event-point) + event)))) + ((fboundp 'posn-window) ; Emacs + (set-buffer (window-buffer (posn-window (event-start event)))) + (goto-char (posn-point (event-start event))))) + (let ((link (muse-link-at-point))) + (when link + (muse-visit-link link other-window) + t))) + ;; Fall back to normal binding for this event + (call-interactively + (lookup-key (current-global-map) (this-command-keys))))) + +(defun muse-follow-name-at-mouse-other-window (event) + "Visit the link at point" + (interactive "e") + ;; throw away the old window position, since other-window will + ;; change it anyway + (select-window (car (cadr event))) + (muse-follow-name-at-mouse event t)) + +;;;###autoload +(defun muse-next-reference () + "Move forward to next Muse link or URL, cycling if necessary." + (interactive) + (let ((pos)) + (save-excursion + (when (get-text-property (point) 'muse-link) + (goto-char (or (next-single-property-change (point) 'muse-link) + (point-max)))) + + (setq pos (next-single-property-change (point) 'muse-link)) + + (when (not pos) + (if (get-text-property (point-min) 'muse-link) + (setq pos (point-min)) + (setq pos (next-single-property-change (point-min) 'muse-link))))) + + (when pos + (goto-char pos)))) + +;;;###autoload +(defun muse-previous-reference () + "Move backward to the next Muse link or URL, cycling if necessary. +In case of Emacs x <= 21 and ignoring of intangible properties (see +`muse-mode-intangible-links'). + +This function is not entirely accurate, but it's close enough." + (interactive) + (let ((pos)) + (save-excursion + + ;; Hack: The user perceives the two cases of point ("|") + ;; position (1) "|[[" and (2) "[[|" or "][|" as "point is at + ;; start of link". But in the sense of the function + ;; "previous-single-property-change" these two cases are + ;; different. The following code aligns these two cases. Emacs + ;; 21: If the intangible property is ignored case (2) is more + ;; complicate and this hack only solves the problem partially. + ;; + (when (and (get-text-property (point) 'muse-link) + (muse-looking-back "\\[\\|\\]")) + (goto-char (or (previous-single-property-change (point) 'muse-link) + (point-min)))) + + (when (eq (point) (point-min)) + (goto-char (point-max))) + + (setq pos (previous-single-property-change (point) 'muse-link)) + + (when (not pos) + (if (get-text-property (point-min) 'muse-link) + (setq pos (point-min)) + (setq pos (previous-single-property-change (point-max) + 'muse-link))))) + + (when pos + (if (get-text-property pos 'muse-link) + (goto-char pos) + (goto-char (or (previous-single-property-change pos 'muse-link) + (point-min))))))) + +;;;###autoload +(defun muse-what-changed () + "Show the unsaved changes that have been made to the current file." + (interactive) + (diff-backup buffer-file-name)) + + +;;; Find text in project pages, or pages referring to the current page + +(defvar muse-search-history nil) + +(defun muse-grep (string &optional grep-command-no-shadow) + "Grep for STRING in the project directories. +GREP-COMMAND if passed will supplant `muse-grep-command'." + ;; careful - grep-command leaks into compile, so we call it + ;; -no-shadow instead + (require 'compile) + (let* ((str (or grep-command-no-shadow muse-grep-command)) + (muse-directories (mapcar + (lambda (thing) + (car (cadr thing))) + muse-project-alist)) + (dirs (mapconcat (lambda (dir) + (shell-quote-argument + (expand-file-name dir))) + muse-directories " "))) + (if (string= dirs "") + (muse-display-warning + "No directories were found in the current project; aborting search") + (while (string-match "%W" str) + (setq str (replace-match string t t str))) + (while (string-match "%D" str) + (setq str (replace-match dirs t t str))) + (if (fboundp 'compilation-start) + (compilation-start str nil (lambda (&rest args) "*search*") + grep-regexp-alist) + (and (fboundp 'compile-internal) + (compile-internal str "No more search hits" "search" + nil grep-regexp-alist)))))) + +;;;###autoload +(defun muse-search-with-command (text) + "Search for the given TEXT string in the project directories +using the specified command." + (interactive + (list (let ((str (concat muse-grep-command)) pos) + (when (string-match "%W" str) + (setq pos (match-beginning 0)) + (unless (featurep 'xemacs) + (setq pos (1+ pos))) + (setq str (replace-match "" t t str))) + (read-from-minibuffer "Search command: " + (cons str pos) nil nil + 'muse-search-history)))) + (muse-grep nil text)) + +;;;###autoload +(defun muse-search () + "Search for the given TEXT using the default grep command." + (interactive) + (muse-grep (read-string "Search: "))) + +;;;###autoload +(defun muse-find-backlinks () + "Grep for the current pagename in all the project directories." + (interactive) + (muse-grep (muse-page-name))) + + +;;; Generate an index of all known Muse pages + +(defun muse-generate-index (&optional as-list exclude-private) + "Generate an index of all Muse pages." + (let ((index (muse-index-as-string as-list exclude-private))) + (with-current-buffer (get-buffer-create "*Muse Index*") + (erase-buffer) + (insert index) + (current-buffer)))) + +;;;###autoload +(defun muse-index () + "Display an index of all known Muse pages." + (interactive) + (message "Generating Muse index...") + (let ((project (muse-project))) + (with-current-buffer (muse-generate-index) + (goto-char (point-min)) + (muse-mode) + (setq muse-current-project project) + (pop-to-buffer (current-buffer)))) + (message "Generating Muse index...done")) + +(defun muse-index-as-string (&optional as-list exclude-private exclude-current) + "Generate an index of all Muse pages. +If AS-LIST is non-nil, insert a dash and spaces before each item. +If EXCLUDE-PRIVATE is non-nil, exclude files that have private permissions. +If EXCLUDE-CURRENT is non-nil, exclude the current file from the output." + (let ((files (sort (copy-alist (muse-project-file-alist)) + (function + (lambda (l r) + (string-lessp (car l) (car r))))))) + (when (and exclude-current (muse-page-name)) + (setq files (delete (assoc (muse-page-name) files) files))) + (with-temp-buffer + (while files + (unless (and exclude-private + (muse-project-private-p (cdar files))) + (insert (if as-list " - " "") "[[" (caar files) "]]\n")) + (setq files (cdr files))) + (buffer-string)))) + +;;; Insert tags interactively on C-c TAB t + +(defvar muse-tag-history nil + "List of recently-entered tags; used by `muse-insert-tag'. +If you want a tag to start as the default, you may manually set +this variable to a list.") + +(defvar muse-custom-tags nil + "Keep track of any new tags entered in `muse-insert-tag'. +If there are (X)HTML tags that you use frequently with that +function, you might want to set this manually.") + +;;;###autoload +(defun muse-insert-tag (tag) + "Insert a tag interactively with a blank line after it." + (interactive + (list + (funcall + muse-completing-read-function + (concat "Tag: " + (when muse-tag-history + (concat "(default: " (car muse-tag-history) ") "))) + (progn + (require 'muse-publish) + (mapcar 'list (nconc (mapcar 'car muse-publish-markup-tags) + muse-custom-tags))) + nil nil nil 'muse-tag-history + (car muse-tag-history)))) + (when (equal tag "") + (setq tag (car muse-tag-history))) + (unless (interactive-p) + (require 'muse-publish)) + (let ((tag-entry (assoc tag muse-publish-markup-tags)) + (options "")) + ;; Add to custom list if no entry exists + (unless tag-entry + (add-to-list 'muse-custom-tags tag)) + ;; Get option + (when (nth 2 tag-entry) + (setq options (read-string "Option: "))) + (unless (equal options "") + (setq options (concat " " options))) + ;; Insert the tag, closing if necessary + (when tag (insert (concat "<" tag options ">"))) + (when (nth 1 tag-entry) + (insert (concat "\n\n\n")) + (forward-line -2)))) + +;;; Muse list edit minor mode + +(defvar muse-list-edit-minor-mode-map + (let ((map (make-sparse-keymap))) + (define-key map [(meta return)] 'muse-l-e-m-m-insert-list-item) + (define-key map [(control ?>)] 'muse-l-e-m-m-increase-list-item-indent) + (define-key map [(control ?<)] 'muse-l-e-m-m-decrease-list-item-indent) + + map) + "Keymap used by Muse list edit minor mode.") + +(defvar muse-l-e-m-m-list-item-regexp + (concat "^%s\\(\\([^\n" muse-regexp-blank "].*?\\)?::" + "\\(?:[" muse-regexp-blank "]+\\|$\\)" + "\\|[" muse-regexp-blank "]?[-*+][" muse-regexp-blank "]*" + "\\|[" muse-regexp-blank "][0-9]+\\.[" muse-regexp-blank "]*\\)") + "Regexp used to match the beginning of a list item. +This is used by `muse-list-edit-minor-mode'. +The '%s' will be replaced with a whitespace regexp when publishing.") + +(defun muse-l-e-m-m-insert-list-item () + "Insert a list item at the current point, taking into account +your current list type and indentation level." + (interactive) + (let ((muse-list-item-regexp muse-l-e-m-m-list-item-regexp)) + (call-interactively 'muse-insert-list-item))) + +(defun muse-l-e-m-m-increase-list-item-indent () + "Increase the indentation of the current list item." + (interactive) + (let ((muse-list-item-regexp muse-l-e-m-m-list-item-regexp)) + (call-interactively 'muse-increase-list-item-indentation))) + +(defun muse-l-e-m-m-decrease-list-item-indent () + "Decrease the indentation of the current list item." + (interactive) + (let ((muse-list-item-regexp muse-l-e-m-m-list-item-regexp)) + (call-interactively 'muse-decrease-list-item-indentation))) + +(defvar muse-l-e-m-m-data nil + "A list of data that was changed by Muse list edit minor mode.") +(make-variable-buffer-local 'muse-l-e-m-m-data) + +;;;###autoload +(define-minor-mode muse-list-edit-minor-mode + "This is a global minor mode for editing files with lists. +It is meant to be used with other major modes, and not with Muse mode. + +Interactively, with no prefix argument, toggle the mode. +With universal prefix ARG turn mode on. +With zero or negative ARG turn mode off. + +This minor mode provides the Muse keybindings for editing lists, +and support for filling lists properly. + +It recognizes not only Muse-style lists, which use the \"-\" +character or numbers, but also lists that use asterisks or plus +signs. This should make the minor mode generally useful. + +Definition lists and footnotes are also recognized. + +Note that list items may omit leading spaces, for compatibility +with modes that set `left-margin', such as +`debian-changelog-mode'. + +\\{muse-list-edit-minor-mode-map}" + :init-value nil + :lighter "" + :keymap muse-list-edit-minor-mode-map + :global nil + :group 'muse-mode + (if (not muse-list-edit-minor-mode) + ;; deactivate + (when muse-l-e-m-m-data + (setq adaptive-fill-regexp (cdr (assoc "a-f-r" muse-l-e-m-m-data)) + paragraph-start (cdr (assoc "p-s" muse-l-e-m-m-data)) + fill-prefix (cdr (assoc "f-p" muse-l-e-m-m-data))) + (setq muse-l-e-m-m-data nil)) + ;; activate + (unless muse-l-e-m-m-data + ;; save previous fill-related data so we can restore it later + (setq muse-l-e-m-m-data + (list (cons "a-f-r" adaptive-fill-regexp) + (cons "p-s" paragraph-start) + (cons "f-p" fill-prefix)))) + ;; make fill work nicely with item lists + (let ((regexp (concat "\\s-*\\([-*+]\\|[0-9]+\\.\\)\\s-+" + "\\|\\[[0-9]+\\]\\s-*" + "\\|.*\\s-*::\\s-+"))) + (set (make-local-variable 'adaptive-fill-regexp) + (concat regexp "\\|\\s-*")) + (set (make-local-variable 'paragraph-start) + (concat paragraph-start "\\|" regexp))) + ;; force fill-prefix to be nil, because if it is a string that has + ;; initial spaces, it messes up fill-paragraph's algorithm + (set (make-local-variable 'fill-prefix) nil))) + +(defun turn-on-muse-list-edit-minor-mode () + "Unconditionally turn on Muse list edit minor mode." + (muse-list-edit-minor-mode 1)) + +(defun turn-off-muse-list-edit-minor-mode () + "Unconditionally turn off Muse list edit minor mode." + (muse-list-edit-minor-mode -1)) + +;;; muse-mode.el ends here diff --git a/elpa/muse-3.20/muse-pkg.el b/elpa/muse-3.20/muse-pkg.el new file mode 100644 index 0000000..6ff6560 --- /dev/null +++ b/elpa/muse-3.20/muse-pkg.el @@ -0,0 +1,2 @@ +(define-package "muse" "3.20" + "Authoring and publishing tool") diff --git a/elpa/muse-3.20/muse-poem.el b/elpa/muse-3.20/muse-poem.el new file mode 100644 index 0000000..bd08b7e --- /dev/null +++ b/elpa/muse-3.20/muse-poem.el @@ -0,0 +1,263 @@ +;;; muse-poem.el --- publish a poem to LaTex or PDF + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; This file specifies a form for recording poetry. It is as follows. +;; +;; Title +;; +;; +;; Body of poem +;; +;; +;; Annotations, history, notes, etc. +;; +;; The `muse-poem' module makes it easy to attractively publish and +;; reference poems in this format, using the "memoir" module for LaTeX +;; publishing. It will also markup poems for every other output +;; style, though none are nearly as pretty. +;; +;; Once a poem is written in this format, just publish it to PDF using +;; the "poem-pdf" style. To make an inlined reference to a poem that +;; you've written -- for example, from a blog page -- there is a +;; "poem" tag defined by this module: +;; +;; +;; +;; Let's assume the template above was called "name.of.poem.page"; +;; then the above tag would result in this inclusion: +;; +;; ** Title +;; +;; > Body of poem +;; +;; I use this module for publishing all of the poems on my website, +;; which are at: http://www.newartisans.com/johnw/poems.html. + +;;; Contributors: + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse Poem Publishing +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'muse-latex) +(require 'muse-project) + +(defgroup muse-poem nil + "Rules for marking up a Muse file as a LaTeX article." + :group 'muse-latex) + +(defcustom muse-poem-latex-header + "\\documentclass[14pt,oneside]{memoir} + +\\usepackage[english]{babel} +\\usepackage[latin1]{inputenc} +\\usepackage[T1]{fontenc} + +\\setlength{\\beforepoemtitleskip}{-5.0ex} + +\\begin{document} + +\\pagestyle{empty} + +\\renewcommand{\\poemtoc}{section} +\\settocdepth{section} + +\\mbox{} +\\vfill + +\\poemtitle{(muse-publishing-directive \"title\")} + +\\settowidth{\\versewidth}{muse-poem-longest-line}\n\n" + "Header used for publishing LaTeX poems. This may be text or a filename." + :type 'string + :group 'muse-poem) + +(defcustom muse-poem-latex-footer "\n\\vfill +\\mbox{} + +\\end{document}" + "Footer used for publishing LaTeX files. This may be text or a filename." + :type 'string + :group 'muse-poem) + +(defcustom muse-poem-markup-strings + '((begin-verse . "\\begin{verse}[\\versewidth]\n") + (verse-space . "\\vin ")) + "Strings used for marking up poems. +These cover the most basic kinds of markup, the handling of which +differs little between the various styles." + :type '(alist :key-type symbol :value-type string) + :group 'muse-poem) + +(defcustom muse-chapbook-latex-header + "\\documentclass{book} + +\\usepackage[english]{babel} +\\usepackage[latin1]{inputenc} +\\usepackage[T1]{fontenc} + +\\setlength{\\beforepoemtitleskip}{-5.0ex} + +\\begin{document} + +\\title{(muse-publishing-directive \"title\")} +\\author{(muse-publishing-directive \"author\")} +\\date{(muse-publishing-directive \"date\")} + +\\maketitle + +\\tableofcontents + +\\renewcommand{\\poemtoc}{section} +\\settocdepth{section}\n" + "Header used for publishing a book of poems in LaTeX form. +This may be text or a filename." + :type 'string + :group 'muse-poem) + +(defcustom muse-chapbook-latex-footer "\n\\end{document}" + "Footer used for publishing a book of poems in LaTeX form. +This may be text or a filename." + :type 'string + :group 'muse-poem) + +(defvar muse-poem-longest-line "") + +(defcustom muse-poem-chapbook-strings + '((begin-verse . "\\newpage +\\mbox{} +\\vfill + +\\poemtitle{(muse-publishing-directive \"title\")} + +\\settowidth{\\versewidth}{muse-poem-longest-line} + +\\begin{verse}[\\versewidth]\n") + (end-verse . "\n\\end{verse}\n\\vfill\n\\mbox{}") + (verse-space . "\\vin ")) + "Strings used for marking up books of poems. +These cover the most basic kinds of markup, the handling of which +differs little between the various styles." + :type '(alist :key-type symbol :value-type string) + :group 'muse-poem) + +(defun muse-poem-prepare-buffer () + (goto-char (point-min)) + (insert "#title ") + (forward-line 1) + (delete-region (point) (1+ (muse-line-end-position))) + (insert "\n") + (let ((beg (point)) end line) + (if (search-forward "\n\n\n" nil t) + (progn + (setq end (copy-marker (match-beginning 0) t)) + (replace-match "\n\n") + (delete-region (point) (point-max))) + (goto-char (point-max)) + (setq end (point)) + (insert "\n")) + (goto-char (1+ beg)) + (set (make-local-variable 'muse-poem-longest-line) "") + (while (< (point) end) + (setq line (buffer-substring-no-properties (point) + (muse-line-end-position))) + (if (> (length line) (length muse-poem-longest-line)) + (setq muse-poem-longest-line line)) + (forward-line 1)) + nil)) + +(defvar muse-poem-tag '("poem" nil t nil muse-poem-markup-tag)) + +(defun muse-poem-markup-tag (beg end attrs) + "This markup tag allows a poem to be included from another project page. +The form of usage is: + " + (let ((page (cdr (assoc (cdr (assoc "title" attrs)) + (muse-project-file-alist)))) + beg end) + (if (null page) + (insert " *Reference to\n unknown poem \"" + (cdr (assoc "title" attrs)) "\".*\n") + (setq beg (point)) + (insert + (muse-with-temp-buffer + (muse-insert-file-contents page) + (goto-char (point-min)) + (if (assoc "nohead" attrs) + (progn + (forward-line 3) + (delete-region (point-min) (point))) + (insert "** ") + (search-forward "\n\n\n") + (replace-match "\n\n")) + (if (search-forward "\n\n\n" nil t) + (setq end (match-beginning 0)) + (setq end (point-max))) + (buffer-substring-no-properties (point-min) end))) + (setq end (point-marker)) + (goto-char beg) + (unless (assoc "nohead" attrs) + (forward-line 2)) + (while (< (point) end) + (insert "> ") + (forward-line 1)) + (set-marker end nil)))) + +(put 'muse-poem-markup-tag 'muse-dangerous-tag t) + +(add-to-list 'muse-publish-markup-tags muse-poem-tag) + +;;; Register the Muse POEM Publishers + +(muse-derive-style "poem-latex" "latex" + :before 'muse-poem-prepare-buffer + :strings 'muse-poem-markup-strings + :header 'muse-poem-latex-header + :footer 'muse-poem-latex-footer) + +(muse-derive-style "poem-pdf" "pdf" + :before 'muse-poem-prepare-buffer + :strings 'muse-poem-markup-strings + :header 'muse-poem-latex-header + :footer 'muse-poem-latex-footer) + +(muse-derive-style "chapbook-latex" "latex" + :before 'muse-poem-prepare-buffer + :strings 'muse-poem-chapbook-strings + :header 'muse-chapbook-latex-header + :footer 'muse-chapbook-latex-footer) + +(muse-derive-style "chapbook-pdf" "pdf" + :before 'muse-poem-prepare-buffer + :strings 'muse-poem-chapbook-strings + :header 'muse-chapbook-latex-header + :footer 'muse-chapbook-latex-footer) + +(provide 'muse-poem) + +;;; muse-poem.el ends here diff --git a/elpa/muse-3.20/muse-project.el b/elpa/muse-3.20/muse-project.el new file mode 100644 index 0000000..7489706 --- /dev/null +++ b/elpa/muse-3.20/muse-project.el @@ -0,0 +1,973 @@ +;;; muse-project.el --- handle Muse projects + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Contributors: + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse Project Maintainance +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'muse-project) + +(require 'muse) +(require 'muse-publish) +(require 'cus-edit) + +(defgroup muse-project nil + "Options controlling the behavior of Muse project handling." + :group 'muse) + +(defcustom muse-before-project-publish-hook nil + "A hook run before a project is published. +Each function is passed the project object, a cons with the format + (PROJNAME . SETTINGS)" + :type 'hook + :group 'muse-project) + +(defcustom muse-after-project-publish-hook nil + "A hook run after a project is published. +Each function is passed the project object, a cons with the format + (PROJNAME . SETTINGS)" + :type 'hook + :group 'muse-project) + +(defvar muse-project-alist-using-customize nil + "Used internally by Muse to indicate whether `muse-project-alist' +has been modified via the customize interface.") +(make-variable-buffer-local 'muse-project-alist-using-customize) + +(defmacro with-muse-project (project &rest body) + `(progn + (unless (muse-project ,project) + (error "Can't find project %s" ,project)) + (with-temp-buffer + (muse-mode) + (setq muse-current-project (muse-project ,project)) + (muse-project-set-variables) + ,@body))) + +(put 'with-muse-project 'lisp-indent-function 0) +(put 'with-muse-project 'edebug-form-spec '(sexp body)) + +(defun muse-project-alist-get (sym) + "Turn `muse-project-alist' into something we can customize easily." + (when (boundp sym) + (setq muse-project-alist-using-customize t) + (let* ((val (copy-alist (symbol-value sym))) + (head val)) + (while val + (let ((head (car (cdar val))) + res) + ;; Turn settings of first part into cons cells, symbol->string + (while head + (cond ((stringp (car head)) + (add-to-list 'res (car head) t) + (setq head (cdr head))) + ((symbolp (car head)) + (add-to-list 'res (list (symbol-name (car head)) + (cadr head)) t) + (setq head (cddr head))) + (t + (setq head (cdr head))))) + (setcdr (car val) (cons res (cdr (cdar val))))) + (let ((styles (cdar val))) + ;; Symbol->string in every style + (while (cdr styles) + (let ((head (cadr styles)) + res) + (while (consp head) + (setq res (plist-put res (symbol-name (car head)) + (cadr head))) + (setq head (cddr head))) + (setcdr styles (cons res (cddr styles)))) + (setq styles (cdr styles)))) + (setq val (cdr val))) + head))) + +(defun muse-project-alist-set (sym val) + "Turn customized version of `muse-project-alist' into something +Muse can make use of." + (set sym val) + (when muse-project-alist-using-customize + ;; Make sure the unescaped version is written to .emacs + (put sym 'saved-value (list (custom-quote val))) + ;; Perform unescaping + (while val + (let ((head (car (cdar val))) + res) + ;; Turn cons cells into flat list, string->symbol + (while head + (cond ((stringp (car head)) + (add-to-list 'res (car head) t)) + ((consp (car head)) + (add-to-list 'res (intern (caar head)) t) + (add-to-list 'res (car (cdar head)) t))) + (setq head (cdr head))) + (setcdr (car val) (cons res (cdr (cdar val))))) + (let ((styles (cdar val))) + ;; String->symbol in every style + (while (cdr styles) + (let ((head (cadr styles)) + res) + (while (consp head) + (setq res (plist-put res (intern (car head)) + (cadr head))) + (setq head (cddr head))) + (setcdr styles (cons res (cddr styles)))) + (setq styles (cdr styles)))) + (setq val (cdr val))))) + +(define-widget 'muse-project 'default + "A widget that defines a Muse project." + :format "\n%v" + :value-create 'muse-widget-type-value-create + :value-get 'muse-widget-child-value-get + :value-delete 'ignore + :match 'muse-widget-type-match + :type '(cons :format " %v" + (repeat :tag "Settings" :format "%{%t%}:\n%v%i\n\n" + (choice + (string :tag "Directory") + (list :tag "Book function" + (const :tag ":book-funcall" ":book-funcall") + (choice (function) + (sexp :tag "Unknown"))) + (list :tag "Book part" + (const :tag ":book-part" ":book-part") + (string :tag "Name")) + (list :tag "Book style" + (const :tag ":book-style" ":book-style") + (string :tag "Style")) + (list :tag "Default file" + (const :tag ":default" ":default") + (string :tag "File")) + (list :tag "End of book" + (const :tag ":book-end" ":book-end") + (const t)) + (list :tag "Force publishing" + (const :tag ":force-publish" ":force-publish") + (repeat (string :tag "File"))) + (list :tag "Major mode" + (const :tag ":major-mode" ":major-mode") + (choice (function :tag "Mode") + (sexp :tag "Unknown"))) + (list :tag "New chapter" + (const :tag ":book-chapter" ":book-chapter") + (string :tag "Name")) + (list :tag "No chapters" + (const :tag ":nochapters" ":nochapters") + (const t)) + (list :tag "Project-level publishing function" + (const :tag ":publish-project" + ":publish-project") + (choice (function :tag "Function") + (sexp :tag "Unknown"))) + (list :tag "Set variables" + (const :tag ":set" ":set") + (repeat (list :inline t + (symbol :tag "Variable") + (sexp :tag "Setting")))) + (list :tag "Visit links using" + (const :tag ":visit-link" ":visit-link") + (choice (function) + (sexp :tag "Unknown"))))) + (repeat :tag "Output styles" :format "%{%t%}:\n%v%i\n\n" + (set :tag "Style" + (list :inline t + :tag "Publishing style" + (const :tag ":base" ":base") + (string :tag "Style")) + (list :inline t + :tag "Base URL" + (const :tag ":base-url" ":base-url") + (string :tag "URL")) + (list :inline t + :tag "Exclude matching" + (const :tag ":exclude" ":exclude") + (regexp)) + (list :inline t + :tag "Include matching" + (const :tag ":include" ":include") + (regexp)) + (list :inline t + :tag "Timestamps file" + (const :tag ":timestamps" ":timestamps") + (file)) + (list :inline t + :tag "Path" + (const :tag ":path" ":path") + (string :tag "Path")))))) + +(defcustom muse-project-alist nil + "An alist of Muse projects. +A project defines a fileset, and a list of custom attributes for use +when publishing files in that project." + :type '(choice (const :tag "No projects defined." nil) + (repeat (cons :format "%{%t%}:\n\n%v" + :tag "Project" :indent 4 + (string :tag "Project name") + muse-project)) + (sexp :tag "Cannot parse expression")) + :get 'muse-project-alist-get + :set 'muse-project-alist-set + :group 'muse-project) + +;; Make it easier to specify a muse-project-alist entry + +(defcustom muse-project-ignore-regexp + (concat "\\`\\(#.*#\\|.*,v\\|.*~\\|\\.\\.?\\|\\.#.*\\|,.*\\)\\'\\|" + "/\\(CVS\\|RCS\\|\\.arch-ids\\|{arch}\\|,.*\\|\\.svn\\|" + "\\.hg\\|\\.git\\|\\.bzr\\|_darcs\\)\\(/\\|\\'\\)") + "A regexp matching files to be ignored in Muse directories. + +You should set `case-fold-search' to nil before using this regexp +in code." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-project-publish-private-files t + "If this is non-nil, files will be published even if their permissions +are set so that no one else on the filesystem can read them. + +Set this to nil if you would like to indicate that some files +should not be published by manually doing \"chmod o-rwx\" on +them. + +This setting has no effect under Windows (that is, all files are +published regardless of permissions) because Windows lacks the +needed filesystem attributes." + :type 'boolean + :group 'muse-project) + +(defun muse-project-recurse-directory (base) + "Recusively retrieve all of the directories underneath BASE. +A list of these directories is returned. + +Directories starting with \".\" will be ignored, as well as those +which match `muse-project-ignore-regexp'." + (let ((case-fold-search nil) + list dir) + (when (and (file-directory-p base) + (not (string-match muse-project-ignore-regexp base))) + (dolist (file (directory-files base t "^[^.]")) + (when (and (file-directory-p file) + (not (string-match muse-project-ignore-regexp file))) + (setq dir (file-name-nondirectory file)) + (push dir list) + (nconc list (mapcar #'(lambda (item) + (concat dir "/" item)) + (muse-project-recurse-directory file))))) + list))) + +(defun muse-project-alist-styles (entry-dir output-dir style &rest other) + "Return a list of styles to use in a `muse-project-alist' entry. +ENTRY-DIR is the top-level directory of the project. +OUTPUT-DIR is where Muse files are published, keeping directory structure. +STYLE is the publishing style to use. + +OTHER contains other definitions to add to each style. It is optional. + +For an example of the use of this function, see +`examples/mwolson/muse-init.el' from the Muse distribution." + (let ((fnd (file-name-nondirectory entry-dir))) + (when (string= fnd "") + ;; deal with cases like "foo/" that have a trailing slash + (setq fnd (file-name-nondirectory (substring entry-dir 0 -1)))) + (cons `(:base ,style :path ,(if (muse-file-remote-p output-dir) + output-dir + (expand-file-name output-dir)) + :include ,(concat "/" fnd "/[^/]+$") + ,@other) + (mapcar (lambda (dir) + `(:base ,style + :path ,(expand-file-name dir output-dir) + :include ,(concat "/" dir "/[^/]+$") + ,@other)) + (muse-project-recurse-directory entry-dir))))) + +(defun muse-project-alist-dirs (entry-dir) + "Return a list of directories to use in a `muse-project-alist' entry. +ENTRY-DIR is the top-level directory of the project. + +For an example of the use of this function, see +`examples/mwolson/muse-init.el' from the Muse distribution." + (cons (expand-file-name entry-dir) + (mapcar (lambda (dir) (expand-file-name dir entry-dir)) + (muse-project-recurse-directory entry-dir)))) + +;; Constructing the file-alist + +(defvar muse-project-file-alist nil + "This variable is automagically constructed as needed.") + +(defvar muse-project-file-alist-hook nil + "Functions that are to be exectuted immediately after updating +`muse-project-file-alist'.") + +(defvar muse-current-project nil + "Project we are currently visiting.") +(make-variable-buffer-local 'muse-current-project) +(defvar muse-current-project-global nil + "Project we are currently visiting. This is used to propagate the value +of `muse-current-project' into a new buffer during publishing.") + +(defvar muse-current-output-style nil + "The output style that we are currently using for publishing files.") + +(defsubst muse-project (&optional project) + "Resolve the given PROJECT into a full Muse project, if it is a string." + (if (null project) + (or muse-current-project + (muse-project-of-file)) + (if (stringp project) + (assoc project muse-project-alist) + (muse-assert (consp project)) + project))) + +(defun muse-project-page-file (page project &optional no-check-p) + "Return a filename if PAGE exists within the given Muse PROJECT." + (setq project (muse-project project)) + (if (null page) + ;; if not given a page, return the first directory instead + (let ((pats (cadr project))) + (catch 'done + (while pats + (if (symbolp (car pats)) + (setq pats (cddr pats)) + (throw 'done (file-name-as-directory (car pats))))))) + (let ((dir (file-name-directory page)) + (expanded-path nil)) + (when dir + (setq expanded-path (concat (expand-file-name + page + (file-name-directory (muse-current-file))) + (when muse-file-extension + (concat "." muse-file-extension)))) + (setq page (file-name-nondirectory page))) + (let ((files (muse-collect-alist + (muse-project-file-alist project no-check-p) + page)) + (matches nil)) + (if dir + (catch 'done + (save-match-data + (dolist (file files) + (if (and expanded-path + (string= expanded-path (cdr file))) + (throw 'done (cdr file)) + (let ((pos (string-match (concat (regexp-quote dir) "\\'") + (file-name-directory + (cdr file))))) + (when pos + (setq matches (cons (cons pos (cdr file)) + matches))))))) + ;; if we haven't found an exact match, pick a candidate + (car (muse-sort-by-rating matches))) + (dolist (file files) + (setq matches (cons (cons (length (cdr file)) (cdr file)) + matches))) + (car (muse-sort-by-rating matches '<))))))) + +(defun muse-project-private-p (file) + "Return non-nil if NAME is a private page with PROJECT." + (unless (or muse-under-windows-p + muse-project-publish-private-files) + (setq file (file-truename file)) + (if (file-attributes file) ; don't publish if no attributes exist + (or (when (eq ?- (aref (nth 8 (file-attributes + (file-name-directory file))) 7)) + (message (concat + "The " (file-name-directory file) + " directory must be readable by others" + " in order for its contents to be published."))) + (eq ?- (aref (nth 8 (file-attributes file)) 7))) + t))) + +(defun muse-project-file-entries (path) + (let* ((names (list t)) + (lnames names) + (case-fold-search nil)) + (cond + ((file-directory-p path) + (dolist (file (directory-files + path t (when (and muse-file-extension + (not (string= muse-file-extension ""))) + (concat "." muse-file-extension "\\'")))) + (unless (or (string-match muse-project-ignore-regexp file) + (string-match muse-project-ignore-regexp + (file-name-nondirectory file)) + (file-directory-p file)) + (setcdr lnames + (cons (cons (muse-page-name file) file) nil)) + (setq lnames (cdr lnames))))) + ((file-readable-p path) + (setcdr lnames + (cons (cons (muse-page-name path) path) nil)) + (setq lnames (cdr lnames))) + (t ; regexp + (muse-assert (file-name-directory path)) + (dolist (file (directory-files + (file-name-directory path) t + (file-name-nondirectory path))) + (unless (or (string-match muse-project-ignore-regexp file) + (string-match muse-project-ignore-regexp + (file-name-nondirectory file))) + (setcdr lnames + (cons (cons (muse-page-name file) file) nil)) + (setq lnames (cdr lnames)))))) + (cdr names))) + +(defvar muse-updating-file-alist-p nil + "Make sure that recursive calls to `muse-project-file-alist' are bounded.") + +(defun muse-project-determine-last-mod (project &optional no-check-p) + "Return the most recent last-modified timestamp of dirs in PROJECT." + (let ((last-mod nil)) + (unless (or muse-under-windows-p no-check-p) + (let ((pats (cadr project))) + (while pats + (if (symbolp (car pats)) + (setq pats (cddr pats)) + (let* ((fnd (file-name-directory (car pats))) + (dir (cond ((file-directory-p (car pats)) + (car pats)) + ((and (not (file-readable-p (car pats))) + fnd + (file-directory-p fnd)) + fnd)))) + (when dir + (let ((mod-time (nth 5 (file-attributes dir)))) + (when (or (null last-mod) + (and mod-time + (muse-time-less-p last-mod mod-time))) + (setq last-mod mod-time))))) + (setq pats (cdr pats)))))) + last-mod)) + +(defun muse-project-file-alist (&optional project no-check-p) + "Return member filenames for the given Muse PROJECT. +Also, update the `muse-project-file-alist' variable. + +On UNIX, this alist is only updated if one of the directories' +contents have changed. On Windows, it is always reread from +disk. + +If NO-CHECK-P is non-nil, do not update the alist, just return +the current one." + (setq project (muse-project project)) + (when (and project muse-project-alist) + (let* ((file-alist (assoc (car project) muse-project-file-alist)) + (last-mod (muse-project-determine-last-mod project no-check-p))) + ;; Either return the currently known list, or read it again from + ;; disk + (if (or (and no-check-p (cadr file-alist)) + muse-updating-file-alist-p + (not (or muse-under-windows-p + (null (cddr file-alist)) + (null last-mod) + (muse-time-less-p (cddr file-alist) last-mod)))) + (cadr file-alist) + (if file-alist + (setcdr (cdr file-alist) last-mod) + (setq file-alist (cons (car project) (cons nil last-mod)) + muse-project-file-alist + (cons file-alist muse-project-file-alist))) + ;; Read in all of the file entries + (let ((muse-updating-file-alist-p t)) + (prog1 + (save-match-data + (setcar + (cdr file-alist) + (let* ((names (list t)) + (pats (cadr project))) + (while pats + (if (symbolp (car pats)) + (setq pats (cddr pats)) + (nconc names (muse-project-file-entries (car pats))) + (setq pats (cdr pats)))) + (cdr names)))) + (run-hooks 'muse-project-file-alist-hook))))))) + +(defun muse-project-add-to-alist (file &optional project) + "Make sure FILE is added to `muse-project-file-alist'. + +It works by either calling the `muse-project-file-alist' function +if a directory has been modified since we last checked, or +manually forcing the file entry to exist in the alist. This +works around an issue where if several files being saved at the +same time, only the first one will make it into the alist. It is +meant to be called by `muse-project-after-save-hook'. + +The project of the file is determined by either the PROJECT +argument, or `muse-project-of-file' if PROJECT is not specified." + (setq project (or (muse-project project) (muse-project-of-file file))) + (when (and project muse-project-alist) + (let* ((file-alist (assoc (car project) muse-project-file-alist)) + (last-mod (muse-project-determine-last-mod project))) + ;; Determine whether we need to call this + (if (or (null (cddr file-alist)) + (null last-mod) + (muse-time-less-p (cddr file-alist) last-mod)) + ;; The directory will show up as modified, so go ahead and + ;; call `muse-project-file-alist' + (muse-project-file-alist project) + ;; It is not showing as modified, so forcefully add the + ;; current file to the project file-alist + (let ((muse-updating-file-alist-p t)) + (prog1 + (save-match-data + (setcar (cdr file-alist) + (nconc (muse-project-file-entries file) + (cadr file-alist)))) + (run-hooks 'muse-project-file-alist-hook))))))) + +(defun muse-project-of-file (&optional pathname) + "Determine which project the given PATHNAME relates to. +If PATHNAME is nil, the current buffer's filename is used." + (if (and (null pathname) muse-current-project) + muse-current-project + (unless pathname (setq pathname (muse-current-file))) + (save-match-data + (when (and (stringp pathname) + muse-project-alist + (not (string= pathname "")) + (not (let ((case-fold-search nil)) + (or (string-match muse-project-ignore-regexp + pathname) + (string-match muse-project-ignore-regexp + (file-name-nondirectory + pathname)))))) + (let* ((file (file-truename pathname)) + (dir (file-name-directory file)) + found rating matches) + (catch 'found + (dolist (project-entry muse-project-alist) + (let ((pats (cadr project-entry))) + (while pats + (if (symbolp (car pats)) + (setq pats (cddr pats)) + (let ((tname (file-truename (car pats)))) + (cond ((or (string= tname file) + (string= (file-name-as-directory tname) dir)) + (throw 'found project-entry)) + ((string-match (concat "\\`" (regexp-quote tname)) + file) + (setq matches (cons (cons (match-end 0) + project-entry) + matches))))) + (setq pats (cdr pats)))))) + ;; if we haven't found an exact match, pick a candidate + (car (muse-sort-by-rating matches)))))))) + +(defun muse-project-after-save-hook () + "Update Muse's file-alist if we are saving a Muse file." + (let ((project (muse-project-of-file))) + (when project + (muse-project-add-to-alist (buffer-file-name) project)))) + +(add-hook 'after-save-hook 'muse-project-after-save-hook) + +(defun muse-read-project (prompt &optional no-check-p no-assume) + "Read a project name from the minibuffer, if it can't be figured + out." + (if (null muse-project-alist) + (error "There are no Muse projects defined; see `muse-project-alist'") + (or (unless no-check-p + (muse-project-of-file)) + (if (and (not no-assume) + (= 1 (length muse-project-alist))) + (car muse-project-alist) + (assoc (funcall muse-completing-read-function + prompt muse-project-alist) + muse-project-alist))))) + +(defvar muse-project-page-history nil) + +(defun muse-read-project-file (project prompt &optional default) + (let* ((file-list (muse-delete-dups + (mapcar #'(lambda (a) (list (car a))) + (muse-project-file-alist project)))) + (name (funcall muse-completing-read-function + prompt file-list nil nil nil + 'muse-project-page-history default))) + (cons name (muse-project-page-file name project)))) + +;;;###autoload +(defun muse-project-find-file (name project &optional command directory) + "Open the Muse page given by NAME in PROJECT. +If COMMAND is non-nil, it is the function used to visit the file. +If DIRECTORY is non-nil, it is the directory in which the page +will be created if it does not already exist. Otherwise, the +first directory within the project's fileset is used." + (interactive + (let* ((project (muse-read-project "Find in project: " + current-prefix-arg)) + (default (muse-get-keyword :default (cadr project))) + (entry (muse-read-project-file + project (if default + (format "Find page: (default: %s) " + default) + "Find page: ") + default))) + (list entry project))) + (setq project (muse-project project)) + (let ((project-name (car project))) + (unless (interactive-p) + (setq project (muse-project project) + name (cons name (muse-project-page-file name project)))) + ;; If we're given a relative or absolute filename, open it as-is + (if (and (car name) + (save-match-data + (or (string-match "\\`\\.+/" (car name)) + (string-match muse-file-regexp (car name)) + (string-match muse-image-regexp (car name))))) + (setcdr name (car name)) + ;; At this point, name is (PAGE . FILE). + (unless (cdr name) + (let ((pats (cadr project))) + (while (and pats (null directory)) + (if (symbolp (car pats)) + (setq pats (cddr pats)) + (if (file-directory-p (car pats)) + (setq directory (car pats) pats nil) + (setq pats (cdr pats)))))) + (when directory + (let ((filename (expand-file-name (car name) directory))) + (when (and muse-file-extension + (not (string= muse-file-extension "")) + (not (file-exists-p (car name)))) + (setq filename (concat filename "." muse-file-extension))) + (unless (file-exists-p directory) + (make-directory directory t)) + (setcdr name filename))))) + ;; Open the file + (if (cdr name) + (funcall (or command 'find-file) (cdr name)) + (error "There is no page %s in project %s" + (car name) project-name)))) + +(defun muse-project-choose-style (closure test styles) + "Run TEST on STYLES and return first style where TEST yields non-nil. +TEST should take two arguments. The first is CLOSURE, which is +passed verbatim. The second if the current style to consider. + +If no style passes TEST, return the first style." + (or (catch 'winner + (dolist (style styles) + (when (funcall test closure style) + (throw 'winner style)))) + (car styles))) + +(defun muse-project-choose-style-by-link-suffix (given-suffix style) + "If the given STYLE has a link-suffix that equals GIVEN-SUFFIX, +return non-nil." + (let ((link-suffix (or (muse-style-element :link-suffix style) + (muse-style-element :suffix style)))) + (and (stringp link-suffix) + (string= given-suffix link-suffix)))) + +(defun muse-project-applicable-styles (file styles) + "Given STYLES, return a list of the ones that are considered for FILE. +The name of a project may be used for STYLES." + (when (stringp styles) + (setq styles (cddr (muse-project styles)))) + (when (and file styles) + (let ((used-styles nil)) + (dolist (style styles) + (let ((include-regexp (muse-style-element :include style)) + (exclude-regexp (muse-style-element :exclude style)) + (rating nil)) + (when (and (or (and (null include-regexp) + (null exclude-regexp)) + (if include-regexp + (setq rating (string-match include-regexp file)) + (not (string-match exclude-regexp file)))) + (file-exists-p file) + (not (muse-project-private-p file))) + (setq used-styles (cons (cons rating style) used-styles))))) + (muse-sort-by-rating (nreverse used-styles))))) + +(defun muse-project-get-applicable-style (file styles) + "Choose a style from the STYLES that FILE can publish to. +The user is prompted if several styles are found." + (muse-publish-get-style + (mapcar (lambda (style) + (cons (muse-get-keyword :base style) style)) + (muse-project-applicable-styles file styles)))) + +(defun muse-project-resolve-directory (page local-style remote-style) + "Figure out the directory part of the path that provides a link to PAGE. +LOCAL-STYLE is the style of the current Muse file, and +REMOTE-STYLE is the style associated with PAGE. + +If REMOTE-STYLE has a :base-url element, concatenate it and PAGE. +Otherwise, return a relative link." + (let ((prefix (muse-style-element :base-url remote-style))) + (if prefix + (concat prefix page) + (file-relative-name (expand-file-name + (file-name-nondirectory page) + (muse-style-element :path remote-style)) + (expand-file-name + (muse-style-element :path local-style)))))) + +(defun muse-project-resolve-link (page local-style remote-styles) + "Return a published link from the output path of one file to another file. + +The best match for PAGE is determined by comparing the link +suffix of the given local style and that of the remote styles. + +The remote styles are usually populated by +`muse-project-applicable-styles'. + +If no remote style is found, return PAGE verbatim + +If PAGE has a :base-url associated with it, return the +concatenation of the :base-url value and PAGE. + +Otherwise, return a relative path from the directory of +LOCAL-STYLE to the best directory among REMOTE-STYLES." + (let ((link-suffix (or (muse-style-element :link-suffix local-style) + (muse-style-element :suffix local-style))) + remote-style) + (if (not (stringp link-suffix)) + (setq remote-style (car remote-styles)) + (setq remote-style (muse-project-choose-style + link-suffix + #'muse-project-choose-style-by-link-suffix + remote-styles))) + (if (null remote-style) + page + (setq page (muse-project-resolve-directory + page local-style remote-style)) + (concat (file-name-directory page) + (muse-publish-link-name page remote-style))))) + +(defun muse-project-current-output-style (&optional file project) + (or muse-current-output-style + (progn + (unless file (setq file (muse-current-file))) + (unless project (setq project (muse-project-of-file file))) + (car (muse-project-applicable-styles file (cddr project)))))) + +(defun muse-project-link-page (page) + (let ((project (muse-project-of-file))) + (muse-project-resolve-link page + (muse-project-current-output-style) + (muse-project-applicable-styles + (muse-project-page-file page project) + (cddr project))))) + +(defun muse-project-publish-file-default (file style output-dir force) + ;; ensure the publishing location is available + (unless (file-exists-p output-dir) + (message "Creating publishing directory %s" output-dir) + (make-directory output-dir t)) + ;; publish the member file! + (muse-publish-file file style output-dir force)) + +(defun muse-project-publish-file (file styles &optional force) + (setq styles (muse-project-applicable-styles file styles)) + (let (published) + (dolist (style styles) + (if (or (not (listp style)) + (not (cdr style))) + (muse-display-warning + (concat "Skipping malformed muse-project-alist style." + "\nPlease double-check your configuration,")) + (let ((output-dir (muse-style-element :path style)) + (muse-current-output-style style) + (fun (or (muse-style-element :publish style t) + 'muse-project-publish-file-default))) + (when (funcall fun file style output-dir force) + (setq published t))))) + published)) + +;;;###autoload +(defun muse-project-publish-this-file (&optional force style) + "Publish the currently-visited file according to `muse-project-alist', +prompting if more than one style applies. + +If FORCE is given, publish the file even if it is up-to-date. + +If STYLE is given, use that publishing style rather than +prompting for one." + (interactive (list current-prefix-arg)) + (let ((muse-current-project (muse-project-of-file))) + (if (not muse-current-project) + ;; file is not part of a project, so fall back to muse-publish + (if (interactive-p) (call-interactively 'muse-publish-this-file) + (muse-publish-this-file style nil force)) + (unless style + (setq style (muse-project-get-applicable-style + buffer-file-name (cddr muse-current-project)))) + (let* ((output-dir (muse-style-element :path style)) + (muse-current-project-global muse-current-project) + (muse-current-output-style (list :base (car style) + :path output-dir)) + (fun (or (muse-style-element :publish style t) + 'muse-project-publish-file-default))) + (unless (funcall fun buffer-file-name style output-dir force) + (message (concat "The published version is up-to-date; use" + " C-u C-c C-t to force an update."))))))) + +(defun muse-project-save-buffers (&optional project) + (setq project (muse-project project)) + (when project + (save-excursion + (map-y-or-n-p + (function + (lambda (buffer) + (and (buffer-modified-p buffer) + (not (buffer-base-buffer buffer)) + (or (buffer-file-name buffer) + (progn + (set-buffer buffer) + (and buffer-offer-save + (> (buffer-size) 0)))) + (with-current-buffer buffer + (let ((proj (muse-project-of-file))) + (and proj (string= (car proj) + (car project))))) + (if (buffer-file-name buffer) + (format "Save file %s? " + (buffer-file-name buffer)) + (format "Save buffer %s? " + (buffer-name buffer)))))) + (function + (lambda (buffer) + (set-buffer buffer) + (save-buffer))) + (buffer-list) + '("buffer" "buffers" "save") + (if (boundp 'save-some-buffers-action-alist) + save-some-buffers-action-alist))))) + +(defun muse-project-publish-default (project styles &optional force) + "Publish the pages of PROJECT that need publishing." + (setq project (muse-project project)) + (let ((published nil)) + ;; publish all files in the project, for each style; the actual + ;; publishing will only happen if the files are newer than the + ;; last published output, or if the file is listed in + ;; :force-publish. Files in :force-publish will not trigger the + ;; "All pages need to be published" message. + (let ((forced-files (muse-get-keyword :force-publish (cadr project))) + (file-alist (muse-project-file-alist project))) + (dolist (pair file-alist) + (when (muse-project-publish-file (cdr pair) styles force) + (setq forced-files (delete (car pair) forced-files)) + (setq published t))) + (dolist (file forced-files) + (muse-project-publish-file (cdr (assoc file file-alist)) styles t))) + ;; run hook after publishing ends + (run-hook-with-args 'muse-after-project-publish-hook project) + ;; notify the user that everything is now done + (if published + (message "All pages in %s have been published." (car project)) + (message "No pages in %s need publishing at this time." + (car project))))) + +;;;###autoload +(defun muse-project-publish (project &optional force) + "Publish the pages of PROJECT that need publishing." + (interactive (list (muse-read-project "Publish project: " nil t) + current-prefix-arg)) + (setq project (muse-project project)) + (let ((styles (cddr project)) + (muse-current-project project) + (muse-current-project-global project)) + ;; determine the style from the project, or else ask + (unless styles + (setq styles (list (muse-publish-get-style)))) + (unless project + (error "Cannot find a project to publish")) + ;; prompt to save any buffers related to this project + (muse-project-save-buffers project) + ;; run hook before publishing begins + (run-hook-with-args 'muse-before-project-publish-hook project) + ;; run the project-level publisher + (let ((fun (or (muse-get-keyword :publish-project (cadr project) t) + 'muse-project-publish-default))) + (funcall fun project styles force)))) + +(defun muse-project-batch-publish () + "Publish Muse files in batch mode." + (let ((muse-batch-publishing-p t) + force) + (if (string= "--force" (or (car command-line-args-left) "")) + (setq force t + command-line-args-left (cdr command-line-args-left))) + (if command-line-args-left + (dolist (project command-line-args-left) + (message "Publishing project %s ..." project) + (muse-project-publish project force)) + (message "No projects specified.")))) + +(eval-when-compile + (put 'make-local-hook 'byte-compile nil)) + +(defun muse-project-set-variables () + "Load project-specific variables." + (when (and muse-current-project-global (null muse-current-project)) + (setq muse-current-project muse-current-project-global)) + (let ((vars (muse-get-keyword :set (cadr muse-current-project))) + sym custom-set var) + (while vars + (setq sym (car vars)) + (setq custom-set (or (get sym 'custom-set) 'set)) + (setq var (if (eq (get sym 'custom-type) 'hook) + (make-local-hook sym) + (make-local-variable sym))) + (funcall custom-set var (car (cdr vars))) + (setq vars (cdr (cdr vars)))))) + +(custom-add-option 'muse-before-publish-hook 'muse-project-set-variables) +(add-to-list 'muse-before-publish-hook 'muse-project-set-variables) + +(defun muse-project-delete-output-files (project) + (interactive + (list (muse-read-project "Remove all output files for project: " nil t))) + (setq project (muse-project project)) + (let ((file-alist (muse-project-file-alist project)) + (styles (cddr project)) + output-file path) + (dolist (entry file-alist) + (dolist (style styles) + (setq output-file + (and (setq path (muse-style-element :path style)) + (expand-file-name + (concat (muse-style-element :prefix style) + (car entry) + (or (muse-style-element :osuffix style) + (muse-style-element :suffix style))) + path))) + (if output-file + (muse-delete-file-if-exists output-file)))))) + +;;; muse-project.el ends here diff --git a/elpa/muse-3.20/muse-protocols.el b/elpa/muse-3.20/muse-protocols.el new file mode 100644 index 0000000..5e1061c --- /dev/null +++ b/elpa/muse-3.20/muse-protocols.el @@ -0,0 +1,251 @@ +;;; muse-protocols.el --- URL protocols that Muse recognizes + +;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; Author: Brad Collins (brad AT chenla DOT org) + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; Here's an example for adding a protocol for the site yubnub, a Web +;; Command line service. +;; +;; (add-to-list 'muse-url-protocols '("yubnub://" muse-browse-url-yubnub +;; muse-resolve-url-yubnub)) +;; +;; (defun muse-resolve-url-yubnub (url) +;; "Resolve a yubnub URL." +;; ;; Remove the yubnub:// +;; (when (string-match "\\`yubnub://\\(.+\\)" url) +;; (match-string 1))) +;; +;; (defun muse-browse-url-yubnub (url) +;; "If this is a yubnub URL-command, jump to it." +;; (setq url (muse-resolve-url-yubnub url)) +;; (browse-url (concat "http://yubnub.org/parser/parse?command=" +;; url))) + +;;; Contributors: + +;; Phillip Lord (Phillip.Lord AT newcastle DOT ac DOT uk) provided a +;; handler for DOI URLs. + +;; Stefan Schlee fixed a bug with handling of colons at the end of +;; URLs. + +;; Valery V. Vorotyntsev contribued the woman:// protocol handler and +;; simplified `muse-browse-url-man'. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse URL Protocols +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'info) +(require 'muse-regexps) + +(defvar muse-url-regexp nil + "A regexp used to match URLs within a Muse page. +This is autogenerated from `muse-url-protocols'.") + +(defun muse-update-url-regexp (sym value) + (setq muse-url-regexp + (concat "\\<\\(" (mapconcat 'car value "\\|") "\\)" + "[^][" muse-regexp-blank "\"'()<>^`{}\n]*" + "[^][" muse-regexp-blank "\"'()<>^`{}.,;:\n]+")) + (set sym value)) + +(defcustom muse-url-protocols + '(("[uU][rR][lL]:" muse-browse-url-url identity) + ("info://" muse-browse-url-info nil) + ("man://" muse-browse-url-man nil) + ("woman://" muse-browse-url-woman nil) + ("google://" muse-browse-url-google muse-resolve-url-google) + ("http:/?/?" browse-url identity) + ("https:/?/?" browse-url identity) + ("ftp:/?/?" browse-url identity) + ("gopher://" browse-url identity) + ("telnet://" browse-url identity) + ("wais://" browse-url identity) + ("file://?" browse-url identity) + ("dict:" muse-browse-url-dict muse-resolve-url-dict) + ("doi:" muse-browse-url-doi muse-resolve-url-doi) + ("news:" browse-url identity) + ("snews:" browse-url identity) + ("mailto:" browse-url identity)) + "A list of (PROTOCOL BROWSE-FUN RESOLVE-FUN) used to match URL protocols. +PROTOCOL describes the first part of the URL, including the +\"://\" part. This may be a regexp. + +BROWSE-FUN should accept URL as an argument and open the URL in +the current window. + +RESOLVE-FUN should accept URL as an argument and return the final +URL, or nil if no URL should be included." + :type '(repeat (list :tag "Protocol" + (string :tag "Regexp") + (function :tag "Browse") + (choice (function :tag "Resolve") + (const :tag "Don't resolve" nil)))) + :set 'muse-update-url-regexp + :group 'muse) + +(add-hook 'muse-update-values-hook + (lambda () + (muse-update-url-regexp 'muse-url-protocols muse-url-protocols))) + +(defcustom muse-wikipedia-country "en" + "Indicate the 2-digit country code that we use for Wikipedia +queries." + :type 'string + :options '("de" "en" "es" "fr" "it" "pl" "pt" "ja" "nl" "sv") + :group 'muse) + +(defun muse-protocol-find (proto list) + "Return the first element of LIST whose car matches the regexp PROTO." + (catch 'found + (dolist (item list) + (when (string-match (concat "\\`" (car item)) proto) + (throw 'found item))))) + +;;;###autoload +(defun muse-browse-url (url &optional other-window) + "Handle URL with the function specified in `muse-url-protocols'. +If OTHER-WINDOW is non-nil, open in a different window." + (interactive (list (read-string "URL: ") + current-prefix-arg)) + ;; Strip text properties + (when (fboundp 'set-text-properties) + (set-text-properties 0 (length url) nil url)) + (when other-window + (switch-to-buffer-other-window (current-buffer))) + (when (string-match muse-url-regexp url) + (let* ((proto (match-string 1 url)) + (entry (muse-protocol-find proto muse-url-protocols))) + (when entry + (funcall (cadr entry) url))))) + +(defun muse-resolve-url (url &rest ignored) + "Resolve URL with the function specified in `muse-url-protocols'." + (when (string-match muse-url-regexp url) + (let* ((proto (match-string 1 url)) + (entry (muse-protocol-find proto muse-url-protocols))) + (when entry + (let ((func (car (cddr entry)))) + (if func + (setq url (funcall func url)) + (setq url nil)))))) + url) + +(defun muse-protocol-add (protocol browse-function resolve-function) + "Add PROTOCOL to `muse-url-protocols'. PROTOCOL may be a regexp. + +BROWSE-FUNCTION should be a function that visits a URL in the +current buffer. + +RESOLVE-FUNCTION should be a function that transforms a URL for +publishing or returns nil if not linked." + (add-to-list 'muse-url-protocols + (list protocol browse-function resolve-function)) + (muse-update-url-regexp 'muse-url-protocols + muse-url-protocols)) + +(defun muse-browse-url-url (url) + "Call `muse-protocol-browse-url' to browse URL. +This is used when we are given something like +\"URL:http://example.org/\". + +If you're looking for a good example for how to make a custom URL +handler, look at `muse-browse-url-dict' instead." + (when (string-match "\\`[uU][rR][lL]:\\(.+\\)" url) + (muse-browse-url (match-string 1 url)))) + +(defun muse-resolve-url-dict (url) + "Return the Wikipedia link corresponding with the given URL." + (when (string-match "\\`dict:\\(.+\\)" url) + (concat "http://" muse-wikipedia-country ".wikipedia.org/" + "wiki/Special:Search?search=" (match-string 1 url)))) + +(defun muse-browse-url-dict (url) + "If this is a Wikipedia URL, browse it." + (let ((dict-url (muse-resolve-url-dict url))) + (when dict-url + (browse-url dict-url)))) + +(defun muse-resolve-url-doi (url) + "Return the URL through DOI proxy server." + (when (string-match "\\`doi:\\(.+\\)" url) + (concat "http://dx.doi.org/" + (match-string 1 url)))) + +(defun muse-browse-url-doi (url) + "If this is a DOI URL, browse it. + +DOI's (digitial object identifiers) are a standard identifier +used in the publishing industry." + (let ((doi-url (muse-resolve-url-doi url))) + (when doi-url + (browse-url doi-url)))) + +(defun muse-resolve-url-google (url) + "Return the correct Google search string." + (when (string-match "\\`google:/?/?\\(.+\\)" url) + (concat "http://www.google.com/search?q=" + (match-string 1 url)))) + +(defun muse-browse-url-google (url) + "If this is a Google URL, jump to it." + (let ((google-url (muse-resolve-url-google url))) + (when google-url + (browse-url google-url)))) + +(defun muse-browse-url-info (url) + "If this in an Info URL, jump to it." + (require 'info) + (cond + ((string-match "\\`info://\\([^#\n]+\\)#\\(.+\\)" url) + (Info-find-node (match-string 1 url) + (match-string 2 url))) + ((string-match "\\`info://\\([^#\n]+\\)" url) + (Info-find-node (match-string 1 url) + "Top")) + ((string-match "\\`info://(\\([^)\n]+\\))\\(.+\\)" url) + (Info-find-node (match-string 1 url) (match-string 2 url))) + ((string-match "\\`info://\\(.+\\)" url) + (Info-find-node (match-string 1 url) "Top")))) + +(defun muse-browse-url-man (url) + "If this in a manpage URL, jump to it." + (require 'man) + (when (string-match "\\`man://\\([^(]+\\(([^)]+)\\)?\\)" url) + (man (match-string 1 url)))) + +(defun muse-browse-url-woman (url) + "If this is a WoMan URL, jump to it." + (require 'woman) + (when (string-match "\\`woman://\\(.+\\)" url) + (woman (match-string 1 url)))) + +(provide 'muse-protocols) + +;;; muse-protocols.el ends here diff --git a/elpa/muse-3.20/muse-publish.el b/elpa/muse-3.20/muse-publish.el new file mode 100644 index 0000000..ec6e176 --- /dev/null +++ b/elpa/muse-3.20/muse-publish.el @@ -0,0 +1,2193 @@ +;;; muse-publish.el --- base publishing implementation + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Contributors: + +;; Yann Hodique (yann DOT hodique AT gmail DOT com) fixed an +;; unnecessary URL description transform in `muse-publish-url'. + +;; Peter K. Lee (saint AT corenova DOT com) provided the +;; `muse-style-elements-list' function. + +;; Jim Ottaway (j DOT ottaway AT lse DOT ac DOT uk) provided a +;; reference implementation for nested lists, as well as some code for +;; the "style" element of the tag. + +;; Deus Max (deusmax AT gmail DOT com) provided the tag. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse Publishing +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'muse-publish) + +(require 'muse) +(require 'muse-regexps) + +(defgroup muse-publish nil + "Options controlling the general behavior of Muse publishing." + :group 'muse) + +(defcustom muse-before-publish-hook nil + "A hook run in the buffer to be published, before it is done." + :type 'hook + :group 'muse-publish) + +(defcustom muse-after-publish-hook nil + "A hook run in the buffer to be published, after it is done." + :type 'hook + :group 'muse-publish) + +(defcustom muse-publish-url-transforms + '(muse-resolve-url) + "A list of functions used to prepare URLs for publication. +Each is passed the URL. The transformed URL should be returned." + :type 'hook + :options '(muse-resolve-url) + :group 'muse-publish) + +(defcustom muse-publish-desc-transforms + '(muse-publish-strip-URL) + "A list of functions used to prepare URL desciptions for publication. +Each is passed the description. The modified description should +be returned." + :type 'hook + :options '(muse-publish-strip-URL) + :group 'muse-publish) + +(defcustom muse-publish-date-format "%B %e, %Y" + "Format string for the date, used by `muse-publish-markup-buffer'. +See `format-time-string' for details on the format options." + :type 'string + :group 'muse-publish) + +(defcustom muse-publish-comments-p nil + "If nil, remove comments before publishing. +If non-nil, publish comments using the markup of the current style." + :type 'boolean + :group 'muse-publish) + +(defcustom muse-publish-report-threshhold 100000 + "If a file is this size or larger, report publishing progress." + :type 'integer + :group 'muse-publish) + +(defcustom muse-publish-markup-regexps + `(;; Remove leading and trailing whitespace from the file + (1000 "\\(\\`\n+\\|\n+\\'\\)" 0 "") + + ;; Remove trailing whitespace from all lines + (1100 ,(concat "[" muse-regexp-blank "]+$") 0 "") + + ;; Handle any leading #directives + (1200 "\\`#\\([a-zA-Z-]+\\)\\s-+\\(.+\\)\n+" 0 directive) + + ;; commented lines + (1250 ,(concat "^;\\(?:[" muse-regexp-blank "]+\\(.+\\)\\|$\\|'\\)") + 0 comment) + + ;; markup tags + (1300 muse-tag-regexp 0 tag) + + ;; prevent emphasis characters in explicit links from being marked + (1400 muse-explicit-link-regexp 0 muse-publish-mark-link) + + ;; emphasized or literal text + (1600 ,(concat "\\(^\\|[-[" muse-regexp-blank + "<('`\"\n]\\)\\(=[^=" muse-regexp-blank + "\n]\\|_[^_" muse-regexp-blank + "\n]\\|\\*+[^*" muse-regexp-blank + "\n]\\)") + 2 word) + + ;; headings, outline-mode style + (1700 "^\\(\\*+\\)\\s-+" 0 heading) + + ;; ellipses + (1800 "\\.\\.\\.\\." 0 enddots) + (1850 "\\.\\.\\." 0 dots) + + ;; horizontal rule, or section separator + (1900 "^----+" 0 rule) + + ;; non-breaking space + (1950 "~~" 0 no-break-space) + + ;; beginning of footnotes section + (2000 "^Footnotes:?\\s-*" 0 fn-sep) + ;; footnote definition/reference (def if at beginning of line) + (2100 "\\[\\([1-9][0-9]*\\)\\]" 0 footnote) + + ;; unnumbered List items begin with a -. numbered list items + ;; begin with number and a period. definition lists have a + ;; leading term separated from the body with ::. centered + ;; paragraphs begin with at least six columns of whitespace; any + ;; other whitespace at the beginning indicates a blockquote. The + ;; reason all of these rules are handled here, is so that + ;; blockquote detection doesn't interfere with indented list + ;; members. + (2200 ,(format muse-list-item-regexp (concat "[" muse-regexp-blank "]*")) + 0 list) + + ;; support table.el style tables + (2300 ,(concat "^" muse-table-el-border-regexp "\n" + "\\(\\(" muse-table-el-line-regexp "\n\\)+" + "\\(" muse-table-el-border-regexp "\\)" + "\\(\n\\|\\'\\)\\)+") + 0 table-el) + + ;; simple table markup is supported, nothing fancy. use | to + ;; separate cells, || to separate header cells, and ||| for footer + ;; cells + (2350 ,(concat "\\(\\([" muse-regexp-blank "]*\n\\)?" + "\\(\\(?:" muse-table-line-regexp "\\|" + muse-table-hline-regexp "\\)\\(?:\n\\|\\'\\)\\)\\)+") + 0 table) + + ;; blockquote and centered text + (2400 ,(concat "^\\([" muse-regexp-blank "]+\\).+") 0 quote) + + ;; the emdash ("--" or "---") + (2500 ,(concat "\\(^\\|[" muse-regexp-blank "]*\\)---?\\($\\|[" + muse-regexp-blank "]*\\)") + 0 emdash) + + ;; "verse" text is indicated the same way as a quoted e-mail + ;; response: "> text", where text may contain initial whitespace + ;; (see below). + (2600 ,(concat "^[" muse-regexp-blank "]*> ") 0 verse) + + ;; define anchor points + (2700 "^\\(\\W*\\)#\\(\\S-+\\)\\s-*" 0 anchor) + + ;; replace links in the buffer (links to other pages) + (2900 muse-explicit-link-regexp 0 link) + + ;; bare URLs + (3000 muse-url-regexp 0 url) + + ;; bare email addresses + (3500 + "\\([^[]\\)[-a-zA-Z0-9._]+@\\([-a-zA-z0-9_]+\\.\\)+[a-zA-Z0-9]+" 0 email) + ) + "List of markup rules for publishing a page with Muse. +The rules given in this variable are invoked first, followed by +whatever rules are specified by the current style. + +Each member of the list is either a function, or a list of the form: + + (REGEXP/SYMBOL TEXT-BEGIN-GROUP REPLACEMENT-TEXT/FUNCTION/SYMBOL) + +REGEXP is a regular expression, or symbol whose value is a regular +expression, which is searched for using `re-search-forward'. +TEXT-BEGIN-GROUP is the matching group within that regexp which +denotes the beginning of the actual text to be marked up. +REPLACEMENT-TEXT is a string that will be passed to `replace-match'. +If it is not a string, but a function, it will be called to determine +what the replacement text should be (it must return a string). If it +is a symbol, the value of that symbol should be a string. + +The replacements are done in order, one rule at a time. Writing +the regular expressions can be a tricky business. Note that case +is never ignored. `case-fold-search' is always bound to nil +while processing the markup rules." + :type '(repeat (choice + (list :tag "Markup rule" + integer + (choice regexp symbol) + integer + (choice string function symbol)) + function)) + :group 'muse-publish) + +(defcustom muse-publish-markup-functions + '((directive . muse-publish-markup-directive) + (comment . muse-publish-markup-comment) + (anchor . muse-publish-markup-anchor) + (tag . muse-publish-markup-tag) + (word . muse-publish-markup-word) + (emdash . muse-publish-markup-emdash) + (enddots . muse-publish-markup-enddots) + (dots . muse-publish-markup-dots) + (rule . muse-publish-markup-rule) + (no-break-space . muse-publish-markup-no-break-space) + (heading . muse-publish-markup-heading) + (footnote . muse-publish-markup-footnote) + (fn-sep . muse-publish-markup-fn-sep) + (list . muse-publish-markup-list) + (quote . muse-publish-markup-quote) + (verse . muse-publish-markup-verse) + (table . muse-publish-markup-table) + (table-el . muse-publish-markup-table-el) + (email . muse-publish-markup-email) + (link . muse-publish-markup-link) + (url . muse-publish-markup-url)) + "An alist of style types to custom functions for that kind of text. + +Each member of the list is of the form: + + (SYMBOL FUNCTION) + +SYMBOL describes the type of text to associate with this rule. +`muse-publish-markup-regexps' maps regexps to these symbols. + +FUNCTION is the function to use to mark up this kind of rule if +no suitable function is found through the :functions tag of the +current style." + :type '(alist :key-type symbol :value-type function) + :group 'muse-publish) + +(defcustom muse-publish-markup-tags + '(("contents" nil t nil muse-publish-contents-tag) + ("verse" t nil nil muse-publish-verse-tag) + ("example" t nil nil muse-publish-example-tag) + ("src" t t nil muse-publish-src-tag) + ("code" t nil nil muse-publish-code-tag) + ("quote" t nil t muse-publish-quote-tag) + ("literal" t t nil muse-publish-literal-tag) + ("verbatim" t nil nil muse-publish-verbatim-tag) + ("br" nil nil nil muse-publish-br-tag) + ("lisp" t t nil muse-publish-lisp-tag) + ("class" t t nil muse-publish-class-tag) + ("div" t t nil muse-publish-div-tag) + ("command" t t nil muse-publish-command-tag) + ("perl" t t nil muse-publish-perl-tag) + ("php" t t nil muse-publish-php-tag) + ("python" t t nil muse-publish-python-tag) + ("ruby" t t nil muse-publish-ruby-tag) + ("comment" t nil nil muse-publish-comment-tag) + ("include" nil t nil muse-publish-include-tag) + ("markup" t t nil muse-publish-mark-up-tag) + ("cite" t t nil muse-publish-cite-tag)) + "A list of tag specifications, for specially marking up text. +XML-style tags are the best way to add custom markup to Muse. +This is easily accomplished by customizing this list of markup tags. + +For each entry, the name of the tag is given, whether it expects +a closing tag, whether it takes an optional set of attributes, +whether it is nestable, and a function that performs whatever +action is desired within the delimited region. + +The tags themselves are deleted during publishing, before the +function is called. The function is called with three arguments, +the beginning and end of the region surrounded by the tags. If +properties are allowed, they are passed as a third argument in +the form of an alist. The `end' argument to the function is +always a marker. + +Point is always at the beginning of the region within the tags, when +the function is called. Wherever point is when the function finishes +is where tag markup will resume. + +These tag rules are processed once at the beginning of markup, and +once at the end, to catch any tags which may have been inserted +in-between." + :type '(repeat (list (string :tag "Markup tag") + (boolean :tag "Expect closing tag" :value t) + (boolean :tag "Parse attributes" :value nil) + (boolean :tag "Nestable" :value nil) + function)) + :group 'muse-publish) + +(defcustom muse-publish-markup-header-footer-tags + '(("lisp" t t nil muse-publish-lisp-tag) + ("markup" t t nil muse-publish-mark-up-tag)) + "Tags used when publishing headers and footers. +See `muse-publish-markup-tags' for details." + :type '(repeat (list (string :tag "Markup tag") + (boolean :tag "Expect closing tag" :value t) + (boolean :tag "Parse attributes" :value nil) + (boolean :tag "Nestable" :value nil) + function)) + :group 'muse-publish) + +(defcustom muse-publish-markup-specials nil + "A table of characters which must be represented specially." + :type '(alist :key-type character :value-type string) + :group 'muse-publish) + +(defcustom muse-publish-enable-local-variables nil + "If non-nil, interpret local variables in a file when publishing." + :type 'boolean + :group 'muse-publish) + +(defcustom muse-publish-enable-dangerous-tags t + "If non-nil, publish tags like and that can +call external programs or expose sensitive information. +Otherwise, ignore tags like this. + +This is useful to set to nil when the file to publish is coming +from an untrusted source." + :type 'boolean + :group 'muse-publish) + +(defvar muse-publishing-p nil + "This is set to t while a page is being published.") +(defvar muse-batch-publishing-p nil + "This is set to t while a page is being batch published.") +(defvar muse-inhibit-before-publish-hook nil + "This is set to t when publishing a file rather than just a buffer. +It is used by `muse-publish-markup-buffer'.") +(defvar muse-publishing-styles nil + "The publishing styles that Muse recognizes. +This is automatically generated when loading publishing styles.") +(defvar muse-publishing-current-file nil + "The file that is currently being published.") +(defvar muse-publishing-current-output-path nil + "The path where the current file will be published to.") +(defvar muse-publishing-current-style nil + "The style of the file that is currently being published.") +(defvar muse-publishing-directives nil + "An alist of publishing directives from the top of a file.") +(defvar muse-publish-generate-contents nil + "Non-nil if a table of contents should be generated. +If non-nil, it is a cons cell specifying (MARKER . DEPTH), to +tell where the was seen, and to what depth the +contents were requested.") +(defvar muse-publishing-last-position nil + "Last position of the point when publishing. +This is used to make sure that publishing doesn't get stalled.") + +(defvar muse-publish-inhibit-style-hooks nil + "If non-nil, do not call the :before or :before-end hooks when publishing.") + +(defvar muse-publish-use-header-footer-tags nil + "If non-nil, use `muse-publish-markup-header-footer-tags' for looking up +tags. Otherwise, use `muse-publish-markup-tags'.") + +(defvar muse-inhibit-style-tags nil + "If non-nil, do not search for style-specific tags. +This is used when publishing headers and footers.") + +;; Functions for handling style information + +(defsubst muse-style (&optional style) + "Resolve the given STYLE into a Muse style, if it is a string." + (if (null style) + muse-publishing-current-style + (if (stringp style) + (assoc style muse-publishing-styles) + (muse-assert (consp style)) + style))) + +(defun muse-define-style (name &rest elements) + (let ((entry (assoc name muse-publishing-styles))) + (if entry + (setcdr entry elements) + (setq muse-publishing-styles + (cons (append (list name) elements) + muse-publishing-styles))))) + +(defun muse-derive-style (new-name base-name &rest elements) + (apply 'muse-define-style new-name + (append elements (list :base base-name)))) + +(defsubst muse-get-keyword (keyword list &optional direct) + (let ((value (cadr (memq keyword list)))) + (if (and (not direct) (symbolp value)) + (symbol-value value) + value))) + +(defun muse-style-elements-list (elem &optional style) + "Return a list all references to ELEM in STYLE, including base styles. +If STYLE is not specified, use current style." + (let (base elements) + (while style + (setq style (muse-style style)) + (setq elements (append elements + (muse-get-keyword elem style))) + (setq style (muse-get-keyword :base style))) + elements)) + +(defun muse-style-element (elem &optional style direct) + "Search for ELEM in STYLE, including base styles. +If STYLE is not specified, use current style." + (setq style (muse-style style)) + (let ((value (muse-get-keyword elem style direct))) + (if value + value + (let ((base (muse-get-keyword :base style))) + (if base + (muse-style-element elem base direct)))))) + +(defun muse-style-derived-p-1 (base style) + "Internal function used by `muse-style-derived-p'." + (if (and (stringp style) + (string= style base)) + t + (setq style (muse-style style)) + (let ((value (muse-get-keyword :base style))) + (when value + (muse-style-derived-p base value))))) + +(defun muse-style-derived-p (base &optional style) + "Return non-nil if STYLE is equal to or derived from BASE, +non-nil otherwise. + +BASE should be a string." + (unless style + (setq style (muse-style))) + (when (and (consp style) + (stringp (car style))) + (setq style (car style))) + (muse-style-derived-p-1 base style)) + +(defun muse-find-markup-element (keyword ident style) + (let ((def (assq ident (muse-style-element keyword style)))) + (if def + (cdr def) + (let ((base (muse-style-element :base style))) + (if base + (muse-find-markup-element keyword ident base)))))) + +(defun muse-markup-text (ident &rest args) + "Insert ARGS into the text markup associated with IDENT. +If the markup text has sections like %N%, this will be replaced +with the N-1th argument in ARGS. After that, `format' is applied +to the text with ARGS as parameters." + (let ((text (muse-find-markup-element :strings ident (muse-style)))) + (if (and text args) + (progn + (let (start repl-text) + (while (setq start (string-match "%\\([1-9][0-9]*\\)%" text start)) + ;; escape '%' in the argument text, since we will be + ;; using format on it + (setq repl-text (muse-replace-regexp-in-string + "%" "%%" + (nth (1- (string-to-number + (match-string 1 text))) args) + t t) + start (+ start (length repl-text)) + text (replace-match repl-text t t text)))) + (apply 'format text args)) + (or text "")))) + +(defun muse-insert-markup (&rest args) + (let ((beg (point))) + (apply 'insert args) + (muse-publish-mark-read-only beg (point)))) + +(defun muse-find-markup-tag (keyword tagname style) + (let ((def (assoc tagname (muse-style-element keyword style)))) + (or def + (let ((base (muse-style-element :base style))) + (if base + (muse-find-markup-tag keyword tagname base)))))) + +(defun muse-markup-tag-info (tagname &rest args) + (let ((tag-info (and (not muse-inhibit-style-tags) + (muse-find-markup-tag :tags tagname (muse-style))))) + (or tag-info + (assoc tagname + (if muse-publish-use-header-footer-tags + muse-publish-markup-header-footer-tags + muse-publish-markup-tags))))) + +(defsubst muse-markup-function (category) + (let ((func (muse-find-markup-element :functions category (muse-style)))) + (or func + (cdr (assq category muse-publish-markup-functions))))) + +;; Publishing routines + +(defun muse-publish-markup (name rules) + (let* ((case-fold-search nil) + (inhibit-read-only t) + (limit (* (length rules) (point-max))) + (verbose (and muse-publish-report-threshhold + (> (point-max) muse-publish-report-threshhold))) + (base 0)) + (while rules + (goto-char (point-min)) + (let ((regexp (nth 1 (car rules))) + (group (nth 2 (car rules))) + (repl (nth 3 (car rules))) + pos) + (setq muse-publishing-last-position nil) + (if (symbolp regexp) + (setq regexp (symbol-value regexp))) + (if (and verbose (not muse-batch-publishing-p)) + (message "Publishing %s...%d%%" name + (* (/ (float (+ (point) base)) limit) 100))) + (while (and regexp (progn + (when (and (get-text-property (point) 'read-only) + (> (point) (point-min))) + (goto-char (or (next-single-property-change + (point) 'read-only) + (point-max)))) + (setq pos (re-search-forward regexp nil t)))) + (if (and verbose (not muse-batch-publishing-p)) + (message "Publishing %s...%d%%" name + (* (/ (float (+ (point) base)) limit) 100))) + (unless (and (> (- (match-end 0) (match-beginning 0)) 0) + (match-beginning group) + (get-text-property (match-beginning group) 'read-only)) + (let* (func + (text (cond + ((and (symbolp repl) + (setq func (muse-markup-function repl))) + (funcall func)) + ((functionp repl) + (funcall repl)) + ((symbolp repl) + (symbol-value repl)) + (t repl)))) + (if (stringp text) + (replace-match text t)))) + (if (and muse-publishing-last-position + (= pos muse-publishing-last-position)) + (if (eobp) + (setq regexp nil) + (forward-char 1))) + (setq muse-publishing-last-position pos))) + (setq rules (cdr rules) + base (+ base (point-max)))) + (if (and verbose (not muse-batch-publishing-p)) + (message "Publishing %s...done" name)))) + +(defun muse-insert-file-or-string (file-or-string &optional title) + (let ((beg (point)) end) + (if (and (not (string-equal file-or-string "")) + (not (string-match "\n" file-or-string)) + (file-readable-p file-or-string)) + (setq end (+ beg + (cadr (muse-insert-file-contents file-or-string)))) + (insert file-or-string) + (setq end (point))) + (save-restriction + (narrow-to-region beg end) + (remove-text-properties (point-min) (point-max) + '(read-only nil rear-nonsticky nil)) + (goto-char (point-min)) + (let ((muse-inhibit-style-tags t) + (muse-publish-use-header-footer-tags t)) + (muse-publish-markup (or title "") + '((100 muse-tag-regexp 0 + muse-publish-markup-tag))))))) + +(defun muse-style-run-hooks (keyword style &rest args) + (catch 'handled + (let ((cache nil)) + (while (and style + (setq style (muse-style style))) + (let ((func (muse-style-element keyword style t))) + (when (and func + (not (member func cache))) + (setq cache (cons func cache)) + (when (apply func args) + (throw 'handled t)))) + (setq style (muse-style-element :base style)))))) + +(defun muse-publish-markup-region (beg end &optional title style) + "Apply the given STYLE's markup rules to the given region. +TITLE is used when indicating the publishing progress; it may be nil. + +The point is guaranteed to be at END if the routine terminates +normally." + (unless title (setq title "")) + (unless style + (or (setq style muse-publishing-current-style) + (error "Cannot find any publishing styles to use"))) + (save-restriction + (narrow-to-region beg end) + (let ((muse-publish-generate-contents nil)) + (unless muse-publish-inhibit-style-hooks + (muse-style-run-hooks :before style)) + (muse-publish-markup + title + (sort (copy-alist (append muse-publish-markup-regexps + (muse-style-elements-list :regexps style))) + (function + (lambda (l r) + (< (car l) (car r)))))) + (unless muse-publish-inhibit-style-hooks + (muse-style-run-hooks :before-end style)) + (muse-publish-escape-specials (point-min) (point-max) nil 'document)) + (goto-char (point-max)))) + +(defun muse-publish-markup-buffer (title style) + "Apply the given STYLE's markup rules to the current buffer." + (setq style (muse-style style)) + (let ((style-header (muse-style-element :header style)) + (style-footer (muse-style-element :footer style)) + (muse-publishing-current-style style) + (muse-publishing-directives + (list (cons "title" title) + (cons "author" (user-full-name)) + (cons "date" (format-time-string + muse-publish-date-format + (if muse-publishing-current-file + (nth 5 (file-attributes + muse-publishing-current-file)) + (current-time)))))) + (muse-publishing-p t) + (inhibit-read-only t)) + (run-hooks 'muse-update-values-hook) + (unless muse-inhibit-before-publish-hook + (run-hooks 'muse-before-publish-hook)) + (muse-publish-markup-region (point-min) (point-max) title style) + (goto-char (point-min)) + (when style-header + (muse-insert-file-or-string style-header title)) + (goto-char (point-max)) + (when style-footer + (muse-insert-file-or-string style-footer title)) + (muse-style-run-hooks :after style) + (run-hooks 'muse-after-publish-hook))) + +(defun muse-publish-markup-string (string &optional style) + "Markup STRING using the given STYLE's markup rules." + (setq style (muse-style style)) + (muse-with-temp-buffer + (insert string) + (let ((muse-publishing-current-style style) + (muse-publishing-p t)) + (muse-publish-markup "*string*" (muse-style-element :rules style))) + (buffer-string))) + +;; Commands for publishing files + +(defun muse-publish-get-style (&optional styles) + (unless styles (setq styles muse-publishing-styles)) + (if (= 1 (length styles)) + (car styles) + (when (catch 'different + (let ((first (car (car styles)))) + (dolist (style (cdr styles)) + (unless (equal first (car style)) + (throw 'different t))))) + (setq styles (muse-collect-alist + styles + (funcall muse-completing-read-function + "Publish with style: " styles nil t)))) + (if (or (= 1 (length styles)) + (not (muse-get-keyword :path (car styles)))) + (car styles) + (setq styles (mapcar (lambda (style) + (cons (muse-get-keyword :path style) + style)) + styles)) + (cdr (assoc (funcall muse-completing-read-function + "Publish to directory: " styles nil t) + styles))))) + +(defsubst muse-publish-get-output-dir (style) + (let ((default-directory (or (muse-style-element :path style) + default-directory))) + (muse-read-directory-name "Publish to directory: " nil default-directory))) + +(defsubst muse-publish-get-info () + (let ((style (muse-publish-get-style))) + (list style (muse-publish-get-output-dir style) + current-prefix-arg))) + +(defsubst muse-publish-output-name (&optional file style) + (setq style (muse-style style)) + (concat (muse-style-element :prefix style) + (muse-page-name file) + (muse-style-element :suffix style))) + +(defsubst muse-publish-output-file (file &optional output-dir style) + (setq style (muse-style style)) + (if output-dir + (expand-file-name (muse-publish-output-name file style) output-dir) + (concat (file-name-directory file) + (muse-publish-output-name file style)))) + +(defsubst muse-publish-link-name (&optional file style) + "Take FILE and add :prefix and either :link-suffix or :suffix from STYLE. +We assume that FILE is a Muse file. + +We call `muse-page-name' on FILE to remove the directory part of +FILE and any extensions that are in `muse-ignored-extensions'." + (setq style (muse-style style)) + (concat (muse-style-element :prefix style) + (muse-page-name file) + (or (muse-style-element :link-suffix style) + (muse-style-element :suffix style)))) + +(defsubst muse-publish-link-file (file &optional style) + "Turn FILE into a URL. + +If FILE exists on the system as-is, return it without +modification. In the case of wanting to link to Muse files when +`muse-file-extension' is nil, you should load muse-project.el. + +Otherwise, assume that it is a Muse file and call +`muse-publish-link-name' to add :prefix, :link-suffix, :suffix, +and removing ignored file extensions, but preserving the +directory part of FILE." + (setq style (muse-style style)) + (if (file-exists-p file) + file + (concat (file-name-directory file) + (muse-publish-link-name file style)))) + +(defsubst muse-publish-link-page (page) + "Turn PAGE into a URL. + +This is called by `muse-publish-classify-url' to figure out what +a link to another file or Muse page should look like. + +If muse-project.el is loaded, call `muse-project-link-page' for this. +Otherwise, call `muse-publish-link-file'." + (if (fboundp 'muse-project-link-page) + (muse-project-link-page page) + (muse-publish-link-file page))) + +(defmacro muse-publish-ensure-block (beg &optional end) + "Ensure that block-level markup at BEG is published with at least one +preceding blank line. BEG must be an unquoted symbol that contains a +position or marker. BEG is modified to be the new position. +The point is left at the new value of BEG. + +Additionally, make sure that BEG is placed on a blank line. + +If END is given, make sure that it is placed on a blank line. In +order to achieve this, END must be an unquoted symbol that +contains a marker. This is the case with Muse tag functions." + `(progn + (goto-char ,beg) + (cond ((not (bolp)) (insert "\n\n")) + ((eq (point) (point-min)) nil) + ((prog2 (backward-char) (bolp) (forward-char)) nil) + (t (insert "\n"))) + (unless (and (bolp) (eolp)) + (insert "\n") + (backward-char)) + (setq ,beg (point)) + (when (markerp ,end) + (goto-char ,end) + (unless (and (bolp) (eolp)) + (insert-before-markers "\n"))) + (goto-char ,beg))) + +;;;###autoload +(defun muse-publish-region (beg end &optional title style) + "Apply the given STYLE's markup rules to the given region. +The result is placed in a new buffer that includes TITLE in its name." + (interactive "r") + (when (interactive-p) + (unless title (setq title (read-string "Title: "))) + (unless style (setq style (muse-publish-get-style)))) + (let ((text (buffer-substring beg end)) + (buf (generate-new-buffer (concat "*Muse: " title "*")))) + (with-current-buffer buf + (insert text) + (muse-publish-markup-buffer title style) + (goto-char (point-min)) + (let ((inhibit-read-only t)) + (remove-text-properties (point-min) (point-max) + '(rear-nonsticky nil read-only nil)))) + (pop-to-buffer buf))) + +;;;###autoload +(defun muse-publish-file (file style &optional output-dir force) + "Publish the given FILE in a particular STYLE to OUTPUT-DIR. +If the argument FORCE is nil, each file is only published if it is +newer than the published version. If the argument FORCE is non-nil, +the file is published no matter what." + (interactive (cons (read-file-name "Publish file: ") + (muse-publish-get-info))) + (let ((style-name style)) + (setq style (muse-style style)) + (unless style + (error "There is no style '%s' defined" style-name))) + (let* ((output-path (muse-publish-output-file file output-dir style)) + (output-suffix (muse-style-element :osuffix style)) + (muse-publishing-current-file file) + (muse-publishing-current-output-path output-path) + (target (if output-suffix + (concat (muse-path-sans-extension output-path) + output-suffix) + output-path)) + (threshhold (nth 7 (file-attributes file)))) + (if (not threshhold) + (message "Please save %s before publishing" file) + (when (or force (file-newer-than-file-p file target)) + (if (and muse-publish-report-threshhold + (> threshhold + muse-publish-report-threshhold)) + (message "Publishing %s ..." file)) + (muse-with-temp-buffer + (muse-insert-file-contents file) + (run-hooks 'muse-before-publish-hook) + (when muse-publish-enable-local-variables + (hack-local-variables)) + (let ((muse-inhibit-before-publish-hook t)) + (muse-publish-markup-buffer (muse-page-name file) style)) + (when (muse-write-file output-path) + (muse-style-run-hooks :final style file output-path target))) + t)))) + +;;;###autoload +(defun muse-publish-this-file (style output-dir &optional force) + "Publish the currently-visited file. +Prompt for both the STYLE and OUTPUT-DIR if they are not +supplied." + (interactive (muse-publish-get-info)) + (setq style (muse-style style)) + (if buffer-file-name + (let ((muse-current-output-style (list :base (car style) + :path output-dir))) + (unless (muse-publish-file buffer-file-name style output-dir force) + (message (concat "The published version is up-to-date; use" + " C-u C-c C-T to force an update.")))) + (message "This buffer is not associated with any file"))) + +(defun muse-batch-publish-files () + "Publish Muse files in batch mode." + (let ((muse-batch-publishing-p t) + (font-lock-verbose nil) + muse-current-output-style + style output-dir) + ;; don't activate VC when publishing files + (setq vc-handled-backends nil) + (setq style (car command-line-args-left) + command-line-args-left (cdr command-line-args-left) + output-dir (car command-line-args-left) + output-dir + (if (string-match "\\`--output-dir=" output-dir) + (prog1 + (substring output-dir (match-end 0)) + (setq command-line-args-left (cdr command-line-args-left)))) + muse-current-output-style (list :base style :path output-dir)) + (setq auto-mode-alist + (delete (cons (concat "\\." muse-file-extension "\\'") + 'muse-mode-choose-mode) + auto-mode-alist)) + (dolist (file command-line-args-left) + (muse-publish-file file style output-dir t)))) + +;; Default publishing rules + +(defun muse-publish-section-close (depth) + "Seach forward for the closing tag of given DEPTH." + (let (not-end) + (save-excursion + (while (and (setq not-end (re-search-forward + (concat "^\\*\\{1," (number-to-string depth) + "\\}\\s-+") + nil t)) + (get-text-property (match-beginning 0) 'read-only))) + (if not-end + (forward-line 0) + (goto-char (point-max))) + (cond ((not (eq (char-before) ?\n)) + (insert "\n\n")) + ((not (eq (char-before (1- (point))) ?\n)) + (insert "\n"))) + (muse-insert-markup (muse-markup-text 'section-close depth)) + (insert "\n")))) + +(defun muse-publish-markup-directive (&optional name value) + (unless name (setq name (match-string 1))) + (unless value (setq value (match-string 2))) + (let ((elem (assoc name muse-publishing-directives))) + (if elem + (setcdr elem value) + (setq muse-publishing-directives + (cons (cons name value) + muse-publishing-directives)))) + ;; Make sure we don't ever try to move the point forward (past the + ;; beginning of buffer) while we're still searching for directives. + (setq muse-publishing-last-position nil) + (delete-region (match-beginning 0) (match-end 0))) + +(defsubst muse-publishing-directive (name) + (cdr (assoc name muse-publishing-directives))) + +(defmacro muse-publish-get-and-delete-attr (attr attrs) + "Delete attribute ATTR from ATTRS only once, destructively. + +This function returns the matching attribute value, if found." + (let ((last (make-symbol "last")) + (found (make-symbol "found")) + (vals (make-symbol "vals"))) + `(let ((,vals ,attrs)) + (if (string= (caar ,vals) ,attr) + (prog1 (cdar ,vals) + (setq ,attrs (cdr ,vals))) + (let ((,last ,vals) + (,found nil)) + (while ,vals + (setq ,vals (cdr ,vals)) + (when (string= (caar ,vals) ,attr) + (setq ,found (cdar ,vals)) + (setcdr ,last (cdr ,vals)) + (setq ,vals nil)) + (setq ,last ,vals)) + ,found))))) + +(defun muse-publish-markup-anchor () + (unless (get-text-property (match-end 1) 'muse-link) + (let ((text (muse-markup-text 'anchor (match-string 2)))) + (unless (string= text "") + (save-match-data + (skip-chars-forward (concat muse-regexp-blank "\n")) + (muse-insert-markup text))) + (match-string 1)))) + +(defun muse-publish-markup-comment () + (if (null muse-publish-comments-p) + "" + (goto-char (match-end 0)) + (muse-insert-markup (muse-markup-text 'comment-end)) + (if (match-beginning 1) + (progn + (muse-publish-mark-read-only (match-beginning 1) (match-end 1)) + (delete-region (match-beginning 0) (match-beginning 1))) + (delete-region (match-beginning 0) (match-end 0))) + (goto-char (match-beginning 0)) + (muse-insert-markup (muse-markup-text 'comment-begin)))) + +(defun muse-publish-markup-tag () + (let ((tag-info (muse-markup-tag-info (match-string 1)))) + (when (and tag-info + (not (get-text-property (match-beginning 0) 'read-only)) + (nth 4 tag-info) + (or muse-publish-enable-dangerous-tags + (not (get (nth 4 tag-info) 'muse-dangerous-tag)))) + (let ((closed-tag (match-string 3)) + (start (match-beginning 0)) + (beg (point)) + end attrs) + (when (nth 2 tag-info) + (let ((attrstr (match-string 2))) + (while (and attrstr + (string-match (concat "\\([^" + muse-regexp-blank + "=\n]+\\)\\(=\"\\" + "([^\"]+\\)\"\\)?") + attrstr)) + (let ((attr (cons (downcase + (muse-match-string-no-properties 1 attrstr)) + (muse-match-string-no-properties 3 attrstr)))) + (setq attrstr (replace-match "" t t attrstr)) + (if attrs + (nconc attrs (list attr)) + (setq attrs (list attr))))))) + (if (and (cadr tag-info) (not closed-tag)) + (if (muse-goto-tag-end (car tag-info) (nth 3 tag-info)) + (delete-region (match-beginning 0) (point)) + (setq tag-info nil))) + (when tag-info + (setq end (point-marker)) + (delete-region start beg) + (goto-char start) + (let ((args (list start end))) + (if (nth 2 tag-info) + (nconc args (list attrs))) + (let ((muse-inhibit-style-tags nil)) + ;; remove the inhibition + (apply (nth 4 tag-info) args))) + (set-marker end nil))))) + nil) + +(defun muse-publish-escape-specials (beg end &optional ignore-read-only context) + "Escape specials from BEG to END using style-specific :specials. +If IGNORE-READ-ONLY is non-nil, ignore the read-only property. +CONTEXT is used to figure out what kind of specials to escape. + +The following contexts exist in Muse. +'underline _underlined text_ +'literal =monospaced text= or region (monospaced, escaped) +'emphasis *emphasized text* +'email email@example.com +'url http://example.com +'url-desc [[...][description of an explicit link]] +'image [[image.png]] +'example region (monospaced, block context, escaped) +'verbatim region (escaped) +'footnote footnote text +'document normal text" + (let ((specials (muse-style-element :specials nil t))) + (cond ((functionp specials) + (setq specials (funcall specials context))) + ((symbolp specials) + (setq specials (symbol-value specials)))) + (if (functionp specials) + (funcall specials beg end ignore-read-only) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (while (< (point) (point-max)) + (if (and (not ignore-read-only) + (get-text-property (point) 'read-only)) + (goto-char (or (next-single-property-change (point) 'read-only) + (point-max))) + (let ((repl (or (assoc (char-after) specials) + (assoc (char-after) + muse-publish-markup-specials)))) + (if (null repl) + (forward-char 1) + (delete-char 1) + (insert-before-markers (cdr repl))))))))))) + +(defun muse-publish-markup-word () + (let* ((beg (match-beginning 2)) + (end (1- (match-end 2))) + (leader (buffer-substring-no-properties beg end)) + open-tag close-tag mark-read-only loc context) + (cond + ((string= leader "_") + (setq context 'underline + open-tag (muse-markup-text 'begin-underline) + close-tag (muse-markup-text 'end-underline))) + ((string= leader "=") + (setq context 'literal + open-tag (muse-markup-text 'begin-literal) + close-tag (muse-markup-text 'end-literal)) + (setq mark-read-only t)) + (t + (let ((l (length leader))) + (setq context 'emphasis) + (cond + ((= l 1) (setq open-tag (muse-markup-text 'begin-emph) + close-tag (muse-markup-text 'end-emph))) + ((= l 2) (setq open-tag (muse-markup-text 'begin-more-emph) + close-tag (muse-markup-text 'end-more-emph))) + ((= l 3) (setq open-tag (muse-markup-text 'begin-most-emph) + close-tag (muse-markup-text 'end-most-emph))) + (t (setq context nil)))))) + (if (and context + (not (get-text-property beg 'muse-link)) + (setq loc (search-forward leader nil t)) + (or (eobp) (not (eq (char-syntax (char-after loc)) ?w))) + (not (eq (char-syntax (char-before (point))) ?\ )) + (not (get-text-property (point) 'muse-link))) + (progn + (replace-match "") + (delete-region beg end) + (setq end (point-marker)) + (muse-insert-markup close-tag) + (goto-char beg) + (muse-insert-markup open-tag) + (setq beg (point)) + (when mark-read-only + (muse-publish-escape-specials beg end t context) + (muse-publish-mark-read-only beg end)) + (set-marker end nil)) + (backward-char)) + nil)) + +(defun muse-publish-markup-emdash () + (unless (get-text-property (match-beginning 0) 'muse-link) + (let ((prespace (match-string 1)) + (postspace (match-string 2))) + (delete-region (match-beginning 0) (match-end 0)) + (muse-insert-markup (muse-markup-text 'emdash prespace postspace)) + (when (eq (char-after) ?\<) + (insert ?\n))))) + +(defun muse-publish-markup-enddots () + (unless (get-text-property (match-beginning 0) 'muse-link) + (delete-region (match-beginning 0) (match-end 0)) + (muse-insert-markup (muse-markup-text 'enddots)))) + +(defun muse-publish-markup-dots () + (unless (get-text-property (match-beginning 0) 'muse-link) + (delete-region (match-beginning 0) (match-end 0)) + (muse-insert-markup (muse-markup-text 'dots)))) + +(defun muse-publish-markup-rule () + (unless (get-text-property (match-beginning 0) 'muse-link) + (delete-region (match-beginning 0) (match-end 0)) + (muse-insert-markup (muse-markup-text 'rule)))) + +(defun muse-publish-markup-no-break-space () + (unless (get-text-property (match-beginning 0) 'muse-link) + (delete-region (match-beginning 0) (match-end 0)) + (muse-insert-markup (muse-markup-text 'no-break-space)))) + +(defun muse-publish-markup-heading () + (let* ((len (length (match-string 1))) + (start (muse-markup-text + (cond ((= len 1) 'section) + ((= len 2) 'subsection) + ((= len 3) 'subsubsection) + (t 'section-other)) + len)) + (end (muse-markup-text + (cond ((= len 1) 'section-end) + ((= len 2) 'subsection-end) + ((= len 3) 'subsubsection-end) + (t 'section-other-end)) + len))) + (delete-region (match-beginning 0) (match-end 0)) + (muse-insert-markup start) + (end-of-line) + (when end + (muse-insert-markup end)) + (forward-line 1) + (unless (eq (char-after) ?\n) + (insert "\n")) + (muse-publish-section-close len))) + +(defvar muse-publish-footnotes nil) + +(defun muse-publish-markup-footnote () + "Scan ahead and snarf up the footnote body." + (cond + ((get-text-property (match-beginning 0) 'muse-link) + nil) + ((= (muse-line-beginning-position) (match-beginning 0)) + "") + (t + (let ((footnote (save-match-data + (string-to-number (match-string 1)))) + (oldtext (match-string 0)) + footnotemark) + (delete-region (match-beginning 0) (match-end 0)) + (save-excursion + (when (re-search-forward (format "^\\[%d\\]\\s-+" footnote) nil t) + (let* ((start (match-beginning 0)) + (beg (goto-char (match-end 0))) + (end (save-excursion + (if (search-forward "\n\n" nil t) + (copy-marker (match-beginning 0)) + (goto-char (point-max)) + (skip-chars-backward "\n") + (point-marker))))) + (while (re-search-forward + (concat "^[" muse-regexp-blank "]+\\([^\n]\\)") + end t) + (replace-match "\\1" t)) + (let ((footnotemark-cmd (muse-markup-text 'footnotemark)) + (footnotemark-end-cmd (muse-markup-text 'footnotemark-end))) + (if (string= "" footnotemark-cmd) + (setq footnotemark + (concat (muse-markup-text 'footnote) + (muse-publish-escape-specials-in-string + (buffer-substring-no-properties beg end) + 'footnote) + (muse-markup-text 'footnote-end))) + (setq footnotemark (format footnotemark-cmd footnote + footnotemark-end-cmd)) + (unless muse-publish-footnotes + (set (make-local-variable 'muse-publish-footnotes) + (make-vector 256 nil))) + (unless (aref muse-publish-footnotes footnote) + (setq footnotemark + (concat + footnotemark + (concat (format (muse-markup-text 'footnotetext) + footnote) + (buffer-substring-no-properties beg end) + (muse-markup-text 'footnotetext-end)))) + (aset muse-publish-footnotes footnote footnotemark)))) + (goto-char end) + (skip-chars-forward "\n") + (delete-region start (point)) + (set-marker end nil)))) + (if footnotemark + (muse-insert-markup footnotemark) + (insert oldtext)))))) + +(defun muse-publish-markup-fn-sep () + (delete-region (match-beginning 0) (match-end 0)) + (muse-insert-markup (muse-markup-text 'fn-sep))) + +(defun muse-insert-markup-end-list (&rest args) + (let ((beg (point))) + (apply 'insert args) + (add-text-properties beg (point) '(muse-end-list t)) + (muse-publish-mark-read-only beg (point)))) + +(defun muse-publish-determine-dl-indent (continue indent-sym determine-sym) + ;; If the caller doesn't know how much indentation to use, figure it + ;; out ourselves. It is assumed that `muse-forward-list-item' has + ;; been called just before this to set the match data. + (when (and continue + (symbol-value determine-sym)) + (save-match-data + ;; snarf all leading whitespace + (let ((indent (and (match-beginning 2) + (buffer-substring (match-beginning 1) + (match-beginning 2))))) + (when (and indent + (not (string= indent ""))) + (set indent-sym indent) + (set determine-sym nil)))))) + +(defun muse-publish-surround-dl (indent post-indent) + (let* ((beg-item (muse-markup-text 'begin-dl-item)) + (end-item (muse-markup-text 'end-dl-item)) + (beg-ddt (muse-markup-text 'begin-ddt)) ;; term + (end-ddt (muse-markup-text 'end-ddt)) + (beg-dde (muse-markup-text 'begin-dde)) ;; definition + (end-dde (muse-markup-text 'end-dde)) + (continue t) + (no-terms t) + beg) + (while continue + ;; envelope this as one term+definitions unit -- HTML does not + ;; need this, but DocBook and Muse's custom XML format do + (muse-insert-markup beg-item) + (when (looking-at muse-dl-term-regexp) + ;; find the term and wrap it with published markup + (setq beg (point) + no-terms nil) + (goto-char (match-end 1)) + (delete-region (point) (match-end 0)) + (muse-insert-markup-end-list end-ddt) + ;; if definition is immediately after term, move to next line + (unless (eq (char-after) ?\n) + (insert ?\n)) + (save-excursion + (goto-char beg) + (delete-region (point) (match-beginning 1)) + (muse-insert-markup beg-ddt))) + ;; handle pathological edge case where there is no term -- I + ;; would prefer to just disallow this, but people seem to want + ;; this behavior + (when (and no-terms + (looking-at (concat "[" muse-regexp-blank "]*::" + "[" muse-regexp-blank "]*"))) + (delete-region (point) (match-end 0)) + ;; but only do this once + (setq no-terms nil)) + (setq beg (point) + ;; move past current item + continue (muse-forward-list-item 'dl-term indent)) + (save-restriction + (narrow-to-region beg (point)) + (goto-char (point-min)) + ;; publish each definition that we find, defaulting to an + ;; empty definition if none are found + (muse-publish-surround-text beg-dde end-dde + (lambda (indent) + (muse-forward-list-item 'dl-entry indent)) + indent post-indent + #'muse-publish-determine-dl-indent) + (goto-char (point-max)) + (skip-chars-backward (concat muse-regexp-blank "\n")) + (muse-insert-markup-end-list end-item) + (when continue + (goto-char (point-max))))))) + +(defun muse-publish-strip-list-indentation (list-item empty-line indent post-indent) + (let ((list-nested nil) + (indent-found nil)) + (while (< (point) (point-max)) + (when (and (looking-at list-item) + (not (or (get-text-property + (muse-list-item-critical-point) 'read-only) + (get-text-property + (muse-list-item-critical-point) 'muse-link)))) + ;; if we encounter a list item, allow no post-indent space + (setq list-nested t)) + (when (and (not (looking-at empty-line)) + (looking-at (concat indent "\\(" + (or (and list-nested "") + post-indent) + "\\)"))) + ;; if list is not nested, remove indentation + (unless indent-found + (setq post-indent (match-string 1) + indent-found t)) + (replace-match "")) + (forward-line 1)))) + +(defun muse-publish-surround-text (beg-tag end-tag move-func &optional indent post-indent determine-indent-func list-item) + (unless list-item + (setq list-item (format muse-list-item-regexp + (concat "[" muse-regexp-blank "]*")))) + (let ((continue t) + (empty-line (concat "^[" muse-regexp-blank "]*\n")) + (determine-indent (if determine-indent-func t nil)) + (new-indent indent) + (first t) + beg) + (unless indent + (setq indent (concat "[" muse-regexp-blank "]+"))) + (if post-indent + (setq post-indent (concat " \\{0," (number-to-string post-indent) + "\\}")) + (setq post-indent "")) + (while continue + (if (or (not end-tag) (string= end-tag "")) + ;; if no end of list item markup exists, treat the beginning + ;; of list item markup as it if it were the end -- this + ;; prevents multiple-level lists from being confused + (muse-insert-markup-end-list beg-tag) + (muse-insert-markup beg-tag)) + (setq beg (point) + ;; move past current item; continue is non-nil if there + ;; are more like items to be processed + continue (if (and determine-indent-func first) + (funcall move-func (concat indent post-indent)) + (funcall move-func indent))) + (when determine-indent-func + (funcall determine-indent-func continue 'new-indent 'determine-indent)) + (when continue + ;; remove list markup if we encountered another item of the + ;; same type + (replace-match "" t t nil 1)) + (save-restriction + ;; narrow to current item + (narrow-to-region beg (point)) + (goto-char (point-min)) + (if (looking-at empty-line) + ;; if initial line is blank, move to first non-blank line + (while (progn (forward-line 1) + (and (< (point) (point-max)) + (looking-at empty-line)))) + ;; otherwise, move to second line of text + (forward-line 1)) + ;; strip list indentation + (muse-publish-strip-list-indentation list-item empty-line + indent post-indent) + (skip-chars-backward (concat muse-regexp-blank "\n")) + (muse-insert-markup-end-list end-tag) + (when determine-indent-func + (setq indent new-indent)) + (when first + (setq first nil)) + (when continue + (goto-char (point-max))))))) + +(defun muse-publish-ensure-blank-line () + "Make sure that a blank line exists on the line before point." + (let ((pt (point-marker))) + (beginning-of-line) + (cond ((eq (point) (point-min)) nil) + ((prog2 (backward-char) (bolp) (forward-char)) nil) + (t (insert-before-markers "\n"))) + (goto-char pt) + (set-marker pt nil))) + +(defun muse-publish-markup-list () + "Markup a list entry. +This function works by marking up items of the same list level +and type, respecting the end-of-list property." + (let* ((str (match-string 1)) + (type (muse-list-item-type str)) + (indent (buffer-substring (muse-line-beginning-position) + (match-beginning 1))) + (post-indent (length str))) + (cond + ((or (get-text-property (muse-list-item-critical-point) 'read-only) + (get-text-property (muse-list-item-critical-point) 'muse-link)) + nil) + ((eq type 'ul) + (unless (eq (char-after (match-end 1)) ?-) + (delete-region (match-beginning 0) (match-end 0)) + (muse-publish-ensure-blank-line) + (muse-insert-markup (muse-markup-text 'begin-uli)) + (save-excursion + (muse-publish-surround-text + (muse-markup-text 'begin-uli-item) + (muse-markup-text 'end-uli-item) + (lambda (indent) + (muse-forward-list-item 'ul indent)) + indent post-indent) + (muse-insert-markup-end-list (muse-markup-text 'end-uli))) + (forward-line 1))) + ((eq type 'ol) + (delete-region (match-beginning 0) (match-end 0)) + (muse-publish-ensure-blank-line) + (muse-insert-markup (muse-markup-text 'begin-oli)) + (save-excursion + (muse-publish-surround-text + (muse-markup-text 'begin-oli-item) + (muse-markup-text 'end-oli-item) + (lambda (indent) + (muse-forward-list-item 'ol indent)) + indent post-indent) + (muse-insert-markup-end-list (muse-markup-text 'end-oli))) + (forward-line 1)) + (t + (goto-char (match-beginning 0)) + (muse-publish-ensure-blank-line) + (muse-insert-markup (muse-markup-text 'begin-dl)) + (save-excursion + (muse-publish-surround-dl indent post-indent) + (muse-insert-markup-end-list (muse-markup-text 'end-dl))) + (forward-line 1)))) + nil) + +(defun muse-publish-markup-quote () + "Markup a quoted paragraph. +The reason this function is so funky, is to prevent text properties +like read-only from being inadvertently deleted." + (let* ((ws (match-string 1)) + (centered (>= (string-width ws) 6)) + (begin-elem (if centered 'begin-center 'begin-quote-item)) + (end-elem (if centered 'end-center 'end-quote-item))) + (replace-match "" t t nil 1) + (unless centered + (muse-insert-markup (muse-markup-text 'begin-quote))) + (muse-publish-surround-text (muse-markup-text begin-elem) + (muse-markup-text end-elem) + (function (lambda (indent) + (muse-forward-paragraph) + nil))) + (unless centered + (muse-insert-markup (muse-markup-text 'end-quote))))) + +(defun muse-publish-markup-leading-space (markup-space multiple) + (let (count) + (when (and markup-space + (>= (setq count (skip-chars-forward " ")) 0)) + (delete-region (muse-line-beginning-position) (point)) + (while (> count 0) + (muse-insert-markup markup-space) + (setq count (- count multiple)))))) + +(defun muse-publish-markup-verse () + (let ((leader (match-string 0))) + (goto-char (match-beginning 0)) + (muse-insert-markup (muse-markup-text 'begin-verse)) + (while (looking-at leader) + (replace-match "") + (muse-publish-markup-leading-space (muse-markup-text 'verse-space) 2) + (let ((beg (point))) + (end-of-line) + (cond + ((bolp) + (let ((text (muse-markup-text 'empty-verse-line))) + (when text (muse-insert-markup text)))) + ((save-excursion + (save-match-data + (forward-line 1) + (or (looking-at (concat leader "[" + muse-regexp-blank + "]*$")) + (not (looking-at leader))))) + (let ((begin-text (muse-markup-text 'begin-last-stanza-line)) + (end-text (muse-markup-text 'end-last-stanza-line))) + (when end-text (muse-insert-markup end-text)) + (goto-char beg) + (when begin-text (muse-insert-markup begin-text)) + (end-of-line))) + (t + (let ((begin-text (muse-markup-text 'begin-verse-line)) + (end-text (muse-markup-text 'end-verse-line))) + (when end-text (muse-insert-markup end-text)) + (goto-char beg) + (when begin-text (muse-insert-markup begin-text)) + (end-of-line)))) + (forward-line 1)))) + (muse-insert-markup (muse-markup-text 'end-verse)) + (insert ?\n)) + +(defun muse-publish-trim-table (table) + "Remove completely blank columns from table, if at start or end of row." + ;; remove first + (catch 'found + (dolist (row (cdr table)) + (let ((el (cadr row))) + (when (and (stringp el) (not (string= el ""))) + (throw 'found t)))) + (dolist (row (cdr table)) + (setcdr row (cddr row))) + (setcar table (1- (car table)))) + ;; remove last + (catch 'found + (dolist (row (cdr table)) + (let ((el (car (last row)))) + (when (and (stringp el) (not (string= el ""))) + (throw 'found t)))) + (dolist (row (cdr table)) + (setcdr (last row 2) nil)) + (setcar table (1- (car table)))) + table) + +(defun muse-publish-table-fields (beg end) + "Parse given region as a table, returning a cons cell. +The car is the length of the longest row. + +The cdr is a list of the fields of the table, with the first +element indicating the type of the row: + 1: body, 2: header, 3: footer, hline: separator. + +The existing region will be removed, except for initial blank lines." + (unless (muse-publishing-directive "disable-tables") + (let ((longest 0) + (left 0) + (seen-hline nil) + fields field-list) + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (while (looking-at (concat "^[" muse-regexp-blank "]*$")) + (forward-line 1)) + (setq beg (point)) + (while (= left 0) + (cond + ((looking-at muse-table-hline-regexp) + (when field-list ; skip if at the beginning of table + (if seen-hline + (setq field-list (cons (cons 'hline nil) field-list)) + (dolist (field field-list) + ;; the preceding fields are header lines + (setcar field 2)) + (setq seen-hline t)))) + ((looking-at muse-table-line-regexp) + (setq fields (cons (length (match-string 1)) + (mapcar #'muse-trim-whitespace + (split-string (match-string 0) + muse-table-field-regexp))) + field-list (cons fields field-list) + longest (max (length fields) longest)) + ;; strip initial bars, if they exist + (let ((first (cadr fields))) + (when (and first (string-match "\\`|+\\s-*" first)) + (setcar (cdr fields) (replace-match "" t t first)))))) + (setq left (forward-line 1)))) + (delete-region beg end) + (if (= longest 0) + (cons 0 nil) + ;; if the last line was an hline, remove it + (when (eq (caar field-list) 'hline) + (setq field-list (cdr field-list))) + (muse-publish-trim-table (cons (1- longest) (nreverse field-list))))))) + +(defun muse-publish-markup-table () + "Style does not support tables.\n") + +(defun muse-publish-table-el-table (variant) + "Publish table.el-style tables in the format given by VARIANT." + (when (condition-case nil + (progn (require 'table) + t) + (error nil)) + (let ((muse-buf (current-buffer))) + (save-restriction + (narrow-to-region (match-beginning 0) (match-end 0)) + (goto-char (point-min)) + (forward-line 1) + (when (search-forward "|" nil t) + (with-temp-buffer + (let ((temp-buf (current-buffer))) + (with-current-buffer muse-buf + (table-generate-source variant temp-buf)) + (with-current-buffer muse-buf + (delete-region (point-min) (point-max)) + (insert-buffer-substring temp-buf) + (muse-publish-mark-read-only (point-min) (point-max)))))))))) + +(defun muse-publish-markup-table-el () + "Mark up table.el-style tables." + (cond ((muse-style-derived-p 'html) + (muse-publish-table-el-table 'html)) + ((muse-style-derived-p 'latex) + (muse-publish-table-el-table 'latex)) + ((muse-style-derived-p 'docbook) + (muse-publish-table-el-table 'cals)) + (t "Style does not support table.el tables.\n"))) + +(defun muse-publish-escape-specials-in-string (string &optional context) + "Escape specials in STRING using style-specific :specials. +CONTEXT is used to figure out what kind of specials to escape. + +See the documentation of the `muse-publish-escape-specials' +function for the list of available contexts." + (unless string + (setq string "")) + (let ((specials (muse-style-element :specials nil t))) + (cond ((functionp specials) + (setq specials (funcall specials context))) + ((symbolp specials) + (setq specials (symbol-value specials)))) + (if (functionp specials) + (funcall specials string) + (apply (function concat) + (mapcar + (lambda (ch) + (let ((repl (or (assoc ch specials) + (assoc ch muse-publish-markup-specials)))) + (if (null repl) + (char-to-string ch) + (cdr repl)))) + (append string nil)))))) + +(defun muse-publish-markup-email () + (let* ((beg (match-end 1)) + (addr (buffer-substring-no-properties beg (match-end 0)))) + (setq addr (muse-publish-escape-specials-in-string addr 'email)) + (goto-char beg) + (delete-region beg (match-end 0)) + (if (or (eq (char-before (match-beginning 0)) ?\") + (eq (char-after (match-end 0)) ?\")) + (insert addr) + (insert (format (muse-markup-text 'email-addr) addr addr))) + (muse-publish-mark-read-only beg (point)))) + +(defun muse-publish-classify-url (target) + "Transform anchors and get published name, if TARGET is a page. +The return value is two linked cons cells. The car is the type +of link, the cadr is the page name, and the cddr is the anchor." + (save-match-data + (cond ((or (null target) (string= target "")) + nil) + ((string-match "\\`[uU][rR][lL]:\\(.+\\)\\'" target) + (cons 'url (cons (match-string 1 target) nil))) + ((string-match muse-image-regexp target) + (cons 'image (cons target nil))) + ((string-match muse-url-regexp target) + (cons 'url (cons target nil))) + ((string-match muse-file-regexp target) + (cons 'file (cons target nil))) + ((string-match "#" target) + (if (eq (aref target 0) ?\#) + (cons 'anchor-ref (cons nil (substring target 1))) + (cons 'link-and-anchor + ;; match-data is changed by + ;; `muse-publish-link-page' or descendants. + (cons (save-match-data + (muse-publish-link-page + (substring target 0 (match-beginning 0)))) + (substring target (match-end 0)))))) + (t + (cons 'link (cons (muse-publish-link-page target) nil)))))) + +(defun muse-publish-url-desc (desc explicit) + (when desc + (dolist (transform muse-publish-desc-transforms) + (setq desc (save-match-data + (when desc (funcall transform desc explicit))))) + (setq desc (muse-link-unescape desc)) + (muse-publish-escape-specials-in-string desc 'url-desc))) + +(defun muse-publish-url (url &optional desc orig-url explicit) + "Resolve a URL into its final form." + (let ((unesc-url url) + (unesc-orig-url orig-url) + (unesc-desc desc) + type anchor) + ;; Transform URL + (dolist (transform muse-publish-url-transforms) + (setq url (save-match-data (when url (funcall transform url explicit))))) + ;; Classify URL + (let ((target (muse-publish-classify-url url))) + (setq type (car target) + url (if (eq type 'image) + (muse-publish-escape-specials-in-string (cadr target) + 'image) + (muse-publish-escape-specials-in-string (cadr target) 'url)) + anchor (muse-publish-escape-specials-in-string + (cddr target) 'url))) + ;; Transform description + (if desc + (setq desc (muse-publish-url-desc desc explicit)) + (when orig-url + (setq orig-url (muse-publish-url-desc orig-url explicit)))) + ;; Act on URL classification + (cond ((eq type 'anchor-ref) + (muse-markup-text 'anchor-ref anchor (or desc orig-url))) + ((and unesc-desc (string-match muse-image-regexp unesc-desc)) + (let ((ext (or (file-name-extension desc) ""))) + (setq desc (muse-publish-escape-specials-in-string unesc-desc + 'image)) + (setq desc (muse-path-sans-extension desc)) + (muse-markup-text 'image-link url desc ext))) + ((string= url "") + desc) + ((eq type 'image) + (let ((ext (or (file-name-extension url) ""))) + (setq url (muse-path-sans-extension url)) + (if desc + (muse-markup-text 'image-with-desc url ext desc) + (muse-markup-text 'image url ext)))) + ((eq type 'link-and-anchor) + (muse-markup-text 'link-and-anchor url anchor + (or desc orig-url) + (muse-path-sans-extension url))) + ((eq type 'link) + (muse-markup-text 'link url (or desc orig-url))) + (t + (or (and (or desc + ;; compare the not-escaped versions of url and + ;; orig-url + (not (string= unesc-url unesc-orig-url))) + (let ((text (muse-markup-text 'url-and-desc url + (or desc orig-url)))) + (and (not (string= text "")) + text))) + (muse-markup-text 'url url (or desc orig-url))))))) + +(defun muse-publish-insert-url (url &optional desc orig-url explicit) + "Resolve a URL into its final form." + (delete-region (match-beginning 0) (match-end 0)) + (let ((text (muse-publish-url url desc orig-url explicit))) + (when text + (muse-insert-markup text)))) + +(defun muse-publish-markup-link () + (let (desc explicit orig-link link) + (setq explicit (save-match-data + (if (string-match muse-explicit-link-regexp + (match-string 0)) + t nil))) + (setq orig-link (if explicit (match-string 1) (match-string 0))) + (setq desc (when explicit (match-string 2))) + (setq link (if explicit + (muse-handle-explicit-link orig-link) + (muse-handle-implicit-link orig-link))) + (when (and link + (or explicit + (not (or (eq (char-before (match-beginning 0)) ?\") + (eq (char-after (match-end 0)) ?\"))))) + ;; if explicit link has no user-provided description, treat it + ;; as if it were an implicit link + (when (and explicit (not desc)) + (setq explicit nil)) + (muse-publish-insert-url link desc orig-link explicit)))) + +(defun muse-publish-markup-url () + (unless (or (eq (char-before (match-beginning 0)) ?\") + (eq (char-after (match-end 0)) ?\")) + (let ((url (match-string 0))) + (muse-publish-insert-url url nil url)))) + +;; Default publishing tags + +(defcustom muse-publish-contents-depth 2 + "The number of heading levels to include with tags." + :type 'integer + :group 'muse-publish) + +(defun muse-publish-contents-tag (beg end attrs) + (set (make-local-variable 'muse-publish-generate-contents) + (cons (copy-marker (point) t) + (let ((depth (cdr (assoc "depth" attrs)))) + (or (and depth (string-to-number depth)) + muse-publish-contents-depth))))) + +(defun muse-publish-verse-tag (beg end) + (muse-publish-ensure-block beg end) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (delete-char 1) + (while (< (point) (point-max)) + (insert "> ") + (forward-line)) + (if (eq ?\ (char-syntax (char-before))) + (delete-char -1))))) + +(defun muse-publish-mark-read-only (beg end) + "Add read-only properties to the given region." + (add-text-properties beg end '(rear-nonsticky (read-only) read-only t)) + nil) + +(defun muse-publish-mark-link (&optional beg end) + "Indicate that the given region is a Muse link, so that other +markup elements respect it. If a region is not specified, use +the 0th match data to determine it. + +This is usually applied to explicit links." + (unless beg (setq beg (match-beginning 0))) + (unless end (setq end (match-end 0))) + (add-text-properties beg end '(muse-link t)) + nil) + +(defun muse-publish-quote-tag (beg end) + (muse-publish-ensure-block beg) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (let ((quote-regexp "^\\(<\\(/?\\)quote>\\)")) + (muse-insert-markup (muse-markup-text 'begin-quote)) + (while (progn + (unless (looking-at (concat "[" muse-regexp-blank "\n]*" + "")) + (muse-publish-surround-text + (muse-markup-text 'begin-quote-item) + (muse-markup-text 'end-quote-item) + (function + (lambda (indent) + (muse-forward-paragraph) + (goto-char (match-end 0)) + (and (< (point) (point-max)) + (not (looking-at quote-regexp))))) + nil nil nil + quote-regexp)) + (if (>= (point) (point-max)) + t + (and (search-forward "" nil t) + (muse-goto-tag-end "quote" t) + (progn (forward-line 1) t) + (< (point) (point-max)))))) + (goto-char (point-max)) + (muse-insert-markup (muse-markup-text 'end-quote)))))) + +(defun muse-publish-code-tag (beg end) + (muse-publish-escape-specials beg end nil 'literal) + (goto-char beg) + (insert (muse-markup-text 'begin-literal)) + (goto-char end) + (insert (muse-markup-text 'end-literal)) + (muse-publish-mark-read-only beg (point))) + +(defun muse-publish-cite-tag (beg end attrs) + (let* ((type (muse-publish-get-and-delete-attr "type" attrs)) + (citetag (cond ((string-equal type "author") + 'begin-cite-author) + ((string-equal type "year") + 'begin-cite-year) + (t + 'begin-cite)))) + (goto-char beg) + (insert (muse-markup-text citetag (muse-publishing-directive "bibsource"))) + (goto-char end) + (insert (muse-markup-text 'end-cite)) + (muse-publish-mark-read-only beg (point)))) + +(defun muse-publish-src-tag (beg end attrs) + (muse-publish-example-tag beg end)) + +(defun muse-publish-example-tag (beg end) + (muse-publish-ensure-block beg end) + (muse-publish-escape-specials beg end nil 'example) + (goto-char beg) + (insert (muse-markup-text 'begin-example)) + (goto-char end) + (insert (muse-markup-text 'end-example)) + (muse-publish-mark-read-only beg (point))) + +(defun muse-publish-literal-tag (beg end attrs) + "Ensure that the text between BEG and END is not interpreted later on. + +ATTRS is an alist of attributes. + +If it contains a \"style\" element, delete the region if the +current style is neither derived from nor equal to this style. + +If it contains both a \"style\" element and an \"exact\" element +with the value \"t\", delete the region only if the current style +is exactly this style." + (let* ((style (cdr (assoc "style" attrs))) + (exact (cdr (assoc "exact" attrs))) + (exactp (and (stringp exact) (string= exact "t")))) + (if (or (not style) + (and exactp (equal (muse-style style) + muse-publishing-current-style)) + (and (not exactp) (muse-style-derived-p style))) + (muse-publish-mark-read-only beg end) + (delete-region beg end) + (when (and (bolp) (eolp) (not (eobp))) + (delete-char 1))))) + +(put 'muse-publish-literal-tag 'muse-dangerous-tag t) + +(defun muse-publish-verbatim-tag (beg end) + (muse-publish-escape-specials beg end nil 'verbatim) + (muse-publish-mark-read-only beg end)) + +(defun muse-publish-br-tag (beg end) + "Insert a line break." + (delete-region beg end) + (muse-insert-markup (muse-markup-text 'line-break))) + +(defalias 'muse-publish-class-tag 'ignore) +(defalias 'muse-publish-div-tag 'ignore) + +(defun muse-publish-call-tag-on-buffer (tag &optional attrs) + "Transform the current buffer as if it were surrounded by the tag TAG. +If attributes ATTRS are given, pass them to the tag function." + (let ((tag-info (muse-markup-tag-info tag))) + (when tag-info + (let* ((end (progn (goto-char (point-max)) (point-marker))) + (args (list (point-min) end)) + (muse-inhibit-style-tags nil)) + (when (nth 2 tag-info) + (nconc args (list attrs))) + (apply (nth 4 tag-info) args) + (set-marker end nil))))) + +(defun muse-publish-examplify-buffer (&optional attrs) + "Transform the current buffer as if it were an region." + (muse-publish-call-tag-on-buffer "example" attrs)) + +(defun muse-publish-srcify-buffer (&optional attrs) + "Transform the current buffer as if it were a region." + (muse-publish-call-tag-on-buffer "src" attrs)) + +(defun muse-publish-versify-buffer (&optional attrs) + "Transform the current buffer as if it were a region." + (muse-publish-call-tag-on-buffer "verse" attrs) + (muse-publish-markup "" + `((100 ,(concat "^[" muse-regexp-blank "]*> ") 0 + muse-publish-markup-verse))) + (goto-char (point-min))) + +(defmacro muse-publish-markup-attribute (beg end attrs reinterp &rest body) + "Evaluate BODY within the bounds of BEG and END. +ATTRS is an alist. Only the \"markup\" element of ATTRS is acted +on. + +If it is omitted, publish the region with the normal Muse rules. +If RE-INTERP is specified, this is done immediately in a new +publishing process. Currently, RE-INTERP is specified only by +the tag. + +If \"nil\", do not mark up the region at all, but prevent it from +being further interpreted by Muse. + +If \"example\", treat the region as if it was surrounded by the + tag. + +If \"src\", treat the region as if it was surrounded by the + tag. + +If \"verse\", treat the region as if it was surrounded by the + tag, to preserve newlines. + +Otherwise, it should be the name of a function to call in the +narrowed region after evaluating BODY. The function should +take the ATTRS parameter. + +BEG is modified to be the start of the published markup." + (let ((attrs-sym (make-symbol "attrs")) + (markup (make-symbol "markup")) + (markup-function (make-symbol "markup-function"))) + `(let* ((,attrs-sym ,attrs) + (,markup (muse-publish-get-and-delete-attr "markup" ,attrs-sym))) + (save-restriction + (narrow-to-region ,beg ,end) + (goto-char (point-min)) + ,@body + (if (not ,markup) + (when ,reinterp + (muse-publish-markup-region (point-min) (point-max)) + (muse-publish-mark-read-only (point-min) (point-max)) + (goto-char (point-max))) + (let ((,markup-function (read ,markup))) + (cond ((eq ,markup-function 'example) + (setq ,markup-function #'muse-publish-examplify-buffer)) + ((eq ,markup-function 'src) + (setq ,markup-function #'muse-publish-srcify-buffer)) + ((eq ,markup-function 'verse) + (setq ,markup-function #'muse-publish-versify-buffer)) + ((and ,markup-function (not (functionp ,markup-function))) + (error "Invalid markup function `%s'" ,markup)) + (t nil)) + (if ,markup-function + (funcall ,markup-function ,attrs-sym) + (muse-publish-mark-read-only (point-min) (point-max)) + (goto-char (point-max))))))))) + +(put 'muse-publish-markup-attribute 'lisp-indent-function 4) +(put 'muse-publish-markup-attribute 'edebug-form-spec + '(sexp sexp sexp sexp body)) + +(defun muse-publish-lisp-tag (beg end attrs) + (muse-publish-markup-attribute beg end attrs nil + (save-excursion + (save-restriction + (let ((str (muse-eval-lisp + (prog1 + (concat "(progn " + (buffer-substring-no-properties (point-min) + (point-max)) + ")") + (delete-region (point-min) (point-max)) + (widen))))) + (set-text-properties 0 (length str) nil str) + (insert str)))))) + +(put 'muse-publish-lisp-tag 'muse-dangerous-tag t) + +(defun muse-publish-command-tag (beg end attrs) + (muse-publish-markup-attribute beg end attrs nil + (while (looking-at "\\s-*$") + (forward-line)) + (let ((interp (muse-publish-get-and-delete-attr "interp" attrs))) + (if interp + (shell-command-on-region (point) (point-max) interp t t) + (shell-command + (prog1 + (buffer-substring-no-properties (point) (point-max)) + (delete-region (point-min) (point-max))) + t))) + ;; make sure there is a newline at end + (goto-char (point-max)) + (forward-line 0) + (unless (looking-at "\\s-*$") + (goto-char (point-max)) + (insert ?\n)) + (goto-char (point-min)))) + +(put 'muse-publish-command-tag 'muse-dangerous-tag t) + +(defun muse-publish-perl-tag (beg end attrs) + (muse-publish-command-tag beg end + (cons (cons "interp" (executable-find "perl")) + attrs))) + +(put 'muse-publish-perl-tag 'muse-dangerous-tag t) + +(defun muse-publish-php-tag (beg end attrs) + (muse-publish-command-tag beg end + (cons (cons "interp" (executable-find "php")) + attrs))) + +(put 'muse-publish-php-tag 'muse-dangerous-tag t) + +(defun muse-publish-python-tag (beg end attrs) + (muse-publish-command-tag beg end + (cons (cons "interp" (executable-find "python")) + attrs))) + +(put 'muse-publish-python-tag 'muse-dangerous-tag t) + +(defun muse-publish-ruby-tag (beg end attrs) + (muse-publish-command-tag beg end + (cons (cons "interp" (executable-find "ruby")) + attrs))) + +(put 'muse-publish-ruby-tag 'muse-dangerous-tag t) + +(defun muse-publish-comment-tag (beg end) + (if (null muse-publish-comments-p) + (delete-region beg end) + (goto-char end) + (muse-insert-markup (muse-markup-text 'comment-end)) + (muse-publish-mark-read-only beg end) + (goto-char beg) + (muse-insert-markup (muse-markup-text 'comment-begin)))) + +(defun muse-publish-include-tag (beg end attrs) + "Include the named file at the current location during publishing. + + + +The `markup' attribute controls how this file is marked up after +being inserted. See `muse-publish-markup-attribute' for an +explanation of how it works." + (let ((filename (muse-publish-get-and-delete-attr "file" attrs)) + (muse-publishing-directives (copy-alist muse-publishing-directives))) + (if filename + (setq filename (expand-file-name + filename + (file-name-directory muse-publishing-current-file))) + (error "No file attribute specified in tag")) + (muse-publish-markup-attribute beg end attrs t + (muse-insert-file-contents filename)))) + +(put 'muse-publish-include-tag 'muse-dangerous-tag t) + +(defun muse-publish-mark-up-tag (beg end attrs) + "Run an Emacs Lisp function on the region delimted by this tag. + + + +The optional \"function\" attribute controls how this section is +marked up. If used, it should be the name of a function to call +with the buffer narrowed to the delimited region. Note that no +further marking-up will be performed on this region. + +If \"function\" is omitted, use the standard Muse markup function. +This is useful for marking up content in headers and footers. + +The optional \"style\" attribute causes the region to be deleted +if the current style is neither derived from nor equal to this +style. + +If both a \"style\" attribute and an \"exact\" attribute are +provided, and \"exact\" is \"t\", delete the region only if the +current style is exactly this style." + (let* ((style (cdr (assoc "style" attrs))) + (exact (cdr (assoc "exact" attrs))) + (exactp (and (stringp exact) (string= exact "t")))) + (if (or (not style) + (and exactp (equal (muse-style style) + muse-publishing-current-style)) + (and (not exactp) (muse-style-derived-p style))) + (let* ((function (cdr (assoc "function" attrs))) + (muse-publish-use-header-footer-tags nil) + (markup-function (and function (intern-soft function)))) + (if (and markup-function (functionp markup-function)) + (save-restriction + (narrow-to-region beg end) + (funcall markup-function) + (goto-char (point-max))) + (let ((muse-publish-inhibit-style-hooks t)) + (muse-publish-markup-region beg end))) + (muse-publish-mark-read-only beg (point))) + (delete-region beg end)))) + +(put 'muse-publish-mark-up-tag 'muse-dangerous-tag t) + +;; Miscellaneous helper functions + +(defun muse-publish-strip-URL (string &rest ignored) + "If the text \"URL:\" exists at the beginning of STRING, remove it. +The text is removed regardless of whether and part of it is uppercase." + (save-match-data + (if (string-match "\\`[uU][rR][lL]:\\(.+\\)\\'" string) + (match-string 1 string) + string))) + +(defun muse-publish-markup-type (category default-func) + (let ((rule (muse-find-markup-element :overrides category (muse-style)))) + (funcall (or rule default-func)))) + +(defun muse-published-buffer-contents (buffer) + (with-current-buffer buffer + (goto-char (point-min)) + (let ((beg (and (search-forward "Emacs Muse begins here") + (muse-line-end-position))) + (end (and (search-forward "Emacs Muse ends here") + (muse-line-beginning-position)))) + (buffer-substring-no-properties beg end)))) + +(defun muse-published-contents (file) + (when (file-readable-p file) + (muse-with-temp-buffer + (muse-insert-file-contents file) + (muse-published-buffer-contents (current-buffer))))) + +(defun muse-publish-transform-output + (file temp-file output-path name gen-func &rest cleanup-exts) + "Transform the given TEMP-FILE into the OUTPUT-PATH, using GEN-FUNC." + (setq file (muse-page-name file)) + (message "Generating %s output for %s..." name file) + (if (not (funcall gen-func temp-file output-path)) + (message "Generating %s from %s...failed" name file) + (message "Generating %s output for %s...done" name file) + (muse-delete-file-if-exists temp-file) + (dolist (ext cleanup-exts) + (muse-delete-file-if-exists + (expand-file-name (concat file ext) + (file-name-directory output-path)))) + (message "Wrote %s" output-path))) + +(defun muse-publish-read-only (string) + (let ((end (1- (length string)))) + (add-text-properties 0 end + '(rear-nonsticky (read-only) read-only t) + string) + string)) + +;;; muse-publish.el ends here diff --git a/elpa/muse-3.20/muse-regexps.el b/elpa/muse-3.20/muse-regexps.el new file mode 100644 index 0000000..ad3ce3f --- /dev/null +++ b/elpa/muse-3.20/muse-regexps.el @@ -0,0 +1,270 @@ +;;; muse-regexps.el --- define regexps used by Muse + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; This file is the part of the Muse project that describes regexps +;; that are used throughout the project. + +;;; Contributors: + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse Regular Expressions +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defgroup muse-regexp nil + "Regular expressions used in publishing and syntax highlighting." + :group 'muse) + +;;; Deal with the lack of character classes for regexps in Emacs21 and +;;; XEmacs + +(defcustom muse-regexp-use-character-classes 'undecided + "Indicate whether to use extended character classes like [:space:]. +If 'undecided, Muse will use them if your emacs is known to support them. + +Emacs 22 and Emacs 21.3.50 are known to support them. XEmacs +does not support them. + +Emacs 21.2 or higher support them, but with enough annoying edge +cases that the sanest default is to leave them disabled." + :type '(choice (const :tag "Yes" t) + (const :tag "No" nil) + (const :tag "Let Muse decide" undecided)) + :group 'muse-regexp) + +(defvar muse-regexp-emacs-revision + (save-match-data + (and (string-match "^[0-9]+\\.[0-9]+\\.\\([0-9]+\\)" + emacs-version) + (match-string 1 emacs-version) + (string-to-number (match-string 1 emacs-version)))) + "The revision number of this version of Emacs.") + +(defun muse-extreg-usable-p () + "Return non-nil if extended character classes can be used, +nil otherwise. + +This is used when deciding the initial values of the muse-regexp +options." + (cond + ((eq muse-regexp-use-character-classes t) + t) + ((eq muse-regexp-use-character-classes nil) + nil) + ((featurep 'xemacs) nil) ; unusable on XEmacs + ((> emacs-major-version 21) t) ; usable if > 21 + ((< emacs-major-version 21) nil) + ((< emacs-minor-version 3) nil) + ;; don't use if version is of format 21.x + ((null muse-regexp-emacs-revision) nil) + ;; only trust 21.3.50 or higher + ((>= muse-regexp-emacs-revision 50) t) + (t nil))) + +(defcustom muse-regexp-blank + (if (muse-extreg-usable-p) + "[:blank:]" + " \t") + "Regexp to use in place of \"[:blank:]\". +This should be something that matches spaces and tabs. + +It is like a regexp, but should be embeddable inside brackets. +Muse will detect the appropriate value correctly most of +the time." + :type 'string + :options '("[:blank:]" " \t") + :group 'muse-regexp) + +(defcustom muse-regexp-alnum + (if (muse-extreg-usable-p) + "[:alnum:]" + "A-Za-z0-9") + "Regexp to use in place of \"[:alnum:]\". +This should be something that matches all letters and numbers. + +It is like a regexp, but should be embeddable inside brackets. +muse will detect the appropriate value correctly most of +the time." + :type 'string + :options '("[:alnum:]" "A-Za-z0-9") + :group 'muse-regexp) + +(defcustom muse-regexp-lower + (if (muse-extreg-usable-p) + "[:lower:]" + "a-z") + "Regexp to use in place of \"[:lower:]\". +This should match all lowercase characters. + +It is like a regexp, but should be embeddable inside brackets. +muse will detect the appropriate value correctly most of +the time." + :type 'string + :options '("[:lower:]" "a-z") + :group 'muse-regexp) + +(defcustom muse-regexp-upper + (if (muse-extreg-usable-p) + "[:upper:]" + "A-Z") + "Regexp to use in place of \"[:upper:]\". +This should match all uppercase characters. + +It is like a regexp, but should be embeddable inside brackets. +muse will detect the appropriate value correctly most of +the time." + :type 'string + :options '("[:upper:]" "A-Z") + :group 'muse-regexp) + +;;; Regexps used to define Muse publishing syntax + +(defcustom muse-list-item-regexp + (concat "^%s\\(\\([^\n" muse-regexp-blank "].*?\\)?::" + "\\(?:[" muse-regexp-blank "]+\\|$\\)" + "\\|[" muse-regexp-blank "]-[" muse-regexp-blank "]*" + "\\|[" muse-regexp-blank "][0-9]+\\.[" muse-regexp-blank "]*\\)") + "Regexp used to match the beginning of a list item. +The '%s' will be replaced with a whitespace regexp when publishing." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-ol-item-regexp (concat "\\`[" muse-regexp-blank "]+[0-9]+\\.") + "Regexp used to match an ordered list item." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-ul-item-regexp (concat "\\`[" muse-regexp-blank "]+-") + "Regexp used to match an unordered list item." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-dl-term-regexp + (concat "[" muse-regexp-blank "]*\\(.+?\\)[" + muse-regexp-blank "]+::\\(?:[" muse-regexp-blank "]+\\|$\\)") + "Regexp used to match a definition list term. +The first match string must contain the term." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-dl-entry-regexp (concat "\\`[" muse-regexp-blank "]*::") + "Regexp used to match a definition list entry." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-table-field-regexp + (concat "[" muse-regexp-blank "]+\\(|+\\)\\(?:[" + muse-regexp-blank "]\\|$\\)") + "Regexp used to match table separators when publishing." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-table-line-regexp (concat ".*" muse-table-field-regexp ".*") + "Regexp used to match a table line when publishing." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-table-hline-regexp (concat "[" muse-regexp-blank + "]*|[-+]+|[" muse-regexp-blank + "]*") + "Regexp used to match a horizontal separator line in a table." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-table-el-border-regexp (concat "[" muse-regexp-blank "]*" + "\\+\\(-*\\+\\)+" + "[" muse-regexp-blank "]*") + "Regexp used to match the beginning and end of a table.el-style table." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-table-el-line-regexp (concat "[" muse-regexp-blank "]*" + "|\\(.*|\\)*" + "[" muse-regexp-blank "]*") + "Regexp used to match a table line of a table.el-style table." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-tag-regexp + (concat "<\\([^/" muse-regexp-blank "\n][^" muse-regexp-blank + "\n]*\\)\\(\\s-+[^<>]+[^\n]\\)?\\(/\\)?>") + "A regexp used to find XML-style tags within a buffer when publishing. +Group 1 should be the tag name, group 2 the properties, and group +3 the optional immediate ending slash." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-explicit-link-regexp + "\\[\\[\\([^][\n]+\\)\\]\\(?:\\[\\([^][\n]+\\)\\]\\)?\\]" + "Regexp used to match [[target][description]] links. +Paren group 1 must match the URL, and paren group 2 the description." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-implicit-link-regexp + (concat "\\([^" muse-regexp-blank "\n]+\\)") + "Regexp used to match an implicit link. +An implicit link is the largest block of text to be checked for +URLs and bare WikiNames by the `muse-link-at-point' function. +Paren group 1 is the text to be checked. + +URLs are checked by default. To get WikiNames, load +muse-wiki.el. + +This is only used when you are using muse-mode.el, but not +muse-colors.el. + +If the above applies, and you want to match things with spaces in +them, you will have to modify this." + :type 'regexp + :group 'muse-regexp) + +;;; Regexps used to determine file types + +(defcustom muse-file-regexp + (concat "\\`[~/]\\|\\?\\|/\\'\\|\\." + "\\(html?\\|pdf\\|mp3\\|el\\|zip\\|txt\\|tar\\)" + "\\(\\.\\(gz\\|bz2\\)\\)?\\'") + "A link matching this regexp will be regarded as a link to a file." + :type 'regexp + :group 'muse-regexp) + +(defcustom muse-image-regexp + "\\.\\(eps\\|gif\\|jp\\(e?g\\)\\|p\\(bm\\|ng\\)\\|tiff\\|x\\([bp]m\\)\\)\\'" + "A link matching this regexp will be published inline as an image. +For example: + + [[./wife.jpg][A picture of my wife]] + +If you omit the description, the alt tag of the resulting HTML +buffer will be the name of the file." + :type 'regexp + :group 'muse-regexp) + +(provide 'muse-regexps) + +;;; muse-regexps.el ends here diff --git a/elpa/muse-3.20/muse-texinfo.el b/elpa/muse-3.20/muse-texinfo.el new file mode 100644 index 0000000..4ad0092 --- /dev/null +++ b/elpa/muse-3.20/muse-texinfo.el @@ -0,0 +1,346 @@ +;;; muse-texinfo.el --- publish entries to Texinfo format or PDF + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Contributors: + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse Texinfo Publishing +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'muse-publish) +(require 'muse-latex) +(require 'texnfo-upd) + +(defgroup muse-texinfo nil + "Rules for marking up a Muse file as a Texinfo article." + :group 'muse-publish) + +(defcustom muse-texinfo-process-natively nil + "If non-nil, use the Emacs `texinfmt' module to make Info files." + :type 'boolean + :require 'texinfmt + :group 'muse-texinfo) + +(defcustom muse-texinfo-extension ".texi" + "Default file extension for publishing Texinfo files." + :type 'string + :group 'muse-texinfo) + +(defcustom muse-texinfo-info-extension ".info" + "Default file extension for publishing Info files." + :type 'string + :group 'muse-texinfo) + +(defcustom muse-texinfo-pdf-extension ".pdf" + "Default file extension for publishing PDF files." + :type 'string + :group 'muse-texinfo) + +(defcustom muse-texinfo-header + "\\input texinfo @c -*-texinfo-*- + +@setfilename (concat (muse-page-name) \".info\") +@settitle (muse-publishing-directive \"title\") + +@documentencoding iso-8859-1 + +@iftex +@finalout +@end iftex + +@titlepage +@title (muse-publishing-directive \"title\") +@author (muse-publishing-directive \"author\") +@end titlepage + +(and muse-publish-generate-contents \"@contents\") + +@node Top, Overview, , (dir) +@top Overview +@c Page published by Emacs Muse begins here\n\n" + "Text to prepend to a Muse page being published as Texinfo. +This may be text or a filename. +It may contain markup tags." + :type 'string + :group 'muse-texinfo) + +(defcustom muse-texinfo-footer + "\n@c Page published by Emacs Muse ends here +@bye\n" + "Text to append to a Muse page being published as Texinfo. +This may be text or a filename. +It may contain markup tags." + :type 'string + :group 'muse-texinfo) + +(defcustom muse-texinfo-markup-regexps nil + "List of markup rules for publishing a Muse page to Texinfo. +For more on the structure of this list, see `muse-publish-markup-regexps'." + :type '(repeat (choice + (list :tag "Markup rule" + integer + (choice regexp symbol) + integer + (choice string function symbol)) + function)) + :group 'muse-texinfo) + +(defcustom muse-texinfo-markup-functions + '((table . muse-texinfo-markup-table) + (heading . muse-texinfo-markup-heading)) + "An alist of style types to custom functions for that kind of text. +For more on the structure of this list, see +`muse-publish-markup-functions'." + :type '(alist :key-type symbol :value-type function) + :group 'muse-texinfo) + +(defcustom muse-texinfo-markup-strings + '((image-with-desc . "@center @image{%1%, , , %3%, %2%}@*\n@center %3%") + (image . "@noindent @image{%s, , , , %s}") + (image-link . "@uref{%s, %s.%s}") + (anchor-ref . "@ref{%s, %s}") + (url . "@uref{%s, %s}") + (link . "@ref{Top, %2%, , %1%, }") + (link-and-anchor . "@ref{%3%, %2%, , %1%, %3%}") + (email-addr . "@email{%s}") + (anchor . "@anchor{%s} ") + (emdash . "---") + (comment-begin . "@ignore\n") + (comment-end . "\n@end ignore\n") + (rule . "@sp 1") + (no-break-space . "@w{ }") + (line-break . "@*") + (enddots . "@enddots{}") + (dots . "@dots{}") + (section . "@chapter ") + (subsection . "@section ") + (subsubsection . "@subsection ") + (section-other . "@subsubheading ") + (footnote . "@footnote{") + (footnote-end . "}") + (begin-underline . "_") + (end-underline . "_") + (begin-literal . "@samp{") + (end-literal . "}") + (begin-emph . "@emph{") + (end-emph . "}") + (begin-more-emph . "@strong{") + (end-more-emph . "}") + (begin-most-emph . "@strong{@emph{") + (end-most-emph . "}}") + (begin-verse . "@display\n") + (end-verse-line . "") + (verse-space . "@ @ ") + (end-verse . "\n@end display") + (begin-example . "@example\n") + (end-example . "\n@end example") + (begin-center . "@quotation\n") + (end-center . "\n@end quotation") + (begin-quote . "@quotation\n") + (end-quote . "\n@end quotation") + (begin-cite . "") + (begin-cite-author . "") + (begin-cite-year . "") + (end-cite . "") + (begin-uli . "@itemize @bullet\n") + (end-uli . "\n@end itemize") + (begin-uli-item . "@item\n") + (begin-oli . "@enumerate\n") + (end-oli . "\n@end enumerate") + (begin-oli-item . "@item\n") + (begin-dl . "@table @strong\n") + (end-dl . "\n@end table") + (begin-ddt . "@item ")) + "Strings used for marking up text. +These cover the most basic kinds of markup, the handling of which +differs little between the various styles." + :type '(alist :key-type symbol :value-type string) + :group 'muse-texinfo) + +(defcustom muse-texinfo-markup-specials + '((?@ . "@@") + (?{ . "@{") + (?} . "@}")) + "A table of characters which must be represented specially." + :type '(alist :key-type character :value-type string) + :group 'muse-texinfo) + +(defcustom muse-texinfo-markup-specials-url + '((?@ . "@@") + (?{ . "@{") + (?} . "@}") + (?, . "@comma{}")) + "A table of characters which must be represented specially. +These are applied to URLs." + :type '(alist :key-type character :value-type string) + :group 'muse-texinfo) + +(defun muse-texinfo-decide-specials (context) + "Determine the specials to escape, depending on CONTEXT." + (cond ((memq context '(underline literal emphasis email url url-desc image + footnote)) + muse-texinfo-markup-specials-url) + (t muse-texinfo-markup-specials))) + +(defun muse-texinfo-markup-table () + (let* ((table-info (muse-publish-table-fields (match-beginning 0) + (match-end 0))) + (row-len (car table-info)) + (field-list (cdr table-info))) + (when table-info + (muse-insert-markup "@multitable @columnfractions") + (dotimes (field row-len) + (muse-insert-markup " " (number-to-string (/ 1.0 row-len)))) + (dolist (fields field-list) + (let ((type (car fields))) + (unless (eq type 'hline) + (setq fields (cdr fields)) + (if (= type 2) + (muse-insert-markup "\n@headitem ") + (muse-insert-markup "\n@item ")) + (insert (car fields)) + (setq fields (cdr fields)) + (dolist (field fields) + (muse-insert-markup " @tab ") + (insert field))))) + (muse-insert-markup "\n@end multitable") + (insert ?\n)))) + +(defun muse-texinfo-remove-links (string) + "Remove explicit links from STRING, replacing them with the link +description. + +If no description exists for the link, use the link itself." + (let ((start nil)) + (while (setq start (string-match muse-explicit-link-regexp string + start)) + (setq string + (replace-match (or (match-string 2 string) + (match-string 1 string)) + t t string))) + string)) + +(defun muse-texinfo-protect-wikiwords (start end) + "Protect all wikiwords from START to END from further processing." + (and (boundp 'muse-wiki-wikiword-regexp) + (featurep 'muse-wiki) + (save-excursion + (goto-char start) + (while (re-search-forward muse-wiki-wikiword-regexp end t) + (muse-publish-mark-read-only (match-beginning 0) + (match-end 0)))))) + +(defun muse-texinfo-markup-heading () + (save-excursion + (muse-publish-markup-heading)) + (let* ((eol (muse-line-end-position)) + (orig-heading (buffer-substring (point) eol)) + (beg (point))) + (delete-region (point) eol) + ;; don't allow links to be published in headings + (insert (muse-texinfo-remove-links orig-heading)) + (muse-texinfo-protect-wikiwords beg (point)))) + +(defun muse-texinfo-munge-buffer () + (muse-latex-fixup-dquotes) + (texinfo-insert-node-lines (point-min) (point-max) t) + (texinfo-all-menus-update t)) + +(defun muse-texinfo-pdf-browse-file (file) + (shell-command (concat "open " file))) + +(defun muse-texinfo-info-generate (file output-path final-target) + ;; The version of `texinfmt.el' that comes with Emacs 21 doesn't + ;; support @documentencoding, so hack it in. + (when (and (not (featurep 'xemacs)) + (eq emacs-major-version 21)) + (put 'documentencoding 'texinfo-format + 'texinfo-discard-line-with-args)) + ;; Most versions of `texinfmt.el' do not support @headitem, so hack + ;; it in. + (unless (get 'headitem 'texinfo-format) + (put 'headitem 'texinfo-format 'texinfo-multitable-item)) + (muse-publish-transform-output + file output-path final-target "Info" + (function + (lambda (file output-path) + (if muse-texinfo-process-natively + (save-window-excursion + (save-excursion + (find-file file) + (let ((inhibit-read-only t)) + (texinfo-format-buffer)) + (save-buffer) + (kill-buffer (current-buffer)) + (let ((buf (get-file-buffer file))) + (with-current-buffer buf + (set-buffer-modified-p nil) + (kill-buffer (current-buffer)))) + t)) + (let ((result (shell-command + (concat "makeinfo --enable-encoding --output=" + output-path " " file)))) + (if (or (not (numberp result)) + (eq result 0)) + t + nil))))))) + +(defun muse-texinfo-pdf-generate (file output-path final-target) + (let ((muse-latex-pdf-program "pdftex") + (muse-latex-pdf-cruft '(".aux" ".cp" ".fn" ".ky" ".log" ".pg" ".toc" + ".tp" ".vr"))) + (muse-latex-pdf-generate file output-path final-target))) + +;;; Register the Muse TEXINFO Publishers + +(muse-define-style "texi" + :suffix 'muse-texinfo-extension + :regexps 'muse-texinfo-markup-regexps + :functions 'muse-texinfo-markup-functions + :strings 'muse-texinfo-markup-strings + :specials 'muse-texinfo-decide-specials + :after 'muse-texinfo-munge-buffer + :header 'muse-texinfo-header + :footer 'muse-texinfo-footer + :browser 'find-file) + +(muse-derive-style "info" "texi" + :final 'muse-texinfo-info-generate + :link-suffix 'muse-texinfo-info-extension + :osuffix 'muse-texinfo-info-extension + :browser 'info) + +(muse-derive-style "info-pdf" "texi" + :final 'muse-texinfo-pdf-generate + :link-suffix 'muse-texinfo-pdf-extension + :osuffix 'muse-texinfo-pdf-extension + :browser 'muse-texinfo-pdf-browse-file) + +(provide 'muse-texinfo) + +;;; muse-texinfo.el ends here diff --git a/elpa/muse-3.20/muse-wiki.el b/elpa/muse-3.20/muse-wiki.el new file mode 100644 index 0000000..e2cd3a2 --- /dev/null +++ b/elpa/muse-3.20/muse-wiki.el @@ -0,0 +1,498 @@ +;;; muse-wiki.el --- wiki features for Muse + +;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; Author: Yann Hodique +;; Keywords: + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Contributors: + +;; Per B. Sederberg (per AT med DOT upenn DOT edu) made it so that all +;; files in a Muse project can become implicit links. + +;;; Code: + +(require 'muse-regexps) +(require 'muse-mode) + +(eval-when-compile + (require 'muse-colors)) + +(defgroup muse-wiki nil + "Options controlling the behavior of Emacs Muse Wiki features." + :group 'muse-mode) + +(defcustom muse-wiki-use-wikiword t + "Whether to use color and publish bare WikiNames." + :type 'boolean + :group 'muse-wiki) + +(defcustom muse-wiki-allow-nonexistent-wikiword nil + "Whether to color bare WikiNames that don't have an existing file." + :type 'boolean + :group 'muse-wiki) + +(defcustom muse-wiki-match-all-project-files nil + "If non-nil, Muse will color and publish implicit links to any +file in your project, regardless of whether its name is a WikiWord." + :type 'boolean + :group 'muse-wiki) + +(defcustom muse-wiki-ignore-implicit-links-to-current-page nil + "If non-nil, Muse will not recognize implicit links to the current +page, both when formatting and publishing." + :type 'boolean + :group 'muse-wiki) + +(defvar muse-wiki-project-file-regexp nil + "Regexp used to match the files in the current project. + +This is set by `muse-wiki-update-project-file-regexp' automatically +when `muse-wiki-match-all-project-files' is non-nil.") +(make-variable-buffer-local 'muse-wiki-project-file-regexp) + +(defun muse-wiki-update-project-file-regexp () + "Update a local copy of `muse-wiki-project-file-regexp' to include +all the files in the project." + ;; see if the user wants to match project files + (when muse-wiki-match-all-project-files + (let ((files (mapcar #'car (muse-project-file-alist (muse-project))))) + (setq muse-wiki-project-file-regexp + (when files + (concat "\\(" + ;; include all files from the project + (regexp-opt files 'words) + "\\)")))) + ;; update coloring setup + (when (featurep 'muse-colors) + (muse-colors-define-highlighting 'muse-mode muse-colors-markup)))) + +(add-hook 'muse-update-values-hook + 'muse-wiki-update-project-file-regexp) +(add-hook 'muse-project-file-alist-hook + 'muse-wiki-update-project-file-regexp) + +(defcustom muse-wiki-wikiword-regexp + (concat "\\<\\(\\(?:[" muse-regexp-upper + "]+[" muse-regexp-lower "]+\\)\\(?:[" + muse-regexp-upper "]+[" muse-regexp-lower "]+\\)+\\)") + "Regexp used to match WikiWords." + :set (function + (lambda (sym value) + (set sym value) + (when (featurep 'muse-colors) + (muse-colors-define-highlighting 'muse-mode muse-colors-markup)))) + :type 'regexp + :group 'muse-wiki) + +(defcustom muse-wiki-ignore-bare-project-names nil + "Determine whether project names without a page specifer are links. + +If non-nil, project names without a page specifier will not be +considered links. + +When nil, project names without a specifier are highlighted and +they link to the default page of the project that they name." + :type 'boolean + :group 'muse-wiki) + +(defvar muse-wiki-interwiki-regexp nil + "Regexp that matches all interwiki links. + +This is automatically generated by setting `muse-wiki-interwiki-alist'. +It can also be set by calling `muse-wiki-update-interwiki-regexp'.") + +(defcustom muse-wiki-interwiki-delimiter "#\\|::" + "Delimiter regexp used for InterWiki links. + +If you use groups, use only shy groups." + :type 'regexp + :group 'muse-wiki) + +(defcustom muse-wiki-interwiki-replacement ": " + "Regexp used for replacing `muse-wiki-interwiki-delimiter' in +InterWiki link descriptions. + +If you want this replacement to happen, you must add +`muse-wiki-publish-pretty-interwiki' to +`muse-publish-desc-transforms'." + :type 'regexp + :group 'muse-wiki) + +(eval-when-compile + (defvar muse-wiki-interwiki-alist)) + +(defun muse-wiki-project-files-with-spaces (&optional project) + "Return a list of files in PROJECT that have spaces." + (setq project (muse-project project)) + (let ((flist nil)) + (save-match-data + (dolist (entry (muse-project-file-alist project)) + (when (string-match " " (car entry)) + (setq flist (cons (car entry) flist))))) + flist)) + +(defun muse-wiki-update-interwiki-regexp () + "Update the value of `muse-wiki-interwiki-regexp' based on +`muse-wiki-interwiki-alist' and `muse-project-alist'." + (if (null muse-project-alist) + (setq muse-wiki-interwiki-regexp nil) + (let ((old-value muse-wiki-interwiki-regexp)) + (setq muse-wiki-interwiki-regexp + (concat "\\<\\(" (regexp-opt (mapcar #'car muse-project-alist)) + (when muse-wiki-interwiki-alist + (let ((interwiki-rules + (mapcar #'car muse-wiki-interwiki-alist))) + (when interwiki-rules + (concat "\\|" (regexp-opt interwiki-rules))))) + "\\)\\(?:\\(" muse-wiki-interwiki-delimiter + "\\)\\(" + (when muse-wiki-match-all-project-files + ;; append the files from the project + (let ((files nil)) + (dolist (proj muse-project-alist) + (setq files + (nconc (muse-wiki-project-files-with-spaces + (car proj)) + files))) + (when files + (concat (regexp-opt files) "\\|")))) + "\\sw+\\)\\(#\\S-+\\)?\\)?\\>")) + (when (and (featurep 'muse-colors) + (not (string= old-value muse-wiki-interwiki-regexp))) + (muse-colors-define-highlighting 'muse-mode muse-colors-markup))))) + +(defcustom muse-wiki-interwiki-alist + '(("EmacsWiki" . "http://www.emacswiki.org/cgi-bin/wiki/")) + "A table of WikiNames that refer to external entities. + +The format of this table is an alist, or series of cons cells. +Each cons cell must be of the form: + + (WIKINAME . STRING-OR-FUNCTION) + +The second part of the cons cell may either be a STRING, which in most +cases should be a URL, or a FUNCTION. If a function, it will be +called with one argument: the tag applied to the Interwiki name, or +nil if no tag was used. If the cdr was a STRING and a tag is used, +the tag is simply appended. + +Here are some examples: + + (\"JohnWiki\" . \"http://alice.dynodns.net/wiki?\") + +Referring to [[JohnWiki::EmacsModules]] then really means: + + http://alice.dynodns.net/wiki?EmacsModules + +If a function is used for the replacement text, you can get creative +depending on what the tag is. Tags may contain any alphabetic +character, any number, % or _. If you need other special characters, +use % to specify the hex code, as in %2E. All browsers should support +this." + :type '(repeat (cons (string :tag "WikiName") + (choice (string :tag "URL") function))) + :set (function + (lambda (sym value) + (set sym value) + (muse-wiki-update-interwiki-regexp))) + :group 'muse-wiki) + +(add-hook 'muse-update-values-hook + 'muse-wiki-update-interwiki-regexp) + +(defun muse-wiki-resolve-project-page (&optional project page) + "Return the published path from the current page to PAGE of PROJECT. + +If PAGE is not specified, use the value of :default in PROJECT. + +If PROJECT is not specified, default to the current project. If +no project is current, use the first project of +`muse-projects-alist'. + +Note that PAGE can have several output directories. If this is +the case, we will use the first one that matches our current +style and has the same link suffix, ignoring the others. If no +style has the same link suffix as the current publishing style, +use the first style we find." + (setq project (or (and project + (muse-project project)) + (muse-project) + (car muse-project-alist)) + page (or page (muse-get-keyword :default (cadr project)))) + (let* ((page-path (and muse-project-alist + (muse-project-page-file page project))) + (remote-styles (and page-path (muse-project-applicable-styles + page-path (cddr project)))) + (local-style (muse-project-current-output-style))) + (cond ((and remote-styles local-style muse-publishing-p) + (muse-project-resolve-link page local-style remote-styles)) + ((not muse-publishing-p) + (if page-path + page-path + (when muse-wiki-allow-nonexistent-wikiword + ;; make a path to a nonexistent file in project + (setq page-path (expand-file-name + page (car (cadr project)))) + (if (and muse-file-extension + (not (string= muse-file-extension ""))) + (concat page-path "." muse-file-extension) + page-path))))))) + +(defun muse-wiki-handle-implicit-interwiki (&optional string) + "If STRING or point has an interwiki link, resolve it to a filename. + +Match string 0 is set to the link." + (when (and muse-wiki-interwiki-regexp + (if string (string-match muse-wiki-interwiki-regexp string) + (looking-at muse-wiki-interwiki-regexp))) + (let* ((project (match-string 1 string)) + (subst (cdr (assoc project muse-wiki-interwiki-alist))) + (word (match-string 3 string)) + (anchor (if (match-beginning 4) + (match-string 4 string) + ""))) + (if subst + (if (functionp subst) + (and (setq word (funcall subst word)) + (concat word anchor)) + (concat subst word anchor)) + (and (assoc project muse-project-alist) + (or word (not muse-wiki-ignore-bare-project-names)) + (setq word (muse-wiki-resolve-project-page project word)) + (concat word anchor)))))) + +(defun muse-wiki-handle-explicit-interwiki (&optional string) + "If STRING or point has an interwiki link, resolve it to a filename." + (let ((right-pos (if string (length string) (match-end 1)))) + (when (and muse-wiki-interwiki-regexp + (if string (string-match muse-wiki-interwiki-regexp string) + (save-restriction + (narrow-to-region (point) right-pos) + (looking-at muse-wiki-interwiki-regexp)))) + (let* ((project (match-string 1 string)) + (subst (cdr (assoc project muse-wiki-interwiki-alist))) + (anchor (and (match-beginning 4) + (match-string 4 string))) + (word (when (match-end 2) + (cond (anchor (match-string 3 string)) + (string (substring string (match-end 2))) + (right-pos (buffer-substring (match-end 2) + right-pos)) + (t nil))))) + (if (and (null word) + right-pos + (not (= right-pos (match-end 1)))) + ;; if only a project name was found, it must take up the + ;; entire string or link + nil + (unless anchor + (if (or (null word) + (not (string-match "#[^#]+\\'" word))) + (setq anchor "") + (setq anchor (match-string 0 word)) + (setq word (substring word 0 (match-beginning 0))))) + (if subst + (if (functionp subst) + (and (setq word (funcall subst word)) + (concat word anchor)) + (concat subst word anchor)) + (and (assoc project muse-project-alist) + (or word (not muse-wiki-ignore-bare-project-names)) + (setq word (muse-wiki-resolve-project-page project word)) + (concat word anchor)))))))) + +(defun muse-wiki-handle-wikiword (&optional string) + "If STRING or point has a WikiWord, return it. + +Match 1 is set to the WikiWord." + (when (and (or (and muse-wiki-match-all-project-files + muse-wiki-project-file-regexp + (if string + (string-match muse-wiki-project-file-regexp string) + (looking-at muse-wiki-project-file-regexp))) + (and muse-wiki-use-wikiword + (if string + (string-match muse-wiki-wikiword-regexp string) + (looking-at muse-wiki-wikiword-regexp)))) + (cond + (muse-wiki-allow-nonexistent-wikiword + t) + ((and muse-wiki-ignore-implicit-links-to-current-page + (string= (match-string 1 string) (muse-page-name))) + nil) + ((and (muse-project-of-file) + (muse-project-page-file + (match-string 1 string) muse-current-project t)) + t) + ((file-exists-p (match-string 1 string)) + t) + (t nil))) + (match-string 1 string))) + +;;; Prettifications + +(defcustom muse-wiki-publish-small-title-words + '("the" "and" "at" "on" "of" "for" "in" "an" "a") + "Strings that should be downcased in a page title. + +This is used by `muse-wiki-publish-pretty-title', which must be +called manually." + :type '(repeat string) + :group 'muse-wiki) + +(defcustom muse-wiki-hide-nop-tag t + "If non-nil, hide tags when coloring a Muse buffer." + :type 'boolean + :group 'muse-wiki) + +(defun muse-wiki-publish-pretty-title (&optional title explicit) + "Return a pretty version of the given TITLE. + +If EXPLICIT is non-nil, TITLE will be returned unmodified." + (unless title (setq title (or (muse-publishing-directive "title") ""))) + (if (or explicit + (save-match-data (string-match muse-url-regexp title))) + title + (save-match-data + (let ((case-fold-search nil)) + (while (string-match (concat "\\([" muse-regexp-lower + "]\\)\\([" muse-regexp-upper + "0-9]\\)") + title) + (setq title (replace-match "\\1 \\2" t nil title))) + (let* ((words (split-string title)) + (w (cdr words))) + (while w + (if (member (downcase (car w)) + muse-wiki-publish-small-title-words) + (setcar w (downcase (car w)))) + (setq w (cdr w))) + (mapconcat 'identity words " ")))))) + +(defun muse-wiki-publish-pretty-interwiki (desc &optional explicit) + "Replace instances of `muse-wiki-interwiki-delimiter' with +`muse-wiki-interwiki-replacement'." + (if (or explicit + (save-match-data (string-match muse-url-regexp desc))) + desc + (muse-replace-regexp-in-string muse-wiki-interwiki-delimiter + muse-wiki-interwiki-replacement + desc))) + +;;; Coloring setup + +(defun muse-wiki-colors-nop-tag (beg end) + "Inhibit the colorization of inhibit links just after the tag. + +Example: WikiWord" + (when muse-wiki-hide-nop-tag + (add-text-properties beg (+ beg 5) + '(invisible muse intangible t))) + (unless (> (+ beg 6) (point-max)) + (add-text-properties (+ beg 5) (+ beg 6) + '(muse-no-implicit-link t)))) + +(defun muse-colors-wikiword-separate () + (add-text-properties (match-beginning 0) (match-end 0) + '(invisible muse intangible t))) + +(defun muse-wiki-insinuate-colors () + (add-to-list 'muse-colors-tags + '("nop" nil nil nil muse-wiki-colors-nop-tag) + t) + (add-to-list 'muse-colors-markup + '(muse-wiki-interwiki-regexp t muse-colors-implicit-link) + t) + (add-to-list 'muse-colors-markup + '(muse-wiki-wikiword-regexp t muse-colors-implicit-link) + t) + (add-to-list 'muse-colors-markup + '(muse-wiki-project-file-regexp t muse-colors-implicit-link) + t) + (add-to-list 'muse-colors-markup + '("''''" ?\' muse-colors-wikiword-separate) + nil) + (muse-colors-define-highlighting 'muse-mode muse-colors-markup)) + +(eval-after-load "muse-colors" '(muse-wiki-insinuate-colors)) + +;;; Publishing setup + +(defun muse-wiki-publish-nop-tag (beg end) + "Inhibit the colorization of inhibit links just after the tag. + +Example: WikiWord" + (unless (= (point) (point-max)) + (muse-publish-mark-read-only (point) (+ (point) 1)))) + +(defun muse-wiki-insinuate-publish () + (add-to-list 'muse-publish-markup-tags + '("nop" nil nil nil muse-wiki-publish-nop-tag) + t) + (add-to-list 'muse-publish-markup-regexps + '(3100 muse-wiki-interwiki-regexp 0 link) + t) + (add-to-list 'muse-publish-markup-regexps + '(3200 muse-wiki-wikiword-regexp 0 link) + t) + (add-to-list 'muse-publish-markup-regexps + '(3250 muse-wiki-project-file-regexp 0 link) + t) + (add-to-list 'muse-publish-markup-regexps + '(3300 "''''" 0 "") + t) + (custom-add-option 'muse-publish-desc-transforms + 'muse-wiki-publish-pretty-interwiki) + (custom-add-option 'muse-publish-desc-transforms + 'muse-wiki-publish-pretty-title)) + +(eval-after-load "muse-publish" '(muse-wiki-insinuate-publish)) + +;;; Insinuate link handling + +(custom-add-option 'muse-implicit-link-functions + 'muse-wiki-handle-implicit-interwiki) +(custom-add-option 'muse-implicit-link-functions + 'muse-wiki-handle-wikiword) + +(custom-add-option 'muse-explicit-link-functions + 'muse-wiki-handle-explicit-interwiki) + +(add-to-list 'muse-implicit-link-functions + 'muse-wiki-handle-implicit-interwiki t) +(add-to-list 'muse-implicit-link-functions + 'muse-wiki-handle-wikiword t) + +(add-to-list 'muse-explicit-link-functions + 'muse-wiki-handle-explicit-interwiki t) + +;;; Obsolete functions + +(defun muse-wiki-update-custom-values () + (muse-display-warning + (concat "Please remove `muse-wiki-update-custom-values' from" + " `muse-mode-hook'. Its use is now deprecated."))) + +(provide 'muse-wiki) +;;; muse-wiki.el ends here diff --git a/elpa/muse-3.20/muse-xml-common.el b/elpa/muse-3.20/muse-xml-common.el new file mode 100644 index 0000000..75869ca --- /dev/null +++ b/elpa/muse-3.20/muse-xml-common.el @@ -0,0 +1,201 @@ +;;; muse-xml-common.el --- common routines for XML-like publishing styles + +;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;;; Contributors: + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse XML Publishing - Common Elements +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'muse-publish) +(require 'muse-regexps) + +(defcustom muse-xml-encoding-map + '((iso-8859-1 . "iso-8859-1") + (iso-2022-jp . "iso-2022-jp") + (utf-8 . "utf-8") + (japanese-iso-8bit . "euc-jp") + (chinese-big5 . "big5") + (mule-utf-8 . "utf-8") + (chinese-iso-8bit . "gb2312") + (chinese-gbk . "gbk")) + "An alist mapping Emacs coding systems to appropriate XML charsets. +Use the base name of the coding system (i.e. without the -unix)." + :type '(alist :key-type coding-system :value-type string) + :group 'muse-xml) + +(defun muse-xml-transform-content-type (content-type default) + "Using `muse-xml-encoding-map', try and resolve an Emacs coding +system to an associated XML coding system. +If no match is found, the DEFAULT charset is used instead." + (let ((match (and (fboundp 'coding-system-base) + (assoc (coding-system-base content-type) + muse-xml-encoding-map)))) + (if match + (cdr match) + default))) + +(defcustom muse-xml-markup-specials + '((?\" . """) + (?\< . "<") + (?\> . ">") + (?\& . "&")) + "A table of characters which must be represented specially." + :type '(alist :key-type character :value-type string) + :group 'muse-xml) + +(defcustom muse-xml-markup-specials-url-extra + '((?\" . """) + (?\< . "<") + (?\> . ">") + (?\& . "&") + (?\ . "%20") + (?\n . "%0D%0A")) + "A table of characters which must be represented specially. +These are extra characters that are escaped within URLs." + :type '(alist :key-type character :value-type string) + :group 'muse-xml) + +(defun muse-xml-decide-specials (context) + "Determine the specials to escape, depending on CONTEXT." + (cond ((memq context '(email url image)) + 'muse-xml-escape-url) + ((eq context 'url-extra) + muse-xml-markup-specials-url-extra) + (t muse-xml-markup-specials))) + +(defun muse-xml-escape-url (str) + "Convert to character entities any non-alphanumeric characters +outside a few punctuation symbols, that risk being misinterpreted +if not escaped." + (when str + (setq str (muse-publish-escape-specials-in-string str 'url-extra)) + (let (pos code len ch) + (save-match-data + (while (setq pos (string-match (concat "[^-" + muse-regexp-alnum + "/:._=@\\?~#%\"\\+<>()&;]") + str pos)) + (setq ch (aref str pos) + code (concat "&#" (int-to-string + (cond ((fboundp 'char-to-ucs) + (char-to-ucs ch)) + ((fboundp 'char-to-int) + (char-to-int ch)) + (t ch))) + ";") + len (length code) + str (concat (substring str 0 pos) + code + (when (< pos (length str)) + (substring str (1+ pos) nil))) + pos (+ len pos))) + str)))) + +(defun muse-xml-markup-anchor () + (unless (get-text-property (match-end 1) 'muse-link) + (let ((text (muse-markup-text 'anchor (match-string 2)))) + (save-match-data + (skip-chars-forward (concat muse-regexp-blank "\n")) + (when (looking-at (concat "<\\([^" muse-regexp-blank "/>\n]+\\)>")) + (goto-char (match-end 0))) + (muse-insert-markup text))) + (match-string 1))) + +(defun muse-xml-sort-table (table) + "Sort the given table structure so that it validates properly." + ;; Note that the decision matrix must have a nil diagonal, or else + ;; elements with the same type will be reversed with respect to each + ;; other. + (let ((decisions '((nil nil nil) ; body < header, body < footer + (t nil t) ; header stays where it is + (t nil nil)))) ; footer < header + (sort table #'(lambda (l r) + (and (integerp (car l)) (integerp (car r)) + (nth (1- (car r)) + (nth (1- (car l)) decisions))))))) + +(defun muse-xml-markup-table (&optional attributes) + "Publish the matched region into a table. +If a string ATTRIBUTES is given, pass it to the markup string begin-table." + (let* ((table-info (muse-publish-table-fields (match-beginning 0) + (match-end 0))) + (row-len (car table-info)) + (supports-group (not (string= (muse-markup-text 'begin-table-group + row-len) + ""))) + (field-list (muse-xml-sort-table (cdr table-info))) + last-part) + (when table-info + (let ((beg (point))) + (muse-publish-ensure-block beg)) + (muse-insert-markup (muse-markup-text 'begin-table (or attributes ""))) + (muse-insert-markup (muse-markup-text 'begin-table-group row-len)) + (dolist (fields field-list) + (let* ((type (car fields)) + (part (cond ((eq type 'hline) nil) + ((= type 1) "tbody") + ((= type 2) "thead") + ((= type 3) "tfoot"))) + (col (cond ((eq type 'hline) nil) + ((= type 1) "td") + ((= type 2) "th") + ((= type 3) "td")))) + (setq fields (cdr fields)) + (unless (and part last-part (string= part last-part)) + (when last-part + (muse-insert-markup " \n") + (when (eq type 'hline) + ;; horizontal separators are represented by closing + ;; the current table group and opening a new one + (muse-insert-markup (muse-markup-text 'end-table-group)) + (muse-insert-markup (muse-markup-text 'begin-table-group + row-len)))) + (when part + (muse-insert-markup " <" part ">\n")) + (setq last-part part)) + (unless (eq type 'hline) + (muse-insert-markup (muse-markup-text 'begin-table-row)) + (dolist (field fields) + (muse-insert-markup (muse-markup-text 'begin-table-entry col)) + (insert field) + (muse-insert-markup (muse-markup-text 'end-table-entry col))) + (muse-insert-markup (muse-markup-text 'end-table-row))))) + (when last-part + (muse-insert-markup " \n")) + (muse-insert-markup (muse-markup-text 'end-table-group)) + (muse-insert-markup (muse-markup-text 'end-table)) + (insert ?\n)))) + +(defun muse-xml-prepare-buffer () + (set (make-local-variable 'muse-publish-url-transforms) + (cons 'muse-xml-escape-string muse-publish-url-transforms))) + +(provide 'muse-xml-common) + +;;; muse-xml-common.el ends here diff --git a/elpa/muse-3.20/muse-xml.el b/elpa/muse-3.20/muse-xml.el new file mode 100644 index 0000000..9f26ade --- /dev/null +++ b/elpa/muse-3.20/muse-xml.el @@ -0,0 +1,274 @@ +;;; muse-xml.el --- publish XML files + +;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; Author: Michael Olson +;; Date: Sat 23-Jul-2005 + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; James Clarke's nxml-mode can be used for editing and validating +;; Muse-generated XML files. If you are in nxml-mode use the command +;; C-c C-s C-f to point to the schema in `contrib/muse.rnc', which +;; comes with Muse. Say yes if you are asked if you want to copy the +;; file to your location. C-c C-s C-a can then be used to reload the +;; schema if you make changes to the file. + +;;; Contributors: + +;; Peter K. Lee (saint AT corenova DOT com) made the initial +;; implementation of planner-publish.el, which was heavily borrowed +;; from. + +;; Brad Collins (brad AT chenla DOT org) provided a Compact RelaxNG +;; schema. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Muse XML Publishing +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'muse-publish) +(require 'muse-regexps) +(require 'muse-xml-common) + +(defgroup muse-xml nil + "Options controlling the behavior of Muse XML publishing. +See `muse-xml' for more information." + :group 'muse-publish) + +(defcustom muse-xml-extension ".xml" + "Default file extension for publishing XML files." + :type 'string + :group 'muse-xml) + +(defcustom muse-xml-header + " + (muse-xml-encoding)\"?> + + + <lisp>(muse-publishing-directive \"title\")</lisp> + (muse-publishing-directive \"author\") + (muse-style-element :maintainer) + (muse-publishing-directive \"date\") + + \n" + "Header used for publishing XML files. +This may be text or a filename." + :type 'string + :group 'muse-xml) + +(defcustom muse-xml-footer " + +\n" + "Footer used for publishing XML files. +This may be text or a filename." + :type 'string + :group 'muse-xml) + +(defcustom muse-xml-markup-regexps + `(;; Beginning of doc, end of doc, or plain paragraph separator + (10000 ,(concat "\\(\\(\n\\(?:[" muse-regexp-blank "]*\n\\)*" + "\\([" muse-regexp-blank "]*\n\\)\\)" + "\\|\\`\\s-*\\|\\s-*\\'\\)") + ;; this is somewhat repetitive because we only require the + ;; line just before the paragraph beginning to be not + ;; read-only + 3 muse-xml-markup-paragraph)) + "List of markup rules for publishing a Muse page to XML. +For more on the structure of this list, see `muse-publish-markup-regexps'." + :type '(repeat (choice + (list :tag "Markup rule" + integer + (choice regexp symbol) + integer + (choice string function symbol)) + function)) + :group 'muse-xml) + +(defcustom muse-xml-markup-functions + '((anchor . muse-xml-markup-anchor) + (table . muse-xml-markup-table)) + "An alist of style types to custom functions for that kind of text. +For more on the structure of this list, see +`muse-publish-markup-functions'." + :type '(alist :key-type symbol :value-type function) + :group 'muse-xml) + +(defcustom muse-xml-markup-strings + '((image-with-desc . "%s") + (image . "") + (image-link . "%s.%s") + (anchor-ref . "%s") + (url . "%s") + (link . "%s") + (link-and-anchor . "%s") + (email-addr . "%s") + (anchor . "\n") + (emdash . "%s--%s") + (comment-begin . "") + (rule . "
    ") + (fn-sep . "
    \n") + (no-break-space . " ") + (line-break . "
    ") + (enddots . "....") + (dots . "...") + (section . "
    ") + (section-end . "") + (subsection . "
    ") + (subsection-end . "") + (subsubsection . "
    ") + (subsubsection-end . "") + (section-other . "
    ") + (section-other-end . "") + (section-close . "
    ") + (footnote . "") + (footnote-end . "") + (begin-underline . "") + (end-underline . "") + (begin-literal . "") + (end-literal . "") + (begin-emph . "") + (end-emph . "") + (begin-more-emph . "") + (end-more-emph . "") + (begin-most-emph . "") + (end-most-emph . "") + (begin-verse . "\n") + (begin-verse-line . "") + (end-verse-line . "") + (empty-verse-line . "") + (begin-last-stanza-line . "") + (end-last-stanza-line . "") + (end-verse . "") + (begin-example . "") + (end-example . "") + (begin-center . "

    \n") + (end-center . "\n

    ") + (begin-quote . "
    \n") + (end-quote . "\n
    ") + (begin-cite . "") + (begin-cite-author . "") + (begin-cite-year . "") + (end-cite . "") + (begin-quote-item . "

    ") + (end-quote-item . "

    ") + (begin-uli . "\n") + (end-uli . "\n") + (begin-uli-item . "") + (end-uli-item . "") + (begin-oli . "\n") + (end-oli . "\n") + (begin-oli-item . "") + (end-oli-item . "") + (begin-dl . "\n") + (end-dl . "\n") + (begin-dl-item . "\n") + (end-dl-item . "\n") + (begin-ddt . "") + (end-ddt . "") + (begin-dde . "") + (end-dde . "") + (begin-table . "\n") + (end-table . "") + (begin-table-row . " \n") + (end-table-row . " \n") + (begin-table-entry . " <%s>") + (end-table-entry . "\n")) + "Strings used for marking up text. +These cover the most basic kinds of markup, the handling of which +differs little between the various styles." + :type '(alist :key-type symbol :value-type string) + :group 'muse-xml) + +(defcustom muse-xml-encoding-default 'utf-8 + "The default Emacs buffer encoding to use in published files. +This will be used if no special characters are found." + :type 'symbol + :group 'muse-xml) + +(defcustom muse-xml-charset-default "utf-8" + "The default XML charset to use if no translation is +found in `muse-xml-encoding-map'." + :type 'string + :group 'muse-xml) + +(defun muse-xml-encoding () + (muse-xml-transform-content-type + (or (and (boundp 'buffer-file-coding-system) + buffer-file-coding-system) + muse-xml-encoding-default) + muse-xml-charset-default)) + +(defun muse-xml-markup-paragraph () + (let ((end (copy-marker (match-end 0) t))) + (goto-char (match-beginning 0)) + (when (save-excursion + (save-match-data + (and (not (get-text-property (max (point-min) (1- (point))) + 'muse-no-paragraph)) + (re-search-backward "<\\(/?\\)p[ >]" nil t) + (not (string-equal (match-string 1) "/"))))) + (when (get-text-property (1- (point)) 'muse-end-list) + (goto-char (previous-single-property-change (1- (point)) + 'muse-end-list))) + (muse-insert-markup "

    ")) + (goto-char end)) + (cond + ((eobp) + (unless (bolp) + (insert "\n"))) + ((get-text-property (point) 'muse-no-paragraph) + (forward-char 1) + nil) + ((eq (char-after) ?\<) + (when (looking-at (concat "<\\(format\\|code\\|link\\|image" + "\\|anchor\\|footnote\\)[ >]")) + (muse-insert-markup "

    "))) + (t + (muse-insert-markup "

    ")))) + +(defun muse-xml-finalize-buffer () + (when (boundp 'buffer-file-coding-system) + (when (memq buffer-file-coding-system '(no-conversion undecided-unix)) + ;; make it agree with the default charset + (setq buffer-file-coding-system muse-xml-encoding-default)))) + +;;; Register the Muse XML Publisher + +(muse-define-style "xml" + :suffix 'muse-xml-extension + :regexps 'muse-xml-markup-regexps + :functions 'muse-xml-markup-functions + :strings 'muse-xml-markup-strings + :specials 'muse-xml-decide-specials + :after 'muse-xml-finalize-buffer + :header 'muse-xml-header + :footer 'muse-xml-footer + :browser 'find-file) + +(provide 'muse-xml) + +;;; muse-xml.el ends here diff --git a/elpa/muse-3.20/muse.el b/elpa/muse-3.20/muse.el new file mode 100644 index 0000000..4d4a0b9 --- /dev/null +++ b/elpa/muse-3.20/muse.el @@ -0,0 +1,881 @@ +;;; muse.el --- an authoring and publishing tool for Emacs + +;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; Emacs Lisp Archive Entry +;; Filename: muse.el +;; Version: 3.20 +;; Date: Sun 31 Jan-2010 +;; Keywords: hypermedia +;; Author: John Wiegley +;; Maintainer: Michael Olson +;; Description: An authoring and publishing tool for Emacs +;; URL: http://mwolson.org/projects/EmacsMuse.html +;; Compatibility: Emacs21 XEmacs21 Emacs22 + +;; This file is part of Emacs Muse. It is not part of GNU Emacs. + +;; Emacs Muse is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; Emacs Muse is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with Emacs Muse; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; Muse is a tool for easily authoring and publishing documents. It +;; allows for rapid prototyping of hyperlinked text, which may then be +;; exported to multiple output formats -- such as HTML, LaTeX, +;; Texinfo, etc. + +;; The markup rules used by Muse are intended to be very friendly to +;; people familiar with Emacs. See the included manual for more +;; information. + +;;; Contributors: + +;;; Code: + +;; Indicate that this version of Muse supports nested tags +(provide 'muse-nested-tags) + +(defvar muse-version "3.20" + "The version of Muse currently loaded") + +(defun muse-version (&optional insert) + "Display the version of Muse that is currently loaded. +If INSERT is non-nil, insert the text instead of displaying it." + (interactive "P") + (if insert + (insert muse-version) + (message muse-version))) + +(defgroup muse nil + "Options controlling the behavior of Muse. +The markup used by Muse is intended to be very friendly to people +familiar with Emacs." + :group 'hypermedia) + +(defvar muse-under-windows-p (memq system-type '(ms-dos windows-nt))) + +(provide 'muse) + +(condition-case nil + (require 'derived) + (error nil)) +(require 'wid-edit) +(require 'muse-regexps) + +(defvar muse-update-values-hook nil + "Hook for values that are automatically generated. +This is to be used by add-on modules for Muse. +It is run just before colorizing or publishing a buffer.") + +(defun muse-update-values () + "Update various values that are automatically generated. + +Call this after changing `muse-project-alist'." + (interactive) + (run-hooks 'muse-update-values-hook) + (dolist (buffer (buffer-list)) + (when (buffer-live-p buffer) + (with-current-buffer buffer + (when (derived-mode-p 'muse-mode) + (and (boundp 'muse-current-project) + (fboundp 'muse-project-of-file) + (setq muse-current-project nil) + (setq muse-current-project (muse-project-of-file)))))))) + +;; Default file extension + +;; By default, use the .muse file extension. +;;;###autoload (add-to-list 'auto-mode-alist '("\\.muse\\'" . muse-mode-choose-mode)) + +;; We need to have this at top-level, as well, so that any Muse or +;; Planner documents opened during init will just work. +(add-to-list 'auto-mode-alist '("\\.muse\\'" . muse-mode-choose-mode)) + +(eval-when-compile + (defvar muse-ignored-extensions)) + +(defvar muse-ignored-extensions-regexp nil + "A regexp of extensions to omit from the ending of a Muse page name. +This is autogenerated from `muse-ignored-extensions'.") + +(defun muse-update-file-extension (sym val) + "Update the value of `muse-file-extension'." + (let ((old (and (boundp sym) (symbol-value sym)))) + (set sym val) + (when (and (featurep 'muse-mode) + (or (not (stringp val)) + (not (stringp old)) + (not (string= old val)))) + ;; remove old auto-mode-alist association + (when (and (boundp sym) (stringp old)) + (setq auto-mode-alist + (delete (cons (concat "\\." old "\\'") + 'muse-mode-choose-mode) + auto-mode-alist))) + ;; associate the new file extension with muse-mode + (when (stringp val) + (add-to-list 'auto-mode-alist + (cons (concat "\\." val "\\'") + 'muse-mode-choose-mode))) + ;; update the ignored extensions regexp + (when (fboundp 'muse-update-ignored-extensions-regexp) + (muse-update-ignored-extensions-regexp + 'muse-ignored-extensions muse-ignored-extensions))))) + +(defcustom muse-file-extension "muse" + "File extension of Muse files. Omit the period at the beginning. +If you don't want Muse files to have an extension, set this to nil." + :type '(choice + (const :tag "None" nil) + (string)) + :set 'muse-update-file-extension + :group 'muse) + +(defcustom muse-completing-read-function 'completing-read + "Function to call when prompting user to choose between a list of options. +This should take the same arguments as `completing-read'." + :type 'function + :group 'muse) + +(defun muse-update-ignored-extensions-regexp (sym val) + "Update the value of `muse-ignored-extensions-regexp'." + (set sym val) + (if val + (setq muse-ignored-extensions-regexp + (concat "\\.\\(" + (regexp-quote (or muse-file-extension "")) "\\|" + (mapconcat 'identity val "\\|") + "\\)\\'")) + (setq muse-ignored-extensions-regexp + (if muse-file-extension + (concat "\\.\\(" muse-file-extension "\\)\\'") + nil)))) + +(add-hook 'muse-update-values-hook + (lambda () + (muse-update-ignored-extensions-regexp + 'muse-ignored-extensions muse-ignored-extensions))) + +(defcustom muse-ignored-extensions '("bz2" "gz" "[Zz]") + "A list of extensions to omit from the ending of a Muse page name. +These are regexps. + +Don't put a period at the beginning of each extension unless you +understand that it is part of a regexp." + :type '(repeat (regexp :tag "Extension")) + :set 'muse-update-ignored-extensions-regexp + :group 'muse) + +(defun muse-update-file-extension-after-init () + ;; This is short, but it has to be a function, otherwise Emacs21 + ;; does not load it properly when running after-init-hook + (unless (string= muse-file-extension "muse") + (let ((val muse-file-extension) + (muse-file-extension "muse")) + (muse-update-file-extension 'muse-file-extension val)))) + +;; Once the user's init file has been processed, determine whether +;; they want a file extension +(add-hook 'after-init-hook 'muse-update-file-extension-after-init) + +;; URL protocols + +(require 'muse-protocols) + +;; Helper functions + +(defsubst muse-delete-file-if-exists (file) + (when (file-exists-p file) + (delete-file file) + (message "Removed %s" file))) + +(defsubst muse-time-less-p (t1 t2) + "Say whether time T1 is less than time T2." + (or (< (car t1) (car t2)) + (and (= (car t1) (car t2)) + (< (nth 1 t1) (nth 1 t2))))) + +(eval-when-compile + (defvar muse-publishing-current-file nil)) + +(defun muse-current-file () + "Return the name of the currently visited or published file." + (or (and (boundp 'muse-publishing-current-file) + muse-publishing-current-file) + (buffer-file-name) + (concat default-directory (buffer-name)))) + +(defun muse-page-name (&optional name) + "Return the canonical form of a Muse page name. + +What this means is that the directory part of NAME is removed, +and the file extensions in `muse-ignored-extensions' are also +removed from NAME." + (save-match-data + (unless (and name (not (string= name ""))) + (setq name (muse-current-file))) + (if name + (let ((page (file-name-nondirectory name))) + (if (and muse-ignored-extensions-regexp + (string-match muse-ignored-extensions-regexp page)) + (replace-match "" t t page) + page))))) + +(defun muse-display-warning (message) + "Display the given MESSAGE as a warning." + (if (fboundp 'display-warning) + (display-warning 'muse message + (if (featurep 'xemacs) + 'warning + :warning)) + (let ((buf (get-buffer-create "*Muse warnings*"))) + (with-current-buffer buf + (goto-char (point-max)) + (insert "Warning (muse): " message) + (unless (bolp) + (newline))) + (display-buffer buf) + (sit-for 0)))) + +(defun muse-eval-lisp (form) + "Evaluate the given form and return the result as a string." + (require 'pp) + (save-match-data + (condition-case err + (let ((object (eval (read form)))) + (cond + ((stringp object) object) + ((and (listp object) + (not (eq object nil))) + (let ((string (pp-to-string object))) + (substring string 0 (1- (length string))))) + ((numberp object) + (number-to-string object)) + ((eq object nil) "") + (t + (pp-to-string object)))) + (error + (muse-display-warning (format "%s: Error evaluating %s: %s" + (muse-page-name) form err)) + "; INVALID LISP CODE")))) + +(defmacro muse-with-temp-buffer (&rest body) + "Create a temporary buffer, and evaluate BODY there like `progn'. +See also `with-temp-file' and `with-output-to-string'. + +Unlike `with-temp-buffer', this will never attempt to save the +temp buffer. It is meant to be used along with +`insert-file-contents' or `muse-insert-file-contents'. + +The undo feature will be disabled in the new buffer. + +If `debug-on-error' is set to t, keep the buffer around for +debugging purposes rather than removing it." + (let ((temp-buffer (make-symbol "temp-buffer"))) + `(let ((,temp-buffer (generate-new-buffer " *muse-temp*"))) + (buffer-disable-undo ,temp-buffer) + (unwind-protect + (if debug-on-error + (with-current-buffer ,temp-buffer + ,@body) + (condition-case err + (with-current-buffer ,temp-buffer + ,@body) + (error + (if (and (boundp 'muse-batch-publishing-p) + muse-batch-publishing-p) + (progn + (message "%s: Error occured: %s" + (muse-page-name) err) + (backtrace)) + (muse-display-warning + (format (concat "An error occurred while publishing" + " %s:\n %s\n\nSet debug-on-error to" + " `t' if you would like a backtrace.") + (muse-page-name) err)))))) + (when (buffer-live-p ,temp-buffer) + (with-current-buffer ,temp-buffer + (set-buffer-modified-p nil)) + (unless debug-on-error (kill-buffer ,temp-buffer))))))) + +(put 'muse-with-temp-buffer 'lisp-indent-function 0) +(put 'muse-with-temp-buffer 'edebug-form-spec '(body)) + +(defun muse-insert-file-contents (filename &optional visit) + "Insert the contents of file FILENAME after point. +Do character code conversion and end-of-line conversion, but none +of the other unnecessary things like format decoding or +`find-file-hook'. + +If VISIT is non-nil, the buffer's visited filename +and last save file modtime are set, and it is marked unmodified. +If visiting and the file does not exist, visiting is completed +before the error is signaled." + (let ((format-alist nil) + (after-insert-file-functions nil) + (inhibit-file-name-handlers + (append '(jka-compr-handler image-file-handler epa-file-handler) + inhibit-file-name-handlers)) + (inhibit-file-name-operation 'insert-file-contents)) + (insert-file-contents filename visit))) + +(defun muse-write-file (filename &optional nomessage) + "Write current buffer into file FILENAME. +Unlike `write-file', this does not visit the file, try to back it +up, or interact with vc.el in any way. + +If the file was not written successfully, return nil. Otherwise, +return non-nil. + +If the NOMESSAGE argument is non-nil, suppress the \"Wrote file\" +message." + (when nomessage (setq nomessage 'nomessage)) + (let ((backup-inhibited t) + (buffer-file-name filename) + (buffer-file-truename (file-truename filename))) + (save-current-buffer + (save-restriction + (widen) + (if (not (file-writable-p buffer-file-name)) + (prog1 nil + (muse-display-warning + (format "Cannot write file %s:\n %s" buffer-file-name + (let ((dir (file-name-directory buffer-file-name))) + (if (not (file-directory-p dir)) + (if (file-exists-p dir) + (format "%s is not a directory" dir) + (format "No directory named %s exists" dir)) + (if (not (file-exists-p buffer-file-name)) + (format "Directory %s write-protected" dir) + "File is write-protected")))))) + (let ((coding-system-for-write + (or (and (boundp 'save-buffer-coding-system) + save-buffer-coding-system) + coding-system-for-write))) + (write-region (point-min) (point-max) buffer-file-name + nil nomessage)) + (when (boundp 'last-file-coding-system-used) + (when (boundp 'buffer-file-coding-system-explicit) + (setq buffer-file-coding-system-explicit + last-coding-system-used)) + (if save-buffer-coding-system + (setq save-buffer-coding-system last-coding-system-used) + (setq buffer-file-coding-system last-coding-system-used))) + t))))) + +(defun muse-collect-alist (list element &optional test) + "Collect items from LIST whose car is equal to ELEMENT. +If TEST is specified, use it to compare ELEMENT." + (unless test (setq test 'equal)) + (let ((items nil)) + (dolist (item list) + (when (funcall test element (car item)) + (setq items (cons item items)))) + items)) + +(defmacro muse-sort-with-closure (list predicate closure) + "Sort LIST, stably, comparing elements using PREDICATE. +Returns the sorted list. LIST is modified by side effects. +PREDICATE is called with two elements of list and CLOSURE. +PREDICATE should return non-nil if the first element should sort +before the second." + `(sort ,list (lambda (a b) (funcall ,predicate a b ,closure)))) + +(put 'muse-sort-with-closure 'lisp-indent-function 0) +(put 'muse-sort-with-closure 'edebug-form-spec '(form function-form form)) + +(defun muse-sort-by-rating (rated-list &optional test) + "Sort RATED-LIST according to the rating of each element. +The rating is stripped out in the returned list. +Default sorting is highest-first. + +If TEST if specified, use it to sort the list. The default test is '>." + (unless test (setq test '>)) + (mapcar (function cdr) + (muse-sort-with-closure + rated-list + (lambda (a b closure) + (let ((na (numberp (car a))) + (nb (numberp (car b)))) + (cond ((and na nb) (funcall closure (car a) (car b))) + (na (not nb)) + (t nil)))) + test))) + +(defun muse-escape-specials-in-string (specials string &optional reverse) + "Apply the transformations in SPECIALS to STRING. + +The transforms should form a fully reversible and non-ambiguous +syntax when STRING is parsed from left to right. + +If REVERSE is specified, reverse an already-escaped string." + (let ((rules (mapcar (lambda (rule) + (cons (regexp-quote (if reverse + (cdr rule) + (car rule))) + (if reverse (car rule) (cdr rule)))) + specials))) + (save-match-data + (with-temp-buffer + (insert string) + (goto-char (point-min)) + (while (not (eobp)) + (unless (catch 'found + (dolist (rule rules) + (when (looking-at (car rule)) + (replace-match (cdr rule) t t) + (throw 'found t)))) + (forward-char))) + (buffer-string))))) + +(defun muse-trim-whitespace (string) + "Return a version of STRING with no initial nor trailing whitespace." + (muse-replace-regexp-in-string + (concat "\\`[" muse-regexp-blank "]+\\|[" muse-regexp-blank "]+\\'") + "" string)) + +(defun muse-path-sans-extension (path) + "Return PATH sans final \"extension\". + +The extension, in a file name, is the part that follows the last `.', +except that a leading `.', if any, doesn't count. + +This differs from `file-name-sans-extension' in that it will +never modify the directory part of the path." + (concat (file-name-directory path) + (file-name-nondirectory (file-name-sans-extension path)))) + +;; The following code was extracted from cl + +(defun muse-const-expr-p (x) + (cond ((consp x) + (or (eq (car x) 'quote) + (and (memq (car x) '(function function*)) + (or (symbolp (nth 1 x)) + (and (eq (and (consp (nth 1 x)) + (car (nth 1 x))) 'lambda) 'func))))) + ((symbolp x) (and (memq x '(nil t)) t)) + (t t))) + +(put 'muse-assertion-failed 'error-conditions '(error)) +(put 'muse-assertion-failed 'error-message "Assertion failed") + +(defun muse-list* (arg &rest rest) + "Return a new list with specified args as elements, cons'd to last arg. +Thus, `(list* A B C D)' is equivalent to `(nconc (list A B C) D)', or to +`(cons A (cons B (cons C D)))'." + (cond ((not rest) arg) + ((not (cdr rest)) (cons arg (car rest))) + (t (let* ((n (length rest)) + (copy (copy-sequence rest)) + (last (nthcdr (- n 2) copy))) + (setcdr last (car (cdr last))) + (cons arg copy))))) + +(defmacro muse-assert (form &optional show-args string &rest args) + "Verify that FORM returns non-nil; signal an error if not. +Second arg SHOW-ARGS means to include arguments of FORM in message. +Other args STRING and ARGS... are arguments to be passed to `error'. +They are not evaluated unless the assertion fails. If STRING is +omitted, a default message listing FORM itself is used." + (let ((sargs + (and show-args + (delq nil (mapcar + (function + (lambda (x) + (and (not (muse-const-expr-p x)) x))) + (cdr form)))))) + (list 'progn + (list 'or form + (if string + (muse-list* 'error string (append sargs args)) + (list 'signal '(quote muse-assertion-failed) + (muse-list* 'list (list 'quote form) sargs)))) + nil))) + +;; Compatibility functions + +(if (fboundp 'looking-back) + (defalias 'muse-looking-back 'looking-back) + (defun muse-looking-back (regexp &optional limit &rest ignored) + (save-excursion + (re-search-backward (concat "\\(?:" regexp "\\)\\=") limit t)))) + +(eval-and-compile + (if (fboundp 'line-end-position) + (defalias 'muse-line-end-position 'line-end-position) + (defun muse-line-end-position (&optional n) + (save-excursion (end-of-line n) (point)))) + + (if (fboundp 'line-beginning-position) + (defalias 'muse-line-beginning-position 'line-beginning-position) + (defun muse-line-beginning-position (&optional n) + (save-excursion (beginning-of-line n) (point)))) + + (if (fboundp 'match-string-no-properties) + (defalias 'muse-match-string-no-properties 'match-string-no-properties) + (defun muse-match-string-no-properties (num &optional string) + (match-string num string)))) + +(defun muse-replace-regexp-in-string (regexp replacement text &optional fixedcase literal) + "Replace REGEXP with REPLACEMENT in TEXT. + +Return a new string containing the replacements. + +If fourth arg FIXEDCASE is non-nil, do not alter case of replacement text. +If fifth arg LITERAL is non-nil, insert REPLACEMENT literally." + (cond + ((and (featurep 'xemacs) (fboundp 'replace-in-string)) + (and (fboundp 'replace-in-string) ; stupid byte-compiler warning + (replace-in-string text regexp replacement literal))) + ((fboundp 'replace-regexp-in-string) + (replace-regexp-in-string regexp replacement text fixedcase literal)) + (t (error (concat "Neither `replace-in-string' nor " + "`replace-regexp-in-string' was found"))))) + +(if (fboundp 'add-to-invisibility-spec) + (defalias 'muse-add-to-invisibility-spec 'add-to-invisibility-spec) + (defun muse-add-to-invisibility-spec (element) + "Add ELEMENT to `buffer-invisibility-spec'. +See documentation for `buffer-invisibility-spec' for the kind of elements +that can be added." + (if (eq buffer-invisibility-spec t) + (setq buffer-invisibility-spec (list t))) + (setq buffer-invisibility-spec + (cons element buffer-invisibility-spec)))) + +(if (fboundp 'read-directory-name) + (defalias 'muse-read-directory-name 'read-directory-name) + (defun muse-read-directory-name (prompt &optional dir default-dirname mustmatch initial) + "Read directory name - see `read-file-name' for details." + (unless dir + (setq dir default-directory)) + (read-file-name prompt dir (or default-dirname + (if initial (expand-file-name initial dir) + dir)) + mustmatch initial))) + +(defun muse-file-remote-p (file) + "Test whether FILE specifies a location on a remote system. +Return non-nil if the location is indeed remote. + +For example, the filename \"/user@host:/foo\" specifies a location +on the system \"/user@host:\"." + (cond ((fboundp 'file-remote-p) + (file-remote-p file)) + ((fboundp 'tramp-handle-file-remote-p) + (tramp-handle-file-remote-p file)) + ((and (boundp 'ange-ftp-name-format) + (string-match (car ange-ftp-name-format) file)) + t) + (t nil))) + +(if (fboundp 'delete-and-extract-region) + (defalias 'muse-delete-and-extract-region 'delete-and-extract-region) + (defun muse-delete-and-extract-region (start end) + "Delete the text between START and END and return it." + (prog1 (buffer-substring start end) + (delete-region start end)))) + +(if (fboundp 'delete-dups) + (defalias 'muse-delete-dups 'delete-dups) + (defun muse-delete-dups (list) + "Destructively remove `equal' duplicates from LIST. +Store the result in LIST and return it. LIST must be a proper list. +Of several `equal' occurrences of an element in LIST, the first +one is kept." + (let ((tail list)) + (while tail + (setcdr tail (delete (car tail) (cdr tail))) + (setq tail (cdr tail)))) + list)) + +;; Set face globally in a predictable fashion +(defun muse-copy-face (old new) + "Copy face OLD to NEW." + (if (featurep 'xemacs) + (copy-face old new 'all) + (copy-face old new))) + +;; Widget compatibility functions + +(defun muse-widget-type-value-create (widget) + "Convert and instantiate the value of the :type attribute of WIDGET. +Store the newly created widget in the :children attribute. + +The value of the :type attribute should be an unconverted widget type." + (let ((value (widget-get widget :value)) + (type (widget-get widget :type))) + (widget-put widget :children + (list (widget-create-child-value widget + (widget-convert type) + value))))) + +(defun muse-widget-child-value-get (widget) + "Get the value of the first member of :children in WIDGET." + (widget-value (car (widget-get widget :children)))) + +(defun muse-widget-type-match (widget value) + "Non-nil if the :type value of WIDGET matches VALUE. + +The value of the :type attribute should be an unconverted widget type." + (widget-apply (widget-convert (widget-get widget :type)) :match value)) + +;; Link-handling functions and variables + +(defun muse-get-link (&optional target) + "Based on the match data, retrieve the link. +Use TARGET to get the string, if it is specified." + (muse-match-string-no-properties 1 target)) + +(defun muse-get-link-desc (&optional target) + "Based on the match data, retrieve the link description. +Use TARGET to get the string, if it is specified." + (muse-match-string-no-properties 2 target)) + +(defvar muse-link-specials + '(("[" . "%5B") + ("]" . "%5D") + ("%" . "%%")) + "Syntax used for escaping and unescaping links. +This allows brackets to occur in explicit links as long as you +use the standard Muse functions to create them.") + +(defun muse-link-escape (text) + "Escape characters in TEXT that conflict with the explicit link +regexp." + (when (stringp text) + (muse-escape-specials-in-string muse-link-specials text))) + +(defun muse-link-unescape (text) + "Un-escape characters in TEXT that conflict with the explicit +link regexp." + (when (stringp text) + (muse-escape-specials-in-string muse-link-specials text t))) + +(defun muse-handle-url (&optional string) + "If STRING or point has a URL, match and return it." + (if (if string (string-match muse-url-regexp string) + (looking-at muse-url-regexp)) + (match-string 0 string))) + +(defcustom muse-implicit-link-functions '(muse-handle-url) + "A list of functions to handle an implicit link. +An implicit link is one that is not surrounded by brackets. + +By default, Muse handles URLs only. +If you want to handle WikiWords, load muse-wiki.el." + :type 'hook + :options '(muse-handle-url) + :group 'muse) + +(defun muse-handle-implicit-link (&optional link) + "Handle implicit links. If LINK is not specified, look at point. +An implicit link is one that is not surrounded by brackets. +By default, Muse handles URLs only. +If you want to handle WikiWords, load muse-wiki.el. + +This function modifies the match data so that match 0 is the +link. + +The match data is restored after each unsuccessful handler +function call. If LINK is specified, only restore at very end. + +This behavior is needed because the part of the buffer that +`muse-implicit-link-regexp' matches must be narrowed to the part +that is an accepted link." + (let ((funcs muse-implicit-link-functions) + (res nil) + (data (match-data t))) + (while funcs + (setq res (funcall (car funcs) link)) + (if res + (setq funcs nil) + (unless link (set-match-data data)) + (setq funcs (cdr funcs)))) + (when link (set-match-data data)) + res)) + +(defcustom muse-explicit-link-functions nil + "A list of functions to handle an explicit link. +An explicit link is one [[like][this]] or [[this]]." + :type 'hook + :group 'muse) + +(defun muse-handle-explicit-link (&optional link) + "Handle explicit links. If LINK is not specified, look at point. +An explicit link is one that looks [[like][this]] or [[this]]. + +The match data is preserved. If no handlers are able to process +LINK, return LINK (if specified) or the 1st match string. If +LINK is not specified, it is assumed that Muse has matched +against `muse-explicit-link-regexp' before calling this +function." + (let ((funcs muse-explicit-link-functions) + (res nil)) + (save-match-data + (while funcs + (setq res (funcall (car funcs) link)) + (if res + (setq funcs nil) + (setq funcs (cdr funcs))))) + (muse-link-unescape + (if res + res + (or link (muse-get-link)))))) + +;; Movement functions + +(defun muse-list-item-type (str) + "Determine the type of list given STR. +Returns either 'ul, 'ol, 'dl-term, 'dl-entry, or nil." + (save-match-data + (cond ((or (string= str "") + (< (length str) 2)) + nil) + ((string-match muse-dl-entry-regexp str) + 'dl-entry) + ((string-match muse-dl-term-regexp str) + 'dl-term) + ((string-match muse-ol-item-regexp str) + 'ol) + ((string-match muse-ul-item-regexp str) + 'ul) + (t nil)))) + +(defun muse-list-item-critical-point (&optional offset) + "Figure out where the important markup character for the +currently-matched list item is. + +If OFFSET is specified, it is the number of groupings outside of +the contents of `muse-list-item-regexp'." + (unless offset (setq offset 0)) + (if (match-end (+ offset 2)) + ;; at a definition list + (match-end (+ offset 2)) + ;; at a different kind of list + (match-beginning (+ offset 1)))) + +(defun muse-forward-paragraph (&optional pattern) + "Move forward safely by one paragraph, or according to PATTERN." + (when (get-text-property (point) 'muse-end-list) + (goto-char (next-single-property-change (point) 'muse-end-list))) + (setq pattern (if pattern + (concat "^\\(?:" pattern "\\|\n\\|\\'\\)") + "^\\s-*\\(\n\\|\\'\\)")) + (let ((next-list-end (or (next-single-property-change (point) 'muse-end-list) + (point-max)))) + (forward-line 1) + (if (re-search-forward pattern nil t) + (goto-char (match-beginning 0)) + (goto-char (point-max))) + (when (> (point) next-list-end) + (goto-char next-list-end)))) + +(defun muse-forward-list-item-1 (type empty-line indented-line) + "Determine whether a nested list item is after point." + (if (match-beginning 1) + ;; if we are given a dl entry, skip past everything on the same + ;; level, except for other dl entries + (and (eq type 'dl-entry) + (not (eq (char-after (match-beginning 2)) ?\:))) + ;; blank line encountered with no list item on the same + ;; level after it + (let ((beg (point))) + (forward-line 1) + (if (save-match-data + (and (looking-at indented-line) + (not (looking-at empty-line)))) + ;; found that this blank line is followed by some + ;; indentation, plus other text, so we'll keep + ;; going + t + (goto-char beg) + nil)))) + +(defun muse-forward-list-item (type indent &optional no-skip-nested) + "Move forward to the next item of TYPE. +Return non-nil if successful, nil otherwise. +The beginning indentation is given by INDENT. + +If NO-SKIP-NESTED is non-nil, do not skip past nested items. +Note that if you desire this behavior, you will also need to +provide a very liberal INDENT value, such as +\(concat \"[\" muse-regexp-blank \"]*\")." + (let* ((list-item (format muse-list-item-regexp indent)) + (empty-line (concat "^[" muse-regexp-blank "]*\n")) + (indented-line (concat "^" indent "[" muse-regexp-blank "]")) + (list-pattern (concat "\\(?:" empty-line "\\)?" + "\\(" list-item "\\)"))) + (while (progn + (muse-forward-paragraph list-pattern) + ;; make sure we don't go past boundary + (and (not (or (get-text-property (point) 'muse-end-list) + (>= (point) (point-max)))) + ;; move past markup that is part of another construct + (or (and (match-beginning 1) + (or (get-text-property + (muse-list-item-critical-point 1) 'muse-link) + (and (derived-mode-p 'muse-mode) + (get-text-property + (muse-list-item-critical-point 1) + 'face)))) + ;; skip nested items + (and (not no-skip-nested) + (muse-forward-list-item-1 type empty-line + indented-line)))))) + (cond ((or (get-text-property (point) 'muse-end-list) + (>= (point) (point-max))) + ;; at a list boundary, so stop + nil) + ((let ((str (when (match-beginning 2) + ;; get the entire line + (save-excursion + (goto-char (match-beginning 2)) + (buffer-substring (muse-line-beginning-position) + (muse-line-end-position)))))) + (and str (eq type (muse-list-item-type str)))) + ;; same type, so indicate that there are more items to be + ;; parsed + (goto-char (match-beginning 1))) + (t + (when (match-beginning 1) + (goto-char (match-beginning 1))) + ;; move to just before foreign list item markup + nil)))) + +(defun muse-goto-tag-end (tag nested) + "Move forward past the end of TAG. + +If NESTED is non-nil, look for other instances of this tag that +may be nested inside of this tag, and skip past them." + (if (not nested) + (search-forward (concat "") nil t) + (let ((nesting 1) + (tag-regexp (concat "\\(<\\(/?\\)" tag "\\([ >]\\)\\)")) + (match-found nil)) + (while (and (> nesting 0) + (setq match-found (re-search-forward tag-regexp nil t))) + ;; for the sake of font-locking code, skip matches in comments + (unless (get-text-property (match-beginning 0) 'muse-comment) + (if (string-equal (match-string 2) "/") + (and (string-equal (match-string 3) ">") + (setq nesting (1- nesting))) + (setq nesting (1+ nesting))))) + match-found))) + +;;; muse.el ends here diff --git a/elpa/muse-3.20/muse.info b/elpa/muse-3.20/muse.info new file mode 100644 index 0000000..28bd20d --- /dev/null +++ b/elpa/muse-3.20/muse.info @@ -0,0 +1,4656 @@ +This is muse.info, produced by makeinfo version 4.13 from muse.texi. + +INFO-DIR-SECTION Emacs +START-INFO-DIR-ENTRY +* Muse: (muse). Authoring and publishing environment for Emacs. +END-INFO-DIR-ENTRY + + This manual is for Emacs Muse version 3.20. + + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free +Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, with the Front-Cover texts + being "A GNU Manual", and with the Back-Cover Texts as in (a) + below. A copy of the license is included in the section entitled + "GNU Free Documentation License" in this manual. + + (a) The FSF's Back-Cover Text is: "You have freedom to copy and + modify this GNU Manual, like GNU software. Copies published by + the Free Software Foundation raise funds for GNU development." + + This document is part of a collection distributed under the GNU + Free Documentation License. If you want to distribute this + document separately from the collection, you can do so by adding a + copy of the license to the document, as described in section 6 of + the license. + + All Emacs Lisp code contained in this document may be used, + distributed, and modified without restriction. + + +File: muse.info, Node: Top, Next: Preface, Prev: (dir), Up: (dir) + +Muse +**** + +This manual is for Emacs Muse version 3.20. + + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free +Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, with the Front-Cover texts + being "A GNU Manual", and with the Back-Cover Texts as in (a) + below. A copy of the license is included in the section entitled + "GNU Free Documentation License" in this manual. + + (a) The FSF's Back-Cover Text is: "You have freedom to copy and + modify this GNU Manual, like GNU software. Copies published by + the Free Software Foundation raise funds for GNU development." + + This document is part of a collection distributed under the GNU + Free Documentation License. If you want to distribute this + document separately from the collection, you can do so by adding a + copy of the license to the document, as described in section 6 of + the license. + + All Emacs Lisp code contained in this document may be used, + distributed, and modified without restriction. + +* Menu: + +* Preface:: About the documentation. +* Introduction:: What is Muse? +* Obtaining Muse:: How to get Muse releases and development + changes. +* Installation:: Compiling and installing Muse. +* Getting Started:: Setting up Muse and editing files. +* Projects:: Creating and managing Muse projects. +* Keystroke Summary:: Keys used in Muse mode. +* Markup Rules:: Rules for using markup. +* Publishing Styles:: Publishing various types of documents. +* Extending Muse:: Making your own publishing styles. +* Miscellaneous:: Miscellaneous add-ons, like a minor mode. +* Getting Help and Reporting Bugs:: +* History:: History of this document. +* Contributors:: Contributors to this documentation. +* GNU Free Documentation License:: The license for this documentation. +* Concept Index:: Search for terms. + + --- The Detailed Node Listing --- + +How to Get Muse Releases and Development Changes + +* Releases:: Released versions of Muse. +* Development:: Latest unreleased development changes. + +Getting Started + +* Loading Muse:: How to load Muse. +* Using Muse Mode:: How to edit files in Muse. +* Publishing Files Overview:: Publishing a single file or project. +* File Extensions:: Using a different file extension. + +Creating and Managing Muse Projects + +* Single Project:: A single-project example. +* Multiple Projects:: A multiple-project example. +* Projects and Subdirectories:: Publishing subdirectories in projects. +* Options for Projects:: Listing of available options for projects. + +Rules for Using Markup + +* Paragraphs:: Paragraphs: centering and quoting. +* Headings:: Levels of headings. +* Directives:: Directives at the beginning of a + document. +* Emphasizing Text:: Bold, italicized, and underlined text. +* Footnotes:: Making notes to be shown at the end. +* Verse:: Indicating poetic stanzas. +* Lists:: Lists of items. +* Tables:: Generation of data tables. +* Explicit Links:: Hyperlinks and email addresses with + descriptions. +* Implicit Links:: Bare URLs, WikiNames, and InterWiki + links. +* Images:: Publishing and displaying images. +* Horizontal Rules and Anchors:: Inserting a horizontal line or anchor. +* Embedded Lisp:: Evaluating Emacs Lisp code in documents + for extensibility. +* Citations:: Support for citing other resources. +* Comments:: Lines to omit from published output. +* Tag Summary:: Tags that Muse recognizes. + +Publishing Various Types of Documents + +* Blosxom:: Integrating Muse and pyblosxom.cgi. +* Book:: Publishing entries into a compilation. +* ConTeXt:: Publishing ConTeXt documents. +* DocBook:: Publishing in DocBook XML form. +* HTML:: Publishing in HTML or XHTML form. +* Ikiwiki:: Integrating with ikiwiki. +* Journal:: Keeping a journal or blog. +* LaTeX:: Publishing LaTeX documents. +* Poem:: Publish a poem to LaTeX or PDF. +* Texinfo:: Publish entries to Texinfo format or PDF. +* XML:: Publish entries to XML. + +Integrating Muse and pyblosxom.cgi + +* Blosxom Requirements:: Other tools needed for the Blosxom style. +* Blosxom Entries:: Format of a Blosxom entry and automation. +* Blosxom Options:: Blosxom styles and options provided. + +Making your own publishing styles + +* Markup Functions:: Specifying functions to mark up text. +* Markup Regexps:: Markup rules for publishing. +* Markup Strings:: Strings specific to a publishing style. +* Markup Tags:: Tag specifications for special markup. +* Style Elements:: Parameters used for defining styles. +* Deriving Styles:: Deriving a new style from an existing + one. + +Miscellaneous add-ons, like a minor mode + +* Muse List Edit Minor Mode:: Edit lists easily in other major modes. + + +File: muse.info, Node: Preface, Next: Introduction, Prev: Top, Up: Top + +1 About the documentation +************************* + +This document describes Muse, which was written by John Wiegley and is +now maintained by Michael Olson. Several versions of this manual are +available on-line. + + * PDF: http://mwolson.org/static/doc/muse.pdf + + * HTML (single file): http://mwolson.org/static/doc/muse.html + + * HTML (multiple files): http://mwolson.org/static/doc/muse/ + + +File: muse.info, Node: Introduction, Next: Obtaining Muse, Prev: Preface, Up: Top + +2 What is Muse? +*************** + +Emacs Muse (also known as "Muse" or "Emacs-Muse") is an authoring and +publishing environment for Emacs. It simplifies the process of writing +documents and publishing them to various output formats. + + Muse consists of two main parts: an enhanced text-mode for authoring +documents and navigating within Muse projects, and a set of publishing +styles for generating different kinds of output. + + What makes Muse distinct from other text-publishing systems is a +modular environment, with a rather simple core, in which "styles" are +derived from to create new styles. Much of Muse's overall +functionality is optional. For example, you can use the publisher +without the major-mode, or the mode without doing any publishing; or if +you don't load the Texinfo or LaTeX modules, those styles won't be +available. + + The Muse codebase is a departure from emacs-wiki.el version 2.44. The +code has been restructured and rewritten, especially its publishing +functions. The focus in this revision is on the authoring and +publishing aspects, and the "wikiness" has been removed as a default +behavior (available in the optional `muse-wiki' module). CamelCase +words are no longer special by default. + + One of the principal aims in the development of Muse is to make it +very easy to produce good-looking, standards-compliant documents. + + +File: muse.info, Node: Obtaining Muse, Next: Installation, Prev: Introduction, Up: Top + +3 How to Get Muse Releases and Development Changes +************************************************** + +* Menu: + +* Releases:: Released versions of Muse. +* Development:: Latest unreleased development changes. + + +File: muse.info, Node: Releases, Next: Development, Prev: Obtaining Muse, Up: Obtaining Muse + +3.1 Released versions of Muse +============================= + +Choose to install a release if you want to minimize risk. + + Errors are corrected in development first. User-visible changes +will be announced on the mailing list. *Note +Getting Help and Reporting Bugs::. + + Debian users can get Muse via apt-get. The `muse-el' package is +available both at Michael Olson's APT repository and the official Debian +repository. To make use of the former, add the following line to your +`/etc/apt/sources.list' file and run `apt-get install muse'. + + deb http://mwolson.org/debian/ ./ + + Ubuntu users can also get Muse via apt-get. The `muse-el' package +is available both at Michael Olson's APT repository and the official +Ubuntu repository. To make use of the former, add the following line to +your `/etc/apt/sources.list' file and run `apt-get install muse'. + + deb http://mwolson.org/ubuntu/ ./ + + The reason for making separate Debian and Ubuntu packages is that +this manual is under the GFDL, and Debian will not allow it to be +distributed in its main repository. Ubuntu, on the other hand, permits +this manual to be included with the `muse-el' package. + + Alternatively, you can download the latest release from +`http://download.gna.org/muse-el/' . + + +File: muse.info, Node: Development, Prev: Releases, Up: Obtaining Muse + +3.2 Latest unreleased development changes +========================================= + +Choose the development version if you want to live on the bleeding edge +of Muse development or try out new features before release. + + The git version control system allows you to keep up-to-date with the +latest changes to the development version of Muse. It also allows you +to contribute changes (via commits, if you are have developer access to +the repository, or via patches, otherwise). If you would like to +contribute to Muse development, it is highly recommended that you use +git. + + If you are new to git, you might find this tutorial helpful: +`http://www.kernel.org/pub/software/scm/git/docs/tutorial.html'. + + Downloading the Muse module with git and staying up-to-date involves +the following steps. + + 1. Install git. + + * Debian and Ubuntu: `apt-get install git-core'. + + * Windows: `http://git.or.cz/gitwiki/WindowsInstall'. + + * Other operating systems: download, compile, and install the + source from `http://www.kernel.org/pub/software/scm/git/', or + find a git package for your operating system. + + 2. Download the Muse development branch. + + If you have developer access to Muse, do: + + git clone ssh://repo.or.cz/srv/git/muse-el.git muse + + otherwise, do: + + git clone git://repo.or.cz/muse-el.git muse + + If you are behind a restrictive firewall, and do not have developer + access, then do the following instead: + + git clone http://repo.or.cz/r/muse-el.git muse + + 3. List upstream changes that are missing from your local copy. Do + this whenever you want to see whether new changes have been + committed to Muse. If you wish, you may skip this step and + proceed directly to the "update" step. + + # Change to the source directory you are interested in. + cd muse + + # Fetch new changes from the repository, but don't apply them yet + git fetch origin + + # Display log messages for the new changes + git log HEAD..origin + + "origin" is git's name for the location where you originally got + Muse from. You can change this location at any time by editing the + `.git/config' file in the directory where the Muse source was + placed. + + 4. Update to the latest version by pulling in any missing changes. + + cd muse + git pull origin + + git will show how many files changed, and will provide a visual + display for how many lines were changed in each file. + + + There are other ways to interact with the Muse repository. + + * Browse git repo: `http://repo.or.cz/w/muse-el.git' + + * Latest development snapshot: + `http://mwolson.org/static/dist/muse-latest.tar.gz' + + * Latest development snapshot (zip file): + `http://mwolson.org/static/dist/muse-latest.zip' + + The latest development snapshot can lag behind the git repo by as +much as 20 minutes, but never more than that. + +Becoming a Muse developer +------------------------- + +If you want commit access to the shared Muse repository, then register +an account at `http://repo.or.cz' (be sure to add an SSH key), and +contact the current maintainer at . It would be best +to send some patches to the mailing list +first, so that he knows that you know what you are doing. *Note +Getting Help and Reporting Bugs::, for instructions on subscribing to +the mailing list. + + You must also be willing to sign a copyright assignment for your +changes to Muse, since Muse is a GNU project. The current maintainer +will assist you in this process if you contact him. + + For information on committing changes to Muse and performing +development, please consult +`http://emacswiki.org/cgi-bin/wiki/MuseDevelopment'. + + +File: muse.info, Node: Installation, Next: Getting Started, Prev: Obtaining Muse, Up: Top + +4 Compiling and Installing Muse +******************************* + +Muse may be compiled and installed on your machine. + +Compilation +----------- + +This is an optional step, since Emacs Lisp source code does not +necessarily have to be byte-compiled. Byte-compilation may yield a very +slight speed increase. + + A working copy of Emacs or XEmacs is needed in order to compile Emacs +Muse. By default, the program that is installed with the name `emacs' +will be used. + + If you want to use the `xemacs' binary to perform the compilation, +you must copy `Makefile.defs.default' to `Makefile.defs' in the +top-level directory, and then edit `Makefile.defs' as follows. You can +put either a full path to an Emacs or XEmacs binary or just the command +name, as long as it is in the `PATH'. + + EMACS = xemacs + SITEFLAG = -no-site-file + # Edit the section as necessary + install_info = install-info --section "XEmacs 21.4" $(1).info \ + $(INFODIR)/dir || : + + Running `make' in the top-level directory should compile the Muse +source files in the `lisp' directory, and generate an autoloads file in +`lisp/muse-autoloads.el'. + +Installation +------------ + +Muse may be installed into your file hierarchy by doing the following. + + Copy `Makefile.defs.default' to `Makefile.defs' in the top-level +directory, if you haven't done so already. Then edit the +`Makefile.defs' file so that `ELISPDIR' points to where you want the +source and compiled Muse files to be installed and `INFODIR' indicates +where to put the Muse manual. You may use a combination of `DESTDIR' +and `PREFIX' to further determine where the installed files should be +placed. As mentioned earlier, you will want to edit `EMACS' and +`SITEFLAG' as shown in the Compilation section if you are using XEmacs. + + If you are installing Muse on a Debian or Ubuntu system, you might +want to change the value of `INSTALLINFO' as specified in +`Makefile.defs'. + + If you wish to install Muse to different locations than the defaults +specify, edit `Makefile.defs' accordingly. + + Run `make' as a normal user, if you haven't done so already. + + Run `make install' as the root user if you have chosen installation +locations that require root permissions. + +ELPA +---- + +For those used to installing software packages, there will be a `muse' +package available in the Emacs Lisp Package Archive (abbreviated +"ELPA") as of the 3.10 release of Muse. This package will be compiled +and installed automatically in a user-specific location. For more +information on ELPA, see `http://tromey.com/elpa/'. + + +File: muse.info, Node: Getting Started, Next: Projects, Prev: Installation, Up: Top + +5 Getting Started +***************** + +* Menu: + +* Loading Muse:: How to load Muse. +* Using Muse Mode:: How to edit files in Muse. +* Publishing Files Overview:: Publishing a single file or project. +* File Extensions:: Using a different file extension. + + +File: muse.info, Node: Loading Muse, Next: Using Muse Mode, Prev: Getting Started, Up: Getting Started + +5.1 How to Load Muse +==================== + +To use Muse, add the directory containing its files to your `load-path' +variable, in your `.emacs' file. Then, load in the authoring mode, and +the styles you wish to publish to. An example follows. + + (add-to-list 'load-path "") + + (require 'muse-mode) ; load authoring mode + + (require 'muse-html) ; load publishing styles I use + (require 'muse-latex) + (require 'muse-texinfo) + (require 'muse-docbook) + + (require 'muse-project) ; publish files in projects + + An easy way of seeing which settings are available and changing +settings is to use the Muse customization interface. To do this, type +`M-x customize-group muse RET'. Each of the options has its own +documentation. Options are grouped logically according to what effect +they have. + + +File: muse.info, Node: Using Muse Mode, Next: Publishing Files Overview, Prev: Loading Muse, Up: Getting Started + +5.2 How to Edit Files in Muse +============================= + +Muse Mode should automatically be activated when you visit a file with a +".muse" extension. One such file is `QuickStart.muse', which is +available in the `examples' directory of the Muse distribution. You +can tell that Muse Mode has been activated by checking for the text +"Muse" in your mode line. If Muse Mode has not been activated, you may +activate it by type `M-x muse-mode RET'. + + You will notice that Muse files are highlighted very simply. Links +are colored blue, headings are large and bold text, and tags +are colored in grey. + + There are several different ways to edit things like links, which +hide the underlying Muse markup. One way is to toggle font-locking off +by hitting `C-c C-l', which is also `M-x font-lock-mode', make changes, +and then hit `C-c C-l' again to toggle font-locking back on. Another +way is just to move into the text and edit it. Markup can also be +removed by normal deletion methods, though some side effects might +require a second deletion. + + For the particular case of editing links, it is easiest to move to +the link and do `C-c C-e', which is also `M-x muse-edit-link-at-point'. +This prompts you for the link and its description, using the previous +contents of the link as initial values. A link to another Muse file +may be created by hitting `C-c TAB l'. A link to a URL may be created +by hitting `C-c TAB u'. Links may be followed by hitting `RET' on them. + + If you want to add a new list item, this may by accomplished by +hitting `M-RET'. This will put a dash and some spaces on the screen. +The dash is the Muse markup that indicates a list item. It is also +possible to created "nested" lists with this command, by adjusting the +number of spaces in front of the dashes. If you have lists with long +lines, you can move to a list item and hit `M-q' to wrap it onto +multiple lines. + + +File: muse.info, Node: Publishing Files Overview, Next: File Extensions, Prev: Using Muse Mode, Up: Getting Started + +5.3 Publishing a Single File or Project +======================================= + +The command `M-x muse-project-publish-this-file' will publish the +current document to any available publishing style (a publishing style +is an output format, like HTML or Docbook), placing the output in the +current directory. If you are in Muse Mode, this command will be bound +to `C-c C-t'. If the file has been published recently, and its +contents have not changed, running `C-c C-t' again will not publish the +file. To force publishing in this case, do `C-u C-c C-t'. + + If you have set up projects and are visiting a file that is part of a +project, then `C-c C-t' will restrict the output formats to those which +are used by the project, and will automatically publish to the output +directory defined by the project. If you want to publish to a +different directory or use a different format, then use `C-c M-C-t', +which is also `M-x muse-publish-this-file'. + + If the currently opened file is part of a defined project in +`muse-project-alist', it (and the rest of the changed files in a +project) may be published using `C-c C-p'. + + +File: muse.info, Node: File Extensions, Prev: Publishing Files Overview, Up: Getting Started + +5.4 Using a Different File Extension +==================================== + +By default, Muse expects all project files to have the file extension +`.muse'. Files without this extension will not be associated with Muse +mode and will not be considered part of any project, even if they are +within a project directory. + + If you don't want to use `.muse', you can customize the extension by +setting the value of `muse-file-extension'. + + If you don't want to use any extension at all, and want Muse to +autodetect project files based on their location, then add the following +to your Muse settings file. + + (setq muse-file-extension nil + muse-mode-auto-p t) + + Note that if you chose to have `muse-file-extension' set to `nil', +you may have trouble if your `.emacs' file or other init scripts +attempt to visit a Muse file. (A very common example of this is if you +use Planner with Muse and run `(plan)' from your `.emacs'.) If you +wish to visit Muse files from your `.emacs', be sure to also add the +following additional code before any such visits happen: + + (add-hook 'find-file-hooks 'muse-mode-maybe) + + +File: muse.info, Node: Projects, Next: Keystroke Summary, Prev: Getting Started, Up: Top + +6 Creating and Managing Muse Projects +************************************* + +Often you will want to publish all the files within a directory to a +particular set of output styles automatically. To support, Muse allows +for the creation of "projects". + +* Menu: + +* Single Project:: A single-project example. +* Multiple Projects:: A multiple-project example. +* Projects and Subdirectories:: Publishing subdirectories in projects. +* Options for Projects:: Listing of available options for projects. + + +File: muse.info, Node: Single Project, Next: Multiple Projects, Prev: Projects, Up: Projects + +6.1 A Single-Project Example +============================ + +Here is a sample project, which may be defined in your `.emacs' file. + + (setq muse-project-alist + '(("Website" ("~/Pages" :default "index") + (:base "html" :path "~/public_html") + (:base "pdf" :path "~/public_html/pdf")))) + + The above defines a project named "website", whose files are located +in the directory `~/Pages'. The default page to visit is `index'. +When this project is published, each page will be output as HTML to the +directory `~/public_html', and as PDF to the directory +`~/public_html/pdf'. Within any project page, you may create a link to +other pages using the syntax `[[pagename]]'. + + If you would like to include only some files from a directory in a +Muse project, you may use a regexp in place of `~/Pages' in the example. + + +File: muse.info, Node: Multiple Projects, Next: Projects and Subdirectories, Prev: Single Project, Up: Projects + +6.2 A Multiple-Project Example +============================== + +It is possible to specify multiple projects. Here is an example of +three projects: a generic website, a projects area, and a day-planner +(the day-planner part requires Planner Mode--see +`http://wjsullivan.net/PlannerMode.html' to get it). + + (setq muse-project-alist + '(("Website" ("~/Pages" :default "index") + (:base "html" :path "~/public_html")) + (("Projects" ("~/Projects" :default "index") + (:base "xhtml" + :path "~/public_html/projects" + :exclude "/TopSecret") + (:base "pdf" + :path "~/public_html/projects/pdf" + :exclude "/TopSecret"))) + ("Plans" ("~/Plans" + :default "TaskPool" + :major-mode planner-mode + :visit-link planner-visit-link) + (:base "planner-xhtml" + :path "~/public_html/plans")))) + + The `:major-mode' attribute specifies which major to use when +visiting files in this directory. + + The `:visit-link' attribute specifies the function to call when +visiting links. + + The `:exclude' attribute has a regexp that matches files to never +publish. + + +File: muse.info, Node: Projects and Subdirectories, Next: Options for Projects, Prev: Multiple Projects, Up: Projects + +6.3 Publishing Subdirectories in Projects +========================================= + +If you want to publish a directory and all of its subdirectories, Muse +provides two convenience functions that together generate the proper +rules for you. Note that we use the backtick to begin this +muse-project-alist definition, rather than a single quote. + + (setq muse-project-alist + `(("Website" ("~/Pages" :default "index") + (:base "html" :path "~/public_html")) + ("Blog" (,@(muse-project-alist-dirs "~/Blog") + :default "index") + ;; Publish this directory and its subdirectories. Arguments + ;; are as follows. The above `muse-project-alist-dirs' part + ;; is also needed. + ;; 1. Source directory + ;; 2. Output directory + ;; 3. Publishing style + ;; remainder: Other things to put in every generated style + ,@(muse-project-alist-styles "~/Blog" + "~/public_html/blog" + "blosxom")))) + + The `muse-project-alist-dirs' function takes a directory and returns +it and all of its subdirectories in a list. + + The `muse-project-alist-styles' function is explained by the +comments above. + + The "blosxom" text is the name of another publishing style, much like +"html". *Note Blosxom::, for further information about it. You can +use any publishing style you like for the third argument to +`muse-project-alist-styles'. + + +File: muse.info, Node: Options for Projects, Prev: Projects and Subdirectories, Up: Projects + +6.4 Listing of Available Options for Projects +============================================= + +This is a listing of all of the various options (or, more accurately: +attributes) that may be specified in `muse-project-alist'. + + Each muse-project-alist entry looks like this: + + (PROJECT-NAME (SOURCES) + OUTPUTS) + + We refer to these names below. + + "Attributes", which compose SOURCES and OUTPUTS, are a pair of +values. The first value is a keyword, like `:default'. The second part +is the value associated with that keyword, such as the text "index". +If you are familiar with Emacs Lisp property lists, the concept is +similar to that, except that in the SOURCES section, single directories +can be interspersed with two-value attributes. + +Project Name +------------ + +This is a string that indicates the name of the project. It is +primarily used for publishing interwiki links with the `muse-wiki.el' +module. + +Sources +------- + +This part of a muse-project-alist entry consists of two-value +attributes, and also directory names. If you are publishing a book, the +order of directories and attributes is significant. + + The minimal content for the sources section is a list of directories. + +`:book-chapter' + Indicates a new chapter of a book. The text of the title of the + chapter comes immediately after this keyword. + +`:book-end' + Indicates the end of a book. Directories listed after this one are + ignored when publishing a book. The value "t" (without quotes) + should come immediately after this keyword. + +`:book-funcall' + A function to call while publishing a book. This is useful for + doing something just after a particular chapter. + +`:book-part' + Indicates the beginning of a new part of the book. The text of the + title should come immediately after this keyword. + +`:book-style' + Indicate a particular publishing style to use for this part of the + book. If this is specified, it should come just after a `:part' + attribute. + +`:default' + The default page to visit when browsing a project. Also, if you + are using the `muse-wiki.el' module, publishing a link to just a + project's name will cause it to link to this default file. + +`:force-publish' + This specifies a list of pages which should be published every + time a project is published (by using `C-c C-p', for example), + regardless of whether their contents have changed. This is useful + for updating Index pages, pages that use the tag, and + other pages that have dynamically-generated content. + +`:major-mode' + This specifies the major mode to use when visiting files in this + project. The default is `muse-mode'. + +`:nochapters' + This indicates that while publishing a book, do not automatically + create chapters. Values which may follow this are nil (the + default, which means that we automatically create chapters), or + non-nil, which means that we manually specify chapters with the + `:book-chapter' attribute, + +`:publish-project' + Indicates which function we should call when publishing a project. + +`:set' + This specifies a list of variables and values to set when + publishing a project. The list should be a property list, which + is in the form: + + (VAR1 VALUE1 VAR2 VALUE2 ...) + +`:visit-link' + Specifies the function to call when visiting a link. The default + is `muse-visit-link-default'. The arguments for that function + should be (1) the link and (2) whether to visit the link in a new + window. + + +Outputs +------- + +This part of a muse-project-alist entry is composed of lists of +attributes. Each list is called an "output style". + + The minimal content for an output style is a `:base' attribute and a +`:path' attribute. + +`:base' + Publishing style to use, such as "html", "docbook", or "pdf". + +`:base-url' + An external URL which can be used to access published files. This + is mainly used by the `muse-wiki' module when publishing links + between two separate projects, if the projects are served on + different domains. + + It is also used by the `muse-journal' module to create the RSS or + RDF output. + +`:exclude' + Exclude items matching a regexp from being published. The regexp + should usually begin with "/". + +`:include' + Only include items matching a regexp when publishing. The regexp + should usually begin with "/". + +`:path' + The directory in which to store published files. + +`:timestamps' + A file containing the timestamps (that is, time of creation) for + files in this project. It might eventually used by the + `muse-blosxom' module, but this option is not currently in use by + any Muse code. + + + +File: muse.info, Node: Keystroke Summary, Next: Markup Rules, Prev: Projects, Up: Top + +7 Keys Used in Muse Mode +************************ + +This is a summary of keystrokes available in every Muse buffer. + +`C-c C-a (`muse-index')' + Display an index of all known Muse pages. + +`C-c C-b (`muse-find-backlinks')' + Find all pages that link to this page. + +`C-c C-e (`muse-edit-link-at-point')' + Edit link at point. + +`C-c C-f (`muse-project-find-file')' + Open another Muse page. Prompt for the name. + +`C-c C-i l, C-c TAB l (`muse-insert-relative-link-to-file')' + Insert a link to a file interactively. + +`C-c C-i t, C-c TAB t (`muse-insert-tag')' + Insert a tag interactively. + +`C-c C-i u, C-c TAB u (`muse-insert-url')' + Insert a URL interactively. + +`C-c C-l (`font-lock-mode')' + Toggle font lock / highlighting for the current buffer. + +`C-c C-p (`muse-project-publish')' + Publish any Muse pages that have changed. + +`C-c C-s (`muse-search')' + Find text in all files of the current project. + +`C-c C-t (`muse-project-publish-this-file')' + Publish the currently-visited file. Prompt for the style if the + current file can be published using more than one style. + +`C-c C-S-t, or C-c C-M-t (`muse-publish-this-file')' + Publish the currently-visited file. Prompt for both the style and + output directory. + +`C-c C-v (`muse-browse-result')' + Show the published result of this page. + +`C-c = (`muse-what-changed')' + Diff this page against the last backup version. + +`TAB' + Move to the next Wiki reference. + +`S-TAB' + Move to the previous Wiki reference. + +`M-TAB' + Complete the name of a page from the current project at point. + +`M-RET' + Insert a new list item at point, indenting properly. + +`C-<' + Decrease the indentation of the list item at point. + +`C->' + Increase the indentation of the list item at point. + +`M-x muse-colors-toggle-inline-images RET' + Toggle display of inlined images on/off. + +`M-x muse-update-values RET' + Update various values that are automatically generated. + + Call this after changing `muse-project-alist'. + + +File: muse.info, Node: Markup Rules, Next: Publishing Styles, Prev: Keystroke Summary, Up: Top + +8 Rules for Using Markup +************************ + +A Muse document uses special, contextual markup rules to determine how +to format the output result. For example, if a paragraph is indented, +Muse assumes it should be quoted. + + There are not too many markup rules, and all of them strive to be as +simple as possible so that you can focus on document creation, rather +than formatting. + +* Menu: + +* Paragraphs:: Paragraphs: centering and quoting. +* Headings:: Levels of headings. +* Directives:: Directives at the beginning of a + document. +* Emphasizing Text:: Bold, italicized, and underlined text. +* Footnotes:: Making notes to be shown at the end. +* Verse:: Indicating poetic stanzas. +* Lists:: Lists of items. +* Tables:: Generation of data tables. +* Explicit Links:: Hyperlinks and email addresses with + descriptions. +* Implicit Links:: Bare URLs, WikiNames, and InterWiki + links. +* Images:: Publishing and displaying images. +* Horizontal Rules and Anchors:: Inserting a horizontal line or anchor. +* Embedded Lisp:: Evaluating Emacs Lisp code in documents + for extensibility. +* Citations:: Support for citing other resources. +* Comments:: Lines to omit from published output. +* Tag Summary:: Tags that Muse recognizes. + + +File: muse.info, Node: Paragraphs, Next: Headings, Prev: Markup Rules, Up: Markup Rules + +8.1 Paragraphs: centering and quoting +===================================== + +Paragraphs in Muse must be separated by a blank line. + +Centered paragraphs and quotations +---------------------------------- + +A line that begins with six or more columns of whitespace (either tabs +or spaces) indicates a centered paragraph. Alternatively, you can use +the

    tag to surround regions that are to be published as +centered paragraphs. + + But if a line begins with whitespace, though less than six columns, +it indicates a quoted paragraph. Alternatively, you can use the + tag to surround regions that are to be published as quoted +paragraphs. + +Literal paragraphs +------------------ + +The tag is used for examples, where whitespace should be +preserved, the text rendered in monospace, and any characters special +to the output style escaped. + + There is also the tag, which causes a marked block to be +entirely left alone. This can be used for inserting a hand-coded HTML +blocks into HTML output, for example. + + If you want some text to only be inserted when publishing to a +particular publishing style, use the `style' attribute for the + tag. An example follows. + + + A LaTeX-based style was used in the publishing of this document. + + + This will leave the region alone if the current publishing style is +"latex" or based on "latex", such as "pdf", and delete the region +otherwise. It is also possible to leave the text alone only for one +particular style, rather than its derivations, by adding `exact="t"' to +the tag. + +Line breaks +----------- + +If you need a line break, then use the `
    ' tag. Most of the time +this tag is unnecessary, because Muse will automatically detect +paragraphs by means of blank lines. If you want to preserve newlines in +several lines of text, then use verse markup instead (*note Verse::). + + +File: muse.info, Node: Headings, Next: Directives, Prev: Paragraphs, Up: Markup Rules + +8.2 Levels of headings +====================== + +A heading becomes a chapter or section in printed output - depending on +the style. To indicate a heading, start a new paragraph with one or +more asterices, followed by a space and the heading title. Then begin +another paragraph to enter the text for that section. + + All levels of headings will be published. Most publishing styles +only distinguish the between the first 4 levels, however. + + * First level + + ** Second level + + *** Third level + + **** Fourth level + + +File: muse.info, Node: Directives, Next: Emphasizing Text, Prev: Headings, Up: Markup Rules + +8.3 Directives at the beginning of a document +============================================= + +Directives are lines beginning with the `#' character that come before +any paragraphs or sections in the document. Directives are of the form +"#directive content of directive". You can use any combination of +uppercase and lowercase letters for directives, even if the directive +is not in the list below. + + The `muse-publishing-directive' function may be used in header and +footer text to access directives. For example, to access the `#title' +directive, use `(muse-publishing-directive "title")'. + + The following is a list of directives that Muse uses. + +`#author' + The author of this document. + + If this is not specified, Muse will attempt to figure it out from + the `user-full-name' variable. + +`#date' + The date that the document was last modified. + + This is used by publishing styles that are able to embed the date + information. + +`#desc' + A short description of this document. + + This is used by the `journal' publishing style to embed information + inside of an RSS/RDF feed. + +`#title' + The title of this document. + + If this is not specified, the name of the file is used. + + + +File: muse.info, Node: Emphasizing Text, Next: Footnotes, Prev: Directives, Up: Markup Rules + +8.4 Bold, italicized, and underlined text +========================================= + +To emphasize text, surround it with certain specially recognized +characters. + + *emphasis* + **strong emphasis** + ***very strong emphasis*** + _underlined_ + =verbatim and monospace= + + While editing a Muse document in Muse mode, these forms of emphasis +will be highlighted in a WYSIWYG manner. Each of these forms may span +multiple lines. + + Verbatim text will be colored as gray by default. To change this, +customize `muse-verbatim-face'. + + You can also use the tag to indicate verbatim and monospace +text. This is handy for regions that have an "=" in them. + + +File: muse.info, Node: Footnotes, Next: Verse, Prev: Emphasizing Text, Up: Markup Rules + +8.5 Making notes to be shown at the end +======================================= + +A footnote reference is simply a number in square brackets. To define +the footnote, place this definition at the bottom of your file. +`footnote-mode' can be used to greatly facilitate the creation of these +kinds of footnotes. + + Footnotes are defined by the same number in brackets occurring at the +beginning of a line. Use footnote-mode's `C-c ! a' command, to very +easily insert footnotes while typing. Use `C-x C-x' to return to the +point of insertion. + + +File: muse.info, Node: Verse, Next: Lists, Prev: Footnotes, Up: Markup Rules + +8.6 Indicating poetic stanzas +============================= + +Poetry requires that whitespace be preserved, but without resorting to +monospace. To indicate this, use the following markup, reminiscent of +email quotations. + + > A line of Emacs verse; + > forgive its being so terse. + + You can also use the tag, if you prefer. + + + A line of Emacs verse; + forgive its being so terse. + + + Multiple stanzas may be included in one set of tags, as +follows. + + + A line of Emacs verse; + forgive its being so terse. + + In terms of terse verse, + you could do worse. + + + +File: muse.info, Node: Lists, Next: Tables, Prev: Verse, Up: Markup Rules + +8.7 Lists of items +================== + +Lists are given using special characters at the beginning of a line. +Whitespace must occur before bullets or numbered items, to distinguish +from the possibility of those characters occurring in a real sentence. + + These are rendered as a bullet list. + + Normal text. + + - bullet item one + - bullet item two + + An enumerated list follows. + + Normal text. + + 1. Enum item one + 2. Enum item two + + Here is a definition list. + + Term1 :: + This is a first definition + And it has two lines; + no, make that three. + + Term2 :: This is a second definition + +Nested lists +------------ + +It is possible to nest lists of the same or different kinds. The +"level" of the list is determined by the amount of initial whitespace. + + Normal text. + + - Level 1, bullet item one + 1. Level 2, enum item one + 2. Level 2, enum item two + - Level 1, bullet item two + 1. Level 2, enum item three + 2. Level 2, enum item four + term :: definition + +Breaking list items +------------------- + +If you want to break up a line within any list type, just put one blank +line between the end of the previous line and the beginning of the next +line, using the same amount of initial indentation. + + - bullet item 1, line 1 + + bullet item 1, line 2 + + 1. Enum line 1 + + Enum line 2 + + - bullet item 2, line 1 + + bullet item 2, line 2 + + +File: muse.info, Node: Tables, Next: Explicit Links, Prev: Lists, Up: Markup Rules + +8.8 Generation of data tables +============================= + +Only very simple tables are supported. The syntax is as follows. + + Double bars || Separate header fields + + Single bars | Separate body fields + Here are more | body fields + + Triple bars ||| Separate footer fields + + Some publishing styles require header fields to come first, then +footer fields, and then the body fields. You can use any order for +these sections that you like, and Muse will re-order them for you at +publish-time. + + If you wish to disable table generation for one Muse file, add the +directive `#disable-tables t' to the top of the file. + +Other table formats +------------------- + +It is possible to publish very basic Orgtbl-mode style tables. + + | org | style | table | + |------+-------+-------| + | one | | one | + | two | two | | + | | three | three | + |------+-------+-------| + | more | stuff | | + + If you are used to the way that Org Mode publishes these tables, then +customize `muse-html-table-attributes' to the following, in order to get +a similar kind of output. + + border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides" + + `table.el' style tables are also supported, as long as `table.el' +itself supports outputting tables for a particular publishing style. +At the time of this writing, the "html", "latex", and "docbook" styles +are supported by `table.el'. Styles derived from these styles will +also work. + + +---+-----+---+ + | | one | 1 | + +---+-----+---+ + | b | two | | + +---+-----+---+ + | c | | 3 | + +---+-----+---+ + + +File: muse.info, Node: Explicit Links, Next: Implicit Links, Prev: Tables, Up: Markup Rules + +8.9 Hyperlinks and email addresses with descriptions +==================================================== + +A hyperlink can reference a URL, or another page within a Muse project. +In addition, descriptive text can be specified, which should be +displayed rather than the link text in output styles that supports link +descriptions. The syntax is as follows. + + [[link target][link description]] + [[link target without description]] + + Thus, the current maintainer's homepage for Muse can be found +`[[http://mwolson.org/projects/EmacsMuse.html][here]]', or at +`[[http://mwolson.org/projects/EmacsMuse.html]]'. + + +File: muse.info, Node: Implicit Links, Next: Images, Prev: Explicit Links, Up: Markup Rules + +8.10 Bare URLs, WikiNames, and InterWiki links +============================================== + +A URL or email address encountered in the input text is published as a +hyperlink. These kind of links are called "implicit links" because +they are not separated from the rest of the Muse document in any way. + + Some characters in URLs will prevent Muse from recognizing them as +implicit links. If you want to link to a URL containing spaces or any of +the characters "][,"'`()<>^", you will have to make the link explicit. +The punctuation characters ".,;:" are also not recognized as part of a +URL when they appear at its end. For information on how to make an +explicit link, see *note Hyperlinks and email addresses with +descriptions: Explicit Links. + + If the `muse-wiki' module is loaded, another form of implicit link +will be made available. WikiNames, which are typed in CamelCase, are +highlighted and published as links, provided that the file they refer +to exists. + + Customization of WikiName recognition may be accomplished by editing +the `muse-wiki-wikiword-regexp' option and subsequently running +`(muse-configure-highlighting 'muse-colors-markupmuse-colors-markup)'. +If you use the Customize interface, the latter will be done +automatically. + + The `muse-wiki' module also allows for InterWiki links. These are +similar to WikiWords, but they specify both the project and page of a +file. The names of your project entries in `muse-project-alist' will +be used as InterWiki names by default. Several examples follow. + + Blog::DocumentingMuse + Projects#EmacsMuse + Website + + In the first case, the interwiki delimiter is `::', `Blog' is the +project name, and `DocumentingMuse' is the page name. In the second +example, `#' is the interwiki delimiter. If the name of a project +occurs by itself in text, like the third case, it will be colorized and +published as a link to the default page of the given project. + + Customization of interwiki links may be accomplished by editing the +`muse-wiki-interwiki-alist' option. + + It is also possible to link to an anchor in an interwiki document. +This is called a "three-part link". Examples of this follow. + + Blog::DocumentingMuse#anchor1 + Projects#EmacsMuse#anchor2 + + +File: muse.info, Node: Images, Next: Horizontal Rules and Anchors, Prev: Implicit Links, Up: Markup Rules + +8.11 Publishing and displaying images +===================================== + +Image links +----------- + +Links to images may be used in either the target or the description, or +both. Thus, the following code will publish as a clickable image that +points to `http://mwolson.org/'. + + [[http://mwolson.org/][/static/logos/site-logo.png]] + + Normally, images in the link part will be inlined. + + If you want these images to be published as links instead, place the +text "URL:" immediately in front of the link text. An example follows. + + [[URL:http://mwolson.org/static/logos/site-logo.png]] + +Displaying images in Muse mode +------------------------------ + +If a link to a locally-available image is encountered in the link +description, Muse mode will attempt to display it if your version of +Emacs permits this. + + This behavior may be toggled with `C-c C-i', or disabled permanently +by setting the `muse-colors-inline-images' option to `nil'. + + The method for finding images may be altered by customizing the +`muse-colors-inline-image-method' option. One useful value for this +option is `muse-colors-use-publishing-directory', which tells Muse mode +to look in the directory where the current file will be published. The +default is to look in the current directory. Relative paths like +`../pics/' should work for either setting. + + Eventually, it is hoped that Muse will be able to copy images from +the a "source" directory to a publishing directory by customizing +`muse-project-alist', but this has not been implemented yet. + +Publishing simple images +------------------------ + +The following example will display correctly and publish correctly if a +PNG file called `TestLogo.png' exists in the `../pics/' directory. If +text is on the same line as the picture, it will remain so in the +output. + + [[../myimage.png]] + +Publishing images with captions +------------------------------- + +If you want to add a caption to an image, use the following syntax. +This will center the image (if the output format supports it) and add a +centered caption below the picture. Formats that do not support +centering the image will instead leave it against the left margin. + + [[../pics/mycat.png][My cat Dexter]] + + Images with captions may only occur in their own paragraphs, with no +text on the same line. Otherwise, the published output will not be +syntactically correct. + + +File: muse.info, Node: Horizontal Rules and Anchors, Next: Embedded Lisp, Prev: Images, Up: Markup Rules + +8.12 Inserting a horizontal line or anchor +========================================== + +Horizontal Rules +---------------- + +Four or more dashes indicate a horizontal rule. Be sure to put blank +lines around it, or it will be considered part of the proceeding or +following paragraph! + +Anchors +------- + +If you begin a line with "#anchor" - where "anchor" can be any word +that doesn't contain whitespace - it defines an anchor at that point +into the document. This point can be referenced using "page#anchor" as +the target in a Muse link. + + +File: muse.info, Node: Embedded Lisp, Next: Citations, Prev: Horizontal Rules and Anchors, Up: Markup Rules + +8.13 Evaluating Emacs Lisp code in documents for extensibility +============================================================== + +Arbitrary kinds of markup can be achieved using the tag. With +the tag, you may generate whatever output text you wish. The +inserted output will get marked up if the tag appears within the +main text of the document. + + (concat "This form gets " "inserted") + + Note that you should not use the `insert' command within a set of + tags, since the return value from the tags will be +automatically inserted into the document. + + It is also possible to treat the output as if it were surrounded by +the , , or tags, by specifying "example", "src", +or "verse" as the `markup' attribute of the tag. + + + (concat "Insert" " me") + + + Other languages also have tags that cause source code to be +evaluated. *Note Tag Summary::, for details. + + +File: muse.info, Node: Citations, Next: Comments, Prev: Embedded Lisp, Up: Markup Rules + +8.14 Support for citing other resources +======================================= + +Example +------- + +Here is an example of what citations look like in a Muse document. + + #bibsource REFDB + + * Title + ** Subtitle + + Some text before Miller1999 and after the citation. + + This is an author-only citation Miller1999. + + And this is a year-only citation Miller1999. + + Finally, this is a multi-head citation + Miller1999,Andrews2005. + +Overview +-------- + +The `#bibsource' directive defines the source of the bibliographies. +The following sources are possible. + + * DocBook + RefDB: the string "REFDB" + + * LaTeX + bibtex: the name of an appropriate bibtex file + + * LaTeX + RefDB: if the input file is called "foo.muse", then set + this to "foo.bib" + + Citations are encoded as elements which enclose the citation +keys as they are defined in the bibliography file or database. In +multi-head citations, the citation keys have to be separated by colons +or semicolons. The `latex' and `docbook' styles translate these to the +proper separator automatically. + + The elements take an optional "type" attribute that defines +how the citation is rendered. If the attribute is missing, you'll get +a regular citation according to the bibliography style, e.g." (Miller +et al., 1999)". If the attribute is set to "author", only the name of +the author(s) will be rendered. Accordingly, "year" will cause the +year to be printed. This is useful to create citations like this: + + Miller et al. had already shown in a previous publication (1999) that + this is not going to work. + + Remember that refdb-mode (the Emacs interface to RefDB) can retrieve +references by simply marking the citation key and running the +`refdb-getref-by-field-on-region' command. Later versions of +`refdb-mode' will also allow to insert references as Muse citations +(which is already implemented for DocBook, TEI, and LaTeX documents). + + You may have noticed that there is no element to indicate the +position of the bibliography. The latter is always created at a valid +position close to the end of the document. The functions +`muse-docbook-bibliography' and `muse-latex-bibliography' are called in +the header or footer to generate this content, so it is possible to +change the exact position. + + +File: muse.info, Node: Comments, Next: Tag Summary, Prev: Citations, Up: Markup Rules + +8.15 Lines to omit from published output +======================================== + +Use the following syntax to indicate a comment. Comments will not be +published. + + ; Comment text goes here. + + That is, only a semi-colon at the beginning of a line, followed by a +literal space, will cause that line to be treated as a comment. + + You can alternatively surround the region with the tag. + + If you wish the comment to be published, but just commented out using +the comment syntax of the output format, then set +`muse-publish-comments-p' to non-nil. + + +File: muse.info, Node: Tag Summary, Prev: Comments, Up: Markup Rules + +8.16 Tags that Muse recognizes +============================== + +Muse has several built-in tags that may prove useful during publishing. +*Note muse-publish-markup-tags::, to see how to customize the tags that +Muse uses, as well as make your own tags. + + Only a small subset of these tags are available in header and footer +text. The `muse-publish-markup-header-footer-tags' option lists the +tags that are allowed in headers and footers. + +Syntax +------ + +If a tag takes arguments, it will look like this, where "tagname" is +the name of the tag. + + + + If you want the tag to look like it came straight from an XHTML +document, you can alternatively do the following. + + + + If a tag surrounds some text, it will look like this. + + Some text + + If a tag surrounds a large region, it will look like this. + + + Some text. + Some more text. + + +Tag listing +----------- + +This is the complete list of tags that Muse accepts, including those +that were mentioned in previous sections. + +`
    ' + Insert a line break. + + Muse will automatically detect paragraphs when publishing by means + of blank lines, so this tag is usually unnecessary. + +`' + Insert a citation to another source. + + This takes the argument `type', which indicates the type of + citation. The valid types are "author" and "year". If this + argument is omitted, include both author and year in the citation. + + The bibliography to use for the citation may be specified by the + `#bibsource' directive. + + *Note Citations::, for additional information. + +`' + If publishing to HTML, surround the given text with a tag. + It takes one argument called "name" that specifies the "class" + attribute of the tag. + + If publishing to a different format, do nothing extra to the text. + +`' + Treat the text surrounded by the tag as if they were enclosed in + equal signs, that is, make it monospace. + +`' + Run a command on the region, replacing the region with the result + of the command. The command is specified with the "interp" + argument. If no value for "interp" is given, pass the entire + region to the shell. + + The "markup" argument controls how this section is marked up. + + If it is omitted, publish the region with the normal Muse rules. + + If "nil", do not mark up the region at all, but prevent Muse from + further interpreting it. + + If "example", treat the region as if it was surrounded by the + tag. + + If "src", treat the included text as if it was surrounded by the + tag. You should also specify the "lang" attribute if doing + this. + + If "verse", treat the region as if it was surrounded by the + tag, to preserve newlines. + + Otherwise, it should be the name of a function to call, with the + buffer narrowed to the region. + +`' + Treat the entire region as a comment. If the option + MUSE-PUBLISH-COMMENTS-P is nil, delete the region, otherwise + publish it using the comment syntax of the current publishing + style. + +`' + Publish a Table of Contents. This will either be inserted + in-place or at the beginning of the document, depending on your + publishing style. It does not have a delimiting tag. + + By default, only 2 levels of headings will be included in the + generated Table of Contents. To change this globally, customize + the MUSE-PUBLISH-CONTENTS-DEPTH option. To change this only for + the current tag, use the "depth" argument. + +`
    ' + Insert a
    tag into HTML documents, and do not insert anything + special for other non-HTML publishing formats. + + If the "style" argument is provided, include it with the published +
    tag. Likewise for the "id" argument. + +`' + Publish the region in monospace, preserving the newlines in the + region. This is useful for snippets of code. + +`' + Insert the given file at the current location during publishing. + The basic use of this tag is as follows, replacing "included_file" + with the name of the file that you want to include. + + + + The "markup" argument controls how this section is marked up. + + If it is omitted, publish the included text with the normal Muse + rules. + + If "nil", do not mark up the included text at all. + + If "example", treat the included text as if it was surrounded by + the tag. + + If "src", treat the included text as if it was surrounded by the + tag. You should also specify the "lang" attribute if doing + this. + + If "verse", treat the included text as if it was surrounded by the + tag, to preserve newlines. + + Otherwise, it should be the name of a function to call after + inserting the file with the buffer narrowed to the section + inserted. + +`' + Evaluate the Emacs Lisp expressions between the initial and ending + tags. The result is then inserted into the document, so you do + not need to explicitly call `insert'. All text properties are + removed from the resulting text. + + This tag takes the "markup" argument. See the description of + for details. + +`' + Make sure that the text enclosed by this tag is published without + escaping it in any way. This is useful for inserting markup + directly into the published document, when Muse does not provide + the desired functionality. + +`' + Mark up the text between the initial and ending tags. The markup + command to use may be specified by the "function" argument. The + standard Muse markup routines are used by default if no "function" + argument is provided. + + This is useful for marking up regions in headers and footers. One + example that comes to mind is generating a published index of all + of the files in the current project by doing the following. + + (muse-index-as-string t t) + +`' + Run the `perl' language interpreter on the region, replacing the + region with the result of the command. + + This tag takes the "markup" argument. See the description of + for details. + +`' + Run the `python' language interpreter on the region, replacing the + region with the result of the command. + + This tag takes the "markup" argument. See the description of + for details. + +`' + Publish the region as a blockquote. This will either be inserted + in-place or at the beginning of the document, depending on your + publishing style. It does not have a delimiting tag. + +`' + Run the `ruby' language interpreter on the region, replacing the + region with the result of the command. + + This tag takes the "markup" argument. See the description of + for details. + +`' + Publish the region using htmlize. The language to use may be + specified by the "lang" attribute. + + Muse will look for a function named LANG-mode, where LANG is the + value of the "lang" attribute. + + This tag requires htmlize 1.34 or later in order to work. If this + is not satisfied, or the current publishing style is not + HTML-based, Muse will publish the region like an tag. + +`' + This is used when you want to prevent Muse from trying to + interpret some markup. Surround the markup in and + , and it will not be interpreted. + + This tag was used often in previous versions of Muse because they + did not support whole-document escaping of specials. Now, it will + only be needed for other tags, and perhaps footnotes as well. + +`' + Preserve the newlines in the region. In formats like HTML, + newlines are removed by default, hence the need for this tag. In + other publishing styles, this tag may cause the text to be + indented slightly in a way that looks nice for poetry and prose. + + + +File: muse.info, Node: Publishing Styles, Next: Extending Muse, Prev: Markup Rules, Up: Top + +9 Publishing Various Types of Documents +*************************************** + +One of the principle features of Muse is the ability to publish a simple +input text to a variety of different output styles. Muse also makes it +easy to create new styles, or derive from an existing style. + +* Menu: + +* Blosxom:: Integrating Muse and pyblosxom.cgi. +* Book:: Publishing entries into a compilation. +* ConTeXt:: Publishing ConTeXt documents. +* DocBook:: Publishing in DocBook XML form. +* HTML:: Publishing in HTML or XHTML form. +* Ikiwiki:: Integrating with ikiwiki. +* Journal:: Keeping a journal or blog. +* LaTeX:: Publishing LaTeX documents. +* Poem:: Publish a poem to LaTeX or PDF. +* Texinfo:: Publish entries to Texinfo format or PDF. +* XML:: Publish entries to XML. + + +File: muse.info, Node: Blosxom, Next: Book, Prev: Publishing Styles, Up: Publishing Styles + +9.1 Integrating Muse and pyblosxom.cgi +====================================== + +The Blosxom publishing style publishes a tree of categorised files to a +mirrored tree of stories to be served by blosxom.cgi or pyblosxom.cgi. +In other words, each blog entry corresponds with one file. + +* Menu: + +* Blosxom Requirements:: Other tools needed for the Blosxom style. +* Blosxom Entries:: Format of a Blosxom entry and automation. +* Blosxom Options:: Blosxom styles and options provided. + + +File: muse.info, Node: Blosxom Requirements, Next: Blosxom Entries, Prev: Blosxom, Up: Blosxom + +9.1.1 Other tools needed for the Blosxom style +---------------------------------------------- + +You will need to have `pyblosxom.cgi' or `blosxom.cgi' installed on a +machine that you have upload access to. + + The major difficulty in both of these programs is specifying the +date of the entries. Both programs rely on the file modification time +rather than any data contained in the entries themselves. A plugin is +needed in order for these programs to be able to get the correct date. + +PyBlosxom +--------- + +There are two different ways of accomplishing this in pyblosxom. The +first way involves gathering the timestamps (as specified by the +`#date' directive) into one file and then sending that file along with +published entries to the webserver. + + The second will read each file at render time and parse the +`#postdate' directive. Muse will translate the `#date' directive into +`#postdate' at publish time, so you don't have to do any extra work. + +Placing timestamps in one file +.............................. + +The following additional components are required in order to make the +date of blog entries display as something sensible. + + 1. A script to gather date directives from the entire blog tree into a + single file. The file must associate a blog entry with a date. + + 2. A plugin for (py)blosxom that reads this file. + + These 2 things are provided for `pyblosxom.cgi' in the +`contrib/pyblosxom' subdirectory. `getstamps.py' provides the former +service, while `hardcodedates.py' provides the latter service. + + Here is a sample listing from my `timestamps' file, which maps each +file to a date. This can really be in any format, as long as your +date-gathering script and your plugin can both understand it. + + 2005-04-01-14-16 personal/paper_cranes + 2005-03-21 personal/spring_break_over + 2004-10-24 personal/finished_free_culture + + The script `contrib/pyblosxom/make-blog' demonstrates how to call +`getstamps.py'. Note that you will need to set the current directory +to where your Muse files are, execute `getstamps.py', and then move the +generated timestamps file to your publishing directory. + +Getting timestamp from entry while rendering +............................................ + +Alternately, the pyblosxom metadate plugin may be used. On the plus +side, there is no need to run a script to gather the date. On the +downside, each entry is read twice rather than once when the page is +rendered. Set the value of `muse-blosxom-use-metadate' to non-nil to +enable adding a `#postdate' directive to all published files. You can +do this by: + + M-x customize-variable RET muse-blosxom-use-metadate RET + + With the metadate plugin installed in pyblosxom, the date set in this +directive will be used instead of the file's modification time. The +plugin is included with Muse at `contrib/pyblosxom/metadate.py'. + +Blosxom +------- + +It is also possible to use Blosxom, which is written in Perl, to serve +blog entries that were published with Muse. The steps are as follows. + + 1. Download and install blosxom from + `http://blosxom.sourceforge.net/'. + + 2. Install the metadate plugin. It is available in + `contrib/blosxom/metadate_0_0_3'. + + 3. Every time you make a new blog entry, change to the blosxom data + directory and execute the `contrib/blosxom/getstamps.pl' script. + This script has only recently been made, and may still have some + bugs, so use with caution. + + + +File: muse.info, Node: Blosxom Entries, Next: Blosxom Options, Prev: Blosxom Requirements, Up: Blosxom + +9.1.2 Format of a Blosxom entry and automation +---------------------------------------------- + +Each Blosxom file must include `#date yyyy-mm-dd', or optionally the +longer `#date yyyy-mm-dd-hh-mm', a title (using the `#title' +directive), plus whatever normal content is desired. + + The date directive is not used directly by `pyblosxom.cgi' or this +program. You need to have the two additional items from the former +section to make use of this feature. + + There is a function called `muse-blosxom-new-entry' that will +automate the process of making a new blog entry. To make use of it, do +the following. + + * Customize `muse-blosxom-base-directory' to the location that your + blog entries are stored. + + * Assign the `muse-blosxom-new-entry' function to a key sequence. I + use the following code to assign this function to `C-c p l''. + + (global-set-key "\C-cpl" 'muse-blosxom-new-entry) + + * You should create your directory structure ahead of time under + your base directory. These directories, which correspond with + category names, may be nested. + + * When you enter this key sequence, you will be prompted for the + category of your entry and its title. Upon entering this + information, a new file will be created that corresponds with the + title, but in lowercase letters and having special characters + converted to underscores. The title and date directives will be + inserted automatically. + + +File: muse.info, Node: Blosxom Options, Prev: Blosxom Entries, Up: Blosxom + +9.1.3 Blosxom styles and options provided +----------------------------------------- + +The following styles and options are available in the Blosxom publishing +style. + +Styles provided +--------------- + +`blosxom-html' + Publish Blosxom entries in HTML form. + +`blosxom-xhtml' + Publish Blosxom entries in XHTML form. + + +Options provided +---------------- + +`muse-blosxom-extension' + Default file extension for publishing Blosxom files. + +`muse-blosxom-header' + Header used for publishing Blosxom files. + + This may be text or a filename. + +`muse-blosxom-footer' + Footer used for publishing Blosxom files. + + This may be text or a filename. + +`muse-blosxom-base-directory' + Base directory of blog entries, used by `muse-blosxom-new-entry'. + + This is the top-level directory where your blog entries may be + found locally. + + + +File: muse.info, Node: Book, Next: ConTeXt, Prev: Blosxom, Up: Publishing Styles + +9.2 Publishing entries into a compilation +========================================= + +This publishing style is used to output "books" in LaTeX or PDF format. + + Each page will become a separate chapter in the book, unless the +style keyword `:nochapters' is used, in which case they are all run +together as if one giant chapter. + + One way of publishing a book is to make a project for it, add the +project to `muse-project-alist', and use the `book-pdf' style with a +very specific `:include' value to specify some page whose contents will +be checked for the values of `#title' and `#date', and whose name will +be used in the output file. Then to publish the book, visit the +aforementioned page and use `C-c C-t' or `C-c C-p' to trigger the +publishing process. An example `muse-project-alist' for this method +follows. + + (setq muse-project-alist + '(("MyNotes" (:nochapters t ; do automatically add chapters + :book-chapter "Computer Science" + "~/Notes/cs" + :book-chapter "Mathematics" + "~/Notes/math" + :book-chapter "Emacs" + "~/Notes/emacs" + :book-end t ; the rest will not be placed in the book + "~/Notes" ; so we can find the notes-anthology page + "~/Notes/private" + :force-publish ("index") + :default "index") + (:base "book-pdf" + :include "/notes-anthology[^/]*$" + :path "~/public_html/notes") + ;; other publishing styles for each directory go here, + ;; if desired + ))) + + In this example, there would be a file called +`~/Notes/notes-anthology.muse', which would contain just the following. +The resulting book would be published to +`~/public_html/notes/notes-anthology.pdf'. + + #title My Technology Ramblings + + Another way is to call the `muse-book-publish-project' function +manually, with a custom project entry. An example of this may be found +in John Wiegley's configuration file at `examples/johnw/muse-init.el', +in the `muse-publish-my-books' function. + +Styles provided +--------------- + +`book-latex' + Publish a book in LaTeX form. The header and footer are different + than the normal LaTeX publishing mode. + +`book-pdf' + Publish a book in PDF form. The header and footer are different + than the normal PDF publishing mode. + + +Options provided +---------------- + +`muse-book-before-publish-hook' + A hook run in the book buffer before it is marked up. + +`muse-book-after-publish-hook' + A hook run in the book buffer after it is marked up. + +`muse-book-latex-header' + Header used for publishing books to LaTeX. + + This may be text or a filename. + +`muse-book-latex-footer' + Footer used for publishing books to LaTeX. + + This may be text or a filename. + + + +File: muse.info, Node: ConTeXt, Next: DocBook, Prev: Book, Up: Publishing Styles + +9.3 Publishing ConTeXt documents +================================ + +This publishing style is capable of producing ConTeXt or PDF documents. + + If you wish to publish PDF documents based on ConTeXt, you will need +to have it installed. For Debian and Ubuntu, this can be accomplished +by installing the "texlive" package. + +Styles provided +--------------- + +`context' + Publish a ConTeXt document. + +`context-pdf' + Publish a PDF document, using an external ConTeXt document + conversion tool. + +`context-slides' + Produce slides from a ConTeXt document. + + Here is an example of a slide. + + * First Slide + + [[Some-sort-of-cute-image.png]] + + ** A subheading + + - A bullet point. + - Another bullet point. + + * Second Slide + + ... and so on + +`context-slides-pdf' + Publish a PDF document of ConTeXt slides. + + +Options provided +---------------- + +`muse-context-extension' + Default file extension for publishing ConTeXt files. + +`muse-context-pdf-extension' + Default file extension for publishing ConTeXt files to PDF. + +`muse-context-pdf-program' + The program that is called to generate PDF content from ConTeXt + content. + +`muse-context-pdf-cruft' + Extensions of files to remove after generating PDF output + successfully. + +`muse-context-header' + Header used for publishing ConTeXt files. + + This may be text or a filename. + +`muse-context-footer' + Footer used for publishing ConTeXt files. + + This may be text or a filename. + +`muse-context-markup-regexps' + List of markup regexps for identifying regions in a Muse page. + + For more on the structure of this list, *Note + muse-publish-markup-regexps::. + +`muse-context-markup-functions' + An alist of style types to custom functions for that kind of text. + + For more on the structure of this list, *Note + muse-publish-markup-functions::. + +`muse-context-markup-strings' + Strings used for marking up text. + + These cover the most basic kinds of markup, the handling of which + differs little between the various styles. + +`muse-context-slides-header' + Header for publishing a presentation (slides) using ConTeXt. + + Any of the predefined modules, which are available in the + tex/context/base directory, can be used by writing a "module" + directive at the top of the Muse file; if no such directive is + provided, module pre-01 is used. Alternatively, you can use your + own style ("mystyle", in this example) by replacing "\usemodule[]" + with "\input mystyle". + + This may be text or a filename. + +`muse-context-slides-markup-strings' + Strings used for marking up text in ConTeXt slides. + +`muse-context-markup-specials-document' + A table of characters which must be represented specially. These + are applied to the entire document, sans already-escaped regions. + +`muse-context-markup-specials-example' + A table of characters which must be represented specially. These + are applied to example> regions. + + With the default interpretation of regions, no specials + need to be escaped. + +`muse-context-markup-specials-literal' + A table of characters which must be represented specially. This + applies to =monospaced text= and regions. + +`muse-context-markup-specials-url' + A table of characters which must be represented specially. These + are applied to URLs. + +`muse-context-markup-specials-image' + A table of characters which must be represented specially. These + are applied to image filenames. + +`muse-context-permit-contents-tag' + If nil, ignore tags. Otherwise, insert table of + contents. + + Most of the time, it is best to have a table of contents on the + first page, with a new page immediately following. To make this + work with documents published in both HTML and ConTeXt, we need to + ignore the tag. + + If you don't agree with this, then set this option to non-nil, and + it will do what you expect. + + + +File: muse.info, Node: DocBook, Next: HTML, Prev: ConTeXt, Up: Publishing Styles + +9.4 Publishing in DocBook XML form +================================== + +This publishing style is used to generate DocBook XML files. + +Styles provided +--------------- + +`docbook' + Publish a file in Docbook form. + + +Options provided +---------------- + +This publishing style uses the same options for markup up special +characters as the "xml" publishing style. *Note XML::, for details. + +`muse-docbook-extension' + Default file extension for publishing DocBook XML files. + +`muse-docbook-header' + Header used for publishing DocBook XML files. + + This may be text or a filename. + +`muse-docbook-footer' + Footer used for publishing DocBook XML files. + + This may be text or a filename. + +`muse-docbook-markup-regexps' + List of markup rules for publishing a Muse page to DocBook XML. + +`muse-docbook-markup-functions' + An alist of style types to custom functions for that kind of text. + +`muse-docbook-markup-strings' + Strings used for marking up text. + + These cover the most basic kinds of markup, the handling of which + differs little between the various styles. + +`muse-docbook-encoding-default' + The default Emacs buffer encoding to use in published files. This + will be used if no special characters are found. + +`muse-docbook-charset-default' + The default DocBook XML charset to use if no translation is found + in `muse-xml-encoding-map'. + + + +File: muse.info, Node: HTML, Next: Ikiwiki, Prev: DocBook, Up: Publishing Styles + +9.5 Publishing in HTML or XHTML form +==================================== + +This publishing style is capable of producing HTML or XHTML documents. + +Styles provided +--------------- + +`html' + Supports publishing to HTML 4.0 and HTML 4.01, Strict or + Transitional. + +`xhtml' + Supports publishing to XHTML 1.0 and XHTML 1.1, Strict or + Transitional. + + +Options provided +---------------- + +If an HTML option does not have a corresponding XHTML option, it will +be used for both of these publishing styles. + + These publishing styles use the same options for markup up special +characters as the "xml" publishing style. *Note XML::, for details. + +`muse-html-extension' + Default file extension for publishing HTML files. + +`muse-xhtml-extension' + Default file extension for publishing XHTML files. + +`muse-html-style-sheet' + Store your stylesheet definitions here. + + This is used in `muse-html-header'. You can put raw CSS in here or + a tag to an external stylesheet. This text may contain + markup tags. + + If you are publishing to XHTML, then customize the + `muse-xhtml-style-sheet' option instead. + +`muse-xhtml-style-sheet' + Store your stylesheet definitions here. + + This is used in `muse-xhtml-header'. You can put raw CSS in here + or a tag to an external stylesheet. This text may contain + markup tags. + +`muse-html-header' + Header used for publishing HTML files. + + This may be text or a filename. + +`muse-html-footer' + Footer used for publishing HTML files. + + This may be text or a filename. + +`muse-xhtml-header' + Header used for publishing XHTML files. + + This may be text or a filename. + +`muse-xhtml-footer' + Footer used for publishing XHTML files. + + This may be text or a filename. + +`muse-html-anchor-on-word' + When true, anchors surround the closest word. + + This allows you to select them in a browser (i.e. for pasting), + but has the side-effect of marking up headers in multiple colors + if your header style is different from your link style. + +`muse-html-table-attributes' + The attribute to be used with HTML tags. + + If you want to make more-complicated tables in HTML, surround the + HTML with the literal tag, so that it does not get escaped. + +`muse-html-markup-regexps' + List of markup rules for publishing a Muse page to HTML. + +`muse-html-markup-functions' + An alist of style types to custom functions for that kind of text. + +`muse-html-markup-strings' + Strings used for marking up text as HTML. + + These cover the most basic kinds of markup, the handling of which + differs little between the various styles. + +`muse-xhtml-markup-strings' + Strings used for marking up text as XHTML. + + These cover the most basic kinds of markup, the handling of which + differs little between the various styles. + +`muse-html-markup-tags' + A list of tag specifications, for specially marking up HTML. + *Note muse-publish-markup-tags::, for more information. + +`muse-html-meta-http-equiv' + The http-equiv attribute used for the HTML tag. + +`muse-html-meta-content-type' + The content type used for the HTML tag. + + If you are striving for XHTML 1.1 compliance, you may want to + change this to "application/xhtml+xml". + +`muse-html-meta-content-encoding' + The charset to append to the HTML tag. + + If set to the symbol 'detect, use `muse-xml-encoding-map' to try + and determine the HTML charset from emacs's coding. If set to a + string, this string will be used to force a particular charset. + +`muse-html-charset-default' + The default HTML meta charset to use if no translation is found in + `muse-xml-encoding-map'. + +`muse-html-encoding-default' + The default Emacs buffer encoding to use in published files. This + will be used if no special characters are found. + + + +File: muse.info, Node: Ikiwiki, Next: Journal, Prev: HTML, Up: Publishing Styles + +9.6 Integrating with ikiwiki +============================ + +Note: Support for Ikiwiki is not yet complete. Use at your own risk. + + Ikiwiki is a wiki compiler (`http://ikiwiki.info/'). Emacs Muse can +(not yet) be used as a source format for Ikiwiki pages with the plugin +`IkiWiki::Plugin::muse'. + + The `lisp/muse-ikiwiki.el' file provides publishing functions and +styles for Ikiwiki. The plugin for Ikiwiki to recognize Muse files is +provided by the `contrib/ikiwiki/IkiWiki/Plugin/muse.pm' file. Two +sample init files are available in the `examples/ikiwiki' directory. +Configure your `ikiwiki.setup' file so that the `muse_init' variable +has the location of your Muse init file. + + If you are using CGI, The directory `contrib/ikiwiki/IkiWiki' must +be copied to the same directory as the CGI script that Ikiwiki +generates. When publishing your wiki, the PERL5LIB environment +variable must contain the path to the `contrib/ikiwiki/IkiWiki' +directory. + +Styles provided +--------------- + +`ikiwiki' + Supports publishing XHTML output that Ikiwiki can understand. + + +Options provided +---------------- + +`muse-ikiwiki-header' + Header used for publishing Ikiwiki output files. + + This may be text or a filename. + +`muse-ikiwiki-footer' + Footer used for publishing Ikiwiki output files. + + This may be text or a filename. + + +Other relevant options +---------------------- + +`muse-colors-evaluate-lisp-tags' + Specify whether to evaluate the contents of tags at display + time. If nil, don't evaluate them. If non-nil, evaluate them. + + The actual contents of the buffer are not changed, only the + displayed text. + +`muse-html-src-allowed-modes' + Modes that we allow the tag to colorize. If `t', permit the + tag to colorize any mode. + + If a list of mode names, such as `'("html" "latex")', and the lang + argument to is not in the list, then use fundamental mode + instead. + +`muse-publish-enable-dangerous-tags' + If non-nil, publish tags like and that can call + external programs or expose sensitive information. Otherwise, + ignore tags like this. + + This is useful to set to `nil' when the file to publish is coming + from an untrusted source. + + + +File: muse.info, Node: Journal, Next: LaTeX, Prev: Ikiwiki, Up: Publishing Styles + +9.7 Keeping a journal or blog +============================= + +The module facilitates the keeping and publication of a journal. When +publishing to HTML, it assumes the form of a web log, or blog. + + The input format for each entry is as follows. + + * 20040317: Title of entry + + text for the entry. + + + "You know who you are. It comes down to a simple gut check: You + either love what you do or you don't. Period." -- P. Bronson + + + The "qotd", or Quote of the Day, is entirely optional. When +generated to HTML, this entry is rendered as the following. + +
    +
    +

    Quote of the Day:

    +

    "You know who you are. It comes down to a simple gut + check: You either love what you do or you don't. Period." + -- P. Bronson

    +
    +
    +
    + +
    +

    Title of entry

    +
    +
    +
    +

    Text for the entry.

    +
    +
    +
    + + The plurality of "div" tags makes it possible to display the entries +in any form you wish, using a CSS style. + + Also, an .RDF file can be generated from your journal by publishing +it with the "rdf" style. It uses the first two sentences of the first +paragraph of each entry as its "description", and auto-generates tags +for linking to the various entries. + +muse-project-alist considerations +--------------------------------- + +If you wish to publish an RDF or RSS feed, it is important to include +the `:base-url' attribute in your `muse-project-alist' entry for your +Journal projects. An example follows. + + (setq muse-project-alist + '(("Journal" ("~/Journal/" + :default "journal") + (:base "journal-rss" + :base-url "http://example.org/journal/" + :path "~/public_html/journal")))) + +Styles provided +--------------- + +`journal-html' + Publish journal entries as an HTML document. + +`journal-xhtml' + Publish journal entries as an XHTML document. + +`journal-latex' + Publish journal entries as a LaTeX document. + +`journal-pdf' + Publish journal entries as a PDF document. + +`journal-book-latex' + Publish journal entries as a LaTeX book. + +`journal-book-pdf' + Publish journal entries as a PDF book. + +`journal-rdf' + Publish journal entries as an RDF file (RSS 1.0). + +`journal-rss' + Publish journal entries as an RSS file (RSS 2.0). + +`journal-rss-entry' + Used internally by `journal-rss' and `journal-rdf' for publishing + individual entries. + + +Options provided +---------------- + +`muse-journal-heading-regexp' + A regexp that matches a journal heading. + + Paren group 1 is the ISO date, group 2 is the optional category, + and group 3 is the optional heading for the entry. + +`muse-journal-date-format' + Date format to use for journal entries. + +`muse-journal-html-heading-regexp' + A regexp that matches a journal heading from an HTML document. + + Paren group 1 is the ISO date, group 2 is the optional category, + and group 3 is the optional heading for the entry. + +`muse-journal-html-entry-template' + Template used to publish individual journal entries as HTML. + + This may be text or a filename. + +`muse-journal-latex-section' + Template used to publish a LaTeX section. + +`muse-journal-latex-subsection' + Template used to publish a LaTeX subsection. + +`muse-journal-markup-tags' + A list of tag specifications, for specially marking up Journal + entries. + + *Note muse-publish-markup-tags::, for more information. + + This is used by `journal-latex' and its related styles, as well as + the `journal-rss-entry' style, which both `journal-rdf' and + `journal-rss' use. + +`muse-journal-rdf-extension' + Default file extension for publishing RDF (RSS 1.0) files. + +`muse-journal-rdf-base-url' + The base URL of the website referenced by the RDF file. + +`muse-journal-rdf-header' + Header used for publishing RDF (RSS 1.0) files. + + This may be text or a filename. + +`muse-journal-rdf-footer' + Footer used for publishing RDF (RSS 1.0) files. + + This may be text or a filename. + +`muse-journal-rdf-date-format' + Date format to use for RDF entries. + +`muse-journal-rdf-entry-template' + Template used to publish individual journal entries as RDF. + + This may be text or a filename. + +`muse-journal-rdf-summarize-entries' + If non-nil, include only summaries in the RDF file, not the full + data. + + The default is nil, because this annoys some subscribers. + +`muse-journal-rss-heading-regexp' + A regexp that matches a journal heading from an HTML document. + + Paren group 1 is the ISO date, group 2 is the optional category, + and group 3 is the optional heading for the entry. + +`muse-journal-rss-extension' + Default file extension for publishing RSS 2.0 files. + +`muse-journal-rss-base-url' + The base URL of the website referenced by the RSS file. + +`muse-journal-rss-header' + Header used for publishing RSS 2.0 files. + + This may be text or a filename. + +`muse-journal-rss-footer' + Footer used for publishing RSS 2.0 files. + + This may be text or a filename. + +`muse-journal-rss-date-format' + Date format to use for RSS 2.0 entries. + +`muse-journal-rss-entry-template' + Template used to publish individual journal entries as RSS 2.0. + + This may be text or a filename. + +`muse-journal-rss-enclosure-types-alist' + File types that are accepted as RSS enclosures. + + This is an alist that maps file extension to content type. + + Useful for podcasting. + +`muse-journal-rss-summarize-entries' + If non-nil, include only summaries in the RSS file, not the full + data. + + The default is nil, because this annoys some subscribers. + +`muse-journal-rss-markup-regexps' + List of markup rules for publishing a Muse journal page to RSS. + + For more information on the structure of this list, *Note + muse-publish-markup-regexps::. + +`muse-journal-rss-markup-functions' + An alist of style types to custom functions for that kind of text. + + For more on the structure of this list, *Note + muse-publish-markup-functions::. + + + +File: muse.info, Node: LaTeX, Next: Poem, Prev: Journal, Up: Publishing Styles + +9.8 Publishing LaTeX documents +============================== + +This publishing style is capable of producing LaTeX or PDF documents. + + If you wish to publish PDF documents, you will need to have a good +LaTeX installation. For Debian and Ubuntu, this can be accomplished by +installing the "tetex-bin" and "tetex-extra" packages. TeX fonts are +also a must. + + If your LaTeX installation has the file `grffile.sty', which may be +found in the `texlive-latex-recommended' package for Debian and Ubuntu, +then consider using it by adding the following to your header file. +This allows spaces in filenames to work. + + \usepackage{grffile} + +Styles provided +--------------- + +`latex' + Publish a LaTeX document. + +`pdf' + Publish a PDF document, using an external LaTeX document conversion + tool. + +`latexcjk' + Publish a LaTeX document with CJK (Chinese) encodings. + +`pdfcjk' + Publish a PDF document with CJK (Chinese) encodings, using an + external LaTeX document conversion tool. + +`slides' + Publish a LaTeX document that uses the Beamer extension. This is + suitable for producing slides. + + Here is an example of a slide. + + + Everything between the slide tags composes this slide. + + [[Some-sort-of-cute-image.png]] + + - A bullet point. + - Another bullet point. + + +`slides-pdf' + Publish a PDF document of slides, using the Beamer extension. + +`lecture-notes' + Publish a LaTeX document that uses the Beamer extension. This is + suitable for producing lecture notes. + + This can also use the tag. + +`lecture-notes-pdf' + Publish a PDF document of lecture notes, using the Beamer + extension. + + +Options provided +---------------- + +`muse-latex-extension' + Default file extension for publishing LaTeX files. + +`muse-latex-pdf-extension' + Default file extension for publishing LaTeX files to PDF. + +`muse-latex-pdf-browser' + The program to use when browsing a published PDF file. + + This should be a format string. + +`muse-latex-pdf-program' + The program that is called to generate PDF content from LaTeX + content. + +`muse-latex-pdf-cruft' + Extensions of files to remove after generating PDF output + successfully. + +`muse-latex-header' + Header used for publishing LaTeX files. + + This may be text or a filename. + +`muse-latex-footer' + Footer used for publishing LaTeX files. + + This may be text or a filename. + +`muse-latexcjk-header' + Header used for publishing LaTeX files (CJK). + + This may be text or a filename. + +`muse-latexcjk-footer' + Footer used for publishing LaTeX files (CJK). + + This may be text or a filename. + +`muse-latex-slides-header' + Header for publishing of slides using LaTeX. + + This may be text or a filename. + + You must have the Beamer extension for LaTeX installed for this to + work. + +`muse-latex-lecture-notes-header' + Header publishing of lecture notes using LaTeX. + + This may be text or a filename. + + You must have the Beamer extension for LaTeX installed for this to + work. + +`muse-latex-markup-regexps' + List of markup regexps for identifying regions in a Muse page. + + For more on the structure of this list, *Note + muse-publish-markup-regexps::. + +`muse-latex-markup-functions' + An alist of style types to custom functions for that kind of text. + + For more on the structure of this list, *Note + muse-publish-markup-functions::. + +`muse-latex-markup-strings' + Strings used for marking up text. + + These cover the most basic kinds of markup, the handling of which + differs little between the various styles. + +`muse-latex-slides-markup-tags' + A list of tag specifications, for specially marking up LaTeX + slides. + +`muse-latexcjk-encoding-map' + An alist mapping emacs coding systems to appropriate CJK codings. + Use the base name of the coding system (ie, without the -unix). + +`muse-latexcjk-encoding-default' + The default Emacs buffer encoding to use in published files. + + This will be used if no special characters are found. + +`muse-latex-markup-specials-document' + A table of characters which must be represented specially. These + are applied to the entire document, sans already-escaped regions. + +`muse-latex-markup-specials-example' + A table of characters which must be represented specially. These + are applied to example> regions. + + With the default interpretation of regions, no specials + need to be escaped. + +`muse-latex-markup-specials-literal' + A table of characters which must be represented specially. This + applies to =monospaced text= and regions. + +`muse-latex-markup-specials-url' + A table of characters which must be represented specially. These + are applied to URLs. + +`muse-latex-markup-specials-image' + A table of characters which must be represented specially. These + are applied to image filenames. + +`muse-latex-permit-contents-tag' + If nil, ignore tags. Otherwise, insert table of + contents. + + Most of the time, it is best to have a table of contents on the + first page, with a new page immediately following. To make this + work with documents published in both HTML and LaTeX, we need to + ignore the tag. + + If you don't agree with this, then set this option to non-nil, and + it will do what you expect. + + + +File: muse.info, Node: Poem, Next: Texinfo, Prev: LaTeX, Up: Publishing Styles + +9.9 Publish a poem to LaTeX or PDF +================================== + +The `muse-poem' module makes it easy to attractively publish and +reference poems in the following format, using the "memoir" module for +LaTeX publishing. It will also markup poems for every other output +style, though none are nearly as pretty. + + Title + + + Body of poem + + + Annotations, history, notes, etc. + + Once a poem is written in this format, just publish it to PDF using +the `poem-pdf' style. To make an inlined reference to a poem that +you've written - for example, from a blog page - there is a "poem" tag +defined by this module. + + + + Let's assume the template above was called `name.of.poem.page'; then +the above tag would result in this inclusion. + + ** Title + + > Body of poem + + John Wiegley uses this module for publishing all of the poems on his +website, which are at `http://www.newartisans.com/johnw/poems.html'. + +Styles provided +--------------- + +`poem-latex' + Publish a poem in LaTeX form. + +`poem-pdf' + Publish a poem to a PDF document. + +`chapbook-latex' + Publish a book of poems in LaTeX form. + +`chapbook-pdf' + Publish a book of poems to a PDF document. + + +Options provided +---------------- + +`muse-poem-latex-header' + Header used for publishing LaTeX poems. + + This may be text or a filename. + +`muse-poem-latex-footer' + Footer used for publishing LaTeX files. + + This may be text or a filename. + +`muse-poem-markup-strings' + Strings used for marking up poems. + + These cover the most basic kinds of markup, the handling of which + differs little between the various styles. + +`muse-chapbook-latex-header' + Header used for publishing a book of poems in LaTeX form. + + This may be text or a filename. + +`muse-chapbook-latex-footer' + Footer used for publishing a book of poems in LaTeX form. + + This may be text or a filename. + +`muse-poem-chapbook-strings' + Strings used for marking up books of poems. + + These cover the most basic kinds of markup, the handling of which + differs little between the various styles. + + + +File: muse.info, Node: Texinfo, Next: XML, Prev: Poem, Up: Publishing Styles + +9.10 Publish entries to Texinfo format or PDF +============================================= + +Rules for publishing a Muse file as a Texinfo article. + +Styles provided +--------------- + +`texi' + Publish a file in Texinfo form. + +`info' + Generate an Info file from a Muse file. + +`info-pdf' + Publish a file in PDF form. + + +Options provided +---------------- + +`muse-texinfo-process-natively' + If non-nil, use the Emacs `texinfmt' module to make Info files. + +`muse-texinfo-extension' + Default file extension for publishing Texinfo files. + +`muse-texinfo-info-extension' + Default file extension for publishing Info files. + +`muse-texinfo-pdf-extension' + Default file extension for publishing PDF files. + +`muse-texinfo-header' + Text to prepend to a Muse page being published as Texinfo. + + This may be text or a filename. It may contain markup tags. + +`muse-texinfo-footer' + Text to append to a Muse page being published as Texinfo. + + This may be text or a filename. It may contain markup tags. + +`muse-texinfo-markup-regexps' + List of markup rules for publishing a Muse page to Texinfo. + + For more on the structure of this list, *Note + muse-publish-markup-regexps::. + +`muse-texinfo-markup-functions' + An alist of style types to custom functions for that kind of text. + + For more on the structure of this list, *Note + muse-publish-markup-functions::. + +`muse-texinfo-markup-strings' + Strings used for marking up text. + + These cover the most basic kinds of markup, the handling of which + differs little between the various styles. + +`muse-texinfo-markup-specials' + A table of characters which must be represented specially. + +`muse-texinfo-markup-specials' + A table of characters which must be represented specially. These + are applied to URLs. + + + +File: muse.info, Node: XML, Prev: Texinfo, Up: Publishing Styles + +9.11 Publish entries to XML +=========================== + +Muse is capable of publishing XML documents, with the help of the +`muse-xml.el' module. + + A RelaxNG schema is available as part of the Muse distribution in the +`etc/muse.rnc' file. + +Styles provided +--------------- + +`xml' + Publish a file in XML form. + + +Options provided +---------------- + +`muse-xml-encoding-map' + An alist mapping Emacs coding systems to appropriate XML charsets. + Use the base name of the coding system (i.e. without the -unix). + +`muse-xml-markup-specials' + A table of characters which must be represented specially in all + XML-like markup formats. + +`muse-xml-markup-specials-url-extra' + A table of characters which must be represented specially in all + XML-like markup formats. + + These are extra characters that are escaped within URLs. + +`muse-xml-extension' + Default file extension used for publishing XML files. + +`muse-xml-header' + Header used for publishing XML files. + + This may be text or a filename. + +`muse-xml-footer' + Footer used for publishing XML files. + + This may be text or a filename. + +`muse-xml-markup-regexps' + List of markup rules for publishing a Muse page to XML. + + For more on the structure of this list, *Note + muse-publish-markup-regexps::. + +`muse-xml-markup-functions' + An alist of style types to custom functions for that kind of text. + + For more on the structure of this list, *Note + muse-publish-markup-functions::. + +`muse-xml-markup-strings' + Strings used for marking up text. + + These cover the most basic kinds of markup, the handling of which + differs little between the various styles. + +`muse-xml-encoding-default' + The default Emacs buffer encoding to use in published files. + + This will be used if no special characters are found. + +`muse-xml-charset-default' + The default XML charset to use if no translation is found in + `muse-xml-encoding-map'. + + + +File: muse.info, Node: Extending Muse, Next: Miscellaneous, Prev: Publishing Styles, Up: Top + +10 Making your own publishing styles +************************************ + +* Menu: + +* Markup Functions:: Specifying functions to mark up text. +* Markup Regexps:: Markup rules for publishing. +* Markup Strings:: Strings specific to a publishing style. +* Markup Tags:: Tag specifications for special markup. +* Style Elements:: Parameters used for defining styles. +* Deriving Styles:: Deriving a new style from an existing + one. + + +File: muse.info, Node: Markup Functions, Next: Markup Regexps, Up: Extending Muse + +10.1 Specifying functions to mark up text +========================================= + +`muse-publish-markup-functions' + + An alist of style types to custom functions for that kind of text. + + This is used by publishing styles to attempt to minimize the amount +of custom regexps that each has to define. `muse-publish' provides +rules for the most common types of markup. + + Each member of the list is of the following form. + + (SYMBOL FUNCTION) + + * SYMBOL Describes the type of text to associate with this rule. + `muse-publish-markup-regexps' maps regexps to these symbols. + + * FUNCTION Function to use to mark up this kind of rule if no + suitable function is found through the `:functions' tag of the + current style. + + +File: muse.info, Node: Markup Regexps, Next: Markup Strings, Prev: Markup Functions, Up: Extending Muse + +10.2 Markup rules for publishing +================================ + +`muse-publish-markup-regexps' + + List of markup rules for publishing a page with Muse. + + The rules given in this variable are invoked first, followed by +whatever rules are specified by the current style. + + Each member of the list is either a function, or a list of the +following form. + + (REGEXP/SYMBOL TEXT-BEGIN-GROUP REPLACEMENT-TEXT/FUNCTION/SYMBOL) + + * REGEXP A regular expression, or symbol whose value is a regular + expression, which is searched for using `re-search-forward'. + + * TEXT-BEGIN-GROUP The matching group within that regexp which + denotes the beginning of the actual text to be marked up. + + * REPLACEMENT-TEXT A string that will be passed to `replace-match'. + + If it is not a string, but a function, it will be called to + determine what the replacement text should be (it must return a + string). If it is a symbol, the value of that symbol should be a + string. + + The replacements are done in order, one rule at a time. Writing the +regular expressions can be a tricky business. Note that case is never +ignored. `case-fold-search' is always bound to nil while processing +the markup rules. + +Publishing order +---------------- + +This is the order that the publishing rules are consulted, by default. +This may be changed by customizing `muse-publish-markup-regexps'. + +`trailing and leading whitespace' + Remove trailing and leading whitespace from a file. + +`directive' + `#directive' + + This is only recognized at the beginning of a file. + +`comment' + `; a commented line' + +`tag' + `' + +`comment' + `; comment' + +`explicit links' + Prevent emphasis characters in explicit links from being marked up. + + Don't actually publish them here, just add a special no-emphasis + text property. + +`word' + Whitespace-delimited word, possibly with emphasis characters + + This function is responsible for marking up emphasis and escaping + some specials. + +`heading' + `** Heading' + + Outline-mode style headings. + +`enddots' + `....' + + These are ellipses with a dot at end. + +`dots' + `...' + + Ellipses. + +`rule' + `----' + + Horizontal rule or section separator. + +`no-break-space' + `~~' + + Prevent lines from being split before or after these characters. + +`line-break' + `
    ' + + Break a line at point. + +`fn-sep' + `Footnotes:' + + Beginning of footnotes section. + +`footnote' + `[1]' + + Footnote definition or reference. If at beginning of line, it is a + definition. + +`list' + * ` 1. ' + + * ` - ' + + * `term :: ' + + Numbered list, item list, or term definition list. + +`table-el' + `table.el' style tables + +`table' + `table | cells' + + Muse tables or orgtbl-mode style tables. + +`quote' + spaces before beginning of text + + Blockquotes. + +`emdash' + `--' + + 2-wide dash + +`verse' + `> verse text' + +`anchor' + `#anchor' + +`link' + `[[explicit][links]]' + +`url' + `http://example.com/' + +`email' + `bare-email@example.com' + + + +File: muse.info, Node: Markup Strings, Next: Markup Tags, Prev: Markup Regexps, Up: Extending Muse + +10.3 Strings specific to a publishing style +=========================================== + +"Markup strings" are strings used for marking up text for a particular +style. + + These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +Available markup strings +------------------------ + +`image-with-desc' + An image and a description. + + Argument 1: image without extension. Argument 2: image extension. + Argument 3: description. + +`image' + An inlined image. + + Argument 1: image without extension. Argument 2: image extension. + +`image-link' + An image with a link around it. + + Argument 1: link. Argument 2: image without extension. Argument + 3: image extension. + +`anchor-ref' + A reference to an anchor on the current page. + + Argument 1: anchor name. Argument 2: description if one exists, + or the original link otherwise. + +`url' + A URL without a description. + + Argument 1: URL. + +`link' + A link to a Muse page with a description. + + Argument 1: link. Argument 2: description if one exists, or the + original link otherwise. + +`link-and-anchor' + A link to a Muse page with an anchor, and a description. + + Argument 1: link. Argument 2: anchor name. Argument 3: + description if one exists, or the original link otherwise. + Argument 4: link without an extension. + +`email-addr' + A link to an email address. + + Argument 1: email address. Argument 2: email address. + +`anchor' + An anchor. + + Argument 1: name of anchor. + +`emdash' + A 2-length dash. + + Argument 1: Initial whitespace. Argument 2: Terminating + whitespace. + +`comment-begin' + Beginning of a comment. + +`comment-end' + End of a comment. + +`rule' + A horizontal line or space. + +`no-break-space' + A space that separates two words which are not to be separated. + +`footnote' + Beginning of footnote. + +`footnote-end' + End of footnote. + +`footnotemark' + Mark a reference for the current footnote. + + Argument 1: number of this footnote. + +`footnotemark-end' + End of a reference for the current footnote. + +`footnotetext' + Indicate the text of the current footnote. + + Argument 1: number of this footnote. + +`footnotetext-end' + End of a footnote text line. + +`fn-sep' + Text used to replace "Footnotes:" line. + +`dots' + 3 dots. + +`enddots' + 4 dots. + +`part' + Beginning of a part indicator line. This is used by book + publishing. + +`part-end' + End of a part indicator line. This is used by book publishing. + +`chapter' + Beginning of a chapter indicator line. This is used by book + publishing. + +`chapter-end' + End of a chapter indicator line. This is used by book publishing. + +`section' + Beginning of level 1 section indicator line. + + Argument 1: level of section; always 1. + +`section-end' + End of level 1 section indicator line. + + Argument 1: level of section; always 1. + +`subsection' + Beginning of level 2 section indicator line. + + Argument 1: level of section; always 2. + +`subsection-end' + End of level 2 section indicator line. + + Argument 1: level of section; always 2. + +`subsubsection' + Beginning of level 3 section indicator line. + + Argument 1: level of section; always 3. + +`subsubsection-end' + End of level 3 section indicator line. + + Argument 1: level of section; always 3. + +`section-other' + Beginning of section indicator line, where level is greater than 3. + + Argument 1: level of section. + +`section-other-end' + End of section indicator line, where level is greater than 3. + + Argument 1: level of section. + +`begin-underline' + Beginning of underlined text. + +`end-underline' + End of underlined text. + +`begin-literal' + Beginning of verbatim text. This includes tags and + =teletype text=. + +`end-literal' + End of verbatim text. This includes tags and =teletype + text=. + +`begin-emph' + Beginning of the first level of emphasized text. + +`end-emph' + End of the first level of emphasized text. + +`begin-more-emph' + Beginning of the second level of emphasized text. + +`end-more-emph' + End of the second level of emphasized text. + +`begin-most-emph' + Beginning of the third (and final) level of emphasized text. + +`end-most-emph' + End of the third (and final) level of emphasized text. + +`begin-verse' + Beginning of verse text. + +`verse-space' + String used to each space that is further indented than the + beginning of the verse. + +`begin-verse-line' + Beginning of a line of verse. + +`empty-verse-line' + End of a line of verse. + +`begin-last-stanza-line' + Beginning of the last line of a verse stanza. + +`end-last-stanza-line' + End of the last line of a verse stanza. + +`end-verse' + End of verse text. + +`begin-example' + Beginning of an example region. To make use of this, an + `' tag is needed. + +`end-example' + End of an example region. To make use of this, an `' tag + is needed. + +`begin-center' + Begin a centered line. + +`end-center' + End a centered line. + +`begin-quote' + Begin a quoted region. + +`end-quote' + End a quoted region. + +`begin-quote-item' + Begin a quote paragraph. + +`end-quote-item' + End a quote paragraph. + +`begin-uli' + Begin an unordered list. + +`end-uli' + End an unordered list. + +`begin-uli-item' + Begin an unordered list item. + +`end-uli-item' + End an unordered list item. + +`begin-oli' + Begin an ordered list. + +`end-oli' + End an ordered list. + +`begin-oli-item' + Begin an ordered list item. + +`end-oli-item' + End an ordered list item. + +`begin-dl' + Begin a definition list. + +`end-dl' + End a definition list. + +`begin-dl-item' + Begin a definition list item. + +`end-dl-item' + End a definition list item. + +`begin-ddt' + Begin a definition list term. + +`end-ddt' + End a definition list term. + +`begin-dde' + Begin a definition list entry. + +`end-dde' + End a definition list entry. + +`begin-table' + Begin a table. + +`end-table' + End a table. + +`begin-table-group' + Begin a table grouping. + +`end-table-group' + End a table grouping. + +`begin-table-row' + Begin a table row. + +`end-table-row' + End a table row. + +`begin-table-entry' + Begin a table entry. + +`end-table-entry' + End a table entry. + + + +File: muse.info, Node: Markup Tags, Next: Style Elements, Prev: Markup Strings, Up: Extending Muse + +10.4 Tag specifications for special markup +========================================== + +`muse-publish-markup-tags' + + A list of tag specifications, for specially marking up text. + + XML-style tags are the best way to add custom markup to Muse. This +is easily accomplished by customizing this list of markup tags. + + For each entry, the name of the tag is given, whether it expects a +closing tag and/or an optional set of attributes, whether it is +nestable, and a function that performs whatever action is desired within +the delimited region. + + The tags themselves are deleted during publishing, before the +function is called. The function is called with three arguments, the +beginning and end of the region surrounded by the tags. If properties +are allowed, they are passed as a third argument in the form of an +alist. The `end' argument to the function is always a marker. + + Point is always at the beginning of the region within the tags, when +the function is called. Wherever point is when the function finishes is +where tag markup will resume. + + These tag rules are processed once at the beginning of markup, and +once at the end, to catch any tags which may have been inserted +in-between. + + +File: muse.info, Node: Style Elements, Next: Deriving Styles, Prev: Markup Tags, Up: Extending Muse + +10.5 Parameters used for defining styles +======================================== + +Style elements are tags that define a style. Use either +`muse-define-style' or `muse-derive-style' (*note Deriving Styles::) to +create a new style. + + -- Function: muse-define-style name &rest elements + +Usable elements +--------------- + +`:suffix' + File extension to use for publishing files with this style. + +`:link-suffix' + File extension to use for publishing links to Muse files with this + style. + +`:osuffix' + File extension to use for publishing second-stage files with this + style. + + For example, PDF publishing generates a LaTeX file first, then a + PDF from that LaTeX file. + +`:regexps' + List of markup rules for publishing a page with Muse. *Note + muse-publish-markup-regexps::. + +`:functions' + An alist of style types to custom functions for that kind of text. + *Note muse-publish-markup-functions::. + +`:strings' + Strings used for marking up text with this style. + + These cover the most basic kinds of markup, the handling of which + differs little between the various styles. + +`:tags' + A list of tag specifications, used for handling extra tags. *Note + muse-publish-markup-tags::. + +`:specials' + A table of characters which must be represented specially. + +`:before' + A function that is to be executed on the newly-created publishing + buffer (or the current region) before any publishing occurs. + + This is used to set extra parameters that direct the publishing + process. + +`:before-end' + A function that is to be executed on the publishing buffer (or the + current region) immediately after applying all of the markup + regexps. + + This is used to fix the order of table elements (header, footer, + body) in XML-ish styles. + +`:after' + A function that is to be executed on the publishing buffer after + :before-end, and immediately after inserting the header and footer. + + This is used for generating the table of contents as well as + setting the file coding system. + +`:final' + A function that is to be executed after saving the published file, + but while still in its buffer. + + This is used for generating second-stage documents like PDF files + from just-published LaTeX files. + + The function must accept three arguments: the name of the muse + source file, the name of the just-published file, and the name of + the second-stage target file. The name of the second-stage target + file is the same as that of the just-published file if no + second-stage publishing is required. + +`:header' + Header used for publishing files of this style. + + This may be a variable, text, or a filename. It is inserted at the + beginning of a file, after evaluating the publishing markup. + +`:footer' + Footer used for publishing files of this style. + + This may be a variable, text, or a filename. It is inserted at + the end of a file, after evaluating the publishing markup. + +`:style-sheet' + Style sheet used for publishing files of this style. + + This may be a variable or text. It is used in the header of HTML + and XHTML based publishing styles. + +`:browser' + The function used to browse the published result of files of this + style. + + + +File: muse.info, Node: Deriving Styles, Prev: Style Elements, Up: Extending Muse + +10.6 Deriving a new style from an existing one +============================================== + +To create a new style from an existing one, use `muse-derive-style' as +follows. This is a good way to fix something you don't like about a +particular publishing style, or to personalize it. + + -- Function: muse-derive-style new-name base-name &rest elements + + The derived name is a string defining the new style, such as +"my-html". The base name must identify an existing style, such as +"html" - if you have loaded `muse-html'. The style parameters are the +same as those used to create a style, except that they override whatever +definitions exist in the base style. However, some definitions only +partially override. The following parameters support partial +overriding. + + *Note Style Elements::, for a complete list of all parameters. + +`:functions' + If a markup function is not found in the derived style's function + list, the base style's function list will be queried. + +`:regexps' + All regexps in the current style and the base style(s) will be + used. + +`:strings' + If a markup string is not found in the derived style's string + list, the base style's string list will be queried. + + + +File: muse.info, Node: Miscellaneous, Next: Getting Help and Reporting Bugs, Prev: Extending Muse, Up: Top + +11 Miscellaneous add-ons, like a minor mode +******************************************* + +* Menu: + +* Muse List Edit Minor Mode:: Edit lists easily in other major modes. + + +File: muse.info, Node: Muse List Edit Minor Mode, Up: Miscellaneous + +11.1 Edit lists easily in other major modes +=========================================== + +`muse-list-edit-minor-mode' is meant to be used with other major modes, +such as Message (for composing email) and debian-changelog-mode (for +editing debian/changelog files). + + It implements practically perfect support for editing and filling +lists. It can even handle nested lists. In addition to Muse-specific +list items ("-", numbers, definition lists, footnotes), it can also +handle items that begin with "*" or "+". Filling list items behaves in +the same way that it does in Muse, regardless of whether filladapt is +also enabled, which is the primary reason to use this tool. + +Installation +------------ + +To use it, add "(require 'muse-mode)" to your Emacs customization file +and add the function `turn-on-muse-list-edit-minor-mode' to any mode +hooks where you wish to enable this minor mode. + +Keybindings +----------- + +`muse-list-edit-minor-mode' uses the following keybindings. + +`M-RET (`muse-l-e-m-m-insert-list-item')' + Insert a new list item at point, using the indentation level of the + current list item. + +`C-< (`muse-l-e-m-m-decrease-list-item-indent')' + Decrease indentation of the current list item. + +`C-> (`muse-l-e-m-m-increase-list-item-indent')' + Increase indentation of the current list item. + + +Functions +--------- + + -- Function: muse-list-edit-minor-mode + This is a global minor mode for editing files with lists. It is + meant to be used with other major modes, and not with Muse mode. + + Interactively, with no prefix argument, toggle the mode. With + universal prefix ARG turn mode on. With zero or negative ARG turn + mode off. + + This minor mode provides the Muse keybindings for editing lists, + and support for filling lists properly. + + It recognizes not only Muse-style lists, which use the "-" + character or numbers, but also lists that use asterisks or plus + signs. This should make the minor mode generally useful. + + Definition lists and footnotes are also recognized. + + Note that list items may omit leading spaces, for compatibility + with modes that set `left-margin', such as `debian-changelog-mode'. + + -- Function: turn-on-muse-list-edit-minor-mode + Unconditionally turn on Muse list edit minor mode. + + -- Function: turn-off-muse-list-edit-minor-mode + Unconditionally turn off Muse list edit minor mode. + + +File: muse.info, Node: Getting Help and Reporting Bugs, Next: History, Prev: Miscellaneous, Up: Top + +12 Getting Help and Reporting Bugs +********************************** + +After you have read this guide, if you still have questions about Muse, +or if you have bugs to report, there are several places you can go. + + * `http://www.emacswiki.org/cgi-bin/wiki/EmacsMuse' is the + emacswiki.org page, and anyone may add tips, hints, or bug + descriptions to it. + + * `http://mwolson.org/projects/EmacsMuse.html' is the web page that + Michael Olson (the current maintainer) made for Muse. + + * Muse has several different mailing lists. + + `muse-el-announce' + Low-traffic list for Muse-related announcements. + + You can join this mailing list () + using the subscription form at + `http://mail.gna.org/listinfo/muse-el-announce/'. This + mailing list is also available via Gmane + (`http://gmane.org/'). The group is called + `gmane.emacs.muse.announce'. + + `muse-el-discuss' + Discussion, bugfixes, suggestions, tips, and the like for + Muse. This mailing list also includes the content of + muse-el-announce. + + You can join this mailing list () + using the subscription form at + `http://mail.gna.org/listinfo/muse-el-discuss/'. This mailing + list is also available via Gmane with the identifier + `gmane.emacs.muse.general'. + + `muse-el-logs' + Log messages for commits made to Muse. + + You can join this mailing list () using + the subscription form at + `http://mail.gna.org/listinfo/muse-el-logs/'. This mailing + list is also available via Gmane with the identifier + `gmane.emacs.muse.scm'. + + `muse-el-commits' + Generated bug reports for Emacs Muse. If you use our + bug-tracker at `https://gna.org/bugs/?group=muse-el', the bug + reports will be sent to this list automatically. + + You can join this mailing list () + using the subscription form at + `http://mail.gna.org/listinfo/muse-el-commits/'. This + mailing list is also available via Gmane with the identifier + `gmane.emacs.muse.cvs'. + + `muse-el-internationalization' + Discussion of translation of the Muse website and + documentation into many languages. + + You can join this mailing list + () using the + subscription form at + `http://mail.gna.org/listinfo/internationalization/'. This + mailing list is also available via Gmane with the identifier + `gmane.emacs.muse.internationalization'. + + + * You can visit the IRC Freenode channel `#emacs'. Many of the + contributors are frequently around and willing to answer your + questions. The `#muse' channel is also available for + Muse-specific help, and its current maintainer hangs out there. + + * The maintainer of Emacs Muse, Michael Olson, may be contacted at + . He can be rather slow at answering email, so + it is often better to use the muse-el-discuss mailing list. + + + +File: muse.info, Node: History, Next: Contributors, Prev: Getting Help and Reporting Bugs, Up: Top + +13 History of This Document +*************************** + + * 2004 John Wiegley started Muse upon realizing that EmacsWiki had + some serious limitations. Around February 2004, he started making + "emacs-wiki version 3.00 APLHA", which eventually became known as + Muse. + + Most of those who frequent the emacs-wiki mailing list continued + to use emacs-wiki, mainly because Planner hasn't been ported over + to it. + + As of 2004-12-01, Michael Olson became the maintainer of Muse, as + per John Wiegley's request. + + * 2005 Michael Olson overhauled this document and added many new + sections in preparation for the first release of Muse (3.01). + + + +File: muse.info, Node: Contributors, Next: GNU Free Documentation License, Prev: History, Up: Top + +14 Contributors to This Documentation +************************************* + +The first draft of this document was taken from the emacs-wiki texinfo +manual. Michael Olson adapted it for Muse and added most of its +content. + + John Sullivan did a majority of the work on the emacs-wiki texinfo +manual. + + While Sacha Chua maintained emacs-wiki, she worked quite a bit on the +emacs-wiki texinfo manual. + + +File: muse.info, Node: GNU Free Documentation License, Next: Concept Index, Prev: Contributors, Up: Top + +Appendix A GNU Free Documentation License +***************************************** + + Version 1.2, November 2002 + + Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + 0. PREAMBLE + + The purpose of this License is to make a manual, textbook, or other + functional and useful document "free" in the sense of freedom: to + assure everyone the effective freedom to copy and redistribute it, + with or without modifying it, either commercially or + noncommercially. Secondarily, this License preserves for the + author and publisher a way to get credit for their work, while not + being considered responsible for modifications made by others. + + This License is a kind of "copyleft," which means that derivative + works of the document must themselves be free in the same sense. + It complements the GNU General Public License, which is a copyleft + license designed for free software. + + We have designed this License in order to use it for manuals for + free software, because free software needs free documentation: a + free program should come with manuals providing the same freedoms + that the software does. But this License is not limited to + software manuals; it can be used for any textual work, regardless + of subject matter or whether it is published as a printed book. + We recommend this License principally for works whose purpose is + instruction or reference. + + + 1. APPLICABILITY AND DEFINITIONS + + This License applies to any manual or other work, in any medium, + that contains a notice placed by the copyright holder saying it + can be distributed under the terms of this License. Such a notice + grants a world-wide, royalty-free license, unlimited in duration, + to use that work under the conditions stated herein. The + "Document," below, refers to any such manual or work. Any member + of the public is a licensee, and is addressed as "you." You + accept the license if you copy, modify or distribute the work in a + way requiring permission under copyright law. + + A "Modified Version" of the Document means any work containing the + Document or a portion of it, either copied verbatim, or with + modifications and/or translated into another language. + + A "Secondary Section" is a named appendix or a front-matter + section of the Document that deals exclusively with the + relationship of the publishers or authors of the Document to the + Document's overall subject (or to related matters) and contains + nothing that could fall directly within that overall subject. + (Thus, if the Document is in part a textbook of mathematics, a + Secondary Section may not explain any mathematics.) The + relationship could be a matter of historical connection with the + subject or with related matters, or of legal, commercial, + philosophical, ethical or political position regarding them. + + The "Invariant Sections" are certain Secondary Sections whose + titles are designated, as being those of Invariant Sections, in + the notice that says that the Document is released under this + License. If a section does not fit the above definition of + Secondary then it is not allowed to be designated as Invariant. + The Document may contain zero Invariant Sections. If the Document + does not identify any Invariant Sections then there are none. + + The "Cover Texts" are certain short passages of text that are + listed, as Front-Cover Texts or Back-Cover Texts, in the notice + that says that the Document is released under this License. A + Front-Cover Text may be at most 5 words, and a Back-Cover Text may + be at most 25 words. + + A "Transparent" copy of the Document means a machine-readable copy, + represented in a format whose specification is available to the + general public, that is suitable for revising the document + straightforwardly with generic text editors or (for images + composed of pixels) generic paint programs or (for drawings) some + widely available drawing editor, and that is suitable for input to + text formatters or for automatic translation to a variety of + formats suitable for input to text formatters. A copy made in an + otherwise Transparent file format whose markup, or absence of + markup, has been arranged to thwart or discourage subsequent + modification by readers is not Transparent. An image format is + not Transparent if used for any substantial amount of text. A + copy that is not "Transparent" is called "Opaque." + + Examples of suitable formats for Transparent copies include plain + ASCII without markup, Texinfo input format, LaTeX input format, + SGML or XML using a publicly available DTD, and + standard-conforming simple HTML, PostScript or PDF designed for + human modification. Examples of transparent image formats include + PNG, XCF and JPG. Opaque formats include proprietary formats that + can be read and edited only by proprietary word processors, SGML + or XML for which the DTD and/or processing tools are not generally + available, and the machine-generated HTML, PostScript or PDF + produced by some word processors for output purposes only. + + The "Title Page" means, for a printed book, the title page itself, + plus such following pages as are needed to hold, legibly, the + material this License requires to appear in the title page. For + works in formats which do not have any title page as such, "Title + Page" means the text near the most prominent appearance of the + work's title, preceding the beginning of the body of the text. + + A section "Entitled XYZ" means a named subunit of the Document + whose title either is precisely XYZ or contains XYZ in parentheses + following text that translates XYZ in another language. (Here XYZ + stands for a specific section name mentioned below, such as + "Acknowledgements," "Dedications," "Endorsements," or "History.") + To "Preserve the Title" of such a section when you modify the + Document means that it remains a section "Entitled XYZ" according + to this definition. + + The Document may include Warranty Disclaimers next to the notice + which states that this License applies to the Document. These + Warranty Disclaimers are considered to be included by reference in + this License, but only as regards disclaiming warranties: any other + implication that these Warranty Disclaimers may have is void and + has no effect on the meaning of this License. + + 2. VERBATIM COPYING + + You may copy and distribute the Document in any medium, either + commercially or noncommercially, provided that this License, the + copyright notices, and the license notice saying this License + applies to the Document are reproduced in all copies, and that you + add no other conditions whatsoever to those of this License. You + may not use technical measures to obstruct or control the reading + or further copying of the copies you make or distribute. However, + you may accept compensation in exchange for copies. If you + distribute a large enough number of copies you must also follow + the conditions in section 3. + + You may also lend copies, under the same conditions stated above, + and you may publicly display copies. + + 3. COPYING IN QUANTITY + + If you publish printed copies (or copies in media that commonly + have printed covers) of the Document, numbering more than 100, and + the Document's license notice requires Cover Texts, you must + enclose the copies in covers that carry, clearly and legibly, all + these Cover Texts: Front-Cover Texts on the front cover, and + Back-Cover Texts on the back cover. Both covers must also clearly + and legibly identify you as the publisher of these copies. The + front cover must present the full title with all words of the + title equally prominent and visible. You may add other material + on the covers in addition. Copying with changes limited to the + covers, as long as they preserve the title of the Document and + satisfy these conditions, can be treated as verbatim copying in + other respects. + + If the required texts for either cover are too voluminous to fit + legibly, you should put the first ones listed (as many as fit + reasonably) on the actual cover, and continue the rest onto + adjacent pages. + + If you publish or distribute Opaque copies of the Document + numbering more than 100, you must either include a + machine-readable Transparent copy along with each Opaque copy, or + state in or with each Opaque copy a computer-network location from + which the general network-using public has access to download + using public-standard network protocols a complete Transparent + copy of the Document, free of added material. If you use the + latter option, you must take reasonably prudent steps, when you + begin distribution of Opaque copies in quantity, to ensure that + this Transparent copy will remain thus accessible at the stated + location until at least one year after the last time you + distribute an Opaque copy (directly or through your agents or + retailers) of that edition to the public. + + It is requested, but not required, that you contact the authors of + the Document well before redistributing any large number of + copies, to give them a chance to provide you with an updated + version of the Document. + + 4. MODIFICATIONS + + You may copy and distribute a Modified Version of the Document + under the conditions of sections 2 and 3 above, provided that you + release the Modified Version under precisely this License, with + the Modified Version filling the role of the Document, thus + licensing distribution and modification of the Modified Version to + whoever possesses a copy of it. In addition, you must do these + things in the Modified Version: + + A. Use in the Title Page (and on the covers, if any) a title + distinct from that of the Document, and from those of previous + versions (which should, if there were any, be listed in the + History section of the Document). You may use the same title + as a previous version if the original publisher of that version + gives permission. + B. List on the Title Page, as authors, one or more persons or + entities responsible for authorship of the modifications in the + Modified Version, together with at least five of the principal + authors of the Document (all of its principal authors, if it + has fewer than five), unless they release you from this + requirement. + C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. + D. Preserve all the copyright notices of the Document. + E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. + F. Include, immediately after the copyright notices, a license + notice giving the public permission to use the Modified Version + under the terms of this License, in the form shown in the + Addendum below. + G. Preserve in that license notice the full lists of Invariant + Sections and required Cover Texts given in the Document's + license notice. + H. Include an unaltered copy of this License. + I. Preserve the section Entitled "History," Preserve its Title, + and add to it an item stating at least the title, year, new + authors, and publisher of the Modified Version as given on the + Title Page. If there is no section Entitled "History" in the + Document, create one stating the title, year, authors, and + publisher of the Document as given on its Title Page, then add + an item describing the Modified Version as stated in the + previous sentence. + J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. + K. For any section Entitled "Acknowledgements" or "Dedications," + Preserve the Title of the section, and preserve in the section all + the substance and tone of each of the contributor + acknowledgements and/or dedications given therein. + L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. + M. Delete any section Entitled "Endorsements." Such a section + may not be included in the Modified Version. + N. Do not retitle any existing section to be Entitled + "Endorsements" or to conflict in title with any Invariant + Section. + O. Preserve any Warranty Disclaimers. + + If the Modified Version includes new front-matter sections or + appendices that qualify as Secondary Sections and contain no + material copied from the Document, you may at your option + designate some or all of these sections as invariant. To do this, + add their titles to the list of Invariant Sections in the Modified + Version's license notice. These titles must be distinct from any + other section titles. + + You may add a section Entitled "Endorsements," provided it contains + nothing but endorsements of your Modified Version by various + parties-for example, statements of peer review or that the text has + been approved by an organization as the authoritative definition + of a standard. + + You may add a passage of up to five words as a Front-Cover Text, + and a passage of up to 25 words as a Back-Cover Text, to the end + of the list of Cover Texts in the Modified Version. Only one + passage of Front-Cover Text and one of Back-Cover Text may be + added by (or through arrangements made by) any one entity. If the + Document already includes a cover text for the same cover, + previously added by you or by arrangement made by the same entity + you are acting on behalf of, you may not add another; but you may + replace the old one, on explicit permission from the previous + publisher that added the old one. + + The author(s) and publisher(s) of the Document do not by this + License give permission to use their names for publicity for or to + assert or imply endorsement of any Modified Version. + + 5. COMBINING DOCUMENTS + + You may combine the Document with other documents released under + this License, under the terms defined in section 4 above for + modified versions, provided that you include in the combination + all of the Invariant Sections of all of the original documents, + unmodified, and list them all as Invariant Sections of your + combined work in its license notice, and that you preserve all + their Warranty Disclaimers. + + The combined work need only contain one copy of this License, and + multiple identical Invariant Sections may be replaced with a single + copy. If there are multiple Invariant Sections with the same name + but different contents, make the title of each such section unique + by adding at the end of it, in parentheses, the name of the + original author or publisher of that section if known, or else a + unique number. Make the same adjustment to the section titles in + the list of Invariant Sections in the license notice of the + combined work. + + In the combination, you must combine any sections Entitled + "History" in the various original documents, forming one section + Entitled "History"; likewise combine any sections Entitled + "Acknowledgements," and any sections Entitled "Dedications." You + must delete all sections Entitled "Endorsements." + + 6. COLLECTIONS OF DOCUMENTS + + You may make a collection consisting of the Document and other + documents released under this License, and replace the individual + copies of this License in the various documents with a single copy + that is included in the collection, provided that you follow the + rules of this License for verbatim copying of each of the + documents in all other respects. + + You may extract a single document from such a collection, and + distribute it individually under this License, provided you insert + a copy of this License into the extracted document, and follow + this License in all other respects regarding verbatim copying of + that document. + + 7. AGGREGATION WITH INDEPENDENT WORKS + + A compilation of the Document or its derivatives with other + separate and independent documents or works, in or on a volume of + a storage or distribution medium, is called an "aggregate" if the + copyright resulting from the compilation is not used to limit the + legal rights of the compilation's users beyond what the individual + works permit. When the Document is included in an aggregate, this + License does not apply to the other works in the aggregate which + are not themselves derivative works of the Document. + + If the Cover Text requirement of section 3 is applicable to these + copies of the Document, then if the Document is less than one half + of the entire aggregate, the Document's Cover Texts may be placed + on covers that bracket the Document within the aggregate, or the + electronic equivalent of covers if the Document is in electronic + form. Otherwise they must appear on printed covers that bracket + the whole aggregate. + + 8. TRANSLATION + + Translation is considered a kind of modification, so you may + distribute translations of the Document under the terms of section + 4. Replacing Invariant Sections with translations requires special + permission from their copyright holders, but you may include + translations of some or all Invariant Sections in addition to the + original versions of these Invariant Sections. You may include a + translation of this License, and all the license notices in the + Document, and any Warranty Disclaimers, provided that you also + include the original English version of this License and the + original versions of those notices and disclaimers. In case of a + disagreement between the translation and the original version of + this License or a notice or disclaimer, the original version will + prevail. + + If a section in the Document is Entitled "Acknowledgements," + "Dedications," or "History," the requirement (section 4) to + Preserve its Title (section 1) will typically require changing the + actual title. + + 9. TERMINATION + + You may not copy, modify, sublicense, or distribute the Document + except as expressly provided for under this License. Any other + attempt to copy, modify, sublicense or distribute the Document is + void, and will automatically terminate your rights under this + License. However, parties who have received copies, or rights, + from you under this License will not have their licenses + terminated so long as such parties remain in full compliance. + + 10. FUTURE REVISIONS OF THIS LICENSE + + The Free Software Foundation may publish new, revised versions of + the GNU Free Documentation License from time to time. Such new + versions will be similar in spirit to the present version, but may + differ in detail to address new problems or concerns. See + http://www.gnu.org/copyleft/. + + Each version of the License is given a distinguishing version + number. If the Document specifies that a particular numbered + version of this License "or any later version" applies to it, you + have the option of following the terms and conditions either of + that specified version or of any later version that has been + published (not as a draft) by the Free Software Foundation. If + the Document does not specify a version number of this License, + you may choose any version ever published (not as a draft) by the + Free Software Foundation. + + +ADDENDUM: How to use this License for your documents +==================================================== + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and license +notices just after the title page: + + Copyright (C) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled ``GNU + Free Documentation License.'' + + If you have Invariant Sections, Front-Cover Texts and Back-Cover +Texts, replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being + LIST. + + If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + + If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, to +permit their use in free software. + + +File: muse.info, Node: Concept Index, Prev: GNU Free Documentation License, Up: Top + +Index +***** + +[index] +* Menu: + +* #author: Directives. (line 18) +* #date: Directives. (line 24) +* #desc: Directives. (line 30) +* #title: Directives. (line 36) +* anchors: Horizontal Rules and Anchors. + (line 13) +* blog, journal style: Journal. (line 6) +* blog, one-file-per-entry style: Blosxom. (line 6) +* bugs, reporting: Getting Help and Reporting Bugs. + (line 6) +* citations: Citations. (line 6) +* comments: Comments. (line 6) +* compiling Muse: Installation. (line 11) +* contributors: Contributors. (line 6) +* dashes: Horizontal Rules and Anchors. + (line 6) +* Debian package for Muse: Releases. (line 12) +* developer, becoming: Development. (line 91) +* development: Development. (line 6) +* directives: Directives. (line 6) +* editing Muse files <1>: Publishing Files Overview. + (line 6) +* editing Muse files: Using Muse Mode. (line 6) +* ELPA package for Muse: Installation. (line 64) +* Email addresses: Implicit Links. (line 6) +* emphasizing text: Emphasizing Text. (line 6) +* examples: Paragraphs. (line 21) +* file extension, specifying: File Extensions. (line 6) +* footnotes: Footnotes. (line 6) +* git version control system, using: Development. (line 9) +* headings: Headings. (line 6) +* help, getting: Getting Help and Reporting Bugs. + (line 6) +* history, of Muse: History. (line 6) +* horizontal rules: Horizontal Rules and Anchors. + (line 6) +* HTML, inserting a raw block: Paragraphs. (line 28) +* HTML, rendering blocks in monospace: Paragraphs. (line 21) +* images: Images. (line 6) +* images, captions: Images. (line 53) +* images, displaying: Images. (line 22) +* images, inlined: Images. (line 43) +* images, local: Images. (line 22) +* images, without descriptions: Images. (line 43) +* inserting files at publish time: Tag Summary. (line 6) +* installing Muse: Installation. (line 38) +* inter-project links: Implicit Links. (line 29) +* InterWiki links: Implicit Links. (line 29) +* italicizing text: Emphasizing Text. (line 6) +* journal: Journal. (line 6) +* keystrokes: Keystroke Summary. (line 6) +* line breaks: Paragraphs. (line 46) +* links, explicit: Explicit Links. (line 6) +* links, implicit: Implicit Links. (line 6) +* links, raw: Implicit Links. (line 6) +* links, with images: Images. (line 6) +* links, with target on same page: Horizontal Rules and Anchors. + (line 13) +* lisp, and insert command: Embedded Lisp. (line 13) +* lisp, embedded: Embedded Lisp. (line 6) +* lists: Lists. (line 6) +* lists, breaking lines: Lists. (line 52) +* lists, bullets: Lists. (line 10) +* lists, definitions: Lists. (line 24) +* lists, enumerated: Lists. (line 17) +* lists, nested: Lists. (line 36) +* literal text: Paragraphs. (line 28) +* markup: Markup Rules. (line 6) +* monospace, rendering blocks: Paragraphs. (line 21) +* monospace, rendering words: Emphasizing Text. (line 6) +* muse-define-style: Style Elements. (line 11) +* muse-derive-style: Deriving Styles. (line 11) +* muse-list-edit-minor-mode: Muse List Edit Minor Mode. + (line 44) +* muse-project-alist, reference: Options for Projects. (line 6) +* muse-xml-encoding-map: XML. (line 22) +* paragraphs: Paragraphs. (line 6) +* paragraphs, centered: Paragraphs. (line 8) +* paragraphs, quoted: Paragraphs. (line 16) +* poetry: Verse. (line 6) +* projects: Projects. (line 6) +* projects, multiple: Multiple Projects. (line 6) +* projects, options: Options for Projects. (line 6) +* projects, single: Single Project. (line 6) +* projects, subdirectories: Projects and Subdirectories. + (line 6) +* publishing styles: Publishing Styles. (line 6) +* publishing styles, blosxom-html: Blosxom Options. (line 12) +* publishing styles, blosxom-xhtml: Blosxom Options. (line 15) +* publishing styles, book-latex: Book. (line 56) +* publishing styles, book-pdf: Book. (line 60) +* publishing styles, chapbook-latex: Poem. (line 45) +* publishing styles, chapbook-pdf: Poem. (line 48) +* publishing styles, context: ConTeXt. (line 15) +* publishing styles, context-pdf: ConTeXt. (line 18) +* publishing styles, context-slides: ConTeXt. (line 22) +* publishing styles, context-slides-pdf: ConTeXt. (line 40) +* publishing styles, deriving: Deriving Styles. (line 6) +* publishing styles, docbook: DocBook. (line 11) +* publishing styles, html: HTML. (line 11) +* publishing styles, ikiwiki: Ikiwiki. (line 28) +* publishing styles, info-pdf: Texinfo. (line 17) +* publishing styles, journal-book-latex: Journal. (line 82) +* publishing styles, journal-book-pdf: Journal. (line 85) +* publishing styles, journal-html: Journal. (line 70) +* publishing styles, journal-latex: Journal. (line 76) +* publishing styles, journal-pdf: Journal. (line 79) +* publishing styles, journal-rdf: Journal. (line 88) +* publishing styles, journal-rss: Journal. (line 91) +* publishing styles, journal-rss-entry: Journal. (line 94) +* publishing styles, journal-xhtml: Journal. (line 73) +* publishing styles, latex: LaTeX. (line 23) +* publishing styles, latexcjk: LaTeX. (line 30) +* publishing styles, lecture-notes: LaTeX. (line 55) +* publishing styles, lecture-notes-pdf: LaTeX. (line 61) +* publishing styles, pdf: LaTeX. (line 26) +* publishing styles, pdfcjk: LaTeX. (line 33) +* publishing styles, poem-latex: Poem. (line 39) +* publishing styles, poem-pdf: Poem. (line 42) +* publishing styles, RSS 1.0: Journal. (line 88) +* publishing styles, RSS 2.0: Journal. (line 91) +* publishing styles, slides: LaTeX. (line 37) +* publishing styles, slides-pdf: LaTeX. (line 52) +* publishing styles, texi: Texinfo. (line 14) +* publishing styles, xml: XML. (line 15) +* publishing, including markup in headers and footers: Tag Summary. + (line 6) +* publishing, inserting files: Tag Summary. (line 6) +* publishing, markup functions: Markup Functions. (line 6) +* publishing, markup regexps: Markup Regexps. (line 6) +* publishing, markup strings: Markup Strings. (line 6) +* publishing, markup tags: Markup Tags. (line 6) +* publishing, omitting lines: Comments. (line 6) +* publishing, rules: Markup Regexps. (line 6) +* publishing, style elements: Style Elements. (line 6) +* quotations: Paragraphs. (line 16) +* releases, Debian package: Releases. (line 12) +* releases, from source: Releases. (line 31) +* releases, Ubuntu package: Releases. (line 19) +* settings: Getting Started. (line 6) +* settings, init file: Loading Muse. (line 6) +* tables: Tables. (line 6) +* tables, orgtbl-mode style: Tables. (line 26) +* tables, simple: Tables. (line 6) +* tables, table.el style: Tables. (line 42) +* tags: Tag Summary. (line 6) +* tags, : Citations. (line 6) +* turn-off-muse-list-edit-minor-mode: Muse List Edit Minor Mode. + (line 67) +* turn-on-muse-list-edit-minor-mode: Muse List Edit Minor Mode. + (line 64) +* Ubuntu package for Muse: Releases. (line 19) +* underlining text: Emphasizing Text. (line 6) +* updating Muse with git: Development. (line 66) +* URLs: Implicit Links. (line 6) +* verbatim text: Emphasizing Text. (line 6) +* verses: Verse. (line 6) +* verses, multiple stanzas: Verse. (line 20) +* WikiNames: Implicit Links. (line 18) +* WYSIWYG: Emphasizing Text. (line 15) + + + +Tag Table: +Node: Top1427 +Node: Preface7398 +Node: Introduction7871 +Node: Obtaining Muse9320 +Node: Releases9657 +Node: Development11046 +Node: Installation14905 +Node: Getting Started17564 +Node: Loading Muse17946 +Node: Using Muse Mode18893 +Node: Publishing Files Overview20926 +Node: File Extensions22170 +Node: Projects23390 +Node: Single Project24012 +Node: Multiple Projects24962 +Node: Projects and Subdirectories26365 +Node: Options for Projects28048 +Node: Keystroke Summary32872 +Node: Markup Rules34991 +Node: Paragraphs36710 +Node: Headings38711 +Node: Directives39334 +Node: Emphasizing Text40654 +Node: Footnotes41431 +Node: Verse42068 +Node: Lists42812 +Node: Tables44361 +Node: Explicit Links46095 +Node: Implicit Links46810 +Node: Images49153 +Node: Horizontal Rules and Anchors51643 +Node: Embedded Lisp52291 +Node: Citations53387 +Node: Comments55871 +Node: Tag Summary56530 +Node: Publishing Styles64773 +Node: Blosxom65872 +Node: Blosxom Requirements66479 +Node: Blosxom Entries70014 +Node: Blosxom Options71577 +Node: Book72505 +Node: ConTeXt75564 +Node: DocBook79691 +Node: HTML81168 +Node: Ikiwiki85163 +Node: Journal87502 +Node: LaTeX94029 +Node: Poem99573 +Node: Texinfo101782 +Node: XML103699 +Node: Extending Muse105730 +Node: Markup Functions106367 +Ref: muse-publish-markup-functions106540 +Node: Markup Regexps107194 +Ref: muse-publish-markup-regexps107372 +Node: Markup Strings110379 +Node: Markup Tags116839 +Ref: muse-publish-markup-tags117032 +Node: Style Elements118151 +Node: Deriving Styles121558 +Node: Miscellaneous122857 +Node: Muse List Edit Minor Mode123142 +Node: Getting Help and Reporting Bugs125621 +Node: History128923 +Node: Contributors129706 +Node: GNU Free Documentation License130214 +Node: Concept Index152443 + +End Tag Table diff --git a/elpa/muse-3.20/texi/Makefile b/elpa/muse-3.20/texi/Makefile new file mode 100644 index 0000000..8f9f341 --- /dev/null +++ b/elpa/muse-3.20/texi/Makefile @@ -0,0 +1,29 @@ +.PHONY: all info-only doc clean realclean distclean fullclean install +.PRECIOUS: %.info %.html + +DEFS = $(shell test -f ../Makefile.defs && echo ../Makefile.defs \ + || echo ../Makefile.defs.default) + +include $(DEFS) + +all: doc + +%.info: %.texi + makeinfo $< + +%.html: %.texi + makeinfo --html --no-split $< + +info-only: $(MANUAL).info + +doc: $(MANUAL).info $(MANUAL).html + +clean: ; + +distclean realclean fullclean: clean + -rm -f $(MANUAL).info $(MANUAL).html + +install: $(MANUAL).info + [ -d $(INFODIR) ] || install -d $(INFODIR) + install -m 0644 $(MANUAL).info $(INFODIR)/$(MANUAL) + $(call install_info,$(MANUAL)) diff --git a/elpa/muse-3.20/texi/dir-template b/elpa/muse-3.20/texi/dir-template new file mode 100644 index 0000000..08346cd --- /dev/null +++ b/elpa/muse-3.20/texi/dir-template @@ -0,0 +1,15 @@ +This is the file .../info/dir, which contains the +topmost node of the Info hierarchy, called (dir)Top. +The first time you invoke Info you start off looking at this node. + +File: dir, Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "?" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs" visits the Emacs manual, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: diff --git a/elpa/muse-3.20/texi/doclicense.texi b/elpa/muse-3.20/texi/doclicense.texi new file mode 100644 index 0000000..83e9d6b --- /dev/null +++ b/elpa/muse-3.20/texi/doclicense.texi @@ -0,0 +1,416 @@ +@c -*-texinfo-*- +@center Version 1.2, November 2002 + +@display +Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +@end display +@sp 1 +@enumerate 0 +@item +PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document ``free'' in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of ``copyleft,'' which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +@sp 1 +@item +APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The ``Document,'' below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as ``you.'' You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (Thus, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not ``Transparent'' is called ``Opaque.'' + + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML, PostScript or PDF designed for human modification. Examples of +transparent image formats include PNG, XCF and JPG. Opaque formats +include proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML, PostScript or PDF produced by some word +processors for output purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +A section ``Entitled XYZ'' means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as ``Acknowledgements,'' +``Dedications,'' ``Endorsements,'' or ``History.'') To ``Preserve the Title'' +of such a section when you modify the Document means that it remains a +section ``Entitled XYZ'' according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. +@sp 1 +@item +VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. +@sp 1 +@item +COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. +@sp 1 +@item +MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission.@* +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement.@* +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher.@* +D. Preserve all the copyright notices of the Document.@* +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices.@* +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below.@* +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice.@* +H. Include an unaltered copy of this License.@* +I. Preserve the section Entitled ``History,'' Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled ``History'' in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence.@* +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the ``History'' section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission.@* +K. For any section Entitled ``Acknowledgements'' or ``Dedications,'' + Preserve the Title of the section, and preserve in the section all + the substance and tone of each of the contributor acknowledgements + and/or dedications given therein.@* +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles.@* +M. Delete any section Entitled ``Endorsements.'' Such a section + may not be included in the Modified Version.@* +N. Do not retitle any existing section to be Entitled ``Endorsements'' + or to conflict in title with any Invariant Section.@* +O. Preserve any Warranty Disclaimers.@* +@sp 1 +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled ``Endorsements,'' provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. +@sp 1 +@item +COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled ``History'' +in the various original documents, forming one section Entitled +``History''; likewise combine any sections Entitled ``Acknowledgements,'' +and any sections Entitled ``Dedications.'' You must delete all sections +Entitled ``Endorsements.'' +@sp 1 +@item +COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. +@sp 1 +@item +AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an ``aggregate'' if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. +@sp 1 +@item +TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled ``Acknowledgements,'' +``Dedications,'' or ``History,'' the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. +@sp 1 +@item +TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. +@sp 1 +@item +FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License ``or any later version'' applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + +@end enumerate + +@unnumberedsec ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +@smallexample +@group +Copyright (C) @var{year} @var{your name}. +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.2 +or any later version published by the Free Software Foundation; +with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +A copy of the license is included in the section entitled ``GNU +Free Documentation License.'' +@end group +@end smallexample + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the ``with...Texts.'' line with this: + +@smallexample +@group +with the Invariant Sections being @var{list their titles}, with the +Front-Cover Texts being @var{list}, and with the Back-Cover Texts being +@var{list}. +@end group +@end smallexample + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + +@ignore + arch-tag: c1679162-1d8a-4f02-bc52-2e71765f0165 +@end ignore diff --git a/elpa/muse-3.20/texi/muse.texi b/elpa/muse-3.20/texi/muse.texi new file mode 100644 index 0000000..f62c030 --- /dev/null +++ b/elpa/muse-3.20/texi/muse.texi @@ -0,0 +1,4247 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename muse.info +@settitle Muse +@c %**end of header + +@dircategory Emacs +@direntry +* Muse: (muse). Authoring and publishing environment for Emacs. +@end direntry + +@syncodeindex fn cp + +@copying +This manual is for Emacs Muse version 3.20. + +Copyright @copyright{} 2004, 2005, 2006, 2007, +2008, 2009, 2010 Free Software Foundation, Inc. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with the Front-Cover texts being ``A GNU +Manual'', and with the Back-Cover Texts as in (a) below. A copy of the +license is included in the section entitled ``GNU Free Documentation +License'' in this manual. + +(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify +this GNU Manual, like GNU software. Copies published by the Free +Software Foundation raise funds for GNU development.'' + +This document is part of a collection distributed under the GNU Free +Documentation License. If you want to distribute this document +separately from the collection, you can do so by adding a copy of the +license to the document, as described in section 6 of the license. + +All Emacs Lisp code contained in this document may be used, distributed, +and modified without restriction. +@end quotation +@end copying + +@titlepage +@title Muse manual +@subtitle an authoring and publishing environment +@subtitle for GNU Emacs and XEmacs + +@c The following two commands +@c start the copyright page. +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@c So the toc is printed at the start +@contents + +@ifnottex +@node Top, Preface, (dir), (dir) +@comment node-name, next, previous, up +@top Muse + +@insertcopying +@end ifnottex + +@menu +* Preface:: About the documentation. +* Introduction:: What is Muse? +* Obtaining Muse:: How to get Muse releases and development + changes. +* Installation:: Compiling and installing Muse. +* Getting Started:: Setting up Muse and editing files. +* Projects:: Creating and managing Muse projects. +* Keystroke Summary:: Keys used in Muse mode. +* Markup Rules:: Rules for using markup. +* Publishing Styles:: Publishing various types of documents. +* Extending Muse:: Making your own publishing styles. +* Miscellaneous:: Miscellaneous add-ons, like a minor mode. +* Getting Help and Reporting Bugs:: +* History:: History of this document. +* Contributors:: Contributors to this documentation. +* GNU Free Documentation License:: The license for this documentation. +* Concept Index:: Search for terms. + +@detailmenu + --- The Detailed Node Listing --- + +How to Get Muse Releases and Development Changes + +* Releases:: Released versions of Muse. +* Development:: Latest unreleased development changes. + +Getting Started + +* Loading Muse:: How to load Muse. +* Using Muse Mode:: How to edit files in Muse. +* Publishing Files Overview:: Publishing a single file or project. +* File Extensions:: Using a different file extension. + +Creating and Managing Muse Projects + +* Single Project:: A single-project example. +* Multiple Projects:: A multiple-project example. +* Projects and Subdirectories:: Publishing subdirectories in projects. +* Options for Projects:: Listing of available options for projects. + +Rules for Using Markup + +* Paragraphs:: Paragraphs: centering and quoting. +* Headings:: Levels of headings. +* Directives:: Directives at the beginning of a + document. +* Emphasizing Text:: Bold, italicized, and underlined text. +* Footnotes:: Making notes to be shown at the end. +* Verse:: Indicating poetic stanzas. +* Lists:: Lists of items. +* Tables:: Generation of data tables. +* Explicit Links:: Hyperlinks and email addresses with + descriptions. +* Implicit Links:: Bare URLs, WikiNames, and InterWiki + links. +* Images:: Publishing and displaying images. +* Horizontal Rules and Anchors:: Inserting a horizontal line or anchor. +* Embedded Lisp:: Evaluating Emacs Lisp code in documents + for extensibility. +* Citations:: Support for citing other resources. +* Comments:: Lines to omit from published output. +* Tag Summary:: Tags that Muse recognizes. + +Publishing Various Types of Documents + +* Blosxom:: Integrating Muse and pyblosxom.cgi. +* Book:: Publishing entries into a compilation. +* ConTeXt:: Publishing ConTeXt documents. +* DocBook:: Publishing in DocBook XML form. +* HTML:: Publishing in HTML or XHTML form. +* Ikiwiki:: Integrating with ikiwiki. +* Journal:: Keeping a journal or blog. +* LaTeX:: Publishing LaTeX documents. +* Poem:: Publish a poem to LaTeX or PDF. +* Texinfo:: Publish entries to Texinfo format or PDF. +* XML:: Publish entries to XML. + +Integrating Muse and pyblosxom.cgi + +* Blosxom Requirements:: Other tools needed for the Blosxom style. +* Blosxom Entries:: Format of a Blosxom entry and automation. +* Blosxom Options:: Blosxom styles and options provided. + +Making your own publishing styles + +* Markup Functions:: Specifying functions to mark up text. +* Markup Regexps:: Markup rules for publishing. +* Markup Strings:: Strings specific to a publishing style. +* Markup Tags:: Tag specifications for special markup. +* Style Elements:: Parameters used for defining styles. +* Deriving Styles:: Deriving a new style from an existing + one. + +Miscellaneous add-ons, like a minor mode + +* Muse List Edit Minor Mode:: Edit lists easily in other major modes. + +@end detailmenu +@end menu + +@node Preface, Introduction, Top, Top +@comment node-name, next, previous, up +@chapter About the documentation + +This document describes Muse, which was written by John Wiegley and is +now maintained by Michael Olson. Several versions of this manual are +available on-line. + +@itemize @bullet +@item PDF: http://mwolson.org/static/doc/muse.pdf +@item HTML (single file): http://mwolson.org/static/doc/muse.html +@item HTML (multiple files): http://mwolson.org/static/doc/muse/ +@end itemize + +@node Introduction, Obtaining Muse, Preface, Top +@comment node-name, next, previous, up +@chapter What is Muse? + +Emacs Muse (also known as ``Muse'' or ``Emacs-Muse'') is an authoring +and publishing environment for Emacs. It simplifies the process of +writing documents and publishing them to various output formats. + +Muse consists of two main parts: an enhanced text-mode for authoring +documents and navigating within Muse projects, and a set of publishing +styles for generating different kinds of output. + +What makes Muse distinct from other text-publishing systems is a modular +environment, with a rather simple core, in which "styles" are derived +from to create new styles. Much of Muse's overall functionality is +optional. For example, you can use the publisher without the +major-mode, or the mode without doing any publishing; or if you don't +load the Texinfo or LaTeX modules, those styles won't be available. + +The Muse codebase is a departure from emacs-wiki.el version 2.44. The +code has been restructured and rewritten, especially its publishing +functions. The focus in this revision is on the authoring and +publishing aspects, and the "wikiness" has been removed as a default +behavior (available in the optional @file{muse-wiki} module). CamelCase +words are no longer special by default. + +One of the principal aims in the development of Muse is to make it very +easy to produce good-looking, standards-compliant documents. + +@node Obtaining Muse, Installation, Introduction, Top +@comment node-name, next, previous, up +@chapter How to Get Muse Releases and Development Changes + +@menu +* Releases:: Released versions of Muse. +* Development:: Latest unreleased development changes. +@end menu + +@node Releases, Development, Obtaining Muse, Obtaining Muse +@comment node-name, next, previous, up +@section Released versions of Muse + +Choose to install a release if you want to minimize risk. + +Errors are corrected in development first. User-visible changes will be +announced on the @email{muse-el-discuss@@gna.org} mailing list. +@xref{Getting Help and Reporting Bugs}. + +@cindex releases, Debian package +@cindex Debian package for Muse +Debian users can get Muse via apt-get. The @file{muse-el} package is +available both at Michael Olson's APT repository and the official Debian +repository. To make use of the former, add the following line to your +@file{/etc/apt/sources.list} file and run @code{apt-get install muse}. + +@example +deb http://mwolson.org/debian/ ./ +@end example + +@cindex releases, Ubuntu package +@cindex Ubuntu package for Muse +Ubuntu users can also get Muse via apt-get. The @file{muse-el} package +is available both at Michael Olson's APT repository and the official +Ubuntu repository. To make use of the former, add the following line to +your @file{/etc/apt/sources.list} file and run @code{apt-get install +muse}. + +@example +deb http://mwolson.org/ubuntu/ ./ +@end example + +The reason for making separate Debian and Ubuntu packages is that this +manual is under the GFDL, and Debian will not allow it to be distributed +in its main repository. Ubuntu, on the other hand, permits this manual +to be included with the @file{muse-el} package. + +@cindex releases, from source +Alternatively, you can download the latest release from +@uref{http://download.gna.org/muse-el/} . + +@node Development, , Releases, Obtaining Muse +@comment node-name, next, previous, up +@section Latest unreleased development changes +@cindex development + +Choose the development version if you want to live on the bleeding edge +of Muse development or try out new features before release. + +@cindex git version control system, using +The git version control system allows you to keep up-to-date with the +latest changes to the development version of Muse. It also allows you +to contribute changes (via commits, if you are have developer access to +the repository, or via patches, otherwise). If you would like to +contribute to Muse development, it is highly recommended that you use +git. + +If you are new to git, you might find this tutorial helpful: +@uref{http://www.kernel.org/pub/software/scm/git/docs/tutorial.html}. + +Downloading the Muse module with git and staying up-to-date involves +the following steps. + +@enumerate +@item Install git. + +@itemize @bullet +@item Debian and Ubuntu: @kbd{apt-get install git-core}. +@item Windows: @uref{http://git.or.cz/gitwiki/WindowsInstall}. +@item Other operating systems: download, compile, and install the source +from @uref{http://www.kernel.org/pub/software/scm/git/}, or find a git +package for your operating system. +@end itemize + +@item Download the Muse development branch. + +If you have developer access to Muse, do: + +@example +git clone ssh://repo.or.cz/srv/git/muse-el.git muse +@end example + +otherwise, do: + +@example +git clone git://repo.or.cz/muse-el.git muse +@end example + +If you are behind a restrictive firewall, and do not have developer +access, then do the following instead: + +@example +git clone http://repo.or.cz/r/muse-el.git muse +@end example + +@item List upstream changes that are missing from your local copy. +Do this whenever you want to see whether new changes have been committed +to Muse. If you wish, you may skip this step and proceed directly to +the ``update'' step. + +@example +# Change to the source directory you are interested in. +cd muse + +# Fetch new changes from the repository, but don't apply them yet +git fetch origin + +# Display log messages for the new changes +git log HEAD..origin +@end example + +``origin'' is git's name for the location where you originally got Muse +from. You can change this location at any time by editing the +@file{.git/config} file in the directory where the Muse source was +placed. + +@cindex updating Muse with git +@item Update to the latest version by pulling in any missing changes. + +@example +cd muse +git pull origin +@end example + +git will show how many files changed, and will provide a visual display +for how many lines were changed in each file. + +@end enumerate + +There are other ways to interact with the Muse repository. + +@itemize +@item Browse git repo: @uref{http://repo.or.cz/w/muse-el.git} +@item Latest development snapshot: @uref{http://mwolson.org/static/dist/muse-latest.tar.gz} +@item Latest development snapshot (zip file): @uref{http://mwolson.org/static/dist/muse-latest.zip} +@end itemize + +The latest development snapshot can lag behind the git repo by as much +as 20 minutes, but never more than that. + +@subheading Becoming a Muse developer +@cindex developer, becoming + +If you want commit access to the shared Muse repository, then register +an account at @uref{http://repo.or.cz} (be sure to add an SSH key), and +contact the current maintainer at @email{mwolson@@gnu.org}. It would be +best to send some patches to the @email{muse-el-discuss@@gna.org} +mailing list first, so that he knows that you know what you are doing. +@xref{Getting Help and Reporting Bugs}, for instructions on subscribing +to the mailing list. + +You must also be willing to sign a copyright assignment for your changes +to Muse, since Muse is a GNU project. The current maintainer will +assist you in this process if you contact him. + +For information on committing changes to Muse and performing +development, please consult +@uref{http://emacswiki.org/cgi-bin/wiki/MuseDevelopment}. + +@node Installation, Getting Started, Obtaining Muse, Top +@comment node-name, next, previous, up +@chapter Compiling and Installing Muse + +Muse may be compiled and installed on your machine. + +@subheading Compilation +@cindex compiling Muse + +This is an optional step, since Emacs Lisp source code does not +necessarily have to be byte-compiled. Byte-compilation may yield a very +slight speed increase. + +A working copy of Emacs or XEmacs is needed in order to compile Emacs +Muse. By default, the program that is installed with the name +@command{emacs} will be used. + +If you want to use the @command{xemacs} binary to perform the +compilation, you must copy @file{Makefile.defs.default} to +@file{Makefile.defs} in the top-level directory, and then edit +@file{Makefile.defs} as follows. You can put either a full path to an +Emacs or XEmacs binary or just the command name, as long as it is in the +@env{PATH}. + +@example +EMACS = xemacs +SITEFLAG = -no-site-file +# Edit the section as necessary +install_info = install-info --section "XEmacs 21.4" $(1).info \ + $(INFODIR)/dir || : +@end example + +Running @code{make} in the top-level directory should compile the Muse +source files in the @file{lisp} directory, and generate an autoloads +file in @file{lisp/muse-autoloads.el}. + +@subheading Installation +@cindex installing Muse + +Muse may be installed into your file hierarchy by doing the following. + +Copy @file{Makefile.defs.default} to @file{Makefile.defs} in the +top-level directory, if you haven't done so already. Then edit the +@file{Makefile.defs} file so that @env{ELISPDIR} points to where you +want the source and compiled Muse files to be installed and +@env{INFODIR} indicates where to put the Muse manual. You may use a +combination of @env{DESTDIR} and @env{PREFIX} to further determine where +the installed files should be placed. As mentioned earlier, you will +want to edit @env{EMACS} and @env{SITEFLAG} as shown in the Compilation +section if you are using XEmacs. + +If you are installing Muse on a Debian or Ubuntu system, you might want +to change the value of @env{INSTALLINFO} as specified in +@file{Makefile.defs}. + +If you wish to install Muse to different locations than the defaults +specify, edit @file{Makefile.defs} accordingly. + +Run @code{make} as a normal user, if you haven't done so already. + +Run @code{make install} as the root user if you have chosen installation +locations that require root permissions. + +@subheading ELPA +@cindex ELPA package for Muse + +For those used to installing software packages, there will be a +@code{muse} package available in the Emacs Lisp Package Archive +(abbreviated ``ELPA'') as of the 3.10 release of Muse. This package +will be compiled and installed automatically in a user-specific +location. For more information on ELPA, see +@uref{http://tromey.com/elpa/}. + +@node Getting Started, Projects, Installation, Top +@comment node-name, next, previous, up +@chapter Getting Started +@cindex settings + +@menu +* Loading Muse:: How to load Muse. +* Using Muse Mode:: How to edit files in Muse. +* Publishing Files Overview:: Publishing a single file or project. +* File Extensions:: Using a different file extension. +@end menu + +@node Loading Muse, Using Muse Mode, Getting Started, Getting Started +@comment node-name, next, previous, up +@section How to Load Muse +@cindex settings, init file + +To use Muse, add the directory containing its files to your +@code{load-path} variable, in your @file{.emacs} file. Then, load in +the authoring mode, and the styles you wish to publish to. An example +follows. + +@lisp +(add-to-list 'load-path "") + +(require 'muse-mode) ; load authoring mode + +(require 'muse-html) ; load publishing styles I use +(require 'muse-latex) +(require 'muse-texinfo) +(require 'muse-docbook) + +(require 'muse-project) ; publish files in projects +@end lisp + +An easy way of seeing which settings are available and changing settings +is to use the Muse customization interface. To do this, type +@kbd{M-x customize-group muse RET}. Each of the options has its own +documentation. Options are grouped logically according to what effect +they have. + +@node Using Muse Mode, Publishing Files Overview, Loading Muse, Getting Started +@comment node-name, next, previous, up +@section How to Edit Files in Muse +@cindex editing Muse files + +Muse Mode should automatically be activated when you visit a file with a +``.muse'' extension. One such file is @file{QuickStart.muse}, which is +available in the @file{examples} directory of the Muse distribution. +You can tell that Muse Mode has been activated by checking for the text +``Muse'' in your mode line. If Muse Mode has not been activated, you +may activate it by type @kbd{M-x muse-mode RET}. + +You will notice that Muse files are highlighted very simply. Links are +colored blue, headings are large and bold text, and @verb{||} +tags are colored in grey. + +There are several different ways to edit things like links, which hide +the underlying Muse markup. One way is to toggle font-locking off by +hitting @kbd{C-c C-l}, which is also @kbd{M-x font-lock-mode}, make +changes, and then hit @kbd{C-c C-l} again to toggle font-locking back +on. Another way is just to move into the text and edit it. Markup can +also be removed by normal deletion methods, though some side effects +might require a second deletion. + +For the particular case of editing links, it is easiest to move to the +link and do @kbd{C-c C-e}, which is also @kbd{M-x +muse-edit-link-at-point}. This prompts you for the link and its +description, using the previous contents of the link as initial values. +A link to another Muse file may be created by hitting @kbd{C-c TAB l}. +A link to a URL may be created by hitting @kbd{C-c TAB u}. Links may be +followed by hitting @kbd{RET} on them. + +If you want to add a new list item, this may by accomplished by hitting +@kbd{M-RET}. This will put a dash and some spaces on the screen. The +dash is the Muse markup that indicates a list item. It is also possible +to created ``nested'' lists with this command, by adjusting the number +of spaces in front of the dashes. If you have lists with long lines, +you can move to a list item and hit @kbd{M-q} to wrap it onto multiple +lines. + +@node Publishing Files Overview, File Extensions, Using Muse Mode, Getting Started +@comment node-name, next, previous, up +@section Publishing a Single File or Project +@cindex editing Muse files + +The command @kbd{M-x muse-project-publish-this-file} will publish the +current document to any available publishing style (a publishing style +is an output format, like HTML or Docbook), placing the output in the +current directory. If you are in Muse Mode, this command will be bound +to @kbd{C-c C-t}. If the file has been published recently, and its +contents have not changed, running @kbd{C-c C-t} again will not publish +the file. To force publishing in this case, do @kbd{C-u C-c C-t}. + +If you have set up projects and are visiting a file that is part of a +project, then @kbd{C-c C-t} will restrict the output formats to those +which are used by the project, and will automatically publish to the +output directory defined by the project. If you want to publish to a +different directory or use a different format, then use @kbd{C-c M-C-t}, +which is also @kbd{M-x muse-publish-this-file}. + +If the currently opened file is part of a defined project in +@code{muse-project-alist}, it (and the rest of the changed files in a +project) may be published using @kbd{C-c C-p}. + +@node File Extensions, , Publishing Files Overview, Getting Started +@comment node-name, next, previous, up +@section Using a Different File Extension +@cindex file extension, specifying + +By default, Muse expects all project files to have the file extension +@file{.muse}. Files without this extension will not be associated with +Muse mode and will not be considered part of any project, even if they +are within a project directory. + +If you don't want to use @file{.muse}, you can customize the extension +by setting the value of @code{muse-file-extension}. + +If you don't want to use any extension at all, and want Muse to +autodetect project files based on their location, then add the following +to your Muse settings file. + +@lisp +(setq muse-file-extension nil + muse-mode-auto-p t) +@end lisp + +Note that if you chose to have @code{muse-file-extension} set to +@code{nil}, you may have trouble if your @file{.emacs} file or other +init scripts attempt to visit a Muse file. (A very common example of +this is if you use Planner with Muse and run @code{(plan)} from your +@file{.emacs}.) If you wish to visit Muse files from your +@file{.emacs}, be sure to also add the following additional code before +any such visits happen: + +@lisp +(add-hook 'find-file-hooks 'muse-mode-maybe) +@end lisp + + +@node Projects, Keystroke Summary, Getting Started, Top +@comment node-name, next, previous, up +@chapter Creating and Managing Muse Projects +@cindex projects + +Often you will want to publish all the files within a directory to a +particular set of output styles automatically. To support, Muse +allows for the creation of "projects". + +@menu +* Single Project:: A single-project example. +* Multiple Projects:: A multiple-project example. +* Projects and Subdirectories:: Publishing subdirectories in projects. +* Options for Projects:: Listing of available options for projects. +@end menu + +@node Single Project, Multiple Projects, Projects, Projects +@comment node-name, next, previous, up +@section A Single-Project Example +@cindex projects, single + +Here is a sample project, which may be defined in your @file{.emacs} +file. + +@lisp +(setq muse-project-alist + '(("Website" ("~/Pages" :default "index") + (:base "html" :path "~/public_html") + (:base "pdf" :path "~/public_html/pdf")))) +@end lisp + +The above defines a project named "website", whose files are located +in the directory @file{~/Pages}. The default page to visit is +@file{index}. When this project is published, each page will be +output as HTML to the directory @file{~/public_html}, and as PDF to +the directory @file{~/public_html/pdf}. Within any project page, you +may create a link to other pages using the syntax @samp{[[pagename]]}. + +If you would like to include only some files from a directory in a Muse +project, you may use a regexp in place of @file{~/Pages} in the example. + +@node Multiple Projects, Projects and Subdirectories, Single Project, Projects +@comment node-name, next, previous, up +@section A Multiple-Project Example +@cindex projects, multiple + +It is possible to specify multiple projects. Here is an example of +three projects: a generic website, a projects area, and a day-planner +(the day-planner part requires Planner Mode---see +@uref{http://wjsullivan.net/PlannerMode.html} to get it). + +@lisp +(setq muse-project-alist + '(("Website" ("~/Pages" :default "index") + (:base "html" :path "~/public_html")) + (("Projects" ("~/Projects" :default "index") + (:base "xhtml" + :path "~/public_html/projects" + :exclude "/TopSecret") + (:base "pdf" + :path "~/public_html/projects/pdf" + :exclude "/TopSecret"))) + ("Plans" ("~/Plans" + :default "TaskPool" + :major-mode planner-mode + :visit-link planner-visit-link) + (:base "planner-xhtml" + :path "~/public_html/plans")))) +@end lisp + +The @option{:major-mode} attribute specifies which major to use when +visiting files in this directory. + +The @option{:visit-link} attribute specifies the function to call when +visiting links. + +The @option{:exclude} attribute has a regexp that matches files to never +publish. + +@node Projects and Subdirectories, Options for Projects, Multiple Projects, Projects +@comment node-name, next, previous, up +@section Publishing Subdirectories in Projects +@cindex projects, subdirectories + +If you want to publish a directory and all of its subdirectories, Muse +provides two convenience functions that together generate the proper +rules for you. Note that we use the backtick to begin this +muse-project-alist definition, rather than a single quote. + +@lisp +(setq muse-project-alist + `(("Website" ("~/Pages" :default "index") + (:base "html" :path "~/public_html")) + ("Blog" (,@@(muse-project-alist-dirs "~/Blog") + :default "index") + ;; Publish this directory and its subdirectories. Arguments + ;; are as follows. The above `muse-project-alist-dirs' part + ;; is also needed. + ;; 1. Source directory + ;; 2. Output directory + ;; 3. Publishing style + ;; remainder: Other things to put in every generated style + ,@@(muse-project-alist-styles "~/Blog" + "~/public_html/blog" + "blosxom")))) +@end lisp + +The @code{muse-project-alist-dirs} function takes a directory and +returns it and all of its subdirectories in a list. + +The @code{muse-project-alist-styles} function is explained by the +comments above. + +The ``blosxom'' text is the name of another publishing style, much like +``html''. @xref{Blosxom}, for further information about it. You can +use any publishing style you like for the third argument to +@code{muse-project-alist-styles}. + +@node Options for Projects, , Projects and Subdirectories, Projects +@comment node-name, next, previous, up +@section Listing of Available Options for Projects +@cindex projects, options +@cindex muse-project-alist, reference + +This is a listing of all of the various options (or, more accurately: +attributes) that may be specified in @code{muse-project-alist}. + +Each muse-project-alist entry looks like this: + +@example + (PROJECT-NAME (SOURCES) + OUTPUTS) +@end example + +We refer to these names below. + +``Attributes'', which compose SOURCES and OUTPUTS, are a pair of values. +The first value is a keyword, like @option{:default}. The second part +is the value associated with that keyword, such as the text ``index''. +If you are familiar with Emacs Lisp property lists, the concept is +similar to that, except that in the SOURCES section, single directories +can be interspersed with two-value attributes. + +@subheading Project Name + +This is a string that indicates the name of the project. It is +primarily used for publishing interwiki links with the +@file{muse-wiki.el} module. + +@subheading Sources + +This part of a muse-project-alist entry consists of two-value +attributes, and also directory names. If you are publishing a book, the +order of directories and attributes is significant. + +The minimal content for the sources section is a list of directories. + +@table @option + +@item :book-chapter +Indicates a new chapter of a book. The text of the title of the chapter +comes immediately after this keyword. + +@item :book-end +Indicates the end of a book. Directories listed after this one are +ignored when publishing a book. The value ``t'' (without quotes) should +come immediately after this keyword. + +@item :book-funcall +A function to call while publishing a book. This is useful for doing +something just after a particular chapter. + +@item :book-part +Indicates the beginning of a new part of the book. The text of the +title should come immediately after this keyword. + +@item :book-style +Indicate a particular publishing style to use for this part of the book. +If this is specified, it should come just after a @option{:part} +attribute. + +@item :default +The default page to visit when browsing a project. Also, if you are +using the @file{muse-wiki.el} module, publishing a link to just a +project's name will cause it to link to this default file. + +@item :force-publish +This specifies a list of pages which should be published every time a +project is published (by using @kbd{C-c C-p}, for example), regardless +of whether their contents have changed. This is useful for updating +Index pages, pages that use the @verb{||} tag, and other pages +that have dynamically-generated content. + +@item :major-mode +This specifies the major mode to use when visiting files in this +project. The default is @code{muse-mode}. + +@item :nochapters +This indicates that while publishing a book, do not automatically create +chapters. Values which may follow this are nil (the default, which +means that we automatically create chapters), or non-nil, which means +that we manually specify chapters with the @option{:book-chapter} +attribute, + +@item :publish-project +Indicates which function we should call when publishing a project. + +@item :set +This specifies a list of variables and values to set when publishing a +project. The list should be a property list, which is in the form: + +@example +(VAR1 VALUE1 VAR2 VALUE2 ...) +@end example + +@item :visit-link +Specifies the function to call when visiting a link. The default is +@code{muse-visit-link-default}. The arguments for that function should +be (1) the link and (2) whether to visit the link in a new window. + +@end table + +@subheading Outputs + +This part of a muse-project-alist entry is composed of lists of +attributes. Each list is called an ``output style''. + +The minimal content for an output style is a @option{:base} attribute +and a @option{:path} attribute. + +@table @option + +@item :base +Publishing style to use, such as ``html'', ``docbook'', or ``pdf''. + +@item :base-url +An external URL which can be used to access published files. This is +mainly used by the @file{muse-wiki} module when publishing links between +two separate projects, if the projects are served on different domains. + +It is also used by the @file{muse-journal} module to create the RSS or +RDF output. + +@item :exclude +Exclude items matching a regexp from being published. The regexp should +usually begin with "/". + +@item :include +Only include items matching a regexp when publishing. The regexp should +usually begin with "/". + +@item :path +The directory in which to store published files. + +@item :timestamps +A file containing the timestamps (that is, time of creation) for files +in this project. It might eventually used by the @file{muse-blosxom} +module, but this option is not currently in use by any Muse code. + +@end table + + +@node Keystroke Summary, Markup Rules, Projects, Top +@comment node-name, next, previous, up +@chapter Keys Used in Muse Mode +@cindex keystrokes + +This is a summary of keystrokes available in every Muse buffer. + +@table @kbd + +@item C-c C-a (`muse-index') +Display an index of all known Muse pages. + +@item C-c C-b (`muse-find-backlinks') +Find all pages that link to this page. + +@item C-c C-e (`muse-edit-link-at-point') +Edit link at point. + +@item C-c C-f (`muse-project-find-file') +Open another Muse page. Prompt for the name. + +@item C-c C-i l, C-c TAB l (`muse-insert-relative-link-to-file') +Insert a link to a file interactively. + +@item C-c C-i t, C-c TAB t (`muse-insert-tag') +Insert a tag interactively. + +@item C-c C-i u, C-c TAB u (`muse-insert-url') +Insert a URL interactively. + +@item C-c C-l (`font-lock-mode') +Toggle font lock / highlighting for the current buffer. + +@item C-c C-p (`muse-project-publish') +Publish any Muse pages that have changed. + +@item C-c C-s (`muse-search') +Find text in all files of the current project. + +@item C-c C-t (`muse-project-publish-this-file') +Publish the currently-visited file. Prompt for the style if the current +file can be published using more than one style. + +@item C-c C-S-t, or C-c C-M-t (`muse-publish-this-file') +Publish the currently-visited file. Prompt for both the style and +output directory. + +@item C-c C-v (`muse-browse-result') +Show the published result of this page. + +@item C-c = (`muse-what-changed') +Diff this page against the last backup version. + +@item TAB +Move to the next Wiki reference. + +@item S-TAB +Move to the previous Wiki reference. + +@item M-TAB +Complete the name of a page from the current project at point. + +@item M-RET +Insert a new list item at point, indenting properly. + +@item C-< +Decrease the indentation of the list item at point. + +@item C-> +Increase the indentation of the list item at point. + +@item M-x muse-colors-toggle-inline-images RET +Toggle display of inlined images on/off. + +@item M-x muse-update-values RET +Update various values that are automatically generated. + +Call this after changing @code{muse-project-alist}. +@end table + + +@node Markup Rules, Publishing Styles, Keystroke Summary, Top +@comment node-name, next, previous, up +@chapter Rules for Using Markup +@cindex markup + +A Muse document uses special, contextual markup rules to determine how +to format the output result. For example, if a paragraph is indented, +Muse assumes it should be quoted. + +There are not too many markup rules, and all of them strive to be as +simple as possible so that you can focus on document creation, rather +than formatting. + +@menu +* Paragraphs:: Paragraphs: centering and quoting. +* Headings:: Levels of headings. +* Directives:: Directives at the beginning of a + document. +* Emphasizing Text:: Bold, italicized, and underlined text. +* Footnotes:: Making notes to be shown at the end. +* Verse:: Indicating poetic stanzas. +* Lists:: Lists of items. +* Tables:: Generation of data tables. +* Explicit Links:: Hyperlinks and email addresses with + descriptions. +* Implicit Links:: Bare URLs, WikiNames, and InterWiki + links. +* Images:: Publishing and displaying images. +* Horizontal Rules and Anchors:: Inserting a horizontal line or anchor. +* Embedded Lisp:: Evaluating Emacs Lisp code in documents + for extensibility. +* Citations:: Support for citing other resources. +* Comments:: Lines to omit from published output. +* Tag Summary:: Tags that Muse recognizes. +@end menu + +@node Paragraphs, Headings, Markup Rules, Markup Rules +@comment node-name, next, previous, up +@section Paragraphs: centering and quoting +@cindex paragraphs + +Paragraphs in Muse must be separated by a blank line. + +@cindex paragraphs, centered +@subheading Centered paragraphs and quotations + +A line that begins with six or more columns of whitespace (either tabs +or spaces) indicates a centered paragraph. Alternatively, you can use +the @verb{|
    |} tag to surround regions that are to be published +as centered paragraphs. + +@cindex paragraphs, quoted +@cindex quotations +But if a line begins with whitespace, though less than six columns, it +indicates a quoted paragraph. Alternatively, you can use the +@verb{||} tag to surround regions that are to be published as +quoted paragraphs. + +@cindex examples +@cindex monospace, rendering blocks +@cindex HTML, rendering blocks in monospace +@subheading Literal paragraphs + +The @verb{||} tag is used for examples, where whitespace should +be preserved, the text rendered in monospace, and any characters special +to the output style escaped. + +@cindex literal text +@cindex HTML, inserting a raw block +There is also the @verb{||} tag, which causes a marked block to +be entirely left alone. This can be used for inserting a hand-coded +HTML blocks into HTML output, for example. + +If you want some text to only be inserted when publishing to a +particular publishing style, use the @option{style} attribute for the +@verb{||} tag. An example follows. + +@example + +A LaTeX-based style was used in the publishing of this document. + +@end example + +This will leave the region alone if the current publishing style is +``latex'' or based on ``latex'', such as ``pdf'', and delete the region +otherwise. It is also possible to leave the text alone only for one +particular style, rather than its derivations, by adding +@code{exact="t"} to the tag. + +@cindex line breaks +@subheading Line breaks + +If you need a line break, then use the @samp{
    } tag. Most of the +time this tag is unnecessary, because Muse will automatically detect +paragraphs by means of blank lines. If you want to preserve newlines in +several lines of text, then use verse markup instead (@pxref{Verse}). + +@node Headings, Directives, Paragraphs, Markup Rules +@comment node-name, next, previous, up +@section Levels of headings +@cindex headings + +A heading becomes a chapter or section in printed output -- depending on +the style. To indicate a heading, start a new paragraph with one or +more asterices, followed by a space and the heading title. Then begin +another paragraph to enter the text for that section. + +All levels of headings will be published. Most publishing styles only +distinguish the between the first 4 levels, however. + +@example +* First level + +** Second level + +*** Third level + +**** Fourth level +@end example + +@node Directives, Emphasizing Text, Headings, Markup Rules +@comment node-name, next, previous, up +@section Directives at the beginning of a document +@cindex directives + +Directives are lines beginning with the @samp{#} character that come +before any paragraphs or sections in the document. Directives are of +the form ``#directive content of directive''. You can use any +combination of uppercase and lowercase letters for directives, even if +the directive is not in the list below. + +The @code{muse-publishing-directive} function may be used in header and +footer text to access directives. For example, to access the +@code{#title} directive, use @code{(muse-publishing-directive "title")}. + +The following is a list of directives that Muse uses. + +@table @code +@cindex #author +@item #author +The author of this document. + +If this is not specified, Muse will attempt to figure it out from the +@code{user-full-name} variable. + +@cindex #date +@item #date +The date that the document was last modified. + +This is used by publishing styles that are able to embed the date +information. + +@cindex #desc +@item #desc +A short description of this document. + +This is used by the @code{journal} publishing style to embed information +inside of an RSS/RDF feed. + +@cindex #title +@item #title +The title of this document. + +If this is not specified, the name of the file is used. + +@end table + +@node Emphasizing Text, Footnotes, Directives, Markup Rules +@comment node-name, next, previous, up +@section Bold, italicized, and underlined text +@cindex emphasizing text +@cindex underlining text +@cindex italicizing text +@cindex verbatim text +@cindex monospace, rendering words + +To emphasize text, surround it with certain specially recognized +characters. + +@example +*emphasis* +**strong emphasis** +***very strong emphasis*** +_underlined_ +=verbatim and monospace= +@end example + +@cindex WYSIWYG +While editing a Muse document in Muse mode, these forms of emphasis will +be highlighted in a WYSIWYG manner. Each of these forms may span +multiple lines. + +Verbatim text will be colored as gray by default. To change this, +customize @code{muse-verbatim-face}. + +You can also use the @verb{||} tag to indicate verbatim and +monospace text. This is handy for regions that have an ``='' in them. + +@node Footnotes, Verse, Emphasizing Text, Markup Rules +@comment node-name, next, previous, up +@section Making notes to be shown at the end +@cindex footnotes + +A footnote reference is simply a number in square brackets. To define +the footnote, place this definition at the bottom of your file. +@samp{footnote-mode} can be used to greatly facilitate the creation of +these kinds of footnotes. + +Footnotes are defined by the same number in brackets occurring at the +beginning of a line. Use footnote-mode's @kbd{C-c ! a} command, to very +easily insert footnotes while typing. Use @kbd{C-x C-x} to return to +the point of insertion. + +@node Verse, Lists, Footnotes, Markup Rules +@comment node-name, next, previous, up +@section Indicating poetic stanzas +@cindex verses +@cindex poetry + +Poetry requires that whitespace be preserved, but without resorting to +monospace. To indicate this, use the following markup, reminiscent of +email quotations. + +@example +> A line of Emacs verse; +> forgive its being so terse. +@end example + +You can also use the @verb{||} tag, if you prefer. + +@example + +A line of Emacs verse; + forgive its being so terse. + +@end example + +@cindex verses, multiple stanzas +Multiple stanzas may be included in one set of @verb{||} tags, as +follows. + +@example + +A line of Emacs verse; + forgive its being so terse. + +In terms of terse verse, + you could do worse. + +@end example + +@node Lists, Tables, Verse, Markup Rules +@comment node-name, next, previous, up +@section Lists of items +@cindex lists + +Lists are given using special characters at the beginning of a line. +Whitespace must occur before bullets or numbered items, to distinguish +from the possibility of those characters occurring in a real sentence. + +@cindex lists, bullets +These are rendered as a bullet list. + +@example +Normal text. + + - bullet item one + - bullet item two +@end example + +@cindex lists, enumerated +An enumerated list follows. + +@example +Normal text. + + 1. Enum item one + 2. Enum item two +@end example + +@cindex lists, definitions +Here is a definition list. + +@example +Term1 :: + This is a first definition + And it has two lines; + no, make that three. + +Term2 :: This is a second definition +@end example + +@subheading Nested lists + +@cindex lists, nested +It is possible to nest lists of the same or different kinds. The +``level'' of the list is determined by the amount of initial whitespace. + +@example +Normal text. + + - Level 1, bullet item one + 1. Level 2, enum item one + 2. Level 2, enum item two + - Level 1, bullet item two + 1. Level 2, enum item three + 2. Level 2, enum item four + term :: definition +@end example + +@subheading Breaking list items + +@cindex lists, breaking lines +If you want to break up a line within any list type, just put one blank +line between the end of the previous line and the beginning of the next +line, using the same amount of initial indentation. + +@example + - bullet item 1, line 1 + + bullet item 1, line 2 + + 1. Enum line 1 + + Enum line 2 + + - bullet item 2, line 1 + + bullet item 2, line 2 +@end example + +@node Tables, Explicit Links, Lists, Markup Rules +@comment node-name, next, previous, up +@section Generation of data tables +@cindex tables + +@cindex tables, simple +Only very simple tables are supported. The syntax is as follows. + +@example +Double bars || Separate header fields + +Single bars | Separate body fields +Here are more | body fields + +Triple bars ||| Separate footer fields +@end example + +Some publishing styles require header fields to come first, then footer +fields, and then the body fields. You can use any order for these +sections that you like, and Muse will re-order them for you at +publish-time. + +If you wish to disable table generation for one Muse file, add the +directive @samp{#disable-tables t} to the top of the file. + +@subheading Other table formats + +@cindex tables, orgtbl-mode style +It is possible to publish very basic Orgtbl-mode style tables. + +@example +| org | style | table | +|------+-------+-------| +| one | | one | +| two | two | | +| | three | three | +|------+-------+-------| +| more | stuff | | +@end example + +If you are used to the way that Org Mode publishes these tables, then +customize `muse-html-table-attributes' to the following, in order to get +a similar kind of output. + +@example +border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides" +@end example + +@cindex tables, table.el style +@file{table.el} style tables are also supported, as long as +@file{table.el} itself supports outputting tables for a particular +publishing style. At the time of this writing, the ``html'', ``latex'', +and ``docbook'' styles are supported by @file{table.el}. Styles derived +from these styles will also work. + +@example ++---+-----+---+ +| | one | 1 | ++---+-----+---+ +| b | two | | ++---+-----+---+ +| c | | 3 | ++---+-----+---+ +@end example + +@node Explicit Links, Implicit Links, Tables, Markup Rules +@comment node-name, next, previous, up +@section Hyperlinks and email addresses with descriptions +@cindex links, explicit + +A hyperlink can reference a URL, or another page within a Muse +project. In addition, descriptive text can be specified, which should +be displayed rather than the link text in output styles that supports +link descriptions. The syntax is as follows. + +@example +[[link target][link description]] +[[link target without description]] +@end example + +Thus, the current maintainer's homepage for Muse can be found +@samp{[[http://mwolson.org/projects/EmacsMuse.html][here]]}, +or at @samp{[[http://mwolson.org/projects/EmacsMuse.html]]}. + +@node Implicit Links, Images, Explicit Links, Markup Rules +@comment node-name, next, previous, up +@section Bare URLs, WikiNames, and InterWiki links +@cindex links, implicit +@cindex links, raw + +@cindex URLs +@cindex Email addresses + +A URL or email address encountered in the input text is published as a +hyperlink. These kind of links are called @dfn{implicit links} because +they are not separated from the rest of the Muse document in any way. + +Some characters in URLs will prevent Muse from recognizing them as +implicit links. If you want to link to a URL containing spaces or any of +the characters ``][,"'`()<>^'', you will have to make the link +explicit. The punctuation characters ``.,;:'' are also not recognized as +part of a URL when they appear at its end. For information on how to +make an explicit link, see @ref{Explicit Links,,Hyperlinks and email +addresses with descriptions}. + +@cindex WikiNames +If the @command{muse-wiki} module is loaded, another form of implicit +link will be made available. WikiNames, which are typed in CamelCase, +are highlighted and published as links, provided that the file they +refer to exists. + +Customization of WikiName recognition may be accomplished by editing the +@code{muse-wiki-wikiword-regexp} option and subsequently running +@code{(muse-configure-highlighting 'muse-colors-markupmuse-colors-markup)}. +If you use the Customize interface, the latter will be done +automatically. + +@cindex InterWiki links +@cindex inter-project links +The @command{muse-wiki} module also allows for InterWiki links. These +are similar to WikiWords, but they specify both the project and page of +a file. The names of your project entries in @code{muse-project-alist} +will be used as InterWiki names by default. Several examples follow. + +@example +Blog::DocumentingMuse +Projects#EmacsMuse +Website +@end example + +In the first case, the interwiki delimiter is @samp{::}, @samp{Blog} is +the project name, and @samp{DocumentingMuse} is the page name. In the +second example, @samp{#} is the interwiki delimiter. If the name of a +project occurs by itself in text, like the third case, it will be +colorized and published as a link to the default page of the given +project. + +Customization of interwiki links may be accomplished by editing the +@code{muse-wiki-interwiki-alist} option. + +It is also possible to link to an anchor in an interwiki document. This +is called a ``three-part link''. Examples of this follow. + +@example +Blog::DocumentingMuse#anchor1 +Projects#EmacsMuse#anchor2 +@end example + +@node Images, Horizontal Rules and Anchors, Implicit Links, Markup Rules +@comment node-name, next, previous, up +@section Publishing and displaying images +@cindex images +@cindex links, with images +@subheading Image links + +Links to images may be used in either the target or the description, or +both. Thus, the following code will publish as a clickable image that +points to @url{http://mwolson.org/}. + +@example +[[http://mwolson.org/][/static/logos/site-logo.png]] +@end example + +Normally, images in the link part will be inlined. + +If you want these images to be published as links instead, place the +text ``URL:'' immediately in front of the link text. An example +follows. + +@example +[[URL:http://mwolson.org/static/logos/site-logo.png]] +@end example + +@cindex images, displaying +@cindex images, local +@subheading Displaying images in Muse mode +If a link to a locally-available image is encountered in the link +description, Muse mode will attempt to display it if your version of +Emacs permits this. + +This behavior may be toggled with @kbd{C-c C-i}, or disabled permanently +by setting the @code{muse-colors-inline-images} option to @code{nil}. + +The method for finding images may be altered by customizing the +@code{muse-colors-inline-image-method} option. One useful value for +this option is @code{muse-colors-use-publishing-directory}, which tells +Muse mode to look in the directory where the current file will be +published. The default is to look in the current directory. Relative +paths like @samp{../pics/} should work for either setting. + +Eventually, it is hoped that Muse will be able to copy images from the a +``source'' directory to a publishing directory by customizing +@code{muse-project-alist}, but this has not been implemented yet. + +@cindex images, without descriptions +@cindex images, inlined +@subheading Publishing simple images +The following example will display correctly and publish correctly if a +@acronym{PNG} file called @file{TestLogo.png} exists in the +@file{../pics/} directory. If text is on the same line as the picture, +it will remain so in the output. + +@example +[[../myimage.png]] +@end example + +@cindex images, captions +@subheading Publishing images with captions +If you want to add a caption to an image, use the following syntax. +This will center the image (if the output format supports it) and add a +centered caption below the picture. Formats that do not support +centering the image will instead leave it against the left margin. + +@example +[[../pics/mycat.png][My cat Dexter]] +@end example + +Images with captions may only occur in their own paragraphs, with no +text on the same line. Otherwise, the published output will not be +syntactically correct. + +@node Horizontal Rules and Anchors, Embedded Lisp, Images, Markup Rules +@comment node-name, next, previous, up +@section Inserting a horizontal line or anchor + +@cindex horizontal rules +@cindex dashes +@subheading Horizontal Rules + +Four or more dashes indicate a horizontal rule. Be sure to put blank +lines around it, or it will be considered part of the proceeding or +following paragraph! + +@cindex anchors +@cindex links, with target on same page +@subheading Anchors + +If you begin a line with "#anchor" -- where "anchor" can be any word +that doesn't contain whitespace -- it defines an anchor at that point +into the document. This point can be referenced using "page#anchor" as +the target in a Muse link. + +@node Embedded Lisp, Citations, Horizontal Rules and Anchors, Markup Rules +@comment node-name, next, previous, up +@section Evaluating Emacs Lisp code in documents for extensibility +@cindex lisp, embedded + +Arbitrary kinds of markup can be achieved using the @verb{||} tag. +With the @verb{||} tag, you may generate whatever output text you +wish. The inserted output will get marked up if the @verb{||} +tag appears within the main text of the document. + +@example +(concat "This form gets " "inserted") +@end example + +@cindex lisp, and insert command +Note that you should not use the @code{insert} command within a set of +@verb{||} tags, since the return value from the @verb{||} +tags will be automatically inserted into the document. + +It is also possible to treat the output as if it were surrounded by the +@verb{||}, @verb{||}, or @verb{||} tags, by +specifying ``example'', ``src'', or ``verse'' as the @option{markup} +attribute of the @verb{||} tag. + +@example + +(concat "Insert" " me") + +@end example + +Other languages also have tags that cause source code to be evaluated. +@xref{Tag Summary}, for details. + +@node Citations, Comments, Embedded Lisp, Markup Rules +@comment node-name, next, previous, up +@section Support for citing other resources +@cindex citations +@cindex tags, + +@subheading Example + +Here is an example of what citations look like in a Muse document. + +@example +#bibsource REFDB + +* Title +** Subtitle + +Some text before Miller1999 and after the citation. + +This is an author-only citation Miller1999. + +And this is a year-only citation Miller1999. + +Finally, this is a multi-head citation +Miller1999,Andrews2005. +@end example + +@subheading Overview + +The @code{#bibsource} directive defines the source of the +bibliographies. The following sources are possible. + +@itemize @bullet +@item DocBook + RefDB: +the string "REFDB" + +@item LaTeX + bibtex: +the name of an appropriate bibtex file + +@item LaTeX + RefDB: +if the input file is called "foo.muse", then set this to "foo.bib" +@end itemize + +Citations are encoded as @verb{||} elements which enclose the +citation keys as they are defined in the bibliography file or database. +In multi-head citations, the citation keys have to be separated by +colons or semicolons. The @code{latex} and @code{docbook} styles +translate these to the proper separator automatically. + +The @verb{||} elements take an optional ``type'' attribute that +defines how the citation is rendered. If the attribute is missing, +you'll get a regular citation according to the bibliography style, +e.g.'' (Miller et al., 1999)''. If the attribute is set to "author", +only the name of the author(s) will be rendered. Accordingly, "year" +will cause the year to be printed. This is useful to create citations +like this: + +@example +Miller et al. had already shown in a previous publication (1999) that +this is not going to work. +@end example + +Remember that refdb-mode (the Emacs interface to RefDB) can retrieve +references by simply marking the citation key and running the +@code{refdb-getref-by-field-on-region} command. Later versions of +@code{refdb-mode} will also allow to insert references as Muse citations +(which is already implemented for DocBook, TEI, and LaTeX documents). + +You may have noticed that there is no element to indicate the position +of the bibliography. The latter is always created at a valid position +close to the end of the document. The functions +@code{muse-docbook-bibliography} and @code{muse-latex-bibliography} are +called in the header or footer to generate this content, so it is +possible to change the exact position. + +@node Comments, Tag Summary, Citations, Markup Rules +@comment node-name, next, previous, up +@section Lines to omit from published output +@cindex comments +@cindex publishing, omitting lines + +Use the following syntax to indicate a comment. Comments will not be +published. + +@example +; Comment text goes here. +@end example + +That is, only a semi-colon at the beginning of a line, followed by a +literal space, will cause that line to be treated as a comment. + +You can alternatively surround the region with the @verb{||} +tag. + +If you wish the comment to be published, but just commented out using +the comment syntax of the output format, then set +@option{muse-publish-comments-p} to non-nil. + +@node Tag Summary, , Comments, Markup Rules +@comment node-name, next, previous, up +@section Tags that Muse recognizes +@cindex tags +@cindex inserting files at publish time +@cindex publishing, including markup in headers and footers +@cindex publishing, inserting files + +Muse has several built-in tags that may prove useful during publishing. +@xref{muse-publish-markup-tags}, to see how to customize the tags that +Muse uses, as well as make your own tags. + +Only a small subset of these tags are available in header and footer +text. The @code{muse-publish-markup-header-footer-tags} option lists +the tags that are allowed in headers and footers. + +@subheading Syntax + +If a tag takes arguments, it will look like this, where ``tagname'' is +the name of the tag. + +@example + +@end example + +If you want the tag to look like it came straight from an XHTML +document, you can alternatively do the following. + +@example + +@end example + +If a tag surrounds some text, it will look like this. + +@example +Some text +@end example + +If a tag surrounds a large region, it will look like this. + +@example + +Some text. +Some more text. + +@end example + +@subheading Tag listing + +This is the complete list of tags that Muse accepts, including those +that were mentioned in previous sections. + +@table @samp + +@item
    +Insert a line break. + +Muse will automatically detect paragraphs when publishing by means of +blank lines, so this tag is usually unnecessary. + +@item +Insert a citation to another source. + +This takes the argument @option{type}, which indicates the type of +citation. The valid types are "author" and "year". If this argument is +omitted, include both author and year in the citation. + +The bibliography to use for the citation may be specified by the +@option{#bibsource} directive. + +@xref{Citations}, for additional information. + +@item +If publishing to HTML, surround the given text with a @verb{||} +tag. It takes one argument called ``name'' that specifies the ``class'' +attribute of the @verb{||} tag. + +If publishing to a different format, do nothing extra to the text. + +@item +Treat the text surrounded by the tag as if they were enclosed in equal +signs, that is, make it monospace. + +@item +Run a command on the region, replacing the region with the result of the +command. The command is specified with the ``interp'' argument. If no +value for ``interp'' is given, pass the entire region to the shell. + +The ``markup'' argument controls how this section is marked up. + +If it is omitted, publish the region with the normal Muse rules. + +If "nil", do not mark up the region at all, but prevent Muse from +further interpreting it. + +If "example", treat the region as if it was surrounded by the +@verb{||} tag. + +If "src", treat the included text as if it was surrounded by the +@verb{||} tag. You should also specify the ``lang'' attribute if +doing this. + +If "verse", treat the region as if it was surrounded by the +@verb{||} tag, to preserve newlines. + +Otherwise, it should be the name of a function to call, with the buffer +narrowed to the region. + +@item +Treat the entire region as a comment. If the option +@var{muse-publish-comments-p} is nil, delete the region, otherwise +publish it using the comment syntax of the current publishing style. + +@item +Publish a Table of Contents. This will either be inserted in-place or +at the beginning of the document, depending on your publishing style. +It does not have a delimiting tag. + +By default, only 2 levels of headings will be included in the generated +Table of Contents. To change this globally, customize the +@var{muse-publish-contents-depth} option. To change this only for the +current tag, use the ``depth'' argument. + +@item
    +Insert a
    tag into HTML documents, and do not insert anything +special for other non-HTML publishing formats. + +If the ``style'' argument is provided, include it with the published +@verb{|
    |} tag. Likewise for the ``id'' argument. + +@item +Publish the region in monospace, preserving the newlines in the region. +This is useful for snippets of code. + +@item +Insert the given file at the current location during publishing. The +basic use of this tag is as follows, replacing ``included_file'' with +the name of the file that you want to include. + +@example + +@end example + +The ``markup'' argument controls how this section is marked up. + +If it is omitted, publish the included text with the normal Muse +rules. + +If "nil", do not mark up the included text at all. + +If "example", treat the included text as if it was surrounded by the +@verb{||} tag. + +If "src", treat the included text as if it was surrounded by the +@verb{||} tag. You should also specify the ``lang'' attribute if +doing this. + +If "verse", treat the included text as if it was surrounded by the +@verb{||} tag, to preserve newlines. + +Otherwise, it should be the name of a function to call after inserting +the file with the buffer narrowed to the section inserted. + +@item +Evaluate the Emacs Lisp expressions between the initial and ending tags. +The result is then inserted into the document, so you do not need to +explicitly call @code{insert}. All text properties are removed from the +resulting text. + +This tag takes the ``markup'' argument. See the description of +@verb{||} for details. + +@item +Make sure that the text enclosed by this tag is published without +escaping it in any way. This is useful for inserting markup directly +into the published document, when Muse does not provide the desired +functionality. + +@item +Mark up the text between the initial and ending tags. The markup +command to use may be specified by the ``function'' argument. The +standard Muse markup routines are used by default if no ``function'' +argument is provided. + +This is useful for marking up regions in headers and footers. One +example that comes to mind is generating a published index of all of the +files in the current project by doing the following. + +@example +(muse-index-as-string t t) +@end example + +@item +Run the @command{perl} language interpreter on the region, replacing the +region with the result of the command. + +This tag takes the ``markup'' argument. See the description of +@verb{||} for details. + +@item +Run the @command{python} language interpreter on the region, replacing +the region with the result of the command. + +This tag takes the ``markup'' argument. See the description of +@verb{||} for details. + +@item +Publish the region as a blockquote. This will either be inserted +in-place or at the beginning of the document, depending on your +publishing style. It does not have a delimiting tag. + +@item +Run the @command{ruby} language interpreter on the region, replacing the +region with the result of the command. + +This tag takes the ``markup'' argument. See the description of +@verb{||} for details. + +@item +Publish the region using htmlize. +The language to use may be specified by the ``lang'' attribute. + +Muse will look for a function named @var{lang}-mode, where @var{lang} is +the value of the ``lang'' attribute. + +This tag requires htmlize 1.34 or later in order to work. If this is +not satisfied, or the current publishing style is not HTML-based, Muse +will publish the region like an @verb{||} tag. + +@item +This is used when you want to prevent Muse from trying to interpret some +markup. Surround the markup in @verb{||} and +@verb{||}, and it will not be interpreted. + +This tag was used often in previous versions of Muse because they did +not support whole-document escaping of specials. Now, it will only be +needed for other tags, and perhaps footnotes as well. + +@item +Preserve the newlines in the region. In formats like HTML, newlines are +removed by default, hence the need for this tag. In other publishing +styles, this tag may cause the text to be indented slightly in a way +that looks nice for poetry and prose. + +@end table + +@node Publishing Styles, Extending Muse, Markup Rules, Top +@comment node-name, next, previous, up +@chapter Publishing Various Types of Documents +@cindex publishing styles + +One of the principle features of Muse is the ability to publish a simple +input text to a variety of different output styles. Muse also makes it +easy to create new styles, or derive from an existing style. + +@menu +* Blosxom:: Integrating Muse and pyblosxom.cgi. +* Book:: Publishing entries into a compilation. +* ConTeXt:: Publishing ConTeXt documents. +* DocBook:: Publishing in DocBook XML form. +* HTML:: Publishing in HTML or XHTML form. +* Ikiwiki:: Integrating with ikiwiki. +* Journal:: Keeping a journal or blog. +* LaTeX:: Publishing LaTeX documents. +* Poem:: Publish a poem to LaTeX or PDF. +* Texinfo:: Publish entries to Texinfo format or PDF. +* XML:: Publish entries to XML. +@end menu + +@node Blosxom, Book, Publishing Styles, Publishing Styles +@comment node-name, next, previous, up +@section Integrating Muse and pyblosxom.cgi +@cindex blog, one-file-per-entry style + +The Blosxom publishing style publishes a tree of categorised files to a +mirrored tree of stories to be served by blosxom.cgi or pyblosxom.cgi. +In other words, each blog entry corresponds with one file. + +@menu +* Blosxom Requirements:: Other tools needed for the Blosxom style. +* Blosxom Entries:: Format of a Blosxom entry and automation. +* Blosxom Options:: Blosxom styles and options provided. +@end menu + +@node Blosxom Requirements, Blosxom Entries, Blosxom, Blosxom +@comment node-name, next, previous, up +@subsection Other tools needed for the Blosxom style + +You will need to have @command{pyblosxom.cgi} or @command{blosxom.cgi} +installed on a machine that you have upload access to. + +The major difficulty in both of these programs is specifying the date of +the entries. Both programs rely on the file modification time rather +than any data contained in the entries themselves. A plugin is needed +in order for these programs to be able to get the correct date. + +@subheading PyBlosxom + +There are two different ways of accomplishing this in pyblosxom. The +first way involves gathering the timestamps (as specified by the +@code{#date} directive) into one file and then sending that file along +with published entries to the webserver. + +The second will read each file at render time and parse the +@code{#postdate} directive. Muse will translate the @code{#date} +directive into @code{#postdate} at publish time, so you don't have to do +any extra work. + +@subsubheading Placing timestamps in one file + +The following additional components are required in order to make the +date of blog entries display as something sensible. + +@enumerate +@item +A script to gather date directives from the entire blog tree into a +single file. The file must associate a blog entry with a date. + +@item +A plugin for (py)blosxom that reads this file. +@end enumerate + +These 2 things are provided for @command{pyblosxom.cgi} in the +@file{contrib/pyblosxom} subdirectory. @file{getstamps.py} provides the +former service, while @file{hardcodedates.py} provides the latter +service. + +Here is a sample listing from my @file{timestamps} file, which maps +each file to a date. This can really be in any format, as long as your +date-gathering script and your plugin can both understand it. + +@example +2005-04-01-14-16 personal/paper_cranes +2005-03-21 personal/spring_break_over +2004-10-24 personal/finished_free_culture +@end example + +The script @file{contrib/pyblosxom/make-blog} demonstrates how to call +@file{getstamps.py}. Note that you will need to set the current +directory to where your Muse files are, execute @file{getstamps.py}, and +then move the generated timestamps file to your publishing directory. + +@subsubheading Getting timestamp from entry while rendering + +Alternately, the pyblosxom metadate plugin may be used. On the plus +side, there is no need to run a script to gather the date. On the +downside, each entry is read twice rather than once when the page is +rendered. Set the value of @code{muse-blosxom-use-metadate} to non-nil +to enable adding a @code{#postdate} directive to all published files. +You can do this by: + +@example +M-x customize-variable RET muse-blosxom-use-metadate RET +@end example + +With the metadate plugin installed in pyblosxom, the date set in this +directive will be used instead of the file's modification time. The +plugin is included with Muse at @file{contrib/pyblosxom/metadate.py}. + +@subheading Blosxom + +It is also possible to use Blosxom, which is written in Perl, to serve +blog entries that were published with Muse. The steps are as follows. + +@enumerate +@item +Download and install blosxom from @url{http://blosxom.sourceforge.net/}. + +@item +Install the metadate plugin. It is available in +@file{contrib/blosxom/metadate_0_0_3}. + +@item +Every time you make a new blog entry, change to the blosxom data +directory and execute the @file{contrib/blosxom/getstamps.pl} script. +This script has only recently been made, and may still have some bugs, +so use with caution. + +@end enumerate + +@node Blosxom Entries, Blosxom Options, Blosxom Requirements, Blosxom +@comment node-name, next, previous, up +@subsection Format of a Blosxom entry and automation + +Each Blosxom file must include `#date yyyy-mm-dd', or optionally the +longer `#date yyyy-mm-dd-hh-mm', a title (using the @code{#title} +directive), plus whatever normal content is desired. + +The date directive is not used directly by @command{pyblosxom.cgi} or +this program. You need to have the two additional items from the former +section to make use of this feature. + +There is a function called @code{muse-blosxom-new-entry} that will +automate the process of making a new blog entry. To make use of it, do +the following. + +@itemize @bullet +@item +Customize @code{muse-blosxom-base-directory} to the location that your +blog entries are stored. + +@item +Assign the @code{muse-blosxom-new-entry} function to a key sequence. I +use the following code to assign this function to @kbd{C-c p l'}. + +@example +(global-set-key "\C-cpl" 'muse-blosxom-new-entry) +@end example + +@item +You should create your directory structure ahead of time under your base +directory. These directories, which correspond with category names, may +be nested. + +@item +When you enter this key sequence, you will be prompted for the category +of your entry and its title. Upon entering this information, a new file +will be created that corresponds with the title, but in lowercase +letters and having special characters converted to underscores. The +title and date directives will be inserted automatically. +@end itemize + +@node Blosxom Options, , Blosxom Entries, Blosxom +@comment node-name, next, previous, up +@subsection Blosxom styles and options provided + +The following styles and options are available in the Blosxom publishing +style. + +@subheading Styles provided + +@table @code + +@cindex publishing styles, blosxom-html +@item blosxom-html +Publish Blosxom entries in HTML form. + +@cindex publishing styles, blosxom-xhtml +@item blosxom-xhtml +Publish Blosxom entries in XHTML form. + +@end table + +@subheading Options provided + +@table @code + +@item muse-blosxom-extension +Default file extension for publishing Blosxom files. + +@item muse-blosxom-header +Header used for publishing Blosxom files. + +This may be text or a filename. + +@item muse-blosxom-footer +Footer used for publishing Blosxom files. + +This may be text or a filename. + +@item muse-blosxom-base-directory +Base directory of blog entries, used by @code{muse-blosxom-new-entry}. + +This is the top-level directory where your blog entries may be found +locally. + +@end table + +@node Book, ConTeXt, Blosxom, Publishing Styles +@comment node-name, next, previous, up +@section Publishing entries into a compilation + +This publishing style is used to output ``books'' in LaTeX or PDF +format. + +Each page will become a separate chapter in the book, unless the style +keyword @option{:nochapters} is used, in which case they are all run +together as if one giant chapter. + +One way of publishing a book is to make a project for it, add the +project to @code{muse-project-alist}, and use the @code{book-pdf} style +with a very specific @option{:include} value to specify some page whose +contents will be checked for the values of @code{#title} and +@code{#date}, and whose name will be used in the output file. Then to +publish the book, visit the aforementioned page and use @kbd{C-c C-t} or +@kbd{C-c C-p} to trigger the publishing process. An example +@code{muse-project-alist} for this method follows. + +@example +(setq muse-project-alist + '(("MyNotes" (:nochapters t ; do automatically add chapters + :book-chapter "Computer Science" + "~/Notes/cs" + :book-chapter "Mathematics" + "~/Notes/math" + :book-chapter "Emacs" + "~/Notes/emacs" + :book-end t ; the rest will not be placed in the book + "~/Notes" ; so we can find the notes-anthology page + "~/Notes/private" + :force-publish ("index") + :default "index") + (:base "book-pdf" + :include "/notes-anthology[^/]*$" + :path "~/public_html/notes") + ;; other publishing styles for each directory go here, + ;; if desired + ))) +@end example + +In this example, there would be a file called +@file{~/Notes/notes-anthology.muse}, which would contain just the +following. The resulting book would be published to +@file{~/public_html/notes/notes-anthology.pdf}. + +@example +#title My Technology Ramblings +@end example + +Another way is to call the @code{muse-book-publish-project} function +manually, with a custom project entry. An example of this may be found +in John Wiegley's configuration file at +@file{examples/johnw/muse-init.el}, in the @code{muse-publish-my-books} +function. + +@subheading Styles provided + +@table @code + +@cindex publishing styles, book-latex +@item book-latex +Publish a book in LaTeX form. The header and footer are different than +the normal LaTeX publishing mode. + +@cindex publishing styles, book-pdf +@item book-pdf +Publish a book in PDF form. The header and footer are different than +the normal PDF publishing mode. + +@end table + +@subheading Options provided + +@table @code + +@item muse-book-before-publish-hook +A hook run in the book buffer before it is marked up. + +@item muse-book-after-publish-hook +A hook run in the book buffer after it is marked up. + +@item muse-book-latex-header +Header used for publishing books to LaTeX. + +This may be text or a filename. + +@item muse-book-latex-footer +Footer used for publishing books to LaTeX. + +This may be text or a filename. + +@end table +@node ConTeXt, DocBook, Book, Publishing Styles +@comment node-name, next, previous, up +@section Publishing ConTeXt documents + +This publishing style is capable of producing ConTeXt or PDF documents. + +If you wish to publish PDF documents based on ConTeXt, you will need to +have it installed. For Debian and Ubuntu, this can be accomplished by +installing the ``texlive'' package. + +@subheading Styles provided + +@table @code + +@cindex publishing styles, context +@item context +Publish a ConTeXt document. + +@cindex publishing styles, context-pdf +@item context-pdf +Publish a PDF document, using an external ConTeXt document conversion +tool. + +@cindex publishing styles, context-slides +@item context-slides +Produce slides from a ConTeXt document. + +Here is an example of a slide. + +@example +* First Slide + +[[Some-sort-of-cute-image.png]] + +** A subheading + + - A bullet point. + - Another bullet point. + +* Second Slide + +... and so on +@end example + +@cindex publishing styles, context-slides-pdf +@item context-slides-pdf +Publish a PDF document of ConTeXt slides. + +@end table + +@subheading Options provided + +@table @code + +@item muse-context-extension +Default file extension for publishing ConTeXt files. + +@item muse-context-pdf-extension +Default file extension for publishing ConTeXt files to PDF. + +@item muse-context-pdf-program +The program that is called to generate PDF content from ConTeXt content. + +@item muse-context-pdf-cruft +Extensions of files to remove after generating PDF output successfully. + +@item muse-context-header +Header used for publishing ConTeXt files. + +This may be text or a filename. + +@item muse-context-footer +Footer used for publishing ConTeXt files. + +This may be text or a filename. + +@item muse-context-markup-regexps +List of markup regexps for identifying regions in a Muse page. + +For more on the structure of this list, +@xref{muse-publish-markup-regexps}. + +@item muse-context-markup-functions +An alist of style types to custom functions for that kind of text. + +For more on the structure of this list, +@xref{muse-publish-markup-functions}. + +@item muse-context-markup-strings +Strings used for marking up text. + +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +@item muse-context-slides-header +Header for publishing a presentation (slides) using ConTeXt. + +Any of the predefined modules, which are available in the +tex/context/base directory, can be used by writing a "module" directive +at the top of the Muse file; if no such directive is provided, module +pre-01 is used. Alternatively, you can use your own style ("mystyle", +in this example) by replacing "\usemodule[]" with "\input mystyle". + +This may be text or a filename. + +@item muse-context-slides-markup-strings +Strings used for marking up text in ConTeXt slides. + +@item muse-context-markup-specials-document +A table of characters which must be represented specially. +These are applied to the entire document, sans already-escaped +regions. + +@item muse-context-markup-specials-example +A table of characters which must be represented specially. +These are applied to @verb{|example>|} regions. + +With the default interpretation of @verb{||} regions, no +specials need to be escaped. + +@item muse-context-markup-specials-literal +A table of characters which must be represented specially. +This applies to =monospaced text= and @verb{||} regions. + +@item muse-context-markup-specials-url +A table of characters which must be represented specially. +These are applied to URLs. + +@item muse-context-markup-specials-image +A table of characters which must be represented specially. +These are applied to image filenames. + +@item muse-context-permit-contents-tag +If nil, ignore @verb{||} tags. Otherwise, insert table of +contents. + +Most of the time, it is best to have a table of contents on the +first page, with a new page immediately following. To make this +work with documents published in both HTML and ConTeXt, we need to +ignore the @verb{||} tag. + +If you don't agree with this, then set this option to non-nil, +and it will do what you expect. + +@end table + +@node DocBook, HTML, ConTeXt, Publishing Styles +@comment node-name, next, previous, up +@section Publishing in DocBook XML form + +This publishing style is used to generate DocBook XML files. + +@subheading Styles provided + +@table @code + +@cindex publishing styles, docbook +@item docbook +Publish a file in Docbook form. + +@end table + +@subheading Options provided + +This publishing style uses the same options for markup up special +characters as the ``xml'' publishing style. @xref{XML}, for details. + +@table @code + +@item muse-docbook-extension +Default file extension for publishing DocBook XML files. + +@item muse-docbook-header +Header used for publishing DocBook XML files. + +This may be text or a filename. + +@item muse-docbook-footer +Footer used for publishing DocBook XML files. + +This may be text or a filename. + +@item muse-docbook-markup-regexps +List of markup rules for publishing a Muse page to DocBook XML. + +@item muse-docbook-markup-functions +An alist of style types to custom functions for that kind of text. + +@item muse-docbook-markup-strings +Strings used for marking up text. + +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +@item muse-docbook-encoding-default +The default Emacs buffer encoding to use in published files. +This will be used if no special characters are found. + +@item muse-docbook-charset-default +The default DocBook XML charset to use if no translation is +found in @code{muse-xml-encoding-map}. + +@end table + +@node HTML, Ikiwiki, DocBook, Publishing Styles +@comment node-name, next, previous, up +@section Publishing in HTML or XHTML form + +This publishing style is capable of producing HTML or XHTML documents. + +@subheading Styles provided + +@table @code + +@cindex publishing styles, html +@item html +Supports publishing to HTML 4.0 and HTML 4.01, Strict or Transitional. + +@item xhtml +Supports publishing to XHTML 1.0 and XHTML 1.1, Strict or Transitional. + +@end table + +@subheading Options provided + +If an HTML option does not have a corresponding XHTML option, it will +be used for both of these publishing styles. + +These publishing styles use the same options for markup up special +characters as the ``xml'' publishing style. @xref{XML}, for details. + +@table @code + +@item muse-html-extension +Default file extension for publishing HTML files. + +@item muse-xhtml-extension +Default file extension for publishing XHTML files. + +@item muse-html-style-sheet +Store your stylesheet definitions here. + +This is used in @code{muse-html-header}. You can put raw CSS in here or +a @verb{||} tag to an external stylesheet. This text may contain +@verb{||} markup tags. + +If you are publishing to XHTML, then customize the +@code{muse-xhtml-style-sheet} option instead. + +@item muse-xhtml-style-sheet +Store your stylesheet definitions here. + +This is used in @code{muse-xhtml-header}. You can put raw CSS in here +or a @verb{||} tag to an external stylesheet. This text may +contain @verb{||} markup tags. + +@item muse-html-header +Header used for publishing HTML files. + +This may be text or a filename. + +@item muse-html-footer +Footer used for publishing HTML files. + +This may be text or a filename. + +@item muse-xhtml-header +Header used for publishing XHTML files. + +This may be text or a filename. + +@item muse-xhtml-footer +Footer used for publishing XHTML files. + +This may be text or a filename. + +@item muse-html-anchor-on-word +When true, anchors surround the closest word. + +This allows you to select them in a browser (i.e. for pasting), but has +the side-effect of marking up headers in multiple colors if your header +style is different from your link style. + +@item muse-html-table-attributes +The attribute to be used with HTML @verb{|
    |} tags. + +If you want to make more-complicated tables in HTML, surround the HTML +with the @verb{|literal|} tag, so that it does not get escaped. + +@item muse-html-markup-regexps +List of markup rules for publishing a Muse page to HTML. + +@item muse-html-markup-functions +An alist of style types to custom functions for that kind of text. + +@item muse-html-markup-strings +Strings used for marking up text as HTML. + +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +@item muse-xhtml-markup-strings +Strings used for marking up text as XHTML. + +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +@item muse-html-markup-tags +A list of tag specifications, for specially marking up HTML. +@xref{muse-publish-markup-tags}, for more information. + +@item muse-html-meta-http-equiv +The http-equiv attribute used for the HTML @verb{||} tag. + +@item muse-html-meta-content-type +The content type used for the HTML @verb{||} tag. + +If you are striving for XHTML 1.1 compliance, you may want to change +this to ``application/xhtml+xml''. + +@item muse-html-meta-content-encoding +The charset to append to the HTML @verb{||} tag. + +If set to the symbol 'detect, use @code{muse-xml-encoding-map} to try +and determine the HTML charset from emacs's coding. If set to a string, +this string will be used to force a particular charset. + +@item muse-html-charset-default +The default HTML meta charset to use if no translation is found in +@code{muse-xml-encoding-map}. + +@item muse-html-encoding-default +The default Emacs buffer encoding to use in published files. +This will be used if no special characters are found. + +@end table + +@node Ikiwiki, Journal, HTML, Publishing Styles +@comment node-name, next, previous, up +@section Integrating with ikiwiki + +Note: Support for Ikiwiki is not yet complete. Use at your own risk. + +Ikiwiki is a wiki compiler (@url{http://ikiwiki.info/}). Emacs Muse can +(not yet) be used as a source format for Ikiwiki pages with the plugin +@file{IkiWiki::Plugin::muse}. + +The @file{lisp/muse-ikiwiki.el} file provides publishing functions and +styles for Ikiwiki. The plugin for Ikiwiki to recognize Muse files is +provided by the @file{contrib/ikiwiki/IkiWiki/Plugin/muse.pm} file. Two +sample init files are available in the @file{examples/ikiwiki} +directory. Configure your @file{ikiwiki.setup} file so that the +@code{muse_init} variable has the location of your Muse init file. + +If you are using CGI, The directory @file{contrib/ikiwiki/IkiWiki} must +be copied to the same directory as the CGI script that Ikiwiki +generates. When publishing your wiki, the @var{PERL5LIB} environment +variable must contain the path to the @file{contrib/ikiwiki/IkiWiki} +directory. + +@subheading Styles provided + +@table @code + +@cindex publishing styles, ikiwiki +@item ikiwiki +Supports publishing XHTML output that Ikiwiki can understand. + +@end table + +@subheading Options provided + +@table @code + +@item muse-ikiwiki-header +Header used for publishing Ikiwiki output files. + +This may be text or a filename. + +@item muse-ikiwiki-footer +Footer used for publishing Ikiwiki output files. + +This may be text or a filename. + +@end table + +@subheading Other relevant options + +@table @code + +@item muse-colors-evaluate-lisp-tags +Specify whether to evaluate the contents of @verb{||} tags at +display time. If nil, don't evaluate them. If non-nil, evaluate +them. + +The actual contents of the buffer are not changed, only the +displayed text. + +@item muse-html-src-allowed-modes +Modes that we allow the @verb{||} tag to colorize. If @code{t}, +permit the @verb{||} tag to colorize any mode. + +If a list of mode names, such as @code{'("html" "latex")}, and the lang +argument to @verb{||} is not in the list, then use fundamental mode +instead. + +@item muse-publish-enable-dangerous-tags +If non-nil, publish tags like @verb{||} and @verb{||} +that can call external programs or expose sensitive information. +Otherwise, ignore tags like this. + +This is useful to set to @code{nil} when the file to publish is coming +from an untrusted source. + +@end table + +@node Journal, LaTeX, Ikiwiki, Publishing Styles +@comment node-name, next, previous, up +@section Keeping a journal or blog +@cindex journal +@cindex blog, journal style + +The module facilitates the keeping and publication of a journal. When +publishing to HTML, it assumes the form of a web log, or blog. + +The input format for each entry is as follows. + +@example +* 20040317: Title of entry + +text for the entry. + + +"You know who you are. It comes down to a simple gut check: You +either love what you do or you don't. Period." -- P. Bronson + +@end example + +The "qotd", or Quote of the Day, is entirely optional. When generated +to HTML, this entry is rendered as the following. + +@example +
    +
    +

    Quote of the Day:

    +

    "You know who you are. It comes down to a simple gut + check: You either love what you do or you don't. Period." + -- P. Bronson

    +
    +
    +
    + +
    +

    Title of entry

    +
    +
    +
    +

    Text for the entry.

    +
    +
    +
    +@end example + +The plurality of "div" tags makes it possible to display the entries in +any form you wish, using a CSS style. + +Also, an .RDF file can be generated from your journal by publishing it +with the "rdf" style. It uses the first two sentences of the first +paragraph of each entry as its "description", and auto-generates tags +for linking to the various entries. + +@subheading muse-project-alist considerations + +If you wish to publish an RDF or RSS feed, it is important to include +the @option{:base-url} attribute in your @code{muse-project-alist} entry +for your Journal projects. An example follows. + +@example +(setq muse-project-alist + '(("Journal" ("~/Journal/" + :default "journal") + (:base "journal-rss" + :base-url "http://example.org/journal/" + :path "~/public_html/journal")))) +@end example + +@subheading Styles provided + +@table @code + +@cindex publishing styles, journal-html +@item journal-html +Publish journal entries as an HTML document. + +@cindex publishing styles, journal-xhtml +@item journal-xhtml +Publish journal entries as an XHTML document. + +@cindex publishing styles, journal-latex +@item journal-latex +Publish journal entries as a LaTeX document. + +@cindex publishing styles, journal-pdf +@item journal-pdf +Publish journal entries as a PDF document. + +@cindex publishing styles, journal-book-latex +@item journal-book-latex +Publish journal entries as a LaTeX book. + +@cindex publishing styles, journal-book-pdf +@item journal-book-pdf +Publish journal entries as a PDF book. + +@cindex publishing styles, journal-rdf +@cindex publishing styles, RSS 1.0 +@item journal-rdf +Publish journal entries as an RDF file (RSS 1.0). + +@cindex publishing styles, journal-rss +@cindex publishing styles, RSS 2.0 +@item journal-rss +Publish journal entries as an RSS file (RSS 2.0). + +@cindex publishing styles, journal-rss-entry +@item journal-rss-entry +Used internally by @code{journal-rss} and @code{journal-rdf} for +publishing individual entries. + +@end table + +@subheading Options provided + +@table @code + +@item muse-journal-heading-regexp +A regexp that matches a journal heading. + +Paren group 1 is the ISO date, group 2 is the optional category, and +group 3 is the optional heading for the entry. + +@item muse-journal-date-format +Date format to use for journal entries. + +@item muse-journal-html-heading-regexp +A regexp that matches a journal heading from an HTML document. + +Paren group 1 is the ISO date, group 2 is the optional category, and +group 3 is the optional heading for the entry. + +@item muse-journal-html-entry-template +Template used to publish individual journal entries as HTML. + +This may be text or a filename. + +@item muse-journal-latex-section +Template used to publish a LaTeX section. + +@item muse-journal-latex-subsection +Template used to publish a LaTeX subsection. + +@item muse-journal-markup-tags +A list of tag specifications, for specially marking up Journal entries. + +@xref{muse-publish-markup-tags}, for more information. + +This is used by @code{journal-latex} and its related styles, as well as +the @code{journal-rss-entry} style, which both @code{journal-rdf} and +@code{journal-rss} use. + +@item muse-journal-rdf-extension +Default file extension for publishing RDF (RSS 1.0) files. + +@item muse-journal-rdf-base-url +The base URL of the website referenced by the RDF file. + +@item muse-journal-rdf-header +Header used for publishing RDF (RSS 1.0) files. + +This may be text or a filename. + +@item muse-journal-rdf-footer +Footer used for publishing RDF (RSS 1.0) files. + +This may be text or a filename. + +@item muse-journal-rdf-date-format +Date format to use for RDF entries. + +@item muse-journal-rdf-entry-template +Template used to publish individual journal entries as RDF. + +This may be text or a filename. + +@item muse-journal-rdf-summarize-entries +If non-nil, include only summaries in the RDF file, not the full data. + +The default is nil, because this annoys some subscribers. + +@item muse-journal-rss-heading-regexp +A regexp that matches a journal heading from an HTML document. + +Paren group 1 is the ISO date, group 2 is the optional category, +and group 3 is the optional heading for the entry. + +@item muse-journal-rss-extension +Default file extension for publishing RSS 2.0 files. + +@item muse-journal-rss-base-url +The base URL of the website referenced by the RSS file. + +@item muse-journal-rss-header +Header used for publishing RSS 2.0 files. + +This may be text or a filename. + +@item muse-journal-rss-footer +Footer used for publishing RSS 2.0 files. + +This may be text or a filename. + +@item muse-journal-rss-date-format +Date format to use for RSS 2.0 entries. + +@item muse-journal-rss-entry-template +Template used to publish individual journal entries as RSS 2.0. + +This may be text or a filename. + +@item muse-journal-rss-enclosure-types-alist +File types that are accepted as RSS enclosures. + +This is an alist that maps file extension to content type. + +Useful for podcasting. + +@item muse-journal-rss-summarize-entries +If non-nil, include only summaries in the RSS file, not the full data. + +The default is nil, because this annoys some subscribers. + +@item muse-journal-rss-markup-regexps +List of markup rules for publishing a Muse journal page to RSS. + +For more information on the structure of this list, +@xref{muse-publish-markup-regexps}. + +@item muse-journal-rss-markup-functions +An alist of style types to custom functions for that kind of text. + +For more on the structure of this list, +@xref{muse-publish-markup-functions}. + +@end table + +@node LaTeX, Poem, Journal, Publishing Styles +@comment node-name, next, previous, up +@section Publishing LaTeX documents + +This publishing style is capable of producing LaTeX or PDF documents. + +If you wish to publish PDF documents, you will need to have a good LaTeX +installation. For Debian and Ubuntu, this can be accomplished by +installing the ``tetex-bin'' and ``tetex-extra'' packages. TeX fonts +are also a must. + +If your LaTeX installation has the file @file{grffile.sty}, which may be +found in the @file{texlive-latex-recommended} package for Debian and +Ubuntu, then consider using it by adding the following to your header +file. This allows spaces in filenames to work. + +@example +\usepackage@{grffile@} +@end example + +@subheading Styles provided + +@table @code + +@cindex publishing styles, latex +@item latex +Publish a LaTeX document. + +@cindex publishing styles, pdf +@item pdf +Publish a PDF document, using an external LaTeX document conversion +tool. + +@cindex publishing styles, latexcjk +@item latexcjk +Publish a LaTeX document with CJK (Chinese) encodings. + +@cindex publishing styles, pdfcjk +@item pdfcjk +Publish a PDF document with CJK (Chinese) encodings, using an external +LaTeX document conversion tool. + +@cindex publishing styles, slides +@item slides +Publish a LaTeX document that uses the Beamer extension. This is +suitable for producing slides. + +Here is an example of a slide. + +@example + +Everything between the slide tags composes this slide. + +[[Some-sort-of-cute-image.png]] + + - A bullet point. + - Another bullet point. + +@end example + +@cindex publishing styles, slides-pdf +@item slides-pdf +Publish a PDF document of slides, using the Beamer extension. + +@cindex publishing styles, lecture-notes +@item lecture-notes +Publish a LaTeX document that uses the Beamer extension. This is +suitable for producing lecture notes. + +This can also use the @verb{||} tag. + +@cindex publishing styles, lecture-notes-pdf +@item lecture-notes-pdf +Publish a PDF document of lecture notes, using the Beamer extension. + +@end table + +@subheading Options provided + +@table @code + +@item muse-latex-extension +Default file extension for publishing LaTeX files. + +@item muse-latex-pdf-extension +Default file extension for publishing LaTeX files to PDF. + +@item muse-latex-pdf-browser +The program to use when browsing a published PDF file. + +This should be a format string. + +@item muse-latex-pdf-program +The program that is called to generate PDF content from LaTeX content. + +@item muse-latex-pdf-cruft +Extensions of files to remove after generating PDF output successfully. + +@item muse-latex-header +Header used for publishing LaTeX files. + +This may be text or a filename. + +@item muse-latex-footer +Footer used for publishing LaTeX files. + +This may be text or a filename. + +@item muse-latexcjk-header +Header used for publishing LaTeX files (CJK). + +This may be text or a filename. + +@item muse-latexcjk-footer +Footer used for publishing LaTeX files (CJK). + +This may be text or a filename. + +@item muse-latex-slides-header +Header for publishing of slides using LaTeX. + +This may be text or a filename. + +You must have the Beamer extension for LaTeX installed for this to work. + +@item muse-latex-lecture-notes-header +Header publishing of lecture notes using LaTeX. + +This may be text or a filename. + +You must have the Beamer extension for LaTeX installed for this to work. + +@item muse-latex-markup-regexps +List of markup regexps for identifying regions in a Muse page. + +For more on the structure of this list, +@xref{muse-publish-markup-regexps}. + +@item muse-latex-markup-functions +An alist of style types to custom functions for that kind of text. + +For more on the structure of this list, +@xref{muse-publish-markup-functions}. + +@item muse-latex-markup-strings +Strings used for marking up text. + +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +@item muse-latex-slides-markup-tags +A list of tag specifications, for specially marking up LaTeX slides. + +@item muse-latexcjk-encoding-map +An alist mapping emacs coding systems to appropriate CJK codings. +Use the base name of the coding system (ie, without the -unix). + +@item muse-latexcjk-encoding-default +The default Emacs buffer encoding to use in published files. + +This will be used if no special characters are found. + +@item muse-latex-markup-specials-document +A table of characters which must be represented specially. +These are applied to the entire document, sans already-escaped +regions. + +@item muse-latex-markup-specials-example +A table of characters which must be represented specially. +These are applied to @verb{|example>|} regions. + +With the default interpretation of @verb{||} regions, no +specials need to be escaped. + +@item muse-latex-markup-specials-literal +A table of characters which must be represented specially. +This applies to =monospaced text= and @verb{||} regions. + +@item muse-latex-markup-specials-url +A table of characters which must be represented specially. +These are applied to URLs. + +@item muse-latex-markup-specials-image +A table of characters which must be represented specially. +These are applied to image filenames. + +@item muse-latex-permit-contents-tag +If nil, ignore @verb{||} tags. Otherwise, insert table of +contents. + +Most of the time, it is best to have a table of contents on the +first page, with a new page immediately following. To make this +work with documents published in both HTML and LaTeX, we need to +ignore the @verb{||} tag. + +If you don't agree with this, then set this option to non-nil, +and it will do what you expect. + +@end table + +@node Poem, Texinfo, LaTeX, Publishing Styles +@comment node-name, next, previous, up +@section Publish a poem to LaTeX or PDF + +The @code{muse-poem} module makes it easy to attractively publish and +reference poems in the following format, using the "memoir" module for +LaTeX publishing. It will also markup poems for every other output +style, though none are nearly as pretty. + +@example +Title + + +Body of poem + + +Annotations, history, notes, etc. +@end example + +Once a poem is written in this format, just publish it to PDF using the +@code{poem-pdf} style. To make an inlined reference to a poem that +you've written -- for example, from a blog page -- there is a "poem" tag +defined by this module. + +@example + +@end example + +Let's assume the template above was called @file{name.of.poem.page}; +then the above tag would result in this inclusion. + +@example +** Title + +> Body of poem +@end example + +John Wiegley uses this module for publishing all of the poems on his +website, which are at +@uref{http://www.newartisans.com/johnw/poems.html}. + +@subheading Styles provided + +@table @code + +@cindex publishing styles, poem-latex +@item poem-latex +Publish a poem in LaTeX form. + +@cindex publishing styles, poem-pdf +@item poem-pdf +Publish a poem to a PDF document. + +@cindex publishing styles, chapbook-latex +@item chapbook-latex +Publish a book of poems in LaTeX form. + +@cindex publishing styles, chapbook-pdf +@item chapbook-pdf +Publish a book of poems to a PDF document. + +@end table + +@subheading Options provided + +@table @code + +@item muse-poem-latex-header +Header used for publishing LaTeX poems. + +This may be text or a filename. + +@item muse-poem-latex-footer +Footer used for publishing LaTeX files. + +This may be text or a filename. + +@item muse-poem-markup-strings +Strings used for marking up poems. + +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +@item muse-chapbook-latex-header +Header used for publishing a book of poems in LaTeX form. + +This may be text or a filename. + +@item muse-chapbook-latex-footer +Footer used for publishing a book of poems in LaTeX form. + +This may be text or a filename. + +@item muse-poem-chapbook-strings +Strings used for marking up books of poems. + +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +@end table + +@node Texinfo, XML, Poem, Publishing Styles +@comment node-name, next, previous, up +@section Publish entries to Texinfo format or PDF + +Rules for publishing a Muse file as a Texinfo article. + +@subheading Styles provided + +@table @code + +@cindex publishing styles, texi +@item texi +Publish a file in Texinfo form. + +@cindex publishing styles, texi +@item info +Generate an Info file from a Muse file. + +@cindex publishing styles, info-pdf +@item info-pdf +Publish a file in PDF form. + +@end table + +@subheading Options provided + +@table @code + +@item muse-texinfo-process-natively +If non-nil, use the Emacs `texinfmt' module to make Info files. + +@item muse-texinfo-extension +Default file extension for publishing Texinfo files. + +@item muse-texinfo-info-extension +Default file extension for publishing Info files. + +@item muse-texinfo-pdf-extension +Default file extension for publishing PDF files. + +@item muse-texinfo-header +Text to prepend to a Muse page being published as Texinfo. + +This may be text or a filename. +It may contain @verb{||} markup tags. + +@item muse-texinfo-footer +Text to append to a Muse page being published as Texinfo. + +This may be text or a filename. +It may contain @verb{||} markup tags. + +@item muse-texinfo-markup-regexps +List of markup rules for publishing a Muse page to Texinfo. + +For more on the structure of this list, +@xref{muse-publish-markup-regexps}. + +@item muse-texinfo-markup-functions +An alist of style types to custom functions for that kind of text. + +For more on the structure of this list, +@xref{muse-publish-markup-functions}. + +@item muse-texinfo-markup-strings +Strings used for marking up text. + +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +@item muse-texinfo-markup-specials +A table of characters which must be represented specially. + +@item muse-texinfo-markup-specials +A table of characters which must be represented specially. +These are applied to URLs. + +@end table + +@node XML, , Texinfo, Publishing Styles +@comment node-name, next, previous, up +@section Publish entries to XML + +Muse is capable of publishing XML documents, with the help of the +@file{muse-xml.el} module. + +A RelaxNG schema is available as part of the Muse distribution in the +@file{etc/muse.rnc} file. + +@subheading Styles provided + +@table @code + +@cindex publishing styles, xml +@item xml +Publish a file in XML form. + +@end table + +@subheading Options provided + +@table @code + +@cindex muse-xml-encoding-map +@item muse-xml-encoding-map +An alist mapping Emacs coding systems to appropriate XML charsets. +Use the base name of the coding system (i.e. without the -unix). + +@item muse-xml-markup-specials +A table of characters which must be represented specially in all +XML-like markup formats. + +@item muse-xml-markup-specials-url-extra +A table of characters which must be represented specially in all +XML-like markup formats. + +These are extra characters that are escaped within URLs. + +@item muse-xml-extension +Default file extension used for publishing XML files. + +@item muse-xml-header +Header used for publishing XML files. + +This may be text or a filename. + +@item muse-xml-footer +Footer used for publishing XML files. + +This may be text or a filename. + +@item muse-xml-markup-regexps +List of markup rules for publishing a Muse page to XML. + +For more on the structure of this list, +@xref{muse-publish-markup-regexps}. + +@item muse-xml-markup-functions +An alist of style types to custom functions for that kind of text. + +For more on the structure of this list, +@xref{muse-publish-markup-functions}. + +@item muse-xml-markup-strings +Strings used for marking up text. + +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +@item muse-xml-encoding-default +The default Emacs buffer encoding to use in published files. + +This will be used if no special characters are found. + +@item muse-xml-charset-default +The default XML charset to use if no translation is found in +@code{muse-xml-encoding-map}. + +@end table + + +@node Extending Muse, Miscellaneous, Publishing Styles, Top +@comment node-name, next, previous, up +@chapter Making your own publishing styles + +@menu +* Markup Functions:: Specifying functions to mark up text. +* Markup Regexps:: Markup rules for publishing. +* Markup Strings:: Strings specific to a publishing style. +* Markup Tags:: Tag specifications for special markup. +* Style Elements:: Parameters used for defining styles. +* Deriving Styles:: Deriving a new style from an existing + one. +@end menu + +@node Markup Functions, Markup Regexps, , Extending Muse +@comment node-name, next, previous, up +@section Specifying functions to mark up text +@cindex publishing, markup functions + +@anchor{muse-publish-markup-functions} +@code{muse-publish-markup-functions} + +An alist of style types to custom functions for that kind of text. + +This is used by publishing styles to attempt to minimize the amount of +custom regexps that each has to define. @file{muse-publish} provides +rules for the most common types of markup. + +Each member of the list is of the following form. + +@example +(SYMBOL FUNCTION) +@end example + +@itemize @bullet +@item SYMBOL +Describes the type of text to associate with this rule. +@code{muse-publish-markup-regexps} maps regexps to these symbols. + +@item FUNCTION +Function to use to mark up this kind of rule if no suitable function is +found through the @option{:functions} tag of the current style. +@end itemize + +@node Markup Regexps, Markup Strings, Markup Functions, Extending Muse +@comment node-name, next, previous, up +@section Markup rules for publishing +@cindex publishing, markup regexps +@cindex publishing, rules + +@anchor{muse-publish-markup-regexps} +@code{muse-publish-markup-regexps} + +List of markup rules for publishing a page with Muse. + +The rules given in this variable are invoked first, followed by whatever +rules are specified by the current style. + +Each member of the list is either a function, or a list of the following +form. + +@example +(REGEXP/SYMBOL TEXT-BEGIN-GROUP REPLACEMENT-TEXT/FUNCTION/SYMBOL) +@end example + +@itemize @bullet +@item REGEXP +A regular expression, or symbol whose value is a regular expression, +which is searched for using `re-search-forward'. + +@item TEXT-BEGIN-GROUP +The matching group within that regexp which denotes the beginning of the +actual text to be marked up. + +@item REPLACEMENT-TEXT +A string that will be passed to `replace-match'. + +If it is not a string, but a function, it will be called to determine +what the replacement text should be (it must return a string). If it is +a symbol, the value of that symbol should be a string. +@end itemize + +The replacements are done in order, one rule at a time. Writing +the regular expressions can be a tricky business. Note that case +is never ignored. `case-fold-search' is always bound to nil +while processing the markup rules. + +@subheading Publishing order + +This is the order that the publishing rules are consulted, by default. +This may be changed by customizing @code{muse-publish-markup-regexps}. + +@table @code + +@item trailing and leading whitespace +Remove trailing and leading whitespace from a file. + +@item directive +@samp{#directive} + +This is only recognized at the beginning of a file. + +@item comment +@samp{; a commented line} + +@item tag +@samp{} + +@item comment +@samp{; comment} + +@item explicit links +Prevent emphasis characters in explicit links from being marked up. + +Don't actually publish them here, just add a special no-emphasis text +property. + +@item word +Whitespace-delimited word, possibly with emphasis characters + +This function is responsible for marking up emphasis and escaping some +specials. + +@item heading +@samp{** Heading} + +Outline-mode style headings. + +@item enddots +@samp{....} + +These are ellipses with a dot at end. + +@item dots +@samp{...} + +Ellipses. + +@item rule +@samp{----} + +Horizontal rule or section separator. + +@item no-break-space +@samp{~~} + +Prevent lines from being split before or after these characters. + +@item line-break +@samp{
    } + +Break a line at point. + +@item fn-sep +@samp{Footnotes:} + +Beginning of footnotes section. + +@item footnote +@samp{[1]} + +Footnote definition or reference. If at beginning of line, it is a +definition. + +@item list +@itemize @bullet +@item +@samp{ 1. } + +@item +@samp{ - } + +@item +@samp{term :: } +@end itemize + +Numbered list, item list, or term definition list. + +@item table-el + +@file{table.el} style tables + +@item table +@samp{table | cells} + +Muse tables or orgtbl-mode style tables. + +@item quote +spaces before beginning of text + +Blockquotes. + +@item emdash +@samp{--} + +2-wide dash + +@item verse +@samp{> verse text} + +@item anchor +@samp{#anchor} + +@item link +@samp{[[explicit][links]]} + +@item url +@samp{http://example.com/} + +@item email +@samp{bare-email@@example.com} + +@end table + +@node Markup Strings, Markup Tags, Markup Regexps, Extending Muse +@comment node-name, next, previous, up +@section Strings specific to a publishing style +@cindex publishing, markup strings + +@dfn{Markup strings} are strings used for marking up text for a +particular style. + +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +@subheading Available markup strings + +@table @code + +@item image-with-desc +An image and a description. + +Argument 1: image without extension. Argument 2: image extension. +Argument 3: description. + +@item image +An inlined image. + +Argument 1: image without extension. Argument 2: image extension. + +@item image-link +An image with a link around it. + +Argument 1: link. Argument 2: image without extension. +Argument 3: image extension. + +@item anchor-ref +A reference to an anchor on the current page. + +Argument 1: anchor name. Argument 2: description if one exists, or the +original link otherwise. + +@item url +A URL without a description. + +Argument 1: URL. + +@item link +A link to a Muse page with a description. + +Argument 1: link. Argument 2: description if one exists, or the +original link otherwise. + +@item link-and-anchor +A link to a Muse page with an anchor, and a description. + +Argument 1: link. Argument 2: anchor name. +Argument 3: description if one exists, or the original link otherwise. +Argument 4: link without an extension. + +@item email-addr +A link to an email address. + +Argument 1: email address. Argument 2: email address. + +@item anchor +An anchor. + +Argument 1: name of anchor. + +@item emdash +A 2-length dash. + +Argument 1: Initial whitespace. Argument 2: Terminating whitespace. + +@item comment-begin +Beginning of a comment. + +@item comment-end +End of a comment. + +@item rule +A horizontal line or space. + +@item no-break-space +A space that separates two words which are not to be separated. + +@item footnote +Beginning of footnote. + +@item footnote-end +End of footnote. + +@item footnotemark +Mark a reference for the current footnote. + +Argument 1: number of this footnote. + +@item footnotemark-end +End of a reference for the current footnote. + +@item footnotetext +Indicate the text of the current footnote. + +Argument 1: number of this footnote. + +@item footnotetext-end +End of a footnote text line. + +@item fn-sep +Text used to replace ``Footnotes:'' line. + +@item dots +3 dots. + +@item enddots +4 dots. + +@item part +Beginning of a part indicator line. This is used by book publishing. + +@item part-end +End of a part indicator line. This is used by book publishing. + +@item chapter +Beginning of a chapter indicator line. This is used by book publishing. + +@item chapter-end +End of a chapter indicator line. This is used by book publishing. + +@item section +Beginning of level 1 section indicator line. + +Argument 1: level of section; always 1. + +@item section-end +End of level 1 section indicator line. + +Argument 1: level of section; always 1. + +@item subsection +Beginning of level 2 section indicator line. + +Argument 1: level of section; always 2. + +@item subsection-end +End of level 2 section indicator line. + +Argument 1: level of section; always 2. + +@item subsubsection +Beginning of level 3 section indicator line. + +Argument 1: level of section; always 3. + +@item subsubsection-end +End of level 3 section indicator line. + +Argument 1: level of section; always 3. + +@item section-other +Beginning of section indicator line, where level is greater than 3. + +Argument 1: level of section. + +@item section-other-end +End of section indicator line, where level is greater than 3. + +Argument 1: level of section. + +@item begin-underline +Beginning of underlined text. + +@item end-underline +End of underlined text. + +@item begin-literal +Beginning of verbatim text. This includes @verb{||} tags and +=teletype text=. + +@item end-literal +End of verbatim text. This includes @verb{||} tags and =teletype +text=. + +@item begin-emph +Beginning of the first level of emphasized text. + +@item end-emph +End of the first level of emphasized text. + +@item begin-more-emph +Beginning of the second level of emphasized text. + +@item end-more-emph +End of the second level of emphasized text. + +@item begin-most-emph +Beginning of the third (and final) level of emphasized text. + +@item end-most-emph +End of the third (and final) level of emphasized text. + +@item begin-verse +Beginning of verse text. + +@item verse-space +String used to each space that is further indented than the beginning of +the verse. + +@item begin-verse-line +Beginning of a line of verse. + +@item empty-verse-line +End of a line of verse. + +@item begin-last-stanza-line +Beginning of the last line of a verse stanza. + +@item end-last-stanza-line +End of the last line of a verse stanza. + +@item end-verse +End of verse text. + +@item begin-example +Beginning of an example region. To make use of this, an +@samp{} tag is needed. + +@item end-example +End of an example region. To make use of this, an @samp{} tag +is needed. + +@item begin-center +Begin a centered line. + +@item end-center +End a centered line. + +@item begin-quote +Begin a quoted region. + +@item end-quote +End a quoted region. + +@item begin-quote-item +Begin a quote paragraph. + +@item end-quote-item +End a quote paragraph. + +@item begin-uli +Begin an unordered list. + +@item end-uli +End an unordered list. + +@item begin-uli-item +Begin an unordered list item. + +@item end-uli-item +End an unordered list item. + +@item begin-oli +Begin an ordered list. + +@item end-oli +End an ordered list. + +@item begin-oli-item +Begin an ordered list item. + +@item end-oli-item +End an ordered list item. + +@item begin-dl +Begin a definition list. + +@item end-dl +End a definition list. + +@item begin-dl-item +Begin a definition list item. + +@item end-dl-item +End a definition list item. + +@item begin-ddt +Begin a definition list term. + +@item end-ddt +End a definition list term. + +@item begin-dde +Begin a definition list entry. + +@item end-dde +End a definition list entry. + +@item begin-table +Begin a table. + +@item end-table +End a table. + +@item begin-table-group +Begin a table grouping. + +@item end-table-group +End a table grouping. + +@item begin-table-row +Begin a table row. + +@item end-table-row +End a table row. + +@item begin-table-entry +Begin a table entry. + +@item end-table-entry +End a table entry. + +@end table + +@node Markup Tags, Style Elements, Markup Strings, Extending Muse +@comment node-name, next, previous, up +@section Tag specifications for special markup +@cindex publishing, markup tags + +@anchor{muse-publish-markup-tags} +@code{muse-publish-markup-tags} + +A list of tag specifications, for specially marking up text. + +XML-style tags are the best way to add custom markup to Muse. This is +easily accomplished by customizing this list of markup tags. + +For each entry, the name of the tag is given, whether it expects a +closing tag and/or an optional set of attributes, whether it is +nestable, and a function that performs whatever action is desired within +the delimited region. + +The tags themselves are deleted during publishing, before the function +is called. The function is called with three arguments, the beginning +and end of the region surrounded by the tags. If properties are +allowed, they are passed as a third argument in the form of an alist. +The `end' argument to the function is always a marker. + +Point is always at the beginning of the region within the tags, when the +function is called. Wherever point is when the function finishes is +where tag markup will resume. + +These tag rules are processed once at the beginning of markup, and once +at the end, to catch any tags which may have been inserted in-between. + +@node Style Elements, Deriving Styles, Markup Tags, Extending Muse +@comment node-name, next, previous, up +@section Parameters used for defining styles +@cindex publishing, style elements + +Style elements are tags that define a style. Use either +@code{muse-define-style} or @code{muse-derive-style} +(@pxref{Deriving Styles}) to create a new style. + +@defun muse-define-style name &rest elements +@end defun + +@subheading Usable elements + +@table @option + +@item :suffix +File extension to use for publishing files with this style. + +@item :link-suffix +File extension to use for publishing links to Muse files with this +style. + +@item :osuffix +File extension to use for publishing second-stage files with this style. + +For example, PDF publishing generates a LaTeX file first, then a PDF +from that LaTeX file. + +@item :regexps +List of markup rules for publishing a page with Muse. +@xref{muse-publish-markup-regexps}. + +@item :functions +An alist of style types to custom functions for that kind of text. +@xref{muse-publish-markup-functions}. + +@item :strings +Strings used for marking up text with this style. + +These cover the most basic kinds of markup, the handling of which +differs little between the various styles. + +@item :tags +A list of tag specifications, used for handling extra tags. +@xref{muse-publish-markup-tags}. + +@item :specials +A table of characters which must be represented specially. + +@item :before +A function that is to be executed on the newly-created publishing buffer +(or the current region) before any publishing occurs. + +This is used to set extra parameters that direct the publishing process. + +@item :before-end +A function that is to be executed on the publishing buffer (or the +current region) immediately after applying all of the markup regexps. + +This is used to fix the order of table elements (header, footer, body) +in XML-ish styles. + +@item :after +A function that is to be executed on the publishing buffer after +:before-end, and immediately after inserting the header and footer. + +This is used for generating the table of contents as well as setting the +file coding system. + +@item :final +A function that is to be executed after saving the published file, but +while still in its buffer. + +This is used for generating second-stage documents like PDF files from +just-published LaTeX files. + +The function must accept three arguments: the name of the muse source +file, the name of the just-published file, and the name of the +second-stage target file. The name of the second-stage target file is +the same as that of the just-published file if no second-stage +publishing is required. + +@item :header +Header used for publishing files of this style. + +This may be a variable, text, or a filename. It is inserted at the +beginning of a file, after evaluating the publishing markup. + +@item :footer +Footer used for publishing files of this style. + +This may be a variable, text, or a filename. It is inserted at the end +of a file, after evaluating the publishing markup. + +@item :style-sheet +Style sheet used for publishing files of this style. + +This may be a variable or text. It is used in the header of HTML and +XHTML based publishing styles. + +@item :browser +The function used to browse the published result of files of this style. + +@end table + +@node Deriving Styles, , Style Elements, Extending Muse +@comment node-name, next, previous, up +@section Deriving a new style from an existing one +@cindex publishing styles, deriving + +To create a new style from an existing one, use @code{muse-derive-style} +as follows. This is a good way to fix something you don't like about a +particular publishing style, or to personalize it. + +@defun muse-derive-style new-name base-name &rest elements +@end defun + +The derived name is a string defining the new style, such as "my-html". +The base name must identify an existing style, such as "html" -- if you +have loaded @file{muse-html}. The style parameters are the same as +those used to create a style, except that they override whatever +definitions exist in the base style. However, some definitions only +partially override. The following parameters support partial +overriding. + +@xref{Style Elements}, for a complete list of all parameters. + +@table @option + +@item :functions +If a markup function is not found in the derived style's function list, +the base style's function list will be queried. + +@item :regexps +All regexps in the current style and the base style(s) will be used. + +@item :strings +If a markup string is not found in the derived style's string list, the +base style's string list will be queried. + +@end table + +@node Miscellaneous, Getting Help and Reporting Bugs, Extending Muse, Top +@comment node-name, next, previous, up +@chapter Miscellaneous add-ons, like a minor mode + +@menu +* Muse List Edit Minor Mode:: Edit lists easily in other major modes. +@end menu + +@node Muse List Edit Minor Mode, , , Miscellaneous +@comment node-name, next, previous, up +@section Edit lists easily in other major modes +@cindex muse-list-edit-minor-mode + +@code{muse-list-edit-minor-mode} is meant to be used with other major +modes, such as Message (for composing email) and debian-changelog-mode +(for editing debian/changelog files). + +It implements practically perfect support for editing and filling lists. +It can even handle nested lists. In addition to Muse-specific list +items ("-", numbers, definition lists, footnotes), it can also handle +items that begin with "*" or "+". Filling list items behaves in the +same way that it does in Muse, regardless of whether filladapt is also +enabled, which is the primary reason to use this tool. + +@subheading Installation + +To use it, add ``(require 'muse-mode)'' to your Emacs customization file +and add the function @code{turn-on-muse-list-edit-minor-mode} to any +mode hooks where you wish to enable this minor mode. + +@subheading Keybindings + +@code{muse-list-edit-minor-mode} uses the following keybindings. + +@table @kbd + +@item M-RET (`muse-l-e-m-m-insert-list-item') +Insert a new list item at point, using the indentation level of the +current list item. + +@item C-< (`muse-l-e-m-m-decrease-list-item-indent') +Decrease indentation of the current list item. + +@item C-> (`muse-l-e-m-m-increase-list-item-indent') +Increase indentation of the current list item. + +@end table + +@subheading Functions + +@defun muse-list-edit-minor-mode +This is a global minor mode for editing files with lists. +It is meant to be used with other major modes, and not with Muse mode. + +Interactively, with no prefix argument, toggle the mode. +With universal prefix @var{arg} turn mode on. +With zero or negative @var{arg} turn mode off. + +This minor mode provides the Muse keybindings for editing lists, +and support for filling lists properly. + +It recognizes not only Muse-style lists, which use the "-" +character or numbers, but also lists that use asterisks or plus +signs. This should make the minor mode generally useful. + +Definition lists and footnotes are also recognized. + +Note that list items may omit leading spaces, for compatibility +with modes that set @code{left-margin}, such as +@code{debian-changelog-mode}. +@end defun + +@defun turn-on-muse-list-edit-minor-mode +Unconditionally turn on Muse list edit minor mode. +@end defun + +@defun turn-off-muse-list-edit-minor-mode +Unconditionally turn off Muse list edit minor mode. +@end defun + +@node Getting Help and Reporting Bugs, History, Miscellaneous, Top +@comment node-name, next, previous, up +@chapter Getting Help and Reporting Bugs +@cindex help, getting +@cindex bugs, reporting + +After you have read this guide, if you still have questions about +Muse, or if you have bugs to report, there are several places you can +go. + +@itemize @bullet + +@item +@uref{http://www.emacswiki.org/cgi-bin/wiki/EmacsMuse} is the +emacswiki.org page, and anyone may add tips, hints, or bug descriptions +to it. + +@item +@uref{http://mwolson.org/projects/EmacsMuse.html} is the web page +that Michael Olson (the current maintainer) made for Muse. + +@item +Muse has several different mailing lists. + +@table @samp + +@item muse-el-announce +Low-traffic list for Muse-related announcements. + +You can join this mailing list (@email{muse-el-announce@@gna.org}) +using the subscription form at +@url{http://mail.gna.org/listinfo/muse-el-announce/}. This +mailing list is also available via Gmane (@url{http://gmane.org/}). The +group is called @samp{gmane.emacs.muse.announce}. + +@item muse-el-discuss +Discussion, bugfixes, suggestions, tips, and the like for Muse. +This mailing list also includes the content of muse-el-announce. + +You can join this mailing list (@email{muse-el-discuss@@gna.org}) +using the subscription form at +@url{http://mail.gna.org/listinfo/muse-el-discuss/}. This mailing +list is also available via Gmane with the identifier +@samp{gmane.emacs.muse.general}. + +@item muse-el-logs +Log messages for commits made to Muse. + +You can join this mailing list (@email{muse-el-logs@@gna.org}) using +the subscription form at +@url{http://mail.gna.org/listinfo/muse-el-logs/}. This mailing list +is also available via Gmane with the identifier +@samp{gmane.emacs.muse.scm}. + +@item muse-el-commits +Generated bug reports for Emacs Muse. If you use our bug-tracker at +@url{https://gna.org/bugs/?group=muse-el}, the bug reports will be +sent to this list automatically. + +You can join this mailing list (@email{muse-el-commits@@gna.org}) using +the subscription form at +@url{http://mail.gna.org/listinfo/muse-el-commits/}. This mailing list +is also available via Gmane with the identifier +@samp{gmane.emacs.muse.cvs}. + +@item muse-el-internationalization +Discussion of translation of the Muse website and documentation into +many languages. + +You can join this mailing list +(@email{muse-el-internationalization@@gna.org}) using the subscription +form at @url{http://mail.gna.org/listinfo/internationalization/}. This +mailing list is also available via Gmane with the identifier +@samp{gmane.emacs.muse.internationalization}. + +@end table + +@item +You can visit the IRC Freenode channel @samp{#emacs}. Many of the +contributors are frequently around and willing to answer your +questions. The @samp{#muse} channel is also available for +Muse-specific help, and its current maintainer hangs out there. + +@item +The maintainer of Emacs Muse, Michael Olson, may be contacted at +@email{mwolson@@gnu.org}. He can be rather slow at answering email, so +it is often better to use the muse-el-discuss mailing list. + +@end itemize + +@node History, Contributors, Getting Help and Reporting Bugs, Top +@comment node-name, next, previous, up +@chapter History of This Document +@cindex history, of Muse + +@itemize +@item 2004 +John Wiegley started Muse upon realizing that EmacsWiki had some serious +limitations. Around February 2004, he started making "emacs-wiki version +3.00 APLHA", which eventually became known as Muse. + +Most of those who frequent the emacs-wiki mailing list continued to use +emacs-wiki, mainly because Planner hasn't been ported over to it. + +As of 2004-12-01, Michael Olson became the maintainer of Muse, as per +John Wiegley's request. + +@item 2005 +Michael Olson overhauled this document and added many new sections in +preparation for the first release of Muse (3.01). + +@end itemize + +@node Contributors, GNU Free Documentation License, History, Top +@comment node-name, next, previous, up +@chapter Contributors to This Documentation +@cindex contributors + +The first draft of this document was taken from the emacs-wiki texinfo +manual. Michael Olson adapted it for Muse and added most of its +content. + +John Sullivan did a majority of the work on the emacs-wiki texinfo +manual. + +While Sacha Chua maintained emacs-wiki, she worked quite a bit on the +emacs-wiki texinfo manual. + + +@node GNU Free Documentation License, Concept Index, Contributors, Top +@appendix GNU Free Documentation License +@include doclicense.texi + + +@node Concept Index, , GNU Free Documentation License, Top +@comment node-name, next, previous, up +@unnumbered Index + +@printindex cp + +@bye