From 6e23192a09974741e5cd1f11828fb264657835f9 Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Sat, 30 Jul 2005 00:00:00 +0200
Subject: stable 2005.07.30

---
 context/data/scite-ctx.properties    |   4 +-
 scripts/context/perl/texexec.pl      |  10 +-
 scripts/context/ruby/base/tex.rb     |  29 +--
 scripts/context/ruby/base/texutil.rb |  23 ++-
 scripts/context/ruby/ctxtools.rb     |  20 +-
 scripts/context/ruby/fcd_start.rb    | 347 +++++++++++++++++++++++++++++++++++
 scripts/context/ruby/texmfstart.rb   |  40 ++--
 scripts/context/ruby/textools.rb     |  72 ++++++--
 tex/context/base/context.tex         |   2 +-
 tex/context/base/core-rul.tex        |   6 +-
 tex/context/base/core-tab.tex        |   4 +-
 tex/context/base/page-sid.tex        |  15 +-
 tex/context/interface/keys-cz.xml    |   2 +-
 tex/context/interface/keys-de.xml    |   2 +-
 tex/context/interface/keys-en.xml    |   2 +-
 tex/context/interface/keys-it.xml    |   2 +-
 tex/context/interface/keys-nl.xml    |   2 +-
 tex/context/interface/keys-ro.xml    |   2 +-
 18 files changed, 506 insertions(+), 78 deletions(-)
 create mode 100644 scripts/context/ruby/fcd_start.rb

diff --git a/context/data/scite-ctx.properties b/context/data/scite-ctx.properties
index bf5625b98..5eb9ae73d 100644
--- a/context/data/scite-ctx.properties
+++ b/context/data/scite-ctx.properties
@@ -64,7 +64,7 @@ ctx.spellcheck.wordsize.nl=3
 ctx.helpinfo=\
     Shift + F11   pop up menu with ctx options|\
     |\
-    Ctrl  + L     check spelling|\
+    Ctrl  + B     check spelling|\
     Ctrl  + M     wrap text (auto indent)|\
     Ctrl  + R     reset spelling results
 
@@ -94,7 +94,7 @@ command.subsystem.22.*=3
 command.22.*=check_text
 command.groupundo.22.*=yes
 command.save.before.22.*=2
-command.shortcut.22.*=Ctrl+L
+command.shortcut.22.*=Ctrl+B
 
 command.name.23.*=CTX Wrap Text
 command.subsystem.23.*=3
