From 8ad1a9bed2cf3271f1922759060c2ba1c8e3ced1 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Sat, 8 May 2010 13:33:00 +0200 Subject: stable 2010.05.08 13:33 --- tex/context/base/cont-new.tex | 2 +- tex/context/base/context.tex | 2 +- tex/context/base/data-use.lua | 10 +- tex/context/base/metatex.tex | 10 +- tex/context/base/mlib-ctx.lua | 2 +- tex/context/base/page-str.lua | 221 ++++++++++++++++ tex/context/base/page-str.mkiv | 379 +++++++--------------------- tex/generic/context/luatex-fonts-merged.lua | 2 +- 8 files changed, 333 insertions(+), 295 deletions(-) create mode 100644 tex/context/base/page-str.lua (limited to 'tex') diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex index 93f757f67..f15d6f259 100644 --- a/tex/context/base/cont-new.tex +++ b/tex/context/base/cont-new.tex @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2010.05.07 14:21} +\newcontextversion{2010.05.08 13:33} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex index 00eabe64c..79768a78b 100644 --- a/tex/context/base/context.tex +++ b/tex/context/base/context.tex @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2010.05.07 14:21} +\edef\contextversion{2010.05.08 13:33} %D For those who want to use this: diff --git a/tex/context/base/data-use.lua b/tex/context/base/data-use.lua index 123cc0eb8..593b03ad9 100644 --- a/tex/context/base/data-use.lua +++ b/tex/context/base/data-use.lua @@ -109,11 +109,13 @@ function statistics.check_fmt_status(texname) local luv = dofile(luvname) if luv and luv.sourcefile then local sourcehash = md5.hex(io.loaddata(resolvers.find_file(luv.sourcefile)) or "unknown") - if luv.enginebanner and luv.enginebanner ~= enginebanner then - return "engine mismatch" + local luvbanner = luv.enginebanner or "?" + if luvbanner ~= enginebanner then + return string.format("engine mismatch (luv:%s <> bin:%s)",luvbanner,enginebanner) end - if luv.sourcehash and luv.sourcehash ~= sourcehash then - return "source mismatch" + local luvhash = luv.sourcehash or "?" + if luvhash ~= sourcehash then + return string.format("source mismatch (luv:%s <> bin:%s)",luvhash,sourcehash) end else return "invalid status file" diff --git a/tex/context/base/metatex.tex b/tex/context/base/metatex.tex index 84c1268db..e90af709c 100644 --- a/tex/context/base/metatex.tex +++ b/tex/context/base/metatex.tex @@ -59,11 +59,11 @@ % needs stripping: -\loadmarkfile{catc-ini} % catcode table management -\loadcorefile{catc-act} % active character definition mechanisms -\loadcorefile{catc-def} % some generic catcode tables -\loadcorefile{catc-ctx} % a couple of context specific tables but expected by later modules -\loadcorefile{catc-sym} % some definitions related to \letter +\loadmarkfile{catc-ini} % catcode table management +\loadcorefile{catc-act} % active character definition mechanisms +\loadcorefile{catc-def} % some generic catcode tables +\loadcorefile{catc-ctx} % a couple of context specific tables but expected by later modules +\loadcorefile{catc-sym} % some definitions related to \letter % helpers, maybe less diff --git a/tex/context/base/mlib-ctx.lua b/tex/context/base/mlib-ctx.lua index 7d7e936cf..cc5682e6f 100644 --- a/tex/context/base/mlib-ctx.lua +++ b/tex/context/base/mlib-ctx.lua @@ -62,7 +62,7 @@ end function metapost.theclippath(...) local result = metapost.getclippath(...) if result then -- we could just print the table - result = join(metapost.flushnormalpath(object.path),"\n") + result = join(metapost.flushnormalpath(result),"\n") sprint(result) end end diff --git a/tex/context/base/page-str.lua b/tex/context/base/page-str.lua new file mode 100644 index 000000000..c4d1957c3 --- /dev/null +++ b/tex/context/base/page-str.lua @@ -0,0 +1,221 @@ +if not modules then modules = { } end modules ['page-str'] = { + version = 1.001, + comment = "companion to page-str.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- work in progresss .. unfinished + +local concat = table.concat + +local find_tail, write_node, free_node, copy_nodelist = node.slide, node.write, node.free, node.copy_list +local vpack_nodelist, hpack_nodelist = node.vpack, node.hpack +local texdimen, texbox = tex.dimen, tex.box + +local new_kern = nodes.kern +local new_glyph = nodes.glyph + +local trace_collecting = false trackers.register("streams.collecting", function(v) trace_collecting = v end) +local trace_flushing = false trackers.register("streams.flushing", function(v) trace_flushing = v end) + +streams = streams or { } + +local data, name, stack = { }, nil, { } + +function streams.enable(newname) + if newname == "default" then + name = nil + else + name = newname + end +end + +function streams.disable() + name = stack[#stack] +end + +function streams.start(newname) + table.insert(stack,name) + name = newname +end + +function streams.stop(newname) + name = table.remove(stack) +end + +function streams.collect(head,where) + if name and head and name ~= "default" then + local tail = node.slide(head) + local dana = data[name] + if not dana then + dana = { } + data[name] = dana + end + local last = dana[#dana] + if last then + local tail = find_tail(last) + tail.next, head.prev = head, tail + elseif last == false then + dana[#dana] = head + else + dana[1] = head + end + if trace_collecting then + logs.report("streams","appending snippet '%s' to slot %s",name,#dana) + end + return nil, true + else + return head, false + end +end + +function streams.push(thename) + if not thename or thename == "" then + thename = name + end + if thename and thename ~= "" then + local dana = data[thename] + if dana then + dana[#dana+1] = false + if trace_collecting then + logs.report("streams","pushing snippet '%s'",thename) + end + end + end +end + +function streams.flush(name,copy) -- problem: we need to migrate afterwards + local dana = data[name] + if dana then + local dn = #dana + if dn == 0 then + -- nothing to flush + elseif copy then + if trace_flushing then + logs.report("streams","flushing copies of %s slots of '%s'",dn,name) + end + for i=1,dn do + local di = dana[i] + if di then + write_node(copy_nodelist(di.list)) -- list, will be option + end + end + if copy then + data[name] = nil + end + else + if trace_flushing then + logs.report("streams","flushing %s slots of '%s'",dn,name) + end + for i=1,dn do + local di = dana[i] + if di then + write_node(di.list) -- list, will be option + di.list = nil + free_node(di) + end + end + end + end +end + +function streams.synchronize(list) -- this is an experiment ! + -- we don't optimize this as we want to trace in detail + list = aux.settings_to_array(list) + local max = 0 + if trace_flushing then + logs.report("streams","synchronizing list: %s",concat(list," ")) + end + for i=1,#list do + local dana = data[list[i]] + if dana then + local n = #dana + if n > max then + max = n + end + end + end + if trace_flushing then + logs.report("streams","maximum number of slots: %s",max) + end + for m=1,max do + local height, depth = 0, 0 + for i=1,#list do + local name = list[i] + local dana = data[name] + local slot = dana[m] + if slot then + local vbox = vpack_nodelist(slot) + local ht, dp = vbox.height, vbox.depth + if ht > height then + height = ht + end + if dp > depth then + depth = dp + end + dana[m] = vbox + if trace_flushing then + logs.report("streams","slot %s of '%s' is packed to height %s and depth %s",m,name,ht,dp) + end + end + end + if trace_flushing then + logs.report("streams","slot %s has max height %s and max depth %s",m,height,depth) + end + local strutht, strutdp = texdimen.globalbodyfontstrutheight, texdimen.globalbodyfontstrutdepth + local struthtdp = strutht + strutdp + for i=1,#list do + local name = list[i] + local dana = data[name] + local vbox = dana[m] + if vbox then + local delta_height = height - vbox.height + local delta_depth = depth - vbox.depth + if delta_height > 0 or delta_depth > 0 then + if false then + -- actually we need to add glue and repack + vbox.height, vbox.depth = height, depth + if trace_flushing then + logs.report("streams","slot %s of '%s' with delta (%s,%s) is compensated",m,i,delta_height,delta_depth) + end + else + -- this is not yet ok as we also need to keep an eye on vertical spacing + -- so we might need to do some splitting or whatever + local tail = vbox.list and find_tail(vbox.list) + local n, delta = 0, delta_height -- for tracing + while delta > 0 do + -- we need to add some interline penalties + local line = copy_nodelist(tex.box.strutbox) + line.height, line.depth = strutht, strutdp + if tail then + tail.next, line.prev = line, tail + end + tail = line + n, delta = n +1, delta - struthtdp + end + dana[m] = vpack_nodelist(vbox.list) + vbox.list = nil + free_node(vbox) + if trace_flushing then + logs.report("streams","slot %s:%s with delta (%s,%s) is compensated by %s lines",m,i,delta_height,delta_depth,n) + end + end + end + else + -- make dummy + end + end + end +end + +tasks.appendaction("mvlbuilders", "normalizers", "streams.collect") + +tasks.disableaction("mvlbuilders", "streams.collect") + +function streams.initialize() + tasks.enableaction ("mvlbuilders", "streams.collect") +end + +-- todo: remove empty last { }'s diff --git a/tex/context/base/page-str.mkiv b/tex/context/base/page-str.mkiv index 4fd5d58a5..4610c7f71 100644 --- a/tex/context/base/page-str.mkiv +++ b/tex/context/base/page-str.mkiv @@ -1,6 +1,6 @@ %D \module %D [ file=page-str, -%D version=2006.03.21, +%D version=2010.03.13, % 2006.03.21, %D title=\CONTEXT\ Page Macros, %D subtitle=Page Streams, %D author=Hans Hagen, @@ -22,103 +22,76 @@ %D %D These macros were written while listening to and watching the DVD %D \quotation {Rush In Rio}. +%D +%D The reimplementation (or rather experimenting with the complete +%D rewrite) was done while looping over \quotation {Wende Snijders +%D No.9}. +%D +%D Remark: marknotes are gone, at least for a while. -% not yet ok in mkiv ... marknotes .. will be completely redone +\writestatus{loading}{ConTeXt Page Macros / Page Streams} -\endinput +\registerctxluafile{page-str}{1.001} \unprotect -\let\currentoutputstream\s!default - -\newtoks\defaultstreamoutput \defaultstreamoutput=\OTRONEoutput - -\newtoks\normalstreamoutput \normalstreamoutput={\saveoutputstream[\currentoutputstream]} - -\newcount\streampenalty \streampenalty=-101010101 - -\ifx\multicolumnseject\undefined \else - \let\normalmulticolumnseject\multicolumnseject - \def\multicolumnseject{\ifinoutputstream\else\normalmulticolumnseject\fi} -\fi - -\newif\ifinoutputstream - +\let \currentoutputstream \empty +\newif \ifinoutputstream \newtoks \everyenableoutputstream \appendtoks - \flushsidefloats + \flushsidefloats \to \everyenableoutputstream +\def\initializeoutputstreams + {\ctxlua{streams.initialize()}% + \glet\initializeoutputstreams\relax} + \def\enableoutputstream[#1]% - {\the\everyenableoutputstream - \finishoutputstream - \writestatus{otr}{switching to output stream #1}% + {\initializeoutputstreams + \the\everyenableoutputstream \inoutputstreamtrue - \xdef\currentoutputstream{#1}} + \xdef\currentoutputstream{#1}% + \ctxlua{streams.enable("#1")}} \def\disableoutputstream - {\finishoutputstream - \writestatus{otr}{switching to default output stream}% - \inoutputstreamfalse - \global\let\currentoutputstream\s!default} - -\def\useoutputstream[#1]% - {\writestatus{otr}{using output stream #1}% - \xdef\currentoutputstream{#1}} - -\def\handlestreamoutput - {\ifx\currentoutputstream\s!default % already expanded - \ifnum\outputpenalty=\streampenalty - \ifvoid\normalpagebox \else - \unvbox\normalpagebox - \fi - \else - \the\defaultstreamoutput - \fi - \else - \the\normalstreamoutput - \fi} - -\OTRONEoutput{\handlestreamoutput} - -\def\defineoutputstream[#1]% - {\doifundefined{otrs:#1}{\expandafter\newbox\csname otrs:#1\endcsname}} - -\def\outputstreamtag#1% - {\csname otrs:#1\endcsname} - -\def\finishoutputstream % todo: installoutput - {\endgraf - \penalty\streampenalty - \endgraf} - -\def\saveoutputstream[#1]% - {\writestatus{otr}{saving otr stream #1}% - \ifvoid\normalpagebox - \global\setbox\outputstreamtag{#1}\emptybox - \else - \global\setbox\outputstreamtag{#1}\vbox - {\presetoutputstream - \ifvoid\outputstreamtag{#1}\else\unvbox\outputstreamtag{#1}\fi - \scratchdimen\dp\normalpagebox - \unvbox\normalpagebox - \vskip-\scratchdimen - \kern\strutdepth}% - \fi} - -\let\presetoutputstream\relax - -\def\outputstreamht [#1]{\ht\outputstreamtag{#1}} -\def\outputstreamdp [#1]{\dp\outputstreamtag{#1}} -\def\outputstreamwd [#1]{\wd\outputstreamtag{#1}} - -\def\dowithoutputstreambox#1[#2]{\ifvoid\outputstreamtag{#2}\else#1\outputstreamtag{#2}\fi} - -\def\outputstreamcopy {\dowithoutputstreambox\copy } -\def\outputstreambox {\dowithoutputstreambox\box } -\def\outputstreamunvcopy{\dowithoutputstreambox\unvcopy} -\def\outputstreamunvbox {\dowithoutputstreambox\unvbox } + {\inoutputstreamfalse + \global\let\currentoutputstream\s!default + \ctxlua{streams.disable()}} + +\def\startoutputstream[#1]% + {\begingroup + \initializeoutputstreams + \the\everyenableoutputstream + \inoutputstreamtrue + \xdef\currentoutputstream{#1}% + \ctxlua{streams.start("#1")}} + +\def\stopoutputstream + {\ctxlua{streams.stop()}% + \endgroup} + +\def\flushoutputstream [#1]{\ctxlua{streams.flush("#1")}} +\def\outputstreamcopy [#1]{\vbox{\ctxlua{streams.flush("#1",true)}}} +\def\outputstreambox [#1]{\vbox{\ctxlua{streams.flush("#1")}}} +\def\outputstreamunvcopy[#1]{\ctxlua{streams.flush("#1",true)}} +\def\outputstreamunvbox [#1]{\ctxlua{streams.flush("#1")}} +\def\synchronizestreams [#1]{\ctxlua{streams.synchronize("#1")}} +\def\dopushoutputstream [#1]{\ctxlua{streams.push("#1")}} + +\def\pushoutputstream {\dosingleempty\dopushoutputstream} + +% \def\defineoutputstream[#1]% +% {\doifundefined{otrs:#1}{\expandafter\newbox\csname otrs:#1\endcsname}} +% +% \def\useoutputstream[#1]% +% {\writestatus{otr}{using output stream #1}% +% \xdef\currentoutputstream{#1}} +% +% \directsetup{stream:\firstoutputstream:set} +% \directsetup{stream:\firstoutputstream:top} +% \directsetup{stream:\firstoutputstream:bottom} +% \directsetup{stream:\firstoutputstream:reset} %D Obsolete in \MKIV: @@ -128,202 +101,44 @@ \def\flushmarknotes [#1]{} \def\erasemarknotes [#1]{} -%D The next section implements synchronization of (currently -%D two) output streams. In due time we will implement both a -%D vertical and horizontal system, as well as alternative -%D splitters (firstpagevsize, succesivevsize etc). - -\def\synchronizeoutputstreams[#1]% [one,two] [left,right] - {\bgroup - \getfromcommalist[#1][\plusone]\let\firstoutputstream \commalistelement - \getfromcommalist[#1][\plustwo]\let\secondoutputstream\commalistelement - \forgeteverypar - \def\roundingeps{50sp}% - \getboxheight\dimen0\of\box\outputstreamtag\firstoutputstream - \getboxheight\dimen2\of\box\outputstreamtag\secondoutputstream - \scratchdimen\dimexpr\dimen0-\dimen2\relax - \ifdim\scratchdimen<-\roundingeps\relax - \scratchdimen-\scratchdimen - \writestatus{sync}{compensating first stream: \the\scratchdimen/\number\scratchdimen}% - \getroundednoflines\scratchdimen - \global\setbox\outputstreamtag\firstoutputstream\vbox - {\presetoutputstream - \unvbox\outputstreamtag\firstoutputstream\dorecurse\noflines\crlf}% - \else\ifdim\scratchdimen>\roundingeps\relax - \writestatus{sync}{compensating second stream: \the\scratchdimen/\number\scratchdimen}% - \getroundednoflines\scratchdimen - \global\setbox\outputstreamtag\secondoutputstream\vbox - {\presetoutputstream - \unvbox\outputstreamtag\secondoutputstream\dorecurse\noflines\crlf}% - \else - \writestatus{sync}{no need to compensate streams: \the\scratchdimen/\number\scratchdimen}% - \fi\fi - \egroup} - -\def\nofoutputstreamsplitlines {\v!auto} % {40} -\def\outputstreamsplittolerance {-5} - -\def\flushoutputstreampages[#1]% - {\bgroup - \getfromcommalist[#1][\plusone]\let\firstoutputstream \commalistelement - \getfromcommalist[#1][\plustwo]\let\secondoutputstream\commalistelement - \doloop - {\flushoutputstreams[#1]% - \ifvoid\outputstreamtag\firstoutputstream - \ifvoid\outputstreamtag\secondoutputstream - \exitloop - \else - \global\setbox\outputstreamtag\firstoutputstream\vbox{\strut}% - \fi - \else - \ifvoid\outputstreamtag\secondoutputstream - \global\setbox\outputstreamtag\secondoutputstream\vbox{\strut}% - \else - % okay - \fi - \fi}% - \egroup} - -\def\flushoutputstreams[#1]% - {\bgroup - \getfromcommalist[#1][\plusone]\let\firstoutputstream \commalistelement - \getfromcommalist[#1][\plustwo]\let\secondoutputstream\commalistelement - \doif\nofoutputstreamsplitlines\v!auto - {\getrawnoflines\textheight - \edef\nofoutputstreamsplitlines{\the\noflines}}% - \splittopskip\strutheight - \scratchdimen\nofoutputstreamsplitlines\lineheight\relax - \unless\iffalse - \dimen0\scratchdimen - \doloop - {\setbox4\copy\outputstreamtag\firstoutputstream - \setbox0\vsplit4 to \dimen0 - \setbox0\vbox - {\directsetup{stream:\firstoutputstream:top}% - \unvbox0 - \directsetup{stream:\firstoutputstream:bottom}}% - \ifdim\ht0>\scratchdimen - \advance\dimen0-\lineheight - \else - \exitloop - \fi}% - \scratchdimen\dimen0 - \dimen2\scratchdimen - \doloop - {\setbox6\copy\outputstreamtag\secondoutputstream - \setbox2\vsplit6 to \dimen2 - \setbox2\vbox - {\directsetup{stream:\secondoutputstream:top}% - \unvbox0 - \directsetup{stream:\secondoutputstream:bottom}}% - \ifdim\ht2>\scratchdimen - \advance\dimen2-\lineheight - \else - \exitloop - \fi}% - \scratchdimen\dimen2 - \fi - \setbox4\copy\outputstreamtag\firstoutputstream - \setbox6\copy\outputstreamtag\secondoutputstream - \scratchcounter\zerocount - \doloop - {\setbox0\vsplit4 to \scratchdimen - \setbox0\vbox{\unvbox0}% - \setbox2\vsplit6 to \scratchdimen - \setbox2\vbox{\unvbox2}% - \ifvoid4 - \exitloop - \else\ifvoid6 - \exitloop - \else - \dimen8=\dimexpr\ht4-\ht6\relax - \ifdim\dimen8<\zeropoint\dimen8=-\dimen8\relax\fi - \advance\scratchcounter\plusone - \ifdim\dimen8<.5\lineheight - \exitloop - \else\ifnum\outputstreamsplittolerance>\zeropoint - \ifnum\scratchcounter>\outputstreamsplittolerance\relax - \exitloop - \else - \advance\scratchdimen\lineheight - \fi - \else\ifnum\outputstreamsplittolerance<\zeropoint - \ifnum-\scratchcounter<\outputstreamsplittolerance\relax - \exitloop - \else - \advance\scratchdimen-\lineheight - \fi - \else\ifnum\outputstreamsplittolerance=\zeropoint - \exitloop - \fi\fi\fi\fi - \fi\fi}% - \setbox0\vsplit\outputstreamtag\firstoutputstream to \scratchdimen - \setbox0\vbox to \textheight - {\presetoutputstream - \directsetup{stream:\firstoutputstream:top}% - \unvbox0 - \vfill - \directsetup{stream:\firstoutputstream:bottom}}% - \setbox2\vsplit\outputstreamtag\secondoutputstream to \scratchdimen - \setbox2\vbox to \textheight - {\presetoutputstream - \directsetup{stream:\secondoutputstream:top}% - \unvbox2 - \vfill - \directsetup{stream:\secondoutputstream:bottom}}% - \directsetup{stream:\firstoutputstream:reset}% - \directsetup{stream:\secondoutputstream:reset}% - \page[even] - \box0\vfill\page - \box2\vfill\page - \egroup} - - %D Although one can put floats in a stream, it sometimes makes sense - %D to keep them apart and this is what local floats do. - - \def\setuplocalfloats - {\getparameters[\??lf]} - - \setuplocalfloats - [%before=\blank, - %after=\blank, - inbetween=\blank] - - \installfloathandler \v!local \somelocalfloat - - \initializeboxstack{localfloats} - - \newcounter\noflocalfloats - - \def\resetlocalfloats - {\doglobal\newcounter\noflocalfloats - \initializeboxstack{localfloats}} - - \def\somelocalfloat[#1]% - {\doglobal\increment\noflocalfloats - \savebox{localfloats}{\noflocalfloats}{\box\floatbox}} - - \def\getlocalfloats - {\dorecurse\noflocalfloats - {\ifnum\recurselevel=\plusone % 1\relax - \getvalue{\??lf\c!before}% - \else - \getvalue{\??lf\c!inbetween}% - \fi - \dontleavehmode\hbox{\foundbox{localfloats}\recurselevel}% - \ifnum\recurselevel=\noflocalfloats\relax - \getvalue{\??lf\c!after}% - \fi}} - - \def\flushlocalfloats - {\getlocalfloats - \resetlocalfloats} - - \def\getlocalfloat#1{\expanded{\foundbox{localfloats}{\number#1}}} - - \def\forcelocalfloats{\let\forcedfloatmethod\v!local} - -%D Because many arrangements are possible, we will implement -%D some examples in a runtime loadable module \type {m-streams}. - \protect \endinput + +% \enabletrackers[streams.flushing] +% +% \setuplayout[grid=yes] \showgrid +% +% \starttext +% +% \input tufte +% +% \startoutputstream[nl] +% +% Wat doen we hier? +% +% \enableoutputstream[en] +% +% Are you sleeping, brother John?\footnote{xxx} +% +% \dorecurse{4}{x \footnote{note \recurselevel}\input tufte \par \pushoutputstream} +% +% \enableoutputstream[de] +% +% Bruder Jakob, schläfst du noch?\footnote{yyy} +% +% \dorecurse{4}{x \footnote{note \recurselevel}\input ward \par \pushoutputstream} +% +% \disableoutputstream +% +% \stopoutputstream +% +% Vader Jacob, slaap je nog?\footnote{zzz} +% +% \input tufte +% +% \synchronizestreams[en,de,nl] +% +% \page \flushoutputstream[en] \input knuth +% \page \flushoutputstream[de] \input knuth +% \page \flushoutputstream[nl] \input knuth +% +% \stoptext diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index bc8b02906..3e3e7c34c 100644 --- a/tex/generic/context/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 05/07/10 14:21:56 +-- merge date : 05/08/10 13:33:54 do -- begin closure to overcome local limits and interference -- cgit v1.2.3