diff options
Diffstat (limited to 'tex/context/base/mkxl')
-rw-r--r-- | tex/context/base/mkxl/cldf-lmt.lmt | 18 | ||||
-rw-r--r-- | tex/context/base/mkxl/cont-new.mkxl | 2 | ||||
-rw-r--r-- | tex/context/base/mkxl/context.mkxl | 2 | ||||
-rw-r--r-- | tex/context/base/mkxl/mlib-lmp.lmt | 9 | ||||
-rw-r--r-- | tex/context/base/mkxl/pack-ori.mkxl | 13 | ||||
-rw-r--r-- | tex/context/base/mkxl/spac-flr.mkxl | 18 | ||||
-rw-r--r-- | tex/context/base/mkxl/spac-hor.mkxl | 1 | ||||
-rw-r--r-- | tex/context/base/mkxl/spac-pag.mkxl | 2 | ||||
-rw-r--r-- | tex/context/base/mkxl/supp-ran.lmt | 245 | ||||
-rw-r--r-- | tex/context/base/mkxl/supp-ran.mkxl | 39 | ||||
-rw-r--r-- | tex/context/base/mkxl/syst-ini.mkxl | 5 | ||||
-rw-r--r-- | tex/context/base/mkxl/toks-scn.lmt | 14 |
12 files changed, 340 insertions, 28 deletions
diff --git a/tex/context/base/mkxl/cldf-lmt.lmt b/tex/context/base/mkxl/cldf-lmt.lmt index e6c046763..aba3dacda 100644 --- a/tex/context/base/mkxl/cldf-lmt.lmt +++ b/tex/context/base/mkxl/cldf-lmt.lmt @@ -1024,3 +1024,21 @@ do } end + +-- for now here: + +do + + local runstring = tex.runstring + local ctxcatcodes = tex.ctxcatcodes + local formatters = string.formatters + + function context.runstring(fmt,str,...) + if str then + runstring(ctxcatcodes,formatters[fmt](str,...)) + elseif fmt then + runstring(ctxcatcodes,fmt) + end + end + +end diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index 804a45955..260197997 100644 --- a/tex/context/base/mkxl/cont-new.mkxl +++ b/tex/context/base/mkxl/cont-new.mkxl @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2021.08.22 11:51} +\newcontextversion{2021.08.24 22:14} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl index f18aa8946..d49770402 100644 --- a/tex/context/base/mkxl/context.mkxl +++ b/tex/context/base/mkxl/context.mkxl @@ -29,7 +29,7 @@ %D {YYYY.MM.DD HH:MM} format. \immutable\edef\contextformat {\jobname} -\immutable\edef\contextversion{2021.08.22 11:51} +\immutable\edef\contextversion{2021.08.24 22:14} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error diff --git a/tex/context/base/mkxl/mlib-lmp.lmt b/tex/context/base/mkxl/mlib-lmp.lmt index 1614f0951..5608488a3 100644 --- a/tex/context/base/mkxl/mlib-lmp.lmt +++ b/tex/context/base/mkxl/mlib-lmp.lmt @@ -505,3 +505,12 @@ do end +do + + local repeatable = utilities.randomizer.repeatable + + registerdirect("repeatablerandom", function() + return repeatable(scanstring()) + end) + +end diff --git a/tex/context/base/mkxl/pack-ori.mkxl b/tex/context/base/mkxl/pack-ori.mkxl index 4365db3ac..83ff08822 100644 --- a/tex/context/base/mkxl/pack-ori.mkxl +++ b/tex/context/base/mkxl/pack-ori.mkxl @@ -72,15 +72,14 @@ \fi \relax} -%D The \type {\immediateassignment} and \type {\immediateassigned} primitives are -%D kind of obsolete and might be dropped (if not already) from \LUAMETATEX. Local -%D scanning is, although it is a bit slower, more general. We didn't really need and -%D use these primitives in \CONTEXT\ anyway, apart from some playing around with -%D some full expansion, which made no sense in the end so it was dropped. When -%D things get that hairy it's often a good reason to look into \LUA\ variants. +%D The \type {\immediateassignment} and \type {\immediateassigned} primitives that +%D are in \LUATEX\ are obsolete in \LUAMETATEX. Local scanning is, although it is +%D a bit slower, more general. We didn't really need and use these primitives in +%D \CONTEXT\ anyway, apart from some playing around with some full expansion, which +%D made no sense in the end so it was dropped. When things get that hairy it's often +%D a good reason to look into \LUA\ variants. \def\auto_orientation#1% - %{\immediateassignment\global\expandafter\chardef\csname\??orientations#1\endcsname\stringtoorientation{#1}% % quite fast {\beginlocalcontrol\global\expandafter\chardef\csname\??orientations#1\endcsname\stringtoorientation{#1}\endlocalcontrol % good enough %{\localcontrolled{\global\expandafter\chardef\csname\??orientations#1\endcsname\stringtoorientation{#1}}% % a bit slower \csname\??orientations#1\endcsname} diff --git a/tex/context/base/mkxl/spac-flr.mkxl b/tex/context/base/mkxl/spac-flr.mkxl index 3ea90bc2c..e6147facd 100644 --- a/tex/context/base/mkxl/spac-flr.mkxl +++ b/tex/context/base/mkxl/spac-flr.mkxl @@ -82,10 +82,10 @@ \endgroup \ignorespaces} -\setvalue{\??filleralternative\s!unknown}% +\defcsname\??filleralternative\s!unknown\endcsname {} -\setvalue{\??filleralternative\v!symbol}% +\defcsname\??filleralternative\v!symbol\endcsname {\expandnamespaceparameter\??fillerleadermethod\fillerparameter\c!method\v!local \ifdim\fillerparameter\c!offset>\zeropoint \simplealignedspreadbox @@ -100,23 +100,23 @@ \fi \hfill} -\setvalue{\??filleralternative\v!stretch}% +\defcsname\??filleralternative\v!stretch\endcsname {\hfill} -\setvalue{\??filleralternative\v!space}% +\defcsname\??filleralternative\v!space\endcsname {\hskip\fillerparameter\c!distance\relax} -\setvalue{\??filleralternative\v!rule}% +\defcsname\??filleralternative\v!rule\endcsname {\expandnamespaceparameter\??fillerleadermethod\fillerparameter\c!method\v!local \hrule \s!height\fillerparameter\c!height \s!depth \fillerparameter\c!depth \hfill} -\letvalue{\??fillerleadermethod\s!local }\normalleaders % overflow ends up inbetween (current box) -\letvalue{\??fillerleadermethod\v!global}\normalgleaders % overflow ends up inbetween (outermost box) -\letvalue{\??fillerleadermethod\v!middle}\normalcleaders % overflow ends up before, after (current box) -\letvalue{\??fillerleadermethod\v!broad }\normalxleaders % overflow ends up before, inbetween, after (current box) +\letcsname\??fillerleadermethod\s!local \endcsname\normalleaders % overflow ends up inbetween (current box) +\letcsname\??fillerleadermethod\v!global\endcsname\normalgleaders % overflow ends up inbetween (outermost box) +\letcsname\??fillerleadermethod\v!middle\endcsname\normalcleaders % overflow ends up before, after (current box) +\letcsname\??fillerleadermethod\v!broad \endcsname\normalxleaders % overflow ends up before, inbetween, after (current box) \setupfillers [\c!width=\emwidth, diff --git a/tex/context/base/mkxl/spac-hor.mkxl b/tex/context/base/mkxl/spac-hor.mkxl index 95be0a352..0b047ccff 100644 --- a/tex/context/base/mkxl/spac-hor.mkxl +++ b/tex/context/base/mkxl/spac-hor.mkxl @@ -23,6 +23,7 @@ \bitwiseflip \normalizelinemode \normalizelinenormalizecode \bitwiseflip \normalizelinemode \clipwidthnormalizecode \bitwiseflip \normalizelinemode \flattendiscretionariesnormalizecode +%bitwiseflip \normalizelinemode \discardzerotabskipsnormalizecode \let\v_spac_indentation_current\empty % amount/keyword diff --git a/tex/context/base/mkxl/spac-pag.mkxl b/tex/context/base/mkxl/spac-pag.mkxl index d9f7c67a1..32b3b8d79 100644 --- a/tex/context/base/mkxl/spac-pag.mkxl +++ b/tex/context/base/mkxl/spac-pag.mkxl @@ -155,7 +155,7 @@ \pagechangedtrue \fi \ifpagechanged - \letgvalue{\??pagechanges#2:#1}\m_spac_pagestates_realpage + \gletcsname\??pagechanges#2:#1\endcsname\m_spac_pagestates_realpage \glet\lastchangedpage\m_spac_pagestates_realpage \else \glet\lastchangedpage\realfolio diff --git a/tex/context/base/mkxl/supp-ran.lmt b/tex/context/base/mkxl/supp-ran.lmt new file mode 100644 index 000000000..6aee72896 --- /dev/null +++ b/tex/context/base/mkxl/supp-ran.lmt @@ -0,0 +1,245 @@ +if not modules then modules = { } end modules ['supp-ran'] = { + version = 1.001, + comment = "companion to supp-ran.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- We cannot ask for the current seed, so we need some messy hack here. + +local report_system = logs.reporter("system","randomizer") + +local trace_random = false trackers.register("system.randomizer", function(v) trace_random = v end) +local trace_details = false trackers.register("system.randomizer.details", function(v) trace_random = v trace_details = v end) + +local insert, remove = table.insert, table.remove + +local tonumber = tonumber +local sub = string.sub +local math = math +local context = context +local implement = interfaces.implement + +local random = math.random +local randomseed = math.randomseed +local round = math.round +local stack = { } +local last = 1 +local maxcount = 0x3FFFFFFF -- 2^30-1 + +math.random = function(...) + local n = random(...) + if trace_details then + report_system("math %s",n) + end + return n +end + +local function setrandomseedi(n) + if n <= 1 then + n = n * maxcount + elseif n < 1000 then + n = n * 1000 + end + n = round(n) + randomseed(n) + last = random(0,maxcount) -- we need an initial value + if trace_details then + report_system("seed %s from %s",last,n) + elseif trace_random then + report_system("setting seed %s",n) + end +end + +math.setrandomseedi = setrandomseedi + +local function getrandomnumber(min,max) + if min > max then + min, max = max, min + end + last = random(min,max) + if trace_details then + report_system("number %s",last) + end + return last +end + +local function setrandomseed(n) + last = n + setrandomseedi(n) +end + +local function getrandomseed() + return last +end + +-- local function getmprandomnumber() +-- last = random(0,4095) +-- if trace_details then +-- report_system("mp number %s",last) +-- end +-- return last +-- end + +-- maybe stack + +local function pushrandomseed() + -- insert(stack,last) -- doesn't work okay + insert(stack,randomseed(last) or last) + if trace_random or trace_details then + report_system("pushing seed %s",last) + end +end + +local function reuserandomseed(n) + local seed = stack[#stack] + if seed then + if trace_random or trace_details then + report_system("reusing seed %s",last) + end + randomseed(seed) + end +end + +local function poprandomseed() + local seed = remove(stack) + if seed then + if trace_random or trace_details then + report_system("popping seed %s",seed) + end + randomseed(seed) + end +end + +local function getrandom(where,...) + if type(where) == "string" then + local n = random(...) + if trace_details then + report_system("%s %s",where,n) + end + return n + else + local n = random(where,...) + if trace_details then + report_system("utilities %s",n) + end + return n + end +end + +-- todo: also open up in utilities.randomizer.* + +implement { name = "getrandomnumber", actions = { getrandomnumber, context }, arguments = { "integer", "integer" } } +implement { name = "getrandomdimen", actions = { getrandomnumber, context }, arguments = { "dimen", "dimen" } } +implement { name = "getrandomfloat", actions = { getrandomnumber, context }, arguments = { "number", "number" } } +implement { name = "getrandomseed", actions = { getrandomseed, context } } +implement { name = "setrandomseed", actions = setrandomseed, arguments = "integer" } +implement { name = "pushrandomseed", actions = pushrandomseed, public = true, } +implement { name = "poprandomseed", actions = poprandomseed, public = true, } +implement { name = "reuserandomseed", actions = reuserandomseed, public = true, } + +-- fun stuff + +local newrepeatable, getrepeatable, getrepeatableseed, repeatable + +do + + local default = environment.version or "context lmtx" + local hashed = md5.HEX + ----- hashed = sha2.HASH256 + local list = { } + local saved = false + + newrepeatable = function(name,seed) + if not name or name == "" then + name = "default" + seed = default + elseif not seed then + seed = default + end + if not saved then + saved = { } + job.variables.collected.repeatable = saved + end + saved[name] = seed + local hash = hashed(seed) + if trace_random then + report_system("repeatable %a with seed %a starts out as %a",name,seed,hash) + end + local func = function() + local n = tonumber(sub(hash,1,8),16) + -- local n = tonumber(sub(hash,1,15),16) + local r = n / 0xFFFFFFFF + -- local r = n / 0xFFFFFFFFFFFFFFF + hash = hashed(hash) + if trace_details then + report_system("repeatable %a moves on to %a giving %i and %0.9f",name,hash,n,r) + end + return r + end + list[name] = func + -- we need to delay this till we have job available + -- but we seldom call this so it's okay + return func + end + + table.setmetatableindex(list,function(t,k) + local v = rawget(t,"default") + if not v then + v = newrepeatable("default",default) + end + t[k] = v + return v + end) + + getrepeatable = function(name) + return list[name or "default"] + end + + repeatable = function(name) + return list[name or "default"]() + end + + getrepeatableseed = function(name) + local r = job.variables.collected.repeatable + return r and r[name or "default"] or default + end + + implement { + name = "newrepeatablerandom", + public = true, + protected = true, + arguments = { "csnameunchecked", "argument" }, + actions = function(c,s) + -- local c = tokens.scanners.csname(true) + -- local s = tokens.scanners.argument() + implement { + name = c, + public = true, + actions = { newrepeatable(c,s), context }, + } + end + } + +end + +-- public + +utilities.randomizer = { + setseedi = setrandomseedi, + getnumber = getrandomnumber, + setseed = setrandomseed, + getseed = getrandomseed, + -- getmpnumber = getmprandomnumber, + pushseed = pushrandomseed, + reuseseed = reuserandomseed, + popseed = poprandomseed, + get = getrandom, + -- the original, only for testing + -- mathrandom = random, + newrepeatable = newrepeatable, + getrepeatable = getrepeatable, + getrepeatableseed = getrepeatableseed, + repeatable = repeatable, +} diff --git a/tex/context/base/mkxl/supp-ran.mkxl b/tex/context/base/mkxl/supp-ran.mkxl index 7d212fdfd..4bcff6a94 100644 --- a/tex/context/base/mkxl/supp-ran.mkxl +++ b/tex/context/base/mkxl/supp-ran.mkxl @@ -26,7 +26,7 @@ %D \type{new}: \dorecurse{10}{\randomnumber{1}{100} }\par %D \stoptyping -\registerctxluafile{supp-ran}{} +\registerctxluafile{supp-ran}{autosuffix} \unprotect @@ -49,4 +49,41 @@ \permanent\def\randomnumber #1#2{\clf_getrandomnumber\numexpr#1\relax\numexpr#2\relax} \permanent\def\mprandomnumber {\clf_getrandomnumber\zerocount\mpscaledmax} +%D \startbuffer +%D \enabletrackers[system.randomizer.details] +%D +%D \newrepeatablerandom\MyRandom {Welcome 2 America} +%D \newrepeatablerandom\MyRandomN{\randomnumber{0}{1000}} +%D \newrepeatablerandom\MyRandomM{\randomnumber{0}{1000}} +%D +%D \cldcontext{utilities.randomizer.getrepeatableseed()}\par +%D \cldcontext{utilities.randomizer.getrepeatableseed("default")}\par +%D \cldcontext{utilities.randomizer.getrepeatableseed("MyRandom")}\par +%D \cldcontext{utilities.randomizer.getrepeatableseed("MyRandomN")}\par +%D \cldcontext{utilities.randomizer.getrepeatableseed("MyRandomM")}\par +%D +%D \dorecurse{10}{\MyRandom\par} +%D +%D \startMPcode +%D randomseed := repeatablerandom("MyRandom") ; +%D draw image ( +%D for i=1 upto 10000 : +%D draw origin randomized 100 ; +%D endfor ; +%D ) withpen pencircle scaled 1 ; +%D \stopMPcode +%D +%D \startluacode +%D context(utilities.randomizer.getrepeatableseed("MyRandom")) +%D context.par() +%D local rep = utilities.randomizer.getrepeatable("MyRandom") +%D for i=1,5 do +%D context(rep()) +%D context.par() +%D end +%D \stopluacode +%D \stopbuffer +%D +%D \typebuffer \blank \getbuffer \blank + \protect \endinput diff --git a/tex/context/base/mkxl/syst-ini.mkxl b/tex/context/base/mkxl/syst-ini.mkxl index f9b40c963..523d8ab2e 100644 --- a/tex/context/base/mkxl/syst-ini.mkxl +++ b/tex/context/base/mkxl/syst-ini.mkxl @@ -799,11 +799,8 @@ %D When we want to see a box we can as well show all of it. -% \showboxdepth \maxcount -% \showboxbreadth\maxcount - \showboxdepth \maxcount -\showboxbreadth\plusten +\showboxbreadth\maxcount %D Just for tracing purposes we set: diff --git a/tex/context/base/mkxl/toks-scn.lmt b/tex/context/base/mkxl/toks-scn.lmt index 621eb063c..5af351939 100644 --- a/tex/context/base/mkxl/toks-scn.lmt +++ b/tex/context/base/mkxl/toks-scn.lmt @@ -202,10 +202,15 @@ local function scanargumentasis() return scanargument(false) end -scanners.bracketed = scanbracketed -scanners.optional = scanoptional -scanners.bracketedasis = scanbracketedasis -scanners.argumentasis = scanargumentasis +local function scancsnameunchecked() + return scancsname(true) +end + +scanners.bracketed = scanbracketed +scanners.optional = scanoptional +scanners.bracketedasis = scanbracketedasis +scanners.argumentasis = scanargumentasis +scanners.csnameunchecked = scancsnameunchecked local shortcuts = { tokens = tokens, @@ -243,6 +248,7 @@ local shortcuts = { scanclose = scanclose, scanlist = scanlist, scancsname = scancsname, + scancsnameunchecked = scancsnameunchecked, scandelimited = scandelimited, -- not directly useable scanbracketed = scanbracketed, scanoptional = scanoptional, |