diff options
-rw-r--r-- | scripts/context/lua/mtx-context.lua | 7 | ||||
-rw-r--r-- | scripts/context/lua/mtxrun.lua | 124 | ||||
-rw-r--r-- | scripts/context/stubs/mswin/mtxrun.lua | 124 | ||||
-rwxr-xr-x | scripts/context/stubs/unix/mtxrun | 124 | ||||
-rw-r--r-- | tex/context/base/context-version.pdf | bin | 4087 -> 4091 bytes | |||
-rw-r--r-- | tex/context/base/context-version.png | bin | 106215 -> 106085 bytes | |||
-rw-r--r-- | tex/context/base/lpdf-ini.lua | 2 | ||||
-rw-r--r-- | tex/context/base/node-ref.lua | 2 | ||||
-rw-r--r-- | tex/context/base/s-mat-12.mkiv | 6 | ||||
-rw-r--r-- | tex/context/base/scrn-but.mkvi | 96 | ||||
-rw-r--r-- | tex/context/base/status-files.pdf | bin | 23927 -> 23921 bytes | |||
-rw-r--r-- | tex/context/base/status-lua.pdf | bin | 162341 -> 162347 bytes | |||
-rw-r--r-- | tex/context/base/strc-itm.mkiv | 9 | ||||
-rw-r--r-- | tex/context/base/strc-ref.lua | 175 | ||||
-rw-r--r-- | tex/context/base/strc-ref.mkiv | 2 | ||||
-rw-r--r-- | tex/context/base/trac-log.lua | 52 | ||||
-rw-r--r-- | tex/context/base/util-deb.lua | 101 |
17 files changed, 495 insertions, 329 deletions
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua index a5ccc8a9a..43dcd3455 100644 --- a/scripts/context/lua/mtx-context.lua +++ b/scripts/context/lua/mtx-context.lua @@ -474,7 +474,7 @@ function scripts.context.multipass.changed(oldhash, newhash) return false end -function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,currentrun,finalrun) +function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,currentrun,finalrun,once) -- take jobname from ctx jobname = file.removesuffix(jobname) local f = io.open(jobname..".top","w") @@ -554,6 +554,9 @@ function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,curr setvalue ("setuppath" , "\\setupsystem[\\c!directory={%s}]") setvalue ("randomseed" , "\\setupsystem[\\c!random=%s]") setvalue ("arguments" , "\\setupenv[%s]") + if once then + setalways("\\enabledirectives[system.runonce]") + end setalways("%% modes") setvalues("modefile" , "\\readlocfile{%s}{}{}") setvalues("mode" , "\\enablemode[%s]", true) @@ -907,7 +910,7 @@ function scripts.context.run(ctxdata,filename) for i=1,maxnofruns do -- 1:first run, 2:successive run, 3:once, 4:last of maxruns local kindofrun = (once and 3) or (i==1 and 1) or (i==maxnofruns and 4) or 2 - scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,i,false) -- kindofrun, currentrun, final + scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,i,false,once) -- kindofrun, currentrun, final report("run %s: %s",i,command) --~ print("\n") -- cleaner, else continuation on same line print("") -- cleaner, else continuation on same line diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 3953eeea2..91491c3d6 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -4821,61 +4821,55 @@ local names = { } -- one local function hook() - local f = getinfo(2,"f").func - local n = getinfo(2,"Sn") --- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + local f = getinfo(2) -- "nS" if f then - local cf = counters[f] - if cf == nil then - counters[f] = 1 - names[f] = n - else - counters[f] = cf + 1 - end - end -end - -local function getname(func) - local n = names[func] - if n then - if n.what == "C" then - return n.name or '<anonymous>' + local n = "unknown" + if f.what == "C" then + n = f.name or '<anonymous>' + if not names[n] then + names[n] = format("%42s",n) + end else -- source short_src linedefined what name namewhat nups func - local name = n.name or n.namewhat or n.what - if not name or name == "" then name = "?" end - return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + n = f.name or f.namewhat or f.what + if not n or n == "" then + n = "?" + end + if not names[n] then + names[n] = format("%42s : % 5i : %s",n,f.linedefined or 0,f.short_src or "unknown source") + end end - else - return "unknown" + counters[n] = (counters[n] or 0) + 1 end end -function debugger.showstats(printer,threshold) +function debugger.showstats(printer,threshold) -- hm, something has changed, rubish now printer = printer or texio.write or print threshold = threshold or 0 local total, grandtotal, functions = 0, 0, 0 - printer("\n") -- ugly but ok - -- table.sort(counters) - for func, count in next, counters do - if count > threshold then - local name = getname(func) - if not find(name,"for generator") then - printer(format("%8i %s", count, name)) - total = total + count - end + local dataset = { } + for name, count in next, counters do + dataset[#dataset+1] = { name, count } + end + table.sort(dataset,function(a,b) return a[2] == b[2] and b[1] > a[1] or a[2] > b[2] end) + for i=1,#dataset do + local d = dataset[i] + local name = d[1] + local count = d[2] + if count > threshold and not find(name,"for generator") then -- move up + printer(format("%8i %s\n", count, names[name])) + total = total + count end grandtotal = grandtotal + count functions = functions + 1 end - printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) + printer("\n") + printer(format("functions : % 10i\n", functions)) + printer(format("total : % 10i\n", total)) + printer(format("grand total: % 10i\n", grandtotal)) + printer(format("threshold : % 10i\n", threshold)) end --- two - - --- rest - function debugger.savestats(filename,threshold) local f = io.open(filename,'w') if f then @@ -5875,19 +5869,55 @@ function logs.start_page_number() real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno end -function logs.stop_page_number() - if real > 0 then - if user > 0 then - if sub > 0 then - report_pages("flushing realpage %s, userpage %s, subpage %s",real,user,sub) +local timing = false +local starttime = nil +local lasttime = nil + +trackers.register("pages.timing", function(v) -- only for myself (diagnostics) + starttime = os.clock() + timing = true +end) + +function logs.stop_page_number() -- the first page can includes the initialization so we omit this in average + if timing then + local elapsed, average + local stoptime = os.clock() + if not lasttime or real < 2 then + elapsed = stoptime + average = stoptime + starttime = stoptime + else + elapsed = stoptime - lasttime + average = (stoptime - starttime) / (real - 1) + end + lasttime = stoptime + if real > 0 then + if user > 0 then + if sub > 0 then + report_pages("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average) + else + report_pages("flushing realpage %s, userpage %s, time %0.04f / %0.04f",real,user,elapsed,average) + end else - report_pages("flushing realpage %s, userpage %s",real,user) + report_pages("flushing realpage %s, time %0.04f / %0.04f",real,elapsed,average) end else - report_pages("flushing realpage %s",real) + report_pages("flushing page, time %0.04f / %0.04f",elapsed,average) end else - report_pages("flushing page") + if real > 0 then + if user > 0 then + if sub > 0 then + report_pages("flushing realpage %s, userpage %s, subpage %s",real,user,sub) + else + report_pages("flushing realpage %s, userpage %s",real,user) + end + else + report_pages("flushing realpage %s",real) + end + else + report_pages("flushing page") + end end logs.flush() end diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index 3953eeea2..91491c3d6 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -4821,61 +4821,55 @@ local names = { } -- one local function hook() - local f = getinfo(2,"f").func - local n = getinfo(2,"Sn") --- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + local f = getinfo(2) -- "nS" if f then - local cf = counters[f] - if cf == nil then - counters[f] = 1 - names[f] = n - else - counters[f] = cf + 1 - end - end -end - -local function getname(func) - local n = names[func] - if n then - if n.what == "C" then - return n.name or '<anonymous>' + local n = "unknown" + if f.what == "C" then + n = f.name or '<anonymous>' + if not names[n] then + names[n] = format("%42s",n) + end else -- source short_src linedefined what name namewhat nups func - local name = n.name or n.namewhat or n.what - if not name or name == "" then name = "?" end - return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + n = f.name or f.namewhat or f.what + if not n or n == "" then + n = "?" + end + if not names[n] then + names[n] = format("%42s : % 5i : %s",n,f.linedefined or 0,f.short_src or "unknown source") + end end - else - return "unknown" + counters[n] = (counters[n] or 0) + 1 end end -function debugger.showstats(printer,threshold) +function debugger.showstats(printer,threshold) -- hm, something has changed, rubish now printer = printer or texio.write or print threshold = threshold or 0 local total, grandtotal, functions = 0, 0, 0 - printer("\n") -- ugly but ok - -- table.sort(counters) - for func, count in next, counters do - if count > threshold then - local name = getname(func) - if not find(name,"for generator") then - printer(format("%8i %s", count, name)) - total = total + count - end + local dataset = { } + for name, count in next, counters do + dataset[#dataset+1] = { name, count } + end + table.sort(dataset,function(a,b) return a[2] == b[2] and b[1] > a[1] or a[2] > b[2] end) + for i=1,#dataset do + local d = dataset[i] + local name = d[1] + local count = d[2] + if count > threshold and not find(name,"for generator") then -- move up + printer(format("%8i %s\n", count, names[name])) + total = total + count end grandtotal = grandtotal + count functions = functions + 1 end - printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) + printer("\n") + printer(format("functions : % 10i\n", functions)) + printer(format("total : % 10i\n", total)) + printer(format("grand total: % 10i\n", grandtotal)) + printer(format("threshold : % 10i\n", threshold)) end --- two - - --- rest - function debugger.savestats(filename,threshold) local f = io.open(filename,'w') if f then @@ -5875,19 +5869,55 @@ function logs.start_page_number() real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno end -function logs.stop_page_number() - if real > 0 then - if user > 0 then - if sub > 0 then - report_pages("flushing realpage %s, userpage %s, subpage %s",real,user,sub) +local timing = false +local starttime = nil +local lasttime = nil + +trackers.register("pages.timing", function(v) -- only for myself (diagnostics) + starttime = os.clock() + timing = true +end) + +function logs.stop_page_number() -- the first page can includes the initialization so we omit this in average + if timing then + local elapsed, average + local stoptime = os.clock() + if not lasttime or real < 2 then + elapsed = stoptime + average = stoptime + starttime = stoptime + else + elapsed = stoptime - lasttime + average = (stoptime - starttime) / (real - 1) + end + lasttime = stoptime + if real > 0 then + if user > 0 then + if sub > 0 then + report_pages("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average) + else + report_pages("flushing realpage %s, userpage %s, time %0.04f / %0.04f",real,user,elapsed,average) + end else - report_pages("flushing realpage %s, userpage %s",real,user) + report_pages("flushing realpage %s, time %0.04f / %0.04f",real,elapsed,average) end else - report_pages("flushing realpage %s",real) + report_pages("flushing page, time %0.04f / %0.04f",elapsed,average) end else - report_pages("flushing page") + if real > 0 then + if user > 0 then + if sub > 0 then + report_pages("flushing realpage %s, userpage %s, subpage %s",real,user,sub) + else + report_pages("flushing realpage %s, userpage %s",real,user) + end + else + report_pages("flushing realpage %s",real) + end + else + report_pages("flushing page") + end end logs.flush() end diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index 3953eeea2..91491c3d6 100755 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -4821,61 +4821,55 @@ local names = { } -- one local function hook() - local f = getinfo(2,"f").func - local n = getinfo(2,"Sn") --- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + local f = getinfo(2) -- "nS" if f then - local cf = counters[f] - if cf == nil then - counters[f] = 1 - names[f] = n - else - counters[f] = cf + 1 - end - end -end - -local function getname(func) - local n = names[func] - if n then - if n.what == "C" then - return n.name or '<anonymous>' + local n = "unknown" + if f.what == "C" then + n = f.name or '<anonymous>' + if not names[n] then + names[n] = format("%42s",n) + end else -- source short_src linedefined what name namewhat nups func - local name = n.name or n.namewhat or n.what - if not name or name == "" then name = "?" end - return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + n = f.name or f.namewhat or f.what + if not n or n == "" then + n = "?" + end + if not names[n] then + names[n] = format("%42s : % 5i : %s",n,f.linedefined or 0,f.short_src or "unknown source") + end end - else - return "unknown" + counters[n] = (counters[n] or 0) + 1 end end -function debugger.showstats(printer,threshold) +function debugger.showstats(printer,threshold) -- hm, something has changed, rubish now printer = printer or texio.write or print threshold = threshold or 0 local total, grandtotal, functions = 0, 0, 0 - printer("\n") -- ugly but ok - -- table.sort(counters) - for func, count in next, counters do - if count > threshold then - local name = getname(func) - if not find(name,"for generator") then - printer(format("%8i %s", count, name)) - total = total + count - end + local dataset = { } + for name, count in next, counters do + dataset[#dataset+1] = { name, count } + end + table.sort(dataset,function(a,b) return a[2] == b[2] and b[1] > a[1] or a[2] > b[2] end) + for i=1,#dataset do + local d = dataset[i] + local name = d[1] + local count = d[2] + if count > threshold and not find(name,"for generator") then -- move up + printer(format("%8i %s\n", count, names[name])) + total = total + count end grandtotal = grandtotal + count functions = functions + 1 end - printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) + printer("\n") + printer(format("functions : % 10i\n", functions)) + printer(format("total : % 10i\n", total)) + printer(format("grand total: % 10i\n", grandtotal)) + printer(format("threshold : % 10i\n", threshold)) end --- two - - --- rest - function debugger.savestats(filename,threshold) local f = io.open(filename,'w') if f then @@ -5875,19 +5869,55 @@ function logs.start_page_number() real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno end -function logs.stop_page_number() - if real > 0 then - if user > 0 then - if sub > 0 then - report_pages("flushing realpage %s, userpage %s, subpage %s",real,user,sub) +local timing = false +local starttime = nil +local lasttime = nil + +trackers.register("pages.timing", function(v) -- only for myself (diagnostics) + starttime = os.clock() + timing = true +end) + +function logs.stop_page_number() -- the first page can includes the initialization so we omit this in average + if timing then + local elapsed, average + local stoptime = os.clock() + if not lasttime or real < 2 then + elapsed = stoptime + average = stoptime + starttime = stoptime + else + elapsed = stoptime - lasttime + average = (stoptime - starttime) / (real - 1) + end + lasttime = stoptime + if real > 0 then + if user > 0 then + if sub > 0 then + report_pages("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average) + else + report_pages("flushing realpage %s, userpage %s, time %0.04f / %0.04f",real,user,elapsed,average) + end else - report_pages("flushing realpage %s, userpage %s",real,user) + report_pages("flushing realpage %s, time %0.04f / %0.04f",real,elapsed,average) end else - report_pages("flushing realpage %s",real) + report_pages("flushing page, time %0.04f / %0.04f",elapsed,average) end else - report_pages("flushing page") + if real > 0 then + if user > 0 then + if sub > 0 then + report_pages("flushing realpage %s, userpage %s, subpage %s",real,user,sub) + else + report_pages("flushing realpage %s, userpage %s",real,user) + end + else + report_pages("flushing realpage %s",real) + end + else + report_pages("flushing page") + end end logs.flush() end diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf Binary files differindex 0be1fa7e4..d73fa6cf9 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 d431ee2e3..e13718c5a 100644 --- a/tex/context/base/context-version.png +++ b/tex/context/base/context-version.png diff --git a/tex/context/base/lpdf-ini.lua b/tex/context/base/lpdf-ini.lua index e07f9748a..88999358c 100644 --- a/tex/context/base/lpdf-ini.lua +++ b/tex/context/base/lpdf-ini.lua @@ -234,7 +234,7 @@ local mt_f = { __lpdftype = "false", __tostring = tostring_f, __call = valu local mt_r = { __lpdftype = "reference", __tostring = tostring_r, __call = value_r } local mt_v = { __lpdftype = "verbose", __tostring = tostring_v, __call = value_v } -local function pdfstream(t) -- we need to add attrbutes +local function pdfstream(t) -- we need to add attributes if t then for i=1,#t do t[i] = tostring(t[i]) diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua index fd01f4fba..278a40b6e 100644 --- a/tex/context/base/node-ref.lua +++ b/tex/context/base/node-ref.lua @@ -222,7 +222,7 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx elseif id == glue_code and current.subtype == leftskip_code then -- any glue at the left? -- elseif id == hlist_code or id == vlist_code then --- somehow reference is true so teh following fails (second one not done) in +-- somehow reference is true so the following fails (second one not done) in -- test \goto{test}[page(2)] test \gotobox{test}[page(2)] -- so let's wait till this fails again -- if not reference and r and (not skip or r > skip) then -- > or ~= diff --git a/tex/context/base/s-mat-12.mkiv b/tex/context/base/s-mat-12.mkiv index 06f3fee10..2b023ff29 100644 --- a/tex/context/base/s-mat-12.mkiv +++ b/tex/context/base/s-mat-12.mkiv @@ -1,5 +1,7 @@ \usemodule[s][mat-10] +% \enabletrackers[pages.timing] + % todo: mode for screen % todo: variant for HD with one menu at the right (with include menu) @@ -147,9 +149,7 @@ \startgot [U+02200] operators \stopgot \quad \startgot [U+02701] symbols a \stopgot \quad \startgot [U+02901] symbols b \stopgot \quad - \startgot [U+02A00] supplemental \stopgot \quad -% \startgot [U+02070] superscripts \stopgot \quad -% \startgot [U+02070] subscripts \stopgot + \startgot [U+02A00] supplemental \stopgot \stopinteractionmenu \defineframed diff --git a/tex/context/base/scrn-but.mkvi b/tex/context/base/scrn-but.mkvi index fee8e757c..7370d944f 100644 --- a/tex/context/base/scrn-but.mkvi +++ b/tex/context/base/scrn-but.mkvi @@ -166,39 +166,46 @@ \endgroup} \def\scrn_button_make_yes - {\ifcase\referencepagestate\relax - \expandafter\scrn_button_make_normal % no state : something else than a page reference + {\scratchcounter\referencerealpage\relax % called in otr + \ifcase\scratchcounter + \expandafter\scrn_button_make_normal % no state : something else than a page reference + \else\ifnum\scratchcounter=\realpageno + \expandafter\expandafter\expandafter\scrn_button_make_yes_same + \else + \expandafter\expandafter\expandafter\scrn_button_make_yes_other + \fi\fi} + +\def\scrn_button_make_yes_same + {\ifcase\locationboxpagestate\relax + \expandafter\scrn_button_make_contrast % same page: yes: same page or not ... todo \or - \ifcase\locationboxpagestate\relax - \expandafter\expandafter\expandafter\scrn_button_make_contrast % same page: yes: same page or not ... todo - \or - \expandafter\expandafter\expandafter\scrn_button_make_empty % same page: empty but frame: no click - \or - \expandafter\expandafter\expandafter\scrn_button_make_nothing % same page: empty no frame: no - \else - \expandafter\expandafter\expandafter\scrn_button_make_skipped % same page: nothing at all - \fi + \expandafter\scrn_button_make_empty % same page: empty but frame: no click + \or + \expandafter\scrn_button_make_nothing % same page: empty no frame: no \else - \ifcase\locationboxpagestate\relax - \expandafter\expandafter\expandafter\scrn_button_make_normal % other page: yes: same page or not ... todo - \or - \expandafter\expandafter\expandafter\scrn_button_make_normal % other page: empty but frame: no click - \or - \expandafter\expandafter\expandafter\scrn_button_make_normal % other page: empty no frame: no - \else - \expandafter\expandafter\expandafter\scrn_button_make_skipped % other page: nothing at all - \fi% + \expandafter\scrn_button_make_skipped % same page: nothing at all + \fi} + +\def\scrn_button_make_yes_other + {\ifcase\locationboxpagestate\relax + \expandafter\scrn_button_make_normal % other page: yes: same page or not ... todo + \or + \expandafter\scrn_button_make_normal % other page: empty but frame: no click + \or + \expandafter\scrn_button_make_normal % other page: empty no frame: no + \else + \expandafter\scrn_button_make_skipped % other page: nothing at all \fi} \def\scrn_button_make_nop {\ifcase\locationboxpagestate\relax - \expandafter\scrn_button_make_framed + \expandafter\scrn_button_make_framed \or - \expandafter\scrn_button_make_empty + \expandafter\scrn_button_make_empty \or - \expandafter\scrn_button_make_nothing + \expandafter\scrn_button_make_nothing \or - \expandafter\scrn_button_make_skipped + \expandafter\scrn_button_make_skipped \fi} \def\scrn_button_make_framed#currentparameter#inheritedframed#letparameter#setparameter#text% @@ -326,25 +333,6 @@ \unexpanded\def\defineinteractionmenu {\dotripleempty\scrn_menu_define} -% \def\scrn_menu_define[#tag][#category][#settings]% category reflects location, settings can be parent -% {\ifthirdargument -% \doifassignmentelse{#settings}% -% {\scrn_menu_define_original[#tag][#category][\c!category=#category,#settings]}% child definition -% {\scrn_menu_define_original[#tag][#settings][\c!category=#category]}% % child definition -% \scrn_menu_register{#tag}{#category}% -% \setevalue{\??am:#tag\s!parent}{\namedinteractionmenuhash{#tag}}% framed -% \else\ifsecondargument -% \doifassignmentelse{#category}% -% {\scrn_menu_define_original[#tag][#category]% % root definition -% \setevalue{\??am:#tag\s!parent}{\namedinteractionmenuhash\empty}}% framed -% {\scrn_menu_define_original[#tag][#category][\c!category=#category]% % child definition -% \scrn_menu_register{#tag}{#category}% -% \setevalue{\??am:#tag\s!parent}{\namedinteractionmenuhash{#tag}}}% framed -% \else -% \scrn_menu_define_original[#tag]% % root definition -% \setevalue{\??am:#tag\s!parent}{\namedinteractionmenuhash\empty}% framed -% \fi\fi} - \def\scrn_menu_define[#tag][#category][#settings]% category reflects location, settings can be parent {\ifthirdargument \doifassignmentelse{#settings}% @@ -545,13 +533,15 @@ %D With the packager being one of: +\let\currentinteractionmenudistance\!!zeropoint + \def\scrn_menu_packager_vertical {\scrn_menu_set_used \hskip\scrn_menu_next_distance \setbox\scrn_menu_box\hbox to \scrn_menu_used_width {\ifx\currentinteractionmenustate\v!empty \else \interactionmenuparameter\c!left - \scrn_menu_package_vertical{\interactionmenuparameter\c!menu}% + \scrn_menu_package_vertical{\strictinteractionmenuparameter\c!menu}% \interactionmenuparameter\c!right \fi}% \edef\currentinteractionmenudistance{\interactionmenuparameter\c!distance}% @@ -572,7 +562,7 @@ {\ifx\currentinteractionmenustate\v!none \else \scrn_menu_top_align \interactionmenuparameter\c!before - \scrn_menu_package_horizontal{\interactionmenuparameter\c!menu}% + \scrn_menu_package_horizontal{\strictinteractionmenuparameter\c!menu}% \interactionmenuparameter\c!after \scrn_menu_bottom_align \fi}% @@ -756,13 +746,13 @@ \newtoks\everysetmenucommands % public \appendtoks - \let\raw\scrn_menu_raw \let\startraw\scrn_menu_raw_start - \let\but\scrn_menu_but \let\startbut\scrn_menu_but_start - \let\got\scrn_menu_got \let\startgot\scrn_menu_got_start - \let\nop\scrn_menu_nop \let\startnop\scrn_menu_nop_start - \let\txt\scrn_menu_txt \let\starttxt\scrn_menu_txt_start - \let\rul\scrn_menu_rul \let\startrul\scrn_menu_rul_start - \let\com\scrn_menu_com \let\startcom\scrn_menu_com_start + \let\raw\scrn_menu_raw \let\startraw\scrn_menu_raw_start \let\stopraw\relax + \let\but\scrn_menu_but \let\startbut\scrn_menu_but_start \let\stopbut\relax + \let\got\scrn_menu_got \let\startgot\scrn_menu_got_start \let\stopgot\relax + \let\nop\scrn_menu_nop \let\startnop\scrn_menu_nop_start \let\stopnop\relax + \let\txt\scrn_menu_txt \let\starttxt\scrn_menu_txt_start \let\stoptxt\relax + \let\rul\scrn_menu_rul \let\startrul\scrn_menu_rul_start \let\stoprul\relax + \let\com\scrn_menu_com \let\startcom\scrn_menu_com_start \let\stopcom\relax \to \everysetmenucommands %D Sometimes handy: @@ -785,7 +775,7 @@ \doif{\interactionmenuparameter\c!state}\v!local {\letinteractionmenuparameter\c!state\v!start % \setinteractionmenuparameter\s!parent{\??am\askedinteractionmenulocation}% nice hack - \interactionmenuparameter\c!menu}% + \strictinteractionmenuparameter\c!menu}% \endgroup} %D Direct call (todo): diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf Binary files differindex dd9d4527a..ad2aeb294 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 db18aa1e8..7c7862d5a 100644 --- a/tex/context/base/status-lua.pdf +++ b/tex/context/base/status-lua.pdf diff --git a/tex/context/base/strc-itm.mkiv b/tex/context/base/strc-itm.mkiv index 14bfd75fa..16c97e691 100644 --- a/tex/context/base/strc-itm.mkiv +++ b/tex/context/base/strc-itm.mkiv @@ -423,7 +423,11 @@ \unexpanded\def\actualitemnumber {\ifconditional\repeatlistitem - \ifcase\currentitemlevel\or\else + \ifcase\currentitemlevel + % skip + \or + \doactualitemnumber % this could become an option + \else \doactualitemnumber \fi \else @@ -1139,7 +1143,8 @@ \ignorespaces} \def\doitemgroupnoitem - {\doadvanceitem\donolistitem} + {\let\currentitemreference\empty + \doadvanceitem\donolistitem} % For Frank Grieshaber and Mojca Miklavec: diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua index d117d3c32..a43b83cc3 100644 --- a/tex/context/base/strc-ref.lua +++ b/tex/context/base/strc-ref.lua @@ -104,42 +104,90 @@ end job.register('structures.references.collected', tobesaved, initializer, finalizer) local maxreferred = 1 +local nofreferred = 0 local function initializer() -- can we use a tobesaved as metatable for collected? tobereferred = references.tobereferred referred = references.referred - local function get(t,n) -- catch sparse, a bit slow but who cares - for i=n,1,-1 do -- we could make a tree ... too much work - local p = rawget(t,i) - if p then - return p - end - end - end - setmetatableindex(referred, get) + nofreferred = #referred end -local function finalizer() -- make sparse - local last +local function initializer() -- can we use a tobesaved as metatable for collected? + tobereferred = references.tobereferred + referred = references.referred + setmetatableindex(referred,get) +end + +-- We make the array sparse (maybe a finalizer should optionally return a table) because +-- there can be quite some page links involved. We only store one action number per page +-- which is normally good enough for what we want (e.g. see above/below) and we do +-- a combination of a binary search and traverse backwards. A previous implementation +-- always did a traverse and was pretty slow on a large number of links (given that this +-- methods was used). It took me about a day to locate this as a bottleneck in processing +-- a 2500 page interactive document with 60 links per page. In that case, traversing +-- thousands of slots per link then brings processing to a grinding halt (especially when +-- there are no slots at all, which is the case in a first run). + +local sparsetobereferred = { } + +local function finalizer() + local lastr, lasti + local n = 0 for i=1,maxreferred do local r = tobereferred[i] - if not last then - last = r - elseif r == last then - tobereferred[i] = nil - else - last = r + if not lastr then + lastr = r + lasti = i + elseif r ~= lastr then + n = n + 1 + sparsetobereferred[n] = { lastr, lasti } + lastr = r + lasti = i end end + if lastr then + n = n + 1 + sparsetobereferred[n] = { lastr, lasti } + end end -job.register('structures.references.referred', tobereferred, initializer, finalizer) - -function references.referredpage(n) - return referred[n] or referred[n] or texcount.realpageno +job.register('structures.references.referred', sparsetobereferred, initializer, finalizer) + +local function referredpage(n) + local max = nofreferred + if max > 0 then + -- find match + local min = 1 + while true do + local mid = floor((min+max)/2) + local r = referred[mid] + local m = r[2] + if n == m then + return r[1] + elseif n > m then + min = mid + 1 + else + max = mid - 1 + end + if min > max then + break + end + end + -- find first previous + for i=min,1,-1 do + local r = referred[i] + if r and r[2] < n then + return r[1] + end + end + end + -- fallback + return texcount.realpageno end -function references.registerpage(n) +references.referredpage = referredpage + +function references.registerpage(n) -- called in the backend code if not tobereferred[n] then if n > maxreferred then maxreferred = n @@ -358,8 +406,9 @@ references.split = splitreference -- -- -- related to strc-ini.lua -- -- -- references.resolvers = references.resolvers or { } +local resolvers = references.resolvers -function references.resolvers.section(var) +function resolvers.section(var) local vi = lists.collected[var.i[2]] if vi then var.i = vi @@ -370,12 +419,12 @@ function references.resolvers.section(var) end end -references.resolvers.float = references.resolvers.section -references.resolvers.description = references.resolvers.section -references.resolvers.formula = references.resolvers.section -references.resolvers.note = references.resolvers.section +resolvers.float = resolvers.section +resolvers.description = resolvers.section +resolvers.formula = resolvers.section +resolvers.note = resolvers.section -function references.resolvers.reference(var) +function resolvers.reference(var) local vi = var.i[2] if vi then var.i = vi @@ -787,7 +836,6 @@ end local strict = false local function resolve(prefix,reference,args,set) -- we start with prefix,reference - texcount.referencehastexstate = 0 if reference and reference ~= "" then if not set then set = { prefix = prefix, reference = reference } @@ -849,9 +897,6 @@ local function resolve(prefix,reference,args,set) -- we start with prefix,refere end end end - if set.has_tex then - texcount.referencehastexstate = 1 - end return set else return { } @@ -945,6 +990,7 @@ local n = 0 local function identify(prefix,reference) local set = resolve(prefix,reference) local bug = false + texcount.referencehastexstate = set.has_tex and 1 or 0 n = n + 1 set.n = n for i=1,#set do @@ -995,7 +1041,7 @@ local function identify(prefix,reference) var.kind = "outer with inner" end var.i = { "reference", r } - references.resolvers.reference(var) + resolvers.reference(var) var.f = outer var.e = true -- external end @@ -1017,7 +1063,7 @@ local function identify(prefix,reference) var.kind = "outer with inner" end var.i = r - references.resolvers[r[1]](var) + resolvers[r[1]](var) var.f = outer end end @@ -1060,7 +1106,7 @@ local function identify(prefix,reference) var.kind = "outer with inner" end var.i = { "reference", inner } - references.resolvers.reference(var) + resolvers.reference(var) var.f = outer elseif special then local s = specials[special] @@ -1135,7 +1181,7 @@ local function identify(prefix,reference) end if i then var.i = { "reference", i } - references.resolvers.reference(var) + resolvers.reference(var) var.kind = "inner" var.p = p else @@ -1172,7 +1218,7 @@ local function identify(prefix,reference) if i then var.kind = "inner" var.i = i - references.resolvers[i[1]](var) + resolvers[i[1]](var) var.p = p else -- no prefixes here @@ -1186,7 +1232,7 @@ local function identify(prefix,reference) if i then var.kind = "inner" var.i = { "reference", i } - references.resolvers.reference(var) + resolvers.reference(var) var.p = "" else var.error = "unknown inner or special" @@ -1488,8 +1534,12 @@ references.testspecials = references.testspecials or { } local runners = references.testrunners local specials = references.testspecials +-- We need to prevent ending up in the 'relative location' analyzer as it is +-- pretty slow (progressively). In the pagebody one can best check the reference +-- real page to determine if we need contrastlocation as that is more lightweight. + local function checkedpagestate(n,page) - local r, p = referred[n] or texcount.realpageno, tonumber(page) + local r, p = referredpage(n), tonumber(page) if not p then return 0 elseif p > r then @@ -1501,18 +1551,15 @@ local function checkedpagestate(n,page) end end -function references.analyze(actions) +local function setreferencerealpage(actions) actions = actions or references.currentset if not actions then - actions = { realpage = 0, pagestate = 0 } - elseif actions.pagestate then - -- already done - elseif actions.realpage then - actions.pagestate = checkedpagestate(actions.n,actions.realpage) + return 0 else - -- we store some analysis data alongside the indexed array - -- at this moment only the real reference page is analyzed - -- normally such an analysis happens in the backend code + local realpage = actions.realpage + if realpage then + return realpage + end local nofactions = #actions if nofactions > 0 then for i=1,nofactions do @@ -1522,9 +1569,32 @@ function references.analyze(actions) what = what(a,actions) -- needs documentation end end - actions.pagestate = checkedpagestate(actions.n,actions.realpage) - else + realpage = actions.realpage + if realpage then + return realpage + end + end + actions.realpage = 0 + return 0 + end +end + +-- we store some analysis data alongside the indexed array +-- at this moment only the real reference page is analyzed +-- normally such an analysis happens in the backend code + +function references.analyze(actions) + actions = actions or references.currentset + if not actions then + actions = { realpage = 0, pagestate = 0 } + elseif actions.pagestate then + -- already done + else + local realpage = actions.realpage or setreferencerealpage(actions) + if realpage == 0 then actions.pagestate = 0 + else + actions.pagestate = checkedpagestate(actions.n,realpage) end end return actions @@ -1542,6 +1612,11 @@ function commands.referencepagestate(actions) end end +function commands.referencerealpage(actions) + actions = actions or references.currentset + context(not actions and 0 or actions.realpage or setreferencerealpage(actions)) +end + local plist, nofrealpages local function realpageofpage(p) diff --git a/tex/context/base/strc-ref.mkiv b/tex/context/base/strc-ref.mkiv index 5c97fba5d..88ed25819 100644 --- a/tex/context/base/strc-ref.mkiv +++ b/tex/context/base/strc-ref.mkiv @@ -293,6 +293,7 @@ \newcount\referencehastexstate % set in backend \def\referencepagestate{\ctxcommand{referencepagestate()}} +\def\referencerealpage {\ctxcommand{referencerealpage ()}} % referencepagestate: % @@ -971,6 +972,7 @@ \defaultrightreferencetoks \let\rightofreferencecontent\empty \fi + % inefficient: double resolve \doifreferencefoundelse{#4} % we need to resolve the text {\goto{\referencesequence}[#4]} {\let\currentreferencecontent\dummyreference diff --git a/tex/context/base/trac-log.lua b/tex/context/base/trac-log.lua index b46075321..fb3a7a6f7 100644 --- a/tex/context/base/trac-log.lua +++ b/tex/context/base/trac-log.lua @@ -405,19 +405,55 @@ function logs.start_page_number() real, user, sub = texcount.realpageno, texcount.userpageno, texcount.subpageno end -function logs.stop_page_number() - if real > 0 then - if user > 0 then - if sub > 0 then - report_pages("flushing realpage %s, userpage %s, subpage %s",real,user,sub) +local timing = false +local starttime = nil +local lasttime = nil + +trackers.register("pages.timing", function(v) -- only for myself (diagnostics) + starttime = os.clock() + timing = true +end) + +function logs.stop_page_number() -- the first page can includes the initialization so we omit this in average + if timing then + local elapsed, average + local stoptime = os.clock() + if not lasttime or real < 2 then + elapsed = stoptime + average = stoptime + starttime = stoptime + else + elapsed = stoptime - lasttime + average = (stoptime - starttime) / (real - 1) + end + lasttime = stoptime + if real > 0 then + if user > 0 then + if sub > 0 then + report_pages("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average) + else + report_pages("flushing realpage %s, userpage %s, time %0.04f / %0.04f",real,user,elapsed,average) + end else - report_pages("flushing realpage %s, userpage %s",real,user) + report_pages("flushing realpage %s, time %0.04f / %0.04f",real,elapsed,average) end else - report_pages("flushing realpage %s",real) + report_pages("flushing page, time %0.04f / %0.04f",elapsed,average) end else - report_pages("flushing page") + if real > 0 then + if user > 0 then + if sub > 0 then + report_pages("flushing realpage %s, userpage %s, subpage %s",real,user,sub) + else + report_pages("flushing realpage %s, userpage %s",real,user) + end + else + report_pages("flushing realpage %s",real) + end + else + report_pages("flushing page") + end end logs.flush() end diff --git a/tex/context/base/util-deb.lua b/tex/context/base/util-deb.lua index fa2d96e41..d82c1a114 100644 --- a/tex/context/base/util-deb.lua +++ b/tex/context/base/util-deb.lua @@ -27,90 +27,55 @@ local names = { } -- one local function hook() - local f = getinfo(2,"f").func - local n = getinfo(2,"Sn") --- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + local f = getinfo(2) -- "nS" if f then - local cf = counters[f] - if cf == nil then - counters[f] = 1 - names[f] = n - else - counters[f] = cf + 1 - end - end -end - -local function getname(func) - local n = names[func] - if n then - if n.what == "C" then - return n.name or '<anonymous>' + local n = "unknown" + if f.what == "C" then + n = f.name or '<anonymous>' + if not names[n] then + names[n] = format("%42s",n) + end else -- source short_src linedefined what name namewhat nups func - local name = n.name or n.namewhat or n.what - if not name or name == "" then name = "?" end - return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + n = f.name or f.namewhat or f.what + if not n or n == "" then + n = "?" + end + if not names[n] then + names[n] = format("%42s : % 5i : %s",n,f.linedefined or 0,f.short_src or "unknown source") + end end - else - return "unknown" + counters[n] = (counters[n] or 0) + 1 end end -function debugger.showstats(printer,threshold) +function debugger.showstats(printer,threshold) -- hm, something has changed, rubish now printer = printer or texio.write or print threshold = threshold or 0 local total, grandtotal, functions = 0, 0, 0 - printer("\n") -- ugly but ok - -- table.sort(counters) - for func, count in next, counters do - if count > threshold then - local name = getname(func) - if not find(name,"for generator") then - printer(format("%8i %s", count, name)) - total = total + count - end + local dataset = { } + for name, count in next, counters do + dataset[#dataset+1] = { name, count } + end + table.sort(dataset,function(a,b) return a[2] == b[2] and b[1] > a[1] or a[2] > b[2] end) + for i=1,#dataset do + local d = dataset[i] + local name = d[1] + local count = d[2] + if count > threshold and not find(name,"for generator") then -- move up + printer(format("%8i %s\n", count, names[name])) + total = total + count end grandtotal = grandtotal + count functions = functions + 1 end - printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) + printer("\n") + printer(format("functions : % 10i\n", functions)) + printer(format("total : % 10i\n", total)) + printer(format("grand total: % 10i\n", grandtotal)) + printer(format("threshold : % 10i\n", threshold)) end --- two - ---~ local function hook() ---~ local n = getinfo(2) ---~ if n.what=="C" and not n.name then ---~ local f = tostring(debug.traceback()) ---~ local cf = counters[f] ---~ if cf == nil then ---~ counters[f] = 1 ---~ names[f] = n ---~ else ---~ counters[f] = cf + 1 ---~ end ---~ end ---~ end ---~ function debugger.showstats(printer,threshold) ---~ printer = printer or texio.write or print ---~ threshold = threshold or 0 ---~ local total, grandtotal, functions = 0, 0, 0 ---~ printer("\n") -- ugly but ok ---~ -- table.sort(counters) ---~ for func, count in next, counters do ---~ if count > threshold then ---~ printer(format("%8i %s", count, func)) ---~ total = total + count ---~ end ---~ grandtotal = grandtotal + count ---~ functions = functions + 1 ---~ end ---~ printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) ---~ end - --- rest - function debugger.savestats(filename,threshold) local f = io.open(filename,'w') if f then |