summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2006-05-14 23:57:00 +0200
committerHans Hagen <pragma@wxs.nl>2006-05-14 23:57:00 +0200
commit6edea41ff329ce2d76f34a59e90fa5d80d0eaee2 (patch)
tree7de07dfd27b99d6351ab279d125fee4ceb706819 /scripts
parente55be69d9eb01458e3e1a884d3edcb637b7a00f8 (diff)
downloadcontext-6edea41ff329ce2d76f34a59e90fa5d80d0eaee2.tar.gz
stable 2006.05.14 23:57
Diffstat (limited to 'scripts')
-rw-r--r--scripts/context/ruby/base/kpse.rb45
-rw-r--r--scripts/context/ruby/base/kpsefast.rb24
-rw-r--r--scripts/context/ruby/base/kpseremote.rb5
-rw-r--r--scripts/context/ruby/base/merge.rb137
-rw-r--r--scripts/context/ruby/base/mp.rb6
-rw-r--r--scripts/context/ruby/base/tex.rb50
-rw-r--r--scripts/context/ruby/pstopdf.rb8
-rw-r--r--scripts/context/ruby/rlxtools.rb4
-rw-r--r--scripts/context/ruby/texmfstart.rb1432
-rw-r--r--scripts/context/ruby/tmftools.rb4
10 files changed, 1623 insertions, 92 deletions
diff --git a/scripts/context/ruby/base/kpse.rb b/scripts/context/ruby/base/kpse.rb
index a61b2f236..b0321672f 100644
--- a/scripts/context/ruby/base/kpse.rb
+++ b/scripts/context/ruby/base/kpse.rb
@@ -21,7 +21,7 @@ require 'rbconfig'
class String
def split_path
- if self =~ /\;/ then
+ if self =~ /\;/o || self =~ /^[a-z]\:/io then
self.split(";")
else
self.split(":")
@@ -217,16 +217,33 @@ module Kpse
end
# locate writable path
if ! formatpath.empty? then
- done = false
- formatpath.split_path.each do |fp|
- fp.gsub!(/\\/,'/')
+ formatpaths, done = formatpath.split_path, false
+ formatpaths.collect! do |fp|
+ fp.gsub!(/\\/o,'/')
+ fp.gsub!(/\/\/$/o,'/')
# remove funny patterns
- fp.sub!(/^!!/,'')
- fp.sub!(/\/+$/,'')
- fp.sub!(/unsetengine/,if enginepath then engine else '' end)
- if ! fp.empty? && (fp != '.') then
- # strip (possible engine) and test for writeability
- fpp = fp.sub(/#{engine}\/*$/,'')
+ fp.sub!(/^!!/o,'')
+ fp.sub!(/\/+$/o,'')
+ fp.sub!(/(unsetengine|unset)/o,if enginepath then engine else '' end)
+ fp
+ end
+ formatpaths.delete_if do |fp|
+ fp.empty? || fp == '.'
+ end
+ # the engine path may not yet be present, find first writable
+ formatpaths.each do |fp|
+ # strip (possible engine) and test for writeability
+ fpp = fp.sub(/#{engine}\/*$/o,'')
+ if FileTest.directory?(fpp) && FileTest.writable?(fpp) then
+ # use this path
+ formatpath, done = fp.dup, true
+ break
+ end
+ end
+ unless done then
+ formatpaths.each do |fp|
+ fpp = fp.sub(/#{engine}\/*$/o,'')
+ File.makedirs(fpp) rescue false # maybe we don't have an path yet
if FileTest.directory?(fpp) && FileTest.writable?(fpp) then
# use this path
formatpath, done = fp.dup, true
@@ -234,15 +251,17 @@ module Kpse
end
end
end
- formatpath = '.' unless done
+ unless done then
+ formatpath = '.'
+ end
end
# needed !
- begin File.makedirs(formatpath) ; rescue ; end ;
+ File.makedirs(formatpath) rescue false
# fall back to current path
formatpath = '.' if formatpath.empty? || ! FileTest.writable?(formatpath)
# append engine but prevent duplicates
formatpath = File.join(formatpath.sub(/\/*#{engine}\/*$/,''), engine) if enginepath
- begin File.makedirs(formatpath) ; rescue ; end ;
+ File.makedirs(formatpath) rescue false
setpath(engine,formatpath)
# ENV['engine'] = savedengine
end
diff --git a/scripts/context/ruby/base/kpsefast.rb b/scripts/context/ruby/base/kpsefast.rb
index 01210ed12..49f58ae30 100644
--- a/scripts/context/ruby/base/kpsefast.rb
+++ b/scripts/context/ruby/base/kpsefast.rb
@@ -13,7 +13,7 @@
class String
def split_path
- if self =~ /\;/ then
+ if self =~ /\;/o || self =~ /^[a-z]\:/io then
self.split(";")
else
self.split(":")
@@ -59,18 +59,31 @@ end
module KpseUtil
- @@texmftrees = ['texmf-local','texmf.local','texmf.gwtex','texmf.tetex','texmf']
+ # to be adapted, see loading cnf file
+
+ @@texmftrees = ['texmf-local','texmf.local','../..','texmf'] # '../..' is for gwtex
@@texmfcnf = 'texmf.cnf'
def KpseUtil::identify
+ # we mainly need to identify the local tex stuff and wse assume that
+ # the texmfcnf variable is set; otherwise we need to expand the
+ # TEXMF variable and that takes time since it may involve more
ownpath = File.expand_path($0)
if ownpath.gsub!(/texmf.*?$/o, '') then
ENV['SELFAUTOPARENT'] = ownpath
else
- ENV['SELFAUTOPARENT'] = '.'
+ ENV['SELFAUTOPARENT'] = '.' # fall back
+ # may be too tricky:
+ #
+ # (ENV['PATH'] ||'').split_path.each do |p|
+ # if p.gsub!(/texmf.*?$/o, '') then
+ # ENV['SELFAUTOPARENT'] = p
+ # break
+ # end
+ # end
end
filenames = Array.new
- if ENV['TEXMFCNF'] and not ENV['TEXMFCNF'].empty? then
+ if ENV['TEXMFCNF'] && ! ENV['TEXMFCNF'].empty? then
ENV['TEXMFCNF'].to_s.split_path.each do |path|
filenames << File.join(path,@@texmfcnf)
end
@@ -296,6 +309,7 @@ class KpseFast
@treepath = @treepath.split(',').collect do |p| File.join(@rootpath,p) end.join(',')
end
@environment['TEXMF'] = @treepath
+ # only the first one
@environment['TEXMFCNF'] = File.join(@treepath.split(',').first,'texmf/web2c')
end
unless @rootpath.empty? then
@@ -660,7 +674,7 @@ end
class KpseFast
def _is_cnf_?(filename)
- filename == File.basename((@cnffiles.first rescue @@texmfcnf))
+ filename == File.basename((@cnffiles.first rescue @@texmfcnf) || @@texmfcnf)
end
def find_file(filename)
diff --git a/scripts/context/ruby/base/kpseremote.rb b/scripts/context/ruby/base/kpseremote.rb
index d66e40e6f..9a73b88b0 100644
--- a/scripts/context/ruby/base/kpseremote.rb
+++ b/scripts/context/ruby/base/kpseremote.rb
@@ -8,10 +8,11 @@ end
class KpseRemote
- @@port = ENV['KPSEPORT'] || 7000
+ @@port = ENV['KPSEPORT'] || 7000
+ @@method = ENV['KPSEMETHOD'] || 'drb'
def KpseRemote::available?
- ENV['KPSEMETHOD'] && ENV['KPSEPORT']
+ @@method && @@port
end
def KpseRemote::start_server(port=nil)
diff --git a/scripts/context/ruby/base/merge.rb b/scripts/context/ruby/base/merge.rb
new file mode 100644
index 000000000..36ab85269
--- /dev/null
+++ b/scripts/context/ruby/base/merge.rb
@@ -0,0 +1,137 @@
+# module : base/merge
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2006
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# --selfmerg ewill create stand alone script (--selfcleanup does the opposite)
+
+# this module will package all the used modules in the file itself
+# so that we can relocate the file at wish, usage:
+#
+# merge:
+#
+# unless SelfMerge::ok? && SelfMerge::merge then
+# puts("merging should happen on the path were the base inserts reside")
+# end
+#
+# cleanup:
+#
+# unless SelfMerge::cleanup then
+# puts("merging should happen on the path were the base inserts reside")
+# end
+
+module SelfMerge
+
+ @@kpsemergestart = "\# kpse_merge_start"
+ @@kpsemergestop = "\# kpse_merge_stop"
+ @@kpsemergefile = "\# kpse_merge_file: "
+ @@kpsemergedone = "\# kpse_merge_done: "
+
+ @@filename = File.basename($0)
+ @@ownpath = File.expand_path(File.dirname($0))
+ @@modroot = '(base|graphics|rslb|www)' # needed in regex in order not to mess up SelfMerge
+ @@modules = $".collect do |file| File.expand_path(file) end
+
+ @@modules.delete_if do |file|
+ file !~ /^#{@@ownpath}\/#{@@modroot}.*$/
+ end
+
+ def SelfMerge::ok?
+ begin
+ @@modules.each do |file|
+ return false unless FileTest.file?(file)
+ end
+ rescue
+ return false
+ else
+ return true
+ end
+ end
+
+ def SelfMerge::merge(filename=@@filename)
+ begin
+ if rbfile = IO.read(filename) then
+ begin
+ inserts = "#{@@kpsemergestart}\n\n"
+ @@modules.each do |file|
+ inserts << "#{@@kpsemergefile}'#{file}'\n\n"
+ inserts << IO.read(file).gsub(/^#.*?\n$/,'')
+ inserts << "\n\n"
+ end
+ inserts << "#{@@kpsemergestop}\n\n"
+ # no gsub! else we end up in SelfMerge
+ rbfile.sub!(/#{@@kpsemergestart}\s*#{@@kpsemergestop}/mois) do
+ inserts
+ end
+ rbfile.gsub!(/^(.*)(require [\"\'].*?#{@@modroot}.*)$/) do
+ pre, post = $1, $2
+ if pre =~ /#{@@kpsemergedone}/ then
+ "#{pre}#{post}"
+ else
+ "#{pre}#{@@kpsemergedone}#{post}"
+ end
+ end
+ rescue
+ return false
+ else
+ begin
+ File.open(filename,'w') do |f|
+ f << rbfile
+ end
+ rescue
+ return false
+ end
+ end
+ end
+ rescue
+ return false
+ else
+ return true
+ end
+ end
+
+ def SelfMerge::cleanup(filename=@@filename)
+ begin
+ if rbfile = IO.read(filename) then
+ begin
+ rbfile.sub!(/#{@@kpsemergestart}(.*)#{@@kpsemergestop}\s*/mois) do
+ "#{@@kpsemergestart}\n\n#{@@kpsemergestop}\n\n"
+ end
+ rbfile.gsub!(/^(.*#{@@kpsemergedone}.*)$/) do
+ str = $1
+ if str =~ /require [\"\']/ then
+ str.gsub(/#{@@kpsemergedone}/, '')
+ else
+ str
+ end
+ end
+ rescue
+ return false
+ else
+ begin
+ File.open(filename,'w') do |f|
+ f << rbfile
+ end
+ rescue
+ return false
+ end
+ end
+ end
+ rescue
+ return false
+ else
+ return true
+ end
+ end
+
+ def SelfMerge::replace(filename=@@filename)
+ SelfMerge::cleanup(filename)
+ SelfMerge::merge(filename)
+ end
+
+end
diff --git a/scripts/context/ruby/base/mp.rb b/scripts/context/ruby/base/mp.rb
index a501b2903..17e9eca76 100644
--- a/scripts/context/ruby/base/mp.rb
+++ b/scripts/context/ruby/base/mp.rb
@@ -152,9 +152,11 @@ EOT
result.gsub!(/\"(\d+)\"/) do
"\"#{strings[$1.to_i]}\""
end
- return result
+ # return result # let's catch xetex bug
+ return result.gsub(/\^\^(M|J)/o, "\n")
else
- return str
+ # return str # let's catch xetex bug
+ return str.gsub(/\^\^(M|J)/o, "\n")
end
end
diff --git a/scripts/context/ruby/base/tex.rb b/scripts/context/ruby/base/tex.rb
index 1e1b67f0f..4335a9618 100644
--- a/scripts/context/ruby/base/tex.rb
+++ b/scripts/context/ruby/base/tex.rb
@@ -499,19 +499,21 @@ class TEX
texformatpath = if getvariable('local') then '.' else Kpse.formatpath(texengine,true) end
# can be empty, to do
report("using tex format path #{texformatpath}")
- begin
- Dir.chdir(texformatpath)
- rescue
- end
- if texformats.length > 0 then
- makeuserfile
- makeresponsefile
- end
- texformats.each do |texformat|
- report("generating tex format #{texformat}")
- command = [quoted(texengine),prognameflag(progname),iniflag,tcxflag,prefixed(texformat,texengine),texmakeextras(texformat)].join(' ')
- report(command) if getvariable('verbose')
- system(command)
+ Dir.chdir(texformatpath) rescue false
+ if FileTest.writable?(texformatpath) then
+ if texformats.length > 0 then
+ makeuserfile
+ makeresponsefile
+ end
+ texformats.each do |texformat|
+ report("generating tex format #{texformat}")
+ command = [quoted(texengine),prognameflag(progname),iniflag,tcxflag,prefixed(texformat,texengine),texmakeextras(texformat)].join(' ')
+ report(command) if getvariable('verbose')
+ system(command)
+ end
+ else
+ report("unable to make format due to lack of permissions")
+ texformatpath = ''
end
else
texformatpath = ''
@@ -521,16 +523,18 @@ class TEX
report("using mp engine #{mpsengine}")
mpsformatpath = if getvariable('local') then '.' else Kpse.formatpath(mpsengine,false) end
report("using mps format path #{mpsformatpath}")
- begin
- Dir.chdir(mpsformatpath)
- rescue
- end
- mpsformats.each do |mpsformat|
- report("generating mps format #{mpsformat}")
- # command = [quoted(mpsengine),prognameflag(progname),iniflag,tcxflag,mpsformat,mpsmakeextras(mpsformat)].join(' ')
- command = [quoted(mpsengine),iniflag,tcxflag,mpsformat,mpsmakeextras(mpsformat)].join(' ')
- report(command) if getvariable('verbose')
- system(command)
+ Dir.chdir(mpsformatpath) rescue false
+ if FileTest.writable?(mpsformatpath) then
+ mpsformats.each do |mpsformat|
+ report("generating mps format #{mpsformat}")
+ # command = [quoted(mpsengine),prognameflag(progname),iniflag,tcxflag,mpsformat,mpsmakeextras(mpsformat)].join(' ')
+ command = [quoted(mpsengine),iniflag,tcxflag,mpsformat,mpsmakeextras(mpsformat)].join(' ')
+ report(command) if getvariable('verbose')
+ system(command)
+ end
+ else
+ report("unable to make format due to lack of permissions")
+ mpsformatpath = ''
end
else
mpsformatpath = ''
diff --git a/scripts/context/ruby/pstopdf.rb b/scripts/context/ruby/pstopdf.rb
index 96469beb4..197f83961 100644
--- a/scripts/context/ruby/pstopdf.rb
+++ b/scripts/context/ruby/pstopdf.rb
@@ -288,7 +288,7 @@ class Commands
if FileTest.directory?(donepath) && FileTest.directory?(resultpath) then
- resultname = resultpath + '/' + filename.sub(/\..*$/,'') + '.pdf'
+ resultname = resultpath + '/' + filename.sub(/\.[^\.]*$/,'') + '.pdf'
@commandline.setoption('inputpath', filepath)
@commandline.setoption('outputpath', resultpath)
@@ -360,7 +360,7 @@ class Commands
suffix = @commandline.option('suffix')
inpfilename = "#{inppath}#{filename}"
- outfilename = "#{outpath}#{prefix}#{filename.sub(/\.(.*?)$/, '')}#{suffix}.pdf"
+ outfilename = "#{outpath}#{prefix}#{filename.sub(/\.([^\.]*?)$/, '')}#{suffix}.pdf"
magick.setvariable('inputfile' , inpfilename)
magick.setvariable('outputfile', outfilename)
@@ -383,7 +383,7 @@ class Commands
suffix = @commandline.option('suffix')
inpfilename = "#{inppath}#{filename}"
- outfilename = "#{outpath}#{prefix}#{filename.sub(/\.(.*?)$/, '')}#{suffix}.pdf"
+ outfilename = "#{outpath}#{prefix}#{filename.sub(/\.([^\.]*?)$/, '')}#{suffix}.pdf"
inkscape.setvariable('inputfile' , inpfilename)
inkscape.setvariable('outputfile', outfilename)
@@ -451,7 +451,7 @@ class Commands
elsif ghostscript.psfile?(filename) then
- if filename =~ /(.*)\.(.*?)$/io then
+ if filename =~ /(.*)\.([^\.]*?)$/io then
filename, filesuffix = $1, $2
else
filesuffix = 'eps'
diff --git a/scripts/context/ruby/rlxtools.rb b/scripts/context/ruby/rlxtools.rb
index addfe9894..6a796114f 100644
--- a/scripts/context/ruby/rlxtools.rb
+++ b/scripts/context/ruby/rlxtools.rb
@@ -97,7 +97,7 @@ class Commands
report("processing record #{nofrecords} (#{variables['file'] || 'noname'}: #{variables.size} entries)")
if conversion = variables['conversion'] then
report("testing for conversion #{conversion}")
- if suffix.downcase = variables['suffix'].downcase then
+ if suffix = variables['suffix'].downcase then
if file = variables['file'] then
report("conversion #{conversion} for suffix #{suffix} for file #{file}")
else
@@ -176,7 +176,7 @@ class Commands
end
end
rescue
- report('error in manipulating files')
+ report("error in manipulating files: #{$!}")
end
begin
logname = "#{filename}.log"
diff --git a/scripts/context/ruby/texmfstart.rb b/scripts/context/ruby/texmfstart.rb
index 490bd609c..8bda35c7b 100644
--- a/scripts/context/ruby/texmfstart.rb
+++ b/scripts/context/ruby/texmfstart.rb
@@ -32,50 +32,1396 @@
$ownpath = File.expand_path(File.dirname($0)) unless defined? $ownpath
-# base/kpseremote
-# texmfstart-lib/base/kpseremote
-# ../../texmf-local/scripts/context/ruby
-# ../../texmf/scripts/context/ruby
-
-# we may assume a symlink on unix systems, so there the library is
-# at the right spot
-
$: << $ownpath
-$: << File.expand_path("#{$ownpath}/../lib")
-$: << File.expand_path("#{$ownpath}/texmfstart-lib")
-$: << File.expand_path("#{$ownpath}/../../texmf-local/scripts/context/ruby")
-# $: << File.expand_path("#{$ownpath}/../../texmf.local/scripts/context/ruby")
-# $: << File.expand_path("#{$ownpath}/../../texmf.gwtex/scripts/context/ruby")
-# $: << File.expand_path("#{$ownpath}/../../texmf.tetex/scripts/context/ruby")
-$: << File.expand_path("#{$ownpath}/../../texmf/scripts/context/ruby")
require "rbconfig"
-$kpsereport, $kpseerror, $kpsemodules = "", false, ['base/kpseremote','base/kpsedirect','base/kpsefast']
+# kpse_merge_done: require 'base/kpseremote'
+# kpse_merge_done: require 'base/kpsedirect'
+# kpse_merge_done: require 'base/kpsefast'
+# kpse_merge_done: require 'base/merge'
-$kpsemodules.each do |basemodule|
- begin
- require basemodule
- rescue Exception
- $kpseerror = true
+# kpse_merge_start
+
+# kpse_merge_file: 'C:/data/develop/context/ruby/base/kpseremote.rb'
+
+# kpse_merge_done: require 'base/kpsefast'
+
+case ENV['KPSEMETHOD']
+ when /soap/o then # kpse_merge_done: require 'base/kpse/soap'
+ when /drb/o then # kpse_merge_done: require 'base/kpse/drb'
+ else # kpse_merge_done: require 'base/kpse/drb'
+end
+
+class KpseRemote
+
+ @@port = ENV['KPSEPORT'] || 7000
+ @@method = ENV['KPSEMETHOD'] || 'drb'
+
+ def KpseRemote::available?
+ @@method && @@port
+ end
+
+ def KpseRemote::start_server(port=nil)
+ kpse = KpseServer.new(port || @@port)
+ kpse.start
+ end
+
+ def KpseRemote::start_client(port=nil) # keeps object in server
+ kpseclient = KpseClient.new(port || @@port)
+ kpseclient.start
+ kpse = kpseclient.object
+ tree = kpse.choose(KpseUtil::identify, KpseUtil::environment)
+ [kpse, tree]
+ end
+
+ def KpseRemote::fetch(port=nil) # no need for defining methods but slower, send whole object
+ kpseclient = KpseClient.new(port || @@port)
+ kpseclient.start
+ kpseclient.object.fetch(KpseUtil::identify, KpseUtil::environment) rescue nil
+ end
+
+ def initialize(port=nil)
+ if KpseRemote::available? then
+ begin
+ @kpse, @tree = KpseRemote::start_client(port)
+ rescue
+ @kpse, @tree = nil, nil
+ end
+ else
+ @kpse, @tree = nil, nil
+ end
+ end
+
+ def progname=(value)
+ @kpse.set(@tree,'progname',value)
+ end
+ def format=(value)
+ @kpse.set(@tree,'format',value)
+ end
+ def engine=(value)
+ @kpse.set(@tree,'engine',value)
+ end
+
+ def progname
+ @kpse.get(@tree,'progname')
+ end
+ def format
+ @kpse.get(@tree,'format')
+ end
+ def engine
+ @kpse.get(@tree,'engine')
+ end
+
+ def load
+ @kpse.load(KpseUtil::identify, KpseUtil::environment)
+ end
+ def okay?
+ @kpse && @tree
+ end
+ def set(key,value)
+ @kpse.set(@tree,key,value)
+ end
+ def load_cnf
+ @kpse.load_cnf(@tree)
+ end
+ def load_lsr
+ @kpse.load_lsr(@tree)
+ end
+ def expand_variables
+ @kpse.expand_variables(@tree)
+ end
+ def expand_braces(str)
+ clean_name(@kpse.expand_braces(@tree,str))
+ end
+ def expand_path(str)
+ clean_name(@kpse.expand_path(@tree,str))
+ end
+ def expand_var(str)
+ clean_name(@kpse.expand_var(@tree,str))
+ end
+ def show_path(str)
+ clean_name(@kpse.show_path(@tree,str))
+ end
+ def var_value(str)
+ clean_name(@kpse.var_value(@tree,str))
+ end
+ def find_file(filename)
+ clean_name(@kpse.find_file(@tree,filename))
+ end
+ def find_files(filename,first=false)
+ # dodo: each filename
+ @kpse.find_files(@tree,filename,first)
+ end
+
+ private
+
+ def clean_name(str)
+ str.gsub(/\\/,'/')
+ end
+
+end
+
+
+# kpse_merge_file: 'C:/data/develop/context/ruby/base/kpsefast.rb'
+
+# module : base/kpsefast
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+
+
+class String
+
+ def split_path
+ if self =~ /\;/o || self =~ /^[a-z]\:/io then
+ self.split(";")
+ else
+ self.split(":")
+ end
+ end
+
+end
+
+class Array
+
+ def join_path
+ self.join(File::PATH_SEPARATOR)
+ end
+
+end
+
+class File
+
+ def File.locate_file(path,name)
+ begin
+ files = Dir.entries(path)
+ if files.include?(name) then
+ fullname = File.join(path,name)
+ return fullname if FileTest.file?(fullname)
+ end
+ files.each do |p|
+ fullname = File.join(path,p)
+ if p != '.' and p != '..' and FileTest.directory?(fullname) and result = locate_file(fullname,name) then
+ return result
+ end
+ end
+ rescue
+ # bad path
+ end
+ return nil
+ end
+
+ def File.glob_file(pattern)
+ return Dir.glob(pattern).first
+ end
+
+end
+
+module KpseUtil
+
+ # to be adapted, see loading cnf file
+
+ @@texmftrees = ['texmf-local','texmf.local','../..','texmf'] # '../..' is for gwtex
+ @@texmfcnf = 'texmf.cnf'
+
+ def KpseUtil::identify
+ # we mainly need to identify the local tex stuff and wse assume that
+ # the texmfcnf variable is set; otherwise we need to expand the
+ # TEXMF variable and that takes time since it may involve more
+ ownpath = File.expand_path($0)
+ if ownpath.gsub!(/texmf.*?$/o, '') then
+ ENV['SELFAUTOPARENT'] = ownpath
+ else
+ ENV['SELFAUTOPARENT'] = '.' # fall back
+ # may be too tricky:
+ #
+ # (ENV['PATH'] ||'').split_path.each do |p|
+ # if p.gsub!(/texmf.*?$/o, '') then
+ # ENV['SELFAUTOPARENT'] = p
+ # break
+ # end
+ # end
+ end
+ filenames = Array.new
+ if ENV['TEXMFCNF'] && ! ENV['TEXMFCNF'].empty? then
+ ENV['TEXMFCNF'].to_s.split_path.each do |path|
+ filenames << File.join(path,@@texmfcnf)
+ end
+ elsif ENV['SELFAUTOPARENT'] == '.' then
+ filenames << File.join('.',@@texmfcnf)
+ else
+ @@texmftrees.each do |tree|
+ filenames << File.join(ENV['SELFAUTOPARENT'],tree,'web2c',@@texmfcnf)
+ end
+ end
+ loop do
+ busy = false
+ filenames.collect! do |f|
+ f.gsub(/\$([a-zA-Z0-9\_\-]*)/o) do
+ busy = true
+ ENV[$1] || ("$#{$1}")
+ end
+ end
+ break unless busy
+ end
+ filenames.delete_if do |f|
+ ! FileTest.file?(f)
+ end
+ return filenames
+ end
+
+ def KpseUtil::environment
+ Hash.new.merge(ENV)
+ end
+
+end
+
+class KpseFast
+
+ # formats are an incredible inconsistent mess
+
+ @@suffixes = Hash.new
+ @@formats = Hash.new
+ @@suffixmap = Hash.new
+
+ @@texmfcnf = 'texmf.cnf'
+
+ @@suffixes['gf'] = ['.<resolution>gf'] # todo
+ @@suffixes['pk'] = ['.<resolution>pk'] # todo
+ @@suffixes['tfm'] = ['.tfm']
+ @@suffixes['afm'] = ['.afm']
+ @@suffixes['base'] = ['.base']
+ @@suffixes['bib'] = ['.bib']
+ @@suffixes['bst'] = ['.bst']
+ @@suffixes['cnf'] = ['.cnf']
+ @@suffixes['ls-R'] = ['ls-R', 'ls-r']
+ @@suffixes['fmt'] = ['.fmt', '.efmt', '.efm', '.ofmt', '.ofm', '.oft', '.eofmt', '.eoft', '.eof', '.pfmt', '.pfm', '.epfmt', '.epf', '.xpfmt', '.xpf', '.afmt', '.afm']
+ @@suffixes['map'] = ['.map']
+ @@suffixes['mem'] = ['.mem']
+ @@suffixes['mf'] = ['.mf']
+ @@suffixes['mfpool'] = ['.pool']
+ @@suffixes['mft'] = ['.mft']
+ @@suffixes['mp'] = ['.mp']
+ @@suffixes['mppool'] = ['.pool']
+ @@suffixes['ocp'] = ['.ocp']
+ @@suffixes['ofm'] = ['.ofm', '.tfm']
+ @@suffixes['opl'] = ['.opl']
+ @@suffixes['otp'] = ['.otp']
+ @@suffixes['ovf'] = ['.ovf']
+ @@suffixes['ovp'] = ['.ovp']
+ @@suffixes['graphic/figure'] = ['.eps', '.epsi']
+ @@suffixes['tex'] = ['.tex']
+ @@suffixes['texpool'] = ['.pool']
+ @@suffixes['PostScript header'] = ['.pro']
+ @@suffixes['type1 fonts'] = ['.pfa', '.pfb']
+ @@suffixes['vf'] = ['.vf']
+ @@suffixes['ist'] = ['.ist']
+ @@suffixes['truetype fonts'] = ['.ttf', '.ttc']
+ @@suffixes['web'] = ['.web', '.ch']
+ @@suffixes['cweb'] = ['.w', '.web', '.ch']
+ @@suffixes['enc files'] = ['.enc']
+ @@suffixes['cmap files'] = ['.cmap']
+ @@suffixes['subfont definition files'] = ['.sfd']
+ @@suffixes['lig files'] = ['.lig']
+ @@suffixes['bitmap font'] = []
+ @@suffixes['MetaPost support'] = []
+ @@suffixes['TeX system documentation'] = []
+ @@suffixes['TeX system sources'] = []
+ @@suffixes['Troff fonts'] = []
+ @@suffixes['dvips config'] = []
+ @@suffixes['type42 fonts'] = []
+ @@suffixes['web2c files'] = []
+ @@suffixes['other text files'] = []
+ @@suffixes['other binary files'] = []
+ @@suffixes['misc fonts'] = []
+ @@suffixes['opentype fonts'] = []
+ @@suffixes['pdftex config'] = []
+ @@suffixes['texmfscripts'] = []
+
+ # replacements
+
+ @@suffixes['fmt'] = ['.fmt']
+ @@suffixes['type1 fonts'] = ['.pfa', '.pfb', '.pfm']
+ @@suffixes['tex'] = ['.tex', '.xml']
+ @@suffixes['texmfscripts'] = ['rb','lua','py','pl']
+
+ @@suffixes.keys.each do |k| @@suffixes[k].each do |s| @@suffixmap[s] = k end end
+
+ # TTF2TFMINPUTS
+ # MISCFONTS
+ # TEXCONFIG
+ # DVIPDFMINPUTS
+ # OTFFONTS
+
+ @@formats['gf'] = ''
+ @@formats['pk'] = ''
+ @@formats['tfm'] = 'TFMFONTS'
+ @@formats['afm'] = 'AFMFONTS'
+ @@formats['base'] = 'MFBASES'
+ @@formats['bib'] = ''
+ @@formats['bst'] = ''
+ @@formats['cnf'] = ''
+ @@formats['ls-R'] = ''
+ @@formats['fmt'] = 'TEXFORMATS'
+ @@formats['map'] = 'TEXFONTMAPS'
+ @@formats['mem'] = 'MPMEMS'
+ @@formats['mf'] = 'MFINPUTS'
+ @@formats['mfpool'] = 'MFPOOL'
+ @@formats['mft'] = ''
+ @@formats['mp'] = 'MPINPUTS'
+ @@formats['mppool'] = 'MPPOOL'
+ @@formats['ocp'] = 'OCPINPUTS'
+ @@formats['ofm'] = 'OFMFONTS'
+ @@formats['opl'] = 'OPLFONTS'
+ @@formats['otp'] = 'OTPINPUTS'
+ @@formats['ovf'] = 'OVFFONTS'
+ @@formats['ovp'] = 'OVPFONTS'
+ @@formats['graphic/figure'] = ''
+ @@formats['tex'] = 'TEXINPUTS'
+ @@formats['texpool'] = 'TEXPOOL'
+ @@formats['PostScript header'] = 'TEXPSHEADERS'
+ @@formats['type1 fonts'] = 'T1FONTS'
+ @@formats['vf'] = 'VFFONTS'
+ @@formats['ist'] = ''
+ @@formats['truetype fonts'] = 'TTFONTS'
+ @@formats['web'] = ''
+ @@formats['cweb'] = ''
+ @@formats['enc files'] = 'ENCFONTS'
+ @@formats['cmap files'] = 'CMAPFONTS'
+ @@formats['subfont definition files'] = 'SFDFONTS'
+ @@formats['lig files'] = 'LIGFONTS'
+ @@formats['bitmap font'] = ''
+ @@formats['MetaPost support'] = ''
+ @@formats['TeX system documentation'] = ''
+ @@formats['TeX system sources'] = ''
+ @@formats['Troff fonts'] = ''
+ @@formats['dvips config'] = ''
+ @@formats['type42 fonts'] = 'T42FONTS'
+ @@formats['web2c files'] = 'WEB2C'
+ @@formats['other text files'] = ''
+ @@formats['other binary files'] = ''
+ @@formats['misc fonts'] = ''
+ @@formats['opentype fonts'] = 'OPENTYPEFONTS'
+ @@formats['pdftex config'] = 'PDFTEXCONFIG'
+ @@formats['texmfscripts'] = 'TEXMFSCRIPTS'
+
+ attr_accessor :progname, :engine, :format, :rootpath, :treepath,
+ :verbose, :remember, :scandisk, :diskcache, :renewcache
+
+ @@cacheversion = '1'
+
+ def initialize
+ @rootpath = ''
+ @treepath = ''
+ @progname = 'kpsewhich'
+ @engine = 'pdfetex'
+ @variables = Hash.new
+ @expansions = Hash.new
+ @files = Hash.new
+ @found = Hash.new
+ @kpsevars = Hash.new
+ @lsrfiles = Array.new
+ @cnffiles = Array.new
+ @verbose = true
+ @remember = true
+ @scandisk = true
+ @diskcache = true
+ @renewcache = false
+ @isolate = false
+
+ @diskcache = false
+ @cachepath = nil
+ @cachefile = 'tmftools.log'
+
+ @environment = ENV
+ end
+
+ def set(key,value)
+ case key
+ when 'progname' then @progname = value
+ when 'engine' then @engine = value
+ when 'format' then @format = value
+ end
+ end
+
+ def push_environment(env)
+ @environment = env
+ end
+
+ # {$SELFAUTOLOC,$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}
+ #
+ # $SELFAUTOLOC : /usr/tex/bin/platform
+ # $SELFAUTODIR : /usr/tex/bin
+ # $SELFAUTOPARENT : /usr/tex
+ #
+ # since we live in scriptpath we need a slightly different method
+
+ def load_cnf(filenames=nil)
+ unless filenames then
+ ownpath = File.expand_path($0)
+ if ownpath.gsub!(/texmf.*?$/o, '') then
+ @environment['SELFAUTOPARENT'] = ownpath
+ else
+ @environment['SELFAUTOPARENT'] = '.'
+ end
+ unless @treepath.empty? then
+ unless @rootpath.empty? then
+ @treepath = @treepath.split(',').collect do |p| File.join(@rootpath,p) end.join(',')
+ end
+ @environment['TEXMF'] = @treepath
+ # only the first one
+ @environment['TEXMFCNF'] = File.join(@treepath.split(',').first,'texmf/web2c')
+ end
+ unless @rootpath.empty? then
+ @environment['TEXMFCNF'] = File.join(@rootpath,'texmf/web2c')
+ @environment['SELFAUTOPARENT'] = @rootpath
+ @isolate = true
+ end
+ filenames = Array.new
+ if @environment['TEXMFCNF'] and not @environment['TEXMFCNF'].empty? then
+ @environment['TEXMFCNF'].to_s.split_path.each do |path|
+ filenames << File.join(path,@@texmfcnf)
+ end
+ elsif @environment['SELFAUTOPARENT'] == '.' then
+ filenames << File.join('.',@@texmfcnf)
+ else
+ ['texmf-local','texmf'].each do |tree|
+ filenames << File.join(@environment['SELFAUTOPARENT'],tree,'web2c',@@texmfcnf)
+ end
+ end
+ end
+ # <root>/texmf/web2c/texmf.cnf
+ filenames = _expanded_path_(filenames)
+ @rootpath = filenames.first
+ 3.times do
+ @rootpath = File.dirname(@rootpath)
+ end
+ filenames.collect! do |f|
+ f.gsub("\\", '/')
+ end
+ filenames.each do |fname|
+ if FileTest.file?(fname) and f = File.open(fname) then
+ @cnffiles << fname
+ while line = f.gets do
+ loop do
+ # concatenate lines ending with \
+ break unless line.sub!(/\\\s*$/o) do
+ f.gets || ''
+ end
+ end
+ case line
+ when /^[\%\#]/o then
+ # comment
+ when /^\s*(.*?)\s*\=\s*(.*?)\s*$/o then
+ key, value = $1, $2
+ unless @variables.key?(key) then
+ value.sub!(/\%.*$/,'')
+ value.sub!(/\~/, "$HOME")
+ @variables[key] = value
+ end
+ @kpsevars[key] = true
+ end
+ end
+ f.close
+ end
+ end
+ end
+
+ def load_lsr
+ @lsrfiles = []
+ simplified_list(expansion('TEXMF')).each do |p|
+ ['ls-R','ls-r'].each do |f|
+ filename = File.join(p,f)
+ if FileTest.file?(filename) then
+ @lsrfiles << [filename,File.size(filename)]
+ break
+ end
+ end
+ end
+ @files = Hash.new
+ if @diskcache then
+ ['HOME','TEMP','TMP','TMPDIR'].each do |key|
+ if @environment[key] then
+ if FileTest.directory?(@environment[key]) then
+ @cachepath = @environment[key]
+ @cachefile = [@rootpath.gsub(/[^A-Z0-9]/io, '-').gsub(/\-+/,'-'),File.basename(@cachefile)].join('-')
+ break
+ end
+ end
+ end
+ if @cachepath and not @renewcache and FileTest.file?(File.join(@cachepath,@cachefile)) then
+ begin
+ if f = File.open(File.join(@cachepath,@cachefile)) then
+ cacheversion = Marshal.load(f)
+ if cacheversion == @@cacheversion then
+ lsrfiles = Marshal.load(f)
+ if lsrfiles == @lsrfiles then
+ @files = Marshal.load(f)
+ end
+ end
+ f.close
+ end
+ rescue
+ @files = Hash.new
+ end
+ end
+ end
+ return if @files.size > 0
+ @lsrfiles.each do |filedata|
+ filename, filesize = filedata
+ filepath = File.dirname(filename)
+ begin
+ path = '.'
+ data = IO.readlines(filename)
+ if data[0].chomp =~ /% ls\-R \-\- filename database for kpathsea\; do not change this line\./io then
+ data.each do |line|
+ case line
+ when /^[a-zA-Z0-9]/o then
+ line.chomp!
+ if @files[line] then
+ @files[line] << path
+ else
+ @files[line] = [path]
+ end
+ when /^\.\/(.*?)\:$/o then
+ path = File.join(filepath,$1)
+ end
+ end
+ end
+ rescue
+ # sorry
+ end
+ end
+ if @diskcache and @cachepath and f = File.open(File.join(@cachepath,@cachefile),'wb') then
+ f << Marshal.dump(@@cacheversion)
+ f << Marshal.dump(@lsrfiles)
+ f << Marshal.dump(@files)
+ f.close
+ end
+ end
+
+ def expand_variables
+ @expansions = Hash.new
+ if @isolate then
+ @variables['TEXMFCNF'] = @environment['TEXMFCNF'].dup
+ @variables['SELFAUTOPARENT'] = @environment['SELFAUTOPARENT'].dup
+ else
+ @environment.keys.each do |e|
+ if e =~ /^([a-zA-Z]+)\_(.*)\s*$/o then
+ @expansions["#{$1}.#{$2}"] = (@environment[e] ||'').dup
+ else
+ @expansions[e] = (@environment[e] ||'').dup
+ end
+ end
+ end
+ @variables.keys.each do |k|
+ @expansions[k] = @variables[k].dup unless @expansions[k]
+ end
+ loop do
+ busy = false
+ @expansions.keys.each do |k|
+ @expansions[k].gsub!(/\$([a-zA-Z0-9\_\-]*)/o) do
+ busy = true
+ @expansions[$1] || ''
+ end
+ @expansions[k].gsub!(/\$\{([a-zA-Z0-9\_\-]*)\}/o) do
+ busy = true
+ @expansions[$1] || ''
+ end
+ end
+ break unless busy
+ end
+ @expansions.keys.each do |k|
+ @expansions[k] = @expansions[k].gsub("\\", '/')
+ end
+ end
+
+ def variable(name='')
+ (name and not name.empty? and @variables[name.sub('$','')]) or ''
+ end
+
+ def expansion(name='')
+ (name and not name.empty? and @expansions[name.sub('$','')]) or ''
+ end
+
+ def variable?(name='')
+ name and not name.empty? and @variables.key?(name.sub('$',''))
+ end
+
+ def expansion?(name='')
+ name and not name.empty? and @expansions.key?(name.sub('$',''))
+ end
+
+ def simplified_list(str)
+ lst = str.gsub(/^\{/o,'').gsub(/\}$/o,'').split(",")
+ lst.collect do |l|
+ l.sub(/^[\!]*/,'').sub(/[\/\\]*$/o,'')
+ end
+ end
+
+ def original_variable(variable)
+ if variable?("#{@progname}.#{variable}") then
+ variable("#{@progname}.#{variable}")
+ elsif variable?(variable) then
+ variable(variable)
+ else
+ ''
+ end
+ end
+
+ def expanded_variable(variable)
+ if expansion?("#{variable}.#{@progname}") then
+ expansion("#{variable}.#{@progname}")
+ elsif expansion?(variable) then
+ expansion(variable)
+ else
+ ''
+ end
+ end
+
+ def original_path(filename='')
+ _expanded_path_(original_variable(var_of_format_or_suffix(filename)).split(";"))
+ end
+
+ def expanded_path(filename='')
+ _expanded_path_(expanded_variable(var_of_format_or_suffix(filename)).split(";"))
+ end
+
+ def _expanded_path_(pathlist)
+ i, n = 0, 0
+ pathlist.collect! do |mainpath|
+ mainpath.gsub(/([\{\}])/o) do
+ if $1 == "{" then
+ i += 1 ; n = i if i > n ; "<#{i}>"
+ else
+ i -= 1 ; "</#{i+1}>"
+ end
+ end
+ end
+ n.times do |i|
+ loop do
+ more = false
+ newlist = []
+ pathlist.each do |path|
+ unless path.sub!(/^(.*?)<(#{n-i})>(.*?)<\/\2>(.*?)$/) do
+ pre, mid, post = $1, $3, $4
+ mid.gsub!(/\,$/,',.')
+ mid.split(',').each do |m|
+ more = true
+ if m == '.' then
+ newlist << "#{pre}#{post}"
+ else
+ newlist << "#{pre}#{m}#{post}"
+ end
+ end
+ end then
+ newlist << path
+ end
+ end
+ if more then
+ pathlist = [newlist].flatten # copy -)
+ else
+ break
+ end
+ end
+ end
+ pathlist = pathlist.uniq.collect do |path|
+ p = path
+ # p.gsub(/^\/+/o) do '' end
+ # p.gsub!(/(.)\/\/(.)/o) do "#{$1}/#{$2}" end
+ # p.gsub!(/\/\/+$/o) do '//' end
+ p.gsub!(/\/\/+/o) do '//' end
+ p
+ end
+ pathlist
+ end
+
+ # todo: ignore case
+
+ def var_of_format(str)
+ @@formats[str] || ''
+ end
+
+ def var_of_suffix(str) # includes .
+ if @@suffixmap.key?(str) then @@formats[@@suffixmap[str]] else '' end
+ end
+
+ def var_of_format_or_suffix(str)
+ if @@formats.key?(str) then
+ @@formats[str]
+ elsif @@suffixmap.key?(File.extname(str)) then # extname includes .
+ @@formats[@@suffixmap[File.extname(str)]] # extname includes .
+ else
+ ''
+ end
+ end
+
+end
+
+class KpseFast
+
+ # test things
+
+ def list_variables(kpseonly=true)
+ @variables.keys.sort.each do |k|
+ if kpseonly then
+ puts("#{k} = #{@variables[k]}") if @kpsevars[k]
+ else
+ puts("#{if @kpsevars[k] then 'K' else 'E' end} #{k} = #{@variables[k]}")
+ end
+ end
+ end
+
+ def list_expansions(kpseonly=true)
+ @expansions.keys.sort.each do |k|
+ if kpseonly then
+ puts("#{k} = #{@expansions[k]}") if @kpsevars[k]
+ else
+ puts("#{if @kpsevars[k] then 'K' else 'E' end} #{k} = #{@expansions[k]}")
+ end
+ end
+ end
+
+ def list_lsr
+ puts("files = #{@files.size}")
+ end
+
+ def set_test_patterns
+ @variables["KPSE_TEST_PATTERN_A"] = "foo/{1,2}/bar//"
+ @variables["KPSE_TEST_PATTERN_B"] = "!!x{A,B{1,2}}y"
+ @variables["KPSE_TEST_PATTERN_C"] = "x{A,B//{1,2}}y"
+ @variables["KPSE_TEST_PATTERN_D"] = "x{A,B//{1,2,}}//y"
+ end
+
+ def show_test_patterns
+ ['A','B','D'].each do |i|
+ puts ""
+ puts @variables ["KPSE_TEST_PATTERN_#{i}"]
+ puts ""
+ puts expand_path("KPSE_TEST_PATTERN_#{i}").split_path
+ puts ""
+ end
+ end
+
+end
+
+class KpseFast
+
+ # kpse stuff
+
+ def expand_braces(str) # output variable and brace expansion of STRING.
+ _expanded_path_(original_variable(str).split_path).join_path
+ end
+
+ def expand_path(str) # output complete path expansion of STRING.
+ _expanded_path_(expanded_variable(str).split_path).join_path
+ end
+
+ def expand_var(str) # output variable expansion of STRING.
+ expanded_variable(str)
+ end
+
+ def show_path(str) # output search path for file type NAME
+ expanded_path(str).join_path
+ end
+
+ def var_value(str) # output the value of variable $STRING.
+ original_variable(str)
+ end
+
+end
+
+class KpseFast
+
+ def _is_cnf_?(filename)
+ filename == File.basename((@cnffiles.first rescue @@texmfcnf) || @@texmfcnf)
+ end
+
+ def find_file(filename)
+ if _is_cnf_?(filename) then
+ @cnffiles.first rescue ''
+ else
+ [find_files(filename,true)].flatten.first || ''
+ end
+ end
+
+ def find_files(filename,first=false)
+ if _is_cnf_?(filename) then
+ result = @cnffiles.dup
+ else
+ if @remember then
+ # stamp = "#{filename}--#{@format}--#{@engine}--#{@progname}"
+ stamp = "#{filename}--#{@engine}--#{@progname}"
+ return @found[stamp] if @found.key?(stamp)
+ end
+ pathlist = expanded_path(filename)
+ result = []
+ filelist = if @files.key?(filename) then @files[filename].uniq else nil end
+ done = false
+ if pathlist.size == 0 then
+ if FileTest.file?(filename) then
+ done = true
+ result << '.'
+ end
+ else
+ pathlist.each do |path|
+ doscan = if path =~ /^\!\!/o then false else true end
+ recurse = if path =~ /\/\/$/o then true else false end
+ pathname = path.dup
+ pathname.gsub!(/^\!+/o, '')
+ done = false
+ if not done and filelist then
+ # checking for exact match
+ if filelist.include?(pathname) then
+ result << pathname
+ done = true
+ end
+ if not done and recurse then
+ # checking for fuzzy //
+ pathname.gsub!(/\/+$/o, '/.*')
+ # pathname.gsub!(/\/\//o,'/[\/]*/')
+ pathname.gsub!(/\/\//o,'/.*?/')
+ re = /^#{pathname}/
+ filelist.each do |f|
+ if re =~ f then
+ result << f # duplicates will be filtered later
+ done = true
+ end
+ break if done
+ end
+ end
+ end
+ if not done and doscan then
+ # checking for path itself
+ pname = pathname.sub(/\.\*$/,'')
+ if not pname =~ /\*/o and FileTest.file?(File.join(pname,filename)) then
+ result << pname
+ done = true
+ end
+ end
+ break if done and first
+ end
+ end
+ if not done and @scandisk then
+ pathlist.each do |path|
+ pathname = path.dup
+ unless pathname.gsub!(/^\!+/o, '') then # !! prevents scan
+ recurse = pathname.gsub!(/\/+$/o, '')
+ complex = pathname.gsub!(/\/\//o,'/*/')
+ if recurse then
+ if complex then
+ if ok = File.glob_file("#{pathname}/**/#{filename}") then
+ result << File.dirname(ok)
+ done = true
+ end
+ elsif ok = File.locate_file(pathname,filename) then
+ result << File.dirname(ok)
+ done = true
+ end
+ elsif complex then
+ if ok = File.glob_file("#{pathname}/#{filename}") then
+ result << File.dirname(ok)
+ done = true
+ end
+ elsif FileTest.file?(File.join(pathname,filename)) then
+ result << pathname
+ done = true
+ end
+ break if done and first
+ end
+ end
+ end
+ result = result.uniq.collect do |pathname|
+ File.join(pathname,filename)
+ end
+ @found[stamp] = result if @remember
+ end
+ return result # redundant
+ end
+
+end
+
+class KpseFast
+
+ class FileData
+ attr_accessor :tag, :name, :size, :date
+ def initialize(tag=0,name=nil,size=nil,date=nil)
+ @tag, @name, @size, @date = tag, name, size, date
+ end
+ def FileData.sizes(a)
+ a.collect do |aa|
+ aa.size
+ end
+ end
+ def report
+ case @tag
+ when 1 then "deleted | #{@size.to_s.rjust(8)} | #{@date.strftime('%m/%d/%Y %I:%M')} | #{@name}"
+ when 2 then "present | #{@size.to_s.rjust(8)} | #{@date.strftime('%m/%d/%Y %I:%M')} | #{@name}"
+ when 3 then "obsolete | #{' '*8} | #{' '*16} | #{@name}"
+ end
+ end
+ end
+
+ def analyze_files(filter='',strict=false,sort='',delete=false)
+ puts("command line = #{ARGV.join(' ')}")
+ puts("number of files = #{@files.size}")
+ puts("filter pattern = #{filter}")
+ puts("loaded cnf files = #{@cnffiles.join(' ')}")
+ puts('')
+ if filter.gsub!(/^not:/,'') then
+ def the_same(filter,filename)
+ not filter or filter.empty? or /#{filter}/ !~ filename
+ end
+ else
+ def the_same(filter,filename)
+ not filter or filter.empty? or /#{filter}/ =~ filename
+ end
+ end
+ @files.keys.each do |name|
+ if @files[name].size > 1 then
+ data = Array.new
+ @files[name].each do |path|
+ filename = File.join(path,name)
+ # if not filter or filter.empty? or /#{filter}/ =~ filename then
+ if the_same(filter,filename) then
+ if FileTest.file?(filename) then
+ if delete then
+ data << FileData.new(1,filename,File.size(filename),File.mtime(filename))
+ begin
+ File.delete(filename) if delete
+ rescue
+ end
+ else
+ data << FileData.new(2,filename,File.size(filename),File.mtime(filename))
+ end
+ else
+ # data << FileData.new(3,filename)
+ end
+ end
+ end
+ if data.length > 1 then
+ if strict then
+ # if data.collect do |d| d.size end.uniq! then
+ # data.sort! do |a,b| b.size <=> a.size end
+ # data.each do |d| puts d.report end
+ # puts ''
+ # end
+ data.sort! do |a,b|
+ if a.size and b.size then
+ b.size <=> a.size
+ else
+ 0
+ end
+ end
+ bunch = Array.new
+ done = false
+ data.each do |d|
+ if bunch.size == 0 then
+ bunch << d
+ elsif bunch[0].size == d.size then
+ bunch << d
+ else
+ if bunch.size > 1 then
+ bunch.each do |b|
+ puts b.report
+ end
+ done = true
+ end
+ bunch = [d]
+ end
+ end
+ puts '' if done
+ else
+ case sort
+ when 'size' then data.sort! do |a,b| a.size <=> b.size end
+ when 'revsize' then data.sort! do |a,b| b.size <=> a.size end
+ when 'date' then data.sort! do |a,b| a.date <=> b.date end
+ when 'revdate' then data.sort! do |a,b| b.date <=> a.date end
+ end
+ data.each do |d| puts d.report end
+ puts ''
+ end
+ end
+ end
+ end
end
+
end
-if $kpseerror then
- $kpsereport << "unable to locate #{$kpsemodules.join('|')} on library paths:\n\n"
- $kpsereport << " " + $:.join("\n ") + "\n\n"
- $kpsereport << "an option is to point the RUBYLIB variable to\n\n"
- $kpsereport << " <texmf-local or texmf>/scripts/context/ruby\n\n"
- $kpsereport << "or to copy\n\n"
- $kpsereport << " <texmf-local or texmf>/scripts/context/ruby/base/kpse*\n\n"
- $kpsereport << "(including the kpse subpath) to e.g.\n\n"
- $kpsereport << " #{$ownpath}/../lib/texmfstart/\n\n"
- $kpsereport << "or to use a stub instead\n\n"
+
+ # k = KpseFast.new # (root)
+ # k.set_test_patterns
+ # k.load_cnf
+ # k.expand_variables
+ # k.load_lsr
+
+ # k.show_test_patterns
+
+ # puts k.list_variables
+ # puts k.list_expansions
+ # k.list_lsr
+ # puts k.expansion("$TEXMF")
+ # puts k.expanded_path("TEXINPUTS","context")
+
+ # k.progname, k.engine, k.format = 'context', 'pdfetex', 'tfm'
+ # k.scandisk = false # == must_exist
+ # k.expand_variables
+
+ # 10.times do |i| puts k.find_file('texnansi-lmr10.tfm') end
+
+ # puts "expand braces $TEXMF"
+ # puts k.expand_braces("$TEXMF")
+ # puts "expand path $TEXMF"
+ # puts k.expand_path("$TEXMF")
+ # puts "expand var $TEXMF"
+ # puts k.expand_var("$TEXMF")
+ # puts "expand path $TEXMF"
+ # puts k.show_path('tfm')
+ # puts "expand value $TEXINPUTS"
+ # puts k.var_value("$TEXINPUTS")
+ # puts "expand value $TEXINPUTS.context"
+ # puts k.var_value("$TEXINPUTS.context")
+
+ # exit
+
+
+
+# kpse_merge_file: 'C:/data/develop/context/ruby/base/kpse/drb.rb'
+
+require 'drb'
+# kpse_merge_done: require 'base/kpse/trees'
+
+class KpseServer
+
+ attr_accessor :port
+
+ def initialize(port=7000)
+ @port = port
+ end
+
+ def start
+ puts "starting drb service at port #{@port}"
+ DRb.start_service("druby://localhost:#{@port}", KpseTrees.new)
+ trap(:INT) do
+ DRb.stop_service
+ end
+ DRb.thread.join
+ end
+
+ def stop
+ # todo
+ end
+
+end
+
+class KpseClient
+
+ attr_accessor :port
+
+ def initialize(port=7000)
+ @port = port
+ @kpse = nil
+ end
+
+ def start
+ # only needed when callbacks are used / slow, due to Socket::getaddrinfo
+ # DRb.start_service
+ end
+
+ def object
+ @kpse = DRbObject.new(nil,"druby://localhost:#{@port}")
+ end
+
end
+
+# SERVER_URI="druby://localhost:8787"
+#
+# # Start a local DRbServer to handle callbacks.
+# #
+# # Not necessary for this small example, but will be required
+# # as soon as we pass a non-marshallable object as an argument
+# # to a dRuby call.
+# DRb.start_service
+#
+
+
+# kpse_merge_file: 'C:/data/develop/context/ruby/base/kpse/trees.rb'
+
+require 'monitor'
+# kpse_merge_done: require 'base/kpsefast'
+
+class KpseTrees < Monitor
+
+ def initialize
+ @trees = Hash.new
+ end
+
+ def pattern(filenames)
+ filenames.join('|').gsub(/\\+/o,'/').downcase
+ end
+
+ def choose(filenames,environment)
+ current = pattern(filenames)
+ load(filenames,environment) unless @trees[current]
+ puts "enabling tree #{current}"
+ current
+ end
+
+ def fetch(filenames,environment) # will send whole object !
+ current = pattern(filenames)
+ load(filenames,environment) unless @trees[current]
+ puts "fetching tree #{current}"
+ @trees[current]
+ end
+
+ def load(filenames,environment)
+ current = pattern(filenames)
+ puts "loading tree #{current}"
+ @trees[current] = KpseFast.new
+ @trees[current].push_environment(environment)
+ @trees[current].load_cnf(filenames)
+ @trees[current].expand_variables
+ @trees[current].load_lsr
+ end
+
+ def set(tree,key,value)
+ case key
+ when 'progname' then @trees[tree].progname = value
+ when 'engine' then @trees[tree].engine = value
+ when 'format' then @trees[tree].format = value
+ end
+ end
+ def get(tree,key)
+ case key
+ when 'progname' then @trees[tree].progname
+ when 'engine' then @trees[tree].engine
+ when 'format' then @trees[tree].format
+ end
+ end
+
+ def load_cnf(tree)
+ @trees[tree].load_cnf
+ end
+ def load_lsr(tree)
+ @trees[tree].load_lsr
+ end
+ def expand_variables(tree)
+ @trees[tree].expand_variables
+ end
+ def expand_braces(tree,str)
+ @trees[tree].expand_braces(str)
+ end
+ def expand_path(tree,str)
+ @trees[tree].expand_path(str)
+ end
+ def expand_var(tree,str)
+ @trees[tree].expand_var(str)
+ end
+ def show_path(tree,str)
+ @trees[tree].show_path(str)
+ end
+ def var_value(tree,str)
+ @trees[tree].var_value(str)
+ end
+ def find_file(tree,filename)
+ @trees[tree].find_file(filename)
+ end
+ def find_files(tree,filename,first)
+ @trees[tree].find_files(filename,first)
+ end
+
+end
+
+
+# kpse_merge_file: 'C:/data/develop/context/ruby/base/kpsedirect.rb'
+
+class KpseDirect
+
+ attr_accessor :progname, :format, :engine
+
+ def initialize
+ @progname, @format, @engine = '', '', ''
+ end
+
+ def expand_path(str)
+ clean_name(`kpsewhich -expand-path=#{str}`.chomp)
+ end
+
+ def expand_var(str)
+ clean_name(`kpsewhich -expand-var=#{str}`.chomp)
+ end
+
+ def find_file(str)
+ clean_name(`kpsewhich #{_progname_} #{_format_} #{str}`.chomp)
+ end
+
+ def _progname_
+ if @progname.empty? then '' else "-progname=#{@progname}" end
+ end
+ def _format_
+ if @format.empty? then '' else "-format=\"#{@format}\"" end
+ end
+
+ private
+
+ def clean_name(str)
+ str.gsub(/\\/,'/')
+ end
+
+end
+
+
+# kpse_merge_file: 'C:/data/develop/context/ruby/base/merge.rb'
+
+# module : base/merge
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2006
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+
+
+# this module will package all the used modules in the file itself
+# so that we can relocate the file at wish, usage:
+#
+# merge:
+#
+# unless SelfMerge::ok? && SelfMerge::merge then
+# puts("merging should happen on the path were the base inserts reside")
+# end
+#
+# cleanup:
+#
+# unless SelfMerge::cleanup then
+# puts("merging should happen on the path were the base inserts reside")
+
+module SelfMerge
+
+ @@kpsemergestart = "\# kpse_merge_start"
+ @@kpsemergestop = "\# kpse_merge_stop"
+ @@kpsemergefile = "\# kpse_merge_file: "
+ @@kpsemergedone = "\# kpse_merge_done: "
+
+ @@filename = File.basename($0)
+ @@ownpath = File.expand_path(File.dirname($0))
+ @@modroot = '(base|graphics|rslb|www)' # needed in regex in order not to mess up SelfMerge
+ @@modules = $".collect do |file| File.expand_path(file) end
+
+ @@modules.delete_if do |file|
+ file !~ /^#{@@ownpath}\/#{@@modroot}.*$/
+ end
+
+ def SelfMerge::ok?
+ begin
+ @@modules.each do |file|
+ return false unless FileTest.file?(file)
+ end
+ rescue
+ return false
+ else
+ return true
+ end
+ end
+
+ def SelfMerge::merge(filename=@@filename)
+ begin
+ if rbfile = IO.read(filename) then
+ begin
+ inserts = "#{@@kpsemergestart}\n\n"
+ @@modules.each do |file|
+ inserts << "#{@@kpsemergefile}'#{file}'\n\n"
+ inserts << IO.read(file).gsub(/^#.*?\n$/,'')
+ inserts << "\n\n"
+ end
+ inserts << "#{@@kpsemergestop}\n\n"
+ # no gsub! else we end up in SelfMerge
+ rbfile.sub!(/#{@@kpsemergestart}\s*#{@@kpsemergestop}/mois) do
+ inserts
+ end
+ rbfile.gsub!(/^(.*)(require [\"\'].*?#{@@modroot}.*)$/) do
+ pre, post = $1, $2
+ if pre =~ /#{@@kpsemergedone}/ then
+ "#{pre}#{post}"
+ else
+ "#{pre}#{@@kpsemergedone}#{post}"
+ end
+ end
+ rescue
+ return false
+ else
+ begin
+ File.open(filename,'w') do |f|
+ f << rbfile
+ end
+ rescue
+ return false
+ end
+ end
+ end
+ rescue
+ return false
+ else
+ return true
+ end
+ end
+
+ def SelfMerge::cleanup(filename=@@filename)
+ begin
+ if rbfile = IO.read(filename) then
+ begin
+ rbfile.sub!(/#{@@kpsemergestart}(.*)#{@@kpsemergestop}\s*/mois) do
+ "#{@@kpsemergestart}\n\n#{@@kpsemergestop}\n\n"
+ end
+ rbfile.gsub!(/^(.*#{@@kpsemergedone}.*)$/) do
+ str = $1
+ if str =~ /require [\"\']/ then
+ str.gsub(/#{@@kpsemergedone}/, '')
+ else
+ str
+ end
+ end
+ rescue
+ return false
+ else
+ begin
+ File.open(filename,'w') do |f|
+ f << rbfile
+ end
+ rescue
+ return false
+ end
+ end
+ end
+ rescue
+ return false
+ else
+ return true
+ end
+ end
+
+ def SelfMerge::replace(filename=@@filename)
+ SelfMerge::cleanup(filename)
+ SelfMerge::merge(filename)
+ end
+
+end
+
+
+# kpse_merge_stop
+
+
+
$mswindows = Config::CONFIG['host_os'] =~ /mswin/
$separator = File::PATH_SEPARATOR
-$version = "1.8.6"
+$version = "2.0.0"
if $mswindows then
require "win32ole"
@@ -198,11 +1544,7 @@ def check_kpse
puts("kpse : direct") if $verbose
end
rescue
- if $verbose then
- puts("using kpse binary")
- puts("")
- puts($kpsereport) unless $kpsereport.empty?
- end
+ puts("kpse : direct (fallback)") if $verbose
end
end
end
@@ -1034,6 +2376,11 @@ def execute(arguments)
$verbose = true if (ENV['_CTX_VERBOSE_'] =~ /(y|yes|t|true|on)/io) && ! $locate && ! $report
+ # private:
+
+ $selfmerge = $directives['selfmerge'] || false
+ $selfcleanup = $directives['selfcleanup'] || false
+
ENV['_CTX_VERBOSE_'] = 'yes' if $verbose
if $openoffice then
@@ -1054,15 +2401,22 @@ def execute(arguments)
end
end
- if $serve then
+ if $selfmerge then
+ output("ruby libraries are cleaned up") if SelfMerge::cleanup
+ output("ruby libraries are merged") if SelfMerge::merge
+ elsif $selfcleanup then
+ output("ruby libraries are cleaned up") if SelfMerge::cleanup
+ elsif $serve then
if ENV['KPSEMETHOD'] && ENV['KPSEPORT'] then
- # require 'base/kpseremote'
+ # # kpse_merge_done: require 'base/kpseremote'
begin
KpseRemote::start_server
rescue
end
else
usage
+ puts("")
+ puts("message : set 'KPSEMETHOD' and 'KPSEPORT' variables")
end
elsif $help || ! $filename || $filename.empty? then
usage
diff --git a/scripts/context/ruby/tmftools.rb b/scripts/context/ruby/tmftools.rb
index 56935b452..074e949d1 100644
--- a/scripts/context/ruby/tmftools.rb
+++ b/scripts/context/ruby/tmftools.rb
@@ -160,8 +160,8 @@ commandline.registerflag('verbose')
commandline.registeraction('help')
commandline.registeraction('version')
-commandline.registeraction('reload')
-commandline.registeraction('serve')
+commandline.registeraction('reload', 'reload file database')
+commandline.registeraction('serve', 'act as kpse server')
commandline.expand