diff options
author | 2011-03-17 11:23:07 +0100 | |
---|---|---|
committer | 2011-03-17 11:23:07 +0100 | |
commit | 57366f385a2f1f35bbe741d7542096db81368c72 (patch) | |
tree | 0313b707c3a472aec1c857dd75a4ad56cba7f747 /emacs.d/elisp/muse/muse-book.el | |
parent | a502df33cea9806665f550d93999d89585269e93 (diff) | |
download | dotfiles-57366f385a2f1f35bbe741d7542096db81368c72.tar.gz dotfiles-57366f385a2f1f35bbe741d7542096db81368c72.zip |
Big changes, last one before I wipe it all.
* Added muse
* Added graphviz-dot-mode
* Remove all trailing whitespace on save.
This is the last commit I'm going to do before throwing it all away
again.
Diffstat (limited to 'emacs.d/elisp/muse/muse-book.el')
-rw-r--r-- | emacs.d/elisp/muse/muse-book.el | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/emacs.d/elisp/muse/muse-book.el b/emacs.d/elisp/muse/muse-book.el new file mode 100644 index 0000000..213a64e --- /dev/null +++ b/emacs.d/elisp/muse/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{<lisp>(muse-publishing-directive \"title\")</lisp>} +\\author{<lisp>(muse-publishing-directive \"author\")</lisp>} +\\date{<lisp>(muse-publishing-directive \"date\")</lisp>} + +\\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 + "<lisp>(muse-latex-bibliography)</lisp> +\\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 |