summaryrefslogtreecommitdiff
path: root/tex/context/base
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2017-06-16 16:00:40 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2017-06-16 16:00:40 +0200
commit008292817580eba8a0f0cf83d8e2d08df8fc8c3f (patch)
tree7e47d035cc5d1f54d20f556476c439844f1956e0 /tex/context/base
parent5e668aa418d6d082446e9369ae06625b50e49943 (diff)
downloadcontext-008292817580eba8a0f0cf83d8e2d08df8fc8c3f.tar.gz
2017-06-15 22:16:00
Diffstat (limited to 'tex/context/base')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/char-def.lua2
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/cont-run.lua2
-rw-r--r--tex/context/base/mkiv/cont-run.mkiv5
-rw-r--r--tex/context/base/mkiv/context.mkiv4
-rw-r--r--tex/context/base/mkiv/enco-ini.mkiv25
-rw-r--r--tex/context/base/mkiv/font-con.lua2
-rw-r--r--tex/context/base/mkiv/font-dsp.lua42
-rw-r--r--tex/context/base/mkiv/font-mis.lua2
-rw-r--r--tex/context/base/mkiv/font-otl.lua2
-rw-r--r--tex/context/base/mkiv/font-otr.lua2
-rw-r--r--tex/context/base/mkiv/font-ots.lua341
-rw-r--r--tex/context/base/mkiv/font-oup.lua3
-rw-r--r--tex/context/base/mkiv/font-run.mkiv2
-rw-r--r--tex/context/base/mkiv/grph-inc.mkiv26
-rw-r--r--tex/context/base/mkiv/lang-txt.lua2
-rw-r--r--tex/context/base/mkiv/lpdf-xmp.lua3
-rw-r--r--tex/context/base/mkiv/luat-cod.lua32
-rw-r--r--tex/context/base/mkiv/luat-ini.lua4
-rw-r--r--tex/context/base/mkiv/luat-run.lua27
-rw-r--r--tex/context/base/mkiv/math-acc.mkvi6
-rw-r--r--tex/context/base/mkiv/math-act.lua13
-rw-r--r--tex/context/base/mkiv/math-ali.mkiv166
-rw-r--r--tex/context/base/mkiv/math-fbk.lua12
-rw-r--r--tex/context/base/mkiv/math-frc.mkiv1
-rw-r--r--tex/context/base/mkiv/math-ini.mkiv1
-rw-r--r--tex/context/base/mkiv/math-noa.lua22
-rw-r--r--tex/context/base/mkiv/math-spa.lua89
-rw-r--r--tex/context/base/mkiv/mtx-context-domotica.tex30
-rw-r--r--tex/context/base/mkiv/mult-low.lua5
-rw-r--r--tex/context/base/mkiv/node-pro.lua22
-rw-r--r--tex/context/base/mkiv/node-syn.lua108
-rw-r--r--tex/context/base/mkiv/scrn-wid.mkvi6
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin25675 -> 25695 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin424652 -> 424912 bytes
-rw-r--r--tex/context/base/mkiv/strc-mat.mkiv47
-rw-r--r--tex/context/base/mkiv/syst-ini.mkiv34
-rw-r--r--tex/context/base/mkiv/task-ini.lua1
-rw-r--r--tex/context/base/mkiv/trac-inf.lua8
-rw-r--r--tex/context/base/mkiv/trac-tex.lua8
-rw-r--r--tex/context/base/mkiv/typo-bld.lua5
-rw-r--r--tex/context/base/mkiv/util-env.lua86
-rw-r--r--tex/context/base/mkiv/util-lib.lua31
-rw-r--r--tex/context/base/mkiv/util-sql-imp-ffi.lua555
-rw-r--r--tex/context/base/mkiv/util-sql.lua10
47 files changed, 1229 insertions, 571 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 1935fc5e2..739813901 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2017.06.06 13:22}
+\newcontextversion{2017.06.15 22:10}
%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/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index c000f8918..d5240d162 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.06.06 13:22}
+\edef\contextversion{2017.06.15 22:10}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/char-def.lua b/tex/context/base/mkiv/char-def.lua
index 76c51a6b4..023515a8d 100644
--- a/tex/context/base/mkiv/char-def.lua
+++ b/tex/context/base/mkiv/char-def.lua
@@ -7813,7 +7813,7 @@ characters.data={
direction="on",
linebreak="ai",
mathclass="topaccent",
- mathname="mathring",
+ mathname="ring",
specials={ "compat", 0x20, 0x30A },
unicodeslot=0x2DA,
},
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 6f78ecbb8..d8924d37a 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2017.06.06 13:22}
+\newcontextversion{2017.06.15 22:10}
%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/mkiv/cont-run.lua b/tex/context/base/mkiv/cont-run.lua
index 2225a0fb2..ee86c6a18 100644
--- a/tex/context/base/mkiv/cont-run.lua
+++ b/tex/context/base/mkiv/cont-run.lua
@@ -181,7 +181,7 @@ local function processjob()
local filename = environment.filename -- hm, not inputfilename !
if arguments.synctex then
- directives.enable("system.synctex="..tostring(arguments.synctex))
+ directives.enable("system.synctex")
end
if not filename or filename == "" then
diff --git a/tex/context/base/mkiv/cont-run.mkiv b/tex/context/base/mkiv/cont-run.mkiv
index 68b2f635f..07154196f 100644
--- a/tex/context/base/mkiv/cont-run.mkiv
+++ b/tex/context/base/mkiv/cont-run.mkiv
@@ -26,6 +26,11 @@
\let\synctexsetfilename \clf_synctexsetfilename
\let\synctexresetfilename\clf_synctexresetfilename
\let\synctexblockfilename\clf_synctexblockfilename
+\let\synctexpause \clf_synctexpause
+\let\synctexresume \clf_synctexresume
+
+\appendtoks\clf_synctexpause \to\everybeforeoutput
+\appendtoks\clf_synctexresume\to\everyafteroutput
\unexpanded\def\setupsynctex[#1]%
{\begingroup
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 48bd46739..ab9a40429 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -22,6 +22,8 @@
% on network shares cq. when no files are cached by the os it's of course
% much worse. A zero run is .27 sec with luajittex.
+% http://build.contextgarden.net/waterfall?tag=c/luatex
+
% Welcome to context, pronounced as kontekst (rather dutch) and not as
% conτεχt.
@@ -39,7 +41,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.06.06 13:22}
+\edef\contextversion{2017.06.15 22:10}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/enco-ini.mkiv b/tex/context/base/mkiv/enco-ini.mkiv
index 50375251a..f1428e7c2 100644
--- a/tex/context/base/mkiv/enco-ini.mkiv
+++ b/tex/context/base/mkiv/enco-ini.mkiv
@@ -543,4 +543,29 @@
\let\buildtextaccent\secondoftwoarguments
\to \everysimplifycommands
+%D A plain one:
+
+% \unexpanded\def\t#1{%
+% \dontleavehmode
+% \begingroup
+% \setbox\scratchboxone\hpack{#1}%
+% \setbox\scratchboxtwo\hpack\bgroup
+% \iffontchar\font"0361\relax
+% \char"0361\relax
+% \else
+% \iffontchar\font"2040\relax\else
+% \the\textfont0
+% \fi
+% \char"2040
+% \fi
+% \egroup
+% \scratchdimenone\wd\ifdim\wd\scratchboxone>\wd\scratchboxtwo\scratchboxone\else\scratchboxtwo\fi
+% \scratchdimentwo\dimexpr-\ht\scratchboxtwo+\ht\scratchboxone+.45\exheight\relax
+% \hpack to \scratchdimenone\bgroup
+% \hpack to \scratchdimenone{\hss\box\scratchboxone\hss}%
+% \hskip -\scratchdimenone
+% \hpack to \scratchdimenone{\hss\raise\scratchdimentwo\box\scratchboxtwo\hss}%
+% \egroup
+% \endgroup}
+
\protect \endinput
diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua
index 5a19d84ee..7287fe017 100644
--- a/tex/context/base/mkiv/font-con.lua
+++ b/tex/context/base/mkiv/font-con.lua
@@ -809,7 +809,7 @@ function constructors.scale(tfmdata,specification)
--
constructors.trytosharefont(target,tfmdata)
--
- -- catch incosnistencies
+ -- catch inconsistencies
--
local vfonts = target.fonts
if isvirtual then
diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua
index b46e1b82c..f4f04d87e 100644
--- a/tex/context/base/mkiv/font-dsp.lua
+++ b/tex/context/base/mkiv/font-dsp.lua
@@ -1393,12 +1393,14 @@ function gsubhandlers.reversechainedcontextsingle(f,fontdata,lookupid,lookupoffs
before = readcoveragearray(f,tableoffset,before,true)
after = readcoveragearray(f,tableoffset,after,true)
return {
- coverage = {
- format = "reversecoverage", -- reversesub
- before = before,
- current = current,
- after = after,
- replacements = replacements,
+ format = "reversecoverage", -- reversesub
+ rules = {
+ {
+ before = before,
+ current = current,
+ after = after,
+ replacements = replacements,
+ }
}
}, "reversechainedcontextsingle"
else
@@ -2091,10 +2093,11 @@ do
local rules = step.rules
if rules then
for i=1,#rules do
- local rule = rules[i]
- local before = rule.before
- local current = rule.current
- local after = rule.after
+ local rule = rules[i]
+ local before = rule.before
+ local current = rule.current
+ local after = rule.after
+ local replacements = rule.replacements
if before then
for i=1,#before do
before[i] = tohash(before[i])
@@ -2103,8 +2106,23 @@ do
rule.before = reversed(before)
end
if current then
- for i=1,#current do
- current[i] = tohash(current[i])
+ if replacements then
+ -- We have a reverse lookup and therefore only one current entry. We might need
+ -- to reverse the order in the before and after lists so that needs checking.
+ local first = current[1]
+ local hash = { }
+ local repl = { }
+ for i=1,#first do
+ local c = first[i]
+ hash[c] = true
+ repl[c] = replacements[i]
+ end
+ rule.current = { hash }
+ rule.replacements = repl
+ else
+ for i=1,#current do
+ current[i] = tohash(current[i])
+ end
end
end
if after then
diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua
index 6d5c9fbf2..5e4da74e3 100644
--- a/tex/context/base/mkiv/font-mis.lua
+++ b/tex/context/base/mkiv/font-mis.lua
@@ -21,7 +21,7 @@ local readers = otf.readers
if readers then
- otf.version = otf.version or 3.029
+ otf.version = otf.version or 3.030
otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true)
function fonts.helpers.getfeatures(name,save)
diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua
index ee57d1d8f..c8006316f 100644
--- a/tex/context/base/mkiv/font-otl.lua
+++ b/tex/context/base/mkiv/font-otl.lua
@@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading")
local fonts = fonts
local otf = fonts.handlers.otf
-otf.version = 3.029 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.030 -- beware: also sync font-mis.lua and in mtx-fonts
otf.cache = containers.define("fonts", "otl", otf.version, true)
otf.svgcache = containers.define("fonts", "svg", otf.version, true)
otf.sbixcache = containers.define("fonts", "sbix", otf.version, true)
diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua
index 4f93c5579..bff81aa87 100644
--- a/tex/context/base/mkiv/font-otr.lua
+++ b/tex/context/base/mkiv/font-otr.lua
@@ -660,12 +660,10 @@ local widths = {
setmetatableindex(weights, function(t,k)
local r = floor((k + 50) / 100) * 100
local v = (r > 900 and "black") or rawget(t,r) or "normal"
--- print("weight:",k,r,v)
return v
end)
setmetatableindex(widths,function(t,k)
--- print("width:",k)
return "normal"
end)
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index bd54b61c9..726899571 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -283,12 +283,12 @@ local checkstep = (tracers and tracers.steppers.check) or function()
local registerstep = (tracers and tracers.steppers.register) or function() end
local registermessage = (tracers and tracers.steppers.message) or function() end
-local function checkdisccontent(d)
- local pre, post, replace = getdisc(d)
- if pre then for n in traverse_id(glue_code,pre) do print("pre",nodes.idstostring(pre)) break end end
- if post then for n in traverse_id(glue_code,post) do print("pos",nodes.idstostring(post)) break end end
- if replace then for n in traverse_id(glue_code,replace) do print("rep",nodes.idstostring(replace)) break end end
-end
+-- local function checkdisccontent(d)
+-- local pre, post, replace = getdisc(d)
+-- if pre then for n in traverse_id(glue_code,pre) do print("pre",nodes.idstostring(pre)) break end end
+-- if post then for n in traverse_id(glue_code,post) do print("pos",nodes.idstostring(post)) break end end
+-- if replace then for n in traverse_id(glue_code,replace) do print("rep",nodes.idstostring(replace)) break end end
+-- end
local function logprocess(...)
if trace_steps then
@@ -391,7 +391,7 @@ local function flattendisk(head,disc)
elseif next then
return next, next
else
- return -- maybe warning
+ -- return -- maybe warning
end
else
if replace then
@@ -469,123 +469,6 @@ local function markstoligature(head,start,stop,char)
end
end
--- local function toligature(head,start,stop,char,dataset,sequence,markflag,discfound) -- brr head
--- if getattr(start,a_noligature) == 1 then
--- -- so we can do: e\noligature{ff}e e\noligature{f}fie (we only look at the first)
--- return head, start
--- end
--- if start == stop and getchar(start) == char then
--- resetinjection(start)
--- setchar(start,char)
--- return head, start
--- end
--- local prev = getprev(start)
--- local next = getnext(stop)
--- local comp = start
--- setprev(start)
--- setnext(stop)
--- local base = copy_no_components(start,copyinjection)
--- if start == head then
--- head = base
--- end
--- resetinjection(base)
--- setchar(base,char)
--- setsubtype(base,ligature_code)
--- set_components(base,comp)
--- setlink(prev,base,next)
--- if not discfound then
--- local deletemarks = markflag ~= "mark"
--- local components = start
--- local baseindex = 0
--- local componentindex = 0
--- local head = base
--- local current = base
--- -- first we loop over the glyphs in start .. stop
--- while start do
--- local char = getchar(start)
--- if not marks[char] then
--- baseindex = baseindex + componentindex
--- componentindex = getcomponentindex(start,marks)
--- elseif not deletemarks then -- quite fishy
--- setligaindex(start,baseindex + getligaindex(start,componentindex))
--- if trace_marks then
--- logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
--- end
--- local n = copy_node(start)
--- copyinjection(n,start)
--- head, current = insert_node_after(head,current,n) -- unlikely that mark has components
--- elseif trace_marks then
--- logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char))
--- end
--- start = getnext(start)
--- end
--- -- we can have one accent as part of a lookup and another following
--- -- local start = components -- was wrong (component scanning was introduced when more complex ligs in devanagari was added)
--- local start = getnext(current)
--- while start do
--- local char = ischar(start)
--- if char then
--- if marks[char] then
--- setligaindex(start,baseindex + getligaindex(start,componentindex))
--- if trace_marks then
--- logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
--- end
--- start = getnext(start)
--- else
--- break
--- end
--- else
--- break
--- end
--- end
--- else
--- -- discfound ... forget about marks .. probably no scripts that hyphenate and have marks
--- local discprev, discnext = getboth(discfound)
--- if discprev and discnext then
--- -- we assume normalization in context, and don't care about generic ... especially
--- -- \- can give problems as there we can have a negative char but that won't match
--- -- anyway
--- local pre, post, replace, pretail, posttail, replacetail = getdisc(discfound,true)
--- if not replace then -- todo: signal simple hyphen
--- local prev = getprev(base)
--- local current = comp
--- local previous = nil
--- local copied = nil
--- while current do
--- if getid(current) == glyph_code then
--- local n = copy_node(current)
--- if copied then
--- setlink(previous,n)
--- else
--- copied = n
--- end
--- previous = n
--- end
--- current = getnext(current)
--- end
--- setprev(discnext) -- also blocks funny assignments
--- setnext(discprev) -- also blocks funny assignments
--- if pre then
--- setlink(discprev,pre)
--- end
--- pre = comp
--- if post then
--- setlink(posttail,discnext)
--- setprev(post)
--- else
--- post = discnext
--- end
--- setlink(prev,discfound,next)
--- setboth(base)
--- set_components(base,copied)
--- setdisc(discfound,pre,post,base) -- was discretionary_code
--- base = prev -- restart
--- end
--- end
--- end
--- return head, base
--- end
-
local function toligature(head,start,stop,char,dataset,sequence,markflag,discfound) -- brr head
if getattr(start,a_noligature) == 1 then
-- so we can do: e\noligature{ff}e e\noligature{f}fie (we only look at the first)
@@ -1190,7 +1073,7 @@ function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,st
if entry then
local dx, dy, bound = setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar])
if trace_cursive then
- logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,anchor,bound,mref(rlmode))
+ logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode))
end
return head, start, true
end
@@ -1836,7 +1719,7 @@ function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,
if entry then
local dx, dy, bound = setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar])
if trace_cursive then
- logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,anchor,bound,mref(rlmode))
+ logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode))
end
return head, start, true
end
@@ -1973,11 +1856,15 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
while start do
if skipped then
while start do
- local char = getchar(start)
- local class = classes[char]
- if class then
- if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then
- start = getnext(start)
+ local char, id = ischar(start,currentfont)
+ if char then
+ local class = classes[char]
+ if class then
+ if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then
+ start = getnext(start)
+ else
+ break
+ end
else
break
end
@@ -2362,15 +2249,15 @@ local function chaindisk(head,start,dataset,sequence,rlmode,ck,skipped)
return head, start, done
end
-local function chaintrac(head,start,dataset,sequence,rlmode,ck,skipped)
+local function chaintrac(head,start,dataset,sequence,rlmode,ck,skipped,match)
local rule = ck[1]
local lookuptype = ck[8] or ck[2]
local nofseq = #ck[3]
local first = ck[4]
local last = ck[5]
local char = getchar(start)
- logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a",
- cref(dataset,sequence),rule,gref(char),first-1,last-first+1,nofseq-last,lookuptype)
+ logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a",
+ cref(dataset,sequence),rule,match and "matches" or "nomatch",gref(char),first-1,last-first+1,nofseq-last,lookuptype)
end
local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
@@ -2806,7 +2693,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
end
if match then
if trace_contexts then
- chaintrac(head,start,dataset,sequence,rlmode,ck,skipped)
+ chaintrac(head,start,dataset,sequence,rlmode,ck,skipped,true)
end
if diskseen or sweepnode then
head, start, done = chaindisk(head,start,dataset,sequence,rlmode,ck,skipped)
@@ -2816,6 +2703,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
if done then
break -- out of contexts (new, needs checking)
end
+ -- else
+ -- chaintrac(head,start,dataset,sequence,rlmode,ck,skipped,match)
end
end
if diskseen then
@@ -3045,7 +2934,6 @@ local function kernrun(disc,k_run,font,attr,...)
done = true
end
setprev(pre,nest)
--- setprev(pre)
setnext(prev,disc)
end
end
@@ -3075,7 +2963,6 @@ local function kernrun(disc,k_run,font,attr,...)
done = true
end
setprev(replace,nest)
- -- setprev(replace)
setnext(prev,disc)
end
if next then
@@ -3146,83 +3033,6 @@ local function comprun(disc,c_run,...) -- vararg faster than the whole list
return getnext(disc), renewed
end
--- local function testrun(disc,t_run,c_run,...)
--- if trace_testruns then
--- report_disc("test",disc)
--- end
--- local prev, next = getboth(disc)
--- if not next then
--- -- weird discretionary
--- return
--- end
--- local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true)
--- local done = false
--- if replace and prev then
--- -- this is a bit strange as we only do replace here and not post
--- -- anyway, we only look ahead ... the idea is that we discard a
--- -- disc when there is a ligature crossing the replace boundary
--- setlink(replacetail,next)
--- local ok, overflow = t_run(replace,next,...)
--- if ok and overflow then
--- -- so, we can have crossed the boundary
--- setfield(disc,"replace")
--- setlink(prev,replace)
--- -- setlink(replacetail,next)
--- setboth(disc)
--- flush_node_list(disc)
--- return replace, true -- restart .. tricky !
--- else
--- -- we stay inside the disc
--- setnext(replacetail)
--- setprev(next,disc)
--- end
--- -- pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true)
--- end
--- --
--- -- like comprun
--- --
--- local renewed = false
--- --
--- if pre then
--- sweepnode = disc
--- sweeptype = "pre"
--- local new, ok = c_run(pre,...)
--- if ok then
--- pre = new
--- renewed = true
--- end
--- end
--- --
--- if post then
--- sweepnode = disc
--- sweeptype = "post"
--- local new, ok = c_run(post,...)
--- if ok then
--- post = new
--- renewed = true
--- end
--- end
--- --
--- if replace then
--- sweepnode = disc
--- sweeptype = "replace"
--- local new, ok = c_run(replace,...)
--- if ok then
--- replace = new
--- renewed = true
--- end
--- end
--- --
--- sweepnode = nil
--- sweeptype = nil
--- if renewed then
--- setdisc(disc,pre,post,replace)
--- return next, true
--- else
--- return next, done
--- end
--- end
-
local function testrun(disc,t_run,c_run,...)
if trace_testruns then
report_disc("test",disc)
@@ -3409,50 +3219,6 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm
return head, done
end
--- local function t_run_single(start,stop,font,attr,lookupcache)
--- while start ~= stop do
--- local char = ischar(start,font)
--- if char then
--- local a -- happens often so no assignment is faster
--- if attr then
--- a = getattr(start,0)
--- end
--- local startnext = getnext(start)
--- if not a or (a == attr) then
--- local lookupmatch = lookupcache[char]
--- if lookupmatch then -- hm, hyphens can match (tlig) so we need to really check
--- -- if we need more than ligatures we can outline the code and use functions
--- local s = startnext
--- local l = nil
--- local d = 0
--- while s do
--- if s == stop then
--- d = 1
--- elseif d > 0 then
--- d = d + 1
--- end
--- local lg = lookupmatch[getchar(s)]
--- if lg then
--- l = lg
--- s = getnext(s)
--- else
--- break
--- end
--- end
--- if l and l.ligature then
--- return true, d > 1
--- end
--- end
--- else
--- -- go on can be a mixed one
--- end
--- start = starttnext
--- else
--- break
--- end
--- end
--- end
-
local function t_run_single(start,stop,font,attr,lookupcache)
local lastd = nil
while start ~= stop do
@@ -3611,58 +3377,6 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm
return head, done
end
--- local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
--- while start ~= stop do
--- local char = ischar(start,font)
--- if char then
--- local a -- happens often so no assignment is faster
--- if attr then
--- a = getattr(start,0)
--- end
--- local startnext = getnext(start)
--- if not a or (a == attr) then
--- for i=1,nofsteps do
--- local step = steps[i]
--- local lookupcache = step.coverage
--- if lookupcache then
--- local lookupmatch = lookupcache[char]
--- if lookupmatch then
--- -- if we need more than ligatures we can outline the code and use functions
--- local s = startnext
--- local l = nil
--- local d = 0
--- while s do
--- if s == stop then
--- d = 1
--- elseif d > 0 then
--- d = d + 1
--- end
--- local lg = lookupmatch[getchar(s)]
--- if lg then
--- l = lg
--- s = getnext(s)
--- else
--- break
--- end
--- end
--- if l and l.ligature then
--- return true, d > 1
--- end
--- end
--- else
--- report_missing_coverage(dataset,sequence)
--- end
--- end
--- else
--- -- go on can be a mixed one
--- end
--- start = startnext
--- else
--- break
--- end
--- end
--- end
-
local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
local lastd = nil
while start ~= stop do
@@ -3836,8 +3550,7 @@ do
-- This is a measurable experimental speedup (only with hyphenated text and multiple
-- fonts per processor call), especially for fonts with lots of contextual lookups.
- -- local fastdisc = true
- local fastdisc = context and LUATEXVERSION >= 1.005
+ local fastdisc = true
directives.register("otf.fastdisc",function(v) fastdisc = v end)
@@ -3926,7 +3639,9 @@ do
end
end
elseif typ == "gsub_reversecontextchain" then
- -- this is a limited case, no special treatments like 'init' etc
+ -- This might need a check: if we have #before or #after > 0 then we might need to reverse
+ -- the before and after lists in the loader. But first I need to see a font that uses multiple
+ -- matches.
local start = find_node_tail(head)
local rlmode = 0 -- how important is this .. do we need to check for dir?
while start do
diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua
index 75ae08526..bf9682a8f 100644
--- a/tex/context/base/mkiv/font-oup.lua
+++ b/tex/context/base/mkiv/font-oup.lua
@@ -2275,6 +2275,9 @@ function readers.expand(data)
local steps = sequence.steps
if steps then
local kind = sequence.type
+-- if kind == "gsub_reversecontextchain" then
+-- inspect(sequence)
+-- end
local markclass = sequence.markclass
if markclass then
if not markclasses then
diff --git a/tex/context/base/mkiv/font-run.mkiv b/tex/context/base/mkiv/font-run.mkiv
index ebb3a576c..610f2e62c 100644
--- a/tex/context/base/mkiv/font-run.mkiv
+++ b/tex/context/base/mkiv/font-run.mkiv
@@ -202,11 +202,13 @@
\scratchcounterthree\numexpr\charplane*256+\scratchcounter\relax
\iffontchar\font\scratchcounterthree
\setbox\scratchbox\ruledhpack{\char\scratchcounterthree}%
+ \bgroup
\tf
\startoverlay
{\wrapbox\scratchbox}
{\textbox\scratchnum}
\stopoverlay
+ \egroup
\else
\copy\scratchboxthree
\fi}}}%
diff --git a/tex/context/base/mkiv/grph-inc.mkiv b/tex/context/base/mkiv/grph-inc.mkiv
index 25058b3f7..3c4d3b980 100644
--- a/tex/context/base/mkiv/grph-inc.mkiv
+++ b/tex/context/base/mkiv/grph-inc.mkiv
@@ -113,19 +113,19 @@
\newtoks \everyexternalfigureresets % for the moment still public
\newtoks \everyexternalfigurechecks % for the moment still public
-% \useexternalfigure[alpha][koe]
-% \useexternalfigure[beta] [koe] [breedte=1cm]
-% \useexternalfigure[gamma][koe][alpha]
-% \useexternalfigure[delta][koe][alpha][breedte=2cm]
+% \useexternalfigure[alpha][cow]
+% \useexternalfigure[beta] [cow] [width=1cm]
+% \useexternalfigure[gamma][cow][alpha]
+% \useexternalfigure[delta][cow][alpha][width=2cm]
%
-% volle breedte: \externalfigure[koe] \par
-% 3cm breed: \externalfigure[koe] [breedte=3cm] \par
-% volle breedte: \externalfigure[alpha] \par
-% 1cm breed: \externalfigure[beta] \par
-% volle breedte: \externalfigure[gamma] \par
-% 2cm breed: \externalfigure[delta] \par
-% 4cm breed: \externalfigure[beta] [breedte=4cm] \par
-% 5cm breed: \externalfigure[gamma][breedte=5cm] \par
+% volle breedte: \externalfigure[cow] \par
+% 3cm breed: \externalfigure[cow] [width=3cm] \par
+% volle breedte: \externalfigure[alpha] \par
+% 1cm breed: \externalfigure[beta] \par
+% volle breedte: \externalfigure[gamma] \par
+% 2cm breed: \externalfigure[delta] \par
+% 4cm breed: \externalfigure[beta] [width=4cm] \par
+% 5cm breed: \externalfigure[gamma][width=5cm] \par
%
% \defineexternalfigure[a][width=10cm]
% \defineexternalfigure[b][width=5cm]
@@ -703,8 +703,6 @@
\letexternalfigureparameter\c!offset\v!overlay
\letexternalfigureparameter\c!width \figurewidth
\letexternalfigureparameter\c!height\figureheight
-% \letexternalfigureparameter\c!align \v!middle
-% \letexternalfigureparameter\c!autowidth\v!no
\inheritedexternalfigureframed{\box\foundexternalfigure}%
\fi
\fi\fi
diff --git a/tex/context/base/mkiv/lang-txt.lua b/tex/context/base/mkiv/lang-txt.lua
index b550ac2b4..443a261df 100644
--- a/tex/context/base/mkiv/lang-txt.lua
+++ b/tex/context/base/mkiv/lang-txt.lua
@@ -3012,5 +3012,3 @@ local functions = data.labels.functions
functions.asin = functions.arcsin
functions.acos = functions.arccos
functions.atan = functions.arctan
-
-table.save("e:/tmp/x.lua",data.labels)
diff --git a/tex/context/base/mkiv/lpdf-xmp.lua b/tex/context/base/mkiv/lpdf-xmp.lua
index 6153b198f..26ced4aee 100644
--- a/tex/context/base/mkiv/lpdf-xmp.lua
+++ b/tex/context/base/mkiv/lpdf-xmp.lua
@@ -250,7 +250,8 @@ local function flushxmpinfo()
local documentid = "no unique document id here"
local instanceid = "no unique instance id here"
- local producer = format("LuaTeX-%i.%i.%s",math.div(version,100),math.mod(version,100),revision)
+ -- local producer = format("LuaTeX-%i.%02i.%s",math.div(version,100),math.mod(version,100),revision)
+ local producer = format("LuaTeX-%0.2f.%s",version/100,revision)
local creator = "LuaTeX + ConTeXt MkIV"
local time = lpdf.timestamp()
local fullbanner = status.banner
diff --git a/tex/context/base/mkiv/luat-cod.lua b/tex/context/base/mkiv/luat-cod.lua
index 31860db78..88b7039d9 100644
--- a/tex/context/base/mkiv/luat-cod.lua
+++ b/tex/context/base/mkiv/luat-cod.lua
@@ -96,29 +96,39 @@ local targetpath = "."
-- environment.jobname = tex.jobname
-- environment.version = tostring(tex.toks.contextversiontoks)
+-- traditionally the revision has been a one character string and only
+-- pdftex went beyond "9" but anyway we test for it
+
+if LUATEXENGINE == nil then
+ LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine)
+ or (find(status.banner,"LuajitTeX") and "luajittex" or "luatex")
+end
+
if LUATEXVERION == nil then
+ LUATEXVERSION = status.luatex_revision
LUATEXVERSION = status.luatex_version/100
- + tonumber(status.luatex_revision)/1000
+ -- + tonumber(LUATEXVERSION)/1000
+ + (tonumber(LUATEXVERSION) or (string.byte(LUATEXVERSION)-string.byte("a")+10))/1000
end
-if LUATEXENGINE == nil then
- LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine)
- or (find(status.banner,"LuajitTeX") and "luajittex" or "luatex")
+if LUATEXFUNCTIONALITY == nil then
+ LUATEXFUNCTIONALITY = status.development_id or 6346
end
if JITSUPPORTED == nil then
- JITSUPPORTED = LUATEXENGINE == "luajittex" or jit
+ JITSUPPORTED = LUATEXENGINE == "luajittex" or jit
end
if INITEXMODE == nil then
- INITEXMODE = status.ini_version
+ INITEXMODE = status.ini_version
end
-environment.initex = INITEXMODE
-environment.initexmode = INITEXMODE
-environment.luatexversion = LUATEXVERSION
-environment.luatexengine = LUATEXENGINE
-environment.jitsupported = JITSUPPORTED
+environment.luatexengine = LUATEXENGINE
+environment.luatexversion = LUATEXVERSION
+environment.luatexfuncitonality = LUATEXFUNCTIONALITY
+environment.jitsupported = JITSUPPORTED
+environment.initex = INITEXMODE
+environment.initexmode = INITEXMODE
if not environment.luafilechunk then
diff --git a/tex/context/base/mkiv/luat-ini.lua b/tex/context/base/mkiv/luat-ini.lua
index 3ea8551c8..44d9e7fd5 100644
--- a/tex/context/base/mkiv/luat-ini.lua
+++ b/tex/context/base/mkiv/luat-ini.lua
@@ -34,3 +34,7 @@ LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine)
JITSUPPORTED = LUATEXENGINE == "luajittex" or jit
INITEXMODE = status.ini_version
+
+function os.setlocale()
+ -- no need for a message
+end
diff --git a/tex/context/base/mkiv/luat-run.lua b/tex/context/base/mkiv/luat-run.lua
index 372bbcbfa..0d30ad11b 100644
--- a/tex/context/base/mkiv/luat-run.lua
+++ b/tex/context/base/mkiv/luat-run.lua
@@ -95,24 +95,29 @@ local function pre_dump_actions()
-- statistics.savefmtstatus("\jobname","\contextversion","context.tex")
end
+local function wrapup_synctex()
+ luatex.synctex.wrapup()
+end
+
-- this can be done later
-callbacks.register('start_run', start_run, "actions performed at the beginning of a run")
-callbacks.register('stop_run', stop_run, "actions performed at the end of a run")
+callbacks.register('start_run', start_run, "actions performed at the beginning of a run")
+callbacks.register('stop_run', stop_run, "actions performed at the end of a run")
----------.register('show_open', show_open, "actions performed when opening a file")
----------.register('show_close', show_close, "actions performed when closing a file")
+---------.register('show_open', show_open, "actions performed when opening a file")
+---------.register('show_close', show_close, "actions performed when closing a file")
-callbacks.register('report_output_pages', report_output_pages, "actions performed when reporting pages")
-callbacks.register('report_output_log', report_output_log, "actions performed when reporting log file")
+callbacks.register('report_output_pages', report_output_pages, "actions performed when reporting pages")
+callbacks.register('report_output_log', report_output_log, "actions performed when reporting log file")
-callbacks.register('start_page_number', start_shipout_page, "actions performed at the beginning of a shipout")
-callbacks.register('stop_page_number', stop_shipout_page, "actions performed at the end of a shipout")
+callbacks.register('start_page_number', start_shipout_page, "actions performed at the beginning of a shipout")
+callbacks.register('stop_page_number', stop_shipout_page, "actions performed at the end of a shipout")
-callbacks.register('process_input_buffer', false, "actions performed when reading data")
-callbacks.register('process_output_buffer', false, "actions performed when writing data")
+callbacks.register('process_input_buffer', false, "actions performed when reading data")
+callbacks.register('process_output_buffer', false, "actions performed when writing data")
-callbacks.register("pre_dump", pre_dump_actions, "lua related finalizers called before we dump the format") -- comes after \everydump
+callbacks.register("pre_dump", pre_dump_actions, "lua related finalizers called before we dump the format") -- comes after \everydump
+callbacks.register("finish_synctex_callback", wrapup_synctex, "rename temporary synctex file")
-- an example:
diff --git a/tex/context/base/mkiv/math-acc.mkvi b/tex/context/base/mkiv/math-acc.mkvi
index c3f8bad40..3411edd1a 100644
--- a/tex/context/base/mkiv/math-acc.mkvi
+++ b/tex/context/base/mkiv/math-acc.mkvi
@@ -190,7 +190,7 @@
\let\normalcheck \check \unexpanded\def\dotlesscheck #1{\normalcheck {\mathdotless#1}}
\let\normalbreve \breve \unexpanded\def\dotlessbreve #1{\normalbreve {\mathdotless#1}}
\let\normaldot \dot \unexpanded\def\dotlessdot #1{\normaldot {\mathdotless#1}}
-\let\normalmathring\mathring \unexpanded\def\dotlessmathring#1{\normalmathring{\mathdotless#1}}
+\let\normalring \ring \unexpanded\def\dotlessring #1{\normalring {\mathdotless#1}}
\let\normaltilde \tilde \unexpanded\def\dotlesstilde #1{\normaltilde {\mathdotless#1}}
\let\normaldddot \dddot \unexpanded\def\dotlessdddot #1{\normaldddot {\mathdotless#1}}
@@ -205,8 +205,10 @@
\unexpanded\def\check {\math_accents_auto_dotless\normalcheck \dotlesscheck }
\unexpanded\def\breve {\math_accents_auto_dotless\normalbreve \dotlessbreve }
\unexpanded\def\dot {\math_accents_auto_dotless\normaldot \dotlessdot }
-\unexpanded\def\mathring{\math_accents_auto_dotless\normalmathring\dotlessmathring}
+\unexpanded\def\ring {\math_accents_auto_dotless\normalring \dotlessring }
\unexpanded\def\tilde {\math_accents_auto_dotless\normaltilde \dotlesstilde }
\unexpanded\def\dddot {\math_accents_auto_dotless\normaldddot \dotlessdddot }
+\let\mathring\ring % for a while
+
\protect \endinput
diff --git a/tex/context/base/mkiv/math-act.lua b/tex/context/base/mkiv/math-act.lua
index 0aeca5106..68f2c5ce4 100644
--- a/tex/context/base/mkiv/math-act.lua
+++ b/tex/context/base/mkiv/math-act.lua
@@ -91,8 +91,6 @@ function mathematics.scaleparameters(target,original)
end
end
-sequencers.appendaction("mathparameters","system","mathematics.scaleparameters")
-
-- AccentBaseHeight vs FlattenedAccentBaseHeight
function mathematics.checkaccentbaseheight(target,original)
@@ -102,8 +100,6 @@ function mathematics.checkaccentbaseheight(target,original)
end
end
-sequencers.appendaction("mathparameters","system","mathematics.checkaccentbaseheight") -- should go in lfg instead
-
function mathematics.checkprivateparameters(target,original)
local mathparameters = target.mathparameters
if mathparameters then
@@ -131,8 +127,6 @@ function mathematics.checkprivateparameters(target,original)
end
end
-sequencers.appendaction("mathparameters","system","mathematics.checkprivateparameters")
-
function mathematics.overloadparameters(target,original)
local mathparameters = target.mathparameters
if mathparameters and next(mathparameters) then
@@ -176,8 +170,6 @@ function mathematics.overloadparameters(target,original)
end
end
-sequencers.appendaction("mathparameters","system","mathematics.overloadparameters")
-
local function applytweaks(when,target,original)
local goodies = original.goodies
if goodies then
@@ -218,6 +210,11 @@ function mathematics.tweakaftercopyingfont(target,original)
end
end
+sequencers.appendaction("mathparameters","system","mathematics.scaleparameters")
+sequencers.appendaction("mathparameters","system","mathematics.checkaccentbaseheight") -- should go in lfg instead
+sequencers.appendaction("mathparameters","system","mathematics.checkprivateparameters") -- after scaling !
+sequencers.appendaction("mathparameters","system","mathematics.overloadparameters")
+
sequencers.appendaction("beforecopyingcharacters","system","mathematics.tweakbeforecopyingfont")
sequencers.appendaction("aftercopyingcharacters", "system","mathematics.tweakaftercopyingfont")
diff --git a/tex/context/base/mkiv/math-ali.mkiv b/tex/context/base/mkiv/math-ali.mkiv
index 1333b4770..1ff72630b 100644
--- a/tex/context/base/mkiv/math-ali.mkiv
+++ b/tex/context/base/mkiv/math-ali.mkiv
@@ -267,7 +267,8 @@
%D Here we implement the user interface part. We start with basic math alignments:
-\newcount\c_math_eqalign_column
+\newcount \c_math_eqalign_column
+\newconditional\c_math_eqalign_first
\newtoks \everymathalignment
\newtoks \everymathalignmentdone
@@ -287,11 +288,20 @@
\dostoptagged % finish cell
\strc_formulas_place_number_nested{#1}{#2}%
\math_number_right_of_eqalign
+ \global\settrue\c_math_eqalign_first
\crcr
\dostoptagged} % finish row
\def\math_alignment_NC
- {\aligntab}
+ {\relax
+ \ifconditional\c_math_eqalign_first
+ \ifx\p_math_alignment_number\v!auto
+ \strc_formulas_place_number_nested{+}{}%
+ \fi
+ \global\setfalse\c_math_eqalign_first
+ \fi
+ \math_number_left_of_eqalign
+ \aligntab}
\def\math_alignment_EQ
{\NC=}
@@ -305,6 +315,7 @@
\let\NN\math_alignment_NN
\let\EQ\math_alignment_EQ
\let\NR\math_alignment_NR
+ \global\settrue\c_math_eqalign_first
\to \everymathalignment
\appendtoks
@@ -321,7 +332,7 @@
\def\math_alignment_snap_start
{\ifgridsnapping
- \snaptogrid[\v!both]\vbox\bgroup
+ \snaptogrid[\v!math]\vbox\bgroup
\fi}
\def\math_alignment_snap_stop
@@ -331,6 +342,8 @@
% end of experimental
+\newconditional\c_math_alignment_auto_number
+
\unexpanded\def\math_alignment_start#1%
{\edef\currentmathalignment{#1}%
\dosingleempty\math_alignment_start_indeed}
@@ -343,6 +356,7 @@
\fi
\the\everymathalignment
\c_math_eqalign_column\zerocount
+ \edef\p_math_alignment_number{\mathalignmentparameter\c!number}%
\processcommacommand
[\mathalignmentparameter\c!align]%
{\advance\c_math_eqalign_column\plusone\math_eqalign_set_column}% takes argument
@@ -1216,6 +1230,8 @@
\newdimen \d_strc_math_display_width
\newbox \b_strc_math_display
\newconstant \c_strc_formulas_frame_mode
+\newdimen \d_strc_math_indent
+\newconditional\c_strc_math_indent
\let\d_strc_math_framed_width\displaywidth
@@ -1230,14 +1246,32 @@
% mode: 0=no frame | 1=number inside frame | 2=number outside frame
\def\strc_math_flush_aligned
- {\ifcase\mathraggedstatus\or\hfill\or\hfill\fi
- \box\b_strc_math_display
- \ifcase\mathraggedstatus\or\or\hfill\or\hfill\fi}
+ {\ifcase\c_strc_math_vertical
+ \ifcase\mathraggedstatus\or\hfill\or\hfill\fi
+ \box\b_strc_math_display
+ \ifcase\mathraggedstatus\or\or\hfill\or\hfill\fi
+ \else
+ \ifconditional\c_strc_math_indent
+ \ifdim\d_strc_math_indent=\zeropoint\else
+ \hangafter\plusone
+ \hangindent\d_strc_math_indent
+ \fi
+ \fi
+ \edef\p_interlinespace{\formulaparameter\c!interlinespace}%
+ \ifx\p_interlinespace\empty\else\baselineskip\p_interlinespace\fi
+ \global\d_strc_math_indent\zeropoint
+ \ifcase\mathraggedstatus\or\raggedleft\or\raggedcenter\or\raggedright\fi
+ \unhbox\b_strc_math_display
+ \fi}
\def\strc_math_flush_box_normal
- {\hbox to \displaywidth\bgroup
+ {\ifcase\c_strc_math_vertical
+ \hbox to \displaywidth\bgroup
+ \strc_math_flush_aligned
+ \egroup
+ \else
\strc_math_flush_aligned
- \egroup}
+ \fi}
\def\strc_math_flush_box_framed_common
{\setformulaframedparameter\c!align{\formulaparameter\c!align}%
@@ -1466,64 +1500,80 @@
\startforceddisplaymath}
\def\strc_math_flush_number_no
- {\ifconditional\c_strc_math_display_overflow
- \ifcase\c_strc_formulas_frame_mode
- \strc_math_flush_box_normal
- \else
- \strc_math_flush_box_framed_fit_inline
- \fi
- \else
- \ifcase\c_strc_formulas_frame_mode
- %\ifconditional\c_strc_formulas_tight
- % \strc_math_flush_box_normal
- %\else
+ {\ifcase\c_strc_math_vertical
+ \ifconditional\c_strc_math_display_overflow
+ \ifcase\c_strc_formulas_frame_mode
\strc_math_flush_box_normal
- %\fi
- \else
- \ifconditional\c_strc_formulas_tight
+ \else
\strc_math_flush_box_framed_fit_inline
+ \fi
+ \else
+ \ifcase\c_strc_formulas_frame_mode
+ %\ifconditional\c_strc_formulas_tight
+ % \strc_math_flush_box_normal
+ %\else
+ \strc_math_flush_box_normal
+ %\fi
\else
- \strc_math_flush_box_framed_display
+ \ifconditional\c_strc_formulas_tight
+ \strc_math_flush_box_framed_fit_inline
+ \else
+ \strc_math_flush_box_framed_display
+ \fi
\fi
\fi
+ \else
+ \strc_math_flush_box
\fi}
\def\strc_math_flush_number_left
- {\ifconditional\c_strc_math_display_overflow
- \ifcase\c_strc_formulas_frame_mode
- \strc_math_number_left_overflow
- \or
- \strc_math_number_left_overflow_outside
- \or
- \strc_math_number_left_overflow_inside
+ {\ifcase\c_strc_math_vertical
+ \ifconditional\c_strc_math_display_overflow
+ \ifcase\c_strc_formulas_frame_mode
+ \strc_math_number_left_overflow
+ \or
+ \strc_math_number_left_overflow_outside
+ \or
+ \strc_math_number_left_overflow_inside
+ \fi
+ \else
+ \ifcase\c_strc_formulas_frame_mode
+ \strc_math_number_left_normal
+ \or
+ \strc_math_number_left_normal_outside
+ \or
+ \strc_math_number_left_normal_inside
+ \fi
\fi
\else
- \ifcase\c_strc_formulas_frame_mode
- \strc_math_number_left_normal
- \or
- \strc_math_number_left_normal_outside
- \or
- \strc_math_number_left_normal_inside
- \fi
+ \box\b_strc_formulas_number
+ \hfill
+ \strc_math_flush_aligned
\fi}
\def\strc_math_flush_number_right
- {\ifconditional\c_strc_math_display_overflow
- \ifcase\c_strc_formulas_frame_mode
- \strc_math_number_right_overflow
- \or
- \strc_math_number_right_overflow_outside
- \or
- \strc_math_number_right_overflow_inside
+ {\ifcase\c_strc_math_vertical
+ \ifconditional\c_strc_math_display_overflow
+ \ifcase\c_strc_formulas_frame_mode
+ \strc_math_number_right_overflow
+ \or
+ \strc_math_number_right_overflow_outside
+ \or
+ \strc_math_number_right_overflow_inside
+ \fi
+ \else
+ \ifcase\c_strc_formulas_frame_mode
+ \strc_math_number_right_normal
+ \or
+ \strc_math_number_right_normal_outside
+ \or
+ \strc_math_number_right_normal_inside
+ \fi
\fi
\else
- \ifcase\c_strc_formulas_frame_mode
- \strc_math_number_right_normal
- \or
- \strc_math_number_right_normal_outside
- \or
- \strc_math_number_right_normal_inside
- \fi
+ \strc_math_flush_aligned
+ \hfill
+ \box\b_strc_formulas_number
\fi}
\unexpanded\def\strc_math_box_stop
@@ -1560,7 +1610,13 @@
\noindent % \noindentation % not \dontleavehmode
\hskip\d_strc_formulas_display_margin_left % was kern but that doesn't indent
\strc_math_traced_state
- \hbox to \displaywidth \bgroup
+ \ifcase\c_strc_math_vertical
+ \hbox to \displaywidth \bgroup
+ \or
+ \vbox \bgroup \hsize\displaywidth
+ \or
+ \bgroup \hsize\displaywidth
+ \fi
\ifcase\mathnumberstatus
\strc_math_flush_box
\or % status 1
@@ -1586,7 +1642,11 @@
\else
\strc_math_flush_box
\fi
- % \egroup
+ \ifcase\c_strc_math_vertical
+ \or
+ \or
+ \par
+ \fi
\egroup}
\defineinnermathhandler\v!left {\strc_math_box_start\plusone }{\strc_math_box_stop}
diff --git a/tex/context/base/mkiv/math-fbk.lua b/tex/context/base/mkiv/math-fbk.lua
index c8843ff1d..c883d57a7 100644
--- a/tex/context/base/mkiv/math-fbk.lua
+++ b/tex/context/base/mkiv/math-fbk.lua
@@ -559,6 +559,8 @@ virtualcharacters[0xFE935] = function(data) return smashed(data,0x02035,true) en
virtualcharacters[0xFE936] = function(data) return smashed(data,0x02036,true) end
virtualcharacters[0xFE937] = function(data) return smashed(data,0x02037,true) end
+local hack = nil
+
function mathematics.getridofprime(target,original)
-- local mathsize = specification.mathsize
-- if mathsize == 1 or mathsize == 2 or mathsize == 3) then
@@ -566,6 +568,7 @@ function mathematics.getridofprime(target,original)
if mathparameters and next(mathparameters) then
local changed = original.changed
if changed then
+ hack = changed[0x02032]
changed[0x02032] = nil
changed[0x02033] = nil
changed[0x02034] = nil
@@ -577,7 +580,16 @@ function mathematics.getridofprime(target,original)
end
end
+function mathematics.setridofprime(target,original)
+ local mathparameters = original.mathparameters
+ if mathparameters and next(mathparameters) and original.changed then
+ target.characters[0xFE931] = target.characters[hack or 0x2032]
+ hack = nil
+ end
+end
+
utilities.sequencers.appendaction("beforecopyingcharacters","system","mathematics.getridofprime")
+utilities.sequencers.appendaction("aftercopyingcharacters", "system","mathematics.setridofprime")
-- actuarian (beware: xits has an ugly one)
diff --git a/tex/context/base/mkiv/math-frc.mkiv b/tex/context/base/mkiv/math-frc.mkiv
index 16ea6e9e1..b573e69bd 100644
--- a/tex/context/base/mkiv/math-frc.mkiv
+++ b/tex/context/base/mkiv/math-frc.mkiv
@@ -328,7 +328,6 @@
}%
}\endgroup}
-
\definemathfraction[xfrac] [\c!alternative=\v!inner,\c!mathstyle=\s!script]
\definemathfraction[xxfrac][\c!alternative=\v!inner,\c!mathstyle=\s!scriptscript]
diff --git a/tex/context/base/mkiv/math-ini.mkiv b/tex/context/base/mkiv/math-ini.mkiv
index 351b18044..c7f75fdc7 100644
--- a/tex/context/base/mkiv/math-ini.mkiv
+++ b/tex/context/base/mkiv/math-ini.mkiv
@@ -76,6 +76,7 @@
\registerctxluafile{math-tag}{1.001}
\registerctxluafile{math-fbk}{1.001}
\registerctxluafile{math-dir}{1.001}
+\registerctxluafile{math-spa}{1.001}
%D A starter:
%D
diff --git a/tex/context/base/mkiv/math-noa.lua b/tex/context/base/mkiv/math-noa.lua
index abc5337c6..970ce3d87 100644
--- a/tex/context/base/mkiv/math-noa.lua
+++ b/tex/context/base/mkiv/math-noa.lua
@@ -1970,8 +1970,26 @@ end)
-- the normal builder
-function builders.kernel.mlist_to_hlist(head,style,penalties)
- return mlist_to_hlist(head,style,penalties), true
+do
+
+ local force_penalties = false
+
+ -- registertracker("math.penalties",function(v)
+ -- force_penalties = v
+ -- end)
+
+ function builders.kernel.mlist_to_hlist(head,style,penalties)
+ return mlist_to_hlist(head,style,force_penalties or penalties), true
+ end
+
+ implement {
+ name = "setmathpenalties",
+ arguments = "integer",
+ actions = function(p)
+ force_penalties = p > 0
+ end,
+ }
+
end
-- function builders.kernel.mlist_to_hlist(head,style,penalties)
diff --git a/tex/context/base/mkiv/math-spa.lua b/tex/context/base/mkiv/math-spa.lua
new file mode 100644
index 000000000..92ee662b9
--- /dev/null
+++ b/tex/context/base/mkiv/math-spa.lua
@@ -0,0 +1,89 @@
+if not modules then modules = { } end modules ['math-spa'] = {
+ version = 1.001,
+ comment = "companion to math-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- for the moment (when testing) we use a penalty 1
+
+local penalty_code = nodes.nodecodes.penalty
+local glue_code = nodes.nodecodes.glue
+
+local nuts = nodes.nuts
+local tonut = nodes.tonut
+local tonode = nodes.tonode
+local getid = nuts.getid
+local getnext = nuts.getnext
+local getwidth = nuts.getwidth
+local setglue = nuts.setglue
+local getpenalty = nuts.getpenalty
+local setpenalty = nuts.setpenalty
+
+local traverse_id = nuts.traverse_id
+local get_dimensions = nuts.dimensions
+
+
+local texsetdimen = tex.setdimen
+
+local v_none = interfaces.variables.none
+local v_auto = interfaces.variables.auto
+
+local method = v_none
+local distance = 0
+
+function noads.handlers.align(l)
+ if method ~= v_none then
+ local h = tonut(l)
+ if method == v_auto then
+ local s = h
+ while s do
+ local id = getid(s)
+ local n = getnext(s)
+ if id == penalty_code and getpenalty(s) == 1 then
+ setpenalty(s,0)
+ if n and getid(n) == glue_code then
+ s = n
+ n = getnext(s)
+ end
+ local w = get_dimensions(h,n) + distance
+ texsetdimen("global","d_strc_math_indent",w)
+ break
+ end
+ s = n
+ end
+ else
+ texsetdimen("global","d_strc_math_indent",distance)
+ end
+ for n in traverse_id(glue_code,h) do
+ setglue(n,getwidth(n),0,0)
+ end
+ else
+ -- texsetdimen("global","d_strc_math_indent",0)
+ end
+ return l, true
+end
+
+interfaces.implement {
+ name = "setmathhang",
+ arguments = {
+ {
+ { "method", "string" },
+ { "distance", "dimension" },
+ }
+ },
+ actions = function(t)
+ method = t.method or v_none
+ distance = t.distance or 0
+ end
+}
+
+interfaces.implement {
+ name = "resetmathhang",
+ actions = function(t)
+ method = v_none
+ distance = 0
+ end
+}
+
diff --git a/tex/context/base/mkiv/mtx-context-domotica.tex b/tex/context/base/mkiv/mtx-context-domotica.tex
index 62e6e8786..83562ee30 100644
--- a/tex/context/base/mkiv/mtx-context-domotica.tex
+++ b/tex/context/base/mkiv/mtx-context-domotica.tex
@@ -33,6 +33,36 @@
%
% end help
+%D In case one wonders what domotica has to do with ConTeXt, here is the short
+%D story. One day I'll wrap up a long one.
+%D
+%D After years of keeping an eye on developments and techniques and being somewhat
+%D disappointed by experiments, I decided to settle on a local approach for simple
+%D domotica (criteria are: stability, full open source, decent scripting, future
+%D safe). Eventually I decides to buy a few (overpriced) hue zigbee hubs: one
+%D private and one for the office, so that I could create different lightning
+%D setups, automatically control light to be turned on and off, etc. Unfortunately
+%D those hubs are rather limited in functionality and performance, which is
+%D surprising for an otherwise mature product. So (we're speaking mid 2015) I wrote
+%D a couple of scripts in \LUA\ that would do the real magic, and only use the hub
+%D for controlling the individual lights, buttons and sensors. That way I could
+%D create complex arrangements (think of setups for working, reading, talking,
+%D either of not in parts or rooms) driven by the available buttons and motion
+%D sensors. I really needed multiple sensors and buttons per room, something (again
+%D surprisingly) not supported by the hub at that time. It seems that more than a
+%D year later functionality that I needed and wrote gets added stepwise to the hub:
+%D multiple sensors, multiple use of buttons, etc. Compared to free \TEX\
+%D developments such commercial products evolve slow.
+%D
+%D In addition to these hubs I bought some zwave devices for controlling heating and
+%D a few rf radio things for sunshades. For zwave I uses the same approach: buy a
+%D decent hub (the nice popp hub) and control it via \LUA. In fact, I can now use
+%D one set of scripts to control a mix of technologies. However, when programming
+%D the lot, one needs to have an overview of devices and that is where this module
+%D comes into view. In fact, \LUATEX\ was already in view as I wrote the scripts in
+%D \LUA, using the \CONTEXT\ helper libraries. And the lots runs on a small low
+%D power (<10W) fitlet using stock \LUATEX\ as \LUA\ engine.
+
% --pattern="e:/domotica/open-zwave/open-zwave-master/config/**.xml"
\input mtx-context-common.tex
diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua
index 4501afefb..29d7adc44 100644
--- a/tex/context/base/mkiv/mult-low.lua
+++ b/tex/context/base/mkiv/mult-low.lua
@@ -29,7 +29,7 @@ return {
--
"bigskipamount", "medskipamount", "smallskipamount",
--
- "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion",
+ "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "texenginefunctionality",
"luatexengine", "pdftexengine", "xetexengine", "unknownengine",
-- "etexversion",
-- "pdftexversion", "pdftexrevision",
@@ -370,7 +370,8 @@ return {
--
"startimath", "stopimath", "normalstartimath", "normalstopimath",
"startdmath", "stopdmath", "normalstartdmath", "normalstopdmath",
- "normalsuperscript", "normalsubscript",
+ "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript",
+ "superscript", "subscript", "nosuperscript", "nosubscript",
--
"uncramped", "cramped", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette",
"mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox",
diff --git a/tex/context/base/mkiv/node-pro.lua b/tex/context/base/mkiv/node-pro.lua
index 3251b0133..4509bac18 100644
--- a/tex/context/base/mkiv/node-pro.lua
+++ b/tex/context/base/mkiv/node-pro.lua
@@ -71,15 +71,16 @@ processors.enabled = true -- this will become a proper state (like trackers)
do
- local has_glyph = nodes.has_glyph
+ local has_glyph = nodes.has_glyph
+ local count_nodes = nodes.countall
function processors.pre_linebreak_filter(head,groupcode) -- ,size,packtype,direction
local found = force_processors or has_glyph(head)
if found then
if trace_callbacks then
- local before = nodes.count(head,true)
+ local before = count_nodes(head,true)
local head, done = actions(head,groupcode) -- ,size,packtype,direction
- local after = nodes.count(head,true)
+ local after = count_nodes(head,true)
if done then
tracer("pre_linebreak","changed",head,groupcode,before,after,true)
else
@@ -91,7 +92,7 @@ do
return done and head or true
end
elseif trace_callbacks then
- local n = nodes.count(head,false)
+ local n = count_nodes(head,false)
tracer("pre_linebreak","no chars",head,groupcode,n,n)
end
return true
@@ -101,9 +102,9 @@ do
local found = force_processors or has_glyph(head)
if found then
if trace_callbacks then
- local before = nodes.count(head,true)
+ local before = count_nodes(head,true)
local head, done = actions(head,groupcode,size,packtype,direction,attributes)
- local after = nodes.count(head,true)
+ local after = count_nodes(head,true)
if done then
tracer("hpack","changed",head,groupcode,before,after,true)
else
@@ -115,7 +116,7 @@ do
return done and head or true
end
elseif trace_callbacks then
- local n = nodes.count(head,false)
+ local n = count_nodes(head,false)
tracer("hpack","no chars",head,groupcode,n,n)
end
return true
@@ -167,7 +168,8 @@ end
do
- local actions = tasks.actions("finalizers") -- head, where
+ local actions = tasks.actions("finalizers") -- head, where
+ local count_nodes = nodes.countall
-- beware, these are packaged boxes so no first_glyph test
-- maybe some day a hash with valid groupcodes
@@ -178,9 +180,9 @@ do
function processors.post_linebreak_filter(head,groupcode)
if trace_callbacks then
- local before = nodes.count(head,true)
+ local before = count_nodes(head,true)
local head, done = actions(head,groupcode)
- local after = nodes.count(head,true)
+ local after = count_nodes(head,true)
if done then
tracer("post_linebreak","changed",head,groupcode,before,after,true)
else
diff --git a/tex/context/base/mkiv/node-syn.lua b/tex/context/base/mkiv/node-syn.lua
index a196f0b95..401cd4349 100644
--- a/tex/context/base/mkiv/node-syn.lua
+++ b/tex/context/base/mkiv/node-syn.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['node-syn'] = {
license = "see context related readme files"
}
--- Because we have these fields in some node that are used by sunctex, I decided (because
+-- Because we have these fields in some node that are used by synctex, I decided (because
-- some users seem to like that feature) to implement a variant that might work out better
-- for ConTeXt. This is experimental code. I don't use it myself so it will take a while
-- to mature. There will be some helpers that one can use in more complex situations like
@@ -20,12 +20,19 @@ if not modules then modules = { } end modules ['node-syn'] = {
-- InverseSearchCmdLine = mtxrun.exe --script synctex --edit --name="%f" --line="%l" $
+-- Unfortunately syntex always removes the files at the end and not at the start (it
+-- happens in synctexterminate). This forces us to use an intermediate file, no big deal
+-- in context (which has a runner) but definitely not nice.
+
local type, rawset = type, rawset
local concat = table.concat
local formatters = string.formatters
+local replacesuffix = file.replacesuffix
local trace = false trackers.register("system.synctex.visualize", function(v) trace = v end)
+local report_system = logs.reporter("system")
+
local nuts = nodes.nuts
local tonut = nuts.tonut
local tonode = nuts.tonode
@@ -164,19 +171,18 @@ end
-- the node stuff
-local result = { }
-local r = 0
-local f = nil
-local nofsheets = 0
-local nofobjects = 0
-local last = 0
-local filesdone = 0
-local enabled = false
-local compact = true
--- local compact = false
-local fulltrace = false
--- local fulltrace = true
-local logfile = false
+local result = { }
+local r = 0
+local f = nil
+local nofsheets = 0
+local nofobjects = 0
+local last = 0
+local filesdone = 0
+local enabled = false
+local compact = true
+local fulltrace = false
+local logfile = false
+local used = false
local function writeanchor()
local size = f:seek("end")
@@ -195,7 +201,7 @@ local function writefiles()
end
local function flushpreamble()
- logfile = file.replacesuffix(tex.jobname,"syncctx")
+ logfile = replacesuffix(tex.jobname,"syncctx")
f = io.open(logfile,"wb")
f:write("SyncTeX Version:1"..eol)
writefiles()
@@ -208,6 +214,12 @@ local function flushpreamble()
flushpreamble = writefiles
end
+function synctex.wrapup()
+ if logfile then
+ os.rename(logfile,replacesuffix(logfile,"synctex"))
+ end
+end
+
local function flushpostamble()
if not f then
return
@@ -537,9 +549,12 @@ if set_synctex_mode then
enabled = true
state = details or 1
set_synctex_mode(state)
- tex.normalsynctex = 0
- directives.enable("system.synctex.xml")
- nodes.tasks.appendaction("shipouts", "after", "nodes.synctex.collect")
+ if not used then
+ directives.enable("system.synctex.xml")
+ nodes.tasks.appendaction("shipouts", "after", "nodes.synctex.collect")
+ report_system("synctex functionality is enabled, expect runtime overhead!")
+ used = true
+ end
elseif state > 0 then
set_synctex_mode(state)
end
@@ -548,12 +563,29 @@ if set_synctex_mode then
function synctex.disable()
if enabled then
set_synctex_mode(0)
+ report_system("synctex functionality is disabled!")
+ enabled = false
end
end
function synctex.finish()
if enabled then
flushpostamble()
+ else
+ os.remove(replacesuffix(tex.jobname,"syncctx"))
+ os.remove(replacesuffix(tex.jobname,"synctex"))
+ end
+ end
+
+ function synctex.pause()
+ if enabled then
+ set_synctex_mode(0)
+ end
+ end
+
+ function synctex.resume()
+ if enabled then
+ set_synctex_mode(state)
end
end
@@ -562,6 +594,8 @@ else
function synctex.enable () end
function synctex.disable() end
function synctex.finish () end
+ function synctex.pause () end
+ function synctex.resume () end
end
@@ -571,36 +605,16 @@ luatex.registerstopactions(synctex.finish)
nodes.tasks.appendaction("shipouts", "after", "luatex.synctex.collect")
--- moved here
-
-local report_system = logs.reporter("system")
-local synctex_used = false
-
-local function setsynctex(v)
- if v == "context" then
+directives.register("system.synctex", function(v)
+ if v then
synctex.enable()
- setcount("normalsynctex",0)
- synctex_used = true
else
- v = tonumber(v) or (toboolean(v,true) and 1) or (v == "zipped" and 1) or (v == "unzipped" and -1) or 0
- setcount("normalsynctex",v)
- synctex_used = v ~= 0
+ synctex.disable()
end
- if synctex_used then
- report_system("synctex functionality is enabled (%s), expect runtime overhead!",tostring(v))
- else
- report_system("synctex functionality is disabled!")
- end
-end
-
-directives.register("system.synctex", setsynctex) -- 0|1|false|true|zipped|unzipped|context
-
-directives.register("system.synctex.context", function(v)
- setsynctex(v and "context" or false)
end)
statistics.register("synctex tracing",function()
- if synctex_used or getcount("normalsynctex") ~= 0 then
+ if used then
return string.format("%i referenced files, %i files ignored, logfile: %s",noftags,nofblocked,logfile)
end
end)
@@ -631,3 +645,13 @@ interfaces.implement {
name = "synctexdisable",
actions = synctex.disable,
}
+
+interfaces.implement {
+ name = "synctexpause",
+ actions = synctex.pause,
+}
+
+interfaces.implement {
+ name = "synctexresume",
+ actions = synctex.resume,
+}
diff --git a/tex/context/base/mkiv/scrn-wid.mkvi b/tex/context/base/mkiv/scrn-wid.mkvi
index f19da57f7..fc0f9fd3e 100644
--- a/tex/context/base/mkiv/scrn-wid.mkvi
+++ b/tex/context/base/mkiv/scrn-wid.mkvi
@@ -223,6 +223,12 @@
tag {\currentattachment}%
registered {\currentattachmentregistered}%
method {\v!hidden}%
+ title {\attachmentparameter\c!title}%
+ subtitle {\attachmentparameter\c!subtitle}%
+ author {\attachmentparameter\c!author}%
+ file {\attachmentparameter\c!file}%
+ name {\attachmentparameter\c!name}%
+ buffer {\attachmentparameter\c!buffer}%
\relax}
\def\scrn_attachment_place
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 74381a37e..e88315d6b 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 13bb888c4..9ae6f503b 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/strc-mat.mkiv b/tex/context/base/mkiv/strc-mat.mkiv
index 4308666f3..8f3d2cc11 100644
--- a/tex/context/base/mkiv/strc-mat.mkiv
+++ b/tex/context/base/mkiv/strc-mat.mkiv
@@ -546,6 +546,8 @@
\newconstant\c_strc_formulas_mode % this will go away
\newconstant\c_strc_formulas_space_model
+\newconstant\c_strc_math_vertical % experiment
+
\c_strc_formulas_mode \plustwo % 0=native 1=simple (old) 2=align (new)
\c_strc_formulas_space_model\plusthree % replaces \plusone
@@ -750,12 +752,57 @@
\setformulaparameter\c!grid{\v!math:-\v!halfline}%
\fi}
+\def\strc_math_set_split
+ {\edef\p_split{\formulaparameter\c!split}%
+ \ifx\p_split\v!yes
+ \global\c_strc_math_vertical\plusone
+ \else\ifx\p_split\v!page
+ \global\c_strc_math_vertical\plustwo
+ \else
+ \global\c_strc_math_vertical\zerocount
+ \fi\fi
+ \ifcase\c_strc_math_vertical
+ \clf_setmathpenalties\zerocount
+ \clf_resetmathhang
+ \else
+ \clf_setmathpenalties\plusone
+ \edef\p_hang{\formulaparameter\c!hang}%
+ \ifx\p_hang\v!none
+ \global\setfalse\c_strc_math_indent
+ \clf_resetmathhang
+ \else
+ \global\settrue\c_strc_math_indent
+ \clf_setmathhang {%
+ method {\p_hang}%
+ distance \formulaparameter\c!distance
+ }%
+ \fi
+ \fi}
+
+\setupformula
+ [\c!split=\v!no,
+ \c!distance=\zeropoint,
+ %\c!interlinespace=1.5\lineheight,
+ \c!interlinespace=,
+ \c!hang=\v!none]
+
+% for the moment (when testing) we use a penalty 1
+
+\unexpanded\def\strc_math_align_here{\ifmmode\penalty\plusone\fi}%
+\unexpanded\def\strc_math_break_here{\ifmmode\hfill\break \fi}%
+
+\appendtoks
+ \let\alignhere\strc_math_align_here
+ \let\breakhere\strc_math_break_here
+\to \everymathematics
+
\unexpanded\def\strc_formulas_start_formula_indeed[#1][#2]% setting leftskip adaption is slow !
{\ifhmode
\par
\fi
\bgroup % HERE
\def\currentformula{#1}%
+ \strc_math_set_split
\dostarttaggedchained\t!formula\currentformula\??formula
\setfalse\c_strc_formulas_tight
\d_strc_formulas_display_skip_left \leftskip
diff --git a/tex/context/base/mkiv/syst-ini.mkiv b/tex/context/base/mkiv/syst-ini.mkiv
index bbc856a5e..63108feb7 100644
--- a/tex/context/base/mkiv/syst-ini.mkiv
+++ b/tex/context/base/mkiv/syst-ini.mkiv
@@ -1095,16 +1095,28 @@
\def\modulonumber#1#2{\the\numexpr#2-((((#2+(#1/2))/#1)-1)*#1)\relax}
\def\dividenumber#1#2{\the\numexpr(#2-(#1/2))/#1\relax}
-\def \texenginename {LuaTeX}
-\edef\texengineversion{\dividenumber{100}\luatexversion.\modulonumber{100}\luatexversion.\luatexrevision}
+\ifdefined\texenginename \else
+ %edef\texenginename{luatex}
+ \edef\texenginename{\directlua{tex.print(LUATEXENGINE)}}
+\fi
+
+\ifdefined\texengineversion \else
+ %edef\texengineversion{\dividenumber{100}\luatexversion.\modulonumber{100}\luatexversion.\luatexrevision}
+ \edef\texengineversion{\directlua{tex.print(LUATEXVERSION)}}
+\fi
+
+\ifdefined\texenginefunctionality \else
+ \edef\texenginefunctionality{\directlua{tex.print(LUATEXFUNCTIONALITY)}}
+\fi
%D We have no reason not to enable this:
\savingvdiscards\plusone
-%D We only can set this one via directives (system.synctex).
+%D We only can set this one via directives (system.synctex) and we only support
+%D the context variant.
-\let\synctex\undefined \newcount\synctex
+\let\synctex\undefined \newcount\synctex \let\normalsynctex\synctex
%D We get rid of the funny \TEX\ offset defaults of one inch by setting them to zero.
@@ -1156,12 +1168,14 @@
%D It makes more sense to have these here:
-\let\normalsuperscript\Usuperscript
-\let\normalsubscript \Usubscript
-\let\normalstartimath \Ustartmath
-\let\normalstopimath \Ustopmath
-\let\normalstartdmath \Ustartdisplaymath
-\let\normalstopdmath \Ustopdisplaymath
+\let\normalsuperscript \Usuperscript
+\let\normalsubscript \Usubscript
+\let\normalnosuperscript\Unosuperscript
+\let\normalnosubscript \Unosubscript
+\let\normalstartimath \Ustartmath
+\let\normalstopimath \Ustopmath
+\let\normalstartdmath \Ustartdisplaymath
+\let\normalstopdmath \Ustopdisplaymath
%D For now:
diff --git a/tex/context/base/mkiv/task-ini.lua b/tex/context/base/mkiv/task-ini.lua
index d0c00f5c8..1d17148c3 100644
--- a/tex/context/base/mkiv/task-ini.lua
+++ b/tex/context/base/mkiv/task-ini.lua
@@ -117,6 +117,7 @@ appendaction("math", "builders", "builders.kernel.mlist_to_hlist")
------------("math", "builders", "noads.handlers.italics", nil, "nohead") -- disabled
appendaction("math", "builders", "typesetters.directions.processmath") -- disabled (has to happen pretty late)
appendaction("math", "builders", "noads.handlers.makeup", nil, "nohead") -- disabled (has to happen last)
+appendaction("math", "builders", "noads.handlers.align", nil, "nohead")
appendaction("finalizers", "lists", "typesetters.paragraphs.normalize") -- moved here
appendaction("finalizers", "lists", "typesetters.margins.localhandler") -- disabled
diff --git a/tex/context/base/mkiv/trac-inf.lua b/tex/context/base/mkiv/trac-inf.lua
index f66485015..d09fce77a 100644
--- a/tex/context/base/mkiv/trac-inf.lua
+++ b/tex/context/base/mkiv/trac-inf.lua
@@ -167,8 +167,12 @@ function statistics.show()
return format("%s, type: %s, binary subtree: %s",
os.platform or "unknown",os.type or "unknown", environment.texos or "unknown")
end)
- register("luatex banner", function()
- return lower(status.banner)
+ -- register("luatex banner", function()
+ -- return lower(status.banner)
+ -- end)
+ register("used engine", function()
+ return format("%s version %s with functionality level %s, banner: %s",
+ LUATEXENGINE, LUATEXVERSION, LUATEXFUNCTIONALITY, lower(status.banner))
end)
register("control sequences", function()
return format("%s of %s + %s", status.cs_count, status.hash_size,status.hash_extra)
diff --git a/tex/context/base/mkiv/trac-tex.lua b/tex/context/base/mkiv/trac-tex.lua
index 38035a044..66ff94721 100644
--- a/tex/context/base/mkiv/trac-tex.lua
+++ b/tex/context/base/mkiv/trac-tex.lua
@@ -16,10 +16,6 @@ local undefined = create("undefined").command
function trackers.savehash()
saved = texhashtokens()
- if type(saved[1]) == "table" then
- -- LUATEXVERSION < 1.002
- saved = table.tohash(saved)
- end
return saved
end
@@ -27,10 +23,6 @@ function trackers.dumphashtofile(filename,delta)
local list = { }
local hash = texhashtokens()
local create = token.create
- if type(hash[1]) == "table" then
- -- LUATEXVERSION < 1.002
- hash = table.sortedkeys(hash)
- end
for i=1,#hash do
local name = hash[i]
if not delta or not saved[name] then
diff --git a/tex/context/base/mkiv/typo-bld.lua b/tex/context/base/mkiv/typo-bld.lua
index 153218eef..753748a2e 100644
--- a/tex/context/base/mkiv/typo-bld.lua
+++ b/tex/context/base/mkiv/typo-bld.lua
@@ -43,6 +43,7 @@ local new_baselineskip = nodepool.baselineskip
local new_lineskip = nodepool.lineskip
local insert_node_before = nodes.insert_before
local hpack_node = nodes.hpack
+local count_nodes = nodes.countall
local starttiming = statistics.starttiming
local stoptiming = statistics.stoptiming
@@ -193,9 +194,9 @@ function builders.vpack_filter(head,groupcode,size,packtype,maxdepth,direction)
if head then
starttiming(builders)
if trace_vpacking then
- local before = nodes.count(head)
+ local before = count_nodes(head)
head, done = vboxactions(head,groupcode,size,packtype,maxdepth,direction)
- local after = nodes.count(head)
+ local after = count_nodes(head)
if done then
nodes.processors.tracer("vpack","changed",head,groupcode,before,after,true)
else
diff --git a/tex/context/base/mkiv/util-env.lua b/tex/context/base/mkiv/util-env.lua
index 0b832e72e..064bd513a 100644
--- a/tex/context/base/mkiv/util-env.lua
+++ b/tex/context/base/mkiv/util-env.lua
@@ -17,56 +17,58 @@ local environment = environment
-- locales are a useless feature in and even dangerous for luatex
-os.setlocale(nil,nil) -- setlocale("all","C")
+local setlocale = os.setlocale
-function os.setlocale()
- -- no way you can mess with it
-end
+setlocale(nil,nil) -- setlocale("all","C")
--- do
---
--- local setlocale = os.setlocale
---
--- function os.resetlocale()
--- setlocale(nil,nil)
--- end
---
--- function os.pushlocale(l,...)
--- insert(stack, {
--- collate = setlocale(nil,"collate"),
--- ctype = setlocale(nil,"ctype"),
--- monetary = setlocale(nil,"monetary"),
--- numeric = setlocale(nil,"numeric"),
--- time = setlocale(nil,"time"),
--- })
--- if l then
--- setlocale(l,...)
--- else
--- setlocale(status.lc_collate ,"collate"),
--- setlocale(status.lc_ctype ,"ctype"),
--- setlocale(status.lc_monetary,"monetary"),
--- setlocale(status.lc_numeric ,"numeric"),
--- setlocale(status.lc_time ,"time"),
--- end
--- end
+-- function os.resetlocale()
+-- setlocale(nil,nil)
+-- end
--
--- function os.poplocale(...)
--- local l = remove(stack)
--- if l then
--- setlocale(unpack(l))
--- else
--- resetlocale()
--- end
+-- function os.pushlocale(l,...)
+-- insert(stack, {
+-- collate = setlocale(nil,"collate"),
+-- ctype = setlocale(nil,"ctype"),
+-- monetary = setlocale(nil,"monetary"),
+-- numeric = setlocale(nil,"numeric"),
+-- time = setlocale(nil,"time"),
+-- })
+-- if l then
+-- setlocale(l,...)
+-- else
+-- setlocale(status.lc_collate ,"collate"),
+-- setlocale(status.lc_ctype ,"ctype"),
+-- setlocale(status.lc_monetary,"monetary"),
+-- setlocale(status.lc_numeric ,"numeric"),
+-- setlocale(status.lc_time ,"time"),
-- end
+-- end
--
--- function os.setlocale()
--- -- no way you can mess with it, use push/pop
+-- function os.poplocale()
+-- local l = remove(stack)
+-- if l then
+-- setlocale(unpack(l))
+-- else
+-- resetlocale()
-- end
---
--- setlocale(nil,nil) -- setlocale("all","C")
---
-- end
+local report = logs.reporter("system")
+
+function os.setlocale(a,b)
+ if a or b then
+ if report then
+ report()
+ report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
+ report("now on are on your own and without support. Crashes or unexpected side effects")
+ report("can happen but don't bother the luatex and context developer team with it.")
+ report()
+ report = nil
+ end
+ setlocale(a,b)
+ end
+end
+
-- dirty tricks (we will replace the texlua call by luatex --luaonly)
local validengines = allocate {
diff --git a/tex/context/base/mkiv/util-lib.lua b/tex/context/base/mkiv/util-lib.lua
index e7b6e4875..817ac2753 100644
--- a/tex/context/base/mkiv/util-lib.lua
+++ b/tex/context/base/mkiv/util-lib.lua
@@ -80,6 +80,7 @@ local pathpart = file.pathpart
local nameonly = file.nameonly
local joinfile = file.join
local removesuffix = file.removesuffix
+local addsuffix = file.addsuffix
local findfile = resolvers.findfile
local findfiles = resolvers.findfiles
local expandpaths = resolvers.expandedpathlistfromvariable
@@ -104,14 +105,22 @@ local function locate(required,version,trace,report,action)
local required_path = pathpart(required_full)
local required_base = nameonly(required_full)
if qualifiedpath(required) then
- if isfile(required) then
+ -- also check with suffix
+ if isfile(addsuffix(required,os.libsuffix)) then
+ if trace then
+ report("qualified name %a found",required)
+ end
found_library = required
+ else
+ if trace then
+ report("qualified name %a not found",required)
+ end
end
else
-- initialize a few variables
local required_name = required_base .. "." .. os.libsuffix
local version = type(version) == "string" and version ~= "" and version or false
- local engine = environment.ownmain or false
+ local engine = "luatex" -- environment.ownmain or false
--
if trace and not done then
local list = expandpaths("lib") -- fresh, no reuse
@@ -179,8 +188,9 @@ local function locate(required,version,trace,report,action)
package.extralibpath(environment.ownpath)
local paths = package.libpaths()
for i=1,#paths do
+ required_path = paths[i]
local found = check(lfs.isfile)
- if found and (not checkpattern or find(found,checkpattern)) then
+ if type(found) == "string" and (not checkpattern or find(found,checkpattern)) then
return found
end
end
@@ -211,18 +221,18 @@ local function locate(required,version,trace,report,action)
if trace then
report("found: %a",found_library)
end
- local message, result = action(found_library,required_base)
+ local result, message = action(found_library,required_base)
if result then
library = result
else
library = false
- report("load error: message %a, library %a",tostring(message),found_library or "no library")
+ report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
end
end
if not library then
- report("unknown: %a",required)
+ report("unknown library: %a",required)
elseif trace then
- report("stored: %a",required)
+ report("stored library: %a",required)
end
return library
end
@@ -254,13 +264,12 @@ do
local libtype = type(library)
if libtype == "function" then
library = library()
- message = true
else
report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
library = false
end
popdir()
- return message, library
+ return library
end)
loadedlibs[required] = library or false
end
@@ -336,7 +345,9 @@ We use the same lookup logic for ffi loading.
local function locateindeed(name)
local message, library = pcall(savedffiload,removesuffix(name))
- if type(library) == "userdata" then
+ if type(message) == "userdata" then
+ return message
+ elseif type(library) == "userdata" then
return library
else
return false
diff --git a/tex/context/base/mkiv/util-sql-imp-ffi.lua b/tex/context/base/mkiv/util-sql-imp-ffi.lua
new file mode 100644
index 000000000..152b0fec9
--- /dev/null
+++ b/tex/context/base/mkiv/util-sql-imp-ffi.lua
@@ -0,0 +1,555 @@
+if not modules then modules = { } end modules ['util-sql-imp-ffi'] = {
+ version = 1.001,
+ comment = "companion to util-sql.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- I looked at luajit-mysql to see how the ffi mapping was done but it didn't work
+-- out that well (at least not on windows) but I got the picture. As I have somewhat
+-- different demands I simplified / redid the ffi bti and just took the swiglib
+-- variant and adapted that.
+
+local tonumber = tonumber
+local concat = table.concat
+local format, byte = string.format, string.byte
+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","ffi")
+
+if not utilities.sql then
+ require("util-sql")
+end
+
+ffi.cdef [[
+
+ /*
+ This is as lean and mean as possible. After all we just need a connection and
+ a query. The rest is handled already in the Lua code elsewhere.
+ */
+
+ typedef void MYSQL_instance;
+ typedef void MYSQL_result;
+ typedef char **MYSQL_row;
+ typedef unsigned int MYSQL_offset;
+
+ typedef struct st_mysql_field {
+ char *name;
+ char *org_name;
+ char *table;
+ char *org_table;
+ char *db;
+ char *catalog;
+ char *def;
+ unsigned long length;
+ unsigned long max_length;
+ unsigned int name_length;
+ unsigned int org_name_length;
+ unsigned int table_length;
+ unsigned int org_table_length;
+ unsigned int db_length;
+ unsigned int catalog_length;
+ unsigned int def_length;
+ unsigned int flags;
+ unsigned int decimals;
+ unsigned int charsetnr;
+ int type;
+ void *extension;
+ } MYSQL_field;
+
+ void free(void*ptr);
+ void * malloc(size_t size);
+
+ MYSQL_instance * mysql_init (
+ MYSQL_instance *mysql
+ );
+
+ MYSQL_instance * mysql_real_connect (
+ MYSQL_instance *mysql,
+ const char *host,
+ const char *user,
+ const char *passwd,
+ const char *db,
+ unsigned int port,
+ const char *unix_socket,
+ unsigned long clientflag
+ );
+
+ unsigned int mysql_errno (
+ MYSQL_instance *mysql
+ );
+
+ const char *mysql_error (
+ MYSQL_instance *mysql
+ );
+
+ /* int mysql_query (
+ MYSQL_instance *mysql,
+ const char *q
+ ); */
+
+ int mysql_real_query (
+ MYSQL_instance *mysql,
+ const char *q,
+ unsigned long length
+ );
+
+ MYSQL_result * mysql_store_result (
+ MYSQL_instance *mysql
+ );
+
+ void mysql_free_result (
+ MYSQL_result *result
+ );
+
+ unsigned long long mysql_num_rows (
+ MYSQL_result *res
+ );
+
+ MYSQL_row mysql_fetch_row (
+ MYSQL_result *result
+ );
+
+ unsigned int mysql_num_fields (
+ MYSQL_result *res
+ );
+
+ /* MYSQL_field *mysql_fetch_field (
+ MYSQL_result *result
+ ); */
+
+ MYSQL_field * mysql_fetch_fields (
+ MYSQL_result *res
+ );
+
+ MYSQL_offset mysql_field_seek(
+ MYSQL_result *result,
+ MYSQL_offset offset
+ );
+
+ void mysql_close(
+ MYSQL_instance *sock
+ );
+
+ /* unsigned long * mysql_fetch_lengths(
+ MYSQL_result *result
+ ); */
+
+]]
+
+local sql = utilities.sql
+local mysql = ffi.load(os.name == "windows" and "libmysql" or "libmysqlclient")
+
+local nofretries = 5
+local retrydelay = 1
+
+local cache = { }
+local helpers = sql.helpers
+local methods = sql.methods
+local validspecification = helpers.validspecification
+local querysplitter = helpers.querysplitter
+local dataprepared = helpers.preparetemplate
+local serialize = sql.serialize
+local deserialize = sql.deserialize
+
+local mysql_initialize = mysql.mysql_init
+
+local mysql_open_connection = mysql.mysql_real_connect
+local mysql_execute_query = mysql.mysql_real_query
+local mysql_close_connection = mysql.mysql_close
+
+local mysql_field_seek = mysql.mysql_field_seek
+local mysql_num_fields = mysql.mysql_num_fields
+local mysql_fetch_fields = mysql.mysql_fetch_fields
+----- mysql_fetch_field = mysql.mysql_fetch_field
+local mysql_num_rows = mysql.mysql_num_rows
+local mysql_fetch_row = mysql.mysql_fetch_row
+----- mysql_fetch_lengths = mysql.mysql_fetch_lengths
+local mysql_init = mysql.mysql_init
+local mysql_store_result = mysql.mysql_store_result
+local mysql_free_result = mysql.mysql_free_result
+
+local mysql_error_message = mysql.mysql_error
+
+local NULL = ffi.cast("MYSQL_result *",0)
+
+local ffi_tostring = ffi.string
+local ffi_gc = ffi.gc
+
+----- mysqldata = ffi.cast("MYSQL_instance*",mysql.malloc(1024*1024))
+local instance = mysql.mysql_init(nil) -- (mysqldata)
+
+local mysql_constant_false = false
+local mysql_constant_true = true
+
+local function finish(t)
+ local r = t._result_
+ if r then
+ ffi_gc(r,mysql_free_result)
+ end
+end
+
+local function getcolnames(t)
+ return t.names
+end
+
+local function getcoltypes(t)
+ return t.types
+end
+
+local function numrows(t)
+ return tonumber(t.nofrows)
+end
+
+local function list(t)
+ local result = t._result_
+ if result then
+ local row = mysql_fetch_row(result)
+ -- local len = mysql_fetch_lengths(result)
+ local result = { }
+ for i=1,t.noffields do
+ result[i] = ffi_tostring(row[i-1])
+ end
+ return result
+ end
+end
+
+local function hash(t)
+ local result = t._result_
+ local fields = t.names
+ if result then
+ local row = mysql_fetch_row(result)
+ -- local len = mysql_fetch_lengths(result)
+ local result = { }
+ for i=1,t.noffields do
+ result[fields[i]] = ffi_tostring(row[i-1])
+ end
+ return result
+ end
+end
+
+local function wholelist(t)
+ return fetch_all_rows(t._result_)
+end
+
+local mt = { __index = {
+ -- regular
+ finish = finish,
+ list = list,
+ hash = hash,
+ wholelist = wholelist,
+ -- compatibility
+ numrows = numrows,
+ getcolnames = getcolnames,
+ getcoltypes = getcoltypes,
+ -- fallback
+ _result_ = nil,
+ names = { },
+ types = { },
+ noffields = 0,
+ nofrows = 0,
+ }
+}
+
+local nt = setmetatable({},mt)
+
+-- session
+
+local function close(t)
+ mysql_close_connection(t._connection_)
+end
+
+local function execute(t,query)
+ if query and query ~= "" then
+ local connection = t._connection_
+ local result = mysql_execute_query(connection,query,#query)
+ if result == 0 then
+ local result = mysql_store_result(connection)
+ if result then
+ mysql_field_seek(result,0)
+ local nofrows = tonumber(mysql_num_rows(result) or 0)
+ local noffields = tonumber(mysql_num_fields(result))
+ local names = { }
+ local types = { }
+ local fields = mysql_fetch_fields(result)
+ for i=1,noffields do
+ local field = fields[i-1]
+ names[i] = ffi_tostring(field.name)
+ types[i] = tonumber(field.type) -- todo
+ end
+ local t = {
+ _result_ = result,
+ names = names,
+ types = types,
+ noffields = noffields,
+ nofrows = nofrows,
+ }
+ return setmetatable(t,mt)
+ else
+ return nt
+ end
+ end
+ end
+ return false
+end
+
+local mt = { __index = {
+ close = close,
+ execute = execute,
+ }
+}
+
+local function open(t,database,username,password,host,port)
+ local connection = mysql_open_connection(
+ t._session_,
+ host or "localhost",
+ username or "",
+ password or "",
+ database or "",
+ port or 0,
+ NULL,
+ 0
+ )
+ if connection ~= NULL then
+ local t = {
+ _connection_ = connection,
+ }
+ return setmetatable(t,mt)
+ end
+end
+
+local function message(t)
+ return mysql_error_message(t._session_)
+end
+
+local function close(t)
+ -- dummy, as we have a global session
+end
+
+local mt = {
+ __index = {
+ connect = open,
+ close = close,
+ message = message,
+ }
+}
+
+local function initialize()
+ local session = {
+ _session_ = mysql_initialize(instance) -- maybe share, single thread anyway
+ }
+ return setmetatable(session,mt)
+end
+
+-- -- -- --
+
+local function connect(session,specification)
+ return session:connect(
+ specification.database or "",
+ specification.username or "",
+ specification.password or "",
+ specification.host or "",
+ specification.port
+ )
+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")
+ return { }, { }
+ end
+ local id = specification.id
+ local session, connection
+ if id then
+ local c = cache[id]
+ if c then
+ session = c.session
+ connection = c.connection
+ end
+ if not connection then
+ 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@%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",
+ specification.database or "no database",
+ specification.username or "no username",
+ specification.host or "no host",
+ specification.port or "no port"
+ )
+ return { }, { }
+ end
+ query = lpegmatch(querysplitter,query)
+ local result, message, okay
+ for i=1,#query do
+ local q = query[i]
+ local r, m = connection:execute(q)
+ if m then
+ report_state("error in query, stage: %s",string.collapsespaces(q or "?"))
+ message = message and format("%s\n%s",message,m) or m
+ end
+ if type(r) == "table" then
+ result = r
+ okay = true
+ elseif not m then
+ okay = true
+ end
+ end
+ local data, keys
+ if result then
+ if converter then
+ data = converter.ffi(result)
+ else
+ keys = result.names
+ data = { }
+ for i=1,result.nofrows do
+ data[i] = result:hash()
+ end
+ end
+ result:finish() -- result:close()
+ elseif message then
+ report_state("message %s",message)
+ end
+ if not keys then
+ keys = { }
+ end
+ if not data then
+ data = { }
+ end
+ if not id then
+ connection:close()
+ session:close()
+ end
+ return data, keys
+end
+
+local function execute(specification)
+ if trace_sql then
+ report_state("executing library")
+ end
+ if not validspecification(specification) then
+ report_state("error in specification")
+ return
+ end
+ local query = dataprepared(specification)
+ if not query then
+ report_state("error in preparation")
+ return
+ end
+ local data, keys = datafetched(specification,query,specification.converter)
+ if not data then
+ report_state("error in fetching")
+ return
+ end
+ local one = data[1]
+ if one then
+ setmetatable(data,{ __index = one } )
+ end
+ return data, keys
+end
+
+local wraptemplate = [[
+local mysql = ffi.load(os.name == "windows" and "libmysql" or "libmysqlclient")
+
+local mysql_fetch_row = mysql.mysql_fetch_row
+local ffi_tostring = ffi.string
+
+local converters = utilities.sql.converters
+local deserialize = utilities.sql.deserialize
+
+local tostring = tostring
+local tonumber = tonumber
+local booleanstring = string.booleanstring
+
+%s
+
+return function(result)
+ if not result then
+ return { }
+ end
+ local nofrows = result.nofrows or 0
+ if nofrows == 0 then
+ return { }
+ end
+ local noffields = result.noffields or 0
+ local _result_ = result._result_
+ local target = { } -- no %s needed here
+ for i=1,nofrows do
+ local cells = { }
+ local row = mysql_fetch_row(_result_)
+ for j=1,noffields do
+ cells[j] = ffi_tostring(row[j-1])
+ end
+ target[%s] = {
+ %s
+ }
+ end
+ result:finish() -- result:close()
+ return target
+end
+]]
+
+local celltemplate = "cells[%s]"
+
+methods.ffi = {
+ runner = function() end, -- never called
+ execute = execute,
+ initialize = initialize, -- returns session
+ usesfiles = false,
+ wraptemplate = wraptemplate,
+ celltemplate = celltemplate,
+}
diff --git a/tex/context/base/mkiv/util-sql.lua b/tex/context/base/mkiv/util-sql.lua
index 09056c048..0eff25130 100644
--- a/tex/context/base/mkiv/util-sql.lua
+++ b/tex/context/base/mkiv/util-sql.lua
@@ -103,7 +103,7 @@ local defaults = { __index =
variables = { },
username = "default",
password = "default",
- host = "localhost",
+ host = "localhost", -- 127.0.0.1 is sometimes more reliable
port = 3306,
database = "default",
},
@@ -285,7 +285,13 @@ local currentmethod
local currentserver
local function firstexecute(...)
- local execute = methods[currentmethod].execute
+ local method = methods[currentmethod]
+ if not method then
+ report_state("invalid sql method")
+ sql.execute = function() end
+ return nil
+ end
+ local execute = method.execute
sql.execute = execute
return execute(...)
end