1 ;;; muse-groff.el --- publish groff -mom -mwww files
3 ;; Copyright (C) 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
6 ;; Author: Andrew J. Korty (ajk AT iu DOT edu)
7 ;; Date: Tue 5-Jul-2005
9 ;; This file is part of Emacs Muse. It is not part of GNU Emacs.
11 ;; Emacs Muse is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published
13 ;; by the Free Software Foundation; either version 3, or (at your
14 ;; option) any later version.
16 ;; Emacs Muse is distributed in the hope that it will be useful, but
17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ;; General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with Emacs Muse; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, USA.
32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
34 ;; Muse Publishing Using groff -mom -mwww
36 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38 (require 'muse-publish
)
40 (defgroup muse-groff nil
41 "Rules for marking up a Muse file with groff -mom -mwww macros."
44 (defcustom muse-groff-extension
".groff"
45 "Default file extension for publishing groff -mom -mwww files."
49 (defcustom muse-groff-pdf-extension
".pdf"
50 "Default file extension for publishing groff -mom -mwww files to PDF."
54 (defcustom muse-groff-header
55 ".TITLE \"<lisp>(muse-publishing-directive \"title\")</lisp>\"
56 .SUBTITLE \"<lisp>(muse-publishing-directive \"date\")</lisp>\"
57 .AUTHOR \"<lisp>(muse-publishing-directive \"author\")</lisp>\"
65 <lisp>(and muse-publish-generate-contents \".TOC\n\")</lisp>\n"
66 "Header used for publishing groff -mom -mwww files."
67 :type
'(choice string file
)
70 (defcustom muse-groff-footer
" "
71 "Footer used for publishing groff -mom -mwww files."
72 :type
'(choice string file
)
75 (defcustom muse-groff-markup-regexps
76 `((10400 ,(concat "\\(\n</\\(blockquote\\|center\\)>\\)?\n"
79 "]*\n\\)+\\(<\\(blockquote\\|center\\)>\n\\)?")
80 0 muse-groff-markup-paragraph
))
81 "List of markup regexps for identifying regions in a Muse page.
82 For more on the structure of this list, see `muse-publish-markup-regexps'."
83 :type
'(repeat (choice
84 (list :tag
"Markup rule"
86 (choice regexp symbol
)
88 (choice string function symbol
))
92 (defcustom muse-groff-markup-functions
93 '((table . muse-groff-markup-table
))
94 "An alist of style types to custom functions for that kind of text.
95 For more on the structure of this list, see
96 `muse-publish-markup-functions'."
97 :type
'(alist :key-type symbol
:value-type function
)
100 (defcustom muse-groff-markup-tags
102 "A list of tag specifications, for specially marking up GROFF."
103 :type
'(repeat (list (string :tag
"Markup tag")
104 (boolean :tag
"Expect closing tag" :value t
)
105 (boolean :tag
"Parse attributes" :value nil
)
106 (boolean :tag
"Nestable" :value nil
)
110 (defcustom muse-groff-markup-strings
111 `((image-with-desc .
"\n.MPIMG -R %s.%s\n")
112 (image .
"\n.MPIMG -R %s.%s\n")
113 (image-link .
"\n.\\\" %s\n.MPIMG -R %s.%s")
114 (url .
"\n.URL %s %s\n\\z")
115 (link .
"\n.URL %s %s\n\\z")
116 (email-addr .
"\f[C]%s\f[]")
119 (no-break-space .
"\\h")
123 ;; (part . "\\part{")
125 ;; (chapter . "\\chapter{")
126 ;; (chapter-end . "}")
127 (section .
".HEAD \"")
129 (subsection .
".SUBHEAD \"")
130 (subsection-end .
"\"")
131 (subsubsection .
".PARAHEAD \"")
132 (subsubsection-end .
"\"")
133 ;; (footnote . "\\c\n.FOOTNOTE\n")
134 ;; (footnote-end . "\n.FOOTNOTE OFF\n")
135 ;; (footnotemark . "\\footnotemark[%d]")
136 ;; (footnotetext . "\\footnotetext[%d]{")
137 ;; (footnotetext-end . "}")
138 (begin-underline .
"\n.UNDERSCORE \"")
139 (end-underline .
"\"\n")
140 (begin-literal .
"\\fC")
141 (end-literal .
"\\fP")
142 (begin-emph .
"\\fI")
144 (begin-more-emph .
"\\fB")
145 (end-more-emph .
"\\fP")
146 (begin-most-emph .
"\\f(BI")
147 (end-most-emph .
"\\fP")
148 (begin-verse .
".QUOTE")
149 (end-verse .
".QUOTE OFF")
150 (begin-center .
"\n.CENTER\n")
151 (end-center .
"\n.QUAD L\n")
152 (begin-example .
,(concat
153 ".QUOTE_FONT CR\n.QUOTE_INDENT 1\n"".QUOTE_SIZE -2\n"
154 ".UNDERLINE_QUOTES OFF\n.QUOTE"))
155 (end-example .
".QUOTE OFF")
156 (begin-quote .
".BLOCKQUOTE")
157 (end-quote .
".BLOCKQUOTE OFF")
159 (begin-cite-author .
"")
160 (begin-cite-year .
"")
162 (begin-uli .
".list BULLET\n.SHIFT_LIST 2m\n.ITEM\n")
163 (end-uli .
"\n.LIST OFF")
164 (begin-oli .
".list DIGIT\n.SHIFT_LIST 2m\n.ITEM\n")
165 (end-oli .
"\n.LIST OFF")
167 (begin-dde .
"\\fP\n.IR 4P\n")
168 (end-ddt .
".IRX CLEAR"))
169 "Strings used for marking up text.
170 These cover the most basic kinds of markup, the handling of which
171 differs little between the various styles."
172 :type
'(alist :key-type symbol
:value-type string
)
175 (defcustom muse-groff-markup-specials
177 "A table of characters which must be represented specially."
178 :type
'(alist :key-type character
:value-type string
)
181 (defun muse-groff-markup-paragraph ()
182 (let ((end (copy-marker (match-end 0) t
)))
183 (goto-char (1+ (match-beginning 0)))
184 (delete-region (point) end
)
185 (unless (looking-at "\.\\(\\(\\(SUB\\|PARA\\)?HEAD \\)\\|RULE$\\)")
186 (muse-insert-markup ".ALD .5v\n.PP\n.ne 2\n"))))
188 (defun muse-groff-protect-leading-chars ()
189 "Protect leading periods and apostrophes from being interpreted as
191 (while (re-search-forward "^[.']" nil t
)
192 (replace-match "\\\\&\\&" t
)))
194 (defun muse-groff-concat-lists ()
198 (while (re-search-forward "^\.LIST[ \t]+\\(.*\\)\n" nil t
)
199 (setq arg
(match-string 1))
200 (if (string= arg
"OFF")
201 (setq begin
(match-beginning 0))
202 (if (and begin
(string= type arg
))
203 (delete-region begin
(match-end 0))
207 (defun muse-groff-fixup-dquotes ()
208 "Fixup double quotes."
210 (while (search-forward "\"" nil t
)
211 (unless (get-text-property (match-beginning 0) 'read-only
)
212 (if (and (bolp) (eq (char-before) ?
\n))
221 (defun muse-groff-prepare-buffer ()
222 (goto-char (point-min))
223 (muse-groff-protect-leading-chars))
225 (defun muse-groff-munge-buffer ()
226 (goto-char (point-min))
227 (muse-groff-concat-lists))
229 (defun muse-groff-pdf-browse-file (file)
230 (shell-command (concat "open " file
)))
232 (defun muse-groff-pdf-generate (file output-path final-target
)
233 (muse-publish-transform-output
234 file output-path final-target
"PDF"
236 (lambda (file output-path
)
239 (concat "file=%s; ext=%s; cd %s && cp $file$ext $file.ref && "
240 "groff -mom -mwww -t $file$ext > $file.ps && "
242 (file-name-sans-extension file
)
244 (file-name-directory output-path
))))
245 (shell-command command
))))
248 ;;; Register the Muse GROFF Publisher
250 (muse-define-style "groff"
251 :suffix
'muse-groff-extension
252 :regexps
'muse-groff-markup-regexps
253 ;;; :functions 'muse-groff-markup-functions
254 :strings
'muse-groff-markup-strings
255 :tags
'muse-groff-markup-tags
256 :specials
'muse-groff-markup-specials
257 :before
'muse-groff-prepare-buffer
258 :before-end
'muse-groff-munge-buffer
259 :header
'muse-groff-header
260 :footer
'muse-groff-footer
263 (muse-derive-style "groff-pdf" "groff"
264 :final
'muse-groff-pdf-generate
265 :browser
'muse-groff-pdf-browse-file
266 :osuffix
'muse-groff-pdf-extension
)
268 (provide 'muse-groff
)
270 ;;; muse-groff.el ends here
273 ;; indent-tabs-mode: nil