- 追加された行はこの色です。
- 削除された行はこの色です。
*[[Ruby:https://www.ruby-lang.org/]] [#ufdd9309]
#ref(http://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Ruby_logo.svg/200px-Ruby_logo.svg.png,right,around,nolink,Ruby)
&color(White,#5F2F2F){ ''◆CONTENTS◆'' };&br;
#contents
*Summary [#z9c2e043]
TeX 関連プログラムには Ruby で書かれたスクリプトがあります.~
[[convbkmk.rb:http://www.tug.org/svn/texlive/trunk/Master/texmf-dist/scripts/convbkmk/convbkmk.rb?view=markup]] などの Ruby で書かれたスクリプトを実行するには Ruby の処理系が必要です.~
-https://www.ruby-lang.org/
-http://www.ruby-doc.org/
**関連リンク [#ha4e0479]
-http://ruby.morphball.net/
-[[「若手エンジニア/初心者のためのRuby 2.1入門」最新記事一覧:http://www.atmarkit.co.jp/ait/kw/ruby_nyumon.html]]
-[[Ruby Advent Calendar 2013 - Qiita [キータ]:http://qiita.com/advent-calendar/2013/ruby]]
-[[Rubyで外部コマンドを実行して結果を受け取る方法あれこれ:http://qiita.com/tyabe/items/56c9fa81ca89088c5627]]
-[[shebangが/bin/envかruby直接指定かで$0利用時の挙動がかわる:http://takai.tumblr.com/post/13843318337/shebang-bin-env-ruby-0]]
-[[Ruby 2.1.1 で Hash#reject のデグレ:http://diary.sorah.jp/2014/02/28/ruby211-hash-reject]] → [[Ruby 2.1.2:https://www.ruby-lang.org/ja/news/2014/05/09/ruby-2-1-2-is-released/]] で修正されました
-[http://sky-y.hatenablog.jp/entry/20120817/1345195421 Ruby: コマンドライン引数の解析で使うoptparseをもっと柔軟に]
-[http://d.hatena.ne.jp/maeharin/20130104/p1 RubyのFile.expand_path('相対パス', __FILE__)の意味]
**派生版 [#w5708e1c]
-[[JRuby:http://jruby.org/]]
-[[Rubinius:http://rubini.us/]]
-[[Topaz:http://topazruby.com/]]
***mruby (組み込み向け Ruby) [#we4042fb]
-https://github.com/mruby/mruby
-[[mruby Advent Calendar 2013 - Qiita [キータ]:http://qiita.com/advent-calendar/2013/mruby]]
*インストール [#oe1e1c67]
**Windows [#j2a4eaa7]
***RubyInstaller for Windows [#p44e196d]
-[[RubyInstaller for Windows:http://rubyinstaller.org/]]
-https://github.com/oneclick/rubyinstaller
RubyInstaller for Windows の Ruby を C:\Ruby200-x64 にインストールした場合は
;C:\Ruby200-x64\bin
を環境変数 PATH に追加します
RubyInstaller for Windows の Ruby を C:\Ruby200 にインストールした場合は
;C:\Ruby200\bin
を環境変数 PATH に追加します
***ActiveScriptRuby [#y961023d]
-[[ActiveScriptRuby and Other packages:http://www.artonx.org/data/asr/]]
***MSYS2 [#a7424fa6]
$ pacman -S ruby
***ビルド [#m4a4d031]
-[[Windows で ruby 2.1.1 をビルドする:http://blog.oogatta.com/entry/20140318/1395161294]]
**OS X [#def5cf73]
-[[brewとrbenvを使ってRuby2.1.2を突っ込む:http://qiita.com/217/items/2d4f2d9551572e2c7352]]
**Linux [#pfcca84f]
***Arch Linux [#k152c3d6]
-https://www.archlinux.org/packages/?name=ruby
***Linux Mint [#o6dd6f52]
-http://packages.ubuntu.com/ja/ruby
-http://packages.ubuntu.com/ja/ruby-full
-http://packages.ubuntu.com/ja/ruby2.1
***Debian [#z226ac1e]
-https://packages.debian.org/ja/ruby
-https://packages.debian.org/ja/ruby-full
-https://packages.debian.org/ja/ruby2.1
***Fedora [#c69aed3b]
-https://apps.fedoraproject.org/packages/ruby
***openSUSE [#r7994550]
-http://software.opensuse.org/package/ruby
***Gentoo Linux [#wf560410]
-https://packages.gentoo.org/package/dev-lang/ruby
*[[fwdevince>Evince/fwdevince]] &aname(fwdevince); [#x681ced4]
**Ruby 版 [#bf356aaf]
inverse search は実装していません.~
forward search のみ実装しています.~
Evince 3.12.1, Ruby 2.1.1, ruby-dbus 0.11.0 で動作確認しています.~
$ sudo gem install ruby-dbus
Fetching: ruby-dbus-0.11.0.gem (100%)
Successfully installed ruby-dbus-0.11.0
Parsing documentation for ruby-dbus-0.11.0
Installing ri documentation for ruby-dbus-0.11.0
Done installing documentation for ruby-dbus after 1 seconds
1 gem installed
----
-fwdevince
----
#!/usr/bin/env ruby
require 'dbus'
pdf = File.expand_path(ARGV[0]).gsub(/ /, '%20')
line = ARGV[1].to_i
tex = File.expand_path(ARGV[2])
bus = DBus::SessionBus.instance
daemon = bus.introspect('org.gnome.evince.Daemon', '/org/gnome/evince/Daemon')
dbus_name = daemon['org.gnome.evince.Daemon'].FindDocument('file://' + pdf, true)[0]
window = bus.introspect(dbus_name, '/org/gnome/evince/Window/0')
sleep(0.2)
window['org.gnome.evince.Window'].SyncView(tex, [line, 1], 0)
----
*[[fwdsumatrapdf>SumatraPDF/fwdsumatrapdf]] &aname(fwdsumatrapdf); [#qec9c8d7]
**Ruby 版 [#p8b1b4df]
RubyInstaller for Windows の ruby 2.0.0p481 (2014-05-08) [x64-mingw32] で動作確認しています.~
----
# vim: ts=4 sw=4 expandtab:
# -*- coding: utf-8 -*-
require 'win32/registry'
require 'fiddle/import'
require 'optparse'
APPCMD_CLIENTONLY = 0x10
CP_WINUNICODE = 1200
CF_UNICODETEXT = 13
XCLASS_FLAGS = 0x4000
XTYP_EXECUTE = (0x0050 | XCLASS_FLAGS)
TIMEOUT = 10000
class String
def wchar()
return (self + "\0").encode('UTF-16LE')
end
end
module Msvcrt
extend Fiddle::Importer
dlload 'msvcrt.dll'
extern 'int wcslen(wchar_t*)'
end
module Kernel32
extend Fiddle::Importer
dlload 'kernel32.dll'
typealias 'DWORD', 'unsigned int'
typealias 'LPDWORD', 'DWORD*'
typealias 'LPWSTR', 'wchar_t*'
typealias 'LPCWSTR', 'const wchar_t*'
typealias 'LPSECURITY_ATTRIBUTES', 'void*'
typealias 'LPVOID', 'void*'
typealias 'LPSTARTUPINFOW', 'STARTUPINFOW*'
typealias 'LPPROCESS_INFORMATION', 'PROCESS_INFORMATION*'
typealias 'BOOL', 'int'
extern 'BOOL CreateProcessW(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION)'
end
module User32
extend Fiddle::Importer
dlload 'user32.dll'
typealias 'WORD', 'unsigned short'
typealias 'DWORD', 'unsigned int'
typealias 'LPDWORD', 'DWORD*'
typealias 'BYTE', 'unsigned char'
typealias 'LPBYTE', 'unsigned char*'
typealias 'LPWSTR', 'wchar_t*'
typealias 'UINT', 'unsigned int'
typealias 'HANDLE', 'void*'
typealias 'PFNCALLBACK', 'void*'
typealias 'HSZ', 'void*'
typealias 'HCONV', 'void*'
typealias 'BOOL', 'int'
typealias 'PCONVCONTEXT', 'void*'
typealias 'HDDEDATA', 'void*'
typealias 'LPBYTE', 'unsigned char*'
extern 'UINT DdeInitializeW(LPDWORD, PFNCALLBACK, DWORD, DWORD)'
extern 'BOOL DdeUninitialize(DWORD)'
extern 'HSZ DdeCreateStringHandleW(DWORD, LPWSTR, int)'
extern 'BOOL DdeFreeStringHandle(DWORD, HSZ)'
extern 'HCONV DdeConnect(DWORD, HSZ, HSZ, PCONVCONTEXT)'
extern 'BOOL DdeDisconnect(HCONV)'
extern 'HDDEDATA DdeCreateDataHandle(DWORD, LPBYTE, DWORD, DWORD, HSZ, UINT, UINT)'
extern 'BOOL DdeFreeDataHandle(HDDEDATA)'
extern 'HDDEDATA DdeClientTransaction(LPBYTE, DWORD, HCONV, HSZ, UINT, UINT, DWORD, LPDWORD)'
extern 'DWORD WaitForInputIdle(HANDLE, DWORD)'
StartupInfoW = struct(['DWORD cb', \
'LPWSTR lpReserved', \
'LPWSTR lpDesktop', \
'LPWSTR lpTitle', \
'DWORD dwX', \
'DWORD dwY', \
'DWORD dwXSize', \
'DWORD dwYSize', \
'DWORD dwXCountChars', \
'DWORD dwYCountChars', \
'DWORD dwFillAttribute', \
'DWORD dwFlags', \
'WORD wShowWindow', \
'WORD lpReserved2', \
'WORD cbReserved2', \
'LPBYTE lpReserved2', \
'HANDLE hStdInput', \
'HANDLE hStdOutput', \
'HANDLE hStdError'])
Process_Information = struct(['HANDLE hProcess', \
'HANDLE hThread', \
'DWORD dwProcessId', \
'DWORD dwThreadId'])
end
def runSumatraPDF()
regValue = nil
Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\SumatraPDF.exe') do |reg|
regValue = reg.read(nil)[1]
end
sumatraPDFCommandLine = nil
if regValue and File.exists?(regValue) then
sumatraPDFCommandLine = "\"" + regValue + "\" -reuse-instance"
else
sumatraPDFCommandLine = "C:\\Windows\\System32\\rundll32.exe shell32,ShellExec_RunDLL SumatraPDF -reuse-instance"
end
siAddr = "\0" * User32::StartupInfoW.size
piAddr = "\0" * User32::Process_Information.size
si = User32::StartupInfoW.new(Fiddle::Pointer[siAddr])
pi = User32::Process_Information.new(Fiddle::Pointer[piAddr])
Kernel32::CreateProcessW(Fiddle::NULL, sumatraPDFCommandLine.wchar, Fiddle::NULL, Fiddle::NULL, 0, 0, Fiddle::NULL, Fiddle::NULL, si.to_ptr, pi.to_ptr)
User32::WaitForInputIdle(pi.hProcess, TIMEOUT)
end
def ddeExecute(server, topic, command)
idInstance = 0
begin
idInstPtr = Fiddle::Pointer[idInstance]
User32.DdeInitializeW(idInstPtr.ref, Fiddle::NULL, APPCMD_CLIENTONLY, 0)
idInstance = idInstPtr.to_i
if idInstance == 0 then raise 'DdeInitializeW error' end
hszServer = User32.DdeCreateStringHandleW(idInstance, server.wchar, CP_WINUNICODE)
if hszServer == Fiddle::NULL then raise 'DdeCreateStringHandleW error' end
hszTopic = User32.DdeCreateStringHandleW(idInstance, topic.wchar, CP_WINUNICODE)
if hszTopic == Fiddle::NULL then raise 'DdeCreateStringHandleW error' end
hConvClient = User32.DdeConnect(idInstance, hszServer, hszTopic, Fiddle::NULL)
if hConvClient == Fiddle::NULL then raise 'DdeConnect error' end
hDdeData = User32.DdeCreateDataHandle(idInstance, command.wchar, (Msvcrt.wcslen(command.wchar) + 1)*2, 0, Fiddle::NULL, CF_UNICODETEXT, 0)
if hDdeData == Fiddle::NULL then raise 'DdeCreateDataHandle error' end
hDdeTransactionData = User32.DdeClientTransaction(hDdeData, -1, hConvClient, Fiddle::NULL, 0, XTYP_EXECUTE, TIMEOUT, Fiddle::NULL)
if hDdeTransactionData == Fiddle::NULL then raise 'DdeClientTransaction error' end
ensure
if hDdeTransactionData != Fiddle::NULL then User32.DdeFreeDataHandle(hDdeTransactionData) end
if hDdeData != Fiddle::NULL then User32.DdeFreeDataHandle(hDdeData) end
if hszServer != Fiddle::NULL then User32.DdeFreeStringHandle(idInstance, hszServer) end
if hszTopic != Fiddle::NULL then User32.DdeFreeStringHandle(idInstance, hszTopic) end
if hConvClient != Fiddle::NULL then User32.DdeDisconnect(hConvClient) end
if idInstance != 0 then User32.DdeUninitialize(idInstance) end
end
end
if $0 == __FILE__
opt = OptionParser.new
opt.permute!(ARGV)
pdf = File.expand_path(ARGV[0])
tex = File.expand_path(ARGV[1])
line = ARGV[2]
server = 'SUMATRA'
topic = 'control'
command = '[ForwardSearch("' + pdf + '","' + tex + '",' + line + ',0,0,0)]'
runSumatraPDF()
ddeExecute(server, topic, command)
end
----