summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/epspdf/epspdfrc.rb
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/scripts/epspdf/epspdfrc.rb')
-rwxr-xr-xMaster/texmf-dist/scripts/epspdf/epspdfrc.rb415
1 files changed, 242 insertions, 173 deletions
diff --git a/Master/texmf-dist/scripts/epspdf/epspdfrc.rb b/Master/texmf-dist/scripts/epspdf/epspdfrc.rb
index aa64309a822..acdbd9ac5e4 100755
--- a/Master/texmf-dist/scripts/epspdf/epspdfrc.rb
+++ b/Master/texmf-dist/scripts/epspdf/epspdfrc.rb
@@ -1,20 +1,16 @@
+EPVERSION = '0.4.0'
+COPYRIGHT = '2006, 2008, 2009'
+
# epspdf conversion utility, configuration module
#####
-# Copyright (C) 2006, 2008 Siep Kroonenberg
+# Copyright (C) 2006, 2008, 2009 Siep Kroonenberg
# n dot s dot kroonenberg at rug dot nl
#
# This program is free software, licensed under the GNU GPL, >=2.0.
# This software comes with absolutely NO WARRANTY. Use at your own risk!
#####
-# This version has been adapted for TeX Live. The adaptations only
-# concern Windows. If TL is set then pdftops and
-# ghostscript are set to the version included in TeXLive, settings are
-# stored in HKCU\software\epspdftl (rather than epspdf) and the logfile
-# is %USERPROFILE%\epspdftl.log, rather than epspdf.log.
-# A future version should offer a dynamic way of settingt his option.
-
# Settings are stored in a settings hash, with some methods added
# for less unwieldy notation.
#
@@ -43,112 +39,145 @@ else
'unix'
end
-TL = ENV.has_key?('TLROOT')
if ARCH == 'w32'
+ # registry and API calls
require 'dl/win32'
require 'win32/registry'
include Win32 # this lets us abbreviate Win32::Registry to Registry
+ # lay groundwork for short_name function
ShortPName = Win32API.new(
'kernel32', 'GetShortPathName', ['P','P','N'], 'N' )
- TLROOT = ENV['TLROOT']
+ # shellopen function
+ ShellEx = Win32API.new(
+ 'shell32','ShellExecute', ['L','P','P','P','P','L'], 'L' )
+ #FindEx = Win32API.new(
+ # 'shell32','FindExecutable', ['P','P','P'], 'L' )
+ # from winuser.h:
+ SW_SHOWNORMAL = 1
end
-# for Windows, use short names within backquotes
-# to avoid quotes within backquotes
-
+# need short_name function to get around limitations of w2k quoting
def short_name( fn )
+ #puts "Calculate short name for #{fn}\n"
return fn if ARCH != 'w32'
- fn.gsub!( /\\/, '/' )
+ fn.gsub!( /\//, "\\" )
buffer = ' ' * 260
length = ShortPName.call( fn, buffer, buffer.size )
- return ( length > 0 ) ? buffer.slice(0..length-1) : fn
+ fn = buffer.slice(0..length-1) if length > 0
+ fn.gsub!( /\\/, '/' )
+ return fn
+end
+
+def shell_open( fn )
+ return nil if ARCH != 'w32'
+ result = ShellEx.call( 0, 0, fn, 0, 0, SW_SHOWNORMAL )
end
+def shell_open_with( fn )
+ return nil if ARCH != 'w32'
+ result = ShellEx.call( 0, 0, "RUNDLL32.EXE", "shell32.dll,OpenAs_RunDLL #{fn}",
+ 0, SW_SHOWNORMAL )
+end
+
+# interpret error value for shell_open
+# values <=32 indicate error
+# constants defined in winerror.h, shellapi.h
+
+def shell_error_string ( e )
+ if e > 32
+ returl nil
+ else
+ return case e
+ when 0: "Out of memory or resources"
+ #define ERROR_FILE_NOT_FOUND 2L
+ #define SE_ERR_FNF 2
+ when 2: "File not found"
+ #define ERROR_PATH_NOT_FOUND 3L
+ #define SE_ERR_PNF 3
+ when 3: "Path not found"
+ #define SE_ERR_ACCESSDENIED 5
+ when 5: "Access denied"
+ #define SE_ERR_OOM 8
+ when 8: "Not enough memory"
+ #define ERROR_BAD_FORMAT 11L
+ when 11: "Invalid exe"
+ #define SE_ERR_SHARE 26
+ when 26: "Sharing violation"
+ #define SE_ERR_ASSOCINCOMPLETE 27
+ when 27: "Invalid file association"
+ #define SE_ERR_DDETIMEOUT 28
+ when 28: "DDE timeout"
+ #define SE_ERR_DDEFAIL 29
+ when 29: "DDE fail"
+ #define SE_ERR_DDEBUSY 30
+ when 30: "DDE busy"
+ #define SE_ERR_NOASSOC 31
+ when 31: "No file association"
+ #define SE_ERR_DLLNOTFOUND 32
+ when 32: "DLL not found"
+ else "Unspecified error"
+ end # case
+ end # else
+end # def
+
# system-dependent location of logfile
LOGFILE = case ARCH
when 'w32'
- TL ? "#{ENV['USERPROFILE']}\\epspdftl.log" :
"#{ENV['USERPROFILE']}\\epspdf.log"
else
- "#{ENV['HOME']}//epspdf.log"
+ "#{ENV['HOME']}/epspdf.log"
end
LOGFILE_OLD = LOGFILE + '.old'
# system-dependent locations of saved settings
-RC_FILE = "#{ENV['HOME']}/.epspdfrc"
-REG_K = TL ? 'epspdftl' : 'epspdf'
-REG_KEY = TL ? 'SOFTWARE\\epspdftl' : 'SOFTWARE\\epspdf'
+RC_FILE = "#{ENV['HOME']}/.epspdfrc" # not used under Windows
+REG_K = 'epspdf'
+REG_KEY = 'SOFTWARE\\epspdf'
# hash of saved settings from rc file or registry
$rc_settings = {}
-# find open command for extension (w32 only)
-
-def open_with( ext )
- ext = '' unless ext
- answer = nil
- if ARCH == 'w32'
- begin # open cl = HKCR\ext safely
- Registry::HKEY_CLASSES_ROOT.open(
- (ext =~ /^\./ ? ext : '.'+ext) ) do |cl|
- begin # read ftype safely
- ftype = cl.read_s( nil )
- begin # open cmd = HKCR\ftype\shell... safely
- Registry::HKEY_CLASSES_ROOT.open(
- ftype + '\\shell\\open\\command' ) do |cmd|
- begin # read answer safely
- answer = cmd.read_s( nil )
- if answer =~ /^"([^"]+)".*/
- answer = $1
- elsif answer =~ /^([^ ]+) .*/
- answer = $1
- end
- answer = nil unless answer and test( ?s, answer )
- rescue # answer not read
- end # read answer safely
- end # HKCR\ftype\shell... do |cmd|
- rescue # cmd not opened
- end # open cmd = HKCR\ftype\shell... safely
- rescue # ftype not read
- end # read ftype safely
- end # HKCR\ext do |cl|
- rescue # cl not opened
- end # open cl = HKCR\ext safely
- end # w32
- answer
-end
-
# test whether a string is a valid program call
# 'which' also works with explicit paths.
# 'which' returns an error for non-executable files.
+# Linux/Unix OS X: for testing existence of gs, pdftops and ps/pdf viewers
+# Mac OS X: for testing existence of gs and pdftops
+# Windows: function not usable and not used
def is_a_program( s )
case ARCH
when 'w32'
nil
else
- ( system "which #{s} >/dev/null" ) ? 1 : nil
+ ( system "which #{s} >/dev/null 2>&1" ) ? 1 : nil
end
end # is_a_program
-# Parse version info from a prog from the xpdf suite.
-# This is used as validity test.
-
-def xpdf_version( arg )
- retval = nil
- arg = short_name( arg ) if ARCH == 'w32'
- version_output = `#{arg} -v 2>&1`
- if version_output and not version_output.empty?
- vo = version_output.split(/\r\n?|\n/)
- vo.grep(/version/i) { |a|
- a =~ /^\D*(\d+\.\w*)\b/
- retval = $& # matched part; nil if no match
- }
+# for Windows, use the registry or the following function instead:
+
+def find_on_path( s )
+ # for now, Windows-only; parameter s with or without path
+ if ARCH != 'w32'
+ return nil
end
- retval
+ ENV['PATH'].gsub( "\\", "/" ).split( /;/ ).each do |d|
+ d = File.expand_path( d ) # this seems a syntactic operation
+ s_full = d.sub( /\/$/, '' ) + '/' + s
+ if test( ?d, d ) and test( ?f, s_full )
+ return s_full
+ end
+ ENV['PATHEXT'].split( /;/ ).each do |e|
+ # components of PATHEXT should include leading dot
+ s_full = d.sub( /\/$/, '' ) + '/' + s + e
+ if test( ?f, s_full )
+ return s_full
+ end
+ end # do |e|
+ end # do |d|
+ return nil
end
class Setting
@@ -167,30 +196,56 @@ PDF_VERSIONS = [ '1.2', '1.3', '1.4', 'default' ]
$settings = {
# converters
+ # ghostscript: under windows it must be told about its directories,
+ # so we don't want users to mess with it.
+ # If they really want to, they can manually edit PATH and set GS_LIB
'gs_prog' => Setting.new( nil, 'auto', nil ),
- 'gs_version' => Setting.new( nil, 'auto', nil ),
+ #'gs_version' => Setting.new( nil, 'auto', nil ),
'pdftops_prog' => Setting.new( nil, ARCH=='w32' ? 'config' : 'auto', nil ),
- # viewers
+ # epspdftk: viewers
'pdf_viewers' => Setting.new( nil, ARCH=='unix' ? 'auto' : nil, nil ),
'ps_viewers' => Setting.new( nil, ARCH=='unix' ? 'auto' : nil, nil ),
'pdf_viewer' => Setting.new( nil, ARCH=='unix' ? 'config' : 'auto', nil ),
'ps_viewer' => Setting.new( nil, ARCH=='unix' ? 'config' : 'auto', nil ),
+ # epspdftk: initial dir
+ 'defaultDir' => Setting.new( nil, 'config', nil ),
# conversion options
'ignore_pdftops' => Setting.new( '0', 'config',
'Ignore pdftops even if available; 1=yes, empty or 0=no(default)' ),
'pdf_target' => Setting.new( 'prepress', 'config',
'Target: screen, ebook, print, prepress (default) or default' ),
- 'pdf_version' => Setting.new( '1.4', 'config',
- 'Pdf version: e.g 1.4 or 1.2 (fewer features, more compatibility)' +
- ' or unspecified' ),
+ 'pdf_version' => Setting.new( 'default', 'config',
+ 'Pdf version: e.g 1.4 or 1.2 or default' ),
'pdf_custom' => Setting.new( '', 'config',
'additional options for [e]ps to pdf conversion' ),
- 'ps_options' => Setting.new( '-level2', 'config',
- 'options for pdftops; default -level2' ),
+ 'ps_options' => Setting.new( '-level3', 'config',
+ 'options for pdftops; default -level3' ),
+ 'ignore_hires_bb' => Setting.new( '0', 'config',
+ 'Ignore hi-res boundingbox for pdf generation;' +
+ ' 1=yes, empty or 0=no(default)' ),
'bb_spread' => Setting.new( '1', 'config',
- 'margin to be added to computed boundingbox; default 1' )
+ 'margin to be added to computed lores boundingbox; default 1' )
}
+# Using pdftops or a hires boundingbox should be the norm, not the exception.
+# We emphasize this by naming the corresponding options ignore_pdftops and
+# ignore_hires_bb, and letting them default to false.
+
+def reverse_of( x )
+ case x
+ when /t(rue)?|y(es)?|1/i
+ false
+ when /f(alse)?|n(o)?|0/i
+ true
+ when 1
+ false
+ when 0
+ true
+ else
+ true
+ end
+end
+
class << $settings
# create shortcut methods $settings.x and $settings.x=
@@ -201,47 +256,15 @@ class << $settings
eval "def #{k}=(v) ; self[\'#{k}\'].val=v ; end"
}
- # use_pdftops is a boolean counterpart and inverse
- # of the stored string attribute ignore_pdftops
+ # use_pdftops and use_hires_bb are a boolean counterparts and inverses
+ # of the stored string attributes ignore_pdftops and ignore_hires_bb
- def use_pdftops
- case self['ignore_pdftops'].val
- when /t(rue)?|y(es)?|1/i
- false
- when /f(alse)?|n(o)?|0/i
- true
- when 1
- false
- when 0
- true
- else
- true
- end
+ def use_hires_bb
+ reverse_of( self['ignore_hires_bb'].val )
end
- # we want use_pdftops = nil = default = true but
- # we also want use_pdftops = nil <=> use_pdftops = false
- # we give the second one priority.
-
- def use_pdftops=( x )
- self['ignore_pdftops'].val = case x
- when /t(rue)?|y(es)?|1/i
- '0'
- when /f(alse)?|n(o)?|0/i
- '1'
- when 1
- '0'
- when 0
- '1'
- when false
- '1'
- when nil # try to avoid this assignment
- '1'
- when true
- '0'
- else
- '1'
- end
+ def use_pdftops
+ reverse_of( self['ignore_pdftops'].val )
end
def accept_pdf_viewer( s )
@@ -337,7 +360,7 @@ class << $settings
end
else
File.open( RC_FILE, 'w' ) do |f|
- f.write( "# This file will be overwritten by epspdf_tk[.rb]" \
+ f.write( "# This file will be overwritten by epspdf[tk][.rb]" \
+ $/ )
$settings.each do |key, st|
if st.type == 'config'
@@ -355,26 +378,40 @@ class << $settings
def get_settings
# phase 1: autodetect
- # w32: gs_prog, gs_version, pdf_viewer, ps_viewer
- # gs: search registry settings; the highest version wins.
- # viewers: check file type registry entry for valid open commands
- # w32/TL: gs_prog, gs_version, pdf_viewer, ps_viewer
- # gs: from TL
- # viewers: check file type registry entry for valid open commands
- # unix: gs_prog, gs_version, pdftops_prog, pdf_viewers, ps_viewers
- # osx: gs_prog, gs_version, pdftops_prog
+ # w32: gs_prog, pdf_viewer, ps_viewer
+ # gs: search path; search registry settings (user and system);
+ # search tex installation. The first one wins.
+ # viewers: check file type registry entry for valid open commands
+ # unix: gs_prog, pdftops_prog, pdf_viewers, ps_viewers
+ # osx: gs_prog, pdftops_prog
# viewers: use Preview; don't check anything
# unix/osx are done together, except that for osx
# the viewers code is skipped.
+ # Windows: test for TeX, because it may come with a hidden
+ # ghostscript. TeX may also come with pdftops.exe, but pdftops
+ # would then be on the searchpath and not require special treatment.
+
+ texbindir = ( ARCH == 'w32' ) ? find_on_path( 'tex' ) : nil
+ texbindir = short_name( File.dirname( texbindir ) ) if texbindir
+
case ARCH
when 'w32'
- if !TL then # else use built-in texlive versions
- # check registry for latest valid version of Ghostscript
- # tentative values; HKLM and HKCU may provide different values
- try_gs_version = nil
+ # ghostscript:
+ # 1. check searchpath
+ # 2. check registry for latest valid version of Ghostscript
+ # 3. check tex installation
+ # TeX Live- and MikTeX versions need environment variables
+ # no need to remember: it will be the last thing we try
+ # searchpath
+ self.gs_prog = find_on_path( 'gswin32c' )
+
+ if not self.gs_prog
+ try_gs_version = 0
try_gs_prog = nil
+ this_gs_prog = nil
+ # tentative values; HKLM and HKCU may provide different values
[Registry::HKEY_LOCAL_MACHINE,
Registry::HKEY_CURRENT_USER].each { |hk|
puts hk.to_s if $DEBUG
@@ -384,55 +421,75 @@ class << $settings
puts key.to_s if $DEBUG
if key =~ /ghostscript/i
gh = hk.open('SOFTWARE\\' + key)
- gh.each_key { |skey, wtime|
- if skey =~ /^\d+\.\d+$/ # version number
- if skey.to_f > try_gs_version.to_f
- this_gs = hk.open('SOFTWARE\\' + key + '\\' + skey)
+ gh.each_key { |this_gs_version, wtime|
+ if this_gs_version =~ /^\d+\.\d+/ # version number
+ if this_gs_version.to_f > try_gs_version.to_f
+ this_gs = hk.open('SOFTWARE\\' + key +
+ '\\' + this_gs_version)
this_gs_prog = this_gs['GS_DLL'].sub(
/([\\\/])([^\\\/]+)$/, '\1gswin32c.exe')
if test(?e,this_gs_prog)
- try_gs_version = skey
+ try_gs_version = this_gs_version
try_gs_prog = this_gs_prog
end # if ?e (exist)
- end # skey.to_f > try_gs_version.to_f
- end # if skey =~ /^\d+\.\d+$/
+ end # this_gs_version.to_f > try_gs_version.to_f
+ end # if this_gs_version =~ /^\d+\.\d+$/
} # gh.each_key
end # if key =~ /ghostscript/i
} # sof.each_key
} # hk.open |sof|
} # [HKCU, HKLM].each
- self.gs_version = try_gs_version
- self.gs_prog = try_gs_prog
- end
-
- # viewers
- self.pdf_viewer = open_with( 'pdf' )
- self.ps_viewer = open_with( 'ps' )
+ self.gs_prog = this_gs_prog if this_gs_prog
+ end # if not self.gs_prog
+ if texbindir and ! self.gs_prog
+ # TeX Live >= 2008:
+ # hidden gs in texbindir/../../tlpkg/tlgs
+ texroot = File.dirname( File.dirname( File.expand_path( texbindir )))
+ gsroot = texroot + '/tlpkg/tlgs'
+ this_gs_prog = gsroot + '/bin/gswin32c.exe'
+ if test( ?f, this_gs_prog )
+ self.gs_prog = this_gs_prog
+ ENV['GS_LIB'] = "#{gsroot}/lib;#{gsroot}/fonts;#{gsroot}/Resource"
+ else # test for MikTeX hidden ghostscript
+ # http://blog.miktex.org/post/2005/04/
+ # Starting-mgsexe-at-the-DOS-Prompt.aspx
+ # That's because mgs.exe doesn't use the original registry keys
+ # and environment variables. For example, mgs.exe queries
+ # MIKTEX_GS_LIB instead of GS_LIB. You can start mgs.exe
+ # at the DOS-prompt if you set MIKTEX_GS_LIB as follows:
+ # MIKTEX_GS_LIB=C:\texmf\ghostscript\base;C:\texmf\fonts
+ this_gs_prog = texbindir + '/mgs.exe'
+ if test( ?f, this_gs_prog ) and
+ test( ?d, "#{texroot}/ghostscript/base" )
+ self.gs_prog = this_gs_prog
+ ENV['MIKTEX_GS_LIB'] =
+ "#{texroot}/ghostscript/base;#{texroot}/fonts"
+ end # ?f, this_gs_prog
+ end # try MikTeX hidden Ghostscript
+ end # texbindir and ! self.gs_prog
+ fail( "No ghostscript" ) unless self.gs_prog
+ self.gs_prog = short_name( self.gs_prog )
+
+ # pdftops: just check the searchpath
+ self.pdftops_prog = find_on_path( 'pdftops' )
when /unix|osx/
# gs
- answer = `gs --version`
- if answer and not answer.empty?
- self.gs_prog = 'gs'
- self.gs_version = answer.chomp
- else
- self.gs_prog = nil
- self.gs_version = nil
- end
+ self.gs_prog = is_a_program( 'gs' ) ? 'gs' : nil
# pdftops
- self.pdftops_prog = xpdf_version( 'pdftops' ) ? 'pdftops' : nil
+ self.pdftops_prog = is_a_program( 'pdftops' ) ? 'pdftops' : nil
# viewers
if ARCH == 'unix'
- vw = %w{ gpdf xpdf acroread evince ggv gv kghostview }
+ vw = %w{ evince gpdf xpdf acroread epdfview gv gsview okular }
vw.delete_if { |x| not is_a_program( x ) }
vw = nil if vw.empty?
self.pdf_viewers = vw
self.pdf_viewer = vw ? vw[0] : nil
if vw
vw2 = vw.dup # copy the elements rather than the array ref
- [ 'gpdf', 'xpdf', 'acroread' ].each { |pg|
+ [ 'gpdf', 'xpdf', 'acroread', 'epdfview' ].each { |pg|
vw2.delete( pg ) if vw2.index( pg )
}
vw2 = nil if vw2.empty?
@@ -440,7 +497,8 @@ class << $settings
self.ps_viewer = vw2 ? vw2[ 0 ] : nil
end # if vw
end # if unix
- end # case
+
+ end # case ARCH
# built-in defaults already set during initialization of $settings
@@ -452,21 +510,10 @@ class << $settings
case ARCH
when 'w32'
- $rc_settings[ 'pdftops_prog' ] = (
- TL ? (TLROOT.gsub( /\//, '\\' ) + '\\bin\\win32\\pdftops.exe') :
- "z:\\aps\\staff\\ber\\miktex\\xpdf\\pdftops.exe" ) unless
- ( $rc_settings[ 'pdftops_prog' ] and
- ! $rc_settings[ 'pdftops_prog' ].empty? )
- ptop = $rc_settings[ 'pdftops_prog' ]
- if xpdf_version( ptop ) then
- self.pdftops_prog = ptop
- end
- if TL
- self.gs_prog = TLROOT.gsub( /\//, '\\' ) +
- '\\tlpkg\\tlgs\\bin\\gswin32c.exe'
- self.gs_version =
- ( `#{short_name( self.gs_prog )} --version` ).chomp
- end
+ self.pdftops_prog = $rc_settings[ 'pdftops_prog' ] if
+ $rc_settings[ 'pdftops_prog' ] and
+ ! $rc_settings[ 'pdftops_prog' ].empty? and
+ test( ?f, $rc_settings[ 'pdftops_prog' ] )
when 'unix'
if v = $rc_settings[ 'pdf_viewer' ] and is_a_program( v )
self.pdf_viewer = v
@@ -482,22 +529,44 @@ class << $settings
end # if
end # case ARCH
+ if ( $rc_settings[ 'defaultDir' ] and
+ ( not $rc_settings[ 'defaultDir' ].strip.empty? ) and
+ test( ?d, $rc_settings[ 'defaultDir' ] ) )
+ self.defaultDir = File.expand_path( $rc_settings[ 'defaultDir' ] )
+ else
+ self.defaultDir = Dir.getwd
+ end
+ #print "defaultDir set to #{self.defaultDir} by epspdfrc.getsettings"
+
+
# no validity checks for pdf- and ps output options.
# reminder: self.s shortcut for self['s'].val
[ 'pdf_target', 'pdf_version', 'pdf_custom', 'ps_options' ].each { |p|
self[ p ].val = $rc_settings[ p ] if $rc_settings[ p ]
}
if $rc_settings.has_key?( 'ignore_pdftops' )
- $settings.ignore_pdftops = case $rc_settings[ 'ignore_pdftops' ]
+ self.ignore_pdftops = case $rc_settings[ 'ignore_pdftops' ]
+ when /1|yes|true|y|t/i
+ '1'
+ when /0|no|false|n|f/i
+ '0'
+ end
+ else
+ self.ignore_pdftops = '0'
+ end
+
+ if $rc_settings.has_key?( 'ignore_hires_bb' )
+ self.ignore_hires_bb = case $rc_settings[ 'ignore_hires_bb' ]
when /1|yes|true|y|t/i
'1'
when /0|no|false|n|f/i
'0'
end
else
- $settings.ignore_pdftops = '0'
+ self.ignore_hires_bb = '0'
end
+ # bb_spread has an effect only if ignore_hires_bb
self.bb_spread = $rc_settings[ 'bb_spread' ] if
$rc_settings.has_key?( 'bb_spread' ) and
$rc_settings[ 'bb_spread' ] =~ /^[+-]?[\d]+$/