- 追加された行はこの色です。
- 削除された行はこの色です。
*[[SumatraPDF:http://blog.kowalczyk.info/software/sumatrapdf/]] [#afa7a42e]
*[[SumatraPDF:https://www.sumatrapdfreader.org/]] [#afa7a42e]
#ref(http://sumatrapdf.googlecode.com/svn/trunk/gfx/SumatraPDF-256x256x32.png,right,around,nolink,SumatraPDF)
&color(White,#5F2F2F){ ''◆目次◆'' };&br;
SumatraPDF は Windows で動作するタブ切り替え型の軽量な PDF ビューアです。
eBook (ePub, MOBI), XPS, DjVu, CHM, Comic Book (CBZ, CBR) などの形式も閲覧できます。
[[SyncTeX]] への対応,ファイルの自動更新機能もあり,TeX のプレビューアに向いています。
PDF ファイルだけではなく PostScript ファイルも表示可能です。
PostScript ファイルの表示には [[Ghostscript]] が必要です。
----
#contents
----
*SumatraPDF とは [#td9ee2f0]
SumatraPDF は PDF ビューアです.~
SyncTeX に対応しています.~
ファイルの自動更新機能もあります.~
[[Adobe Reader]] よりも TeX のプレビューアに向いています.~
PDF ファイルだけではなく PostScript ファイルも表示可能です.([[Ghostscript]] が必要です.)~
プレビューする場合に複数の SumatraPDF が起動するのを防止したい場合は -reuse-instance オプションを追加します.~
forward search を行う場合は -forward-search <texfile> <linenumber> オプションを追加します.~
**不具合 [#v813d27a]
-[[SumatraPDF 公式サイト:http://blog.kowalczyk.info/software/sumatrapdf/]]
--[[News:http://blog.kowalczyk.info/software/sumatrapdf/news.html]]
--[[ダウンロード:http://blog.kowalczyk.info/software/sumatrapdf/download-free-pdf-viewer-ja.html]]
--[[SumatraPDF pre-release builds:http://blog.kowalczyk.info/software/sumatrapdf/prerelease.html]] テスト用のプレリリースビルド版
-[[sumatrapdf - PDF viewer for Windows - Google Project Hosting:http://code.google.com/p/sumatrapdf/]]
--[[コミットログ:http://code.google.com/p/sumatrapdf/source/list]]
--[[Wiki:http://code.google.com/p/sumatrapdf/w/]]
---[[DDEcommands :http://code.google.com/p/sumatrapdf/wiki/DDEcommands]]
-[[Sumatra PDF Viewer forum:http://forums.fofou.org/sumatrapdf/]]
--[[forward search fails in texlive 2011:http://forums.fofou.org/sumatrapdf/topic?id=2131346]]
--[[Forward search from Vim to sumatrapdf:http://forums.fofou.org/sumatrapdf/topic?id=2353338]]
***SumatraPDF 3.4.6 (2022-06-08) で SyncTeX のエラー表示 → SumatraPDF 3.3.3 (2021-07-20) に戻す [#o17d1f9c]
**動作環境 [#z85aa9cd]
-https://twitter.com/arai_amide/status/1564784523216568320
-[[zipped synctex · Discussion #2640 · sumatrapdfreader/sumatrapdf · GitHub:https://github.com/sumatrapdfreader/sumatrapdf/discussions/2640]]
-[[zipped synctex fails in 3.4.x · Issue #2642 · sumatrapdfreader/sumatrapdf · GitHub:https://github.com/sumatrapdfreader/sumatrapdf/issues/2642]]
Windows 8, 7, Vista, XP
**インストール [#r04b7fad]
**License [#f48c8095]
[[Sumatra PDF reader download page:https://www.sumatrapdfreader.org/download-free-pdf-viewer.html]] から Installer をダウンロードします。
後はダブルクリックして指示に従えばインストールが完了します。
[[GPLv3:http://code.google.com/p/sumatrapdf/source/browse/trunk/COPYING]]
SumatraPDF インストール先フォルダは
**リリース情報 [#b67b5a28]
[[News:http://blog.kowalczyk.info/software/sumatrapdf/news.html]] を参照.~
SumatraPDF をデフォルトでインストールした場合は
>
C:\Users\<ユーザー名>\AppData\Local\SumatraPDF
<
SumatraPDF を全てのユーザーに対してインストールした場合は
>
C:\Program Files\SumatraPDF
<
になります。
v1.9 から コマンドラインオプション (-forward-search <texfile> <linenumber>) を指定して forward search ができるようになりました. ([[SumatraPDF v1.9.4622:http://code.google.com/p/sumatrapdf/source/detail?r=4622]] を参照)~
v1.6 から PostScript ファイルの表示にも対応しました.([[Ghostscript]] が必要です.)~
**使い方(SyncTeX の利用) [#wd50e1d3]
**派生版・独自ビルド版 [#i2d3e037]
[[SyncTeX]] とは PDF ファイルと TeX ソースファイルの相互ジャンプを行うための機能です。
TeX エンジンが SyncTeX に対応しており(主要なエンジンは対応しています)、かつ LaTeX ソースが -synctex=1 または -synctex=-1 オプションとともにコンパイルされている必要があります。(LaTeX ソースファイルと同じフォルダに拡張子が .synctex のファイルができます。)
ジャンプはエディタ -> SumatraPDF(forward search)と SumatraPDF -> エディタ(inverse search)の両方が可能です。
-[[PDFlite:http://www.pdflite.com/]]
-[[XhmikosR's builds home/sumatrapdf/:http://xhmikosr.1f0.de/index.php?folder=c3VtYXRyYXBkZg==]]
-最適化ビルド版の [[SumatraPDF x86/x64 Optimized Builds:http://guti.is-great.org/static.php?page=SumatraPDFOpt]]
-[[PortableApps.com:http://portableapps.com/]] の [[SumatraPDF Portable:http://portableapps.com/apps/office/sumatra_pdf_portable]]
-TeX ユーザのための [[SumatraPDF-TeX:http://william.famille-blum.org/software/sumatra/]] → 本家にマージされました.
***forward search [#m71d9172]
*forward search [#m71d9172]
コマンドラインオプション (-forward-search <texfile> <linenumber>) を指定して forward search を行うことが可能です。
forward search を行うには TeX コマンドのオプションに -synctex=1 または -synctex=-1 を追加する必要があります.~
コマンドラインオプション (-forward-search <texfile> <linenumber>) を指定して forward search を行う場合は v1.9 以降にアップグレードしてください.~
DDE で forward search を行う場合は v1.7 以降にアップグレードしてください.~
以下の統合環境,テキストエディタ +(マクロ・プラグイン)は SumatraPDF で forward and inverse search が可能です。
以下のエディタ・マクロ・プラグインは v1.9 以降の SumatraPDF で forward and inverse search が可能です.
■ フリーソフトウェア (オープンソースソフトウェア)
-[[LyX]]
-[[Texmaker]]
-[[TeXstudio]]
-[[Eclipse]]
--[[TeXlipse]]
-[[Texmaker]]
-[[TeXnicCenter]]
-[[Visual Studio Code]]
--[[LaTeX>Visual Studio Code/LaTeX]]
-[[Emacs]]
--[[TeX Mode>Emacs#h04d4173]]
--[[TeX mode>Emacs/TeX mode]]
--[[AUCTeX]]
--[[YaTeX]]
-[[Vim]]
--[[tex.vim>Vim#y0b061e7]]
--[[tex.vim>Vim/tex.vim]]
--[[VimTeX]]
--[[Vim-LaTeX]]
-[[xyzzy]]
--[[KaTeX]]
-[[Eclipse]]
--[[TeXlipse]]
-[[Notepad++]]
--[[MTeX for Notepad++>Notepad++#n6c79c5f]]
--[[NppExec>Notepad++#cb7d631d]]
--[[NppExec]]
--[[jN]]
-[[サクラエディタ]]
--[[SumatraPDF.js>サクラエディタ#s758d3d9]]
-[[TeXnicCenter]]
--[[Typeset.js>サクラエディタ/マクロ#i861969f]]
■ フリーウェア (無料)
-[[EasyTeX]]
-[[Visual Windows for TeX]]
-[[WinShell]]
***fwdsumatrapdf &aname(fwdsumatrapdf); [#n8da77e2]
■ シェアウェア
-[[Inlage:http://www.inlage.com/]] (シェアウェア)
-[[WinEdt:http://www.winedt.com/]] (シェアウェア)
-[[秀丸エディタ]] (シェアウェア)
--[[祝鳥 (のりてふ)>祝鳥]]
-[[Sublime Text]] (シェアウェア)
--[[LaTeXTools (LaTeX Plugin for Sublime Text 2)>Sublime Text#e60d4c0f]]
forward search するときに SumatraPDF を前面に表示したくない場合は fwdsumatrapdf を使用します。
[[SumatraPDF/fwdsumatrapdf]] を参照してください。
**fwdsumatrapdf.exe [#n8da77e2]
***inverse search [#wfcdbef6]
fwdsumatrapdf.exe は SumatraPDF で forward search を行うツールです.~
forward search を行うには TeX コマンドのオプションに -synctex=1 または -synctex=-1 を追加する必要があります.~
inverse search は SumatraPDF の画面をダブルクリックすると実行されます.ただし,設定が必要です。
***お知らせ [#ebfb06f5]
SumatraPDF v1.9 から コマンドラインオプション -forward-search <texfile> <linenumber> による forward search に対応しました.~
forward search するときに SumatraPDF を前面に表示したい場合は fwdsumatrapdf.exe を使用せずに SumatraPDF のコマンドラインオプションを使用してください.~
forward search するときに SumatraPDF を前面に表示したくない場合は fwdsumatrapdf.exe を使ってください.~
ただし,SumatraPDF の起動時は SumatraPDF が前面に表示されます.~
%APPDATA%\SumatraPDF\SumatraPDF-settings.txt に
EnableTeXEnhancements = false
と記述されている場合は逆順検索コマンドラインの設定が表示されません。
***F# 版 [#pd9dd173]
fwdsumatrapdf.exe のビルド・実行には [[F#:http://research.microsoft.com/fsharp/]] が必要です.~
逆順検索コマンドラインの設定が表示されていない場合は [☰] > [設定(S)] > [詳細設定(A)] で %APPDATA%\SumatraPDF\SumatraPDF-settings.txt を開いて
EnableTeXEnhancements = true
に修正します。
-fwdsumatrapdf.exe の作成方法
--[[F#:http://fsharp.org/]] をインストールします.
---F# 3.0 でビルドできます.Windows 8, Windows 7 SP1 では [[F# Tools for Visual Studio Express 2012 for Web:http://www.microsoft.com/en-us/download/details.aspx?id=34675]] をダウンロードしてインストールすれば F# 3.0 が使用できます.F# Tools for Visual Studio Express 2012 for Web は Visual Studio Express 2012 をインストールしなくても使用可能ですが F# でプログラムを作成したい方は Visual Studio Express 2012 をインストールすることをおすすめします.(Windows 7 SP1 の場合は .NET Framework 4.5 をインストールする必要があります)
---F# 2.0 でもビルドできます.Windows Vista, XP では Visual Studio Express 2012 が動作しないので Windows Vista, XP の場合は F# 2.0 を使用してください.F# 2.0 の場合は ([[Microsoft F#, April 2011 Community Technology Preview:http://www.microsoft.com/download/en/details.aspx?id=11100]]) をダウンロードしてインストールします.
--C:\w32tex\bin\fwdsumatrapdf.fsx を作成します.
あるいは,-synctex オプションとともにコンパイルされた PDF ファイルを開いてください。(正確には,.synctex ファイルが同じフォルダにある PDF ファイルを開いてください。)
----
-C:\w32tex\bin\fwdsumatrapdf.fsx
----
// vim: ts=4 sw=4 expandtab:
// >fsc -r:Microsoft.VisualBasic.dll fwdsumatrapdf.fsx
#r "Microsoft.VisualBasic.dll"
#light
open System
open System.IO
open System.Diagnostics
open System.ComponentModel
open System.Runtime.InteropServices
open Microsoft.VisualBasic
module Ddeml =
//exception DdemlError of string
type DdemlError(e) = inherit Exception(e)
let APPCMD_CLIENTONLY = 0x10u
let CP_WINUNICODE = 1200
let CF_UNICODETEXT = 13u
let XCLASS_FLAGS = 0x4000u
let XTYP_EXECUTE = (0x0050u ||| XCLASS_FLAGS)
[<DllImport(@"user32.dll", EntryPoint="DdeInitializeW", CharSet=CharSet.Unicode)>]
extern uint32 DdeInitializeW (uint32&, nativeint, uint32, uint32)
[<DllImport(@"user32.dll", EntryPoint="DdeUninitialize", CharSet=CharSet.Unicode)>]
extern bool DdeUninitialize (uint32)
[<DllImport(@"user32.dll", EntryPoint="DdeCreateStringHandleW", CharSet=CharSet.Unicode)>]
extern nativeint DdeCreateStringHandleW (uint32, string, int)
[<DllImport(@"user32.dll", EntryPoint="DdeFreeStringHandle", CharSet=CharSet.Unicode)>]
extern bool DdeFreeStringHandle (uint32, nativeint)
[<DllImport(@"user32.dll", EntryPoint="DdeCreateDataHandle", CharSet=CharSet.Unicode)>]
extern nativeint DdeCreateDataHandle (uint32, string, uint32, uint32, nativeint, uint32, uint32)
[<DllImport(@"user32.dll", EntryPoint="DdeFreeDataHandle", CharSet=CharSet.Unicode)>]
extern bool DdeFreeDataHandle (nativeint)
[<DllImport(@"user32.dll", EntryPoint="DdeConnect", CharSet=CharSet.Unicode)>]
extern nativeint DdeConnect (uint32, nativeint, nativeint, nativeint)
[<DllImport(@"user32.dll", EntryPoint="DdeDisconnect", CharSet=CharSet.Unicode)>]
extern bool DdeDisconnect (nativeint)
[<DllImport(@"user32.dll", EntryPoint="DdeClientTransaction", CharSet=CharSet.Unicode)>]
extern nativeint DdeClientTransaction (nativeint, uint32, nativeint, nativeint, uint32, uint32, uint32, nativeint)
let timeout = 10000
let Usage args = do
#if INTERACTIVE
let s = "usage: fsi.exe fwdsumatrapdf.fsx pdffile texfile line"
#else
let s = "usage: fwdsumatrapdf.exe pdffile texfile line"
#endif
if Array.length args = 3 then ()
else do
eprintfn "%s" s
exit 2
let RunSumatraPDF pdf = do
if Process.GetProcessesByName "SumatraPDF" |> Array.length <> 0 then ()
else do
let ps = new Process ()
let sumatrapdfWin32 = @"C:\Program Files\SumatraPDF\SumatraPDF.exe"
let sumatrapdfWin64 = @"C:\Program Files (x86)\SumatraPDF\SumatraPDF.exe"
if File.Exists sumatrapdfWin32 then
ps.StartInfo.FileName <- sumatrapdfWin32
elif File.Exists sumatrapdfWin64 then
ps.StartInfo.FileName <- sumatrapdfWin64
else
ps.StartInfo.FileName <- Interaction.InputBox ("Input the path to SumatraPDF.exe.", "fwdsumatrapdf", "SumatraPDF.exe")
ps.StartInfo.Arguments <- "-reuse-instance " + "\"" + pdf + "\""
ps.Start () |> ignore
ps.WaitForInputIdle timeout |> ignore
let DdeExecute server topic command = do
let mutable idInstance = 0u
let mutable hszServer = 0n
let mutable hszTopic = 0n
let mutable hConvClient = 0n
let mutable hDdeData = 0n
let mutable hDdeTransactionData = 0n
try
Ddeml.DdeInitializeW (&idInstance, 0n, Ddeml.APPCMD_CLIENTONLY, 0u) |> ignore
if idInstance = 0u then raise (Ddeml.DdemlError("DdeInitializeW error"))
hszServer <- Ddeml.DdeCreateStringHandleW (idInstance, server, Ddeml.CP_WINUNICODE)
if hszServer = 0n then raise (Ddeml.DdemlError("DdeCreateStringHandleW error"))
hszTopic <- Ddeml.DdeCreateStringHandleW (idInstance, topic, Ddeml.CP_WINUNICODE)
if hszTopic = 0n then raise (Ddeml.DdemlError("DdeCreateStringHandleW error"))
hConvClient <- Ddeml.DdeConnect (idInstance, hszServer, hszTopic, 0n)
if hConvClient = 0n then raise (Ddeml.DdemlError("DdeConnect error"))
hDdeData <- Ddeml.DdeCreateDataHandle (idInstance, command, uint32 ((String.length command + 1)*sizeof<char>), 0u, 0n, Ddeml.CF_UNICODETEXT, 0u)
if hDdeData = 0n then raise (Ddeml.DdemlError("DdeCreateDataHandle error"))
hDdeTransactionData <- Ddeml.DdeClientTransaction (hDdeData, uint32 -1, hConvClient, 0n, 0u, Ddeml.XTYP_EXECUTE, uint32 timeout, 0n)
if hDdeTransactionData = 0n then raise (Ddeml.DdemlError("DdeClientTransaction error"))
finally
if hDdeTransactionData <> 0n then Ddeml.DdeFreeDataHandle (hDdeTransactionData) |> ignore
if hDdeData <> 0n then Ddeml.DdeFreeDataHandle (hDdeData) |> ignore
if hszServer <> 0n then Ddeml.DdeFreeStringHandle (idInstance, hszServer) |> ignore
if hszTopic <> 0n then Ddeml.DdeFreeStringHandle (idInstance, hszTopic) |> ignore
if hConvClient <> 0n then Ddeml.DdeDisconnect (hConvClient) |> ignore
if idInstance <> 0u then Ddeml.DdeUninitialize (idInstance) |> ignore
let Main args = do
Usage args
let pdf = args.[0]
let tex = args.[1]
let line = args.[2]
try
int line |> ignore
RunSumatraPDF pdf
let active = 0
let forwardSearch = "[ForwardSearch(\"" + pdf + "\",\"" + tex + "\"," + line + ",0,0," + string active + ")]"
DdeExecute "SUMATRA" "control" forwardSearch
with
| :? Win32Exception as e -> do
eprintfn "%s" e.Message
exit -3
| :? InvalidOperationException as e -> do
eprintfn "%s" e.Message
exit -2
| e -> do
eprintfn "%s" e.Message
exit -1
#if INTERACTIVE
fsi.CommandLineArgs |> Array.toList |> List.tail |> List.toArray |> Main
#else
[<EntryPoint; STAThread>]
let EntryPoint args =
Main args
0
#endif
----
SumatraPDF の [☰] > [設定(S)] > [オプション(O)...] の逆順検索コマンドラインの設定で inverse search で実行されるコマンドラインの設定を行います。
--fwdsumatrapdf.fsx をビルドして fwdsumatrapdf.exe を作成します.
inverse search の設定はコマンドラインから -inverse-search オプションで指定することも可能です。
C:\w32tex\bin\fwdsumatrapdf.fsx を fsc.exe でコンパイルすると C:\w32tex\bin\fwdsumatrapdf.exe が作成されます.~
コマンドラインからビルドする場合は以下のようにしてビルドします.~
設定方法については統合環境,テキストエディタ +(マクロ・プラグイン)によって異なるのでそれぞれのマニュアルを見て設定してください。
>C:
>cd C:\w32tex\bin
[[TeXstudio]] であれば
"C:\Program Files\texstudio\texstudio.exe" "%f" -line %l
となります。
-F# 3.0 の場合
***コマンドラインオプション [#d9cff28c]
プレビューする場合に複数の SumatraPDF が起動するのを防止したい場合は -reuse-instance オプションを追加します。
C:\w32tex\bin>fsc -r:Microsoft.VisualBasic.dll fwdsumatrapdf.fsx
上記のコマンドでうまく動作しない場合は
C:\w32tex\bin>fsc -r:Microsoft.VisualBasic.dll -r:System.ServiceModel.Internals -r:SMDiagnostics --standalone fwdsumatrapdf.fsx
-https://www.sumatrapdfreader.org/manual.html
-https://github.com/sumatrapdfreader/sumatrapdf/blob/master/src/Flags.cpp
-F# 2.0 の場合
C:\w32tex\bin>fsc -r:Microsoft.VisualBasic.dll fwdsumatrapdf.fsx
上記のコマンドでうまく動作しない場合は
C:\w32tex\bin>fsc -r:Microsoft.VisualBasic.dll --standalone fwdsumatrapdf.fsx
**リンク [#pad542dc]
-[[SumatraPDF 公式サイト:https://www.sumatrapdfreader.org/]]
--[[News:https://www.sumatrapdfreader.org/news.html]]
--[[Download:https://www.sumatrapdfreader.org/download-free-pdf-viewer.html]]
--[[SumatraPDF pre-release builds:https://www.sumatrapdfreader.org/prerelease.html]] テスト用のプレリリースビルド版
-[[sumatrapdfreader · GitHub:https://github.com/sumatrapdfreader]]
--[[Home · sumatrapdfreader/sumatrapdf Wiki · GitHub:https://github.com/sumatrapdfreader/sumatrapdf/wiki]]
-[[Discussions · sumatrapdfreader/sumatrapdf · GitHub:https://github.com/sumatrapdfreader/sumatrapdf/discussions]]
-[[MyTeXpert:SumatraPDF]]
-[[Sumatra PDF のインストールと設定 | お知らせ+活動記録+たわごと:http://blog.fujioizumi.verse.jp/?eid=230]]
----
-32bit Windows の場合
----
C:.
├─w32tex
│ └─bin
│ ├─fwdsumatrapdf.exe
│ └─fwdsumatrapdf.fsx
└─Program Files
└─Microsoft SDKs
└─F#
└─3.0
└─Framework
└─v4.0
├─Fsc.exe
└─Fsi.exe
----
-64bit Windows の場合
----
C:.
├─w32tex
│ └─bin
│ ├─fwdsumatrapdf.exe
│ └─fwdsumatrapdf.fsx
└─Program Files (x86)
└─Microsoft SDKs
└─F#
└─3.0
└─Framework
└─v4.0
├─Fsc.exe
└─Fsi.exe
----
***License [#f48c8095]
[[GPLv3:https://github.com/sumatrapdfreader/sumatrapdf/blob/master/COPYING]]
ビルドせずに fsi.exe で実行することも可能です.
***ChangeLog [#b67b5a28]
-[[News:https://www.sumatrapdfreader.org/news.html]]
-[[コミットログ:https://github.com/sumatrapdfreader/sumatrapdf/commits/master]]
>fsi C:\w32tex\bin\fwdsumatrapdf.fsx hoge.pdf hoge.tex 30
引数に渡すパラメータや状況によって例外が発生することがあります.~
-使用上の注意点
F# 2.0 でビルドするときに --standalone オプションを追加しなかった場合,環境によっては fwdsumatrapdf.exe を実行したときに以下のような例外が発生するかもしれません.
ハンドルされていない例外: System.IO.FileNotFoundException: ファイルまたはアセン
ブリ 'FSharp.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=????????????
????'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つ
かりません。
ファイル名 'FSharp.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=??????
??????????' です。
場所 Fwdsumatrapdf.EntryPoint(String[] args)
上記のエラーが発生する場合は以下のように --standalone オプションを追加してビルドしてください.
>C:
>cd C:\w32tex\bin
C:\w32tex\bin>fsc -r:Microsoft.VisualBasic.dll --standalone fwdsumatrapdf.fsx
F# 2.0 でビルドするときに --standalone オプションを追加した場合以下の警告が表示されるかもしれませんが実行できるので気にしないでください.
warning FS2009: Ignoring mixed managed/unmanaged assembly 'System.Data' during s
tatic linking
warning FS2009: Ignoring mixed managed/unmanaged assembly 'System.Transactions'
during static linking
warning FS2009: Ignoring mixed managed/unmanaged assembly 'System.Data.OracleCli
ent' during static linking
//F# 3.0 の場合
//
// warning FS2011: Assembly 'System.ServiceModel.Internals' was referenced transiti
// vely and the assembly could not be resolved automatically. Static linking will a
// ssume this DLL has no dependencies on the F# library or other statically linked
// DLLs. Consider adding an explicit reference to this DLL.
//
// warning FS2011: Assembly 'SMDiagnostics' was referenced transitively and the ass
// embly could not be resolved automatically. Static linking will assume this DLL h
// as no dependencies on the F# library or other statically linked DLLs. Consider a
// dding an explicit reference to this DLL.
***C# 版 [#de1b4851]
C# 版も作成してみました.~
F# 版がうまく動作しない場合は C# 版を使用してください.~
コマンドラインからビルドする場合は以下のようにしてビルドします.~
>C:
>cd C:\w32tex\bin
C:\w32tex\bin>csc /r:Microsoft.VisualBasic.dll fwdsumatrapdf.cs
----
-C:\w32tex\bin\fwdsumatrapdf.cs
----
// vim: ts=4 sw=4 expandtab:
// >csc /r:Microsoft.VisualBasic.dll fwdsumatrapdf.cs
using System;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Microsoft.VisualBasic;
namespace Ddeml
{
public class Ddeml
{
public class DdemlError : Exception
{
public DdemlError(string e) : base(e)
{
}
}
public const uint APPCMD_CLIENTONLY = 0x10u;
public const int CP_WINUNICODE = 1200;
public const uint CF_UNICODETEXT = 13u;
public const uint XCLASS_FLAGS = 0x4000u;
public const uint XTYP_EXECUTE = (0x0050u | XCLASS_FLAGS);
[DllImport(@"user32.dll", EntryPoint="DdeInitializeW", CharSet=CharSet.Unicode)]
public static extern uint DdeInitializeW(ref uint pidInst, IntPtr pfnCallback, uint afCmd, uint ulRes);
[DllImport(@"user32.dll", EntryPoint="DdeUninitialize", CharSet=CharSet.Unicode)]
public static extern bool DdeUninitialize(uint idInst);
[DllImport(@"user32.dll", EntryPoint="DdeCreateStringHandleW", CharSet=CharSet.Unicode)]
public static extern IntPtr DdeCreateStringHandleW(uint idInst, string psz, int iCodePage);
[DllImport(@"user32.dll", EntryPoint="DdeFreeStringHandle", CharSet=CharSet.Unicode)]
public static extern bool DdeFreeStringHandle(uint idInst, IntPtr hsz);
[DllImport(@"user32.dll", EntryPoint="DdeCreateDataHandle", CharSet=CharSet.Unicode)]
public static extern IntPtr DdeCreateDataHandle(uint idInst, string pSrc, uint cb, uint cbOff, IntPtr hszItem, uint wFmt, uint afCmd);
[DllImport(@"user32.dll", EntryPoint="DdeFreeDataHandle", CharSet=CharSet.Unicode)]
public static extern bool DdeFreeDataHandle(IntPtr hData);
[DllImport(@"user32.dll", EntryPoint="DdeConnect", CharSet=CharSet.Unicode)]
public static extern IntPtr DdeConnect(uint idInst, IntPtr hszServer, IntPtr hszTopic, IntPtr pCC);
[DllImport(@"user32.dll", EntryPoint="DdeDisconnect", CharSet=CharSet.Unicode)]
public static extern bool DdeDisconnect(IntPtr hConvList);
[DllImport(@"user32.dll", EntryPoint="DdeClientTransaction", CharSet=CharSet.Unicode)]
public static extern IntPtr DdeClientTransaction(IntPtr pData, uint cbData, IntPtr hConv, IntPtr hszItem, uint wFmt, uint wType, uint dwTimeout, IntPtr pdwResult);
}
}
namespace SumatraPDFClient
{
using Ddeml;
public class ForwardSearch
{
private const int timeout = 10000;
private static void Usage(string[] args)
{
var s = "usage: fwdsumatrapdf.exe pdffile texfile line";
if (args.Length == 3) {
return;
}
else {
Console.Error.WriteLine(s);
Environment.Exit(2);
}
}
private static void RunSumatraPDF(string pdf)
{
if (Process.GetProcessesByName("SumatraPDF").Length != 0) {
return;
}
else {
var ps = new Process();
var sumatrapdfWin32 = @"C:\Program Files\SumatraPDF\SumatraPDF.exe";
var sumatrapdfWin64 = @"C:\Program Files (x86)\SumatraPDF\SumatraPDF.exe";
if (File.Exists(sumatrapdfWin32)) {
ps.StartInfo.FileName = sumatrapdfWin32;
}
else if (File.Exists(sumatrapdfWin64)) {
ps.StartInfo.FileName = sumatrapdfWin64;
}
else {
ps.StartInfo.FileName = Interaction.InputBox("Input the path to SumatraPDF.exe.", "fwdsumatrapdf", "SumatraPDF.exe");
}
ps.StartInfo.Arguments = "-reuse-instance " + "\"" + pdf + "\"";
ps.Start();
ps.WaitForInputIdle(timeout);
}
}
private static void DdeExecute(string server, string topic, string command)
{
var idInstance = 0u;
var hszServer = IntPtr.Zero;
var hszTopic = IntPtr.Zero;
var hConvClient = IntPtr.Zero;
var hDdeData = IntPtr.Zero;
var hDdeTransactionData = IntPtr.Zero;
try {
Ddeml.DdeInitializeW(ref idInstance, IntPtr.Zero, Ddeml.APPCMD_CLIENTONLY, 0u);
if (idInstance == 0u) throw new Ddeml.DdemlError("DdeInitializeW error");
hszServer = Ddeml.DdeCreateStringHandleW(idInstance, server, Ddeml.CP_WINUNICODE);
if (hszServer == IntPtr.Zero) throw new Ddeml.DdemlError("DdeCreateStringHandleW error");
hszTopic = Ddeml.DdeCreateStringHandleW(idInstance, topic, Ddeml.CP_WINUNICODE);
if (hszTopic == IntPtr.Zero) throw new Ddeml.DdemlError("DdeCreateStringHandleW error");
hConvClient = Ddeml.DdeConnect(idInstance, hszServer, hszTopic, IntPtr.Zero);
if (hConvClient == IntPtr.Zero) throw new Ddeml.DdemlError("DdeConnect error");
hDdeData = Ddeml.DdeCreateDataHandle(idInstance, command, (uint)((command.Length + 1)*sizeof(char)), 0u, IntPtr.Zero, Ddeml.CF_UNICODETEXT, 0u);
if (hDdeData == IntPtr.Zero) throw new Ddeml.DdemlError("DdeCreateDataHandle error");
hDdeTransactionData = Ddeml.DdeClientTransaction(hDdeData, unchecked((uint)-1), hConvClient, IntPtr.Zero, 0u, Ddeml.XTYP_EXECUTE, (uint)timeout, IntPtr.Zero);
if (hDdeTransactionData == IntPtr.Zero) throw new Ddeml.DdemlError("DdeClientTransaction error");
}
finally {
if (hDdeTransactionData != IntPtr.Zero) Ddeml.DdeFreeDataHandle(hDdeTransactionData);
if (hDdeData != IntPtr.Zero) Ddeml.DdeFreeDataHandle(hDdeData);
if (hszServer != IntPtr.Zero) Ddeml.DdeFreeStringHandle(idInstance, hszServer);
if (hszTopic != IntPtr.Zero) Ddeml.DdeFreeStringHandle(idInstance, hszTopic);
if (hConvClient != IntPtr.Zero) Ddeml.DdeDisconnect(hConvClient);
if (idInstance != 0u) Ddeml.DdeUninitialize(idInstance);
}
}
[STAThread]
public static void Main(string[] args)
{
Usage(args);
var pdf = args[0];
var tex = args[1];
var line = args[2];
try {
int.Parse(line);
RunSumatraPDF(pdf);
var active = 0;
var forwardSearch = "[ForwardSearch(\"" + pdf + "\",\"" + tex + "\"," + line + ",0,0," + active.ToString() + ")]";
DdeExecute("SUMATRA", "control", forwardSearch);
}
catch (Win32Exception e) {
Console.Error.WriteLine(e.Message);
Environment.Exit(-3);
}
catch (InvalidOperationException e) {
Console.Error.WriteLine(e.Message);
Environment.Exit(-2);
}
catch (Exception e) {
Console.Error.WriteLine(e.Message);
Environment.Exit(-1);
}
}
}
}
----
***C 版 [#qf7ea8bf]
C 版も作成してみました.~
F# 版, C# 版がうまく動作しない場合は C 版を使用してください.~
[[MinGW]] の GCC でビルドできます.~
$ cd /c/w32tex/bin
$ gcc -o fwdsumatrapdf.exe fwdsumatrapdf.c -luser32 -lshell32 -lshlwapi
Microsoft Visual Studio Express の C/C++ Optimizing Compiler for x86/x64 でもビルド可能です.~
>cd /d c:\w32tex\bin
>cl fwdsumatrapdf.c user32.lib shlwapi.lib
----
-C:\w32tex\bin\fwdsumatrapdf.c
----
/* vim: ts=2 sw=2 expandtab:
*
* MinGW
* $ gcc -o fwdsumatrapdf.exe fwdsumatrapdf.c -luser32 -lshell32 -lshlwapi
*
* Microsoft Visual Studio Express
* >cl fwdsumatrapdf.c user32.lib shlwapi.lib
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <errno.h>
#include <locale.h>
#include <windows.h>
#include <shlwapi.h>
#include <ddeml.h>
BOOL CALLBACK GetSumatraHWND(HWND, LPARAM);
int RunSumatraPDF(const wchar_t*);
int DdeExecute(const wchar_t*, const wchar_t*, const wchar_t*);
#define FWDSUMATRAPDF_BUF_SIZE 1024
#define TIMEOUT 10000
static BOOL existSumatraHWND = FALSE;
BOOL CALLBACK
GetSumatraHWND(
HWND hwnd,
LPARAM lParam)
{
wchar_t* title = NULL;
wchar_t windowText[sizeof(wchar_t)*FWDSUMATRAPDF_BUF_SIZE] = L"";
UNREFERENCED_PARAMETER(lParam);
GetWindowTextW(hwnd, windowText, sizeof(windowText));
if (windowText[0] == L'\0') {
goto next;
}
if ((title = wcsrchr(windowText, L'S')) == NULL) {
goto next;
}
if (StrCmpW(title, L"SumatraPDF") != 0) {
goto next;
}
existSumatraHWND = TRUE;
next:
return TRUE;
}
int
RunSumatraPDF(
const wchar_t* pdf)
{
int err = 0;
const wchar_t* sumatrapdfWin32 = L"C:\\Program Files\\SumatraPDF\\SumatraPDF.exe";
const wchar_t* sumatrapdfWin64 = L"C:\\Program Files (x86)\\SumatraPDF\\SumatraPDF.exe";
wchar_t* sumatrapdf = (wchar_t*)L"SumatraPDF.exe";
const wchar_t* reuseInstance = L"-reuse-instance";
wchar_t sumatrapdfCommandLine[sizeof(wchar_t)*FWDSUMATRAPDF_BUF_SIZE] = L"";
static HWND hList;
STARTUPINFOW si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
if (PathFileExistsW(sumatrapdfWin32)) {
sumatrapdf = (wchar_t*)sumatrapdfWin32;
} else if (PathFileExistsW(sumatrapdfWin64)) {
sumatrapdf = (wchar_t*)sumatrapdfWin64;
} else {
sumatrapdf = (wchar_t*)L"SumatraPDF.exe";
}
wsprintfW(
sumatrapdfCommandLine,
L"\"%ls\" %ls \"%ls\"",
sumatrapdf, reuseInstance, pdf);
EnumWindows(GetSumatraHWND, (LPARAM)hList);
if (existSumatraHWND == TRUE) {
goto exn;
}
if (CreateProcessW(
NULL,
sumatrapdfCommandLine,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi) == 0) {
err = 3;
goto exn;
}
WaitForInputIdle(
pi.hProcess,
TIMEOUT);
exn:
return err;
}
int
DdeExecute(
const wchar_t* server,
const wchar_t* topic,
const wchar_t* command)
{
int err = 0;
HCONV hConvClient = NULL;
DWORD idInstance = 0;
HSZ hszServer = NULL;
HSZ hszTopic = NULL;
HDDEDATA hDdeData = NULL;
HDDEDATA hDdeTransactionData = NULL;
if (DdeInitializeW(
&idInstance,
NULL,
APPCMD_CLIENTONLY,
0) != DMLERR_NO_ERROR) {
fputws(L"DdeInitializeW error\n", stderr);
err = 4;
goto exn;
}
if ((hszServer = DdeCreateStringHandleW(
idInstance,
server,
CP_WINUNICODE)) == NULL) {
fputws(L"DdeCreateStringHandleW error\n", stderr);
err = DdeGetLastError(idInstance);
goto exn;
}
if ((hszTopic = DdeCreateStringHandleW(
idInstance,
topic,
CP_WINUNICODE)) == NULL) {
fputws(L"DdeCreateStringHandleW error\n", stderr);
err = DdeGetLastError(idInstance);
goto exn;
}
if ((hConvClient = DdeConnect(
idInstance,
hszServer,
hszTopic,
NULL)) == NULL) {
fputws(L"DdeConnect error\n", stderr);
err = DdeGetLastError(idInstance);
goto exn;
}
if ((hDdeData = DdeCreateDataHandle(
idInstance,
(BYTE*)command,
(DWORD)(wcslen(command) + 1)*sizeof(wchar_t),
0,
NULL,
CF_UNICODETEXT,
0)) == NULL) {
fputws(L"DdeCreateDataHandle error\n", stderr);
err = DdeGetLastError(idInstance);
goto exn;
}
if ((hDdeTransactionData = DdeClientTransaction(
(BYTE*)hDdeData,
(DWORD)-1,
hConvClient,
NULL,
0,
XTYP_EXECUTE,
TIMEOUT,
NULL)) == NULL) {
fputws(L"DdeClientTransaction error\n", stderr);
err = DdeGetLastError(idInstance);
goto exn;
}
exn:
if (hDdeTransactionData) {
if (DdeFreeDataHandle(
hDdeTransactionData) == FALSE) {
err = DdeGetLastError(idInstance);
if (err) {
fputws(L"DdeFreeDataHandle error\n", stderr);
}
}
}
if (hDdeData) {
if (DdeFreeDataHandle(
hDdeData) == FALSE) {
err = DdeGetLastError(idInstance);
if (err) {
fputws(L"DdeFreeDataHandle error\n", stderr);
}
}
}
if (hszServer) {
if (DdeFreeStringHandle(
idInstance,
hszServer) == FALSE) {
fputws(L"DdeFreeStringHandle error\n", stderr);
err = DdeGetLastError(idInstance);
}
}
if (hszTopic) {
if (DdeFreeStringHandle(
idInstance,
hszTopic) == FALSE) {
fputws(L"DdeFreeStringHandle error\n", stderr);
err = DdeGetLastError(idInstance);
}
}
if (hConvClient) {
if (DdeDisconnect(hConvClient) == FALSE) {
fputws(L"DdeDisconnect error\n", stderr);
err = DdeGetLastError(idInstance);
}
}
if (idInstance) {
if (DdeUninitialize(idInstance) == FALSE) {
fputws(L"DdeUninitialize error\n", stderr);
err = 5;
}
}
return err;
}
#if defined (_MSC_VER)
int
wmain(
int argc,
wchar_t** argv)
#else
int APIENTRY
WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
#endif
{
int err = 0;
wchar_t* pdf = NULL;
wchar_t* tex = NULL;
wchar_t* line = NULL;
int active = 0;
wchar_t forwardSearch[sizeof(wchar_t)*FWDSUMATRAPDF_BUF_SIZE] = L"";
#if !defined (_MSC_VER)
wchar_t** argv;
int argc;
UNREFERENCED_PARAMETER(hInstance);
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
argv = CommandLineToArgvW(GetCommandLineW(), &argc);
#endif
if (argc != 4) {
fwprintf(stderr, L"usage: %ls pdffile texfile line\n", argv[0]);
err = 2;
goto exn;
}
pdf = argv[1];
tex = argv[2];
line = argv[3];
if (wcslen(pdf) > (FWDSUMATRAPDF_BUF_SIZE/4)) {
fwprintf(stderr, L"%ls is too long.\n", pdf);
err = -4;
goto exn;
}
if (wcslen(tex) > (FWDSUMATRAPDF_BUF_SIZE/4)) {
fwprintf(stderr, L"%ls is too long.\n", tex);
err = -3;
goto exn;
}
if (wcslen(line) > (FWDSUMATRAPDF_BUF_SIZE/4)) {
fwprintf(stderr, L"%ls is too long.\n", line);
err = -2;
goto exn;
}
if (wcstol(line, NULL, 0) == 0 || errno == ERANGE) {
fwprintf(stderr, L"%ls can't convert to the line number.\n", line);
err = -1;
goto exn;
}
if ((err = RunSumatraPDF(pdf)) != 0) {
goto exn;
}
wsprintfW(
forwardSearch,
L"%ls%ls%ls%ls%ls%ls%ls%d%ls",
L"[ForwardSearch(\"", pdf, L"\",\"", tex, L"\",", line, L",0,0,", active, L")]");
if ((err = DdeExecute(L"SUMATRA", L"control", forwardSearch)) != 0) {
goto exn;
}
exn:
return err;
}
----
***使用可能なエディタ・マクロ・プラグイン [#g4dd3cd8]
fwdsumatrapdf.exe は以下のエディタ・マクロ・プラグインで使用可能です.
■ フリーソフトウェア (オープンソースソフトウェア)
-[[LyX]]
-[[Texmaker]]
-[[TeXstudio]]
-[[Eclipse]]
--[[TeXlipse]]
-[[Emacs]]
--[[TeX Mode>Emacs#h04d4173]]
--[[AUCTeX]]
--[[YaTeX]]
-[[Vim]]
--[[Vim-LaTeX]]
-[[xyzzy]]
--[[KaTeX]]
-[[Notepad++]]
--[[MTeX for Notepad++>Notepad++#n6c79c5f]]
--[[NppExec>Notepad++#cb7d631d]]
-[[サクラエディタ]]
--[[fwdsumatrapdf.js>サクラエディタ#ce8c0353]]
-[[TeXnicCenter]]
*inverse search [#wfcdbef6]
inverse search を行うには TeX コマンドのオプションに -synctex=1 または -synctex=-1 を追加する必要があります.~
inverse search は SumatraPDF の画面をダブルクリックすると実行されます.~
SumatraPDF の [設定(S)]-[オプション(O)...]-[逆順検索コマンドラインの設定] で inverse search で実行されるコマンドラインの設定を行います.~
inverse search の設定はコマンドラインから -inverse-search オプションで指定することも可能です.~
派生版・独自ビルド版の中にはこの設定が削除されているものがあるので,その場合は
-公式サイトの SumatraPDF を使用する
-SumatraPDF のコマンドラインの -inverse-search オプションで指定する
などの方法で対処してください.~
どのように設定するかはエディタ・マクロ・プラグインによって異なるのでそれぞれのマニュアルを見て設定してください.~
例えば [[W32TeX]] に含まれている [[TeXworks]] であれば
----
&color(Black,#FFF100){%%% &color(#FF4000){''SumatraPDF のオプション''}; &color(Black,#CC3333){%%%[ ''&color(White){✕};'' ]%%%}; %%%};&br;
...&br;
逆順検索コマンドラインの設定&br;
PDF ドキュメント上でダブルクリックしたときに呼び出すコマンドラインを入&br;
力:&br;
%%%C:\w32tex\share\texworks\TeXworks.exe --position=%l "%f"%%%&br;
----
となります.
*関連リンク [#c84cbf92]
-[[F# at Microsoft Research - Microsoft Research:http://research.microsoft.com/fsharp/]]
-[[DDEML Functions (Windows):http://msdn.microsoft.com/en-us/library/windows/desktop/ff468833(v=vs.85).aspx]]
-[[Windows Data Types (Windows):http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx]]
-[[The New Data Types (Windows):http://msdn.microsoft.com/en-us/library/windows/desktop/aa384264(v=vs.85).aspx]]
-[[NDde:http://ndde.codeplex.com/]]
-[[USBメモリ活用講座【基礎編・PDFビューアのポータブル化-Sumatra PDF】:http://www.nagaoka-ct.ac.jp/ec/labo/visu/usb/pdf/sumatra.shtml]]
-[[Windows 7 で W32TeX を導入して日本語 SyncTeX を試してみる:http://skalldan.wordpress.com/2011/11/11/windows-7-%E3%81%A7-w32tex-%E3%82%92%E5%B0%8E%E5%85%A5%E3%81%97%E3%81%A6%E6%97%A5%E6%9C%AC%E8%AA%9E-synctex-%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B/]]
-[[SweaveでエディタとDVIビューア間の相互移動 - RjpWiki:http://www.okada.jp.org/RWiki/?Sweave%A4%C7%A5%A8%A5%C7%A5%A3%A5%BF%A4%C8DVI%A5%D3%A5%E5%A1%BC%A5%A2%B4%D6%A4%CE%C1%EA%B8%DF%B0%DC%C6%B0]]
-[[F# 3.0 を Visual Studio なしでインストールする:http://blog.recyclebin.jp/archives/2889]]
-[[Microsoft、「Visual Studio Express」でF#言語を利用可能にするアドインを公開:http://www.forest.impress.co.jp/docs/news/20120913_559448.html]]
-[[DDEApp Tutorial (C#, C++):http://www.codeproject.com/Articles/401117/DDEApp-Tutorial-Csharp-Cplusplus]]
-[[Process.Start()で起動したプロセスのメインウィンドウのハンドルが取得できない場合の対処法:http://www.slotware.net/blog/2009/11/processstart.html]]
-[[[SDK32] バッファ長の指定が不十分だと DDEML で不具合が発生する:http://support.microsoft.com/kb/107387/ja]]
-[[DDE Is Still Alive & Kicking:http://chrisoldwood.blogspot.jp/2009/10/dde-is-still-alive-kicking.html]]