1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;; Muse Publishing Using groff -mom -mwww
5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7 (require 'muse-publish
)
9 (defgroup muse-groff nil
10 "Rules for marking up a Muse file with groff -mom -mwww macros."
13 (defcustom muse-groff-extension
".groff"
14 "Default file extension for publishing groff -mom -mwww files."
18 (defcustom muse-groff-pdf-extension
".pdf"
19 "Default file extension for publishing groff -mom -mwww files to PDF."
23 (defcustom muse-groff-header
24 ".TITLE \"<lisp>(muse-publishing-directive \"title\")</lisp>\"
25 .SUBTITLE \"<lisp>(muse-publishing-directive \"date\")</lisp>\"
26 .AUTHOR \"<lisp>(muse-publishing-directive \"author\")</lisp>\"
34 <lisp>(and muse-publish-generate-contents \".TOC\n\")</lisp>\n"
35 "Header used for publishing groff -mom -mwww files."
36 :type
'(choice string file
)
39 (defcustom muse-groff-footer
" "
40 "Footer used for publishing groff -mom -mwww files."
41 :type
'(choice string file
)
44 (defcustom muse-groff-markup-regexps
45 `((10400 ,(concat "\\(\n</\\(blockquote\\|center\\)>\\)?\n"
48 "]*\n\\)+\\(<\\(blockquote\\|center\\)>\n\\)?")
49 0 muse-groff-markup-paragraph
))
50 "List of markup regexps for identifying regions in a Muse page.
51 For more on the structure of this list, see `muse-publish-markup-regexps'."
52 :type
'(repeat (choice
53 (list :tag
"Markup rule"
55 (choice regexp symbol
)
57 (choice string function symbol
))
61 (defcustom muse-groff-markup-functions
62 '((table . muse-groff-markup-table
))
63 "An alist of style types to custom functions for that kind of text.
64 For more on the structure of this list, see
65 `muse-publish-markup-functions'."
66 :type
'(alist :key-type symbol
:value-type function
)
69 (defcustom muse-groff-markup-tags
71 "A list of tag specifications, for specially marking up GROFF."
72 :type
'(repeat (list (string :tag
"Markup tag")
73 (boolean :tag
"Expect closing tag" :value t
)
74 (boolean :tag
"Parse attributes" :value nil
)
78 (defcustom muse-groff-markup-strings
79 `((image-with-desc .
"\n.MPIMG -R %s\n")
80 (image-link .
"\n.MPIMG -R %s\n")
81 (url-with-image .
"\n.\\\" %s\n.MPIMG -R %s")
82 (url .
"\n.URL %s %s\n\\z")
83 (link .
"\n.URL %s %s\n\\z")
84 (email-addr .
"\f[C]%s\f[]")
87 (no-break-space .
"\\h")
92 ;; (chapter . "\\chapter{")
93 ;; (chapter-end . "}")
94 (section .
".HEAD \"")
96 (subsection .
".SUBHEAD \"")
97 (subsection-end .
"\"")
98 (subsubsection .
".PARAHEAD \"")
99 (subsubsection-end .
"\"")
100 ;; (footnote . "\\c\n.FOOTNOTE\n")
101 ;; (footnote-end . "\n.FOOTNOTE OFF\n")
102 ;; (footnotemark . "\\footnotemark[%d]")
103 ;; (footnotetext . "\\footnotetext[%d]{")
104 ;; (footnotetext-end . "}")
105 (begin-underline .
"\n.UNDERSCORE \"")
106 (end-underline .
"\"\n")
107 (begin-literal .
"\\fC")
108 (end-literal .
"\\fP")
109 (begin-emph .
"\\fI")
111 (begin-more-emph .
"\\fB")
112 (end-more-emph .
"\\fP")
113 (begin-most-emph .
"\\f(BI")
114 (end-most-emph .
"\\fP")
115 (begin-verse .
".QUOTE")
116 (end-verse .
".QUOTE OFF")
117 (begin-center .
"\n.CENTER\n")
118 (end-center .
"\n.QUAD L\n")
119 (begin-example .
,(concat
120 ".QUOTE_FONT CR\n.QUOTE_INDENT 1\n"".QUOTE_SIZE -2\n"
121 ".UNDERLINE_QUOTES OFF\n.QUOTE"))
122 (end-example .
".QUOTE OFF")
123 (begin-quote .
".BLOCKQUOTE")
124 (end-quote .
".BLOCKQUOTE OFF")
125 (begin-uli .
".list BULLET\n.SHIFT_LIST 2m\n.ITEM\n")
126 (end-uli .
"\n.LIST OFF")
127 (begin-oli .
".list DIGIT\n.SHIFT_LIST 2m\n.ITEM\n")
128 (end-oli .
"\n.LIST OFF")
130 (begin-dde .
"\\fP\n.IR 4P\n")
131 (end-ddt .
".IRX CLEAR"))
132 "Strings used for marking up text.
133 These cover the most basic kinds of markup, the handling of which
134 differs little between the various styles."
135 :type
'(alist :key-type symbol
:value-type string
)
138 (defcustom muse-groff-markup-specials
140 "A table of characters which must be represented specially."
141 :type
'(alist :key-type character
:value-type string
)
144 (defun muse-groff-markup-paragraph ()
145 (let ((end (copy-marker (match-end 0) t
)))
146 (goto-char (1+ (match-beginning 0)))
147 (delete-region (point) end
)
148 (unless (looking-at "\.\\(\\(\\(SUB\\|PARA\\)?HEAD \\)\\|RULE$\\)")
149 (muse-insert-markup ".ALD .5v\n.PP\n.ne 2\n"))))
151 (defun muse-groff-protect-leading-chars ()
152 "Protect leading periods and apostrophes from being interpreted as
154 (while (re-search-forward "^[.']" nil t
)
155 (replace-match "\\\\&\\&" t
)))
157 (defun muse-groff-concat-lists ()
161 (while (re-search-forward "^\.LIST[ \t]+\\(.*\\)\n" nil t
)
162 (setq arg
(match-string 1))
163 (if (string= arg
"OFF")
164 (setq begin
(match-beginning 0))
165 (if (and begin
(string= type arg
))
166 (delete-region begin
(match-end 0))
170 (defun muse-groff-fixup-dquotes ()
171 "Fixup double quotes."
173 (while (search-forward "\"" nil t
)
174 (unless (get-text-property (match-beginning 0) 'read-only
)
175 (if (and (bolp) (eq (char-before) ?
\n))
184 (defun muse-groff-prepare-buffer ()
185 (goto-char (point-min))
186 (muse-groff-protect-leading-chars))
188 (defun muse-groff-finalize-buffer ()
189 (goto-char (point-min))
190 (muse-groff-concat-lists))
192 (defun muse-groff-pdf-browse-file (file)
193 (shell-command (concat "open " file
)))
195 (defun muse-groff-pdf-generate (file output-path final-target
)
196 (muse-publish-transform-output
197 file output-path final-target
"PDF"
199 (lambda (file output-path
)
202 (concat "file=%s; ext=%s; cd %s && cp $file$ext $file.ref && "
203 "groff -mom -mwww -t $file$ext > $file.ps && "
205 (file-name-sans-extension file
)
207 (file-name-directory output-path
))))
208 (shell-command command
))))
211 (unless (assoc "groff" muse-publishing-styles
)
212 (muse-define-style "groff"
213 :suffix
'muse-groff-extension
214 :regexps
'muse-groff-markup-regexps
215 ;;; :functions 'muse-groff-markup-functions
216 :strings
'muse-groff-markup-strings
217 :tags
'muse-groff-markup-tags
218 :specials
'muse-groff-markup-specials
219 :before
'muse-groff-prepare-buffer
220 :after
'muse-groff-finalize-buffer
221 :header
'muse-groff-header
222 :footer
'muse-groff-footer
225 (muse-derive-style "groff-pdf" "groff"
226 :final
'muse-groff-pdf-generate
227 :browser
'muse-groff-pdf-browse-file
228 :osuffix
'muse-groff-pdf-extension
))
230 (provide 'muse-groff
)
232 ;;; muse-groff.el ends here
235 ;; indent-tabs-mode: nil