~ubuntu-branches/ubuntu/quantal/muse-el/quantal

« back to all changes in this revision

Viewing changes to lisp/muse-context.el

  • Committer: Bazaar Package Importer
  • Author(s): Michael W. Olson (GNU address)
  • Date: 2008-01-09 15:51:46 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080109155146-0wwzermvvzs9rqzo
Tags: 3.11-3ubuntu1
* Merge with with Debian unstable (LP: #137284). Remaining Ubuntu changes:
  - Keep manual.
  - Set Ubuntu MOTU to be Maintainer

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;;; muse-context.el --- publish entries in ConTeXt or PDF format
 
2
 
 
3
;; Copyright (C) 2007 Free Software Foundation, Inc.
 
4
 
 
5
;; Author: Jean Magnan de Bornier (jean@bornier.net)
 
6
;; Created: 16-Apr-2007
 
7
 
 
8
;; Emacs Muse is free software; you can redistribute it and/or modify
 
9
;; it under the terms of the GNU General Public License as published
 
10
;; by the Free Software Foundation; either version 3, or (at your
 
11
;; option) any later version.
 
12
 
 
13
;; This file when loaded allows you to publish .muse files as ConTeXt
 
14
;; files or as pdf files, using respectively the "context" and
 
15
;; "context-pdf" styles. It is far from being perfect, so any feedback
 
16
;; will be welcome and any mistake hopefully fixed.
 
17
 
 
18
;;; Author:
 
19
 
 
20
;; Jean Magnan de Bornier, who based this file on muse-latex.el and
 
21
;; made the context, context-pdf, context-slides, and
 
22
;; context-slides-pdf Muse publishing styles.
 
23
 
 
24
;; 16 Avril 2007
 
25
 
 
26
;;; Code:
 
27
 
 
28
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
29
;;
 
30
;; Muse ConTeXt Publishing
 
31
;;
 
32
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
33
 
 
34
(require 'muse-publish)
 
35
 
 
36
(defgroup muse-context nil
 
37
  "Rules for marking up a Muse file as a ConTeXt article."
 
38
  :group 'muse-publish)
 
39
 
 
40
(defcustom muse-context-extension ".tex"
 
41
  "Default file extension for publishing ConTeXt files."
 
42
  :type 'string
 
43
  :group 'muse-context)
 
44
 
 
45
(defcustom muse-context-pdf-extension ".pdf"
 
46
  "Default file extension for publishing ConTeXt files to PDF."
 
47
  :type 'string
 
48
  :group 'muse-context)
 
49
 
 
50
(defcustom muse-context-pdf-program "texexec --pdf"
 
51
  "The program that is called to generate PDF content from ConTeXt content."
 
52
  :type 'string
 
53
  :group 'muse-context)
 
54
 
 
55
(defcustom muse-context-pdf-cruft '(".pgf" ".tmp" ".tui" ".tuo" ".toc"  ".log")
 
56
  "Extensions of files to remove after generating PDF output successfully."
 
57
  :type 'string
 
58
  :group 'muse-context)
 
59
 
 
60
(defcustom muse-context-header
 
61
  "\\setupinteraction [state=start]
 
62
\\usemodule[tikz]
 
63
\\usemodule[bib]\n
 
64
<lisp>(muse-context-setup-bibliography)</lisp>
 
65
 \\setuppublications[]\n
 
66
\\setuppublicationlist[]\n\\setupcite[]\n
 
67
\\starttext
 
68
\\startalignment[center]
 
69
  \\blank[2*big]
 
70
    {\\tfd <lisp>(muse-publishing-directive \"title\")</lisp>}
 
71
  \\blank[3*medium]
 
72
    {\\tfa <lisp>(muse-publishing-directive \"author\")</lisp>}
 
73
  \\blank[2*medium]
 
74
    {\\tfa <lisp>(muse-publishing-directive \"date\")</lisp>}
 
75
  \\blank[3*medium]
 
76
\\stopalignment
 
77
 
 
78
<lisp>(and muse-publish-generate-contents
 
79
           (not muse-context-permit-contents-tag)
 
80
           \"\\\\placecontent\n\\\\page[yes]\")</lisp>\n\n"
 
81
  "Header used for publishing ConTeXt files.  This may be text or a filename."
 
82
  :type 'string
 
83
  :group 'muse-context)
 
84
 
 
85
(defcustom muse-context-footer "<lisp>(muse-context-bibliography)</lisp>
 
86
\\stoptext\n"
 
87
  "Footer used for publishing ConTeXt files.  This may be text or a filename."
 
88
  :type 'string
 
89
  :group 'muse-context)
 
90
 
 
91
(defcustom muse-context-markup-regexps
 
92
  `(;; numeric ranges
 
93
    (10000 "\\([0-9]+\\)-\\([0-9]+\\)" 0 "\\1--\\2")
 
94
 
 
95
    ;; be careful of closing quote pairs
 
96
    (10100 "\"'" 0 "\"\\\\-'"))
 
97
  "List of markup regexps for identifying regions in a Muse page.
 
98
For more on the structure of this list, see `muse-publish-markup-regexps'."
 
99
  :type '(repeat (choice
 
100
                  (list :tag "Markup rule"
 
101
                        integer
 
102
                        (choice regexp symbol)
 
103
                        integer
 
104
                        (choice string function symbol))
 
105
                  function))
 
106
  :group 'muse-context)
 
107
 
 
108
(defcustom muse-context-markup-functions
 
109
  '((table . muse-context-markup-table))
 
110
  "An alist of style types to custom functions for that kind of text.
 
111
For more on the structure of this list, see
 
112
`muse-publish-markup-functions'."
 
113
  :type '(alist :key-type symbol :value-type function)
 
114
  :group 'muse-context)
 
115
 
 
116
(defcustom muse-context-markup-strings
 
117
  '((image-with-desc . "\\placefigure[][]{%3%}{\\externalfigure[%1%.%2%]}")
 
118
    (image           . "\\placefigure[][]{}{\\externalfigure[%s.%s]}")
 
119
    (image-link      . "\\useURL[aa][%s][][%1%] \\from[aa]")
 
120
    (anchor-ref      . "\\goto{%2%}{}[%1%]")
 
121
    (url             . "\\useURL[aa][%s][][%s] \\from[aa]")
 
122
    (url-and-desc    . "\\useURL[bb][%s][][%s]\\from[bb]\\footnote{%1%}")
 
123
    (link            . "\\goto{%2%}[program(%1%)]\\footnote{%1%}")
 
124
    (link-and-anchor . "\\useexternaldocument[%4%][%4%][] \\at{%3%, page}{}[%4%::%2%]\\footnote{%1%}")
 
125
    (email-addr      . "\\useURL[mail][mailto:%s][][%s]\\from[mail]")
 
126
    (anchor          . "\\reference[%s] ")
 
127
    (emdash          . "---")
 
128
    (comment-begin   . "\\doifmode{comment}{")
 
129
    (comment-end     . "}")
 
130
    (rule            . "\\blank[medium]\\hrule\\blank[medium]")
 
131
    (no-break-space  . "~")
 
132
    (enddots         . "\\ldots ")
 
133
    (dots            . "\\dots ")
 
134
    (part            . "\\part{")
 
135
    (part-end        . "}")
 
136
    (chapter         . "\\chapter{")
 
137
    (chapter-end     . "}")
 
138
    (section         . "\\section{")
 
139
    (section-end     . "}")
 
140
    (subsection      . "\\subsection{")
 
141
    (subsection-end  . "}")
 
142
    (subsubsection   . "\\subsubsection{")
 
143
    (subsubsection-end . "}")
 
144
    (section-other   . "\\subsubsubject{")
 
145
    (section-other-end . "}")
 
146
    (footnote        . "\\footnote{")
 
147
    (footnote-end    . "}")
 
148
    (footnotetext    . "\\footnotetext[%d]{")
 
149
    (begin-underline . "\\underbar{")
 
150
    (end-underline   . "}")
 
151
    (begin-literal   . "\\type{")
 
152
    (end-literal     . "}")
 
153
    (begin-emph      . "{\\em ")
 
154
    (end-emph        . "}")
 
155
    (begin-more-emph . "{\\bf ")
 
156
    (end-more-emph   . "}")
 
157
    (begin-most-emph . "{\\bf {\\em ")
 
158
    (end-most-emph   . "}}")
 
159
    (begin-example   . "\\starttyping")
 
160
    (end-example     . "\\stoptyping")
 
161
    (begin-center    . "\\startalignment[center]\n")
 
162
    (end-center      . "\n\\stopalignment")
 
163
    (begin-quote     . "\\startquotation\n")
 
164
    (end-quote       . "\n\\stopquotation")
 
165
    (begin-cite     . "\\cite[authoryear][")
 
166
    (begin-cite-author . "\\cite[author][")
 
167
    (begin-cite-year . "\\cite[year][")
 
168
    (end-cite        . "]")
 
169
    (begin-uli       . "\\startitemize\n")
 
170
    (end-uli         . "\n\\stopitemize")
 
171
    (begin-uli-item  . "\\item ")
 
172
    (begin-oli       . "\\startitemize[n]\n")
 
173
    (end-oli         . "\n\\stopitemize")
 
174
    (begin-oli-item  . "\\item ")
 
175
    (begin-dl        . "\\startitemize\n")
 
176
    (end-dl          . "\n\\stopitemize")
 
177
    (begin-ddt       . "\\head ")
 
178
    (end-ddt         . "\n")
 
179
    (begin-verse     . "\\blank[big]")
 
180
    (end-verse-line  . "\\par")
 
181
    (verse-space     . "\\fixedspaces ~~")
 
182
    (end-verse       . "\\blank[big]"))
 
183
  "Strings used for marking up text.
 
184
These cover the most basic kinds of markup, the handling of which
 
185
differs little between the various styles."
 
186
  :type '(alist :key-type symbol :value-type string)
 
187
  :group 'muse-context)
 
188
 
 
189
(defcustom muse-context-slides-header
 
190
  "\\usemodule[<lisp>(if (string-equal (muse-publishing-directive \"module\") nil) \"pre-01\" (muse-publishing-directive \"module\"))</lisp>]
 
191
\\usemodule[tikz]
 
192
\\usemodule[newmat]
 
193
\\setupinteraction [state=start]
 
194
\\starttext
 
195
\\TitlePage { <lisp>(muse-publishing-directive \"title\")</lisp>
 
196
\\blank[3*medium]
 
197
\\tfa <lisp>(muse-publishing-directive \"author\")</lisp>
 
198
 \\blank[2*medium]
 
199
  \\tfa <lisp>(muse-publishing-directive \"date\")</lisp>}"
 
200
  "Header for publishing a presentation (slides) using ConTeXt.
 
201
Any of the predefined modules, which are available in the
 
202
tex/context/base directory, can be used by writing a \"module\"
 
203
directive at the top of the muse file; if no such directive is
 
204
provided, module pre-01 is used.  Alternatively, you can use your
 
205
own style (\"mystyle\", in this example) by replacing
 
206
\"\\usemodule[]\" with \"\\input mystyle\".
 
207
 
 
208
This may be text or a filename."
 
209
  :type 'string
 
210
  :group 'muse-context)
 
211
 
 
212
(defcustom muse-context-slides-markup-strings
 
213
   '((section      . "\\Topic {")
 
214
     (subsection   . "\\page \n{\\bf ")
 
215
     (subsubsection . "{\\em "))
 
216
  "Strings used for marking up text in ConTeXt slides."
 
217
  :type '(alist :key-type symbol :value-type string)
 
218
  :group 'muse-context)
 
219
 
 
220
(defcustom muse-context-markup-specials-document
 
221
  '((?\\ . "\\textbackslash")
 
222
    (?\_ . "\\textunderscore")
 
223
    (?\< . "\\switchtobodyfont[small]")
 
224
    (?\> . "\\switchtobodyfont[big]")
 
225
    (?^  . "\\^")
 
226
    (?\~ . "\\~")
 
227
    (?\@ . "\\@")
 
228
    (?\$ . "\\$")
 
229
    (?\% . "\\%")
 
230
    (?\{ . "\\{")
 
231
    (?\} . "\\}")
 
232
    (?\& . "\\&")
 
233
    (?\# . "\\#"))
 
234
  "A table of characters which must be represented specially.
 
235
These are applied to the entire document, sans already-escaped
 
236
regions."
 
237
  :type '(alist :key-type character :value-type string)
 
238
  :group 'muse-context)
 
239
 
 
240
(defcustom muse-context-markup-specials-example
 
241
  '()
 
242
  "A table of characters which must be represented specially.
 
243
These are applied to <example> regions.
 
244
 
 
245
With the default interpretation of <example> regions, no specials
 
246
need to be escaped."
 
247
  :type '(alist :key-type character :value-type string)
 
248
  :group 'muse-context)
 
249
 
 
250
(defcustom muse-context-markup-specials-literal
 
251
  '()
 
252
  "A table of characters which must be represented specially.
 
253
This applies to =monospaced text= and <code> regions."
 
254
  :type '(alist :key-type character :value-type string)
 
255
  :group 'muse-context)
 
256
 
 
257
(defcustom muse-context-markup-specials-url
 
258
  '((?\\ . "\\textbackslash")
 
259
    (?\_ . "\\_")
 
260
    (?\< . "\\<")
 
261
    (?\> . "\\>")
 
262
    (?\$ . "\\$")
 
263
    (?\% . "\\%")
 
264
    (?\{ . "\\{")
 
265
    (?\} . "\\}")
 
266
    (?\& . "\\&")
 
267
    (?\# . "\\#"))
 
268
  "A table of characters which must be represented specially.
 
269
These are applied to URLs."
 
270
  :type '(alist :key-type character :value-type string)
 
271
  :group 'muse-context)
 
272
 
 
273
(defcustom muse-context-markup-specials-image
 
274
  '((?\\ . "\\textbackslash")       ; cannot find suitable replacement
 
275
    (?\< . "\\<")
 
276
    (?\> . "\\>")
 
277
    (?\$ . "\\$")
 
278
    (?\% . "\\%")
 
279
    (?\{ . "\\{")
 
280
    (?\} . "\\}")
 
281
    (?\& . "\\&")
 
282
    (?\# . "\\#")                     ; cannot find suitable replacement
 
283
    )
 
284
  "A table of characters which must be represented specially.
 
285
These are applied to image filenames."
 
286
  :type '(alist :key-type character :value-type string)
 
287
  :group 'muse-context)
 
288
 
 
289
(defun muse-context-decide-specials (context)
 
290
  "Determine the specials to escape, depending on the CONTEXT argument."
 
291
  (cond ((memq context '(underline emphasis document url-desc verbatim))
 
292
         muse-context-markup-specials-document)
 
293
        ((eq context 'image)
 
294
         muse-context-markup-specials-image)
 
295
        ((memq context '(email url))
 
296
         muse-context-markup-specials-url)
 
297
        ((eq context 'literal)
 
298
         muse-context-markup-specials-literal)
 
299
        ((eq context 'example)
 
300
         muse-context-markup-specials-example)
 
301
        (t (error "Invalid context argument '%s' in muse-context" context))))
 
302
 
 
303
(defun muse-context-markup-table ()
 
304
  (let* ((table-info (muse-publish-table-fields (match-beginning 0)
 
305
                                                (match-end 0)))
 
306
         (row-len (car table-info))
 
307
         (field-list (cdr table-info)))
 
308
    (when table-info
 
309
      (muse-insert-markup "\\starttable[|"
 
310
                          (mapconcat 'symbol-name (make-vector row-len 'l)
 
311
                                     "|") "|]\n \\HL\n \\VL ")
 
312
      (dolist (fields field-list)
 
313
        (let ((type (car fields)))
 
314
          (setq fields (cdr fields))
 
315
          (when (= type 3)
 
316
            (muse-insert-markup ""))
 
317
          (insert (car fields))
 
318
          (setq fields (cdr fields))
 
319
          (dolist (field fields)
 
320
            (muse-insert-markup " \\VL ")
 
321
            (insert field))
 
322
          (muse-insert-markup "\\VL\\NR\n \\HL\n \\VL ")
 
323
          (when (= type 2)
 
324
            (muse-insert-markup " "))))
 
325
      (muse-insert-markup "\\stoptable\n")
 
326
      (while (search-backward "VL \\stoptable" nil t)
 
327
        (replace-match "stoptable" nil t)))))
 
328
 
 
329
(defun muse-context-fixup-dquotes ()
 
330
  "Fixup double quotes."
 
331
  (goto-char (point-min))
 
332
  (let ((open t))
 
333
    (while (search-forward "\"" nil t)
 
334
      (unless (get-text-property (match-beginning 0) 'read-only)
 
335
        (when (or (bobp)
 
336
                  (eq (char-before) ?\n))
 
337
          (setq open t))
 
338
        (if open
 
339
            (progn
 
340
              (replace-match "``")
 
341
              (setq open nil))
 
342
          (replace-match "''")
 
343
          (setq open t))))))
 
344
 
 
345
(defcustom muse-context-permit-contents-tag nil
 
346
  "If nil, ignore <contents> tags.  Otherwise, insert table of contents.
 
347
 
 
348
Most of the time, it is best to have a table of contents on the
 
349
first page, with a new page immediately following.  To make this
 
350
work with documents published in both HTML and ConTeXt, we need to
 
351
ignore the <contents> tag.
 
352
 
 
353
If you don't agree with this, then set this option to non-nil,
 
354
and it will do what you expect."
 
355
  :type 'boolean
 
356
  :group 'muse-context)
 
357
 
 
358
(defun muse-context-fixup-citations ()
 
359
  "Replace semicolons in multi-head citations with colons."
 
360
  (goto-char (point-min))
 
361
  (while (re-search-forward "\\\\cite.?\\[" nil t)
 
362
    (let ((start (point))
 
363
          (end (re-search-forward "]")))
 
364
      (save-restriction
 
365
        (narrow-to-region start end)
 
366
        (goto-char (point-min))
 
367
        (while (re-search-forward ";" nil t)
 
368
          (replace-match ","))))))
 
369
 
 
370
(defun muse-context-munge-buffer ()
 
371
  (muse-context-fixup-dquotes)
 
372
  (muse-context-fixup-citations)
 
373
  (when (and muse-context-permit-contents-tag
 
374
             muse-publish-generate-contents)
 
375
    (goto-char (car muse-publish-generate-contents))
 
376
    (muse-insert-markup "\\placecontent")))
 
377
 
 
378
(defun muse-context-bibliography ()
 
379
  (save-excursion
 
380
    (goto-char (point-min))
 
381
    (if (re-search-forward "\\\\cite.?\\[" nil t)
 
382
        "\\completepublications[criterium=all]"
 
383
      "")))
 
384
 
 
385
(defun muse-context-setup-bibliography ()
 
386
  (save-excursion
 
387
    (goto-char (point-min))
 
388
    (if (re-search-forward "\\\\cite.?\\[" nil t)
 
389
        (concat
 
390
         "\\usemodule[bibltx]\n\\setupbibtex [database="
 
391
         (muse-publishing-directive "bibsource") "]")
 
392
      "")))
 
393
 
 
394
(defun muse-context-pdf-browse-file (file)
 
395
  (shell-command (concat "open " file)))
 
396
 
 
397
(defun muse-context-pdf-generate (file output-path final-target)
 
398
  (apply
 
399
   #'muse-publish-transform-output
 
400
   file output-path final-target "PDF"
 
401
   (function
 
402
    (lambda (file output-path)
 
403
      (let* ((fnd (file-name-directory output-path))
 
404
             (command (format "cd \"%s\"; %s \"%s\""
 
405
                              fnd muse-context-pdf-program
 
406
                              (file-relative-name file fnd)))
 
407
             (times 0)
 
408
             result)
 
409
        ;; XEmacs can sometimes return a non-number result.  We'll err
 
410
        ;; on the side of caution by continuing to attempt to generate
 
411
        ;; the PDF if this happens and treat the final result as
 
412
        ;; successful.
 
413
        (while (and (< times 2)
 
414
                    (or (not (numberp result))
 
415
                        (not (eq result 0))
 
416
                        ;; table of contents takes 2 passes
 
417
;;                         (file-readable-p
 
418
;;                          (muse-replace-regexp-in-string
 
419
;;                           "\\.tex\\'" ".toc" file t t))
 
420
                        ))
 
421
          (setq result (shell-command command)
 
422
                times (1+ times)))
 
423
        (if (or (not (numberp result))
 
424
                (eq result 0))
 
425
            t
 
426
          nil))))
 
427
   muse-context-pdf-cruft))
 
428
 
 
429
(muse-define-style "context"
 
430
                   :suffix    'muse-context-extension
 
431
                   :regexps   'muse-context-markup-regexps
 
432
                   :functions 'muse-context-markup-functions
 
433
                   :strings   'muse-context-markup-strings
 
434
                   :specials  'muse-context-decide-specials
 
435
                   :after     'muse-context-munge-buffer
 
436
                   :header    'muse-context-header
 
437
                   :footer    'muse-context-footer
 
438
                   :browser   'find-file)
 
439
 
 
440
(muse-derive-style "context-pdf" "context"
 
441
                   :final   'muse-context-pdf-generate
 
442
                   :browser 'muse-context-pdf-browse-file
 
443
                   :link-suffix 'muse-context-pdf-extension
 
444
                   :osuffix 'muse-context-pdf-extension)
 
445
 
 
446
(muse-derive-style "context-slides" "context"
 
447
                   :header  'muse-context-slides-header
 
448
                   :strings 'muse-context-slides-markup-strings)
 
449
 
 
450
(muse-derive-style "context-slides-pdf" "context-pdf"
 
451
                   :header  'muse-context-slides-header
 
452
                   :strings 'muse-context-slides-markup-strings)
 
453
 
 
454
(provide 'muse-context)
 
455
 
 
456
;;; muse-context.el ends here