diff options
Diffstat (limited to 'tex')
54 files changed, 1286 insertions, 371 deletions
diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index 6bb07be54..b2df7931a 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2013.03.29 01:03} +\newcontextversion{2013.03.29 01:31} %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/cont-new.mkiv b/tex/context/base/cont-new.mkiv index a877420d9..ec48d6bae 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2013.04.02 11:22} +\newcontextversion{2013.04.05 22:00} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf Binary files differindex a654316df..bccf8fc16 100644 --- a/tex/context/base/context-version.pdf +++ b/tex/context/base/context-version.pdf diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png Binary files differindex c1c1e1e98..0a8bac0da 100644 --- a/tex/context/base/context-version.png +++ b/tex/context/base/context-version.png diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index 7ac0a0c82..1309ce1cb 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -1,4 +1,4 @@ -%D \module + %D \module %D [ file=context, %D version=2008.28.10, % 1995.10.10, %D title=\CONTEXT, @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2013.03.29 01:03} +\edef\contextversion{2013.03.29 01:31} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index e20dad34b..e4442fdcd 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -25,7 +25,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2013.04.02 11:22} +\edef\contextversion{2013.04.05 22:00} \edef\contextkind {beta} %D For those who want to use this: @@ -314,6 +314,7 @@ \loadmarkfile{page-imp} \loadmkvifile{page-sel} % optional +\loadmkvifile{page-inj} % optional \loadmkvifile{scrn-pag} \loadmkvifile{scrn-wid} diff --git a/tex/context/base/core-con.lua b/tex/context/base/core-con.lua index 06102188c..cb284b9a7 100644 --- a/tex/context/base/core-con.lua +++ b/tex/context/base/core-con.lua @@ -177,20 +177,17 @@ converters.maxchrs = maxchrs local lowercharacter = characters.lcchars local uppercharacter = characters.ucchars -local function do_alphabetic(n,mapping,mapper,t) +local function do_alphabetic(n,mapping,mapper,t) -- todo: make zero based variant (initial n + 1) if not t then t = { } end - local chr = mapping[n] or fallback - if mapper then - chr = mapper[chr] - end local max = #mapping if n > max then do_alphabetic(floor((n-1)/max),mapping,mapper,t) n = (n-1) % max + 1 end - t[#t+1] = chr + local chr = mapping[n] or fallback + t[#t+1] = mapper and mapper[chr] or chr if n <= max then return concat(t) end @@ -635,22 +632,22 @@ end -- print(gregorian_to_jalali(2009,02,24)) -- print(jalali_to_gregorian(1387,12,06)) --- more efficient but needs testing --- --- local escapes = utffilters.private.escapes --- +-- -- more efficient but needs testing + +-- local escapes = characters.filters.utf.private.escapes + -- local function do_alphabetic(n,mapping,chr) -- local max = #mapping -- if n > max then --- do_alphabetic(floor((n-1)/max),max,chr) +-- do_alphabetic(floor((n-1)/max),mapping,chr) -- n = (n-1)%max+1 -- end -- n = chr(n,mapping) -- context(escapes[n] or utfchar(n)) -- end --- + -- local lccodes, uccodes, safechar = characters.lccode, characters.uccode, commands.safechar --- + -- local function do_alphabetic(n,mapping,chr) -- local max = #mapping -- if n > max then @@ -659,16 +656,16 @@ end -- end -- safechar(chr(n,mapping)) -- end --- + -- local function lowercased(n,mapping) return characters.lccode(mapping[n] or fallback) end -- local function uppercased(n,mapping) return characters.uccode(mapping[n] or fallback) end --- + -- function converters.alphabetic(n,code) --- do_alphabetic(n,counters[code] or counters['**'],lowercased) -- lccode catches wrong tables +-- do_alphabetic(n,counters[code] or counters.default,lowercased) -- lccode catches wrong tables -- end --- + -- function converters.Alphabetic(n,code) --- do_alphabetic(n,counters[code] or counters['**'],uppercased) +-- do_alphabetic(n,counters[code] or counters.default,uppercased) -- end local ordinals = { diff --git a/tex/context/base/data-lua.lua b/tex/context/base/data-lua.lua index fde79d464..7e3d92585 100644 --- a/tex/context/base/data-lua.lua +++ b/tex/context/base/data-lua.lua @@ -14,7 +14,7 @@ local gsub = string.gsub local concat = table.concat local addsuffix = file.addsuffix -local P, Cs, lpegmatch = lpeg.P, lpeg.Cs, lpeg.match +local P, S, Cs, lpegmatch = lpeg.P, lpeg.S, lpeg.Cs, lpeg.match local libsuffixes = { 'tex', 'lua' } local clibsuffixes = { 'lib' } @@ -77,17 +77,17 @@ local function loadedbyformat(name,rawname,suffixes,islib) local trace = helpers.trace local report = helpers.report if trace then - report("! locating %a as %a using formats %a",rawname,name,suffixes) + report("locating %a as %a using formats %a",rawname,name,suffixes) end for i=1,#suffixes do -- so we use findfile and not a lookup loop local format = suffixes[i] local resolved = resolvers.findfile(name,format) or "" if trace then - report("! checking for %a using format %a",name,format) + report("checking %a using format %a",name,format) end if resolved ~= "" then if trace then - report("! lib %a located on %a",name,resolved) + report("lib %a located on %a",name,resolved) end if islib then return true, loadedaslib(resolved,rawname) @@ -102,8 +102,25 @@ helpers.loadedbyformat = loadedbyformat -- alternatively we could set the package.searchers +local pattern = Cs((((1-S("\\/"))^0 * (S("\\/")^1/"/"))^0 * (P(".")^1/"/"+P(1))^1) * -1) + +local function lualibfile(name) + return lpegmatch(pattern,name) or name +end + +helpers.lualibfile = lualibfile + +-- print(lualibfile("bar")) +-- print(lualibfile("foo.bar")) +-- print(lualibfile("crap/foo...bar")) +-- print(lualibfile("crap//foo.bar")) +-- print(lualibfile("crap/../foo.bar")) +-- print(lualibfile("crap/.././foo.bar")) + +-- alternatively we could split in path and base and temporary set the libpath to path + function helpers.loaded(name) - local thename = gsub(name,"%.","/") + local thename = lualibfile(name) local luaname = addsuffix(thename,"lua") local libname = addsuffix(thename,os.libsuffix) local libpaths = getlibpaths() @@ -135,7 +152,7 @@ function helpers.loaded(name) return notloaded(name) end -package.searchers[3] = nil -- get rid of the built in one +-- package.searchers[3] = nil -- get rid of the built in one (done in l-lua) -- package.extraclibpath(environment.ownpath) diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua index c69ee4ce3..f7e238a11 100644 --- a/tex/context/base/data-res.lua +++ b/tex/context/base/data-res.lua @@ -290,11 +290,12 @@ end local slash = P("/") -local pathexpressionpattern = Cs ( +local pathexpressionpattern = Cs ( -- create lpeg instead (2013/2014) Cc("^") * ( Cc("%") * S(".-") + slash^2 * P(-1) / "/.*" - + slash^2 / "/.-/" +-- + slash^2 / "/.-/" + + slash^2 / "/[^/]*/*" + (1-slash) * P(-1) * Cc("/") + P(1) )^1 * Cc("$") -- yes or no $ @@ -1138,7 +1139,11 @@ local function find_intree(filename,filetype,wantedfiles,allresults) if trace_detail then report_resolving("checking filename %a",filename) end + local resolve = resolvers.resolve local result = { } + -- pathlist : resolved + -- dirlist : unresolved or resolved + -- filelist : unresolved for k=1,#pathlist do local path = pathlist[k] local pathname = lpegmatch(inhibitstripper,path) @@ -1158,9 +1163,10 @@ local function find_intree(filename,filetype,wantedfiles,allresults) local fl = filelist[k] local f = fl[2] local d = dirlist[k] - if find(d,expression) then + -- resolve is new: + if find(d,expression) or find(resolve(d),expression) then -- todo, test for readable - result[#result+1] = resolvers.resolve(fl[3]) -- no shortcut + result[#result+1] = resolve(fl[3]) -- no shortcut done = true if allresults then if trace_detail then @@ -1182,7 +1188,7 @@ local function find_intree(filename,filetype,wantedfiles,allresults) else method = "filesystem" -- bonus, even when !! is specified pathname = gsub(pathname,"/+$","") - pathname = resolvers.resolve(pathname) + pathname = resolve(pathname) local scheme = url.hasscheme(pathname) if not scheme or scheme == "file" then local pname = gsub(pathname,"%.%*$",'') @@ -1413,7 +1419,9 @@ local function findgivenfiles(filename,allresults) if found ~= "" then noffound = noffound + 1 result[noffound] = resolvers.resolve(found) - if not allresults then break end + if not allresults then + break + end end else for kk=1,#blist do diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index deba4e49d..cb640b892 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -402,6 +402,8 @@ local function presetcontext(name,parent,features) -- will go to con and shared features[k] = v end end + else + -- just ignore an undefined one .. i.e. we can refer to not yet defined end end end @@ -659,8 +661,23 @@ end -- we need a copy as we will add (fontclass) goodies to the features and -- that is bad for a shared table +-- local function splitcontext(features) -- presetcontext creates dummy here +-- return fastcopy(setups[features] or (presetcontext(features,"","") and setups[features])) +-- end + local function splitcontext(features) -- presetcontext creates dummy here - return fastcopy(setups[features] or (presetcontext(features,"","") and setups[features])) + local sf = setups[features] + if not sf then + local n -- number + if find(features,",") then + -- let's assume a combination which is not yet defined but just specified (as in math) + n, sf = presetcontext(features,features,"") + else + -- we've run into an unknown feature and or a direct spec so we create a dummy + n, sf = presetcontext(features,"","") + end + end + return fastcopy(sf) end -- local splitter = lpeg.splitat("=") diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua index 74073227a..5074e49ed 100644 --- a/tex/context/base/font-def.lua +++ b/tex/context/base/font-def.lua @@ -328,9 +328,21 @@ function definers.loadfont(specification) return tfmdata end ---[[ldx-- -<p>For virtual fonts we need a slightly different approach:</p> ---ldx]]-- +local function checkvirtual(tfmdata) + -- begin of experiment: we can use { "slot", 0, number } in virtual fonts + local fonts = tfmdata.fonts + local selfid = font.nextid() + if fonts and #fonts > 0 then + for i=1,#fonts do + if fonts[i][2] == 0 then + fonts[i][2] = selfid + end + end + else + tfmdata.fonts = { "id", selfid } + end + -- end of experiment +end function constructors.readanddefine(name,size) -- no id -- maybe a dummy first local specification = definers.analyze(name,size) @@ -344,7 +356,7 @@ function constructors.readanddefine(name,size) -- no id -- maybe a dummy first if not id then local tfmdata = definers.loadfont(specification) if tfmdata then - tfmdata.properties.hash = hash + checkvirtual(tfmdata) -- experiment, will become obsolete when slots can selfreference id = font.define(tfmdata) definers.register(tfmdata,id) else diff --git a/tex/context/base/font-ext.lua b/tex/context/base/font-ext.lua index df8cbe160..89d5927d4 100644 --- a/tex/context/base/font-ext.lua +++ b/tex/context/base/font-ext.lua @@ -902,7 +902,9 @@ function fonts.helpers.addprivate(tfmdata,name,characterdata) privates = { } properties.privates = privates end - privates[name] = lastprivate + if name then + privates[name] = lastprivate + end properties.lastprivate = lastprivate tfmdata.characters[lastprivate] = characterdata if properties.finalized then diff --git a/tex/context/base/font-gds.lua b/tex/context/base/font-gds.lua index 810d49eea..91a5ea66c 100644 --- a/tex/context/base/font-gds.lua +++ b/tex/context/base/font-gds.lua @@ -719,3 +719,19 @@ end commands.loadfontgoodies = fontgoodies.load commands.enablefontcolorschemes = colorschemes.enable + +-- weird place ... depends on math + +local function finalize(tfmdata,feature,value) + mathematics.overloaddimensions(tfmdata,tfmdata,value) +end + +registerotffeature { + name = "mathdimensions", + description = "manipulate math dimensions", + -- default = true, + manipulators = { + base = finalize, + node = finalize, + } +} diff --git a/tex/context/base/l-lua.lua b/tex/context/base/l-lua.lua index 555d5d746..538c65d7e 100644 --- a/tex/context/base/l-lua.lua +++ b/tex/context/base/l-lua.lua @@ -214,7 +214,7 @@ local function addpath(what,paths,extras,hash,...) local path = cleanpath(path) if not hash[path] then if trace then - report("! extra %s path: %s",what,path) + report("extra %s path: %s",what,path) end paths [#paths +1] = path extras[#extras+1] = path @@ -253,7 +253,7 @@ end -- local path = cleanpath(path) -- if not libhash[path] then -- if trace then --- report("! extra lua path: %s",path) +-- report("extra lua path: %s",path) -- end -- libextras[#libextras+1] = path -- libpaths [#libpaths +1] = path @@ -283,7 +283,7 @@ end -- local path = cleanpath(path) -- if not clibhash[path] then -- if trace then --- report("! extra lib path: %s",path) +-- report("extra lib path: %s",path) -- end -- clibextras[#clibextras+1] = path -- clibpaths [#clibpaths +1] = path @@ -317,14 +317,14 @@ local function loadedaslib(resolved,rawname) -- local init = "luaopen_" .. string.match(rawname,".-([^%.]+)$") local init = "luaopen_"..gsub(rawname,"%.","_") if helpers.trace then - helpers.report("! calling loadlib with '%s' with init '%s'",resolved,init) + helpers.report("calling loadlib with '%s' with init '%s'",resolved,init) end return package.loadlib(resolved,init) end local function loadedbylua(name) if helpers.trace then - helpers.report("! locating '%s' using normal loader",name) + helpers.report("locating '%s' using normal loader",name) end return true, searchers[-2](name) -- the original end @@ -333,17 +333,17 @@ local function loadedbypath(name,rawname,paths,islib,what) local trace = helpers.trace local report = helpers.report if trace then - report("! locating '%s' as '%s' on '%s' paths",rawname,name,what) + report("locating '%s' as '%s' on '%s' paths",rawname,name,what) end for p=1,#paths do local path = paths[p] local resolved = filejoin(path,name) if trace then -- mode detail - report("! checking for '%s' using '%s' path '%s'",name,what,path) + report("checking for '%s' using '%s' path '%s'",name,what,path) end if isreadable(resolved) then if trace then - report("! lib '%s' located on '%s'",name,resolved) + report("lib '%s' located on '%s'",name,resolved) end if islib then return true, loadedaslib(resolved,rawname) diff --git a/tex/context/base/luat-lib.mkiv b/tex/context/base/luat-lib.mkiv index a2ad4cac4..3f72e780e 100644 --- a/tex/context/base/luat-lib.mkiv +++ b/tex/context/base/luat-lib.mkiv @@ -30,7 +30,6 @@ \registerctxluafile{trac-inf}{1.001} %registerctxluafile{trac-pro}{1.001} \registerctxluafile{util-lua}{1.001} -\registerctxluafile{util-lib}{1.001} \registerctxluafile{util-deb}{1.001} % could also be done in trac-deb.mkiv \registerctxluafile{util-tpl}{1.001} % needs tracker @@ -61,6 +60,8 @@ \registerctxluafile{data-use}{1.001} \registerctxluafile{data-aux}{1.001} +\registerctxluafile{util-lib}{1.001} + \registerctxluafile{luat-cbk}{1.001} \registerctxluafile{luat-run}{1.001} \registerctxluafile{luat-fio}{1.001} diff --git a/tex/context/base/m-graph.mkiv b/tex/context/base/m-graph.mkiv index c80e4ad91..25933d9eb 100644 --- a/tex/context/base/m-graph.mkiv +++ b/tex/context/base/m-graph.mkiv @@ -67,11 +67,12 @@ if unknown context_grap: input "mp-grap.mpiv" ; fi ; \stopMPdefinitions -% gone: -% -% \startMPextensions -% if unknown Fe_plus : picture Fe_plus ; Fe_plus := textext("+") ; fi ; -% \stopMPextensions +% For backwards compatibility (for the moment), also load the graph macros in +% the standard MP instance (scaled integer): + +\startMPdefinitions + if unknown context_grap: input "mp-grap.mpiv" ; fi ; +\stopMPdefinitions \protect @@ -79,7 +80,7 @@ \starttext -\startMPpage +\startMPpage[instance=graph] label(format("@g","1e-8"), (0, 0)) ; label(format("@g","1e+8"), (2cm, 0)) ; label(format("@g","1e-10"), (0, -0.5cm)) ; @@ -94,19 +95,19 @@ label(format("@g","1e+102"),(2cm,-2.5cm)) ; \stopMPpage -% \startMPpage +% \startMPpage[instance=graph] % draw begingraph(3in,2in); % gdraw "t:/metapost/grphdata/agepop91.d"; % endgraph; % \stopMPpage -% \startMPpage +% \startMPpage[instance=graph] % draw begingraph(3in,2in); % gdraw "agepop91.d" plot btex $\bullet$ etex; % endgraph; % \stopMPpage -% \startMPpage +% \startMPpage[instance=graph] % draw begingraph(3in,2in); % glabel.lft(btex \vbox{\hbox{Population} \hbox{in millions}} etex, OUT); % glabel.bot(btex Age in years etex, OUT); @@ -114,7 +115,7 @@ % endgraph; % \stopMPpage -% \startMPpage +% \startMPpage[instance=graph] % draw begingraph(3in,2in); % glabel.lft(btex \vbox{\hbox{Population} \hbox{in millions}} etex, OUT); % glabel.bot(btex Age in years etex, OUT); @@ -123,7 +124,7 @@ % endgraph; % \stopMPpage -% \startMPpage +% \startMPpage[instance=graph] % draw begingraph(2.3in,2in); % setcoords(log,log); % glabel.lft(btex Seconds etex,OUT); @@ -136,7 +137,7 @@ % endgraph; % \stopMPpage -% \startMPpage +% \startMPpage[instance=graph] % draw begingraph(6.5cm,4.5cm); % setrange(80,0, 90,whatever); % glabel.bot(btex Year etex, OUT); diff --git a/tex/context/base/math-act.lua b/tex/context/base/math-act.lua index bfc229a92..8aeb0a97f 100644 --- a/tex/context/base/math-act.lua +++ b/tex/context/base/math-act.lua @@ -8,6 +8,9 @@ if not modules then modules = { } end modules ['math-act'] = { -- Here we tweak some font properties (if needed). +local type, next = type, next +local fastcopy = table.fastcopy + local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end) local report_math = logs.reporter("mathematics","initializing") @@ -193,6 +196,89 @@ end sequencers.appendaction("beforecopyingcharacters","system","mathematics.tweakbeforecopyingfont") sequencers.appendaction("aftercopyingcharacters", "system","mathematics.tweakaftercopyingfont") +function mathematics.overloaddimensions(target,original,set) + local goodies = target.goodies + if goodies then + for i=1,#goodies do + local goodie = goodies[i] + local mathematics = goodie.mathematics + local dimensions = mathematics and mathematics.dimensions + if dimensions then + if trace_defining then + report_math("overloading dimensions in %a @ %p",target.properties.fullname,target.parameters.size) + end + local characters = target.characters + local parameters = target.parameters + local factor = parameters.factor + local hfactor = parameters.hfactor + local vfactor = parameters.vfactor + local addprivate = fonts.helpers.addprivate + local function overload(dimensions) + for unicode, data in next, dimensions do + local character = characters[unicode] + if character then + -- + local width = data.width + local height = data.height + local depth = data.depth + if trace_defining and (width or height or depth) then + report_math("overloading dimensions of %C, width %a, height %a, depth %a",unicode,width,height,depth) + end + if width then character.width = width * hfactor end + if height then character.height = height * vfactor end + if depth then character.depth = depth * vfactor end + -- + local xoffset = data.xoffset + local yoffset = data.yoffset + if xoffset then + xoffset = { "right", xoffset * hfactor } + end + if yoffset then + yoffset = { "down", -yoffset * vfactor } + end + if xoffset or yoffset then + local slot = { "slot", 1, addprivate(target,nil,fastcopy(character)) } + if xoffset and yoffset then + character.commands = { xoffset, yoffset, slot } + elseif xoffset then + character.commands = { xoffset, slot } + else + character.commands = { yoffset, slot } + end + character.index = nil + end + elseif trace_defining then + report_math("no overloading dimensions of %C, not in font",unicode) + end + end + end + if set == nil then + set = { "default" } + end + if set == "all" or set == true then + for name, set in next, dimensions do + overload(set) + end + else + if type(set) == "string" then + set = utilities.parsers.settings_to_array(set) + end + if type(set) == "table" then + for i=1,#set do + local d = dimensions[set[i]] + if d then + overload(d) + end + end + end + end + end + end + end +end + +sequencers.appendaction("aftercopyingcharacters", "system","mathematics.overloaddimensions") + -- a couple of predefined tewaks: local tweaks = { } diff --git a/tex/context/base/math-ali.mkiv b/tex/context/base/math-ali.mkiv index 0e08c70bb..a172dc8ae 100644 --- a/tex/context/base/math-ali.mkiv +++ b/tex/context/base/math-ali.mkiv @@ -424,6 +424,7 @@ \setupmathcases [\c!distance=\emwidth, + \c!strut=\v!yes, % new \c!numberdistance=2.5\emwidth, \c!left={\left\{\mskip\thinmuskip}, \c!right={\right.}] @@ -438,30 +439,72 @@ \edef\currentmathcases{#1}% \dosingleempty\math_cases_start_indeed} +\def\math_cases_NC_zero + {\math_cases_NC} + +\def\math_cases_MC_zero + {\math_cases_NC + \ifmmode\else + \startimath + \let\math_cases_end_math\stopimath + \fi} + +\let\math_cases_end_math\relax + +\def\math_cases_NR_zero + {\unskip + \math_cases_end_math + \aligntab + \global\let\math_cases_NC\math_cases_NC_first + \dodirectdoubleempty\math_cases_NR} + +\def\math_cases_NC_first + {\global\let\math_cases_NC\math_cases_NC_second} + +\def\math_cases_NC_second + {\math_cases_end_math\aligntab} + +\let\math_cases_NR\math_align_NR_generic + \unexpanded\def\math_cases_start_indeed[#1]% {\iffirstargument \setupcurrentmathcases[#1]% \fi + \edef\p_strut{\mathcasesparameter\c!strut}% + \ifx\p_strut\v!yes + \let\math_cases_strut\strut + \else + \let\math_cases_strut\relax + \fi \mathcasesparameter\c!left \vcenter\bgroup \pushmacro\math_cases_NC \let\endmath\relax - \def\NC{\math_cases_NC}% - \def\MC{\math_cases_NC\ifmmode\else$\def\endmath{$}\fi}% - \global\let\math_cases_NC\math_cases_NC_indeed - \def\NR{\unskip\endmath&\global\let\math_cases_NC\math_cases_NC_indeed\dodirectdoubleempty\math_cases_NR}% + \let\NC\math_cases_NC_zero + \let\MC\math_cases_MC_zero + \let\NR\math_cases_NR_zero + \global\let\math_cases_NC\math_cases_NC_first \normalbaselines \mathsurround\zeropoint \everycr\emptytoks \tabskip\zeropoint \global\c_math_eqalign_column\plusone \halign\bgroup - $\mathcasesparameter\c!style##$\hfil - &\hskip\mathcasesparameter\c!distance\relax - \popmacro\math_cases_NC##\hfil - &\hskip\mathcasesparameter\c!numberdistance\relax - \let\formuladistance\!!zeropoint - \span\math_text_in_eqalign{##}% + \startimath + \mathcasesparameter\c!style + \alignmark\alignmark + \stopimath + \hfil + \aligntab + \hskip\mathcasesparameter\c!distance\relax + \popmacro\math_cases_NC + \math_cases_strut % looks better + \alignmark\alignmark + \hfil + \aligntab + \hskip\mathcasesparameter\c!numberdistance\relax + \let\formuladistance\!!zeropoint + \span\math_text_in_eqalign{\alignmark\alignmark}% \crcr} % todo: number \def\math_cases_stop @@ -472,11 +515,6 @@ \mathcasesparameter\c!right \endgroup} -\def\math_cases_NC_indeed - {\gdef\math_cases_NC{\endmath&}} - -\let\math_cases_NR\math_align_NR_generic - \definemathcases[cases] \definemathcases[\v!mathcases] diff --git a/tex/context/base/mult-aux.mkiv b/tex/context/base/mult-aux.mkiv index 62111a642..97b330248 100644 --- a/tex/context/base/mult-aux.mkiv +++ b/tex/context/base/mult-aux.mkiv @@ -266,6 +266,12 @@ \let\definehandlerparent\empty +\def\mult_check_for_parent#1#2#3#4% + {\ifcsname#1#4:\s!parent\endcsname \else \ifx#4\empty \else + \writestatus\m!system{error: invalid parent #4 for #3, #4 defined too (best check it)}% + \expandafter\edef\csname#1#4:\s!parent\endcsname{#2}% + \fi \fi} + \unexpanded\def\mult_interfaces_install_define_handler#1#2#3#4#5#6#7#8#9% why is \expanded still needed in clones {\ifx#4\relax\let#4\empty\fi % see \defineregister \unexpanded\def#2{\dotripleempty#5}% @@ -277,6 +283,7 @@ \ifthirdargument \the#6% predefine \edef#8{##2}% + \mult_check_for_parent{#1}{#3}#4#8% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% \mult_interfaces_get_parameters{#1#4:}[##3]% \else\ifsecondargument @@ -288,6 +295,7 @@ \mult_interfaces_get_parameters{#1#4:}[##2]% \else \edef#8{##2}% + \mult_check_for_parent{#1}{#3}#4#8% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% \fi \else diff --git a/tex/context/base/mult-fun.lua b/tex/context/base/mult-fun.lua index f7a7792e5..a661c53bb 100644 --- a/tex/context/base/mult-fun.lua +++ b/tex/context/base/mult-fun.lua @@ -11,6 +11,7 @@ return { -- "autoarrows", "ahfactor", -- "angleoffset", anglelength", anglemethod", "metapostversion", + "maxdimensions", }, commands = { -- diff --git a/tex/context/base/pack-pos.mkiv b/tex/context/base/pack-pos.mkiv index ff8244f0a..f92ceb78a 100644 --- a/tex/context/base/pack-pos.mkiv +++ b/tex/context/base/pack-pos.mkiv @@ -146,7 +146,8 @@ \c!yscale \c!yfactor \vbox to \zeropoint - {\vskip\d_pack_positioning_y_position + {\offinterlineskip % else we get an empty line + \vskip\d_pack_positioning_y_position \hbox to \zeropoint {\hskip\d_pack_positioning_x_position \box\nextbox diff --git a/tex/context/base/page-imp.mkiv b/tex/context/base/page-imp.mkiv index db7986c28..213f8be1a 100644 --- a/tex/context/base/page-imp.mkiv +++ b/tex/context/base/page-imp.mkiv @@ -90,18 +90,33 @@ \installshipoutmethod \v!none {\page_shipouts_ignore} +% extension mechanism + +\newcount\c_page_boxes_flush_n % set at the lua end + +\let\page_boxes_flush_before\relax +\let\page_boxes_flush_after \relax + +% used here: + \def\page_boxes_shipout#1% or: \page_shipouts_apply - {\dontcomplain % redundant - \the\everybeforeshipout - \ifcase\shipoutfinalizemethod - \page_shipouts_handle{#1}% - \else - \setbox\shipoutscratchbox\hbox{#1}% just in case there are objects there, hook for testing (will go away) - \finalizeshipoutbox\shipoutscratchbox - \page_shipouts_handle{\box\shipoutscratchbox}% - \fi - \setnextrealpageno % so this comes before \everyaftershipout so in fact: - \the\everyaftershipout} % at this point we're already on the next realpage + {\dontcomplain % redundant + \ifcase\c_page_boxes_flush_n\else + \page_boxes_flush_before + \fi + \the\everybeforeshipout + \ifcase\shipoutfinalizemethod + \page_shipouts_handle{#1}% + \else + \setbox\shipoutscratchbox\hbox{#1}% just in case there are objects there, hook for testing (will go away) + \finalizeshipoutbox\shipoutscratchbox + \page_shipouts_handle{\box\shipoutscratchbox}% + \fi + \setnextrealpageno % so this comes before \everyaftershipout so in fact: + \the\everyaftershipout % at this point we're already on the next realpage + \ifcase\c_page_boxes_flush_n\else + \page_boxes_flush_after + \fi} \def\page_shipouts_ignore#1% {\begingroup diff --git a/tex/context/base/page-inj.lua b/tex/context/base/page-inj.lua new file mode 100644 index 000000000..5b450d60e --- /dev/null +++ b/tex/context/base/page-inj.lua @@ -0,0 +1,101 @@ +if not modules then modules = { } end modules ["page-inj"] = { + version = 1.000, + comment = "Page injections", + author = "Wolfgang Schuster & Hans Hagen", + copyright = "Wolfgang Schuster & Hans Hagen", + license = "see context related readme files", +} + +-- Adapted a bit by HH: numbered states, tracking, delayed, order, etc. + +local injections = pagebuilders.injections or { } +pagebuilders.injections = injections + +local report = logs.reporter("pagebuilder","injections") +local trace = false trackers.register("pagebuilder.injections",function(v) trace = v end) + +local variables = interfaces.variables + +local v_yes = variables.yes +local v_previous = variables.previous +local v_next = variables.next + +local order = 0 +local cache = { } + +function injections.save(specification) -- maybe not public, just commands.* + order = order + 1 + cache[#cache+1] = { + order = order, + name = specification.name, + state = tonumber(specification.state) or specification.state, + parameters = specification.userdata, + } + tex.setcount("global","c_page_boxes_flush_n",#cache) +end + +function injections.flushbefore() -- maybe not public, just commands.* + if #cache > 0 then + local delayed = { } + context.unprotect() + for i=1,#cache do + local c = cache[i] + local oldstate = c.state + if oldstate == v_previous then + if trace then + report("entry %a, order %a, flushing due to state %a",i,c.order,oldstate) + end + context.page_injections_flush_saved(c.name,c.parameters) + elseif type(oldstate) == "number" and oldstate < 0 then + local newstate = oldstate + 1 + if newstate >= 0 then + newstate = v_previous + end + if trace then + report("entry %a, order %a, changing state from %a to %a",i,c.order,oldstate,newstate) + end + c.state = newstate + delayed[#delayed+1] = c + else + delayed[#delayed+1] = c + end + end + context.unprotect() + cache = delayed + tex.setcount("global","c_page_boxes_flush_n",#cache) + end +end + +function injections.flushafter() -- maybe not public, just commands.* + if #cache > 0 then + local delayed = { } + context.unprotect() + for i=1,#cache do + local c = cache[i] + local oldstate = c.state + if oldstate == v_next then + if trace then + report("entry %a, order %a, flushing due to state %a",i,c.order,oldstate) + end + context.page_injections_flush_saved(c.name,c.parameters) + elseif type(oldstate) == "number" and oldstate> 0 then + local newstate = oldstate- 1 + if newstate <= 0 then + newstate = v_next + end + if trace then + report("entry %a, order %a, changing state from %a to %a",i,c.order,oldstate,newstate) + end + c.state = newstate + delayed[#delayed+1] = c + end + end + context.protect() + cache = delayed + tex.setcount("global","c_page_boxes_flush_n",#cache) + end +end + +commands.page_injections_save = injections.save +commands.page_injections_flush_after = injections.flushafter +commands.page_injections_flush_before = injections.flushbefore diff --git a/tex/context/base/page-inj.mkvi b/tex/context/base/page-inj.mkvi new file mode 100644 index 000000000..bee564683 --- /dev/null +++ b/tex/context/base/page-inj.mkvi @@ -0,0 +1,217 @@ +%D \module +%D [ file=page-inj, +%D version=2013.02.10, +%D title=\CONTEXT\ Page Module, +%D subtitle=Injections, +%D author=Wolfgang Schuster \& Hans Hagen, +%D date=\currentdate, +%D copyright=Wolfgang Schuster \& Hans Hagen, +%D license=see context related readme files (gpl)] + +%D This module is based on an idea and prototype by Wolfgang but instead of +%D injectioning into a page constructor we injection it into the regular shipout +%D handler because that way we get page numbering. It's a sort of variation +%D on postponing but the content does not end up in the regular page flow, so +%D it's closer to page figures but without the usual page builder. +%D +%D This module is following the mkvi way of rendering setups and configuration +%D and is somewhat experimental. Probably more alternatives will be added. This +%D could become a delayed loaded module at some point (no real consequences). + +\unprotect + +\registerctxluafile{page-inj}{1.001} + +\installcorenamespace {pageinjection} +\installcorenamespace {pageinjectionalternative} +\installcorenamespace {pageinjectionrenderings} + +\installframedcommandhandler \??pageinjection {pageinjection} \??pageinjection +\installcommandhandler \??pageinjectionalternative {pageinjectionalternative} \??pageinjectionalternative + +\def\page_boxes_flush_before{\ctxcommand{page_injections_flush_before()}} +\def\page_boxes_flush_after {\ctxcommand{page_injections_flush_after ()}} + +\def\page_injections_flush_saved#name#parameters% + {\begingroup + \edef\currentpageinjection{#name}% + \getdummyparameters[#parameters]% + \edef\currentpageinjectionalternative {\pageinjectionparameter \c!alternative }% + \edef\p_page_injectionalternative_rederingsetup{\pageinjectionalternativeparameter\c!renderingsetup}% + \page_injections_nextpage + \invokepagehandler\v!normal{\inheritedpageinjectionframed{\texsetup\p_page_injectionalternative_rederingsetup}}% + \endgroup} + +\unexpanded\def\pageinjection + {\begingroup + \dodoubleempty\page_injections_direct} + +\def\page_injections_direct[#1][#2]% name parameters | settings parameters | name | parameters + {\doifassignmentelse{#1} + {\doifassignmentelse{#2} + {\page_injections_direct_settings_parameters{#1}{#2}} + {\page_injections_direct_parameters {#1}}} + {\doifassignmentelse{#2} + {\page_injections_direct_name_parameters {#1}{#2}} + {\page_injections_direct_name {#1}}}} + +\def\page_injections_direct_settings_parameters#settings% #parameters% + {\let\currentpageinjection\empty + \checkpageinjectionparent + \setupcurrentpageinjection[#settings]% + \page_injections_direct_indeed} + +\def\page_injections_direct_parameters% #parameters% + {\let\currentpageinjection\empty + \checkpageinjectionparent + \page_injections_direct_indeed} + +\def\page_injections_direct_name_parameters#name% #parameters% + {\edef\currentpageinjection{#name}% + \checkpageinjectionparent + \page_injections_direct_indeed} + +\def\page_injections_direct_name#name% + {\edef\currentpageinjection{#name}% + \checkpageinjectionparent + \page_injections_direct_indeed{}} + +\def\page_injections_direct_indeed% #parameters% + {\edef\p_page_injections_state{\pageinjectionparameter\c!state}% + \edef\p_page_injections_delay{\pageinjectionparameter\c!delay}% + \edef\p_page_injections_page {\pageinjectionparameter\c!page }% + \ifx\p_page_injections_delay\v!yes + \expandafter\page_injections_direct_indeed_yes + \else + \expandafter\page_injections_direct_indeed_nop + \fi} + +\def\page_injections_direct_indeed_yes#parameters% + {\ctxcommand{page_injections_save{ + name = "\currentpageinjection", + state = "\p_page_injections_state", + userdata = \!!bs\normalunexpanded{#parameters}\!!es + }}% + \endgroup} + +\def\page_injections_direct_indeed_nop#parameters% + {\ifx\p_page_injections_page\empty + \page + \else + \page[\p_page_injections_page]% + \fi + \getdummyparameters[#parameters]% + \page_injections_place + \endgroup} + +\def\page_injections_place + {\edef\currentpageinjectionalternative {\pageinjectionparameter \c!alternative }% + \edef\p_page_injectionalternative_rederingsetup{\pageinjectionalternativeparameter\c!renderingsetup}% + \page_injections_nextpage + \ifx\currentpageinjectionalternative\v!none \else % increment counter but don’t generate output + \invokepagehandler\v!normal{\inheritedpageinjectionframed{\texsetup\p_page_injectionalternative_rederingsetup}}% + \fi} + +\def\page_injections_nextpage + {\edef\p_page_injections_pagestate{\pageinjectionparameter\c!pagestate}% + \ifx\p_page_injections_pagestate\v!stop \else + \edef\p_page_injections_n{\pageinjectionparameter\c!n}% + \ifx\p_page_injections_n\empty + \let\p_page_injections_n\plusone + \fi + \dorecurse\p_page_injections_n + {\incrementcounter[\s!realpage]% + \incrementcounter[\s!userpage]}% + \fi} + +\definepageinjectionalternative[\v!figure][\c!renderingsetup=\??pageinjectionrenderings:\v!figure] +\definepageinjectionalternative[\v!buffer][\c!renderingsetup=\??pageinjectionrenderings:\v!buffer] +\definepageinjectionalternative[\v!setups][\c!renderingsetup=\??pageinjectionrenderings:\s!setup ] + +\startsetups[\??pageinjectionrenderings:\v!figure] + \dontleavehmode\externalfigure[\dummyparameter\c!name][\c!factor=\v!max] +\stopsetups + +\startsetups[\??pageinjectionrenderings:\s!setup] + \setups[\dummyparameter\c!setup]% kind of redundant but fits in +\stopsetups + +\startsetups[\??pageinjectionrenderings:\v!buffer] + \getbuffer[\dummyparameter\c!name]% +\stopsetups + +% \setuppaper +% [\c!method=\v!pageinjection] + +\setuppageinjection + [ \c!width=\paperwidth, + \c!height=\paperheight, + \c!frame=\v!off, + \c!offset=\v!overlay, + \c!delay=\v!no, + \c!state=\v!next, + \c!alternative=\v!figure] + +\definepageinjection[\v!previouspage][\c!delay=\v!yes,\c!state=\v!previous] +\definepageinjection[\v!nextpage] [\c!delay=\v!yes,\c!state=\v!next] +\definepageinjection[\v!here] % direct +\definepageinjection[\v!empty] [\c!alternative=\v!none] + +%definepageinjection[\v!chapter] [\v!previouspage][\c!pagestate=\v!stop] + +\protect \endinput + +% \enabletrackers[pagebuilder.injections] +% +% \setuppageinjection[offset=2em] +% +% \definepageinjection[chapter][previouspage][pagestate=stop] +% \definepageinjection[later] [delay=yes,state=+2] +% +% \useMPlibrary[dum] +% +% \starttext +% +% \startchapter[title={Insert pages before/after the current page}] +% +% \dorecurse{10}{one: \input ward\par} +% +% \pageinjection[previouspage][name=dummy-1] +% +% \dorecurse{20}{two: \input ward\par} \page +% +% \pageinjection[nextpage][name=dummy-2] +% \pageinjection[later] [name=dummy-4] +% \pageinjection[delay=yes,state=+2][name=dummy-5] +% +% \dorecurse{100}{three: \input ward\par} +% +% \stopchapter +% +% \startbuffer[whatever] +% \dorecurse{10}{whatever #1 } +% \stopbuffer +% +% \startchapter[title={Insert pages at the current location}] +% +% \dorecurse{10}{\input ward\par} +% +% \pageinjection[direct][name=dummy-3] +% \pageinjection[direct][alternative=buffer,name=whatever] +% +% \dorecurse{10}{\input ward\par} +% +% \stopchapter +% +% \setuphead +% [chapter] +% [beforesection={\pageinjection[empty]}, +% insidesection={\pageinjection[chapter][name=\structureuservariable{image}]}] +% +% \startchapter[title={Combine both mechanism}][name=dummy-4] +% +% \dorecurse{10}{\input ward\par} +% +% \stopchapter +% +% \stoptext diff --git a/tex/context/base/s-abr-01.tex b/tex/context/base/s-abr-01.tex index bbaa1e941..026f2ea09 100644 --- a/tex/context/base/s-abr-01.tex +++ b/tex/context/base/s-abr-01.tex @@ -233,6 +233,7 @@ \logo [SSD] {ssd} \logo [SVG] {svg} \logo [SWIG] {swig} +\logo [SWIGLIB] {SwigLib} \logo [TABLE] {\TaBlE} \logo [TCPIP] {tcp/ip} \logo [TDS] {tds} % no sc te diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf Binary files differindex 0647c17dc..28cb15781 100644 --- a/tex/context/base/status-files.pdf +++ b/tex/context/base/status-files.pdf diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf Binary files differindex c758864d9..8cc75d46c 100644 --- a/tex/context/base/status-lua.pdf +++ b/tex/context/base/status-lua.pdf diff --git a/tex/context/base/strc-enu.mkvi b/tex/context/base/strc-enu.mkvi index 62b54dbe0..185b4177e 100644 --- a/tex/context/base/strc-enu.mkvi +++ b/tex/context/base/strc-enu.mkvi @@ -229,30 +229,6 @@ % Maybe we should move counters to the construction level as more derived mechanisms % use it \unknown\ so don't depend on names here! -% \newtoks\everysetupenumerationcounter -% -% \let\v_strc_enumerations_counter_name\empty % or just p_counter -% -% \def\strc_enumerations_setup_counter#tag% -% {\edef\v_strc_enumerations_counter_name{#tag}% only used in the token list -% \the\everysetupenumerationcounter} -% -% \def\strc_enumerations_define_counter#tag% todo: fast inheritance (was mainparameter) -% {\definecounter[#tag]% -% \strc_enumerations_setup_counter{#tag}} -% -% \appendtoks -% \strc_counter_setup_using_parameter\v_strc_enumerations_counter_name\enumerationparameter -% \to \everysetupenumerationcounter -% -% \appendtoks -% \ifx\currentenumeration\empty -% \synchronizeenumerationcounters % this one can also do the rest .... but we need an extra arg then -% \else -% \strc_enumerations_setup_counter\currentenumeration -% \fi -% \to \everysetupenumeration - \def\strc_enumerations_define_counter#tag% todo: move inline {\definecounter[#tag]% \registerenumerationcounter{#tag}} @@ -261,6 +237,10 @@ \synchronizeenumerationcounters \to \everysetupenumeration +\appendtoks + \synchronizeenumerationcounters +\to \everydefineenumeration + %D Initializer: %D The handlers. diff --git a/tex/context/base/strc-flt.mkvi b/tex/context/base/strc-flt.mkvi index 696a03e99..dbf70f9c3 100644 --- a/tex/context/base/strc-flt.mkvi +++ b/tex/context/base/strc-flt.mkvi @@ -143,10 +143,15 @@ \installcounterassociation{floatcaption} \appendtoks - \let\currentfloat\currentfloatcaption + \let\currentfloat\currentfloatcaption % ? \synchronizefloatcaptioncounters \to \everysetupfloatcaption +\appendtoks + \let\currentfloat\currentfloatcaption % ? + \synchronizefloatcaptioncounters +\to \everydefinefloatcaption + %D Definitions: \let\strc_floats_define_saved\definefloat diff --git a/tex/context/base/strc-lab.mkiv b/tex/context/base/strc-lab.mkiv index 28a5020ed..772a9cc19 100644 --- a/tex/context/base/strc-lab.mkiv +++ b/tex/context/base/strc-lab.mkiv @@ -92,7 +92,6 @@ \fi \doifcounterelse\p_counter\donothing{\strc_labels_define_counter\p_counter}% \letlabelparameter\s!counter\p_counter - %\strc_labels_setup_counter\currentlabel \to \everydefinelabel \let\p_strc_constructions_title \empty @@ -139,28 +138,6 @@ % similar to enumerations -% \newtoks\everysetuplabelcounter -% -% \let\v_strc_labels_counter_name\empty -% -% \def\strc_labels_setup_counter#1% -% {\edef\v_strc_labels_counter_name{#1}% -% \the\everysetuplabelcounter} -% -% \def\strc_labels_define_counter#1% -% {\definecounter[#1]% -% \strc_labels_setup_counter{#1}} -% -% \appendtoks -% \strc_counter_setup_using_parameter\v_strc_labels_counter_name\labelparameter -% \to \everysetuplabelcounter -% -% \appendtoks -% \ifx\currentlabel\empty \else -% \strc_labels_setup_counter\currentlabel -% \fi -% \to \everysetuplabel - \def\strc_labels_define_counter#1% {\definecounter[#1]% \registerlabelcounter{#1}} @@ -169,6 +146,10 @@ \synchronizelabelcounters \to \everysetuplabel +\appendtoks + \synchronizelabelcounters +\to \everydefinelabel + % no start stop here \expandafter\let\csname\??constructionmainhandler\v!label\expandafter\endcsname\csname\??constructionmainhandler\v!description\endcsname diff --git a/tex/context/base/strc-mat.mkiv b/tex/context/base/strc-mat.mkiv index 933dce48a..20fa078a2 100644 --- a/tex/context/base/strc-mat.mkiv +++ b/tex/context/base/strc-mat.mkiv @@ -57,18 +57,16 @@ [\v!formula] [numbers,characters] % no \v! ? -% \strc_counter_preset_using_parameter\setupformulas\rootcounterparameter -% -% \appendtoks -% \strc_counter_setup_using_parameter\v!formula\formulaparameter -% \to \everysetupformula - \installcounterassociation{formula} \registerformulacounter\v!formula % currently we only have one \appendtoks \synchronizeformulacounters \to \everysetupformula +% \appendtoks +% \synchronizeformulacounters +% \to \everydefineformula + \setupformulas [\c!numberconversionset=\v!formula] % why forgotten diff --git a/tex/context/base/strc-not.mkvi b/tex/context/base/strc-not.mkvi index 324499b4e..09ea41bc4 100644 --- a/tex/context/base/strc-not.mkvi +++ b/tex/context/base/strc-not.mkvi @@ -382,20 +382,6 @@ \def\currentnoteinsertion {\noteparameter\s!insert} \def\currentnoteinsertionnumber{\namedinsertionnumber{\noteparameter\s!insert}} -% \appendtoks -% \doifinsertionelse\currentnote -% \donothing -% {\defineinsertion[\currentnote]% could be an option -% \normalexpanded{\t_strc_notes{\the\t_strc_notes\noexpand\strc_notes_process_list{\currentnote}}}}% -% \letnoteparameter\s!insert\currentnote -% \ctxcommand{definenote("\currentnote","insert",\number\currentnoteinsertionnumber)}% -% \ifx\currentnoteparent\empty -% \definenotation[\currentnote][\c!type=\v!note]% -% \else -% \definenotation[\currentnote][\currentnoteparent][\c!type=\v!note]% -% \fi -% \to \everydefinenote - \appendtoks \ifx\currentnoteparent\empty \doifinsertionelse\currentnote @@ -413,30 +399,6 @@ % maybe we will share this at some point: -% \newtoks\everysetupnotecounter -% -% \let\v_strc_note_counter_name\empty -% -% \def\strc_notes_setup_counter#tag% -% {\edef\v_strc_note_counter_name{#tag}% only used in the token list -% \the\everysetupnotecounter} -% -% \def\strc_notes_define_counter#tag% todo: fast inheritance (was mainparameter -% {\definecounter[#tag]% -% \strc_notes_setup_counter{#tag}} -% -% \appendtoks -% \strc_counter_setup_using_parameter\v_strc_note_counter_name\notationparameter -% \to \everysetupnotecounter -% -% \appendtoks -% \ifx\currentnotation\empty -% \synchronizeenumerationcounters -% \else -% \strc_notes_setup_counter\currentnotation -% \fi -% \to \everysetupnotation - \def\strc_notes_define_counter#tag% todo: move inline {\definecounter[#tag]% \registerenumerationcounter{#tag}} @@ -445,6 +407,10 @@ \synchronizenotationcounters \to \everysetupnotation +\appendtoks + \synchronizenotationcounters +\to \everydefinenotation + % so far %expandafter\let\csname\??constructionstarthandler \v!notation\expandafter\endcsname\csname\??constructionstarthandler \v!enumeration\endcsname diff --git a/tex/context/base/strc-reg.mkiv b/tex/context/base/strc-reg.mkiv index de9ebf6b4..b0d73f28c 100644 --- a/tex/context/base/strc-reg.mkiv +++ b/tex/context/base/strc-reg.mkiv @@ -133,7 +133,7 @@ \setuevalue{\e!setup\currentregister\e!endsetup}{\setupregister[\currentregister]}% \dorecurse\plusthree {% weird, expanded should not be needed \normalexpanded{\defineregister[\currentregister:\recurselevel][\currentregister]}% -% \defineregister[\currentregister:\recurselevel][\currentregister]% + %\defineregister[\currentregister:\recurselevel][\currentregister]% \letregisterparameter{\c!entries:\recurselevel}\empty % needed as we use detokenize (ok, we can \letregisterparameter{\c!keys :\recurselevel}\empty % avoid it, but it's faster too) }% diff --git a/tex/context/base/tabl-tab.mkiv b/tex/context/base/tabl-tab.mkiv index b9b519620..dbea3efe9 100644 --- a/tex/context/base/tabl-tab.mkiv +++ b/tex/context/base/tabl-tab.mkiv @@ -14,19 +14,17 @@ % Todo: consistent namespace and get rid of not used code -% In \MKIV\ the old table macros are sort of obsolete. The -% color extensions have been removed and some code is stripped. -% For practical reasons the \TABLE\ macros that are used are -% embedded in this file. +% In \MKIV\ the old table macros are sort of obsolete. The color extensions +% have been removed and some code is stripped. For practical reasons the +% \TABLE\ macros that are used are embedded in this file. % -% The following code is based on TABLE 1.0 by Michael J. Wichura -% (August 1988. We used a patched version with many overloads -% and extensions. The documented (and larger) source can be found -% in \type {thrd-tab.tex}. +% The following code is based on TABLE 1.0 by Michael J. Wichura (August 1988. +% We used a patched version with many overloads and extensions. The documented +% (and larger) source can be found in \type {thrd-tab.tex}. % -% Some code has been stripped. Some color has been added. Some macros -% have been renamed. Registers have been replaces. And probably much -% more can be cleaned up. +% Some code has been stripped. Some color has been added. Some macros have +% been renamed. Registers have been replaces. And probably much more can be +% cleaned up. We also need to use \tabl_tab_ prefixes here. \unprotect @@ -1370,8 +1368,8 @@ {\dochucktableautorow % before the tail, else noalign problem \doinserttabletail \starttablenoalign - \globalletempty\dotablehead - \globalletempty\dotabletail + \global\let\dotablehead\empty + \global\let\dotabletail\empty \stoptablenoalign \dofinishtable \ifx\p_tabl_table_frame\empty @@ -1598,6 +1596,8 @@ \egroup \dontcomplain \dosplittablebox\tablecontentbox + \global\let\dotablehead\empty % new here + \global\let\dotabletail\empty % new here \flushnotes \egroup} @@ -1651,18 +1651,10 @@ \let\dotablehead\empty % needs checking \let\dotabletail\empty % needs checking -\letbeundefined{\e!start\v!tablehead} -\letbeundefined{\e!stop \v!tablehead} -\letbeundefined{\e!start\v!tabletail} -\letbeundefined{\e!stop \v!tabletail} - -\expanded - {\long\def\csname\e!start\v!tablehead\endcsname##1\csname\e!stop\v!tablehead\endcsname% - {\noexpand\settablehead##1\noexpand\end}} - -\expanded - {\long\def\csname\e!start\v!tabletail\endcsname##1\csname\e!stop\v!tabletail\endcsname% - {\noexpand\settabletail##1\noexpand\end}} +\letvalue{\e!start\v!tablehead}\relax +\letvalue{\e!stop \v!tablehead}\relax +\letvalue{\e!start\v!tabletail}\relax +\letvalue{\e!stop \v!tabletail}\relax %D The second argument is a dummy one, by scanning for it, we %D get rid of interfering spaces. @@ -1671,11 +1663,27 @@ \newconditional\hassometablehead \newconditional\hassometabletail -\def\settablehead{\dodoubleempty\dosettablehead} -\def\settabletail{\dodoubleempty\dosettabletail} +\unexpanded\def\settablehead{\dodoubleempty\dosettablehead} +\unexpanded\def\settabletail{\dodoubleempty\dosettabletail} + +% \def\dosettablehead[#1][#2]#3\end{\setvalue{\??tablehead#1}{\tablenoalign{\global\settrue\hassometablehead}#3}} +% \def\dosettabletail[#1][#2]#3\end{\setvalue{\??tabletail#1}{\tablenoalign{\global\settrue\hassometabletail}#3}} + +\def\dosettablehead[#1][#2]#3\end + {\gdef\dotablehead{\executeifdefined{\??tablehead#1}\empty}% new + \setvalue{\??tablehead#1}{\tablenoalign{\global\settrue\hassometablehead}#3}} + +\def\dosettabletail[#1][#2]#3\end + {\gdef\dotabletail{\executeifdefined{\??tabletail#1}\empty}% new + \setvalue{\??tabletail#1}{\tablenoalign{\global\settrue\hassometabletail}#3}} + +\normalexpanded + {\def\csname\e!start\v!tablehead\endcsname#1\csname\e!stop\v!tablehead\endcsname% + {\settablehead#1\noexpand\end}} -\long\def\dosettablehead[#1][#2]#3\end{\setvalue{\??tablehead#1}{\tablenoalign{\global\settrue\hassometablehead}#3}} -\long\def\dosettabletail[#1][#2]#3\end{\setvalue{\??tabletail#1}{\tablenoalign{\global\settrue\hassometabletail}#3}} +\normalexpanded + {\def\csname\e!start\v!tabletail\endcsname#1\csname\e!stop\v!tabletail\endcsname% + {\settabletail#1\noexpand\end}} %D Redundant \type{\HL}'s are removed automatically, so %D mid||lines can be used without problems. diff --git a/tex/context/base/trac-deb.lua b/tex/context/base/trac-deb.lua index ba37447a6..fe167c343 100644 --- a/tex/context/base/trac-deb.lua +++ b/tex/context/base/trac-deb.lua @@ -106,18 +106,31 @@ function tracers.showlines(filename,linenumber,offset,errorstr) end local lines = data and string.splitlines(data) if lines and #lines > 0 then - -- this does not work yet as we cannot access the last lua error - -- table.print(status.list()) - -- this will be a plugin sequence - local what, where = match(errorstr,"LuaTeX error <main (%a+) instance>:(%d+)") - if what and where then + -- This does not work completely as we cannot access the last Lua error using + -- table.print(status.list()). This is on the agenda. Eventually we will + -- have a sequence of checks here (tex, lua, mp) at this end. + -- + -- Actually, in 0.75+ the lua error message is even weirder as you can + -- get: + -- + -- LuaTeX error [string "\directlua "]:3: unexpected symbol near '1' ... + -- + -- <inserted text> \endgroup \directlua { + -- + -- So there is some work to be done in the LuaTeX engine. + -- + local what, where = match(errorstr,[[LuaTeX error <main (%a+) instance>:(%d+)]]) + or match(errorstr,[[LuaTeX error %[string "\\(.-lua) "%]:(%d+)]]) -- buglet + if where then -- lua error: linenumber points to last line - local start, stop = "\\start" .. what .. "code", "\\stop" .. what .. "code" + local start = "\\startluacode" + local stop = "\\stopluacode" + local where = tonumber(where) if lines[linenumber] == start then local n = linenumber for i=n,1,-1 do if lines[i] == start then - local n = i + tonumber(where) + local n = i + where if n <= linenumber then linenumber = n end @@ -156,6 +169,7 @@ function tracers.printerror(offset) -- add a bit of spacing around our variant texio.write_nl("\n") local errorstr = status.lasterrorstring or "?" + -- inspect(status.list()) report_system("error on line %s in file %s: %s ...\n",linenumber,filename,errorstr) -- lua error? texio.write_nl(tracers.showlines(filename,linenumber,offset,errorstr),"\n") end diff --git a/tex/context/base/trac-log.lua b/tex/context/base/trac-log.lua index 1ea257bc3..0dadb855e 100644 --- a/tex/context/base/trac-log.lua +++ b/tex/context/base/trac-log.lua @@ -6,60 +6,60 @@ if not modules then modules = { } end modules ['trac-log'] = { license = "see context related readme files" } -if tex and (tex.jobname or tex.formatname) then - - -- quick hack, awaiting speedup in engine (8 -> 6.4 sec for --make with console2) - -- still needed for luajittex - - local texio_write_nl = texio.write_nl - local texio_write = texio.write - local io_write = io.write - - local write_nl = function(target,...) - if not io_write then - io_write = io.write - end - if target == "term and log" then - texio_write_nl("log",...) - texio_write_nl("term","") - io_write(...) - elseif target == "log" then - texio_write_nl("log",...) - elseif target == "term" then - texio_write_nl("term","") - io_write(...) - else - texio_write_nl("log",...) - texio_write_nl("term","") - io_write(...) - end - end - - local write = function(target,...) - if not io_write then - io_write = io.write - end - if target == "term and log" then - texio_write("log",...) - io_write(...) - elseif target == "log" then - texio_write("log",...) - elseif target == "term" then - io_write(...) - else - texio_write("log",...) - io_write(...) - end - end - - texio.write = write - texio.write_nl = write_nl - -else - - -- texlua or just lua - -end +-- if tex and (tex.jobname or tex.formatname) then +-- +-- -- quick hack, awaiting speedup in engine (8 -> 6.4 sec for --make with console2) +-- -- still needed for luajittex +-- +-- local texio_write_nl = texio.write_nl +-- local texio_write = texio.write +-- local io_write = io.write +-- +-- local write_nl = function(target,...) +-- if not io_write then +-- io_write = io.write +-- end +-- if target == "term and log" then +-- texio_write_nl("log",...) +-- texio_write_nl("term","") +-- io_write(...) +-- elseif target == "log" then +-- texio_write_nl("log",...) +-- elseif target == "term" then +-- texio_write_nl("term","") +-- io_write(...) +-- else +-- texio_write_nl("log",target,...) +-- texio_write_nl("term","") +-- io_write(target,...) +-- end +-- end +-- +-- local write = function(target,...) +-- if not io_write then +-- io_write = io.write +-- end +-- if target == "term and log" then +-- texio_write("log",...) +-- io_write(...) +-- elseif target == "log" then +-- texio_write("log",...) +-- elseif target == "term" then +-- io_write(...) +-- else +-- texio_write("log",target,...) +-- io_write(target,...) +-- end +-- end +-- +-- texio.write = write +-- texio.write_nl = write_nl +-- +-- else +-- +-- -- texlua or just lua +-- +-- end -- todo: less categories, more subcategories (e.g. nodes) -- todo: split into basics and ctx specific @@ -502,8 +502,10 @@ function logs.show() report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max) end -local delayed_reporters = { } setmetatableindex(delayed_reporters,function(t,k) - local v = logs.reporter(k) +local delayed_reporters = { } + +setmetatableindex(delayed_reporters,function(t,k) + local v = logs.reporter(k.name) t[k] = v return v end) diff --git a/tex/context/base/trac-set.lua b/tex/context/base/trac-set.lua index 6f91e25f7..95fdc43b3 100644 --- a/tex/context/base/trac-set.lua +++ b/tex/context/base/trac-set.lua @@ -33,7 +33,7 @@ function setters.initialize(filename,name,values) -- filename only for diagnosti local setter = data[name] if setter then frozen = true -- don't permitoverload --- trace_initialize = true + -- trace_initialize = true local data = setter.data if data then for key, newvalue in next, values do diff --git a/tex/context/base/trac-vis.lua b/tex/context/base/trac-vis.lua index 1727bddca..88d2c886e 100644 --- a/tex/context/base/trac-vis.lua +++ b/tex/context/base/trac-vis.lua @@ -196,13 +196,10 @@ local function enable() end local function setvisual(n,a,what) -- this will become more efficient when we have the bit lib linked in - if not a then - a = 0 - end if not n or n == "reset" then return unsetvalue elseif n == "makeup" then - if a == 0 then + if not a or a == 0 or a == unsetvalue then a = preset_makeup else a = setbit(a,preset_makeup) @@ -211,7 +208,7 @@ local function setvisual(n,a,what) -- this will become more efficient when we ha -- end end elseif n == "boxes" then - if a == 0 then + if not a or a == 0 or a == unsetvalue then a = preset_boxes else a = setbit(a,preset_boxes) @@ -222,7 +219,7 @@ local function setvisual(n,a,what) -- this will become more efficient when we ha elseif n == "all" then if what == false then return unsetvalue - elseif a == 0 then + elseif not a or a == 0 or a == unsetvalue then a = preset_all else a = setbit(a,preset_all) @@ -232,26 +229,24 @@ local function setvisual(n,a,what) -- this will become more efficient when we ha end else local m = modes[n] - if m then - if a == unsetvalue then - if what == false then - return unsetvalue - else - -- a = setbit(0,m) - a = m - end - elseif what == false then - a = clearbit(a,m) - elseif a == 0 then - a = m + if not m then + -- go on + elseif a == unsetvalue then + if what == false then + return unsetvalue else - a = setbit(a,m) + -- a = setbit(0,m) + a = m end - elseif not a then - return unsetvalue + elseif what == false then + a = clearbit(a,m) + elseif not a or a == 0 then + a = m + else + a = setbit(a,m) end end - if a == unsetvalue or a == 0 then + if not a or a == 0 or a == unsetvalue then return unsetvalue elseif not enabled then -- must happen at runtime (as we don't store layers yet) enable() diff --git a/tex/context/base/trac-vis.mkiv b/tex/context/base/trac-vis.mkiv index 4990913d7..fbc6ad6c4 100644 --- a/tex/context/base/trac-vis.mkiv +++ b/tex/context/base/trac-vis.mkiv @@ -39,7 +39,13 @@ \newconstant\c_syst_visualizers_state \newtoks \t_syst_visualizers_optimize -\definesystemattribute[visual][public,global] +\definesystemattribute[visual][public,global] % global ? + +% no, but can become an option: +% +% \appendtoks +% \attribute\visualattribute\attributeunsetvalue +% \to \everybeforepagebody %D We only provide box visualizers as they can come in handy for testing %D macros. In due time we will move some of the m-visual code here too. diff --git a/tex/context/base/type-imp-latinmodern.mkiv b/tex/context/base/type-imp-latinmodern.mkiv index f17f46e7d..b0e25e82c 100644 --- a/tex/context/base/type-imp-latinmodern.mkiv +++ b/tex/context/base/type-imp-latinmodern.mkiv @@ -168,10 +168,16 @@ \definefontsynonym [LMTypewriterVarWd-DarkOblique] [\s!file:lmmonoproplt10-boldoblique] [\s!features=\s!default] \stoptypescript +% \starttypescript [\s!math] [modern,latin-modern] +% \loadfontgoodies[lm] +% \definefontsynonym [LMMathRoman-Regular] [\v!file:latinmodern-math-regular.otf] [\s!features=\s!math\mathsizesuffix,\s!goodies=lm] +% \definefontsynonym [LMMathRoman-Bold] [\v!file:latinmodern-math-regular.otf] [\s!features=\s!math\mathsizesuffix,\s!goodies=lm] +% \stoptypescript + \starttypescript [\s!math] [modern,latin-modern] \loadfontgoodies[lm] - \definefontsynonym [LMMathRoman-Regular] [\v!file:latinmodern-math-regular.otf] [\s!features=\s!math\mathsizesuffix,\s!goodies=lm] - \definefontsynonym [LMMathRoman-Bold] [\v!file:latinmodern-math-regular.otf] [\s!features=\s!math\mathsizesuffix,\s!goodies=lm] + \definefontsynonym [LMMathRoman-Regular] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math},\s!goodies=lm] + \definefontsynonym [LMMathRoman-Bold] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math},\s!goodies=lm] \stoptypescript \starttypescript [modern-designsize-virtual] diff --git a/tex/context/base/typo-cap.lua b/tex/context/base/typo-cap.lua index 8f49580a4..fdbf2e353 100644 --- a/tex/context/base/typo-cap.lua +++ b/tex/context/base/typo-cap.lua @@ -29,6 +29,7 @@ local kerncodes = nodes.kerncodes local glyph_code = nodecodes.glyph local kern_code = nodecodes.kern +local math_code = nodecodes.math local kerning_code = kerncodes.kerning local userskip_code = skipcodes.userskip diff --git a/tex/context/base/typo-itc.lua b/tex/context/base/typo-itc.lua index 73d841aa3..b39ea2f23 100644 --- a/tex/context/base/typo-itc.lua +++ b/tex/context/base/typo-itc.lua @@ -20,6 +20,7 @@ local glyph_code = nodecodes.glyph local kern_code = nodecodes.kern local glue_code = nodecodes.glue local disc_code = nodecodes.disc +local math_code = nodecodes.math local tasks = nodes.tasks diff --git a/tex/context/base/typo-krn.lua b/tex/context/base/typo-krn.lua index cd50c205e..52c4c6521 100644 --- a/tex/context/base/typo-krn.lua +++ b/tex/context/base/typo-krn.lua @@ -40,6 +40,7 @@ local disc_code = nodecodes.disc local glue_code = nodecodes.glue local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist +local math_code = nodecodes.math local kerning_code = kerncodes.kerning local userkern_code = kerncodes.userkern diff --git a/tex/context/base/typo-spa.lua b/tex/context/base/typo-spa.lua index 619b3eddd..5eba22889 100644 --- a/tex/context/base/typo-spa.lua +++ b/tex/context/base/typo-spa.lua @@ -31,6 +31,7 @@ local v_reset = interfaces.variables.reset local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph +local math_code = nodecodes.math local somespace = nodes.somespace local somepenalty = nodes.somepenalty @@ -71,12 +72,14 @@ local function process(namespace,attribute,head) -- head is always begin of par (whatsit), so we have at least two prev nodes -- penalty followed by glue while start do - if start.id == glyph_code then + local id = start.id + if id == glyph_code then local attr = start[attribute] if attr and attr > 0 then local data = mapping[attr] if data then - local map = data.characters[start.char] + local char = start.char + local map = data.characters[char] start[attribute] = unsetvalue -- needed? if map then local left = map.left @@ -86,31 +89,31 @@ local function process(namespace,attribute,head) local prev = start.prev if left and left ~= 0 and prev then local ok = false + local prevprev = prev.prev if alternative == 1 then local somespace = somespace(prev,true) if somespace then - local prevprev = prev.prev local somepenalty = somepenalty(prevprev,10000) if somepenalty then if trace_spacing then - report_spacing("removing penalty and space before %C (left)",start.char) + report_spacing("removing penalty and space before %C (left)",char) end head = remove_node(head,prev,true) head = remove_node(head,prevprev,true) else if trace_spacing then - report_spacing("removing space before %C (left)",start.char) + report_spacing("removing space before %C (left)",char) end head = remove_node(head,prev,true) end end ok = true else - ok = not (somespace(prev,true) and somepenalty(prev.prev,true)) or somespace(prev,true) + ok = not (somespace(prev,true) and somepenalty(prevprev,true)) or somespace(prev,true) end if ok then if trace_spacing then - report_spacing("inserting penalty and space before %C (left)",start.char) + report_spacing("inserting penalty and space before %C (left)",char) end insert_node_before(head,start,new_penalty(10000)) insert_node_before(head,start,new_glue(left*quad)) @@ -120,14 +123,14 @@ local function process(namespace,attribute,head) local next = start.next if right and right ~= 0 and next then local ok = false + local nextnext = next.next if alternative == 1 then local somepenalty = somepenalty(next,10000) if somepenalty then - local nextnext = next.next local somespace = somespace(nextnext,true) if somespace then if trace_spacing then - report_spacing("removing penalty and space after %C right",start.char) + report_spacing("removing penalty and space after %C right",char) end head = remove_node(head,next,true) head = remove_node(head,nextnext,true) @@ -136,18 +139,18 @@ local function process(namespace,attribute,head) local somespace = somespace(next,true) if somespace then if trace_spacing then - report_spacing("removing space after %C (right)", start.char) + report_spacing("removing space after %C (right)", char) end head = remove_node(head,next,true) end end ok = true else - ok = not (somepenalty(next,10000) and somespace(next.next,true)) or somespace(next,true) + ok = not (somepenalty(next,10000) and somespace(nextnext,true)) or somespace(next,true) end if ok then if trace_spacing then - report_spacing("inserting penalty and space after %C (right)",start.char) + report_spacing("inserting penalty and space after %C (right)",char) end insert_node_after(head,start,new_glue(right*quad)) insert_node_after(head,start,new_penalty(10000)) diff --git a/tex/context/base/typo-spa.mkiv b/tex/context/base/typo-spa.mkiv index df2dab47c..d783353d6 100644 --- a/tex/context/base/typo-spa.mkiv +++ b/tex/context/base/typo-spa.mkiv @@ -22,6 +22,8 @@ % experimental spacing % % test: oeps {\setcharacterspacing[frenchpunctuation]x: xx \bfd x: xx} oeps: test +% +% todo: page | text => pagebody or text only \installcorenamespace{characterspacing} diff --git a/tex/context/base/util-lib.lua b/tex/context/base/util-lib.lua index c987bdde3..fde1f987e 100644 --- a/tex/context/base/util-lib.lua +++ b/tex/context/base/util-lib.lua @@ -37,15 +37,15 @@ In swiglib we have chosen for a clear organization and although one can use variants normally in the tex directory structure predictability is more or less the standard. For instance: -..../tex/texmf-mswin/bin/swiglib/gmwand +.../tex/texmf-mswin/bin/lib/luatex/lua/swiglib/mysql/core.dll +.../tex/texmf-mswin/bin/lib/luajittex/lua/swiglib/mysql/core.dll +.../tex/texmf-mswin/bin/lib/luatex/context/lua/swiglib/mysql/core.dll +.../tex/texmf-mswin/bin/lib/swiglib/lua/mysql/core.dll +.../tex/texmf-mswin/bin/lib/swiglib/lua/mysql/5.6/core.dll -]]-- - -local savedrequire = require -local loaded = package.loaded -local gsub, find = string.gsub, string.find +The lookups are determined via an entry in texmfcnf.lua: ---[[ +CLUAINPUTS = ".;$SELFAUTOLOC/lib/{$engine,luatex}/lua//", A request for t.e.x is converted to t/e/x.dll or t/e/x.so depending on the platform. Then we use the regular finder to locate the file in the tex @@ -53,38 +53,123 @@ directory structure. Once located we goto the path where it sits, load the file and return to the original path. We register as t.e.x in order to prevent reloading and also because the base name is seldom unique. +The main function is a big one and evolved out of experiments that Luigi +Scarso and I conducted when playing with variants of SwigLib. The function +locates the library using the context mkiv resolver that operates on the +tds tree and if that doesn't work out well, the normal clib path is used. + +The lookups is somewhat clever in the sense that it can deal with (optional) +versions and can fall back on non versioned alternatives if needed, either +or not using a wildcard lookup. + +This code is experimental and by providing a special abstract loader (called +swiglib) we can start using the libraries. + ]]-- -local function requireswiglib(required) +-- seems to be clua in recent texlive + +local gsub, find = string.gsub, string.find +local pathpart, nameonly, joinfile = file.pathpart, file.nameonly, file.join +local findfile, findfiles = resolvers and resolvers.findfile, resolvers and resolvers.findfiles + +local loaded = package.loaded + +local report_swiglib = logs.reporter("swiglib") +local trace_swiglib = false trackers.register("resolvers.swiglib", function(v) trace_swiglib = v end) + +-- We can check if there are more that one component, and if not, we can +-- append 'core'. + +local function requireswiglib(required,version) local library = loaded[required] - if not library then - local name = gsub(required,"%.","/") .. "." .. os.libsuffix - local full = resolvers.findfile(name,"lib") - -- local full = resolvers.findfile(name) - if not full or full == "" then - -- We can consider alternatives but we cannot load yet ... I - -- need to extent l-lua with a helper if we really want that. - -- - -- package.helpers.trace = true - -- package.extraclibpath(environment.ownpath) + if library == nil then + -- initialize a few variables + local required_full = gsub(required,"%.","/") + local required_path = pathpart(required_full) + local required_base = nameonly(required_full) + local required_name = required_base .. "." .. os.libsuffix + local version = type(version) == "string" and version ~= "" and version or false + -- helper + local function check(locate,...) + local found_library = nil + if version then + local asked_library = joinfile(required_path,version,required_name) + if trace_swiglib then + report_swiglib("checking %s: %a","with version",asked_library) + end + found_library = locate(asked_library,...) + if not found_library or found_library == ""then + asked_library = joinfile(required_path,required_name) + if trace_swiglib then + report_swiglib("checking %s: %a","without version",asked_library) + end + found_library = locate(asked_library,...) + end + else + local asked_library = joinfile(required_path,required_name) + if trace_swiglib then + report_swiglib("checking %s: %a","without version",asked_library) + end + found_library = locate(asked_library,...) + end + return found_library and found_library ~= "" and found_library or false + end + -- check cnf spec using name and version + local found_library = findfile and check(findfile,"lib") + -- check cnf spec using wildcard + if findfiles and not found_library then + local asked_library = joinfile(required_path,".*",required_name) + if trace_swiglib then + report_swiglib("checking %s: %a","latest version",asked_library) + end + local list = findfiles(asked_library,"lib",true) + if list and #list > 0 then + table.sort(list) + found_library = list[#list] + end + end + -- check clib paths using name and version + if not found_library then + package.extraclibpath(environment.ownpath) + local paths = package.clibpaths() + for i=1,#paths do + local found_library = check(lfs.isfile) + if found_library then + break + end + end end - local path = file.pathpart(full) - local base = file.nameonly(full) - dir.push(path) - -- if false then - -- local savedlibrary = loaded[base] - -- library = savedrequire(base) - -- loaded[base] = savedlibrary - -- else - library = package.loadlib(full,"luaopen_" .. base) + -- load and initialize when found + if not found_library then + if trace_swiglib then + report_swiglib("not found: %a",asked_library) + end + library = false + else + local path = pathpart(found_library) + local base = nameonly(found_library) + dir.push(path) + if trace_swiglib then + report_swiglib("found: %a",found_library) + end + library = package.loadlib(found_library,"luaopen_" .. required_base) if type(library) == "function" then library = library() else - -- some error + library = false end - -- end - dir.pop() + dir.pop() + end + -- cache result + if not library then + report_swiglib("unknown: %a",required) + elseif trace_swiglib then + report_swiglib("stored: %a",required) + end loaded[required] = library + else + report_swiglib("reused: %a",required) end return library end @@ -96,31 +181,32 @@ we could put the specific loader in the global namespace. ]]-- -function require(name,...) -- this might disappear or change +local savedrequire = require + +function require(name,version) if find(name,"^swiglib%.") then - return requireswiglib(name,...) + return requireswiglib(name,version) else - return savedrequire(name,...) + return savedrequire(name) end end --[[ At the cost of some overhead we provide a specific loader so that we can keep -track of swiglib usage which is handy for development. +track of swiglib usage which is handy for development. In context this is the +recommended loader. ]]-- -local report_swiglib = logs.reporter("swiglib") - local swiglibs = { } -function swiglib(name) +function swiglib(name,version) local library = swiglibs[name] if not library then statistics.starttiming(swiglibs) report_swiglib("loading %a",name) - library = requireswiglib("swiglib." .. name) + library = requireswiglib("swiglib." .. name,version) swiglibs[name] = library statistics.stoptiming(swiglibs) end @@ -137,9 +223,10 @@ end) So, we now have: ------ gm = requireswiglib("swiglib.gmwand.core") -- most bare method (not public in context) -local gm = require("swiglib.gmwand.core") -- nicer integrated (maybe not in context) -local gm = swiglib("gmwand.core") -- the context way +local gm = require("swiglib.gmwand.core") +local gm = swiglib("gmwand.core") +local sq = swiglib("mysql.core") +local sq = swiglib("mysql.core","5.6") Watch out, the last one is less explicit and lacks the swiglib prefix. diff --git a/tex/context/base/util-sql-imp-swiglib.lua b/tex/context/base/util-sql-imp-swiglib.lua index 15fbe2487..9a22477a9 100644 --- a/tex/context/base/util-sql-imp-swiglib.lua +++ b/tex/context/base/util-sql-imp-swiglib.lua @@ -15,13 +15,20 @@ local concat = table.concat local format = string.format local lpegmatch = lpeg.match local setmetatable, type = setmetatable, type +local sleep = os.sleep local trace_sql = false trackers.register("sql.trace", function(v) trace_sql = v end) local trace_queries = false trackers.register("sql.queries",function(v) trace_queries = v end) local report_state = logs.reporter("sql","swiglib") local sql = utilities.sql -local mysql = require("swigluamysql") +local mysql = require("swiglib.mysql.core") -- "5.6" + +-- inspect(table.sortedkeys(mysql)) + +local nofretries = 5 +local retrydelay = 1 + local cache = { } local helpers = sql.helpers local methods = sql.methods @@ -53,15 +60,28 @@ local mysql_options_argument = mysql.mysql_options_argument local instance = mysql.MYSQL() -local mysql_constant_false = mysql_options_argument(false) -- 0 "\0" -local mysql_constant_true = mysql_options_argument(true) -- 1 "\1" - --- print(swig_type(mysql_constant_false)) --- print(swig_type(mysql_constant_true)) - -mysql.mysql_options(instance,mysql.MYSQL_OPT_RECONNECT,mysql_constant_true); +local mysql_constant_false = false +local mysql_constant_true = true + +-- if mysql_options_argument then +-- +-- mysql_constant_false = mysql_options_argument(false) -- 0 "\0" +-- mysql_constant_true = mysql_options_argument(true) -- 1 "\1" +-- +-- -- print(swig_type(mysql_constant_false)) +-- -- print(swig_type(mysql_constant_true)) +-- +-- mysql.mysql_options(instance,mysql.MYSQL_OPT_RECONNECT,mysql_constant_true); +-- +-- else +-- +-- print("") +-- print("incomplete swiglib.mysql interface") +-- print("") +-- +-- end -local typemap = { +local typemap = mysql.MYSQL_TYPE_VAR_STRING and { [mysql.MYSQL_TYPE_VAR_STRING ] = "string", [mysql.MYSQL_TYPE_STRING ] = "string", [mysql.MYSQL_TYPE_DECIMAL ] = "number", @@ -272,6 +292,16 @@ local function connect(session,specification) ) end +local function error_in_connection(specification,action) + report_state("error in connection: [%s] %s@%s to %s:%s", + action or "unknown", + specification.database or "no database", + specification.username or "no username", + specification.host or "no host", + specification.port or "no port" + ) +end + local function datafetched(specification,query,converter) if not query or query == "" then report_state("no valid query") @@ -288,11 +318,45 @@ local function datafetched(specification,query,converter) if not connection then session = initialize() connection = connect(session,specification) - cache[id] = { session = session, connection = connection } + if not connection then + for i=1,nofretries do + sleep(retrydelay) + report_state("retrying to connect: [%s.%s] %s@%s to %s:%s", + id,i, + specification.database or "no database", + specification.username or "no username", + specification.host or "no host", + specification.port or "no port" + ) + connection = connect(session,specification) + if connection then + break + end + end + end + if connection then + cache[id] = { session = session, connection = connection } + end end else session = initialize() connection = connect(session,specification) + if not connection then + for i=1,nofretries do + sleep(retrydelay) + report_state("retrying to connect: [%s] %s@%s to %s:%s", + i, + specification.database or "no database", + specification.username or "no username", + specification.host or "no host", + specification.port or "no port" + ) + connection = connect(session,specification) + if connection then + break + end + end + end end if not connection then report_state("error in connection: %s@%s to %s:%s", diff --git a/tex/context/base/x-steps.mkiv b/tex/context/base/x-steps.mkiv new file mode 100644 index 000000000..29b3f7eaa --- /dev/null +++ b/tex/context/base/x-steps.mkiv @@ -0,0 +1,102 @@ +%D \module +%D [ file=m-steps, +%D version=2001.05.28, +%D title=\CONTEXT\ Modules, +%D subtitle=Step Charts \& Tables, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D The \XML\ interface. This module can be made way more efficient +%D in \MKIV\ using textext but it makes only sense to do this when +%D I really need it in a demanding application. Probably half of the +%D code in m-steps.tex can go. + +\usemodule[m][steps] + +\unprotect + +\installcorenamespace {xmlstepchart} +\installcorenamespace {xmlsteptable} + +\def\xmlstepchartdirective#1{\executeifdefined{\??xmlstepchart#1}\gobbletwoarguments} % {#2}{#3} +\def\xmlsteptabledirective#1{\executeifdefined{\??xmlsteptable#1}\gobbletwoarguments} % {#2}{#3} + +\setvalue{\??xmlstepchart charts}{\setsomevalue\@@STPC} +\setvalue{\??xmlstepchart cells}{\setsomevalue\@@STEC} +\setvalue{\??xmlstepchart texts}{\setsomevalue\@@STET} +\setvalue{\??xmlstepchart lines}{\setsomevalue\@@STEL} + +\setvalue{\??xmlsteptable tables}{\setsomevalue\@@STPT} +\setvalue{\??xmlsteptable cells}{\setsomevalue\@@STEC} +\setvalue{\??xmlsteptable texts}{\setsomevalue\@@STET} +\setvalue{\??xmlsteptable lines}{\setsomevalue\@@STEL} + +\startxmlsetups xml:ct:define + \xmlsetsetup {#1} {ct:*} {xml:ct:*} + % \xmlsetsetup {#1} {ct:stepaligntable/cells} {xml:ct:stepaligntable:cells} + % \xmlsetsetup {#1} {ct:stepaligntable/lines} {xml:ct:stepaligntable:lines} +\stopxmlsetups + +\xmlregisterns{ct}{stepcharts} + +\xmlregistersetup{xml:ct:define} + +\startxmlsetups xml:ct:prep + \expanded{\prep[\xmltoparameters{#1}]}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:ct:text + \expanded{\text[\xmltoparameters{#1}]}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:ct:texts + \expanded{\texts[\xmltoparameters{#1}]}{\xmltext{#1}{/top}} {\xmltext{#1}{/bot}} +\stopxmlsetups + +\startxmlsetups xml:ct:cell + \expanded{\cell[\xmltoparameters{#1}]}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:ct:cells + \expanded{\cells[\xmltoparameters{#1}]}{\xmltext{#1}{/top}} {\xmltext{#1}{/bot}} +\stopxmlsetups + +\startxmlsetups xml:ct:lines + \expanded{\startlines[\xmltoparameters{#1}]} + \xmlflush{#1} + \stoplines +\stopxmlsetups + +\startxmlsetups xml:ct:steptable + \expanded{\startSTEPtable[\xmltoparameters{#1}]} + \xmlflush{#1} + \stopSTEPtable +\stopxmlsetups + +\startxmlsetups xml:ct:stepchart + \expanded{\startSTEPchart[\xmltoparameters{#1}]} + \xmlflush{#1} + \stopSTEPchart +\stopxmlsetups + +% \startxmlsetups xml:ct:stepaligntable +% \expanded{\startSTEPaligntable[\xmltoparameters{#1}]} +% \xmlflush{#1} +% \stopSTEPaligntable +% \stopxmlsetups +% +% \startxmlsetups xml:ct:stepaligntable:cells +% \expanded{\cells[\xmltoparameters{#1}]} {\xmltext{#1}{/ct:c1}} {\xmltext{#1}{/ct:c2}} {\xmltext{#1}{/ct:c3}} +% \stopxmlsetups +% +% \startxmlsetups xml:ct:stepaligntable:lines +% \expanded{\setupSTEPlines[\xmltoparameters{#1}]} +% \xmlflush{#1} +% \stopxmlsetups + +\protect \endinput diff --git a/tex/context/fonts/lm.lfg b/tex/context/fonts/lm.lfg index 5f78eddfd..792e723e8 100644 --- a/tex/context/fonts/lm.lfg +++ b/tex/context/fonts/lm.lfg @@ -13,6 +13,28 @@ return { mathematics.tweaks.fixbadprime, -- prime is too low }, }, + dimensions = { + -- always applied +-- default = { +-- }, + -- driven by 'mathdimensions' feature + signs = { + -- set dimensions + -- [0x00B1] = { -- ± + -- height = 500, depth = 0, + -- }, + -- [0x2213] = { -- ∓ + -- height = 500, depth = 0, + -- }, + -- move in boundingbox + [0x00B1] = { -- ± + yoffset = 100, + }, + [0x2213] = { -- ∓ + yoffset = -100, + }, + } + } }, filenames = { ["latinmodern-math-regular.otf"] = { diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 820ea3852..d1b4bcda9 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 04/02/13 11:22:33 +-- merge date : 04/05/13 22:00:23 do -- begin closure to overcome local limits and interference @@ -123,7 +123,7 @@ local function addpath(what,paths,extras,hash,...) local path=cleanpath(path) if not hash[path] then if trace then - report("! extra %s path: %s",what,path) + report("extra %s path: %s",what,path) end paths [#paths+1]=path extras[#extras+1]=path @@ -157,13 +157,13 @@ searchers[3]=nil local function loadedaslib(resolved,rawname) local init="luaopen_"..gsub(rawname,"%.","_") if helpers.trace then - helpers.report("! calling loadlib with '%s' with init '%s'",resolved,init) + helpers.report("calling loadlib with '%s' with init '%s'",resolved,init) end return package.loadlib(resolved,init) end local function loadedbylua(name) if helpers.trace then - helpers.report("! locating '%s' using normal loader",name) + helpers.report("locating '%s' using normal loader",name) end return true,searchers[-2](name) end @@ -171,17 +171,17 @@ local function loadedbypath(name,rawname,paths,islib,what) local trace=helpers.trace local report=helpers.report if trace then - report("! locating '%s' as '%s' on '%s' paths",rawname,name,what) + report("locating '%s' as '%s' on '%s' paths",rawname,name,what) end for p=1,#paths do local path=paths[p] local resolved=filejoin(path,name) if trace then - report("! checking for '%s' using '%s' path '%s'",name,what,path) + report("checking for '%s' using '%s' path '%s'",name,what,path) end if isreadable(resolved) then if trace then - report("! lib '%s' located on '%s'",name,resolved) + report("lib '%s' located on '%s'",name,resolved) end if islib then return true,loadedaslib(resolved,rawname) @@ -10704,6 +10704,19 @@ function definers.loadfont(specification) end return tfmdata end +local function checkvirtual(tfmdata) + local fonts=tfmdata.fonts + local selfid=font.nextid() + if fonts and #fonts>0 then + for i=1,#fonts do + if fonts[i][2]==0 then + fonts[i][2]=selfid + end + end + else + tfmdata.fonts={ "id",selfid } + end +end function constructors.readanddefine(name,size) local specification=definers.analyze(name,size) local method=specification.method @@ -10716,7 +10729,7 @@ function constructors.readanddefine(name,size) if not id then local tfmdata=definers.loadfont(specification) if tfmdata then - tfmdata.properties.hash=hash + checkvirtual(tfmdata) id=font.define(tfmdata) definers.register(tfmdata,id) else diff --git a/tex/generic/context/luatex/luatex-swiglib-test.lua b/tex/generic/context/luatex/luatex-swiglib-test.lua new file mode 100644 index 000000000..db6a72909 --- /dev/null +++ b/tex/generic/context/luatex/luatex-swiglib-test.lua @@ -0,0 +1,25 @@ +local gm = swiglib("gmwand.core") + +gm.InitializeMagick(".") + +local magick_wand = gm.NewMagickWand() +local drawing_wand = gm.NewDrawingWand() + +gm.MagickSetSize(magick_wand,800,600) +gm.MagickReadImage(magick_wand,"xc:red") + +gm.DrawPushGraphicContext(drawing_wand) + +gm.DrawSetFillColor(drawing_wand,gm.NewPixelWand()) + +-- gm.DrawSetFont(drawing_wand, kpse.findfile("DejaVuSerifBold.ttf")) +-- gm.DrawSetFontSize(drawing_wand, 96) +-- gm.DrawAnnotation(drawing_wand,300,200, "LuaTeX") + +gm.DrawPopGraphicContext(drawing_wand) +gm.MagickDrawImage(magick_wand,drawing_wand) + +gm.MagickWriteImages(magick_wand,"./luatex-swiglib-test.jpg",1) + +gm.DestroyDrawingWand(drawing_wand) +gm.DestroyMagickWand(magick_wand) diff --git a/tex/generic/context/luatex/luatex-swiglib-test.tex b/tex/generic/context/luatex/luatex-swiglib-test.tex new file mode 100644 index 000000000..d26bb6ffb --- /dev/null +++ b/tex/generic/context/luatex/luatex-swiglib-test.tex @@ -0,0 +1,11 @@ +% luatex --fmt=luatex=plain luatex-swiglib-test.tex + +\input luatex-swiglib.tex + +\directlua { + dofile("luatex-swiglib-test.lua") +} + +\pdfximage {luatex-swiglib-test.jpg} \pdfrefximage\pdflastximage + +\end diff --git a/tex/generic/context/luatex/luatex-swiglib.lua b/tex/generic/context/luatex/luatex-swiglib.lua new file mode 100644 index 000000000..7ffcdc375 --- /dev/null +++ b/tex/generic/context/luatex/luatex-swiglib.lua @@ -0,0 +1,62 @@ +if not modules then modules = { } end modules ['luatex-swiglib'] = { + version = 1.001, + comment = "companion to luatex-swiglib.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local savedrequire = require + +local libsuffix = os.type == "windows" and ".dll" or ".so" + +function requireswiglib(required,version) + local library = package.loaded[required] + if library then + return library + else + local name = string.gsub(required,"%.","/") .. libsuffix + local list = kpse.show_path("clua") + for root in string.gmatch(list,"([^;]+)") do + local full = false + if type(version) == "string" and version ~= "" then + full = root .. "/" .. version .. "/" .. name + full = lfs.isfile(full) and full + end + if not full then + full = root .. "/" .. name + full = lfs.isfile(full) and full + end + if full then + local path, base = string.match(full,"^(.-)([^\\/]+)" .. libsuffix .."$") + local savedlibrary = package.loaded[base] + package.loaded[base] = nil + local savedpath = lfs.currentdir() + lfs.chdir(path) + library = package.loadlib(full,"luaopen_" .. base) + if type(library) == "function" then + library = library() + texio.write("<swiglib: '",required,"' is loaded>") + end + lfs.chdir(savedpath) + package.loaded[base] = savedlibrary + package.loaded[required] = library + return library + end + end + texio.write("<swiglib: '",name,"'is not found on '",list,"'") + end + texio.write("<swiglib: '",required,"' is not found>") +end + +function require(name) + if string.find(name,"^swiglib%.") then + return requireswiglib(name) + else + return savedrequire(name) + end +end + +function swiglib(name,version) + return requireswiglib("swiglib." .. name,version) +end diff --git a/tex/generic/context/luatex/luatex-swiglib.tex b/tex/generic/context/luatex/luatex-swiglib.tex new file mode 100644 index 000000000..7c4377515 --- /dev/null +++ b/tex/generic/context/luatex/luatex-swiglib.tex @@ -0,0 +1,20 @@ +%D \module +%D [ file=luatex-swiglib, +%D version=2013.03.30, +%D title=\LUATEX\ Support Macros, +%D subtitle=Generic \SWIGLIB\ Font Handler, +%D author=Hans Hagen, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] + +%D This is an experimental setup. Usage: +%D +%D \starttyping +%D local gm = swiglib("gmwand.core") +%D local gm = require("swiglib.gmwand.core") +%D local sq = swiglib("mysql.core") +%D local sq = swiglib("mysql.core","5.6") +%D \stoptyping + +\directlua { + dofile(kpse.find_file("luatex-swiglib.lua","tex")) +} |