diff --git a/scripts/context/perl/texexec.pl b/scripts/context/perl/texexec.pl
index 6335e6900..d8e26da35 100644
--- a/scripts/context/perl/texexec.pl
+++ b/scripts/context/perl/texexec.pl
@@ -1763,15 +1763,19 @@ sub RunConTeXtFile {
             while (<XML>) {
                 if (/\<[a-z]+/io) {
                     last ;
-                } elsif (/\<\?context\-directive\s+(.+?)\s+(.+?)\s+(.+?)\s*\?\>/o) {
-                    my ($class, $key, $value) = ($1, $2, $3) ;
+                } elsif (/\<\?context\-directive\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*?)\s*\?\>/o) {
+                    my ($class, $key, $value, $rest) = ($1, $2, $3, $4) ;
                     if ($class eq 'job') {
-                        if (($key eq 'stylefile') || ($key eq 'environment')) {
+                        if (($key eq 'mode') || ($key eq 'modes')) {
+                            print TMP "\\enablemode[$value]\n" ;
+                        } elsif (($key eq 'stylefile') || ($key eq 'environment')) {
                             print TMP "\\environment $value\n" ;
                         } elsif ($key eq 'module') {
                             print TMP "\\usemodule[$value]\n" ;
                         } elsif ($key eq 'interface') {
                             $ConTeXtInterface = $value ;
+                        } elsif ($key eq 'control') {
+                            if ($rest == 'purge') { $Purge = 1 }
                         }
                     }
                 }
diff --git a/scripts/context/ruby/base/tex.rb b/scripts/context/ruby/base/tex.rb
index 382b5aa73..e2013b87e 100644
--- a/scripts/context/ruby/base/tex.rb
+++ b/scripts/context/ruby/base/tex.rb
@@ -126,7 +126,7 @@ class TEX
         'mpyforce', 'forcempy',
         'forcetexutil', 'texutil',
         'globalfile', 'autopath',
-        'purge', 'autopdf', 'simplerun', 'verbose',
+        'purge', 'purgeall', 'autopdf', 'simplerun', 'verbose',
     ]
     @@stringvars = [
         'modefile', 'result', 'suffix', 'response', 'path',
@@ -767,15 +767,19 @@ class TEX
                     xml.each do |line|
                         if line =~ /<[a-z]+/io then
                             break
-                        elsif line =~ /<\?context\-directive\s+(.+?)\s+(.+?)\s+(.+?)\s*\?>/o then
-                            category, key, value = $1, $2, $3
+                        elsif line =~ /<\?context\-directive\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*?)\s*\?>/o then
+                            category, key, value, rest = $1, $2, $3, $4
                             case category
                                 when 'job' then
                                     case key
+                                        when 'control' then
+                                            setvariable(value,if rest.empty? then true else rest end)
+                                        when 'mode', 'modes' then
+                                            tmp << "\\enablemode[#{value}]\n"
                                         when 'stylefile', 'environment' then
-                                            tmp << "\\environment $value\n"
+                                            tmp << "\\environment #{value}\n"
                                         when 'module' then
-                                            tmp << "\\usemodule[$value]\n"
+                                            tmp << "\\usemodule[#{value}]\n"
                                         when 'interface' then
                                             contextinterface = value
                                     end
@@ -1260,7 +1264,8 @@ class TEX
                         end
                     end
 
-                    Kpse.runscript('ctxtools',jobname,'--purge') if getvariable('purge')
+                    Kpse.runscript('ctxtools',jobname,'--purge')    if getvariable('purge')
+                    Kpse.runscript('ctxtools',jobname,'--purgeall') if getvariable('purgeall')
 
                 when 'latex' then
 
@@ -1272,13 +1277,15 @@ class TEX
 
             end
 
-            begin
-                File.delete(File.suffixed(jobname,jobsuffix)) if dummyfile || forcexml
-            rescue
-                report("unable to delete stub file")
+            if (dummyfile or forcexml) and FileTest.file?(File.suffixed(jobname,jobsuffix)) then
+                begin
+                    File.delete(File.suffixed(jobname,jobsuffix))
+                rescue
+                    report("unable to delete stub file")
+                end
             end
 
-            if ok && getvariable('autopdf') then
+            if ok and getvariable('autopdf') then
                 PDFview.open(File.suffixed(if result.empty? then jobname else result end,'pdf'))
             end
 
diff --git a/scripts/context/ruby/base/texutil.rb b/scripts/context/ruby/base/texutil.rb
index 8a40627d3..083e11bdb 100644
--- a/scripts/context/ruby/base/texutil.rb
+++ b/scripts/context/ruby/base/texutil.rb
@@ -738,17 +738,20 @@ class TeXUtil
         def loaded(filename)
             begin
                 report("parsing file #{filename}")
-                File.open(File.suffixed(filename,'tui')).each do |line|
-                    case line.chomp
-                        when /^f (.*)$/o then @plugins.reader('MyFiles',    $1.splitdata)
-                        when /^c (.*)$/o then @plugins.reader('MyCommands', [$1])
-                        when /^e (.*)$/o then @plugins.reader('MyExtras',   $1.splitdata)
-                        when /^s (.*)$/o then @plugins.reader('MySynonyms', $1.splitdata)
-                        when /^r (.*)$/o then @plugins.reader('MyRegisters',$1.splitdata)
-                        when /^p (.*)$/o then @plugins.reader('MyPlugins',  $1.splitdata)
-                        when /^x (.*)$/o then @plugins.reader('MyKeys',     $1.splitdata)
-                        else report("unknown entry #{line[0,1]} in line #{line.chomp}")
+                if f = open(File.suffixed(filename,'tui')) then
+                    f.each do |line|
+                        case line.chomp
+                            when /^f (.*)$/o then @plugins.reader('MyFiles',    $1.splitdata)
+                            when /^c (.*)$/o then @plugins.reader('MyCommands', [$1])
+                            when /^e (.*)$/o then @plugins.reader('MyExtras',   $1.splitdata)
+                            when /^s (.*)$/o then @plugins.reader('MySynonyms', $1.splitdata)
+                            when /^r (.*)$/o then @plugins.reader('MyRegisters',$1.splitdata)
+                            when /^p (.*)$/o then @plugins.reader('MyPlugins',  $1.splitdata)
+                            when /^x (.*)$/o then @plugins.reader('MyKeys',     $1.splitdata)
+                            else report("unknown entry #{line[0,1]} in line #{line.chomp}")
+                        end
                     end
+                    f.close
                 end
             rescue
                 report("fatal error in parsing #{filename}")
diff --git a/scripts/context/ruby/ctxtools.rb b/scripts/context/ruby/ctxtools.rb
index 10cff23cf..44bf85b5b 100644
--- a/scripts/context/ruby/ctxtools.rb
+++ b/scripts/context/ruby/ctxtools.rb
@@ -377,7 +377,7 @@ class Commands
 
     def purgefiles(all=false)
 
-        pattern = @commandline.arguments
+        pattern  = @commandline.arguments
         purgeall = @commandline.option("all") || all
 
         $dontaskprefixes.push(Dir.glob("mpx-*"))
@@ -407,10 +407,7 @@ class Commands
         files.sort!
 
         $dontaskprefixes.each do |file|
-            removecontextfile(file) if FileTest.file?(file)
-        end
-        $dontasksuffixes.each do |file|
-            removecontextfile(file) if FileTest.file?(file)
+            removecontextfile(file)
         end
         $dontasksuffixes.each do |suffix|
             files.each do |file|
@@ -447,6 +444,13 @@ class Commands
             end
         end
 
+        files = Dir.glob("*.*")
+        $dontasksuffixes.each do |suffix|
+            files.each do |file|
+                removecontextfile(file) if file =~ /^#{suffix}$/i
+            end
+        end
+
         if $removedfiles || $keptfiles || $persistentfiles then
             report("removed files : #{$removedfiles}")
             report("kept files : #{$keptfiles}")
@@ -474,9 +478,9 @@ class Commands
         "cont-opt.tex", "cont-opt.bak"
     ]
     $dontasksuffixes = [
-        "mpgraph.mp", "mpgraph.mpd", "mpgraph.mpo", "mpgraph.mpy",
-        "mprun.mp", "mprun.mpd", "mprun.mpo", "mprun.mpy",
-        "xlscript.xsl"
+        "mp(graph|run)\\.mp", "mp(graph|run)\\.mpd", "mp(graph|run)\\.mpo", "mp(graph|run)\\.mpy",
+        "mp(graph|run)\\.\\d+",
+        "xlscript\\.xsl"
     ]
     $forsuresuffixes = [
         "tui", "tup", "ted", "tes", "top",
diff --git a/scripts/context/ruby/fcd_start.rb b/scripts/context/ruby/fcd_start.rb
new file mode 100644
index 000000000..29e040027
--- /dev/null
+++ b/scripts/context/ruby/fcd_start.rb
@@ -0,0 +1,347 @@
+# Hans Hagen / PRAGMA ADE / 2005 / www.pragma-ade.com
+#
+# Fast Change Dir
+#
+# This is a kind of variant of the good old ncd
+# program. This script uses the same indirect cmd
+# trick as Erwin Waterlander's wcd program.
+#
+# === windows: fcd.cmd ===
+#
+# @echo off
+# ruby -S fcd_start.rb %1 %2 %3 %4 %5 %6 %7 %8 %9
+# if exist "%HOME%/fcd_stage.cmd" call %HOME%/fcd_stage.cmd
+#
+# === linux: fcd (fcd.sh) ===
+#
+# !/usr/bin/env sh
+# ruby -S fcd_start.rb $1 $2 $3 $4 $5 $6 $7 $8 $9
+# if test -f "$HOME/fcd_stage.sh" ; then
+#   . $HOME/fcd_stage.sh ;
+# fi;
+#
+# ===
+#
+# On linux, one should source the file: ". fcd args" in order
+# to make the chdir persistent.
+#
+# You can create a stub with:
+#
+# ruby fcd_start.rb --stub --verbose
+
+require 'rbconfig'
+
+class FastCD
+
+    @@rootpath = nil
+
+    ['HOME','TEMP','TMP','TMPDIR'].each do |key|
+        if ENV[key] then
+            if FileTest.directory?(ENV[key]) then
+                @@rootpath = ENV[key]
+                break
+            end
+        end
+    end
+
+    exit unless @@rootpath
+
+    @@mswindows = Config::CONFIG['host_os'] =~ /mswin/
+    @@maxlength = 26
+
+    require 'Win32API' if @@mswindows
+
+    if @@mswindows then
+        @@stubcode = [
+            '@echo off',
+            '',
+            'if not exist "%HOME%" goto temp',
+            '',
+            ':home',
+            '',
+            'ruby -S fcd_start.rb %1 %2 %3 %4 %5 %6 %7 %8 %9',
+            '',
+            'if exist "%HOME%\fcd_stage.cmd" call %HOME%\fcd_stage.cmd',
+            'goto end',
+            '',
+            ':temp',
+            '',
+            'ruby -S fcd_start.rb %1 %2 %3 %4 %5 %6 %7 %8 %9',
+            '',
+            'if exist "%TEMP%\fcd_stage.cmd" call %TEMP%\fcd_stage.cmd',
+            'goto end',
+            '',
+            ':end'
+        ].join("\n")
+    else
+        @@stubcode = [
+            '#!/usr/bin/env sh',
+            '',
+            'ruby -S fcd_start.rb $1 $2 $3 $4 $5 $6 $7 $8 $9',
+            '',
+            'if test -f "$HOME/fcd_stage.sh" ; then',
+            '  . $HOME/fcd_stage.sh ;',
+            'fi;'
+        ].join("\n")
+    end
+
+    @@selfpath = File.dirname($0)
+    @@datafile = File.join(@@rootpath,'fcd_state.dat')
+    @@cdirfile = File.join(@@rootpath,if @@mswindows then 'fcd_stage.cmd' else 'fcd_stage.sh' end)
+    @@stubfile = File.join(@@selfpath,if @@mswindows then 'fcd.cmd'       else 'fcd'          end)
+
+    def initialize(verbose=false)
+        @list = Array.new
+        @result = Array.new
+        @pattern = ''
+        @verbose = verbose
+        if f = File.open(@@cdirfile,'w') then
+            f << "#{if @@mswindows then 'rem' else '#' end} no dir to change to"
+            f.close
+        else
+            report("unable to create stub #{@@cdirfile}")
+        end
+    end
+
+    def filename(name)
+        File.join(@@root,name)
+    end
+
+    def report(str,verbose=@verbose)
+        puts(">> #{str}") if verbose
+    end
+
+    def flush(str,verbose=@verbose)
+        print(str) if verbose
+    end
+
+    def scan(dir='.')
+        begin
+            [dir].flatten.sort.uniq.each do |dir|
+                begin
+                    Dir.chdir(dir)
+                    report("scanning '#{dir}'")
+                    # flush(">> ")
+                    Dir.glob("**/*").each do |d|
+                        if FileTest.directory?(d) then
+                            @list << File.expand_path(d)
+                            # flush(".")
+                        end
+                    end
+                    # flush("\n")
+                    @list = @list.sort.uniq
+                    report("#{@list.size} entries found")
+                rescue
+                    report("unknown directory '#{dir}'")
+                end
+            end
+        rescue
+            report("invalid dir specification   ")
+        end
+    end
+
+    def save
+        begin
+            if f = File.open(@@datafile,'w') then
+                @list.each do |l|
+                    f.puts(l)
+                end
+                f.close
+            end
+            report("#{@list.size} status bytes saved in #{@@datafile}")
+        rescue
+            report("error in saving status in #{@@datafile}")
+        end
+    end
+
+    def load
+        begin
+            @list = IO.read(@@datafile).split("\n")
+            report("#{@list.length} status bytes loaded from #{@@datafile}")
+        rescue
+            report("error in loading status from #{@@datafile}")
+        end
+    end
+
+    def show
+        begin
+            @list.each do |l|
+                puts(l)
+            end
+        rescue
+        end
+    end
+
+    def find(pattern=nil)
+        begin
+            if pattern = [pattern].flatten.first then
+                if  pattern.length > 0 and @pattern = pattern then
+                    @result = @list.grep(/\/#{@pattern}$/i)
+                    if @result.length == 0 then
+                        @result = @list.grep(/\/#{@pattern}[^\/]*$/i)
+                    end
+                end
+            end
+        rescue
+        end
+    end
+
+    def chdir(dir)
+        begin
+            if dir then
+                if f = File.open(@@cdirfile,'w') then
+                    if @@mswindows then
+                        f.puts("cd /d #{dir.gsub('/','\\')}")
+                    else
+                        f.puts("cd #{dir.gsub("\\",'/')}")
+                    end
+                end
+                report("changing to #{dir}",true)
+            else
+                report("not changing dir")
+            end
+        rescue
+        end
+    end
+
+    def choose
+        unless @pattern.empty? then
+            begin
+                case @result.size
+                    when 0 then
+                        report("dir '#{@pattern}' not found",true)
+                    when 1 then
+                        chdir(@result[0])
+                    else
+                        list = @result.dup
+                        loop do
+                            print("\n")
+                            list.each_index do |i|
+                                if i < @@maxlength then
+                                    puts("#{(i+?a).chr}  #{list[i]}")
+                                else
+                                    puts("\n   there are #{list.length-@@maxlength} entries more")
+                                    break
+                                end
+                            end
+                            print("\n>> ")
+                            if answer = wait then
+                                if answer >= ?a and answer <= ?z then
+                                    index = answer - ?a
+                                    dir = list[index]
+                                    if dir then
+                                        print("#{answer.chr} ")
+                                        chdir(dir)
+                                    else
+                                        print("quit\n")
+                                    end
+                                    break
+                                elsif list.length >= @@maxlength then
+                                    @@maxlength.times do |i| list.shift end
+                                    print("next set")
+                                    print("\n")
+                                else
+                                    print("quit\n")
+                                    break
+                                end
+                            end
+                        end
+                    end
+            rescue
+            end
+        end
+    end
+
+    def wait
+        begin
+            $stdout.flush
+            return getc
+        rescue
+            return nil
+        end
+    end
+
+    def getc
+        begin
+            if @@mswindows then
+                ch = Win32API.new('crtdll','_getch',[],'L').call
+            else
+                system('stty raw -echo')
+                ch = $stdin.getc
+                system('stty -raw echo')
+            end
+        rescue
+            ch = nil
+        end
+        return ch
+    end
+
+    def check
+        unless FileTest.file?(@@stubfile) then
+            report("creating stub #{@@stubfile}")
+            begin
+                if f = File.open(@@stubfile,'w') then
+                    f.puts(@@stubcode)
+                    f.close
+                end
+            rescue
+                report("unable to create stub #{@@stubfile}")
+            else
+                unless @mswindows then
+                    begin
+                        File.chmod(0755,@@stubfile)
+                    rescue
+                        report("unable to change protections on #{@@stubfile}")
+                    end
+                end
+            end
+        else
+            report("stub #{@@stubfile} already present")
+        end
+    end
+
+end
+
+verbose, action, args = false, 30, Array.new
+
+usage = "fcd [--make|add|show|find] [--verbose] [pattern]"
+
+ARGV.each do |a|
+    case a
+        when '-v', '--verbose' then verbose = true
+        when '-m', '--make'    then action = 10
+        when '-a', '--add'     then action = 11
+        when '-s', '--show'    then action = 20
+        when '-l', '--list'    then action = 20
+        when '-f', '--find'    then action = 30
+        when       '--stub'    then action = 40
+        when '-h', '--help'    then puts "usage: #{usage}" ; exit
+        when /^\-\-.*/         then puts "unknown switch: #{a}" + "\n" + "usage: #{usage}" ; exit
+                               else args << a
+    end
+end
+
+$stdout.sync = true
+
+fcd = FastCD.new(verbose)
+
+fcd.report("Fast Change Dir / version 1.0")
+
+case action
+    when 10 then
+        fcd.scan(args)
+        fcd.save
+    when 11 then
+        fcd.load
+        fcd.scan(args)
+        fcd.save
+    when 20 then
+        fcd.load
+        fcd.show
+    when 30 then
+        fcd.load
+        fcd.find(args)
+        fcd.choose
+    when 40
+        fcd.check
+end
diff --git a/scripts/context/ruby/texmfstart.rb b/scripts/context/ruby/texmfstart.rb
index 083e7532b..aa1f70788 100644
--- a/scripts/context/ruby/texmfstart.rb
+++ b/scripts/context/ruby/texmfstart.rb
@@ -64,9 +64,13 @@ $suffixinputs['pdf'] = 'PDFINPUTS'
 $predefined['texexec']  = 'texexec.pl'
 $predefined['texutil']  = 'texutil.pl'
 $predefined['texfont']  = 'texfont.pl'
+
 $predefined['mptopdf']  = 'mptopdf.pl'
+$predefined['pstopdf']  = 'pstopdf.rb'
+
 $predefined['examplex'] = 'examplex.rb'
 $predefined['concheck'] = 'concheck.rb'
+
 $predefined['textools'] = 'textools.rb'
 $predefined['ctxtools'] = 'ctxtools.rb'
 $predefined['rlxtools'] = 'rlxtools.rb'
@@ -74,7 +78,7 @@ $predefined['pdftools'] = 'pdftools.rb'
 $predefined['mpstools'] = 'mpstools.rb'
 $predefined['exatools'] = 'exatools.rb'
 $predefined['xmltools'] = 'xmltools.rb'
-$predefined['pstopdf']  = 'pstopdf.rb'
+
 
 if ENV['TEXMFSTART_MODE'] = 'experimental' then
     $predefined['texexec'] = 'newtexexec.rb'
@@ -143,21 +147,21 @@ if $mswindows then
         end
     end
 
-    def shortpathname (filename)
-        dowith_pathname(filename,GetShortPathName)
-    end
-
     def longpathname (filename)
         dowith_pathname(filename,GetLongPathName)
     end
 
+    def shortpathname (filename)
+        dowith_pathname(filename,GetShortPathName)
+    end
+
 else
 
-    def shortpathname (filename)
+    def longpathname (filename)
         filename
     end
 
-    def longpathname (filename)
+    def shortpathname (filename)
         filename
     end
 
@@ -177,6 +181,14 @@ class File
         end
     end
 
+    def File.timestamp(name)
+        begin
+            "#{File.stat(name).mtime}"
+        rescue
+            return 'unknown'
+        end
+    end
+
     def File.syncmtimes(oldname,newname)
         begin
             if $mswindows then
@@ -189,14 +201,6 @@ class File
         end
     end
 
-    def File.timestamp(name)
-        begin
-            "#{File.stat(name).mtime}"
-        rescue
-            return 'unknown'
-        end
-    end
-
 end
 
 def hashed (arr=[])
@@ -376,9 +380,9 @@ def usage
     print("\n")
     print("usage    : texmfstart [switches] filename [optional arguments]\n")
     print("\n")
-    print("switches : --verbose --report --browser --direct --execute --locate\n")
-    print("           --program --file   --page    --arguments\n")
-    print("           --make    --lmake  --wmake\n")
+    print("switches : --verbose --report --browser --direct --execute --locate --iftouched\n")
+    print("           --program --file --page --arguments --batch --edit --report --clear\n")
+    print("           --make --lmake --wmake --path --stubpath --indirect --before --after\n")
     print("\n")
     print("example  : texmfstart pstopdf.rb cow.eps\n")
     print("           texmfstart --locate examplex.rb\n")
diff --git a/scripts/context/ruby/textools.rb b/scripts/context/ruby/textools.rb
index a0a98e8c2..c524ffa41 100644
--- a/scripts/context/ruby/textools.rb
+++ b/scripts/context/ruby/textools.rb
@@ -356,7 +356,7 @@ class Commands
 
     end
 
-    def replace
+    def replacefile
 
         report('replace file')
 
@@ -723,12 +723,14 @@ class Commands
 
     public
 
-    def mergeupdate
+    def updatetree
 
-        nocheck = @commandline.option('nocheck')
-        force   = @commandline.option('force')
-        root    = @commandline.argument('first')
-        path    = @commandline.argument('second')
+        nocheck  = @commandline.option('nocheck')
+        merge    = @commandline.option('merge')
+        prune    = @commandline.option('prune')
+        force    = @commandline.option('force')
+        root     = @commandline.argument('first')
+        path     = @commandline.argument('second')
 
         if FileTest.directory?(root) then
             report("scanning #{root}")
@@ -775,17 +777,37 @@ class Commands
             end
         end
 
+        donehash = Hash.new
+        copied   = Array.new
+
         pathhash.keys.each do |f|
-            if pathhash[f] && roothash[f] then
-                p = File.expand_path(File.join(pathhash[f],f))
+            if pathhash[f] and roothash[f] then
+                p = File.expand_path(File.join(pathhash[f],f)) # destination
                 r = File.expand_path(File.join(roothash[f],f))
                 if p != r then
-                    if nocheck or File.mtime(p) < File.mtime(r) then
-                        report("copying '#{r}' to '#{p}'")
+                    if not FileTest.file?(p) then
+                        if merge then
+                            report("merging '#{r}' to '#{p}'")
+                            begin
+                                File.copy(r,p) if force
+                                copied << p
+                            rescue
+                                report("merging failed")
+                            else
+                                donehash[File.dirname(r)] = File.dirname(p)
+                            end
+                        else
+                            report("skipping '#{r}' to '#{p}'")
+                        end
+                    elsif nocheck or File.mtime(p) < File.mtime(r) then
+                        report("updating '#{r}' to '#{p}'")
                         begin
                             File.copy(r,p) if force
+                            copied << p
                         rescue
-                            report("copying failed")
+                            report("updating failed")
+                        else
+                            donehash[File.dirname(r)] = File.dirname(p)
                         end
                     else
                         report("skipping '#{r}' to '#{p}'")
@@ -794,6 +816,29 @@ class Commands
             end
         end
 
+        report("")
+        donehash.keys.sort.each do |d|
+            rootfiles = Dir.glob("#{d}/**/*")
+            pathfiles = Dir.glob("#{donehash[d]}/**/*")
+            pathfiles.collect! do |file| File.expand_path(file) end
+            rootfiles.collect! do |file| File.expand_path(file) end
+            difference = pathfiles - rootfiles - copied
+            if difference.length > 0 then
+                length = 0
+                difference.each do |file|
+                    if l = File.basename(file).length and l > length then length = l end
+                end
+                report("")
+                difference.sort.each do |file|
+                    if prune then
+                        report("deleting '#{file.ljust(length)}'")
+                    else
+                        report("keeping '#{file.ljust(length)}'")
+                    end
+                end
+            end
+        end
+
     end
 
 end
@@ -810,8 +855,8 @@ commandline.registeraction('unzipfiles'       , '[pattern]   [--recurse]')
 commandline.registeraction('fixafmfiles'      , '[pattern]   [--recurse]')
 commandline.registeraction('mactodos'         , '[pattern]   [--recurse]')
 commandline.registeraction('fixtexmftrees'    , '[texmfroot] [--force]')
-commandline.registeraction('replace'          , 'filename    [--force]')
-commandline.registeraction('mergeupdate'      , 'fromroot toroot [--force --nocheck]')
+commandline.registeraction('replacefile'      , 'filename    [--force]')
+commandline.registeraction('updatetree'       , 'fromroot toroot [--force --nocheck --merge --prune]')
 commandline.registeraction('downcasefilenames', '[--recurse] [--force]') # not yet documented
 commandline.registeraction('stripformfeeds'   , '[--recurse] [--force]') # not yet documented
 commandline.registeraction('showfont'         , 'filename')
@@ -821,6 +866,7 @@ commandline.registeraction('version')
 
 commandline.registerflag('recurse')
 commandline.registerflag('force')
+commandline.registerflag('prune')
 commandline.registerflag('nocheck')
 
 commandline.expand
diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex
index 355bc7e47..171305424 100644
--- a/tex/context/base/context.tex
+++ b/tex/context/base/context.tex
@@ -31,7 +31,7 @@
 %D 2004.8.30 the low level interface is english. Watch out and adapt
 %D your styles an modules.
 
-\def\contextversion{2005.07.27}
+\def\contextversion{2005.07.30}
 
 %D Welcome to the main module. When this module is ran through
 %D \type{initex} or \type {tex -i} or \type {whatevertex} using
diff --git a/tex/context/base/core-rul.tex b/tex/context/base/core-rul.tex
index 8ef18ab20..7116d05c4 100644
--- a/tex/context/base/core-rul.tex
+++ b/tex/context/base/core-rul.tex
@@ -791,7 +791,7 @@
      \else
        \boxhaswidthfalse
      \fi
-   \else\ifx\localwidth\v!fixed % equals \v!broad
+   \else\ifx\localwidth\v!fixed % equals \v!fix but no shapebox
      \ifboxhasformat
        \boxhaswidthtrue
        \!!widtha\hsize
@@ -1744,7 +1744,7 @@
 \newdimen\framedlastlength
 
 \def\resetshapeframebox
-  {\framednoflines\zerocount
+  {\framednoflines  \zerocount
    \framedlastlength\zeropoint}
 
 % The next implementation is frozen! It preserves the depth,
@@ -3300,7 +3300,7 @@
    \hskip\getvalue{\??fc#1\c!rightoffset}%
    \egroup
    \doifvalue{\??fc#1\c!width}\v!fit
-     {\letvalue{\??fc#1\c!width}\v!fixed}%
+     {\letvalue{\??fc#1\c!width}\v!fixed}% no shapebox
    \ifinsidefloat
      \donefalse
    \else
diff --git a/tex/context/base/core-tab.tex b/tex/context/base/core-tab.tex
index f2c836461..73850e5af 100644
--- a/tex/context/base/core-tab.tex
+++ b/tex/context/base/core-tab.tex
@@ -2484,8 +2484,8 @@
   {\getparameters[\??ti][#1]%
    \processaction
      [\@@tialign]
-     [ \v!right=>\def\TABLEparalignment{\raggedright},
-        \v!left=>\def\TABLEparalignment{\raggedleft},
+     [  \v!right=>\def\TABLEparalignment{\raggedright},
+         \v!left=>\def\TABLEparalignment{\raggedleft},
        \v!middle=>\def\TABLEparalignment{\raggedcenter},
       \s!default=>\def\TABLEparalignment{\notragged},
       \s!unknown=>\def\TABLEparalignment{\notragged}]%
diff --git a/tex/context/base/page-sid.tex b/tex/context/base/page-sid.tex
index 0ad5c787e..882464fc3 100644
--- a/tex/context/base/page-sid.tex
+++ b/tex/context/base/page-sid.tex
@@ -309,6 +309,19 @@
       \brokenpenalty\the\brokenpenalty
       \let\poppenalties\relax}}
 
+% shouldn;t that be:
+%
+% \def\pushpenalties % needed?
+%   {\let\pushpenalties\relax
+%    \edef\poppenalties
+%      {\widowpenalty \the\widowpenalty
+%       \clubpenalty  \the\clubpenalty
+%       \brokenpenalty\the\brokenpenalty
+%       \let\poppenalties\relax}%
+%    \widowpenalty\plusone
+%    \clubpenalty\plustwo
+%    \brokenpenalty\plusone}
+
 \let\poppenalties=\relax
 
 \def\restorepenalties
@@ -767,7 +780,7 @@
        \else
          \scratchcounter\sidefloatlinesdone
          \advance\scratchcounter-\!!counta
-         \global\sidefloatsidelines-\scratchcounter
+         \global\advance\sidefloatsidelines-\scratchcounter
        \fi
      \fi
      \ifnum\sidefloatsidelines>\zerocount
diff --git a/tex/context/interface/keys-cz.xml b/tex/context/interface/keys-cz.xml
index c5a57b820..f94c1a0f7 100644
--- a/tex/context/interface/keys-cz.xml
+++ b/tex/context/interface/keys-cz.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="cz" version="2005.07.27">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="cz" version="2005.07.30">
 
   <cd:variables>
     <cd:variable name="one" value="jedna"/>
diff --git a/tex/context/interface/keys-de.xml b/tex/context/interface/keys-de.xml
index ad86466dc..7c1bd3b63 100644
--- a/tex/context/interface/keys-de.xml
+++ b/tex/context/interface/keys-de.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="de" version="2005.07.27">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="de" version="2005.07.30">
 
   <cd:variables>
     <cd:variable name="one" value="eins"/>
diff --git a/tex/context/interface/keys-en.xml b/tex/context/interface/keys-en.xml
index 5f8a2554d..b58087107 100644
--- a/tex/context/interface/keys-en.xml
+++ b/tex/context/interface/keys-en.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="en" version="2005.07.27">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="en" version="2005.07.30">
 
   <cd:variables>
     <cd:variable name="one" value="one"/>
diff --git a/tex/context/interface/keys-it.xml b/tex/context/interface/keys-it.xml
index 3998abce9..79b82bba1 100644
--- a/tex/context/interface/keys-it.xml
+++ b/tex/context/interface/keys-it.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="it" version="2005.07.27">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="it" version="2005.07.30">
 
   <cd:variables>
     <cd:variable name="one" value="uno"/>
diff --git a/tex/context/interface/keys-nl.xml b/tex/context/interface/keys-nl.xml
index 8132906fe..32f053d32 100644
--- a/tex/context/interface/keys-nl.xml
+++ b/tex/context/interface/keys-nl.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="nl" version="2005.07.27">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="nl" version="2005.07.30">
 
   <cd:variables>
     <cd:variable name="one" value="een"/>
diff --git a/tex/context/interface/keys-ro.xml b/tex/context/interface/keys-ro.xml
index f8f2a5ca4..7258a1b9a 100644
--- a/tex/context/interface/keys-ro.xml
+++ b/tex/context/interface/keys-ro.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="ro" version="2005.07.27">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="ro" version="2005.07.30">
 
   <cd:variables>
     <cd:variable name="one" value="unu"/>
-- 
cgit v1.2.3