--- title: '[emacs][muse] Carbon EmacsでMuseのPDFを生成する' author: kazu634 date: 2009-01-09 url: /2009/01/10/_1191/ wordtwit_post_info: - 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:4481;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}' categories: - つれづれ ---

f:id:sirocco634:20090110073921p:image

対象とする人

基本的な設定

Carbon Emacsでの設定例は以下のサイトが参考になります。

を参考にするといいです。特に「[hiro] muse-modeでpdf作成」では小川版のplatexを用いた関数が定義されているようなので、これを用います。

問題発生!

小川版のpLatexは文字コードとしてshift-jisしかダメなようです。でもそれだと、文字コードの違うtexソースは文字化けして、platexを通りません。結果的に、dviファイルが作成されずエラーが出てPDFが作れなくなります。

[hiro] muse-modeでpdf作成」ではPDF作成用の関数を自前で定義しているようです:

(defun muse-latex-pdf-generate2 (file output-path final-target)
(muse-publish-transform-output
file output-path final-target "PDF"
(function
(lambda (file output-path)
(let ((command (format "cd \"%s\"; platex \"%s\";"
(file-name-directory output-path) file))
(times )
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 ))
;; 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 ))
t
nil))
(let ((dvi (muse-replace-regexp-in-string
".tex" "" file t t)))
(shell-command (format "cd \"%s\"; dvipdfmx \"%s\";"
(file-name-directory output-path) dvi)))
))
".aux" ".toc" ".out" ".log" ".dvi"))

単純にplatexを適切な回数分実行し、生成されたdviファイルをdvipdfmxに渡しているようです。

問題なのは生成されるtexファイルの文字コードがshift-jisではないことなので、以下の関数を定義してみました:

;; This function receives an argument and
;; it converts that file into shift-jis.
(defun generate_shiftjis (file)
(let* ((tempfile (expand-file-name (make-temp-file "tmp" nil ".tex")))
(cmd1 (format "cp %s %s" file tempfile))
(cmd2 (format "nkf -s %s > %s" tempfile file))
(cmd3 (format "rm %s" tempfile))
result)
(call-process shell-file-name nil nil t
shell-command-switch cmd1) ;    (shell-command cmd1)
(call-process shell-file-name nil nil t
shell-command-switch cmd2) ;    (shell-command cmd2)
(call-process shell-file-name nil nil t
shell-command-switch cmd3))) ;    (shell-command cmd3)

やっているのは

  1. 既存のtexファイル(文字コードがshit-jisではない)を一時ファイルに待避
  2. nkfで待避ファイルをshift-jisに変換し、その結果を既存のtexファイルにリダイレクト
  3. 待避ファイルの削除

です。これをplatex実行前に行うようにしてみました。

実際の設定

このようになりました:

;; ============
;; === muse ===
;; ============
;; load authoring mode
(require 'muse-mode)
;; load publishing styles I use
(require 'muse-html)
(require 'muse-latex)
(require 'muse-texinfo)
(require 'muse-docbook)
(require 'muse-wiki)
;; (setq muse-html-encoding-default 'utf-8)
;; (setq muse-html-meta-content-encoding (quote utf-8))
(setq muse-latexcjk-encoding-default
(cdr (assoc 'utf-8 muse-latexcjk-encoding-map)))
(setq
muse-mode-hook
'(lambda ()
(setq outline-regexp "*+")
(setq outline-minor-mode t)
(setq coding-system-for-write 'utf-8)))
(require 'muse-project)
(add-to-list 'muse-project-alist
'("Default"
("~/working/muse/default" :default "index")
(:base "html" :path "~/publish/html")
(:base "latex" :path "~/publish/pdf")
(:base "pdf" :path "~/publish/pdf")))
(setq muse-latex-header
(concat
"\\documentclass{jsarticle}\n"
"\\usepackage[expert,deluxe,multi]{otf}\n"
"\\usepackage[dvipdfm]{graphicx}\n"
"\\usepackage{tabularx}\n"
"\\renewcommand{\\figurename}{Fig.}\n\n"
"\\usepackage{float}\n\n"
"\\usepackage{fancyhdr}\n"
"\\pagestyle{fancy}\n"
"\\lhead{<lisp>(muse-publishing-directive \"title\")</lisp>}\n"
"\\chead{}\n"
"\\rhead{<lisp>(muse-publishing-directive \"date\")</lisp>}\n"
"\\cfoot{\\thepage}\n"
"\\setlength{\\headheight}{16pt}\n"
"\\begin{document}\n\n"
"% フォントの選択\n"
"% \\usekanji{JY1}{mc}{m}{n} % 明朝\n"
"% \\usekanji{JY1}{mc}{bx}{n} % ゴシック\n"
"% \\usekanji{JY1}{gt}{m}{n} % ゴシック\n"
"% \\gtfamily % ヒラギノ角ゴシック\n"
"% \\bfseries % ヒラギノ明朝ボールド\n"
"% \\gtfamily\\bfseries % ヒラギノゴシックボールド\n"
"\\mgfamily % ヒラギノ丸ゴシック\n\n"
"%% 表紙作製\n"
"\\title{<lisp>(muse-publishing-directive \"title\")</lisp>}\n"
"\\author{<lisp>(muse-publishing-directive \"author\")</lisp>}\n"
"\\date{<lisp>(muse-publishing-directive \"date\")</lisp>}\n\n"
"\\maketitle\n"
"\\pagebreak\n\n"
"%% 目次ページ作製\n"
"% \\Large\n"
"% \\hypertarget{mokuji}{}\n"
"% \\begin{center}\\LARGE\\bf\n"
"% 目次のタイトル\n"
"% \\end{center}\n"
"% \\tableofcontents\n"
"% \\pagebreak\n\n"
"<lisp>(and muse-publish-generate-contents\n           \"\\\\tableofcontents\n\\\\newpage\")</lisp>\n"))
(defun muse-latex-pdf-generate2 (file output-path final-target)
(muse-publish-transform-output
file output-path final-target "PDF"
(function
(lambda (file output-path)
(let ((command (format "cd \"%s\"; platex \"%s\";"
(file-name-directory output-path) file))
(times )
result)
;; Convert the character code into shift-jis
(generate_shiftjis file)
;; 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 ))
;; 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 ))
t
nil))
(let ((dvi (muse-replace-regexp-in-string
".tex" "" file t t)))
(shell-command (format "cd \"%s\"; dvipdfmx \"%s\";"
(file-name-directory output-path) dvi)))
))
".aux" ".toc" ".out" ".log" ".dvi"))
;; This function receives an argument and
;; it converts that file into shift-jis.
(defun generate_shiftjis (file)
(let* ((tempfile (expand-file-name (make-temp-file "tmp" nil ".tex")))
(cmd1 (format "cp %s %s" file tempfile))
(cmd2 (format "nkf -s %s > %s" tempfile file))
(cmd3 (format "rm %s" tempfile))
result)
(call-process shell-file-name nil nil t
shell-command-switch cmd1) ;    (shell-command cmd1)
(call-process shell-file-name nil nil t
shell-command-switch cmd2) ;    (shell-command cmd2)
(call-process shell-file-name nil nil t
shell-command-switch cmd3))) ;    (shell-command cmd3)
(muse-derive-style "pdf" "latex"
:final 'muse-latex-pdf-generate2
:browser 'muse-latex-pdf-browse-file
:link-suffix 'muse-latex-pdf-extension
:osuffix 'muse-latex-pdf-extension)