ねらい

PDFビューアーからEmacs上のSweaveにカーソルジャンプする方法で,patchDVI の SyncTeX サポートを利用する方法を書きました.
しかし,この方法はまだ開発中でベータ版の LuaLaTeX の使用を前提としているため安定していません.
そこで,patchDVIパッケージに手を入れて,日本語を含む Sweave ファイルを uplatex または platex で処理する方法を示します.
Windows 用の記述がメインですが,Linux での設定方法も加筆しました.
Mac は持ってないので未確認です.
もっと簡潔でエレガントな方法を見つけた方は,是非,修正/追記をお願いします.(by せーだ).

Windows, Linux の人は以下の事柄に注意すればいいと思います.

これまで予想以上の多くの方にダウンロードして頂いた添付のスクリプトは,古い方のファイル(不要)を削除しました.
残したファイルをリネームしたのでカウンターがリセットされましたが,+120程度に考えて下さい.

新着情報

[2014/12/25] knitrでSweaveファイルを処理する方法を追記しました.

[2014/12/1] おそらく ver. 1.9.1590 以降,ここで書いた処理を行うと、必要な情報以外に内部コードなどが大量に表示されます.これは,関数 patchLog() 内の if(length(concords)) の直後に browser() が呼び出されているためです.デバッグ時の消し忘れでしょうか.気になる人は patchLog() の定義を書き直して,browser() を無効にしましょう.

[2014/5/1] RStudio への対応方法を追記しました.patchDVI パッケージを必要としない(RStudio には同等の機能が含まれている)ので簡単なはずです.

[2013/12/18] patchDVI ver. 1.9.1601が15日にCRANに登録されました.Windowsでは,今までの方法で動作を確認済です.下記のdvipdfmxを通す関数SweaveDVIPDFM()は,latexコンパイルとdvipdfmxによるPDF作成をセットで実行する仕様です.つまり,正しい結果が得られるまで,ユーザが繰り返しSweaveDVIPDFM()を呼び出し続けなければならず,かつ,途中段階では不要なPDF作成も試みます.bibtexを使うなら,その処理(手動)も入るでしょうorz.回避策として,Makefileやlatexmkといった外部ツールに一連のコンパイルを背負わせる工夫が必要かと思われます.SweaveDVIPDFM()のオプションを上手に指定することが大切です.また,Duncan Murdoch先生来日後に公開された記事やドキュメントではUnicodeを前提としていますが,Sweave()のエンコーディングを適切に選べば,Unicode以外でも動作するはずです.学会から提供されるクラスファイルによっては,依然としてplatex(Shift_JIS/EUC-JP)用のみの場合もあるので,ここの情報はまだ使えると考えています.

[2013/12/9] patchDVI ver. 1.9.158以降で、dvipdfmxが通るようになりました。詳細はR研究集会のページに記しましたので、そちらもご参照下さい。

[2013/1/17] 1/10付でpatchDVI Ver. 1.9がCRANに登録されました.Windowsでは,ここに記述した方法で従来通りに動作することを確認済です. なお,SumatraPDFはVer. 1.9以降でForward/Inverse Searchの機能を持っています.

手順(Windowsの場合)

  1. (事前準備) TeX レベルでの,エディタ(Emacs 系を仮定)と PDF ビューアー(SumatraPDF)の相互参照が可能な状態にしておきます.
    情報はネット上にいっぱいあります.
    特に TeX Wiki が詳しいです.
    R 本体も最新版にしましょう.
  2. patchDVI パッケージをインストールします.
    install.packages("patchDVI", repos="http://R-Forge.R-project.org")
  3. 上記パッケージの関数patchDVI()とpatchSynctex()を編集し,それぞれmypatchDVI(),mypatchSynctex()として定義します.
    ここでは,c:/R/mypatchDVI.Rとして保存すると仮定します(添付ファイルをダウンロードしてください).
    最低限動くようにしただけなので,同じ処理を2度やってしまった場合の例外処理などの対応は含めていません.
    なお,patchDVIパッケージの本来の売りの1つである,分割・インクルードされたSweaveファイルにも使えます.
    Sweaveファイルの拡張子はRnwとします.
    中で用いている関数DVIspecials()やsetDVIspecials()は,patchDVIパッケージ内で定義されています.
    具体的な修正箇所には添付ファイル内でコメントを入れてあります.
  4. C:/Program Files/R/R-3.x.x/share/texmf/tex/latex にあるファイル類全部を,TeXから見えるところにコピーします.
    PDFビューアーからEmacs上のSweaveにカーソルジャンプする方法では,Sweave.styの中に\Sconcordanceというマクロを追記すると書きましたが,最近のSweave.styには,これが最初から定義されているため,コピーするだけでOKです.
  5. Sweaveファイルを編集しましょう.LaTeXプリアンブルに以下を明記することが注意点です(特に2行目).
    \usepackage{Sweave}
    \SweaveOpts{concordance=TRUE}
  6. 作成したSweaveファイル(test.Rnwと仮定)をRで処理します.
    R-3.x.x から,関数Sweave()の引数にencordingを明示する必要があります.
    UTF-8 なら次のようにします.
    Sweave("test.Rnw", encoding = "utf-8")
    Shift_JIS なら次のようにします.
    Sweave("test.Rnw", encoding = "cp932")
    この処理が終わると,test.tex(と,必要に応じた画像ファイルなど)の他に,test-concordance.texが作成されます.
    これは,test.texの中で\inputされるので,消してはいけません.
    Sweaveファイルを分割/インクルードしている場合は,patchDVIパッケージの関数SweaveAll()を使いましょう.
    ただし,インクルードされるSweaveファイルをサブディレクトリに置いても,TeXファイルはマスターのSweaveファイル(とそのTeXファイル)と同じディレクトリに置かれます(この条件はオリジナルのpatchDVIパッケージも同じです).
  7. 生成されたTeXファイルをコンパイルします.引数に注意しましょう.latexmk を使えば,必要なだけコンパイルし,関連する処理(bibtex など)も勝手にしてくれるので簡単です.
    uplatex の場合は次のようにします.
    uplatex -synctex=1 -guess-input-enc test.tex
    platex の場合は次のようにします.
    platex -synctex=1 -guess-input-enc test.tex
    引数 -synctex=1 により,LaTeXコンパイル後にtest.synctex.gzが作成されます.
    このファイルもSumatraPDFが使うため,消してはいけません.
    また,展開の必要もありません.
    ファイルの文字コードを自動判別する場合は -guess-input-enc オプションを追加します.
    自動判別せずに文字コードに UTF-8 を指定する場合は -no-guess-input-enc -kanji=utf8 オプションを使用します.
    uplatex の場合は次のようにします.
    uplatex -synctex=1 -no-guess-input-enc -kanji=utf8 test.tex
    platex の場合は次のようにします.
    platex -synctex=1 -no-guess-input-enc -kanji=utf8 test.tex
    自動判別せずに文字コードに Shift_JIS を指定する場合は -no-guess-input-enc -kanji=sjis オプションを使用します.
    platex -synctex=1 -no-guess-input-enc -kanji=sjis test.tex
    最近はPDFでプレビューするケースが多くなってきたかもしれませんが,dvioutを使う場合は -src オプションも必要です.
    uplatex の場合は次のようにします.
    uplatex -src -synctex=1 -guess-input-enc test.tex
    platex の場合は次のようにします.
    platex -src -synctex=1 -guess-input-enc test.tex
  8. R側で,DVI/PDFファイルにパッチを当てます.mypatchSynctex()はmypatchDVI()よりも先に実行しないと正常動作しないと思います(理由は後述します).
    library(patchDVI)
    source("c:/R/mypatchDVI.R")
    mypatchSynctex("test.synctex")
    mypatchDVI("test.dvi")
    latexコンパイルとDVIファイルへのパッチは,まとめてスクリプト化するといいです.
    例えば,latexmkと上記内容をRscriptに食わせるバッチファイル(mylatexmk.bat)はこんな感じになります.
    一応,通常のTeXファイルのコンパイルと併用できるような書き方にしてますが,latexmk側で複数の引数を駆使する細かい使い方には対応できていません.
    call latexmk.bat %~n1
    set CONCORD=%~n1-concordance.tex
    set DVI=%~n1.dvi
    if exist %CONCORD% Rscript -e "Com <- commandArgs();library(patchDVI);\
      source(\"C:/home/hoge/R/etc/mypatchDVI.R\");\
      DVI <- paste(Com[7], \".dvi\", sep = \"\");\
      SYNC <- paste(Com[7], \".synctex\", sep = \"\");\
      mypatchSynctex(SYNC);mypatchDVI(DVI)" %~n1
    下から5行は実際は1行です.
    行末のバックスラッシュ(円記号)と,行頭のスペースを取り除いて連結してください.
    RscriptのRコマンド行部分は,基本的に上のRコードを取り込んでいるだけです.
    これをPATH上のどこかに置き,Windows PowerShell またはコマンド プロンプトから次のように用います.
    引数は拡張子なしのtestでも構いません.
    mylatexmk.bat test.tex
    ESS使いであれば,ess-swv.elの141行目付近の
    (call-process "latex" nil tex-buf 1 latex-filename)
    を次のように直すと,M-n lでLaTeXコンパイルとDVIファイルへのパッチ処理を一気にやります(※EmacsLispファイルの手の入れ方を知らない人にはお勧めしません).
    (call-process "mylatexmk.bat" nil tex-buf 1 latex-filename)
  9. SumatraPDFとEmacs間の相互移動は,ここの通りにすれば実現できます.
    PDFファイルをSumatraPDFで開き,画面上の文字を適当にダブルクリックすると,Emacsでtest.Rnwの該当箇所付近にカーソルが飛びます.
    Emacs→SumatraPDFの場合,YaTeX 1.78.1 以降,SumatraPDF 1.9以降でSumatraPDFのforward searchに対応しています.
    元ネタはここです.
    Emacsのtest.Rnw上でC-c C-gした文字が,SumatraPDF側で青色で表示されます.
    当然ながら,この関数は普通のTeXファイルでも使えます.
    むしろ,SumatraPDF→Emacsの場合と同様,普通のTeXファイル用の設定がSweaveファイルでもそのまま使えるというべきですね.
    ~/.emacs.d/init.elに次の記述をします(YaTeXの利用が前提です).
    (setq YaTeX-inhibit-prefix-letter t)
    (setq YaTeX-dvi2-command-ext-alist
          '(("TeXworks\\|texworks\\|texstudio\\|mupdf\\|SumatraPDF\\|Preview\\|Skim\\|TeXShop\\|evince\\|okular\\|zathura\\|qpdfview\\|Firefox\\|firefox\\|chrome\\|chromium\\|Adobe\\|Acrobat\\|AcroRd32\\|acroread\\|pdfopen\\|xdg-open\\|open\\|start" . ".pdf")))
    (setq dvi2-command "rundll32 shell32,ShellExec_RunDLL SumatraPDF -reuse-instance")
    (setq tex-pdfview-command "rundll32 shell32,ShellExec_RunDLL SumatraPDF -reuse-instance")
    C-c C-g を入力すれば SumatraPDF で forward seasrch ができます.
    SumatraPDFを前面に表示させたくない場合はTeX Wikiのfwdsumatrapdfを使えば前面に表示されなくなります.
    (defun sumatrapdf-forward-search ()
      (interactive)
      (progn
        (process-kill-without-query
         (start-process
          "fwdsumatrapdf"
          nil
          "fwdsumatrapdf"
          (expand-file-name
           (concat (file-name-sans-extension (or YaTeX-parent-file
                                                 (save-excursion
                                                   (YaTeX-visit-main t)
                                                   buffer-file-name)))
                   ".pdf"))
          (buffer-name)
          (number-to-string (save-restriction
                              (widen)
                              (count-lines (point-min) (point))))))))
    YaTeXへのキーバインドをアサインします.ここではC-c sにアサインしました.
    (add-hook 'yatex-mode-hook
              '(lambda ()
                 (define-key YaTeX-mode-map (kbd "C-c s") 'sumatrapdf-forward-search)))
    Sweave ファイルを分割/インクルードしている場合は,ミニバッファでマスターの Sweave ファイル名を聞かれるので,それを入力すれば SumatraPDF に飛びます.
    YaTeXとの連携方法もここに載っています.
    Sweaveファイルの分割・インクルードにも対応しています.
  10. 元々のpatchSynctex()およびmypatchSynctex()は,PDFファイル(test.pdf)ではなく,test.synctex.gzを修正します.
    従って,DVIファイルから一般的な方法でPDFファイルを作って大丈夫でしょう.
    手元の環境では,dvipdfmx,dvips→Distiller,dvips→ps2pdfのどれでも動作しました.
    完成したPDFを,SumatraPDFで次のように起動します.
    SumatraPDF.exe -reuse-instance -inverse-search "emacsclientw.exe --no-wait +%l %f" test.pdf
    ここではemacsclientwを使いましたが,gnuclientwでも同じように動かせると思います.
    これで,SumatraPDFの画面上でダブルクリックすると,Emacs上のSweaveファイル上で,該当文字を含む段落付近にカーソルが飛びます.
    カーソルが飛ばない場合はM-x server-startを実行します.
    M-x server-startの実行が面倒な場合は~/.emacs.d/init.elに
    (server-start)
    を記述しておきます.

【番外編】RStudio で UTF-8 または Shift_JIS の日本語 Sweave ファイルを (u)pLaTeX + dvipdfmx で処理する

RStudio は patchDVI 相当の機能が内蔵されていますが,TeX コンパイラは PDFLaTeX または XeLaTeX の2択です ToT.
設定をいじってLuaLaTeXを使う方法もありますが,ここではもう少し頑張って UTF-8 または Shift_JIS の (u)platex on Windows を使えるようにします.

  1. TeX Live または W32TeX をインストールします.W32TeX の場合は ptex2pdf.exe を動かすために「標準インストール」の luatex-w32.tar.xz は必須と思われます.
  2. R と RStudio を入れます.これを書いている時点での最新版は R-3.1.0,RStudio v0.98.507 です.【手順(Windowsの場合)】の4.も忘れずに対応しましょう.一般的に、Rのバージョンアップ直後は,RStudio がそれに対応できてないことが多いです.
  3. Shift_JIS を使用する場合は RStudio を起動して,メニューの [Tools] ⇒ [Global Options..] で設定画面を開きます.[General] セクションが開いているはずなので,下から2番目の [Default text encoding:] を "CP932" に変更して [Apply] ⇒ [OK] します.
  4. UTF-8 を 使用する場合は ptex2pdf を次のように修正します.ptex2pdf.exe の実体は TEXMF-DIST/scripts/ptex2pdf/ptex2pdf.lua なので,その中の 169 行目を以下のように修正します.
    texopts = "-synctex=1 -kanji=utf8 -no-guess-input-enc"
    uplatex を使用する場合は 175 行目を次のように修正して保存します.
    use_uptex = 1
    同様に,176 行目も次のように修正して保存します.
    lua スクリプトの再コンパイルは必要ありません.
    use_latex = 1
    これは,Windows PowerShell またはコマンド プロンプトから
    ptex2pdf.exe -l -u -ot "-synctex=1 -kanji=utf8 -no-guess-input-enc" hoge.tex
    または
    ptex2pdf.exe -l -ot "-synctex=1 -kanji=utf8 -no-guess-input-enc" hoge.tex
    と引数を付与することなく,
    ptex2pdf.exe hoge.tex
    で同じことができるようにしています.この設定を,ご自身が常用している TeX コンパイラや文字コードに合わせて適宜変更してください.
  5. Shift_JIS を 使用する場合は ptex2pdf を次のように修正します.ptex2pdf.exe の実体は TEXMF-DIST/scripts/ptex2pdf/ptex2pdf.lua なので,その中の 169 行目を以下のように修正します.
    texopts = "-synctex=1 -kanji=sjis -no-guess-input-enc"
    同様に,176 行目も次のように修正して保存します.
    lua スクリプトの再コンパイルは必要ありません.
    use_latex = 1
    これは,Windows Powershell またはコマンド プロンプトから
    ptex2pdf.exe -l -ot "-synctex=1 -kanji=sjis -no-guess-input-enc" hoge.tex
    と引数を付与することなく,
    ptex2pdf.exe hoge.tex
    で同じことができるようにしています.この設定を,ご自身が常用している TeX コンパイラや文字コードに合わせて適宜変更してください.
  6. 環境変数 RSTUDIO_PDFLATEX を ptex2pdf.exe に設定します.環境変数を直接設定せずに,Rprofile.site に
    Sys.setenv("RSTUDIO_PDFLATEX" = "ptex2pdf.exe")
    と記入してもいいでしょう.もちろん RStudio の console にその都度打ち込んでも構いません.ptex2pdf.exe に引数を含めて渡すことができないので要注意です(4.での修正はそのためです).
  7. RStudio で Sweave ファイルを編集し,[Compile PDF] ボタンをクリックすると,Sweave ⇒ LaTeX + PDF (ptex2pdf) が一括処理されます(少し時間がかかるかも).問題がなければ RStudio にバンドルされている SumatraPDF で PDF が表示されます.SumatraPDF の画面をダブルクリックすると,RStudio で開いている Sweave ファイルの該当箇所付近にカーソルが飛びます.PDF 作成に成功すると,[Compile PDF] ボタンの横に新しいボタン(カーソルを合わせると "Sync PDF view to editor location" とポップアップが出ます)が表示されています.このボタンをクリックすると,Sweave ファイル編集画面のカーソルがある位置に対応する SumatraPDF の画面が表示され,該当箇所付近が数秒間ブルーで反転表示されます.Sweave ファイル編集画面にカーソルを合わせて Ctrl-Click または Ctrl-F8 でも同じことができます.

【番外編2】knitr で Sweave ファイルを処理する

knitr は,Sweaveをベースに他の便利な機能を含めて拡張されているパッケージで,現在も開発が活発に進められています.ただ,knitrはSweaveに対して完全に上位互換ではないため,従来の書式で作ったSweaveファイルがそのままknit()で処理できるとは限りません.例えば,このスレッドで説明している機能は,RStudioはある程度うまくやってくれるようですが,Rコンソールから直接knit()するとエラーが出ます.これを回避する方法は以下の通りです.

  1. knit()はSweaveファイル中に\usepackage{Sweave}や\SweaveOpts{}があるとエラーを出します.しかし,Sweave.sty中の\Sconcordanceというマクロだけは必要なので,それをSconcordance.styとして別ファイルに取り出します.更に『手順(Windowsの場合)』の5.に対応する部分を次のように書き換えます.この内容を含むファイル名がtmp.Rnwであると仮定しています.
    \usepackage{Sconcordance}
    \input{tmp-concordance}
    <<include=FALSE>>=
      opts_knit$set(concordance=TRUE)
    @
    knit()で生成されるTeXファイルには,\documentclassの最後尾に "\usepackage[]{graphicx}\usepackage[]{color}" が強制的に書き込まれます.opts_knit$set()の中でドライバ名を事前に指定すれば,手動で書き込む手間が省けます.例えばdvipsであれば次のようにします.
    opts_knit$set(concordance=TRUE,latex.options.graphicx="dvips",latex.options.color="dvips")
  2. Sweave固有のチャンクオプションなどを含めないように,knitrのマニュアル等を良く読んでtmp.Rnwを作成します.
  3. ここまでの作業を行ったtmp.Rnwをknit()で処理します.エンコーディングはOSのデフォルトが使われますが,それと一致しないときは引数encodingを明示します.
    library(knitr)
    knit("tmp.Rnw")
    同じフォルダにtmp.texとtmp-concordance.texが作られているはずです.
  4. 後の処理はこれまでと同じのため省略します.

既存のSweaveファイルをknit()で処理するために,knitrパッケージにはSweave2knitr()というコンバーター関数が用意されています.次のように使います.

library(knitr)
Sweave2knitr("sample.Rnw") ## これで sample-knitr.Rnw が作られる
knit("sample-knitr.Rnw")

しかしSweave2knitr()はconcordance周りに対応できてないのと,なぜかopts_knit$set()がopts_chunk$set()になっているので,修正版を置いておきます.

library(knitr)
source("mySweave2knitr.R")
mySweave2knitr("sample.Rnw") ## これで sample-knitr.Rnw が作られる
knit("sample-knitr.Rnw")

これで,sample.Rnwの

\usepackage{Sweave}
\SweaveOpts{concordance=TRUE}

だった部分が,sample-knitr.Rnwでは上記手順1.と同様に変更され,Sweave固有のチャンクオプションも適切に修正されます.

手順(Linuxの場合)

まず,Linux の uplatex, platex が SyncTeX に未対応の場合,TeX Live を最新版にアップグレードします.
GNOME の場合は Evince を使用します.
Evince バージョン 3.0.0 以降でないと以下の設定が動作しない可能性が高いので注意してください.
KDE の場合は Okular を使用します.
Debian/Stable(Wheezy) での動作(ESS+YaTeXを利用)は確認したので,以後の記述はそれに基づきます.

  1. Windowsの場合の手順1から6は,Linuxでも概ね同じです.
    文字コードが UTF-8 の場合は次のようにします.
    Sweave("test.Rnw", encoding = "utf-8")
    文字コードが EUC-JP の場合は次のようにします.
    Sweave("test.Rnw", encoding = "euc-jp")
  2. uplatex または platex を -synctex=1 オプション付きで起動します.
    uplatex の場合は次のようにします.
    uplatex -synctex=1 test.tex
    platex の場合は次のようにします.
    platex -synctex=1 test.tex
    文字コードが EUC-JP の場合は -kanji=euc オプションも付けます.
    platex -synctex=1 -kanji=euc test.tex
    Windows と同様,xdvik などを使う場合は,-src オプションが必要になります.
    platex -src -synctex=1 -kanji=euc test.tex
    latexmk を使うなら,上記コンパイルをシェルスクリプト化(例えばplatex-syncとします)して,.latexmkrcの該当部分を次のように修正します.
    $latex  = 'platex-sync';
  3. DVI/PDFへのパッチも,Windowsの場合の手順8と同等の処理を行います.Windowsのmylatexmk.batに対応するシェルスクリプトmylatexmkは次のようになります.
    #!/bin/bash
    BASE=`basename $1 .tex`
    latexmk $BASE
    
    if [ -e $BASE.synctex.gz ]
    then
    SCRIPT='library(patchDVI);source("/home/hoge/mypatchDVI.R");\
      mypatchSynctex("'$BASE.synctex'");mypatchDVI("'$BASE.dvi'")'
    Rscript -e $SCRIPT
    fi
    SCRIPTから始まる行と,その次の行は実際には1行です.
    SCRIPTから始まる行の最後尾のバックスラッシュと,次の行頭のスペースを取り除いて連結してください.
    なお,添付の mypatchDVI-new.R の文字コードは Shift_JIS なので,UTF-8 や EUC-JP に変換しないといけないかもしれません.
  4. EvinceとEmacs間の相互移動は,ここの通りにすれば実現できます.
    Evince⇒Emacsは~/.emacs.d/init.elに次の関数を記述します.
    (require 'dbus)
    
    (defun un-urlify (fname-or-url)
      "A trivial function that replaces a prefix of file:/// with just /."
      (if (string= (substring fname-or-url 0 8) "file:///")
          (substring fname-or-url 7)
        fname-or-url))
    
    (defun evince-inverse-search (file linecol &rest ignored)
      (let* ((fname (decode-coding-string (url-unhex-string (un-urlify file)) 'utf-8))
             (buf (find-file fname))
             (line (car linecol))
             (col (cadr linecol)))
        (if (null buf)
            (message "[Synctex]: %s is not opened..." fname)
          (switch-to-buffer buf)
          (goto-line (car linecol))
          (unless (= col -1)
            (move-to-column col))
          (x-focus-frame (selected-frame)))))
    
    (dbus-register-signal
     :session nil "/org/gnome/evince/Window/0"
     "org.gnome.evince.Window" "SyncSource"
     'evince-inverse-search)
    Evince⇒Emacsの実行はCtrl-左クリックです.
    Emacs⇒Evinceは,TeX Wikiのここを参考します.
    Emacs⇒Evinceは,YaTeX 1.78 以降で対応しています.
    fwdevinceはTeX Wikiのfwdevinceを使用します(要Python).
    ~/.emacs.d/init.elに次の記述をします.
    (setq YaTeX-inhibit-prefix-letter t)
    (setq YaTeX-dvi2-command-ext-alist
          '(("TeXworks\\|texworks\\|texstudio\\|mupdf\\|SumatraPDF\\|Preview\\|Skim\\|TeXShop\\|evince\\|okular\\|zathura\\|qpdfview\\|Firefox\\|firefox\\|chrome\\|chromium\\|Adobe\\|Acrobat\\|AcroRd32\\|acroread\\|pdfopen\\|xdg-open\\|open\\|start" . ".pdf")))
    (setq dvi2-command "evince")
    (setq tex-pdfview-command "evince")
    C-c C-g を入力すれば Evince で forward seasrch ができます.
  5. OkularとEmacs間の相互移動は,ここの通りにすれば実現できます.
    Okular⇒Emacsは[設定(S)]-[Okular を設定(O)...]-[エディタ]でEmacs clientを選択します.
    エディタ:
    Emacs client
    コマンド:
    emacsclient -a emacs --no-wait +%l %f
    Okular⇒Emacsの実行はShift-左クリックです.
    カーソルが飛ばない場合はM-x server-startを実行します.
    M-x server-startの実行が面倒な場合は~/.emacs.d/init.elに
    (server-start)
    を記述しておきます.
    Emacs⇒Okularは,TeX Wikiのここを参考に,~/.emacs.d/init.elに次の記述をします.
    (setq YaTeX-inhibit-prefix-letter t)
    (setq YaTeX-dvi2-command-ext-alist
          '(("TeXworks\\|texworks\\|texstudio\\|mupdf\\|SumatraPDF\\|Preview\\|Skim\\|TeXShop\\|evince\\|okular\\|zathura\\|qpdfview\\|Firefox\\|firefox\\|chrome\\|chromium\\|Adobe\\|Acrobat\\|AcroRd32\\|acroread\\|pdfopen\\|xdg-open\\|open\\|start" . ".pdf")))
    (setq dvi2-command "okular --unique")
    (setq tex-pdfview-command "okular --unique")
    (with-eval-after-load 'yatexprc
      (defun YaTeX-preview-jump-line ()
        "Call jump-line function of various previewer on current main file"
        (interactive)
        (save-excursion
          (save-restriction
            (widen)
            (let*((pf (or YaTeX-parent-file
                          (save-excursion (YaTeX-visit-main t) (buffer-file-name))))
                  (pdir (file-name-directory pf))
                  (bnr (substring pf 0 (string-match "\\....$" pf)))
                  ;(cf (file-relative-name (buffer-file-name) pdir))
                  (cf (buffer-file-name)) ;2016-01-08
                  (buffer (get-buffer-create " *preview-jump-line*"))
                  (line (count-lines (point-min) (point-end-of-line)))
                  (previewer (YaTeX-preview-default-previewer))
                  (cmd (cond
                        ((string-match "Skim" previewer)
                         (format "%s %d '%s.pdf' '%s'"
                                 YaTeX-cmd-displayline line bnr cf))
                        ((string-match "evince" previewer)
                         (format "%s '%s.pdf' %d '%s'"
                                 "fwdevince" bnr line cf))
                        ((string-match "sumatra" previewer)
                         (format "%s \"%s.pdf\" -forward-search \"%s\" %d"
                                 previewer bnr cf line))
                        ((string-match "zathura" previewer)
                         (format "%s --synctex-forward '%d:0:%s' '%s.pdf'"
                                 previewer line cf bnr))
                        ((string-match "qpdfview" previewer)
                         (format "%s '%s.pdf#src:%s:%d:0'"
                                 previewer bnr cf line))
                        ((string-match "okular" previewer)
                         (format "%s '%s.pdf#src:%d %s'"
                                 previewer bnr line (expand-file-name cf)))
                        )))
              (YaTeX-system cmd "jump-line" 'noask pdir))))))
    C-c C-g を入力すれば Okular で forward seasrch ができます.
  6. (補足)LinuxのデフォルトロケールがUTF-8だと,ESS起動時の日本語メッセージもUTF-8で表示されます.このとき,Emacsのデフォルト文字コードをEUC-JPにしてESSを起動すると,ESSの日本語(UTF-8)が腐りますが,~/.emacs.d/init.elで次のように設定すれば回避できると思います.
    ;; Emacsのデフォルト文字コードはEUC-JP
    (set-default-coding-systems 'euc-jp-unix)
    (set-terminal-coding-system 'euc-jp-unix)
    (set-buffer-file-coding-system 'euc-jp-unix)
    (set-keyboard-coding-system 'euc-jp-unix)
    ;; ESSから呼び出すバッファだけUTF-8にする
    (setq ess-pre-run-hook
      '((lambda () 
          (set-locale-environment "utf-8")
          (setenv "LANG" "ja_JP.UTF-8")
    )))

大雑把な説明

Sweave ファイルに \SweaveOpts{concordance=TRUE} を追加すると,関数 Sweave() によって Sweave ファイルと TeX ファイルの行番号の対応が書き込まれたファイル(上記の場合は test-concordance.tex)が作成されます.
開いてみれば分かりますが,これは情報を圧縮した形式なので,そのままでは意味不明です.
詳細は patchDVI パッケージのマニュアルに説明があります.

今回定義した関数 mypatchDVI() では,その圧縮した情報を展開してベクトル concord に付値します.
要素数が TeX ファイルの行数と同じで,n 番目の要素は TeX ファイルの行番号(n 行目)に対応する,Sweave ファイルの行番号です.
つまり,concord はコードチャンクを除いた Sweave ファイルの行番号になっています.

一方,引数 -src をつけてコンパイルした DVI ファイルには,source-special によって TeX ファイルの行番号と,元になる TeX ファイル名が埋め込まれているので,それを取り出し,concord の中身とファイル名をSweave ファイルに対応するように置き換えて,その結果を元の DVI ファイルに戻しています.

mypatchSynctex() でも,原理的には似たようなことを *.synctex.gz に対して行います.
オリジナルの関数 patchSynctex() では pdflatex の利用が前提ですが、pdflatex を使うと,PDF ファイルに上記 concord の素になる情報が取り込まれます.
しかし、uplatex または platex でコンパイルすると,その情報は DVI ファイルにしか反映されません.
したがって,mypatchSynctex() では,mypatchDVI() で処理する前の DVI ファイルから,必要な情報を抽出して対処するように変更しています.
mypatchSynctex() を mypatchDVI() の前に実行するのはそのためです.
なお,mypatchDVI() は,uplatex または platex のコンパイルに -src オプションを付けないと正しく動作しません.

まとめ

今回の内容で,Sweaveファイルの編集効率もそれなりに上がります.
TexmakerもSweaveに対応しているので,TeXレベルでDVI/PDFビューアとの相互移動ができていれば,対応可能だと思います.
人柱になって頂ける方や,同様の情報を持っている方がいらっしゃれば集約しましょう.



添付ファイル: filemypatchDVI.R 771件 [詳細] filemySweave2knitr.R 701件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2023-03-25 (土) 11:19:16