diff options
77 files changed, 3016 insertions, 334 deletions
| diff --git a/colors/icc/profiles/default_gray.icc b/colors/icc/profiles/default_gray.iccBinary files differ deleted file mode 100644 index daaa7480a..000000000 --- a/colors/icc/profiles/default_gray.icc +++ /dev/null diff --git a/colors/icc/profiles/ecirgb_v2.icc b/colors/icc/profiles/ecirgb_v2.iccBinary files differ deleted file mode 100644 index 8fd642f85..000000000 --- a/colors/icc/profiles/ecirgb_v2.icc +++ /dev/null diff --git a/colors/icc/profiles/ecirgb_v2_iccv4.icc b/colors/icc/profiles/ecirgb_v2_iccv4.iccBinary files differ deleted file mode 100644 index efceaef63..000000000 --- a/colors/icc/profiles/ecirgb_v2_iccv4.icc +++ /dev/null diff --git a/colors/icc/profiles/isocoated_v2_300_eci.icc b/colors/icc/profiles/isocoated_v2_300_eci.iccBinary files differ deleted file mode 100644 index 0c46e9eb8..000000000 --- a/colors/icc/profiles/isocoated_v2_300_eci.icc +++ /dev/null diff --git a/colors/icc/profiles/isocoated_v2_eci.icc b/colors/icc/profiles/isocoated_v2_eci.iccBinary files differ deleted file mode 100644 index dceb393f6..000000000 --- a/colors/icc/profiles/isocoated_v2_eci.icc +++ /dev/null diff --git a/colors/icc/profiles/srgb.icc b/colors/icc/profiles/srgb.iccBinary files differ deleted file mode 100644 index 7f9d18d09..000000000 --- a/colors/icc/profiles/srgb.icc +++ /dev/null diff --git a/colors/icc/profiles/srgb_v4_icc_preference.icc b/colors/icc/profiles/srgb_v4_icc_preference.iccBinary files differ deleted file mode 100644 index cfbd03e1f..000000000 --- a/colors/icc/profiles/srgb_v4_icc_preference.icc +++ /dev/null diff --git a/doc/context/documents/general/manuals/musings.pdf b/doc/context/documents/general/manuals/musings.pdfBinary files differ index 69197240f..a02e1b6a1 100644 --- a/doc/context/documents/general/manuals/musings.pdf +++ b/doc/context/documents/general/manuals/musings.pdf diff --git a/doc/context/sources/general/manuals/lowlevel/lowlevel-buffers.tex b/doc/context/sources/general/manuals/lowlevel/lowlevel-buffers.tex new file mode 100644 index 000000000..5c600cd6f --- /dev/null +++ b/doc/context/sources/general/manuals/lowlevel/lowlevel-buffers.tex @@ -0,0 +1,506 @@ +% language=us runpath=texruns:manuals/lowlevel + +\environment lowlevel-style + +\startdocument +  [title=buffers, +   color=middlegreen] + +\startsectionlevel[title=Preamble] + +Buffers are not that low level but it makes sense to discuss them in this +perspective because it relates to tokenization, internal representation and +manipulating. + +{\em In due time we can describe some more commands and details here. This +is a start. Feel free to tell me what needs to be explained.} + +\stopsectionlevel + +\startsectionlevel[title=Encoding] + +Normally processing a document starts with reading from file. In the past we were +talking single bytes that were then maps onto a specific input encoding that +itself matches the encoding of a font. When you enter an \quote {a} its (normally +\ASCII) number 97 becomes the index into a font. That same number is also used in +the hyphenator which is why font encoding and hyphenation are strongly related. +If in an eight bit \TEX\ engine you need a precomposed \quote {รค} you have to use +an encoding that has that character in some slot with again matching fonts and +patterns. The actually used font can have the {\em shapes} in different slots and +remapping is then done in the backend code using encoding and mapping files. When +\OPENTYPE\ fonts are used the relationship between characters (input) and glyphs +(rendering) also depends on the application of font features. + +In eight bit environments all this brings a bit of a resource management +nightmare along with complex installation of new fonts. It also puts strain on +the macro package, especially when you want to mix different input encodings onto +different font encodings and thereby pattern encodings in the same document. You +can compare this with code pages in operating system, but imagine them +potentially being mixed in one document, which can happen when you mix multiple +languages where the accumulated number of different characters exceeds 256. You +end up switching between encodings. One way to deal with it is making special +characters active and let their meaning differ per situation. That is for +instance how in \MKII\ we handled \UTF8\ and thereby got around distributing +multiple pattern files per language as we only needed to encoding them in \UTF\ +and then remap them to the required encoding when loading patterns. A mental +exercise is wondering how to support \CJK\ scripts in an eight bit \MKII, +something that actually can be done with some effort. + +The good news is that when we moved from \MKII\ to \MKIV\ we went exclusively +\UTF8\ because that is what the \LUATEX\ engine expects. Upto four bytes are read +in and translated into one \UNICODE\ character. The internal representation is a +32 bit integer (four bytes) instead of a single byte. That also means that in the +transition we got rid of quite some encoding related low level font and pattern +handling. We still support input encodings (called regimes in \CONTEXT) but I'm +pretty sure that nowadays no one uses input other than \UTF8. While \CONTEXT\ is +normally quite upward compatible this is one area where there were fundamental +changes. + +There is still some interpretation going on when reading from file: for instance, +we need to normalize the \UNICODE\ input, and we feed the engine separate lines +on demand. Apart from that, some characters like the backslash, dollar sign and +curly braces have special meaning so for accessing them as characters we have to +use commands that inject those characters. That didn't change when we went from +\MKII\ to \MKIV. In practice it's never really a problem unless you find yourself +in one of the following situations: + +\startitemize +\startitem +    {\em Example code has to be typeset as|-|is, so braces etc.\ are just that.} +    This means that we have to change the way characters are interpreted. +    Typesetting code is needed when you want to document \TEX\ and macros which +    is why mechanisms for that have to be present right from the start. +\stopitem +\startitem +    {\em Content is collected and used later.} A separation of content and usage +    later on often helps making a source look cleaner. Examples are \quotation +    {wrapping a table in a buffer} and \quotation {including that buffer when a +    table is placed} using the placement macros. +\stopitem +\startitem +    {\em Embedded \METAPOST\ and \LUA\ code.} These languages come with different +    interpretation of some characters and especially \METAPOST\ code is often +    stored first and used (processed) later. +\stopitem +\startitem +    {\em The content comes from a different source.} Examples are \XML\ files +    where angle brackets are special but for instance braces aren't. The data is +    interpreted as a stream or as a structured tree. +\stopitem +\startitem +    {\em The content is generated.} It can for instance come from \LUA, where +    bytes (representing \UTF) is just text and no special characters are to be +    intercepted. Or it can come from a database (using a library). +\stopitem +\stopitemize + +For these reasons \CONTEXT\ always had ways to store data in ways that makes this +possible. The details on how that is done might have changed over versions, been +optimized, extended with additional interfaces and features but given where we +come from most has been there from the start. + +\stopsectionlevel + +\startsectionlevel[title=Performance] + +When \TEX\ came around, the bottlenecks in running \TEX\ were the processor, +memory and disks and depending on the way one used it the speed of the console or +terminal; so, basically the whole system. One could sit there and wait for the +page counters (\typ {[1] [2] ..} to show up. It was possible to run \TEX\ on a +personal computer but it was somewhat resource hungry: one needed a decent disk +(a 10 MB hard disk was huge and with todays phone camera snapshots that sounds +crazy). One could use memory extenders to get around the 640K limitation (keep in +mind that the programs and operating systems also took space). This all meant +that one could not afford to store too many tokens in memory but even using files +for all kind of (multi|-|pass) trickery was demanding. + +When processors became faster and memory plenty the disk became the bottleneck, +but that changed when \SSD's showed up. Combined with already present file +caching that had some impact. We are now in a situation that \CPU\ cores don't +get that much faster (at least not twice as fast per iteration) and with \TEX\ +being a single core byte cruncher we're more or less in a situation where +performance has to come from efficient programming. That means that, given enough +memory, in some cases storing in tokens wins over storing in files, but it is no +rule. In practice there is not much difference so one can even more than +yesterday choose for the most convenient method. Just assume that the \CONTEXT\ +code, combined with \LUAMETATEX\ will give you what you need with a reasonable +performance. When in doubt, test with simple test files and it that works out +well compared to the real code, try to figure out where \quote {mistakes} are +made. Inefficient \LUA\ and \TEX\ code has way more impact than storing a few +more tokens or using some files. + +\stopsectionlevel + +\startsectionlevel[title=Files] + +Nearly always files are read once per run. The content (mixed with commands) is +scanned and macros are expanded and|/|or text is typeset as we go. Internally the +\LUAMETATEX\ engine is in \quotation {scanning from file}, \quotation {scanning +from token lists}, or \quotation {scanning from \LUA\ output} mode. The first +mode is (in principle) the slowest because \UTF\ sequences are converted to +tokens (numbers) but there is no way around it. The second method is fast because +we already have these numbers, but we need to take into account where the linked +list of tokens comes from. If it is converted runtime from for instance file +input or macro expansion we need to add the involved overhead. But scanning a +stored macro body is pretty efficient especially when the macro is part of the +loaded macro package (format file). The third method is comparable with reading +from file but here we need to add the overhead involved with storing the \LUA\ +output into data structures suitable for \TEX's input mechanism, which can +involve memory allocation outside the reserved pool of tokens. On modern systems +that is not really a problem. It is good to keep in mind that when \TEX\ was +written much attention was paid to optimization and in \LUAMETATEX\ we even went +a bit further, also because we know what kind of input, processing and output +we're dealing with. + +When reading from file or \LUA\ output we interpret bytes turned \UTF\ numbers +and that is when catcode regimes kick in: characters are interpreted according to +the catcode properties: escape character (backslash), curly braces (grouping and +arguments), dollars (math), etc.\ While with reading from token lists these +catcodes are already taken care of and we're basically interpreting meanings +instead of characters. By changing the catcode regime we can for instance typeset +content verbatim from files and \LUA\ strings but when reading from token lists +we're sort of frozen. There are tricks to reinterpret the token list but that +comes with overhead and limitations. + +\stopsectionlevel + +\startsectionlevel[title=Macros] + +A macro can be seen as a named token with a meaning attached. In \LUAMETATEX\ +macros can take up to 15 arguments (six more than regular \TEX) that can be +separated by so called delimiters. A token has a command property (operator) and +a value (operand). Because a \UNICODE\ character doesn't need all four bytes of +an integer and because in the engine numbers, dimensions and pointers are limited +in size we can store all of these efficiently with the command code. Here the +body of \type {\foo} is a list of three tokens: + +\starttyping +\def\foo{abc} \foo \foo \foo +\stoptyping + +When the engine fetches a token from a list it will interpret the command and +when it fetches from file it will create tokens on the fly and then interpret +those. When a file or list is exhausted the engine pops the stack and continues +at the previous level. Because macros are already tokenized they are more +efficient than file input. For more about macros you can consult the low level +document about them. + +The more you use a macro, the more it pays off compared to a file. However don't +overestimate this, because in the end the typesetting and expanding all kind of +other involved macros might reduce the file overhead to noise. + +\stopsectionlevel + +\startsectionlevel[title=Token lists] + +A token list is like a macro but is part of the variable (register) system. It +is just a list (so no arguments) and you can append and prepend to that list. + +\starttyping +\toks123={abc}    \the\toks123 +\scratchtoks{abc} \the\scratchtoks +\stoptyping + +Here \type {\scratchtoks} is defined with \type {\newtoks} which creates an +efficient reference to a list so that, contrary to the first line, no register +number has to be scanned. There are low level manuals about tokens and registers +that you can read if you want to know more about this. As with macros the list in +this example is three tokens long. Contrary to macros there is no macro overhead +as there is no need to check for arguments. \footnote {In \LUAMETATEX\ a macro +without arguments is also quite efficient.} + +Because they use more or less the same storage method macros and token list +registers perform the same. The power of registers comes from some additional +manipulators in \LUATEX\ (and \LUAMETATEX) and the fact that one can control +expansion with \type {\the}, although that later advantage is compensated with +extensions to the macro language (like \type {\protected} macro definitions). + +\stopsectionlevel + +\startsectionlevel[title=Buffers] + +Buffers are something specific for \CONTEXT\ and they have always been part of +this system. A buffer is defined as follows: + +\startbuffer +\startbuffer[one] +line 1 +line 2 +\stopbuffer +\stopbuffer + +\typebuffer + +Among the operations on buffers the next two are used most often: + +\starttyping +\typebuffer[one] +\getbuffer[one] +\stoptyping + +Scanning a buffer at the \TEX\ end takes a little effort because when we start +reading the catcodes are ignored and for instance backslashes and curly braces +are retained. Hardly any interpretation takes place. The same is true for +spacing, so multiple spaces are not collapsed and newlines stay. The tokenized +content of a buffer is converted back to a string and that content is then read +in as a pseudo file when we need it. So, basically buffers are files! In \MKII\ +they actually were files (in the \type {\jobname} name space and suffix \type +{tmp}), but in \MKIV\ they are stored in and managed by \LUA. That also means +that you can set them very efficiently at the \LUA\ end: + +\starttyping +\startluacode +buffers.assign("one",[[ +line 1 +line 2 +]]) +\stopluacode +\stoptyping + +Always keep in mind that buffers eventually are read as files: character by +character, and at that time the content gets (as with other files) tokenized. A +buffer name is optional. You can nest buffers, with and without names. + +Because \CONTEXT\ is very much about re-use of content and selective processing +we have an (already old) subsystem for defining named blocks of text (using \type +{\begin...} and \type {\end...} tagging. These blocks are stored just like +buffers but selective flushing is part of the concept. Think of coding an +educational document with explanations, questions, answers and then typesetting +only the explanations, or the explanation along width some questions. Other +components can be typeset later so one can make for instance a special book(let) +with answers that either of not repeats the questions. Here we need features like +synchronization of numbers so that's why we cannot really use buffers. An +alternative is to use \XML\ and filter from that. + +The \typ {\definebuffer} command defines a new buffer environment. When you set +buffers in \LUA\ you don't need to define a buffer because likely you don't need +the \type {\start} and \type {\stop} commands. Instead of \typ {\getbuffer} you +can also use \typ {\getdefinedbuffer} with defined buffers. In that case the +\type {before} and \type {after} keys of that specific instance are used. + +The \typ {\getinlinebuffer} command, which like the getters takes a list of +buffer names, ignores leading and trailing spaces. When multiple buffers are +flushed this way, spacing between buffers is retained. + +The most important aspect of buffers is that the content is {\em not} interpreted +and tokenized: the bytes stay as they are. + +\startbuffer +\definebuffer[MyBuffer] + +\startMyBuffer +\bold{this is +a buffer} +\stopMyBuffer + +\typeMyBuffer \getMyBuffer +\stopbuffer + +\typebuffer + +These commands result in: + +\getbuffer + +There are not that many parameters that can be set: \type {before}, \type {after} +and \type {strip} (when set to \type {no} leading and trailing spacing will be +kept. The \type {\stop...} command, in our example \typ {\stopMyBuffer}, can be +defined independent to so something after the buffer has be read and stored but +by default nothing is done. + +You can test if a buffer exists with \typ {\doifelsebuffer} (expandable) and \typ +{\doifelsebufferempty} (unexpandable). A buffer is kept in memory unless it gets +wiped clean with \typ {resetbuffer}. + +\starttyping +\savebuffer      [MyBuffer][temp]     % gets name: jobname-temp.tmp +\savebufferinfile[MyBuffer][temp.log] % gets name: temp.log +\stoptyping + +You can also stepwise fill such a buffer: + +\starttyping +\definesavebuffer[slide] + +\startslide +    \starttext +\stopslide +\startslide +    slide 1 +\stopslide +text 1 \par +\startslide +    slide 2 +\stopslide +text 2 \par +\startslide +    \stoptext +\stopslide +\stoptyping + +After this you will have a file \type {\jobname-slide.tex} that has the two lines +wrapped as text. You can set up a \quote {save buffer} to use a different +filename (with the \type {file} key), a different prefix using \type {prefix} and +you can set up a \type {directory}. A different name is set with the \type {list} +key. + +You can assign content to a buffer with a somewhat clumsy interface where we use +the delimiter \type {\endbuffer}. The only restriction is that this delimiter +cannot be part of the content: + +\starttyping +\setbuffer[name]here comes some text\endbuffer +\stoptyping + +For more details and obscure commands that are used in other commands +you can peek into the source. + +% These are somewhat obscure: +% +% \getbufferdata{...} +% \grabbufferdatadirect % name start stop +% \grabbufferdata % was: \dostartbuffer +% \thebuffernumber +% \thedefinedbuffer + +Using buffers in the \CLD\  interface is tricky because of the catcode magick that is +involved but there are setters and getters: + +\starttabulate[|T|T|] +\BC function               \BC arguments \NC \NR +\ML +\NC buffers.assign         \NC name, content [,catcodes] \NC \NR +%NC buffers.raw            \NC \NC \NR +\NC buffers.erase          \NC name \NC \NR +\NC buffers.prepend        \NC name, content \NC \NR +\NC buffers.append         \NC name, content \NC \NR +\NC buffers.exists         \NC name \NC \NR +\NC buffers.empty          \NC name \NC \NR +\NC buffers.getcontent     \NC name \NC \NR +\NC buffers.getlines       \NC name \NC \NR +%NC buffers.collectcontent \NC \NC \NR +%NC buffers.loadcontent    \NC \NC \NR +%NC buffers.get            \NC \NC \NR +%NC buffers.getmkiv        \NC \NC \NR +%NC buffers.gettexbuffer   \NC \NC \NR +%NC buffers.run            \NC \NC \NR +\stoptabulate + +There are a few more helpers that are used in other (low level) commands. Their +functionality might adapt to their usage there. The \typ {context.startbuffer} +and \typ {context.stopbuffer} are somewhat differently defined than regular +\CLD\ commands. + +\stopsectionlevel + +\startsectionlevel[title=Setups] + +A setup is basically a macro but is stored and accessed in a namespace separated +from ordinary macros. One important characteristic is that inside setups newlines +are ignored. + +\startbuffer +\startsetups MySetupA +    This is line 1 +    and this is line 2 +\stopsetups + +\setup{MySetupA} +\stopbuffer + +\typebuffer {\bf \getbuffer} + +A simple way out is to add a comment character preceded by a space. Instead you +can also use \type {\space}: + +\startbuffer +\startsetups [MySetupB] +    This is line 1 % +    and this is line 2\space +    while here we have line 3 +\stopsetups + +\setup[MySetupB] +\stopbuffer + +\typebuffer {\bf \getbuffer} + +You can use square brackets instead of space delimited names in definitions and +also in calling up a (list of) setup(s). The \type {\directsetup} command takes a +single setup name and is therefore more efficient. + +Setups are basically simple macros although there is some magic involved that +comes from their usage in for instance \XML\ where we pass an argument. That +means we can do the following: + +\startbuffer +\startsetups MySetupC +    before#1after +\stopsetups + +\setupwithargument{MySetupC}{ {\em and} } +\stopbuffer + +\typebuffer {\bf \getbuffer} + +Because a setup is a macro, the body is a linked list of tokens where each token +takes 8 bytes of memory, so \type {MySetupC} has 12 tokens that take 96 bytes of +memory (plus some overhead related to macro management). + +\stopsectionlevel + +\startsectionlevel[title=\XML] + +Discussing \XML\ is outside the scope of this document but it is worth mentioning +that once an \XML\ tree is read is, the content is stored in strings and can be +filtered into \TEX, where it is interpreted as if coming from files (in this case +\LUA\ strings). If needed the content can be interpreted as \TEX\ input. + +\stopsectionlevel + +\startsectionlevel[title=\LUA] + +As mentioned already, output from \LUA\ is stored and when a \LUA\ call finishes +it ends up on the so called input stack. Every time the engine needs a token it +will fetch from the input stack and the top of the stack can represent a file, +token list or \LUA\ output. Interpreting bytes from files or \LUA\ strings +results in tokens. As a side note: \LUA\ output can also be already tokenized, +because we can actually write tokens and nodes from \LUA, but that's more an +implementation detail that makes the \LUA\ input stack entries a bit more +complex. It is normally not something users will do when they use \LUA\ in their +documents. + +\stopsectionlevel + +\startsectionlevel[title=Protection] + +When you define macros there is the danger of overloading some defined by the +system. Best use CamelCase so that you stay away from clashes. You can enable +some checking: + +\starttyping +\enabledirectives[overloadmode=warning] +\stoptyping + +or when you want to quit on a clash: + +\starttyping +\enabledirectives[overloadmode=error] +\stoptyping + +When these trackers are enabled you can get around the check with: + +\starttyping +\pushoverloadmode +  ... +\popoverloadmode +\stoptyping + +But delay that till you're sure that redefining is okay. + +\stopsectionlevel + +% efficiency + +\stopdocument + diff --git a/doc/context/sources/general/manuals/musings/musings-toocomplex.tex b/doc/context/sources/general/manuals/musings/musings-toocomplex.tex index 103dd1906..f12f15c1e 100644 --- a/doc/context/sources/general/manuals/musings/musings-toocomplex.tex +++ b/doc/context/sources/general/manuals/musings/musings-toocomplex.tex @@ -387,3 +387,5 @@ is not needed any more by then.  \stopsection  \stopchapter + +\stopcomponent diff --git a/doc/context/sources/general/manuals/musings/musings.tex b/doc/context/sources/general/manuals/musings/musings.tex index 13bf4f4ef..bccab890a 100644 --- a/doc/context/sources/general/manuals/musings/musings.tex +++ b/doc/context/sources/general/manuals/musings/musings.tex @@ -28,6 +28,7 @@    % \component musings-whytex-again      \component musings-dontusetex      \component musings-speed +    \component musings-texlive  \stopbodymatter  \stopproduct diff --git a/metapost/context/base/common/boxes.mp b/metapost/context/base/common/mp-remapped-boxes.mp index f9cb4a5bb..f9cb4a5bb 100644 --- a/metapost/context/base/common/boxes.mp +++ b/metapost/context/base/common/mp-remapped-boxes.mp diff --git a/metapost/context/base/common/hatching.mp b/metapost/context/base/common/mp-remapped-hatching.mp index ae63b676e..ae63b676e 100644 --- a/metapost/context/base/common/hatching.mp +++ b/metapost/context/base/common/mp-remapped-hatching.mp diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index e53152d53..306f84a1c 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -5136,7 +5136,7 @@ do -- create closure to overcome 200 locals limit  package.loaded["l-dir"] = package.loaded["l-dir"] or true --- original size: 18217, stripped down to: 10792 +-- original size: 18893, stripped down to: 11170  if not modules then modules={} end modules ['l-dir']={   version=1.001, @@ -5600,6 +5600,23 @@ do     return str    end   end + function dir.expandlink(dir,report) +  local curdir=currentdir() +  local trace=type(report)=="function" +  if chdir(dir) then +   local newdir=currentdir() +   if newdir~=dir and trace then +    report("following symlink %a to %a",dir,newdir) +   end +   chdir(curdir) +   return newdir +  else +   if trace then +    report("unable to check path %a",dir) +   end +   return dir +  end + end  end  file.expandname=dir.expandname   local stack={} @@ -20748,7 +20765,7 @@ do -- create closure to overcome 200 locals limit  package.loaded["data-ini"] = package.loaded["data-ini"] or true --- original size: 11605, stripped down to: 7467 +-- original size: 10636, stripped down to: 7049  if not modules then modules={} end modules ['data-ini']={   version=1.001, @@ -20759,9 +20776,11 @@ if not modules then modules={} end modules ['data-ini']={  }  local next,type,getmetatable,rawset=next,type,getmetatable,rawset  local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char -local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join +local filedirname,filebasename,filejoin,replacesuffix=file.dirname,file.basename,file.join,file.replacesuffix  local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv  local sortedpairs=table.sortedpairs +local isfile,currentdir=lfs.isfile,lfs.currentdir +local expandlink=dir.expandlink  local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match  local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)  local trace_expansions=false  trackers.register("resolvers.expansions",function(v) trace_expansions=v end) @@ -20811,24 +20830,11 @@ do   if not environment.ownmain then    environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"   end - local ownbin=environment.ownbin  or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex" + local ownbin=environment.ownbin  or os.selfbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luametatex"   local ownpath=environment.ownpath or os.selfdir - ownbin=file.collapsepath(ownbin) + ownbin=file.collapsepath(ownbin)      ownpath=file.collapsepath(ownpath) - local symlinktarget=lfs.symlinktarget - if symlinktarget then -  while true do -   local new=symlinktarget(ownpath) or ownpath -   if new==ownpath then -    break -   else -    ownpath=new -   end -  end -  ownpath=file.collapsepath(ownpath) - else -  lfs.symlinktarget=function() return nil end  - end + ownpath=expandlink(ownpath,trace_locating and report_initialization)   if not ownpath or ownpath=="" or ownpath=="unset" then    ownpath=args[-1] or arg[-1]    ownpath=ownpath and filedirname(gsub(ownpath,"\\","/")) @@ -20842,27 +20848,14 @@ do    end    if not ownpath or ownpath=="" then     if os.binsuffix~="" then -    binary=file.replacesuffix(binary,os.binsuffix) +    binary=replacesuffix(binary,os.binsuffix)     end     local path=osgetenv("PATH")     if path then      for p in gmatch(path,"[^"..io.pathseparator.."]+") do       local b=filejoin(p,binary) -     if lfs.isfile(b) then -      local olddir=lfs.currentdir() -      if lfs.chdir(p) then -       local pp=lfs.currentdir() -       if trace_locating and p~=pp then -        report_initialization("following symlink %a to %a",p,pp) -       end -       ownpath=pp -       lfs.chdir(olddir) -      else -       if trace_locating then -        report_initialization("unable to check path %a",p) -       end -       ownpath=p -      end +     if isfile(b) then +      ownpath=expandlink(p,trace_locating and report_initialization)        break       end      end @@ -26100,8 +26093,8 @@ end -- of closure  -- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua  -- skipped libraries : - --- original bytes    : 1036036 --- stripped bytes    : 408397 +-- original bytes    : 1035743 +-- stripped bytes    : 408144  -- end library merge diff --git a/scripts/context/lua/texlua.lua b/scripts/context/lua/texlua.lua new file mode 100644 index 000000000..5c0524a56 --- /dev/null +++ b/scripts/context/lua/texlua.lua @@ -0,0 +1,141 @@ +-- version   = 1.000, +-- comment   = "companion to luametatex", +-- author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +-- copyright = "PRAGMA ADE / ConTeXt Development Team", +-- license   = "see context related readme files" + +-- If you copy or link 'luametatex' to 'texlua' and put this script in the same path +-- we have a more pure Lua runner (as with luatex and texlua). + +-- todo: error trace +-- todo: protect these locals + +local texlua_load     = load +local texlua_loadfile = loadfile +local texlua_type     = type +local texlua_xpcall   = xpcall +local texlua_find     = string.find +local texlua_dump     = string.dump +local texlua_open     = io.open +local texlua_print    = print +local texlua_show     = luac.print + +function texlua_inspect(v) +    if texlua_type(v) == "function" then +        local ok, str = texlua_xpcall(texlua_dump,function() end,v) +        if ok then +            v = str +        end +    end +    if type(v) == "string" then +        texlua_show(v,true) +    else +        texlua_print(v) +    end +end + +local function main_execute(str,loader) +    if str and str ~= "" then +        local str = loader(str) +        if texlua_type(str) == "function" then +            str() +        end +    end +end + +local function main_compile(str,loader,out,strip) +    if str and str ~= "" then +        local str = loader(str) +        if texlua_type(str) == "function" then +            str = texlua_dump(str,strip) +            if type(out) == "string" and out ~= "" then +                local f = texlua_open(out,"wb") +                if f then +                    f:write(str) +                    f:close() +                end +            elseif out == true then +                texlua_inspect(str) +            else +                texlua_print(str) +            end +        end +    end +end + +local function main_help() +    texlua_print("LuaMetaTeX in Lua mode:") +    texlua_print("") +    texlua_print("-o  'filename'  output filename") +    texlua_print("-e  'string'    execute loaded string") +    texlua_print("-f  'filename'  execute loaded file") +    texlua_print("-d  'string'    dump bytecode of loaded string") +    texlua_print("-c  'filename'  dump bytecode of loaded file") +    texlua_print("-i  'string'    list bytecode of loaded string") +    texlua_print("-l  'filename'  list bytecode of loaded file") +    texlua_print("-s              strip byte code") +    texlua_print("    'filename'  execute loaded file") +end + +local function main() +    local i = 1 +    local o = "" +    local s = false +    while true do +        local option = arg[i] or "" +        if option == "" then +            if i == 1 then +                main_help() +            end +            break +        elseif option == "-e" then +            i = i + 1 +            main_execute(arg[i],texlua_load) +            o = "" +            s = false +        elseif option == "-f" then +            i = i + 1 +            main_execute(arg[i],texlua_loadfile) +            o = "" +            s = false +        elseif option == "-d" then +            i = i + 1 +            main_compile(arg[i],texlua_load,o,s) +            o = "" +            s = false +        elseif option == "-c" then +            i = i + 1 +            main_compile(arg[i],texlua_loadfile,o,s) +            o = "" +            s = false +        elseif option == "-i" then +            i = i + 1 +            main_compile(arg[i],texlua_load,true) +            o = "" +            s = false +        elseif option == "-l" then +            i = i + 1 +            main_compile(arg[i],texlua_loadfile,true) +            o = "" +            s = false +        elseif option == "-s" then +            s = true +        elseif option == "-o" then +            i = i + 1 +            o = arg[i] or "" +            if texlua_find(o,"^%-") then +                help() +                break +            end +        elseif not texlua_find(option,"^%-") then +            main_execute(option,texlua_loadfile) +            break +        else +            main_help() +            break +        end +        i = i + 1 +    end +end + +main() diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index e53152d53..306f84a1c 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -5136,7 +5136,7 @@ do -- create closure to overcome 200 locals limit  package.loaded["l-dir"] = package.loaded["l-dir"] or true --- original size: 18217, stripped down to: 10792 +-- original size: 18893, stripped down to: 11170  if not modules then modules={} end modules ['l-dir']={   version=1.001, @@ -5600,6 +5600,23 @@ do     return str    end   end + function dir.expandlink(dir,report) +  local curdir=currentdir() +  local trace=type(report)=="function" +  if chdir(dir) then +   local newdir=currentdir() +   if newdir~=dir and trace then +    report("following symlink %a to %a",dir,newdir) +   end +   chdir(curdir) +   return newdir +  else +   if trace then +    report("unable to check path %a",dir) +   end +   return dir +  end + end  end  file.expandname=dir.expandname   local stack={} @@ -20748,7 +20765,7 @@ do -- create closure to overcome 200 locals limit  package.loaded["data-ini"] = package.loaded["data-ini"] or true --- original size: 11605, stripped down to: 7467 +-- original size: 10636, stripped down to: 7049  if not modules then modules={} end modules ['data-ini']={   version=1.001, @@ -20759,9 +20776,11 @@ if not modules then modules={} end modules ['data-ini']={  }  local next,type,getmetatable,rawset=next,type,getmetatable,rawset  local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char -local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join +local filedirname,filebasename,filejoin,replacesuffix=file.dirname,file.basename,file.join,file.replacesuffix  local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv  local sortedpairs=table.sortedpairs +local isfile,currentdir=lfs.isfile,lfs.currentdir +local expandlink=dir.expandlink  local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match  local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)  local trace_expansions=false  trackers.register("resolvers.expansions",function(v) trace_expansions=v end) @@ -20811,24 +20830,11 @@ do   if not environment.ownmain then    environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"   end - local ownbin=environment.ownbin  or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex" + local ownbin=environment.ownbin  or os.selfbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luametatex"   local ownpath=environment.ownpath or os.selfdir - ownbin=file.collapsepath(ownbin) + ownbin=file.collapsepath(ownbin)      ownpath=file.collapsepath(ownpath) - local symlinktarget=lfs.symlinktarget - if symlinktarget then -  while true do -   local new=symlinktarget(ownpath) or ownpath -   if new==ownpath then -    break -   else -    ownpath=new -   end -  end -  ownpath=file.collapsepath(ownpath) - else -  lfs.symlinktarget=function() return nil end  - end + ownpath=expandlink(ownpath,trace_locating and report_initialization)   if not ownpath or ownpath=="" or ownpath=="unset" then    ownpath=args[-1] or arg[-1]    ownpath=ownpath and filedirname(gsub(ownpath,"\\","/")) @@ -20842,27 +20848,14 @@ do    end    if not ownpath or ownpath=="" then     if os.binsuffix~="" then -    binary=file.replacesuffix(binary,os.binsuffix) +    binary=replacesuffix(binary,os.binsuffix)     end     local path=osgetenv("PATH")     if path then      for p in gmatch(path,"[^"..io.pathseparator.."]+") do       local b=filejoin(p,binary) -     if lfs.isfile(b) then -      local olddir=lfs.currentdir() -      if lfs.chdir(p) then -       local pp=lfs.currentdir() -       if trace_locating and p~=pp then -        report_initialization("following symlink %a to %a",p,pp) -       end -       ownpath=pp -       lfs.chdir(olddir) -      else -       if trace_locating then -        report_initialization("unable to check path %a",p) -       end -       ownpath=p -      end +     if isfile(b) then +      ownpath=expandlink(p,trace_locating and report_initialization)        break       end      end @@ -26100,8 +26093,8 @@ end -- of closure  -- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua  -- skipped libraries : - --- original bytes    : 1036036 --- stripped bytes    : 408397 +-- original bytes    : 1035743 +-- stripped bytes    : 408144  -- end library merge diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index e53152d53..306f84a1c 100644 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -5136,7 +5136,7 @@ do -- create closure to overcome 200 locals limit  package.loaded["l-dir"] = package.loaded["l-dir"] or true --- original size: 18217, stripped down to: 10792 +-- original size: 18893, stripped down to: 11170  if not modules then modules={} end modules ['l-dir']={   version=1.001, @@ -5600,6 +5600,23 @@ do     return str    end   end + function dir.expandlink(dir,report) +  local curdir=currentdir() +  local trace=type(report)=="function" +  if chdir(dir) then +   local newdir=currentdir() +   if newdir~=dir and trace then +    report("following symlink %a to %a",dir,newdir) +   end +   chdir(curdir) +   return newdir +  else +   if trace then +    report("unable to check path %a",dir) +   end +   return dir +  end + end  end  file.expandname=dir.expandname   local stack={} @@ -20748,7 +20765,7 @@ do -- create closure to overcome 200 locals limit  package.loaded["data-ini"] = package.loaded["data-ini"] or true --- original size: 11605, stripped down to: 7467 +-- original size: 10636, stripped down to: 7049  if not modules then modules={} end modules ['data-ini']={   version=1.001, @@ -20759,9 +20776,11 @@ if not modules then modules={} end modules ['data-ini']={  }  local next,type,getmetatable,rawset=next,type,getmetatable,rawset  local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char -local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join +local filedirname,filebasename,filejoin,replacesuffix=file.dirname,file.basename,file.join,file.replacesuffix  local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv  local sortedpairs=table.sortedpairs +local isfile,currentdir=lfs.isfile,lfs.currentdir +local expandlink=dir.expandlink  local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match  local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)  local trace_expansions=false  trackers.register("resolvers.expansions",function(v) trace_expansions=v end) @@ -20811,24 +20830,11 @@ do   if not environment.ownmain then    environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"   end - local ownbin=environment.ownbin  or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex" + local ownbin=environment.ownbin  or os.selfbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luametatex"   local ownpath=environment.ownpath or os.selfdir - ownbin=file.collapsepath(ownbin) + ownbin=file.collapsepath(ownbin)      ownpath=file.collapsepath(ownpath) - local symlinktarget=lfs.symlinktarget - if symlinktarget then -  while true do -   local new=symlinktarget(ownpath) or ownpath -   if new==ownpath then -    break -   else -    ownpath=new -   end -  end -  ownpath=file.collapsepath(ownpath) - else -  lfs.symlinktarget=function() return nil end  - end + ownpath=expandlink(ownpath,trace_locating and report_initialization)   if not ownpath or ownpath=="" or ownpath=="unset" then    ownpath=args[-1] or arg[-1]    ownpath=ownpath and filedirname(gsub(ownpath,"\\","/")) @@ -20842,27 +20848,14 @@ do    end    if not ownpath or ownpath=="" then     if os.binsuffix~="" then -    binary=file.replacesuffix(binary,os.binsuffix) +    binary=replacesuffix(binary,os.binsuffix)     end     local path=osgetenv("PATH")     if path then      for p in gmatch(path,"[^"..io.pathseparator.."]+") do       local b=filejoin(p,binary) -     if lfs.isfile(b) then -      local olddir=lfs.currentdir() -      if lfs.chdir(p) then -       local pp=lfs.currentdir() -       if trace_locating and p~=pp then -        report_initialization("following symlink %a to %a",p,pp) -       end -       ownpath=pp -       lfs.chdir(olddir) -      else -       if trace_locating then -        report_initialization("unable to check path %a",p) -       end -       ownpath=p -      end +     if isfile(b) then +      ownpath=expandlink(p,trace_locating and report_initialization)        break       end      end @@ -26100,8 +26093,8 @@ end -- of closure  -- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua  -- skipped libraries : - --- original bytes    : 1036036 --- stripped bytes    : 408397 +-- original bytes    : 1035743 +-- stripped bytes    : 408144  -- end library merge diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua index e53152d53..306f84a1c 100644 --- a/scripts/context/stubs/win64/mtxrun.lua +++ b/scripts/context/stubs/win64/mtxrun.lua @@ -5136,7 +5136,7 @@ do -- create closure to overcome 200 locals limit  package.loaded["l-dir"] = package.loaded["l-dir"] or true --- original size: 18217, stripped down to: 10792 +-- original size: 18893, stripped down to: 11170  if not modules then modules={} end modules ['l-dir']={   version=1.001, @@ -5600,6 +5600,23 @@ do     return str    end   end + function dir.expandlink(dir,report) +  local curdir=currentdir() +  local trace=type(report)=="function" +  if chdir(dir) then +   local newdir=currentdir() +   if newdir~=dir and trace then +    report("following symlink %a to %a",dir,newdir) +   end +   chdir(curdir) +   return newdir +  else +   if trace then +    report("unable to check path %a",dir) +   end +   return dir +  end + end  end  file.expandname=dir.expandname   local stack={} @@ -20748,7 +20765,7 @@ do -- create closure to overcome 200 locals limit  package.loaded["data-ini"] = package.loaded["data-ini"] or true --- original size: 11605, stripped down to: 7467 +-- original size: 10636, stripped down to: 7049  if not modules then modules={} end modules ['data-ini']={   version=1.001, @@ -20759,9 +20776,11 @@ if not modules then modules={} end modules ['data-ini']={  }  local next,type,getmetatable,rawset=next,type,getmetatable,rawset  local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char -local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join +local filedirname,filebasename,filejoin,replacesuffix=file.dirname,file.basename,file.join,file.replacesuffix  local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv  local sortedpairs=table.sortedpairs +local isfile,currentdir=lfs.isfile,lfs.currentdir +local expandlink=dir.expandlink  local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match  local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)  local trace_expansions=false  trackers.register("resolvers.expansions",function(v) trace_expansions=v end) @@ -20811,24 +20830,11 @@ do   if not environment.ownmain then    environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"   end - local ownbin=environment.ownbin  or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex" + local ownbin=environment.ownbin  or os.selfbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luametatex"   local ownpath=environment.ownpath or os.selfdir - ownbin=file.collapsepath(ownbin) + ownbin=file.collapsepath(ownbin)      ownpath=file.collapsepath(ownpath) - local symlinktarget=lfs.symlinktarget - if symlinktarget then -  while true do -   local new=symlinktarget(ownpath) or ownpath -   if new==ownpath then -    break -   else -    ownpath=new -   end -  end -  ownpath=file.collapsepath(ownpath) - else -  lfs.symlinktarget=function() return nil end  - end + ownpath=expandlink(ownpath,trace_locating and report_initialization)   if not ownpath or ownpath=="" or ownpath=="unset" then    ownpath=args[-1] or arg[-1]    ownpath=ownpath and filedirname(gsub(ownpath,"\\","/")) @@ -20842,27 +20848,14 @@ do    end    if not ownpath or ownpath=="" then     if os.binsuffix~="" then -    binary=file.replacesuffix(binary,os.binsuffix) +    binary=replacesuffix(binary,os.binsuffix)     end     local path=osgetenv("PATH")     if path then      for p in gmatch(path,"[^"..io.pathseparator.."]+") do       local b=filejoin(p,binary) -     if lfs.isfile(b) then -      local olddir=lfs.currentdir() -      if lfs.chdir(p) then -       local pp=lfs.currentdir() -       if trace_locating and p~=pp then -        report_initialization("following symlink %a to %a",p,pp) -       end -       ownpath=pp -       lfs.chdir(olddir) -      else -       if trace_locating then -        report_initialization("unable to check path %a",p) -       end -       ownpath=p -      end +     if isfile(b) then +      ownpath=expandlink(p,trace_locating and report_initialization)        break       end      end @@ -26100,8 +26093,8 @@ end -- of closure  -- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua  -- skipped libraries : - --- original bytes    : 1036036 --- stripped bytes    : 408397 +-- original bytes    : 1035743 +-- stripped bytes    : 408144  -- end library merge diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c index 1b62a389c..01db082b2 100644 --- a/source/luametatex/source/tex/texmath.c +++ b/source/luametatex/source/tex/texmath.c @@ -3100,17 +3100,15 @@ void tex_run_math_accent(void)                                  if (tex_scan_character("t", 0, 0, 0)) {                                       switch (tex_scan_character("thTH", 0, 0, 0)) {                                           case 'h': case 'H': -                                             if (tex_scan_mandate_keyword("both", 4)) { -                                                  /*tex top bottom */ -                                                  if (tex_scan_keyword("fixed")) { -                                                      node_subtype(accent) = fixedtop_accent_subtype; -                                                  } -                                                  t = tex_scan_mathchar(umath_mathcode); -                                                  if (tex_scan_keyword("fixed")) { -                                                      node_subtype(accent) = fixedboth_accent_subtype; -                                                  } -                                                  b = tex_scan_mathchar(umath_mathcode); -                                             } +                                            /*tex top bottom */ +                                            if (tex_scan_keyword("fixed")) { +                                                node_subtype(accent) = fixedtop_accent_subtype; +                                            } +                                            t = tex_scan_mathchar(umath_mathcode); +                                            if (tex_scan_keyword("fixed")) { +                                                node_subtype(accent) = fixedboth_accent_subtype; +                                            } +                                            b = tex_scan_mathchar(umath_mathcode);                                              goto DONE;                                           case 't': case 'T':                                               if (tex_scan_mandate_keyword("bottom", 4)) { diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index cf16f7947..adf47a428 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{2023.03.06 23:15} +\newcontextversion{2023.03.10 12:15}  %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 a8623d2ce..cbe8cf4ff 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{2023.03.06 23:15} +\edef\contextversion{2023.03.10 12:15}  %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii index 6ee6ea7d3..9057e3b91 100644 --- a/tex/context/base/mkii/mult-de.mkii +++ b/tex/context/base/mkii/mult-de.mkii @@ -450,6 +450,7 @@  \setinterfacevariable{printable}{druckbar}  \setinterfacevariable{process}{process}  \setinterfacevariable{product}{produkt} +\setinterfacevariable{profile}{profile}  \setinterfacevariable{program}{programm}  \setinterfacevariable{project}{projekt}  \setinterfacevariable{protected}{geschuetzt} @@ -591,6 +592,7 @@  \setinterfacevariable{temporary}{temporaer}  \setinterfacevariable{test}{test}  \setinterfacevariable{text}{text} +\setinterfacevariable{textdisplay}{textdisplay}  \setinterfacevariable{textnote}{textnote}  \setinterfacevariable{three}{drei}  \setinterfacevariable{thursday}{donnerstag} @@ -718,6 +720,7 @@  \setinterfaceconstant{bookmark}{bookmark}  \setinterfaceconstant{bottom}{unten}  \setinterfaceconstant{bottomafter}{bottomafter} +\setinterfaceconstant{bottomalign}{bottomalign}  \setinterfaceconstant{bottombefore}{bottombefore}  \setinterfaceconstant{bottomcolor}{bottomcolor}  \setinterfaceconstant{bottomcommand}{bottomcommand} @@ -829,6 +832,7 @@  \setinterfaceconstant{exitoffset}{exitoffset}  \setinterfaceconstant{expansion}{expansion}  \setinterfaceconstant{export}{export} +\setinterfaceconstant{extradata}{extradata}  \setinterfaceconstant{extras}{extras}  \setinterfaceconstant{factor}{faktor}  \setinterfaceconstant{fallback}{fallback} @@ -952,6 +956,7 @@  \setinterfaceconstant{lastpage}{letzteseite}  \setinterfaceconstant{lastpagesep}{lastpagesep}  \setinterfaceconstant{lastpubsep}{lastpubsep} +\setinterfaceconstant{lasttextseparator}{lasttextseparator}  \setinterfaceconstant{layout}{layout}  \setinterfaceconstant{left}{links}  \setinterfaceconstant{leftclass}{leftclass} @@ -1332,6 +1337,7 @@  \setinterfaceconstant{toffset}{toffset}  \setinterfaceconstant{tolerance}{toleranz}  \setinterfaceconstant{top}{oben} +\setinterfaceconstant{topalign}{topalign}  \setinterfaceconstant{topcolor}{topcolor}  \setinterfaceconstant{topcommand}{topcommand}  \setinterfaceconstant{topdistance}{obenabstand} diff --git a/tex/context/base/mkiv/char-def.lua b/tex/context/base/mkiv/char-def.lua index 1aea51318..5e9d7d05a 100644 --- a/tex/context/base/mkiv/char-def.lua +++ b/tex/context/base/mkiv/char-def.lua @@ -64034,6 +64034,8 @@ characters.data={    combining=0xE6,    description="COMBINING LEFT ARROW ABOVE",    direction="nsm", +  mathclass="topaccent", +  mathstretch="h",    linebreak="cm",    unicodeslot=0x20D6,   }, @@ -64248,6 +64250,8 @@ characters.data={    description="COMBINING LEFT ARROW BELOW",    direction="nsm",    linebreak="cm", +  mathclass="bottomaccent", +  mathstretch="h",    unicodeslot=0x20EE,   },   [0x20EF]={ @@ -64256,6 +64260,8 @@ characters.data={    description="COMBINING RIGHT ARROW BELOW",    direction="nsm",    linebreak="cm", +  mathclass="bottomaccent", +  mathstretch="h",    unicodeslot=0x20EF,   },   [0x20F0]={ diff --git a/tex/context/base/mkiv/cldf-ini.lua b/tex/context/base/mkiv/cldf-ini.lua index 0bdc60379..9b5e705ca 100644 --- a/tex/context/base/mkiv/cldf-ini.lua +++ b/tex/context/base/mkiv/cldf-ini.lua @@ -99,7 +99,7 @@ local tonut             = node.direct.todirect  local tonode            = node.direct.tonode  local newtoken          = token.new -local createtoken       = token.create +----- createtoken       = token.create  local istoken           = token.istoken or token.is_token  local setluatoken       = token.setlua  or token.set_lua diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index b62b775ad..22e4d4bae 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -13,7 +13,7 @@  % \normalend % uncomment this to get the real base runtime -\newcontextversion{2023.03.06 23:15} +\newcontextversion{2023.03.10 12:15}  %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/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 860d411a5..1c9effa6a 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -49,7 +49,7 @@  %D {YYYY.MM.DD HH:MM} format.  \edef\contextformat {\jobname} -\edef\contextversion{2023.03.06 23:15} +\edef\contextversion{2023.03.10 12:15}  %D Kind of special: diff --git a/tex/context/base/mkiv/data-ini.lua b/tex/context/base/mkiv/data-ini.lua index c36e0bb9c..57a800d83 100644 --- a/tex/context/base/mkiv/data-ini.lua +++ b/tex/context/base/mkiv/data-ini.lua @@ -8,9 +8,11 @@ if not modules then modules = { } end modules ['data-ini'] = {  local next, type, getmetatable, rawset = next, type, getmetatable, rawset  local gsub, find, gmatch, char = string.gsub, string.find, string.gmatch, string.char -local filedirname, filebasename, filejoin = file.dirname, file.basename, file.join +local filedirname, filebasename, filejoin, replacesuffix = file.dirname, file.basename, file.join, file.replacesuffix  local ostype, osname, osuname, ossetenv, osgetenv = os.type, os.name, os.uname, os.setenv, os.getenv  local sortedpairs = table.sortedpairs +local isfile, currentdir = lfs.isfile, lfs.currentdir +local expandlink = dir.expandlink  local P, S, R, C, Cs, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.match @@ -103,31 +105,19 @@ do          environment.ownmain = status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"      end -    local ownbin  = environment.ownbin  or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex" +    local ownbin  = environment.ownbin  or os.selfbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luametatex"      local ownpath = environment.ownpath or os.selfdir -    ownbin  = file.collapsepath(ownbin) +    ownbin  = file.collapsepath(ownbin)   -- This one an actually also contain the path!      ownpath = file.collapsepath(ownpath)      -- We need to follow the symlink on osx - texlive. This only works luametatex and -    -- lmtx so we might as wel forget abnotu luatex/mkiv there. The regular context -    -- installation doesn't have this link issue. +    -- lmtx so we might as wel forget about luatex/mkiv there. The regular context +    -- installation doesn't have this link issue. I tried several variants but in the +    -- end the chdir variants was most reliable. Everything else is ugly. (Experimtal +    -- code is in data-osx.lua). -    local symlinktarget = lfs.symlinktarget - -    if symlinktarget then -        while true do -            local new = symlinktarget(ownpath) or ownpath -            if new == ownpath then -                break -            else -                ownpath = new -            end -        end -        ownpath = file.collapsepath(ownpath) -    else -        lfs.symlinktarget = function() return nil end -- forget about it, luatex is frozen -    end +    ownpath = expandlink(ownpath,trace_locating and report_initialization)      if not ownpath or ownpath == "" or ownpath == "unset" then          ownpath = args[-1] or arg[-1] @@ -142,31 +132,14 @@ do          end          if not ownpath or ownpath == "" then              if os.binsuffix ~= "" then -                binary = file.replacesuffix(binary,os.binsuffix) +                binary = replacesuffix(binary,os.binsuffix)              end              local path = osgetenv("PATH")              if path then                  for p in gmatch(path,"[^"..io.pathseparator.."]+") do                      local b = filejoin(p,binary) -                    if lfs.isfile(b) then -                        -- we assume that after changing to the path the currentdir function -                        -- resolves to the real location and use this side effect here; this -                        -- trick is needed because on the mac installations use symlinks in the -                        -- path instead of real locations -                        local olddir = lfs.currentdir() -                        if lfs.chdir(p) then -                            local pp = lfs.currentdir() -                            if trace_locating and p ~= pp then -                                report_initialization("following symlink %a to %a",p,pp) -                            end -                            ownpath = pp -                            lfs.chdir(olddir) -                        else -                            if trace_locating then -                                report_initialization("unable to check path %a",p) -                            end -                            ownpath =  p -                        end +                    if isfile(b) then +                        ownpath = expandlink(p,trace_locating and report_initialization)                          break                      end                  end diff --git a/tex/context/base/mkiv/grph-con.lua b/tex/context/base/mkiv/grph-con.lua index fdae2223b..fcc8c931d 100644 --- a/tex/context/base/mkiv/grph-con.lua +++ b/tex/context/base/mkiv/grph-con.lua @@ -312,7 +312,7 @@ do -- png | jpg | profiles      -- [[convert %?colorspace: -colorspace "%colorspace%" ?%]]      local rgbprofile  = "srgb_v4_icc_preference.icc" -- srgb.icc -    local cmykprofile = "isocoated_v2_300_eci.icc"   -- isocoated_v2_eci.icc +    local cmykprofile = "isocoated_v2_eci.icc"       -- isocoated_v2_300_eci.icc      directives.register("graphics.conversion.rgbprofile", function(v) rgbprofile  = type(v) == "string" and v or rgbprofile  end)      directives.register("graphics.conversion.cmykprofile",function(v) cmykprofile = type(v) == "string" and v or cmykprofile end) @@ -320,9 +320,14 @@ do -- png | jpg | profiles      local jpgconverters = converters.jpg      local pngconverters = converters.png +    local findfile = resolvers.findfile +      local function profiles()          if not isfile(rgbprofile) then -            local found = resolvers.findfile(rgbprofile) +            local found = findfile(rgbprofile) +            if not found or found == "" then +                found = findfile("colo-imp-"..rgbprofile) +            end              if found and found ~= "" then                  rgbprofile = found              else @@ -331,6 +336,9 @@ do -- png | jpg | profiles          end          if not isfile(cmykprofile) then              local found = resolvers.findfile(cmykprofile) +            if not found or found == "" then +                found = findfile("colo-imp-"..cmykprofile) +            end              if found and found ~= "" then                  cmykprofile = found              else diff --git a/tex/context/base/mkiv/l-dir.lua b/tex/context/base/mkiv/l-dir.lua index c8543f025..3e24e4e2a 100644 --- a/tex/context/base/mkiv/l-dir.lua +++ b/tex/context/base/mkiv/l-dir.lua @@ -596,6 +596,27 @@ do      end +    -- This go there anc check works okay in tricky situation as we encounter +    -- on osx, where tex installations use rather complex chains of links. + +    function dir.expandlink(dir,report) +        local curdir = currentdir() +        local trace  = type(report) == "function" +        if chdir(dir) then +            local newdir = currentdir() +            if newdir ~= dir and trace then +                report("following symlink %a to %a",dir,newdir) +            end +            chdir(curdir) +            return newdir +        else +            if trace then +                report("unable to check path %a",dir) +            end +            return dir +        end +    end +  end  file.expandname = dir.expandname -- for convenience diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdfBinary files differ index 66f1aba27..c073662c5 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdfBinary files differ index f78a5e548..5bced88ec 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/toks-scn.lua b/tex/context/base/mkiv/toks-scn.lua index 98d2f66c0..c51377941 100644 --- a/tex/context/base/mkiv/toks-scn.lua +++ b/tex/context/base/mkiv/toks-scn.lua @@ -347,6 +347,11 @@ local presets = {      ["2 arguments"] = { "argument", "argument" },      ["3 arguments"] = { "argument", "argument", "argument" },      ["4 arguments"] = { "argument", "argument", "argument", "argument" }, + +    ["1 integer"]  = { "integer" }, +    ["2 integers"] = { "integer", "integer" }, +    ["3 integers"] = { "integer", "integer", "integer" }, +    ["4 integers"] = { "integer", "integer", "integer", "integer" },  }  tokens.presets = presets diff --git a/tex/context/base/mkiv/typo-prc.lua b/tex/context/base/mkiv/typo-prc.lua index 2704149db..72b159e9c 100644 --- a/tex/context/base/mkiv/typo-prc.lua +++ b/tex/context/base/mkiv/typo-prc.lua @@ -15,7 +15,7 @@ local implement         = interfaces.implement  local formatters        = string.formatters -typesetters.processors  = typesetters.processors   or { } +typesetters.processors  = typesetters.processors or { }  local processors        = typesetters.processors  local trace_processors  = false diff --git a/tex/context/base/mkxl/anch-pos.lmt b/tex/context/base/mkxl/anch-pos.lmt index 79a0da097..07a6ecf33 100644 --- a/tex/context/base/mkxl/anch-pos.lmt +++ b/tex/context/base/mkxl/anch-pos.lmt @@ -2280,13 +2280,13 @@ implement {  implement {      name      = "markregionbox", -    arguments = { "integer", "integer" }, +    arguments = "2 integers",      actions   = markregionbox  }  implement {      name      = "setregionbox", -    arguments = { "integer", "integer" }, +    arguments = "2 integers",      actions   = setregionbox  } diff --git a/tex/context/base/mkxl/char-tex.lmt b/tex/context/base/mkxl/char-tex.lmt index 02d9a6cb6..0e0297381 100644 --- a/tex/context/base/mkxl/char-tex.lmt +++ b/tex/context/base/mkxl/char-tex.lmt @@ -583,7 +583,7 @@ implement {  implement {      name      = "uchar", -    arguments = { "integer", "integer" }, +    arguments = "2 integers",      actions   = function(h,l)          context(utfchar(h*256+l))      end diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index f693cbb59..ef7c40717 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{2023.03.06 23:15} +\newcontextversion{2023.03.10 12:15}  %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 f5bf1803c..8f9513510 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{2023.03.06 23:15} +\immutable\edef\contextversion{2023.03.10 12:15}  %overloadmode 1 % check frozen / warning  %overloadmode 2 % check frozen / error @@ -702,7 +702,6 @@  % c:/data/develop/context/sources/file-ini.lua  % c:/data/develop/context/sources/file-lib.lua  % c:/data/develop/context/sources/file-res.lua -% c:/data/develop/context/sources/file-syn.lua  % c:/data/develop/context/sources/font-afk.lua  % c:/data/develop/context/sources/font-agl.lua @@ -782,7 +781,7 @@  % c:/data/develop/context/sources/meta-pdf.lua  % c:/data/develop/context/sources/meta-tex.lua -% c:/data/develop/context/sources/mult-aux.lua +% c:/data/develop/context/sources/mult-aux.lua % move some to s-system-*  % c:/data/develop/context/sources/mult-fmt.lua  % c:/data/develop/context/sources/page-cst.lua @@ -822,17 +821,13 @@  % c:/data/develop/context/sources/strc-blk.lua  % c:/data/develop/context/sources/strc-con.lua  % c:/data/develop/context/sources/strc-doc.lua -% c:/data/develop/context/sources/strc-flt.lua  % c:/data/develop/context/sources/strc-ini.lua -% c:/data/develop/context/sources/strc-itm.lua  % c:/data/develop/context/sources/strc-lev.lua -% c:/data/develop/context/sources/strc-mat.lua  % c:/data/develop/context/sources/strc-num.lua  % c:/data/develop/context/sources/strc-pag.lua -% c:/data/develop/context/sources/strc-syn.lua  % c:/data/develop/context/sources/strc-usr.lua -% c:/data/develop/context/sources/syst-cmp.lua +% c:/data/develop/context/sources/syst-cmp.lua -- nothing  % c:/data/develop/context/sources/syst-con.lua  % c:/data/develop/context/sources/trac-ctx.lua @@ -842,10 +837,5 @@  % c:/data/develop/context/sources/typo-cln.lua -- wrong name for what it does  % c:/data/develop/context/sources/typo-dha.lua -% c:/data/develop/context/sources/typo-fkr.lua -% c:/data/develop/context/sources/typo-inj.lua -% c:/data/develop/context/sources/typo-man.lua -% c:/data/develop/context/sources/typo-prc.lua -% c:/data/develop/context/sources/typo-rep.lua  % c:/data/develop/context/sources/unic-ini.lua diff --git a/tex/context/base/mkxl/file-syn.lmt b/tex/context/base/mkxl/file-syn.lmt new file mode 100644 index 000000000..1c3010b43 --- /dev/null +++ b/tex/context/base/mkxl/file-syn.lmt @@ -0,0 +1,79 @@ +if not modules then modules = { } end modules ['file-syn'] = { +    version   = 1.001, +    comment   = "companion to file-syn.mkvi", +    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +    copyright = "PRAGMA ADE / ConTeXt Development Team", +    license   = "see context related readme files" +} + + +environment.filesynonyms = environment.filesynonyms or { } +local filesynonyms       = environment.filesynonyms + +local settings_to_array  = utilities.parsers.settings_to_array +local findfile           = resolvers.findfile + +local implement          = interfaces.implement + +storage.register("environment/filesynonyms", filesynonyms, "environment.filesynonyms") + +local function truefilename(name) +    local realname = filesynonyms[name] or name +    if realname ~= name then +        return truefilename(realname) +    else +        return realname +    end +end + +environment.truefilename = truefilename + +function environment.definefilesynonym(name,realname) +    if name and realname then +        local names = settings_to_array(name) +        for i=1,#names do +            local name    = names[i] +            local synonym = filesynonyms[name] +            if synonym then +                interfaces.showmessage("files",1,{ name or "?", realname or "?", synonym or "?" }) +            end +            filesynonyms[name] = realname +        end +    end +end + +function environment.definefilefallback(name,alternatives) +    if name and alternatives then +        local names = settings_to_array(alternatives) +        for i=1,#names do +            local realname = findfile(names[i]) +            if realname ~= "" then +                filesynonyms[name] = realname +                break +            end +        end +    end +end + +implement { +    name      = "truefilename", +    public    = true, +    actions   = { truefilename, context }, +    arguments = "argument" +} + +implement { +    name      = "definefilesynonym", +    public    = true, +    protected = true, +    actions   = environment.definefilesynonym, +    arguments = "2 optionals" +} + +implement { +    name      = "definefilefallback", +    public    = true, +    protected = true, +    actions   = environment,definefilefallback, +    arguments = "2 optionals" +} diff --git a/tex/context/base/mkxl/file-syn.mklx b/tex/context/base/mkxl/file-syn.mklx index 25f36f742..3bbf15c4c 100644 --- a/tex/context/base/mkxl/file-syn.mklx +++ b/tex/context/base/mkxl/file-syn.mklx @@ -15,7 +15,7 @@  \unprotect -\registerctxluafile{file-syn}{} +\registerctxluafile{file-syn}{autosuffix}  %D \macros  %D   {definefilesynonym,definefilefallback} @@ -42,8 +42,8 @@  %D \usemodules[pictex,chemie,unit]  %D \stoptyping -\permanent\tolerant\def\definefilesynonym     [#name]#spacer[#realname]{\clf_definefilesynonym {#name}{#realname}} -\permanent\tolerant\def\definefilefallback[#name]#spacer[#alternatives]{\clf_definefilefallback{#name}{#alternatives}} +% \permanent\tolerant\def\definefilesynonym     [#name]#spacer[#realname]{\clf_definefilesynonym {#name}{#realname}} +% \permanent\tolerant\def\definefilefallback[#name]#spacer[#alternatives]{\clf_definefilefallback{#name}{#alternatives}}  %D \macros  %D   {truefilename} @@ -56,6 +56,6 @@  %D  %D The implementation shows that nesting is supported. -\permanent\def\truefilename#1{\clf_truefilename{#1}} +% \permanent\def\truefilename#1{\clf_truefilename{#1}}  \protect \endinput diff --git a/tex/context/base/mkxl/libs-imp-sqlite.lmt b/tex/context/base/mkxl/libs-imp-sqlite.lmt index 4b2925bcc..0d1f77d17 100644 --- a/tex/context/base/mkxl/libs-imp-sqlite.lmt +++ b/tex/context/base/mkxl/libs-imp-sqlite.lmt @@ -100,7 +100,7 @@ local function execute(specification)                  end              end          else -            db       = open_db(filename) +            db       = sqlite_open(filename)              preamble = f_preamble(filename,base,base)          end          if not db then diff --git a/tex/context/base/mkxl/math-acc.mklx b/tex/context/base/mkxl/math-acc.mklx index 6e25c413f..49f97ae9c 100644 --- a/tex/context/base/mkxl/math-acc.mklx +++ b/tex/context/base/mkxl/math-acc.mklx @@ -57,23 +57,35 @@    [\v!bottom]    [\v!both] +\setupmathaccents +  [\v!top] +  [i=\v!auto] + +\setupmathaccents +  [\v!both] +  [i=\v!auto] + +\setupmathaccents +  [\v!bottom] +  [i=] +  \permanent\tolerant\protected\def\definemathtopaccent[#1]#*[#2]#*[#3]% class name top    {\ifparameter#3\or -     \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_make_double                        {#1}\plusone{\number#3}\zerocount}% +     \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_make_double                       {#1}\plusone{\number#3}\zerocount}%     \else       \frozen\protected\instance\edefcsname#1\endcsname{\math_accent_make_double\noexpand\currentmathaccent\plusone{\number#2}\zerocount}%     \fi}  \permanent\tolerant\protected\def\definemathbottomaccent[#1]#*[#2]#*[#3]% class name bottom    {\ifparameter#3\or -     \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_make_double                        {#1}\plustwo\zerocount{\number#3}}% +     \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_make_double                       {#1}\plustwo\zerocount{\number#3}}%     \else       \frozen\protected\instance\edefcsname#1\endcsname{\math_accent_make_double\noexpand\currentmathaccent\plustwo\zerocount{\number#2}}%     \fi}  \permanent\tolerant\protected\def\definemathdoubleaccent[#1]#*[#2]#*[#3]#*[#4]% class name top bottom    {\ifparameter#4\or -     \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_make_double                        {#1}\plusthree{\number#3}{\number#4}}% +     \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_make_double                       {#1}\plusthree{\number#3}{\number#4}}%     \else       \frozen\protected\instance\edefcsname#1\endcsname{\math_accent_make_double\noexpand\currentmathaccent\plusthree{\number#2}{\number#3}}%     \fi} @@ -97,16 +109,16 @@       \fam\zerocount#bottom     \or       both \m_fixed -     \fam\zerocount#top       \fam\zerocount#bottom +     \fam\zerocount#top     \fi -   {\ifconditional\c_math_accent_auto_dotless\mathdotless\fi#content}% +   {\ifcstok{\mathaccentparameter{i}}\v!auto\mathdotless\fi#content}%     \stopusemathstyleparameter     \endmathgroup}  %D Relative new: -\newconditional\c_math_accent_auto_dotless \settrue\c_math_accent_auto_dotless % cf opentype math +% \newconditional\c_math_accent_auto_dotless \settrue\c_math_accent_auto_dotless % cf opentype math  % \aliased\let\normalgrave\grave  % \aliased\let\normalddot \ddot @@ -125,39 +137,100 @@  % These retain the given unicode values ... but can stretch when configured  % to do so: \setupmathaccent[\v!top][\c!stretch=\v!yes] -\definemathtopaccent[\v!top][grave]["0060] % these are old school -\definemathtopaccent[\v!top][ddot] ["00A8] -\definemathtopaccent[\v!top][bar]  ["00AF] -\definemathtopaccent[\v!top][acute]["00B4] -\definemathtopaccent[\v!top][hat]  ["02C6] -\definemathtopaccent[\v!top][check]["02C7] -\definemathtopaccent[\v!top][breve]["02D8] -\definemathtopaccent[\v!top][dot]  ["02D9] -\definemathtopaccent[\v!top][ring] ["02DA] -\definemathtopaccent[\v!top][tilde]["02DC] -\definemathtopaccent[\v!top][dddot]["20DB] +% Extended/modified below +% +% \definemathtopaccent[\v!top][grave]["0060] % these are old school +% \definemathtopaccent[\v!top][ddot] ["00A8] +% \definemathtopaccent[\v!top][bar]  ["00AF] +% \definemathtopaccent[\v!top][acute]["00B4] +% \definemathtopaccent[\v!top][hat]  ["02C6] +% \definemathtopaccent[\v!top][check]["02C7] +% \definemathtopaccent[\v!top][breve]["02D8] +% \definemathtopaccent[\v!top][dot]  ["02D9] +% \definemathtopaccent[\v!top][ring] ["02DA] +% \definemathtopaccent[\v!top][tilde]["02DC] +% \definemathtopaccent[\v!top][dddot]["20DB] + +\definemathtopaccent[\v!top][grave]   ["0300] +\definemathtopaccent[\v!top][acute]   ["0301] +\definemathtopaccent[\v!top][hat]     ["0302] +\definemathtopaccent[\v!top][tilde]   ["0303] +\definemathtopaccent[\v!top][bar]     ["0304] +%definemathtopaccent[\v!top][overbar] ["0305]% We expect overbar to stretch, so later +\definemathtopaccent[\v!top][breve]   ["0306] +\definemathtopaccent[\v!top][dot]     ["0307] +\definemathtopaccent[\v!top][ddot]    ["0308] +\definemathtopaccent[\v!top][overhook]["0309] +\definemathtopaccent[\v!top][ring]    ["030A] +\definemathtopaccent[\v!top][check]   ["030C] + +% Here starts the weird unicode ones + +%definemathtopaccent[\v!top][candra]               ["0310] +%definemathtopaccent[\v!top][overturnedcomma]      ["0312] +%definemathtopaccent[\v!top][overcommatopright]    ["0315] +%definemathtopaccent[\v!top][leftangleabove]       ["031A] +\definemathtopaccent[\v!top][leftharpoonaccent]    ["20D0] +\definemathtopaccent[\v!top][rightharpoonaccent]   ["20D1] +%definemathtopaccent[\v!top][verticaloverlayaccent]["20D2] +%definemathtopaccent[\v!top][vec]                  ["20D7]% We expect vec to stretch, so later +\definemathtopaccent[\v!top][dddot]                ["20DB] +\definemathtopaccent[\v!top][ddddot]               ["20DC] +%definemathtopaccent[\v!top][annuityaccent]        ["20E7] +%definemathtopaccent[\v!top][overbracketaccent]    ["20E9] +%definemathtopaccent[\v!top][asterixaccent]        ["20F0] + +% Weird ones (why no single and double underdots in unicode?) + +%definemathbottomaccent[\v!bottom][underdot]  ["0323]%Conflicting +%definemathbottomaccent[\v!bottom][underddot] ["0324] +%definemathbottomaccent[\v!bottom][underdddot]["20E8]  \definemathaccent    [\v!top:\v!stretch]    [\v!top]    [\c!stretch=\v!yes] +\definemathaccent +  [\v!bottom:\v!stretch] +  [\v!bottom] +  [\c!stretch=\v!yes] + +\definemathaccent +  [\v!both:\v!stretch] +  [\v!both] +  [\c!stretch=\v!yes] +  %D We have a problem. We can use stackers but then we need to adapt the dimensions  %D which is font dependent. So, for now we keep them as accents.  \definemathtopaccent[\v!top:\v!stretch][widegrave]["0300] % these are generic modern -\definemathtopaccent[\v!top:\v!stretch][wideddot] ["0308] -\definemathtopaccent[\v!top:\v!stretch][widebar]  ["0304]  \definemathtopaccent[\v!top:\v!stretch][wideacute]["0301]  \definemathtopaccent[\v!top:\v!stretch][widehat]  ["0302] -\definemathtopaccent[\v!top:\v!stretch][widecheck]["030C] +\definemathtopaccent[\v!top:\v!stretch][widetilde]["0303] +\definemathtopaccent[\v!top:\v!stretch][widebar]  ["0305]%or 305  \definemathtopaccent[\v!top:\v!stretch][widebreve]["0306]  \definemathtopaccent[\v!top:\v!stretch][widedot]  ["0307] +\definemathtopaccent[\v!top:\v!stretch][wideddot] ["0308]  \definemathtopaccent[\v!top:\v!stretch][widering] ["030A] -\definemathtopaccent[\v!top:\v!stretch][widetilde]["0303] +\definemathtopaccent[\v!top:\v!stretch][widecheck]["030C]  \definemathtopaccent[\v!top:\v!stretch][widedddot]["20DB] -\definemathtopaccent[\v!top:\v!stretch][vec]      ["20D7] % clumsy notation for vectors +\definemathtopaccent[\v!top:\v!stretch][vec]["20D7] % clumsy notation for vectors + +\definemathtopaccent[\v!top:\v!stretch][wideoverleftharpoon]   ["20D0] +\definemathtopaccent[\v!top:\v!stretch][wideoverrightharpoon]  ["20D1] +\definemathtopaccent[\v!top:\v!stretch][wideoverleftarrow]     ["20D6]  +\definemathtopaccent[\v!top:\v!stretch][wideoverrightarrow]    ["20D7]  +\definemathtopaccent[\v!top:\v!stretch][wideoverleftrightarrow]["20E1] + +\definemathbottomaccent[\v!bottom:\v!stretch][wideundertilde]["0330] +\definemathbottomaccent[\v!bottom:\v!stretch][wideunderbar]["0332] +\definemathbottomaccent[\v!bottom:\v!stretch][wideunderleftrightarrow]["034D] +\definemathbottomaccent[\v!bottom:\v!stretch][wideunderrightharpoon]["20EC] +\definemathbottomaccent[\v!bottom:\v!stretch][wideunderleftharpoon]["20ED] +\definemathbottomaccent[\v!bottom:\v!stretch][wideunderleftarrow]["20EE] +\definemathbottomaccent[\v!bottom:\v!stretch][wideunderrightarrow]["20EF]  \aliased\let\mathring\ring % for a while diff --git a/tex/context/base/mkxl/math-act.lmt b/tex/context/base/mkxl/math-act.lmt index 370415c81..a6614aaa5 100644 --- a/tex/context/base/mkxl/math-act.lmt +++ b/tex/context/base/mkxl/math-act.lmt @@ -2624,6 +2624,20 @@ end  do +    function mathtweaks.inspect(target,original,parameters) +        local characters = target.characters +        local slot = parameters.slot or parameters.unicode +        if slot then +            -- todo: show unicode +            report_math(formatters["%C data:"](slot)) +            inspect(characters[slot]) +        end +    end + +end + +do +      local single <const> = 0x003D      local double <const> = 0x2A75      local triple <const> = 0x2A76 @@ -3886,13 +3900,13 @@ mathematics.horizontalcode = horizontalcode  interfaces.implement { -- can be public with two times "integerargument"      name      = "extensiblecode", -    arguments = { "integer", "integer" }, +    arguments = "2 integers",      actions   = { extensiblecode, context }  }  interfaces.implement { -- can be public with two times "integerargument"      name      = "horizontalcode", -    arguments = { "integer", "integer" }, +    arguments = "2 integers",      actions   = function(family,unicode)          local kind, loffset, roffset = horizontalcode(family,unicode)          texsetdimen(d_scratchleftoffset, loffset) @@ -3939,7 +3953,7 @@ end  interfaces.implement {      name      = "mathvariantcode",      public    = true, -    arguments = { "integer", "integer" }, +    arguments = "2 integers",      actions   = { mathematics.variantcode, context },  } diff --git a/tex/context/base/mkxl/math-noa.lmt b/tex/context/base/mkxl/math-noa.lmt index 6ccda30f3..4a0cb5744 100644 --- a/tex/context/base/mkxl/math-noa.lmt +++ b/tex/context/base/mkxl/math-noa.lmt @@ -2492,8 +2492,6 @@ end  do -    -- do we need this -      local traversehlist = nuts.traversers.hlist      local texgetdimen   = tex.getdimen diff --git a/tex/context/base/mkxl/mlib-ctx.lmt b/tex/context/base/mkxl/mlib-ctx.lmt index 8ed6b0b00..1ee21db38 100644 --- a/tex/context/base/mkxl/mlib-ctx.lmt +++ b/tex/context/base/mkxl/mlib-ctx.lmt @@ -231,7 +231,7 @@ implement {  implement {      name      = "mpsetoutercolor",      actions   = function(...) metapost.setoutercolor(...) end, -- not yet implemented -    arguments = { "integer", "integer", "integer", "integer" } +    arguments = "4 integers",  }  -- this has to become a codeinjection diff --git a/tex/context/base/mkxl/mlib-fio.lmt b/tex/context/base/mkxl/mlib-fio.lmt index 07c9275be..57984839f 100644 --- a/tex/context/base/mkxl/mlib-fio.lmt +++ b/tex/context/base/mkxl/mlib-fio.lmt @@ -69,15 +69,24 @@ local splitlines  = string.splitlines  local suffixlist = { "mpxl", "mpiv", "mp" } -- no "mf" +local remapped = { +    -- We don't yet have an interface for adding more here but when needed +    -- there will be one. +    ["hatching.mp"] = "mp-remapped-hatching.mp", +    ["boxes.mp"]    = "mp-remapped-boxes.mp", +    ["hatching"]    = "mp-remapped-hatching.mp", +    ["boxes"]       = "mp-remapped-boxes.mp", +} +  local function findmpfile(name,ftype) +    local usedname = remapped[name] or name      local validtyp = validftype(ftype) - -- local fullname = findfile(name,validtyp) -    local fullname = findtexfile(name,validtyp) +    local fullname = findtexfile(usedname,validtyp)      if fullname and fullname ~= "" then          return fullname -    elseif suffix(name) == "" then +    elseif suffix(usedname) == "" then          for i=1,#suffixlist do -            fullname = findfile(addsuffix(name,suffixlist[i]),validtyp) +            fullname = findfile(addsuffix(usedname,suffixlist[i]),validtyp)              if fullname and fullname ~= "" then                  return fullname              end diff --git a/tex/context/base/mkxl/page-flt.mkxl b/tex/context/base/mkxl/page-flt.mkxl index 8808ef00b..ae2bd4cf8 100644 --- a/tex/context/base/mkxl/page-flt.mkxl +++ b/tex/context/base/mkxl/page-flt.mkxl @@ -167,6 +167,36 @@          \blank[\rootfloatparameter\c!spaceafter]%        \fi}} +%D Not the best name for a command: +%D +%D \starttyping +%D \samplefile{tufte} +%D \placefigure[somewhere:a]{}{\externalfigure[dummy-001]} +%D \samplefile{tufte} +%D \placefigure{}{\externalfigure[dummy-002]} +%D \samplefile{tufte} +%D \startplacefigure[location={somewhere:b,tight}] +%D     \externalfigure[dummy-003] +%D \stopplacefigure +%D \samplefile{tufte} +%D \placefigure{}{\externalfigure[dummy-004]} +%D \page +%D \placesavedfloat[figure][b][location={none,left}] \samplefile{tufte} +%D \placesavedfloat[figure][a] +%D % \placenamedfloat[figure][*] +%D % \placenamedfloat[figure][b] +%D \stoptyping + +\newbox\b_strc_float_saved + +\permanent\tolerant\protected\def\placesavedfloat[#1]#*[#2]#*[#3]% experiment for Alan B +  {\clf_flushlabeledfloat\s!somewhere{#2}\relax +  %\def\currentfloat{#1}% +   \setbox\b_strc_float_saved\vpack{\box\floatbox}% +   \startplacefloat[#1][\c!location=\v!none,#3]% +     \box\b_strc_float_saved +   \stopplacefloat} +  % \setupcaption [figure]   [align=flushleft]  % \setupcaption [figure-1] [align=flushleft,leftmargin=10mm]  % \setupcaption [figure-2] [align=flushleft,leftmargin=10mm,rightmargin=-10mm,width=\textwidth] diff --git a/tex/context/base/mkxl/page-lin.lmt b/tex/context/base/mkxl/page-lin.lmt index f50031ab3..3c20feaee 100644 --- a/tex/context/base/mkxl/page-lin.lmt +++ b/tex/context/base/mkxl/page-lin.lmt @@ -414,5 +414,5 @@ end  implement {      name      = "addlinenumbers",      actions   = boxed.addlinenumbers, -    arguments = { "integer", "integer", "integer" } +    arguments = "3 integers",  } diff --git a/tex/context/base/mkxl/spac-ver.lmt b/tex/context/base/mkxl/spac-ver.lmt index 06032bcce..a2b02c34c 100644 --- a/tex/context/base/mkxl/spac-ver.lmt +++ b/tex/context/base/mkxl/spac-ver.lmt @@ -2830,7 +2830,7 @@ do          name      = "vspacingsnap",          actions   = vspacing.snapbox,          scope     = "private", -        arguments = { "integer", "integer" } +        arguments = "2 integers",      }      implement { diff --git a/tex/context/base/mkxl/strc-flt.lmt b/tex/context/base/mkxl/strc-flt.lmt new file mode 100644 index 000000000..e47046f8c --- /dev/null +++ b/tex/context/base/mkxl/strc-flt.lmt @@ -0,0 +1,53 @@ +if not modules then modules = { } end modules ['strc-flt'] = { +    version   = 1.001, +    comment   = "companion to strc-flt.mkiv", +    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +    copyright = "PRAGMA ADE / ConTeXt Development Team", +    license   = "see context related readme files" +} + +-- nothing + +local sequencers         = utilities.sequencers +local appendaction       = sequencers.appendaction +local enableaction       = sequencers.enableaction +local disableaction      = sequencers.disableaction + +local texgetdimen        = tex.getdimen +local texgetoutputactive = tex.getoutputactive + +local trace              = trackers.register("structure.sidefloats.pageflush") +local report             = logs.reporter("structure","floats") + +local forcepageflush     = builders.vspacing.forcepageflush + +local d_page_sides_vsize = tex.isdimen("d_page_sides_vsize") + +function builders.checksidefloat(mode,indented) +    if not texgetoutputactive() then +        local s = texgetdimen(d_page_sides_vsize) +        if s > 0 then +            if trace then +                report("force flushing page state, height %p",s) +            end +            forcepageflush() +        end +    else +        -- we don't have side floats outside the main vertical list +    end +    return indented +end + +-- These two lines might move to task-ini.lmt where we currently only deal +-- with node handlers: + +appendaction ("paragraph","system","builders.checksidefloat") +disableaction("paragraph","builders.checksidefloat") + +interfaces.implement { +    name     = "enablesidefloatchecker", +    onlyonce = true, +    actions  = function() +        enableaction("paragraph","builders.checksidefloat") +    end, +} diff --git a/tex/context/base/mkxl/strc-flt.mklx b/tex/context/base/mkxl/strc-flt.mklx index b82a80a71..6af22631a 100644 --- a/tex/context/base/mkxl/strc-flt.mklx +++ b/tex/context/base/mkxl/strc-flt.mklx @@ -15,10 +15,12 @@  \writestatus{loading}{ConTeXt Structure Macros / Float Numbering} -\registerctxluafile{strc-flt}{} -  \unprotect +\ifdefined\d_page_sides_vsize \else \newdimension\d_page_sides_vsize \fi + +\registerctxluafile{strc-flt}{autosuffix} +  % todo: a keyword for this (and then a settings->hash for speed)  %  % \setuplayout[width=middle,backspace=3cm] @@ -2127,15 +2129,38 @@       \hpack{\strc_floats_locate_text_float{\box\b_strc_floats_caption}}%     \fi} +\def\strc_floats_build_box_top_stack_normal_tight +  {\hpack{\box\b_strc_floats_caption}% +   \strc_floats_between_stack +   \hpack{\box\b_strc_floats_content}} + +\def\strc_floats_build_box_bottom_stack_normal_tight +  {\hpack{\box\b_strc_floats_content}% +   \strc_floats_between_stack +   \hpack{\box\b_strc_floats_caption}} +  \def\strc_floats_build_box_top_stack_normal    {\doifelseinset\v!overlay{\floatcaptionparameter\c!location}       \strc_floats_build_box_top_stack_normal_overlay -     \strc_floats_build_box_top_stack_normal_content} +  {\doifelseinset\v!tight{\floatlocation} +     \strc_floats_build_box_top_stack_normal_tight +     \strc_floats_build_box_top_stack_normal_content}}  \def\strc_floats_build_box_bottom_stack_normal -  {\doifinset\v!overlay{\floatcaptionparameter\c!location} +  {\doifelseinset\v!overlay{\floatcaptionparameter\c!location}       \strc_floats_build_box_bottom_stack_normal_overlay -     \strc_floats_build_box_bottom_stack_normal_content} +  {\doifelseinset\v!tight{\floatlocation} +     \strc_floats_build_box_bottom_stack_normal_tight +     \strc_floats_build_box_bottom_stack_normal_content}} + +% \def\strc_floats_build_box_bottom_stack_normal +%   {\ifhasxtoks{,\v!overlay,}{,\floatcaptionparameter\c!location,}% +%      \strc_floats_build_box_bottom_stack_normal_overlay +%    \orelse\ifhasxtoks{,\v!tight,}{,\floatlocation,}% +%      \strc_floats_build_box_bottom_stack_normal_tight +%    \else +%      \strc_floats_build_box_bottom_stack_normal_content +%    \fi}  \def\strc_floats_build_box_top_stack_grid    {\dp\b_strc_floats_caption\strutdepth @@ -2264,16 +2289,30 @@  \def\strc_floats_build_box_after    {\doifelseframed\floatframedparameter\strc_floats_build_box_after_indeed\relax} +% \def\strc_floats_build_box_after_indeed +%   {\global\setbox\floatbox\hpack +%      {\edef\m_width{\floatframedparameter\c!width}% +%       \ifx\m_width\v!fit +%         \let\m_width\floatwidth +%       \orelse\ifx\m_width\v!broad +%         \let\m_width\v!fit +%       \fi +%       \letfloatframedparameter\c!strut\v!no +%       \letfloatframedparameter\c!width\m_width +%       \inheritedfloatframedframed +%         {\box\floatbox}}} +  \def\strc_floats_build_box_after_indeed    {\global\setbox\floatbox\hpack       {\edef\m_width{\floatframedparameter\c!width}%        \ifx\m_width\v!fit -        \let\m_width\floatwidth +        \letfloatframedparameter\c!width\floatwidth        \orelse\ifx\m_width\v!broad -        \let\m_width\v!fit +        \letfloatframedparameter\c!width\v!fit +      \else +        \letfloatframedparameter\c!width\m_width % expanded, not really needed        \fi        \letfloatframedparameter\c!strut\v!no -      \letfloatframedparameter\c!width\m_width        \inheritedfloatframedframed          {\box\floatbox}}} diff --git a/tex/context/base/mkxl/strc-itm.lmt b/tex/context/base/mkxl/strc-itm.lmt new file mode 100644 index 000000000..f9153c98e --- /dev/null +++ b/tex/context/base/mkxl/strc-itm.lmt @@ -0,0 +1,64 @@ +if not modules then modules = { } end modules ['strc-itm'] = { +    version   = 1.001, +    comment   = "companion to strc-itm.mkiv", +    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +    copyright = "PRAGMA ADE / ConTeXt Development Team", +    license   = "see context related readme files" +} + +local structures  = structures +local itemgroups  = structures.itemgroups +local jobpasses   = job.passes + +local implement   = interfaces.implement + +local setvariable = jobpasses.save +local getvariable = jobpasses.getfield + +local texsetcount = tex.setcount +local texsetdimen = tex.setdimen + +local f_stamp     = string.formatters["itemgroup:%s:%s"] +local counts      = table.setmetatableindex("number") + +local c_strc_itemgroups_max_items = tex.iscount("c_strc_itemgroups_max_items") +local d_strc_itemgroups_max_width = tex.isdimen("d_strc_itemgroups_max_width") + +-- We keep the counter at the Lua end so we can group the items within +-- an itemgroup which in turn makes for less passes when one itemgroup +-- entry is added or removed. + +local trialtypesetting = context.trialtypesetting + +local function analyzeitemgroup(name,level) +    local n = counts[name] +    if level == 1 then +        n = n + 1 +        counts[name] = n +    end +    local stamp = f_stamp(name,n) +    texsetcount(c_strc_itemgroups_max_items,getvariable(stamp,level,1,0)) +    texsetdimen(d_strc_itemgroups_max_width,getvariable(stamp,level,2,0)) +end + +local function registeritemgroup(name,level,nofitems,maxwidth) +    local n = counts[name] +    if not trialtypesetting() then +        -- no trialtypsetting +        setvariable(f_stamp(name,n), { nofitems, maxwidth }, level) +    elseif level == 1 then +        counts[name] = n - 1 +    end +end + +implement { +    name      = "analyzeitemgroup", +    actions   = analyzeitemgroup, +    arguments = { "string", "integer" } +} + +implement { +    name      = "registeritemgroup", +    actions   = registeritemgroup, +    arguments = { "string", "integer", "integer", "dimen" } +} diff --git a/tex/context/base/mkxl/strc-itm.mklx b/tex/context/base/mkxl/strc-itm.mklx index cecb01cfc..737580a27 100644 --- a/tex/context/base/mkxl/strc-itm.mklx +++ b/tex/context/base/mkxl/strc-itm.mklx @@ -13,7 +13,12 @@  \writestatus{loading}{ConTeXt Structure Macros / Itemgroups} -\registerctxluafile{strc-itm}{} +\unprotect + +\newdimension\d_strc_itemgroups_max_width +\newinteger  \c_strc_itemgroups_max_items + +\registerctxluafile{strc-itm}{autosuffix}  %D As we analyze/register widths and such we could as well push and pop the numbers  %D at the \LUA\ end (which saves a few calls). @@ -170,8 +175,6 @@  % \item {test} is this okay?  % \stopitemize -\unprotect -  \newconditional\c_strc_itemgroups_sub  \newconditional\c_strc_itemgroups_head  \newconditional\c_strc_itemgroups_intro @@ -216,8 +219,10 @@  \newdimension  \d_strc_itemgroups_list_width  \newdimension  \d_strc_itemgroups_asked_width -\newdimension  \d_strc_itemgroups_max_width      \def\d_strc_itemgroups_max_width_reference{\d_strc_itemgroups_max_width} -\newinteger    \c_strc_itemgroups_max_items +%newdimension  \d_strc_itemgroups_max_width % defined already, used at the Lua end +%newinteger    \c_strc_itemgroups_max_items % idem + +\def\d_strc_itemgroups_max_width_reference{\d_strc_itemgroups_max_width} % no alias!  \newinteger    \c_strc_itemgroups_n_of_items  \newinteger    \c_strc_itemgroups_nesting diff --git a/tex/context/base/mkxl/strc-mat.mkxl b/tex/context/base/mkxl/strc-mat.mkxl index 6abc4b2cb..2e6c21ad2 100644 --- a/tex/context/base/mkxl/strc-mat.mkxl +++ b/tex/context/base/mkxl/strc-mat.mkxl @@ -2010,6 +2010,19 @@  %D New:  %D  %D \setupformula[snap=yes,snapstep=medium] +%D +%D \startbuffer +%D We test \dorecurse{20}{$x^{#1}$ and $\frac{1}{#1}^x$ and $\sqrt[#1]{x}$ and }that's it. +%D \stopbuffer +%D +%D \startcombination[nx=2,ny=3,location=top] +%D     {\ruledvbox{\hsize.45\textwidth \setupformula[snap=no]                 \showboxes            \enabletrackers [math.snapping=darkred] \getbuffer}} {} +%D     {\ruledvbox{\hsize.45\textwidth \setupformula[snap=no]                                       \disabletrackers[math.snapping]         \getbuffer}} {} +%D     {\ruledvbox{\hsize.45\textwidth \setupformula[snap=yes,snapstep=small] \showboxes \darkgreen \enabletrackers [math.snapping=darkred] \getbuffer}} {} +%D     {\ruledvbox{\hsize.45\textwidth \setupformula[snap=yes,snapstep=small]            \darkgreen \disabletrackers[math.snapping]         \getbuffer}} {} +%D     {\ruledvbox{\hsize.45\textwidth \setupformula[snap=yes,snapstep=big]   \showboxes \darkblue  \enabletrackers [math.snapping=darkred] \getbuffer}} {} +%D     {\ruledvbox{\hsize.45\textwidth \setupformula[snap=yes,snapstep=big]              \darkblue  \disabletrackers[math.snapping]         \getbuffer}} {} +%D \stopcombination  \definesystemattribute[mathsnap][public] diff --git a/tex/context/base/mkxl/strc-reg.lmt b/tex/context/base/mkxl/strc-reg.lmt index e2c4fdf02..b66b22921 100644 --- a/tex/context/base/mkxl/strc-reg.lmt +++ b/tex/context/base/mkxl/strc-reg.lmt @@ -1065,6 +1065,10 @@ implement {      end  } +function registers.tweak(data,options) +    -- Just in case it's needed. +end +  local function analyzeregister(class,options)      local data = rawget(collected,class)      if not data then @@ -1110,11 +1114,12 @@ local function analyzeregister(class,options)      if data and data.entries then          options = options or { }          sorters.setlanguage(options.language,options.method,options.numberorder) -        registers.filter(data,options)      -- filter entries into results (criteria) -        registers.prepare(data,options)     -- adds split table parallel to list table -        registers.sort(data,options)        -- sorts results -        registers.unique(data,options)      -- get rid of duplicates -        registers.finalize(data,options)    -- split result in ranges +        registers.filter(data,options)  -- filter entries into results (criteria) +        registers.prepare(data,options) -- adds split table parallel to list table +        registers.sort(data,options)    -- sorts results +        registers.unique(data,options)  -- get rid of duplicates +        registers.tweak(data,options)   -- plugin +        registers.finalize(data,options)-- split result in ranges          data.metadata.sorted = true          return data.metadata.nofsorted or 0      else diff --git a/tex/context/base/mkxl/strc-syn.lmt b/tex/context/base/mkxl/strc-syn.lmt new file mode 100644 index 000000000..940b982a7 --- /dev/null +++ b/tex/context/base/mkxl/strc-syn.lmt @@ -0,0 +1,420 @@ +if not modules then modules = { } end modules ['strc-syn'] = { +    version   = 1.001, +    comment   = "companion to str-syn.mkiv", +    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +    copyright = "PRAGMA ADE / ConTeXt Development Team", +    license   = "see context related readme files" +} + +local next, type = next, type +local sortedkeys = table.sortedkeys + +local context      = context +local implement    = interfaces.implement + +local allocate     = utilities.storage.allocate + +local sorters      = sorters + +local structures   = structures +local synonyms     = structures.synonyms +local tags         = structures.tags + +local collected    = allocate() +local tobesaved    = allocate() + +local firstofsplit = sorters.firstofsplit +local strip        = sorters.strip +local splitter     = sorters.splitters.utf + +synonyms.collected = collected +synonyms.tobesaved = tobesaved + +local progressions = { } -- false=not_yet_shown  true=shown + +local variables    = interfaces.variables +local v_all        = variables.all +local v_current    = variables.current + +local function initializer() +    collected = synonyms.collected +    tobesaved = synonyms.tobesaved +end + +local function finalizer() +    for entry, data in next, tobesaved do +        data.hash = nil +     -- being sparse can be an option but often we actually do want the +     -- whole list so we don't do this ... only as possible option +     -- +-- maybe pages = sortedkeys(pages) is more efficient +     -- +     -- local entries = data.entries +     -- local t = { } +     -- local n = 0 +     -- for i=1,#entries do +     --     local e = entries[i] +     --     if e.definition.shown then +     --         n = n + 1 +     --         t[n] = e +     --     end +     -- end +     -- data.entries = t +    end +end + +job.register('structures.synonyms.collected', tobesaved, initializer, finalizer) + +-- todo: allocate becomes metatable + +table.setmetatableindex(tobesaved,function(t,k) +    local v = { +        metadata = { +            language = 'en', +            sorted   = false, +            class    = v +        }, +        entries  = { +        }, +        hash = { +        } +    } +    t[k] = v +    return v +end) + +function synonyms.define(class,kind) +    local data = tobesaved[class] +    data.metadata.kind = kind +end + +function synonyms.register(class,kind,spec) +    local data       = tobesaved[class] +    local hash       = data.hash +    local definition = spec.definition +    local tag        = definition.tag or "" +    data.metadata.kind = kind -- runtime, not saved in format (yet) +    if not hash[tag] then +        local entries = data.entries +        entries[#entries+1] = spec +        hash[tag] = spec +    end +end + +function synonyms.registerused(class,tag) +    local data = tobesaved[class] +    local okay = data.hash[tag] +    if okay then +        local definition = okay.definition +        definition.used = true +        definition.list = true +    end +end + +function synonyms.registershown(class,tag) +    local data = tobesaved[class] +    local okay = data.hash[tag] +    if okay then +        local definition = okay.definition +        definition.shown = true +        definition.list  = true +    end +end + +function synonyms.isused(class,tag) +    local data = tobesaved[class] +    local okay = data.hash[tag] +    return okay and okay.definition.used or false +end + +function synonyms.isshown(class,tag) +    local data = tobesaved[class] +    local okay = data.hash[tag] +    return okay and okay.definition.shown or false +end + +local function resetused(class) +    for tag, data in next, tobesaved[class].hash do +        data.definition.used = nil +    end +end + +local function resetshown(class) +    for tag, data in next, tobesaved[class].hash do +        data.definition.shown = nil +    end +end + +local function resetlist(class) +    for tag, data in next, tobesaved[class].hash do +        data.definition.list = nil +    end +end + +local function resetall(class) +    for tag, data in next, tobesaved[class].hash do +        local definition = data.definition +        definition.used  = nil +        definition.shown = nil +        definition.list  = nil +    end +end + +synonyms.resetused  = resetused +synonyms.resetshown = resetshown +synonyms.resetlist  = resetlist +synonyms.resetall   = resetall + +function synonyms.reset(class,what) +    if what == "progress" then +        progressions = { } +    elseif what == "used" then +        resetused(class) +    elseif what == "shown" then +        resetshown(class) +    elseif what == "list" then +        resetlist(class) +    else +        resetall(class) +    end +end + +function synonyms.synonym(class,tag) +    local data = tobesaved[class] +    local okay = data.hash[tag] +    if okay then +        local definition = okay.definition +        definition.used = true +        definition.list = true +        context(definition.synonym) +    end +    if progressions[tag] == nil then +        progressions[tag] = false -- not yet shown +    end +end + +function synonyms.meaning(class,tag) +    local data = tobesaved[class] +    local okay = data.hash[tag] +    if okay then +        local definition = okay.definition +        definition.shown = true +        definition.list  = true +        context(definition.meaning) +    end +end + +function synonyms.pages(class,tag) +    local data = tobesaved[class] +    local okay = data.hash[tag] +    if okay then +        local definition = okay.definition +        local pages = definition.pages +        if pages and next(pages) then +            context("%,t",sortedkeys(pages)) +        end +    end +end + +local ctx_latelua = context.latelua + +local function enhance(data) +    local page = tex.getcount("realpageno") +    data.pages[page] = true +end + +function synonyms.enhance(class,tag) +    local data = tobesaved[class] +    local okay = data.hash[tag] +    if okay then +        local definition = okay.definition +        local pages      = definition.pages +        if not pages then +            pages            = { } +            definition.pages = pages +        end +        ctx_latelua { action = enhance, pages = pages } +    end +end + +synonyms.compare = sorters.comparers.basic -- (a,b) + +function synonyms.filter(data,options) +    local result    = { } +    local entries   = data.entries +    local criterium = options and options.criterium +    if criterium == v_all then +        for i=1,#entries do +            result[i] = entries[i] +        end +    else +        for i=1,#entries do +            local entry      = entries[i] +            local definition = entry.definition +            if definition.list then +                local tag  = definition.tag +                local done = progressions[tag] +                if done == false then +                    result[#result+1] = entry +                    progressions[tag] = true +                end +            end +        end +        if criterium == v_current then +            progressions = { } +        end +    end +    data.result = result +end + +function synonyms.prepare(data) +    local result = data.result +    if result then +        for i=1, #result do +            local entry      = result[i] +            local definition = entry.definition +            if definition then +                local srt = definition.sortkey or "" +                local tag = definition.tag or "" +                local key = (srt ~= "" and srt) or (tag ~= "" and tag) or definition.synonym +                if key then +                    entry.split = splitter(strip(key)) +                end +            end +        end +    end +end + +function synonyms.sort(data,options) +    sorters.sort(data.result,synonyms.compare) +    data.metadata.sorted = true +end + +function synonyms.finalize(data,options) -- mostly the same as registers so we will generalize it: sorters.split +    local result   = data.result +    local split    = { } +    local nofsplit = 0 +    local lasttag  = nil +    local lasttag  = nil +    local nofdone  = 0 +    for k=1,#result do +        local entry = result[k] +        local first, tag = firstofsplit(entry) +        if tag ~= lasttag then +         -- if trace_registers then +         --     report_registers("splitting at %a",tag) +         -- end +            done     = { } +            nofdone  = 0 +            nofsplit = nofsplit + 1 +            lasttag  = tag +            split[nofsplit] = { tag = tag, data = done } +        end +        nofdone = nofdone + 1 +        done[nofdone] = entry +    end +    data.result = split +end + +-- for now, maybe at some point we will do a multipass or so +-- maybe pass the settings differently + +local ctx_synonymentry = context.synonymentry + +function synonyms.flush(data,options) +    local result = data.result +    for i=1,#result do +        local sublist = result[i] +        local data    = sublist.data +        for d=1,#data do +            local entry = data[d].definition +            ctx_synonymentry(d,entry.tag,entry.synonym,entry.meaning or "") +        end +    end +    data.result          = nil +    data.metadata.sorted = false +end + +function synonyms.analyzed(class,options) +    local data = collected[class] +    if data and data.entries then +        options = options or { } +        sorters.setlanguage(options.language,options.method) +        synonyms.filter(data,options)   -- filters entries to result +        synonyms.prepare(data,options)  -- adds split table parallel to list table +        synonyms.sort(data,options)     -- sorts entries in result +        synonyms.finalize(data,options) -- do things with data.entries +        data.metadata.sorted = true +    end +    return data and data.metadata.sorted and data.result and next(data.result) +end + +function synonyms.process(class,options) +    if synonyms.analyzed(class,options) then +        synonyms.flush(collected[class],options) +    end +end + +-- todo: local higher up + +implement { name = "registerusedsynonym",  actions = synonyms.registerused,  arguments = "2 strings" } +implement { name = "registershownsynonym", actions = synonyms.registershown, arguments = "2 strings" } +implement { name = "synonymmeaning",       actions = synonyms.meaning,       arguments = "2 arguments" } +implement { name = "synonymname",          actions = synonyms.synonym,       arguments = "2 arguments" } +implement { name = "synonympages",         actions = synonyms.pages,         arguments = "2 arguments" } +implement { name = "enhancesynonym",       actions = synonyms.enhance,       arguments = "2 arguments" } +--        { name = "resetusedsynonyms",    actions = resetused,              arguments = "string" } +--        { name = "resetshownsynonyms",   actions = resetshown,             arguments = "string" } +--        { name = "resetlistsynonyms",    actions = resetlist,              arguments = "string" } +implement { name = "resetsynonyms",        actions = synonyms.reset,         arguments = "2 strings" } + +implement { +    name      = "doifelsesynonymused", +    actions   = { synonyms.isused, commands.doifelse }, +    arguments = "2 arguments", +} + +implement { +    name      = "doifelsesynonymshown", +    actions   = { synonyms.isshown, commands.doifelse }, +    arguments = "2 arguments", +} + +implement { +    name      = "registersynonym", +    actions   = synonyms.register, +    arguments = { +        "string", +        "string", +        { +            { "metadata", { +                    { "catcodes", "integer" }, +                    { "coding" }, +                    { "xmlroot" } +                } +            }, +            { +                "definition", { +                    { "tag" }, +                    { "synonym" }, +                    { "meaning" }, +                    { "sortkey" }, +                    { "used", "boolean" } +                } +            } +        } +    } +} + +implement { +    name      = "processsynonyms", +    actions   = synonyms.process, +    arguments = { +        "string", +        { +            { "criterium" }, +            { "language" }, +            { "method" } +        } +    } +} diff --git a/tex/context/base/mkxl/strc-syn.mkxl b/tex/context/base/mkxl/strc-syn.mkxl index af6d0c6e2..9b4c37ceb 100644 --- a/tex/context/base/mkxl/strc-syn.mkxl +++ b/tex/context/base/mkxl/strc-syn.mkxl @@ -13,7 +13,7 @@  \writestatus{loading}{ConTeXt Structure Macros / Synonyms and Sorting} -\registerctxluafile{strc-syn}{} +\registerctxluafile{strc-syn}{autosuffix}  %D Although we could nowadays build this on top of regular lists we keep this  %D more efficient variant around. Eventually we can add some options to lists @@ -354,24 +354,37 @@          }%       \relax       \ifx\currentsynonymoption\v!yes -       \instance\setuxvalue\currentsynonymtag{\strc_synonyms_insert{\currentsynonym}{\currentsynonymtag}}% +      %\instance\setuxvalue\currentsynonymtag{\strc_synonyms_insert{\currentsynonym}{\currentsynonymtag}}% +       \protected\instance\xdefcsname\currentsynonymtag\endcsname +         {\strc_synonyms_insert{\currentsynonym}{\currentsynonymtag}}%       \fi     \fi     \endgroup}  \permanent\tolerant\protected\def\registersynonym  [#1]#*[#2]{\clf_registerusedsynonym{#1}{#2}} -\permanent         \protected\def\currentsynonymname         {\clf_synonymname{\currentsimplelist}{\currentsynonymtag}} -\permanent         \protected\def\currentsynonymmeaning      {\clf_synonymmeaning{\currentsimplelist}{\currentsynonymtag}} -\permanent         \protected\def\doifelsecurrentsynonymused {\clf_doifelsesynonymused{\currentsimplelist}{\currentsynonymtag}} -\permanent         \protected\def\doifelsecurrentsynonymshown{\clf_doifelsesynonymshown{\currentsimplelist}{\currentsynonymtag}} +\permanent         \protected\def\currentsynonymname         {\clf_synonymname\currentsimplelist\currentsynonymtag} +\permanent         \protected\def\currentsynonymmeaning      {\clf_synonymmeaning\currentsimplelist\currentsynonymtag} +\permanent         \protected\def\currentsynonympages        {\clf_synonympages\currentsimplelist\currentsynonymtag} +\permanent         \protected\def\doifelsecurrentsynonymused {\clf_doifelsesynonymused\currentsimplelist\currentsynonymtag} +\permanent         \protected\def\doifelsecurrentsynonymshown{\clf_doifelsesynonymshown\currentsimplelist\currentsynonymtag}  \permanent         \protected\def\resetusedsynonyms      [#1]{\clf_resetsynonyms{#1}{used}}  \permanent         \protected\def\resetshownsynonyms     [#1]{\clf_resetsynonyms{#1}{shown}}  \permanent         \protected\def\resetlistsynonyms      [#1]{\clf_resetsynonyms{#1}{list}}  \permanent         \protected\def\resetsynonyms          [#1]{\clf_resetsynonyms{#1}{all}}  \permanent         \protected\def\resetsynonymsprogress  [#1]{\clf_resetsynonyms{#1}{progress}} +\permanent\protected\def\registercurrentsynonympage % \registercurrentsortingpage +  {\ifcstok{\simplelistparameter\v!page}\v!yes +     \clf_enhancesynonym\currentsimplelist\currentsortingtag +   \fi} +  \aliased\let\rawsynonymname   \clf_synonymname  \aliased\let\rawsynonymmeaning\clf_synonymmeaning +\aliased\let\rawsynonympages  \clf_synonympages + +\permanent\protected\def\synonymname   [#1]#*[#2]{\clf_synonymname   {#1}{#2}} +\permanent\protected\def\synonymmeaning[#1]#*[#2]{\clf_synonymmeaning{#1}{#2}} +\permanent\protected\def\synonympages  [#1]#*[#2]{\clf_synonympages  {#1}{#2}}  \installcorenamespace{simplelistalternative} % specific ways of rendering a list  \installcorenamespace{simplelistrenderings}  % a namespace for setups (rather local) @@ -424,6 +437,7 @@      \dostarttaggedchained\t!synonym\currentsynonym\??simplelist      \dotagsynonym      \usesimpleliststyleandcolor\c!synonymstyle\c!synonymcolor +    \registercurrentsynonympage      \simplelistparameter\c!synonymcommand{\currentsynonymname}%      \dostoptagged      \endgroup @@ -523,9 +537,7 @@  \aliased\let\setupsorting\setupsimplelist -% if #3=\relax or \v!none, then no command but still protected - -% these  might become private +% some of these might become private  \mutable\lettonothing\currentsortingoption  \mutable\lettonothing\currentsortingcoding @@ -536,10 +548,14 @@  \permanent\tolerant\protected\def\definesorting[#1]#*[#2]#*[#3]%    {\ifnum\lastarguments=\plusthree -     \doifnot{#3}\v!none -       {\ifx#3\relax \else -          \protected\instance\def#3##1{\strc_sorting_insert{#1}{##1}}% -        \fi}% +  %\ifparameter#3\or +     \ifcstok{#3}\v!none +       % skip +     \orelse\ifrelax#3\relax +       % skip +     \else +       \protected\instance\def#3##1{\strc_sorting_insert{#1}{##1}}% +     \fi       \frozen\instance\protected\defcsname#1\endcsname{\definesort[\v!no][#1]}%     \else       \frozen\instance\protected\defcsname#1\endcsname{\definesort[\v!yes][#1]}% @@ -600,14 +616,25 @@          }%       \relax       \ifx\currentsortingoption\v!yes -       \instance\setuxvalue\currentsortingtag{\strc_sorting_insert{\currentsorting}{\currentsortingtag}}% +      %\instance\setuxvalue\currentsortingtag{\strc_sorting_insert{\currentsorting}{\currentsortingtag}}% +       \protected\instance\xdefcsname\currentsortingtag\endcsname +         {\strc_sorting_insert{\currentsorting}{\currentsortingtag}}%       \fi     \fi     \endgroup} -\permanent\protected\def\currentsortingname         {\clf_synonymname         {\currentsimplelist}{\currentsortingtag}} -\permanent\protected\def\doifelsecurrentsortingused {\clf_doifelsesynonymused {\currentsimplelist}{\currentsortingtag}} -\permanent\protected\def\resetusedsortings      [#1]{\clf_resetusedsynonyms   {#1}} +\permanent\protected\def\currentsortingname         {\clf_synonymname\currentsimplelist\currentsortingtag} +\permanent\protected\def\currentsortingpages        {\clf_synonympages\currentsimplelist\currentsortingtag} +\permanent\protected\def\doifelsecurrentsortingused {\clf_doifelsesynonymused\currentsimplelist\currentsortingtag} +\permanent\protected\def\resetusedsortings      [#1]{\clf_resetusedsynonyms{#1}} + +\permanent\protected\def\sortingname [#1]#*[#2]{\clf_synonymname {#1}{#2}} +\permanent\protected\def\sortingpages[#1]#*[#2]{\clf_synonympages{#1}{#2}} + +\aliased\let\rawsortingname \clf_synonymname +\aliased\let\rawsortingpages\clf_synonymmeaning + +\aliased\let\registercurrentsortingpage\registercurrentsynonympage  \setupsimplelist    [\v!sorting] @@ -641,6 +668,7 @@      \dostarttaggedchained\t!sorting\currentsorting\??simplelist      \dotagsorting      \usesimpleliststyleandcolor\c!style\c!color +    \registercurrentsortingpage      \currentsortingname      \dostoptagged      \endgroup @@ -649,6 +677,9 @@  \permanent\tolerant\protected\def\registersort[#1]#*[#2]%    {\clf_registerusedsynonym{#1}{#2}} +\permanent\tolerant\protected\def\registersortpage[#1]#*[#2]% +  {\clf_enhancesynonym{#1}{#2}} +  % before after  %  % maybe just 'commandset' and then combine diff --git a/tex/context/base/mkxl/tabl-ntb.lmt b/tex/context/base/mkxl/tabl-ntb.lmt new file mode 100644 index 000000000..a307d046a --- /dev/null +++ b/tex/context/base/mkxl/tabl-ntb.lmt @@ -0,0 +1,143 @@ +if not modules then modules = { } end modules ['tabl-ntb'] = { +    version   = 1.001, +    comment   = "companion to tabl-ntb.mkxl", +    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +    copyright = "PRAGMA ADE / ConTeXt Development Team", +    license   = "see context related readme files" +} + +local context = context + +local a_tablesection = attributes.system("tablesection") + +local hlist_code     = nodes.nodecodes.hlist + +local nuts           = nodes.nuts +local tonode         = nuts.tonode +local getbox         = nuts.getbox +local getlist        = nuts.getlist +local getid          = nuts.getid +local getnext        = nuts.getnext +local setnext        = nuts.setnext +local getattr        = nuts.getattr +local copylist       = nuts.copylist +local flushlist      = nuts.flushlist + +local integer_value  = tokens.values.integer + +local implement      = interfaces.implement + +local list           = { } +local sections       = { } + +local function check(b) +    local c = getbox(b) +    local l = c and getlist(c) +    local d = false +    local n = 0 +    while l do +        if getid(l) == hlist_code then +            local line = getattr(l,a_tablesection) +            if line and line ~= d then +                local s = sections[line] +                if s then +                    local count = s[2] +                    local last = l +                    local next = getnext(l) +                    while next and count > 0 do +                        last  = next +                        next  = getnext(next) +                        count = count - 1 +                    end +                    setnext(last) +                    list[line] = { l, copylist(l) } +                    if next then +                        setnext(last,next) +                    end +                    d = line +                end +            end +            n = n + 1 +        end +        l = getnext(l) +    end +end + +local function reset(b) +    for k, v in next, list do +        flushlist(v[2]) +    end +    list     = { } +    sections = { } +end + +local function locate(b) +    local c = getbox(b) +    local l = c and getlist(c) +    while l do +        if getid(l) == hlist_code then +            local line = getattr(l,a_tablesection) +            if line then +                local v = list[line] +                if v and v[1] ~= l then +                    return line +                end +            end +            return 0 +        end +        l = getnext(l) +    end +    return 0 +end + +local function fetch(n) +    local b = list[n] +    if b then +        b = copylist(b[2]) +        return tonode(b) +    end +end + +implement { +    name      = "tabl_ntb_set_sec", +    public    = true, +    arguments = { "integer", "integer", "integer" }, +    actions   = function(n,m,count) +        sections[n] = { m, count } +    end, +} + +implement { +    name      = "tabl_ntb_get_sec", +    public    = true, +    arguments = "integer", +    usage     = "value", +    actions   = function(n) +        local s =  sections[n] +        return integer_value, s and s[1] or 0 +    end, +} + +implement { +    name      = "ntb_split_section_check", +    arguments = "integer", +    actions   = check, +} + +implement { +    name      = "ntb_split_section_reset", +    arguments = "integer", +    actions   = reset, +} + +implement { +    name      = "ntb_split_section_locate", +    arguments = "integer", +    actions   = { locate, context }, +} + +implement { +    name      = "ntb_split_section_fetch", +    arguments = "integer", +    actions   = { fetch, context }, +} diff --git a/tex/context/base/mkxl/tabl-ntb.mkxl b/tex/context/base/mkxl/tabl-ntb.mkxl index 6eb926b09..414a04f3a 100644 --- a/tex/context/base/mkxl/tabl-ntb.mkxl +++ b/tex/context/base/mkxl/tabl-ntb.mkxl @@ -24,6 +24,8 @@  \writestatus{loading}{ConTeXt Table Macros / Natural Tables} +\registerctxluafile{tabl-ntb}{autosuffix} +  % sometimes this helps (with nc going wild): \setupTABLE[maxwidth=100cm]  %  % bug: width 3cm is not honored and column becomes too wide as given width is added @@ -2295,6 +2297,99 @@  \permanent\protected\def\bTRs[#1]#2\eTRs    {\normalexpanded{\bTR[\begincsname\??naturaltablesetup#1\endcsname]}#2\eTR} +%D This is new (for Ramkumar, Kb) +%D +%D \starttyping +%D \bTABLE[split=repeat] +%D     \bTABLEhead +%D         \bTR \bTH \darkblue header \eTH \bTH \darkblue done \eTH \eTR +%D     \eTABLEhead +%D     \dorecurse{12}{ +%D         \bTABLEbody +%D             \bTABLEsection +%D                 \bTR \bTD \darkred line #1.1 \eTD \bTD \darkred done \eTD \eTR +%D                 \bTR \bTD \darkred line #1.2 \eTD \bTD \darkred done \eTD \eTR +%D             \eTABLEsection +%D             \bTABLEsection[repeat=2] +%D                 \bTR[samepage=after] \bTH \darkorange header #1.1 \eTH \bTH \darkorange done \eTH \eTR +%D                 \bTR[samepage=after] \bTH \darkorange header #1.2 \eTH \bTH \darkorange done \eTH \eTR +%D                 \bTR                 \bTD \darkgreen  hline  #1.3 \eTD \bTD \darkgreen  done \eTD \eTR +%D                 \bTR                 \bTD \darkgreen  hline  #1.4 \eTD \bTD \darkgreen  done \eTD \eTR +%D                 \bTR                 \bTD \darkgreen  hline  #1.5 \eTD \bTD \darkgreen  done \eTD \eTR +%D             \eTABLEsection +%D         \eTABLEbody +%D     } +%D \eTABLE +%D \stoptyping + +\definesystemattribute[tablesection][public] + +\newinteger\c_tabl_ntb_section +\newinteger\c_tabl_ntb_section_repeat + +\def\tabl_ntb_section_mark_indeed +  {\ifcase\c_tabl_ntb_section_repeat +     \tabl_ntb_set_sec\c_tabl_ntb_maximum_row\zerocount\zerocount +   \else +     \tabl_ntb_set_sec\c_tabl_ntb_maximum_row\c_tabl_ntb_section\c_tabl_ntb_section_repeat +   \fi} + +\def\tabl_ntb_section_checkup_indeed +  {\scratchcounter\tabl_ntb_get_sec\c_tabl_ntb_row\relax +   \ifcase\scratchcounter +     \c_attr_tablesection\attributeunsetvalue +   \else +     \c_attr_tablesection\scratchcounter +   \fi} + +\def\tabl_ntb_section_split_indeed +  {\scratchcounter\clf_ntb_split_section_locate\b_split_content\relax +   \ifcase\scratchcounter\else +     \clf_ntb_split_section_fetch\scratchcounter +   \fi} + +\def\tabl_ntb_section_wrapup_indeed +   {\clf_ntb_split_section_reset\b_split_content +    \tabl_ntb_section_setup} + +\def\tabl_ntb_section_install_indeed +  {\clf_ntb_split_section_check\b_split_content +   \t_split_section{\tabl_ntb_section_split}} + +\def\tabl_ntb_section_disable +  {\glet\tabl_ntb_section_mark   \relax +   \glet\tabl_ntb_section_checkup\relax +   \glet\tabl_ntb_section_split  \relax +   \glet\tabl_ntb_section_install\relax +   \glet\tabl_ntb_section_wrapup \relax} + +\def\tabl_ntb_section_enable +  {\let\tabl_ntb_section_enable  \relax +   \glet\tabl_ntb_section_mark   \tabl_ntb_section_mark_indeed +   \glet\tabl_ntb_section_checkup\tabl_ntb_section_checkup_indeed +   \glet\tabl_ntb_section_split  \tabl_ntb_section_split_indeed +   \glet\tabl_ntb_section_install\tabl_ntb_section_install_indeed +   \glet\tabl_ntb_section_wrapup \tabl_ntb_section_wrapup_indeed} + +\def\tabl_ntb_section_setup +  {\global\c_tabl_ntb_section_repeat\zerocount +   \c_tabl_ntb_section\zerocount +   \tabl_ntb_section_disable} + +\tolerant\permanent\protected\def\bTABLEsection[#1]% +  {\ifempty{#1}% +     \global\c_tabl_ntb_section_repeat\zerocount +   \else +     \letdummyparameter\c!repeat\zerocount +     \getdummyparameters[#1]% +     \global\c_tabl_ntb_section_repeat\dummyparameter\c!repeat\relax +   \fi +   \global\advanceby\c_tabl_ntb_section\plusone +   \tabl_ntb_section_enable} + +\permanent\protected\def\eTABLEsection +  {\global\c_tabl_ntb_section_repeat\zerocount} +  \protect \endinput  % todo: mode: first|next (of niets) diff --git a/tex/context/base/mkxl/task-ini.lmt b/tex/context/base/mkxl/task-ini.lmt index d2ce7f770..57376ae2b 100644 --- a/tex/context/base/mkxl/task-ini.lmt +++ b/tex/context/base/mkxl/task-ini.lmt @@ -227,3 +227,8 @@ directives.register("nodes.basepass", function(v)           disableaction("processors", "builders.kernel.kerning")      end  end) + +-- These are different and currently done in strc-flt.lmt but it might move here: +-- +-- utilities.sequencers.appendaction ("paragraph","system","builders.checksidefloat") +-- utilities.sequencers.disableaction("paragraph","builders.checksidefloat") diff --git a/tex/context/base/mkxl/toks-scn.lmt b/tex/context/base/mkxl/toks-scn.lmt index 5af351939..ab531a462 100644 --- a/tex/context/base/mkxl/toks-scn.lmt +++ b/tex/context/base/mkxl/toks-scn.lmt @@ -358,6 +358,16 @@ local presets = {      ["2 arguments"] = { "argument", "argument" },      ["3 arguments"] = { "argument", "argument", "argument" },      ["4 arguments"] = { "argument", "argument", "argument", "argument" }, + +    ["1 integer"]  = { "integer" }, +    ["2 integers"] = { "integer", "integer" }, +    ["3 integers"] = { "integer", "integer", "integer" }, +    ["4 integers"] = { "integer", "integer", "integer", "integer" }, + +    ["1 optional"]  = { "optional" }, +    ["2 optionals"] = { "optional", "optional" }, +    ["3 optionals"] = { "optional", "optional", "optional" }, +    ["4 optionals"] = { "optional", "optional", "optional", "optional" },  }  tokens.presets = presets diff --git a/tex/context/base/mkxl/type-set.mkxl b/tex/context/base/mkxl/type-set.mkxl index 5b83f287e..62dd3c9ab 100644 --- a/tex/context/base/mkxl/type-set.mkxl +++ b/tex/context/base/mkxl/type-set.mkxl @@ -105,26 +105,28 @@  \definefilesynonym [type-imp-eulernovum.mkiv]             [type-imp-euler.mkiv]  \definefilesynonym [type-imp-eulernova.mkiv]              [type-imp-euler.mkiv] -\definefilesynonym [type-imp-euler-with-pagella.mkiv]     [type-imp-euler.mkiv] -\definefilesynonym [type-imp-pagella-with-euler.mkiv]     [type-imp-euler.mkiv] - -\definefilesynonym [type-imp-mdbch.mkiv]                  [type-imp-mathdesign.mkiv] -\definefilesynonym [type-imp-mdugm.mkiv]                  [type-imp-mathdesign.mkiv] -\definefilesynonym [type-imp-mdput.mkiv]                  [type-imp-mathdesign.mkiv] -\definefilesynonym [type-imp-mdici.mkiv]                  [type-imp-mathdesign.mkiv] -\definefilesynonym [type-imp-mdpgd.mkiv]                  [type-imp-mathdesign.mkiv] -\definefilesynonym [type-imp-mdpus.mkiv]                  [type-imp-mathdesign.mkiv] - -\definefilesynonym [type-imp-mathdesignch.mkiv]           [type-imp-mathdesign.mkiv] -\definefilesynonym [type-imp-mathdesigngm.mkiv]           [type-imp-mathdesign.mkiv] -\definefilesynonym [type-imp-mathdesignut.mkiv]           [type-imp-mathdesign.mkiv] -\definefilesynonym [type-imp-mathdesignci.mkiv]           [type-imp-mathdesign.mkiv] -\definefilesynonym [type-imp-mathdesigngd.mkiv]           [type-imp-mathdesign.mkiv] -\definefilesynonym [type-imp-mathdesignus.mkiv]           [type-imp-mathdesign.mkiv] - -\definefilesynonym [type-imp-mathdesigncharter.mkiv]      [type-imp-mathdesign.mkiv] -\definefilesynonym [type-imp-mathdesigngaramond.mkiv]     [type-imp-mathdesign.mkiv] -\definefilesynonym [type-imp-mathdesignutopia.mkiv]       [type-imp-mathdesign.mkiv] +\definefilesynonym [type-imp-euler-with-pagella.mkiv]     [type-imp-euler.mkxl] +\definefilesynonym [type-imp-pagella-with-euler.mkiv]     [type-imp-euler.mkxl] +\definefilesynonym [type-imp-euleroverpagella.mkiv]       [type-imp-euler.mkxl] +\definefilesynonym [type-imp-pagellaovereuler.mkiv]       [type-imp-euler.mkxl] + +%definefilesynonym [type-imp-mdbch.mkiv]                  [type-imp-mathdesign.mkiv] +%definefilesynonym [type-imp-mdugm.mkiv]                  [type-imp-mathdesign.mkiv] +%definefilesynonym [type-imp-mdput.mkiv]                  [type-imp-mathdesign.mkiv] +%definefilesynonym [type-imp-mdici.mkiv]                  [type-imp-mathdesign.mkiv] +%definefilesynonym [type-imp-mdpgd.mkiv]                  [type-imp-mathdesign.mkiv] +%definefilesynonym [type-imp-mdpus.mkiv]                  [type-imp-mathdesign.mkiv] + +%definefilesynonym [type-imp-mathdesignch.mkiv]           [type-imp-mathdesign.mkiv] +%definefilesynonym [type-imp-mathdesigngm.mkiv]           [type-imp-mathdesign.mkiv] +%definefilesynonym [type-imp-mathdesignut.mkiv]           [type-imp-mathdesign.mkiv] +%definefilesynonym [type-imp-mathdesignci.mkiv]           [type-imp-mathdesign.mkiv] +%definefilesynonym [type-imp-mathdesigngd.mkiv]           [type-imp-mathdesign.mkiv] +%definefilesynonym [type-imp-mathdesignus.mkiv]           [type-imp-mathdesign.mkiv] + +%definefilesynonym [type-imp-mathdesigncharter.mkiv]      [type-imp-mathdesign.mkiv] +%definefilesynonym [type-imp-mathdesigngaramond.mkiv]     [type-imp-mathdesign.mkiv] +%definefilesynonym [type-imp-mathdesignutopia.mkiv]       [type-imp-mathdesign.mkiv]  \definefilesynonym [type-imp-cows.mkiv]                   [type-imp-koeielettersot.mkiv]  \definefilesynonym [type-imp-sheep.mkiv]                  [type-imp-koeielettersot.mkiv] diff --git a/tex/context/base/mkxl/typo-fkr.lmt b/tex/context/base/mkxl/typo-fkr.lmt new file mode 100644 index 000000000..3491c9eff --- /dev/null +++ b/tex/context/base/mkxl/typo-fkr.lmt @@ -0,0 +1,122 @@ +if not modules then modules = { } end modules ['typo-fkr'] = { +    version   = 1.001, +    comment   = "companion to typo-fkr.mkiv", +    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +    copyright = "PRAGMA ADE / ConTeXt Development Team", +    license   = "see context related readme files" +} + +local nuts          = nodes.nuts +local getid         = nuts.getid +local getnext       = nuts.getnext +local getattr       = nuts.getattr +local isglyph       = nuts.isglyph + +local nodecodes     = nodes.nodecodes +local glyph_code    = nodecodes.glyph + +local fontdata      = fonts.hashes.identifiers +local getkernpair   = fonts.handlers.otf.getkern + +local insertbefore  = nuts.insertbefore +local new_kern      = nuts.pool.fontkern + +local enableaction  = nodes.tasks.enableaction + +local a_extrakern   = attributes.private("extrafontkern") + +-- 0=none 1=min 2=max 3=mixed + +typesetters.fontkerns = { } + +function typesetters.fontkerns.handler(head) +    local current   = head +    local lastfont  = nil +    local lastchar  = nil +    local lastdata  = nil +    while current do +        local char, font = isglyph(current) +        if char then +            local a = getattr(current,a_extrakern) +            if a then +                if font ~= lastfont then +                    if a > 0 and lastchar then +                        if not lastdata then +                            lastdata = fontdata[lastfont] +                        end +                        local kern  = nil +                        local data  = fontdata[font] +                        local kern1 = getkernpair(lastdata,lastchar,char) +                        local kern2 = getkernpair(data,lastchar,char) +                        if a == 1 then +                            kern = kern1 > kern2 and kern2 or kern1 -- min +                        elseif a == 2 then +                            kern = kern1 > kern2 and kern1 or kern2 -- max +                        else -- 3 +                            kern = (kern1 + kern2)/2                -- mixed +                        end +                        if kern ~= 0 then +                            head = insertbefore(head,current,new_kern(kern)) +                        end +                        lastdata = data +                    else +                        lastdata = nil +                    end +                elseif lastchar then +                    if not lastdata then +                        lastdata = fontdata[lastfont] +                    end +                    local kern = getkernpair(lastdata,lastchar,char) +                    if kern ~= 0 then +                        head = insertbefore(head,current,new_kern(kern)) +                    end +                end +                lastchar = char +                lastfont = font +            elseif lastfont then +                lastfont = nil +                lastchar = nil +                lastdata = nil +            end +        elseif lastfont then +            lastfont = nil +            lastchar = nil +            lastdata = nil +        end +        current = getnext(current) +    end +    return head +end + +do + +    local variables    = interfaces.variables +    local unsetvalue   = attributes.unsetvalue +    local enabled      = false +    local setattribute = tex.setattribute + +    local values       = { +        [variables.none ] = 0, +        [variables.min  ] = 1, +        [variables.max  ] = 2, +        [variables.mixed] = 3, +        [variables.reset] = unsetvalue, +    } + +    local function setextrafontkerns(str) +        if not enabled then +            enableaction("processors","typesetters.fontkerns.handler") +            enabled = true +        end +        setattribute(a_extrakern,str and values[str] or unsetvalue) +    end + +    interfaces.implement { +        name      = "setextrafontkerns", +        public    = true, +        protected = true, +        arguments = "optional", +        actions   = setextrafontkerns, +    } + +end diff --git a/tex/context/base/mkxl/typo-fkr.mkxl b/tex/context/base/mkxl/typo-fkr.mkxl index f56294dc0..726e02646 100644 --- a/tex/context/base/mkxl/typo-fkr.mkxl +++ b/tex/context/base/mkxl/typo-fkr.mkxl @@ -13,7 +13,7 @@  \writestatus{loading}{ConTeXt Typesetting Macros / Additional Font Kerning} -\registerctxluafile{typo-fkr}{} +\registerctxluafile{typo-fkr}{autosuffix}  \definesystemattribute[extrafontkern][public] @@ -25,8 +25,8 @@  % mixed : mean value across fonts  % reset : disable -\permanent\protected\def\setextrafontkerns[#1]% % can be public implementor -  {\clf_setextrafontkerns{#1}} +% \permanent\protected\def\setextrafontkerns[#1]% defined at the lua end +%   {\clf_setextrafontkerns{#1}}  \permanent\protected\def\resetextrafontkerns    {\c_attr_extrafontkern\attributeunsetvalue} diff --git a/tex/context/base/mkxl/typo-inj.lmt b/tex/context/base/mkxl/typo-inj.lmt new file mode 100644 index 000000000..238524a94 --- /dev/null +++ b/tex/context/base/mkxl/typo-inj.lmt @@ -0,0 +1,119 @@ +if not modules then modules = { } end modules ['typo-inj'] = { -- was node-par +    version   = 1.001, +    comment   = "companion to typo-inj.mkiv", +    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +    copyright = "PRAGMA ADE / ConTeXt Development Team", +    license   = "see context related readme files" +} + +local tonumber = tonumber + +local context           = context +local implement         = interfaces.implement + +local injectors         = { } +typesetters.injectors   = injectors +local list              = { } +injectors.list          = list +local showall           = false + +local settings_to_array = utilities.parsers.settings_to_array + +local variables         = interfaces.variables +local v_next            = variables.next +local v_previous        = variables.previous + +local ctx_domarkinjector     = context.domarkinjector +local ctx_doactivateinjector = context.doactivateinjector + +table.setmetatableindex(list,function(t,k) +    local v = { +        counter = 0, +        actions = { }, +        show    = false, +        active  = false, +    } +    t[k] = v +    return v +end) + +function injectors.reset(name) +    list[name] = nil +end + +local function activate(injector,name) +    if not injector.active then +        ctx_doactivateinjector(name) +        injector.active = true +        if showall then +            -- in case we already enabled tracing +            injector.show = true +        end +    end +end + +function injectors.set(name,numbers,command) +    local injector = list[name] +    local actions  = injector.actions +    local places   = settings_to_array(numbers) +    for i=1,#places do +        actions[tonumber(places[i])] = command +    end +    -- not: injector.show = true +    activate(injector,name) +end + +function injectors.show(name) +    if not name or name == "" then +        showall = true +        local names = settings_to_array(name) +        for name, injector in next, list do +            injector.show = true +            activate(injector,name) +        end +    else +        local names = settings_to_array(name) +        for i=1,#names do +            local name     = names[i] +            local injector = list[name] +            if injector then +                injector.show = true +                activate(injector,name) +            end +        end +    end +end + +function injectors.mark(name,show) +    local injector = list[name] +    local n = injector.counter + 1 +    injector.counter = n +    if showall or injector.show then +        ctx_domarkinjector(injector.actions[n] and 1 or 0,n) +    end +end + +function injectors.check(name,n) -- we could also accent n = number : +/- 2 +    local injector = list[name] +    if not n or n == "" or n == v_next then +        n = injector.counter + 1 +    elseif n == v_previous then +        n = injector.counter +    else +        n = tonumber(n) or 0 +    end +    local action = injector.actions[n] +    if action then +        context(action) +    end +end + +-- maybe string -> argument + +implement { name = "resetinjector",         actions = injectors.reset, arguments = "string" } +implement { name = "showinjector",          actions = injectors.show,  arguments = "string" } +implement { name = "setinjector",           actions = injectors.set,   arguments = "3 strings" } +implement { name = "markinjector",          actions = injectors.mark,  arguments = "string" } +implement { name = "checkinjector",         actions = injectors.check, arguments = "2 strings" } +--------- { name = "checkpreviousinjector", actions = injectors.check, arguments = { "string", v_previous } } +--------- { name = "checknextinjector",     actions = injectors.check, arguments = { "string", v_next } } diff --git a/tex/context/base/mkxl/typo-inj.mkxl b/tex/context/base/mkxl/typo-inj.mkxl index bf329482e..04c4f677c 100644 --- a/tex/context/base/mkxl/typo-inj.mkxl +++ b/tex/context/base/mkxl/typo-inj.mkxl @@ -24,7 +24,7 @@  \unprotect -\registerctxluafile{typo-inj}{} +\registerctxluafile{typo-inj}{autosuffix}  % todo: no need in trialmode diff --git a/tex/context/base/mkxl/typo-man.lmt b/tex/context/base/mkxl/typo-man.lmt new file mode 100644 index 000000000..051e888f1 --- /dev/null +++ b/tex/context/base/mkxl/typo-man.lmt @@ -0,0 +1,119 @@ +if not modules then modules = { } end modules ['typo-man'] = { +    version   = 1.001, +    comment   = "companion to typo-prc.mkiv", +    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +    copyright = "PRAGMA ADE / ConTeXt Development Team", +    license   = "see context related readme files" +} + +if not characters then +    -- for testing stand-alone +    require("char-def") +    require("char-ini") +end + +local lpegmatch  = lpeg.match +local P, R, C, Ct, Cs, Carg = lpeg.P, lpeg.R, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg +local global = global or _G + +local methods = { +    uppercase = characters.upper, +    lowercase = characters.lower, +    Word      = converters.Word, +    Words     = converters.Words, +} + +local function nothing(s) return s end -- we already have that one somewhere + +-- table.setmetatableindex(methods,function(t,k) +--     t[k] = nothing +--     return nothing +-- end) + +local splitter = lpeg.tsplitat(".") + +table.setmetatableindex(methods,function(t,k) +    local s = lpegmatch(splitter,k) +    local v = global +    for i=1,#s do +        v = v[s[i]] +        if not v then +            break +        end +    end +    if not v or v == global then +        v = nothing +    end +    t[k] = v +    return v +end) + +local whitespace = lpeg.patterns.whitespace^0 +local separator  = whitespace * P("->") * whitespace +local pair       = C((1-separator)^1) * separator * C(P(1)^0) +local list       = Ct((C((1-separator)^1) * separator)^1) * C(P(1)^0) + +local pattern = Carg(1) * pair / function(methods,operation,str) +    return methods[operation](str) or str +end + +local function apply(str,m) +    return lpegmatch(pattern,str,1,m or methods) or str +end + +local function splitspecification(field,m) +    local m, f = lpegmatch(list,field,1,m or methods) +    if m then +        return m, f or field +    else +        return nil, field +    end +end + +local function applyspecification(actions,str) +    if actions then +        for i=1,#actions do +            local action = methods[actions[i]] +            if action then +                str = action(str) or str +            end +        end +    end +    return str +end + +if not typesetters then typesetters = { } end + +typesetters.manipulators = { +    methods            = methods, +    apply              = apply, +    patterns           = { +        pair = pair, +        list = list, +    }, +    splitspecification = splitspecification, +    applyspecification = applyspecification, +} + +local pattern = Cs((1 - P(1) * P(-1))^0 * (P(".")/"" + P(1))) + +methods.stripperiod = function(str) return lpegmatch(pattern,str) end + +-- print(apply("hans")) +-- print(apply("uppercase->hans")) +-- print(apply("string.reverse -> hans")) +-- print(apply("uppercase->hans",{ uppercase = string.reverse } )) + +-- print(applyspecification(splitspecification("hans"))) +-- print(applyspecification(splitspecification("lowercase->uppercase->hans"))) +-- print(applyspecification(splitspecification("uppercase->stripperiod->hans."))) + +if commands then + +    local context = context + +    function commands.manipulated(str) +        context(apply(str)) +    end + +end diff --git a/tex/context/base/mkxl/typo-prc.lmt b/tex/context/base/mkxl/typo-prc.lmt new file mode 100644 index 000000000..72b159e9c --- /dev/null +++ b/tex/context/base/mkxl/typo-prc.lmt @@ -0,0 +1,129 @@ +if not modules then modules = { } end modules ['typo-prc'] = { +    version   = 1.001, +    comment   = "companion to typo-prc.mkiv", +    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +    copyright = "PRAGMA ADE / ConTeXt Development Team", +    license   = "see context related readme files" +} + +local lpegmatch, patterns, P, C, Cs = lpeg.match, lpeg.patterns, lpeg.P, lpeg.C, lpeg.Cs + +-- processors: syntax: processor->data ... not ok yet + +local context           = context +local implement         = interfaces.implement + +local formatters        = string.formatters + +typesetters.processors  = typesetters.processors or { } +local processors        = typesetters.processors + +local trace_processors  = false +local report_processors = logs.reporter("processors") +local registered        = { } + +local ctx_applyprocessor      = context.applyprocessor +local ctx_firstofoneargument  = context.firstofoneargument + +trackers.register("typesetters.processors", function(v) trace_processors = v end) + +function processors.register(p) +    registered[p] = true +end + +function processors.reset(p) +    registered[p] = nil +end + +--~ local splitter = lpeg.splitat("->",true) -- also support => + +local becomes    = P('->') +local processor  = (1-becomes)^1 +local splitter   = C(processor) * becomes * Cs(patterns.argument + patterns.content) + +function processors.split(str,nocheck) +    local p, s = lpegmatch(splitter,str) +    if p and (nocheck or registered[p]) then +        return p, s +    else +        return false, str +    end +end + +function processors.apply(p,s) +    local str = p +    if s == nil then +        p, s = lpegmatch(splitter,p) +    end +    if p and registered[p] then +        if trace_processors then +            report_processors("applying %s processor %a, argument: %s","known",p,s) +        end +        ctx_applyprocessor(p,s) +    elseif s then +        if trace_processors then +            report_processors("applying %s processor %a, argument: %s","unknown",p,s) +        end +        context(s) +    elseif str then +        if trace_processors then +            report_processors("applying %s processor, data: %s","ignored",str) +        end +        context(str) +    end +end + +function processors.startapply(p,s) +    local str = p +    if s == nil then +        p, s = lpegmatch(splitter,p) +    end +    if p and registered[p] then +        if trace_processors then +            report_processors("start applying %s processor %a","known",p) +        end +        ctx_applyprocessor(p) +        context("{") +        return s +    elseif p then +        if trace_processors then +            report_processors("start applying %s processor %a","unknown",p) +        end +        ctx_firstofoneargument() +        context("{") +        return s +    else +        if trace_processors then +            report_processors("start applying %s processor","ignored") +        end +        ctx_firstofoneargument() +        context("{") +        return str +    end +end + +function processors.stopapply() +    context("}") +    if trace_processors then +        report_processors("stop applying processor") +    end +end + +function processors.tostring(str) +    local p, s = lpegmatch(splitter,str) +    if registered[p] then +        return formatters["\\applyprocessor{%s}{%s}"](p,s) +    else +        return str +    end +end + +function processors.stripped(str) +    local p, s = lpegmatch(splitter,str) +    return s or str +end + +-- interface + +implement { name = "registerstructureprocessor", actions = processors.register, arguments = "string" } +implement { name = "resetstructureprocessor",    actions = processors.reset,    arguments = "string" } diff --git a/tex/context/base/mkxl/typo-prc.mklx b/tex/context/base/mkxl/typo-prc.mklx index 9531949b8..f2df32986 100644 --- a/tex/context/base/mkxl/typo-prc.mklx +++ b/tex/context/base/mkxl/typo-prc.mklx @@ -16,8 +16,8 @@  %D For the moment manipulators are loaded here too, as they're in the same category  %D as processors. This might change. (They are used in publications.) -\registerctxluafile{typo-prc}{} -\registerctxluafile{typo-man}{} +\registerctxluafile{typo-prc}{autosuffix} +\registerctxluafile{typo-man}{autosuffix}  \unprotect @@ -72,8 +72,7 @@     \fi}  \def\typo_processor_apply -  {\edef\p_state{\processorparameter\c!state}% -   \ifx\p_state\v!stop +  {\ifcstok{\processorparameter\c!state}\v!stop       \expandafter\firstofoneargument     \else       \expandafter\typo_processor_apply_indeed diff --git a/tex/context/base/mkxl/typo-rep.lmt b/tex/context/base/mkxl/typo-rep.lmt new file mode 100644 index 000000000..683b483ef --- /dev/null +++ b/tex/context/base/mkxl/typo-rep.lmt @@ -0,0 +1,135 @@ +if not modules then modules = { } end modules ['typo-rep'] = { +    version   = 1.001, +    comment   = "companion to node-ini.mkiv", +    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +    copyright = "PRAGMA ADE / ConTeXt Development Team", +    license   = "see context related readme files" +} + +-- This was rather boring to program (more of the same) but I could +-- endure it by listening to a couple cd's by The Scene and The Lau +-- on the squeezebox on my desk. + +local next, type, tonumber = next, type, tonumber + +local trace_stripping = false  trackers.register("nodes.stripping",  function(v) trace_stripping = v end) +                               trackers.register("fonts.stripping",  function(v) trace_stripping = v end) + +local report_stripping = logs.reporter("fonts","stripping") + +local nodes           = nodes +local enableaction    = nodes.tasks.enableaction + +local nuts            = nodes.nuts + +local getnext         = nuts.getnext +local getchar         = nuts.getchar +local isglyph         = nuts.isglyph + +local getattr         = nuts.getattr + +local remove_node     = nuts.remove +local replace_node    = nuts.replace +local copy_node       = nuts.copy + +local nodecodes       = nodes.nodecodes + +local chardata        = characters.data +local collected       = false + +local a_stripping     = attributes.private("stripping") + +local texsetattribute = tex.setattribute +local unsetvalue      = attributes.unsetvalue + +local v_reset         = interfaces.variables.reset + +-- todo: other namespace -> typesetters + +nodes.stripping  = nodes.stripping  or { } local stripping  = nodes.stripping +stripping.glyphs = stripping.glyphs or { } local glyphs     = stripping.glyphs + +local function initialize() +    for k, v in next, chardata do +        if v.category == "cf" and not v.visible and not glyphs[k] then +            glyphs[k] = true +        end +    end +    initialize = nil +end + +local function process(what,head,current,char) +    if what == true then +        if trace_stripping then +            report_stripping("deleting %C from text",char) +        end +        head, current = remove_node(head,current,true) +    elseif type(what) == "function" then +        head, current = what(head,current) +        current = getnext(current) +        if trace_stripping then +            report_stripping("processing %C in text",char) +        end +    elseif what then  -- assume node +        head, current = replace_node(head,current,copy_node(what)) +        current = getnext(current) +        if trace_stripping then +            report_stripping("replacing %C in text",char) +        end +    end +    return head, current +end + +function nodes.handlers.stripping(head) -- use loop +    local current = head +    while current do +        local char, id = isglyph(current) +        if char then +            -- it's more efficient to keep track of what needs to be kept +            local todo = getattr(current,a_stripping) +            if todo == 1 then +                local what = glyphs[char] +                if what then +                    head, current = process(what,head,current,char) +                else -- handling of spacing etc has to be done elsewhere +                    current = getnext(current) +                end +            else +                current = getnext(current) +            end +        else +            current = getnext(current) +        end +    end +    return head +end + +local enabled = false + +function stripping.set(n) -- number or 'reset' +    if n == v_reset then +        n = unsetvalue +    else +        n = tonumber(n) +        if n then +            if not enabled then +                if initialize then initialize() end +                enableaction("processors","nodes.handlers.stripping") +                enabled = true +            end +        else +            n = unsetvalue +        end +    end +    texsetattribute(a_stripping,n) +end + +-- interface + +interfaces.implement { +    name      = "setcharacterstripping", +    public    = true, +    protected = true, +    actions   = stripping.set, +    arguments = "optional" +} diff --git a/tex/context/base/mkxl/typo-rep.mkxl b/tex/context/base/mkxl/typo-rep.mkxl index 6e0a9a22c..aa70c5564 100644 --- a/tex/context/base/mkxl/typo-rep.mkxl +++ b/tex/context/base/mkxl/typo-rep.mkxl @@ -24,12 +24,12 @@  \unprotect -\registerctxluafile{typo-rep}{} +\registerctxluafile{typo-rep}{autosuffix}  \definesystemattribute[stripping][public] -\permanent\protected\def\setcharacterstripping[#1]% -  {\clf_setcharacterstripping{#1}} +% \permanent\protected\def\setcharacterstripping[#1]% defined at the lua end +%   {\clf_setcharacterstripping{#1}}  \permanent\protected\def\resetcharacterstripping    {\c_attr_stripping\attributeunsetvalue} diff --git a/tex/context/base/mkxl/typo-spa.lmt b/tex/context/base/mkxl/typo-spa.lmt index 88ade876e..f06ac7913 100644 --- a/tex/context/base/mkxl/typo-spa.lmt +++ b/tex/context/base/mkxl/typo-spa.lmt @@ -15,6 +15,7 @@ local report_spacing = logs.reporter("typesetting","spacing")  local nodes, fonts, node = nodes, fonts, node  local fonthashes         = fonts.hashes +local chardata           = fonthashes.characters  local quaddata           = fonthashes.quads  local texsetattribute    = tex.setattribute @@ -92,6 +93,9 @@ function spacings.handler(head)                              local alternative = map.alternative                              local quad = quaddata[font]                              local prev = getprev(start) +                            if not chardata[font][char] then +                                report_spacing("missing character %C in font %i",char,font) +                            end                              if left and left ~= 0 and prev then                                  local ok = false                                  local prevprev = getprev(prev) diff --git a/tex/context/fonts/mkiv/kpfonts-math.lfg b/tex/context/fonts/mkiv/kpfonts-math.lfg index 409b17cbc..67ad3841f 100644 --- a/tex/context/fonts/mkiv/kpfonts-math.lfg +++ b/tex/context/fonts/mkiv/kpfonts-math.lfg @@ -134,7 +134,17 @@ return {                      tweak = "setoptions",                      set   = { "ignorekerndimensions" }                  }, -            }, +-- { +--     tweak = "inspect", +--     unicode = 0x2192 +-- }, +-- { +--     tweak = "inspect", +--     unicode = 0x20EF +-- }, +-- { +            } +          },          alternates = {           -- italic = { feature = 'ss01', value = 1, comment = "Mathematical Alternative Lowercase Italic" }, diff --git a/tex/context/interface/mkii/keys-de.xml b/tex/context/interface/mkii/keys-de.xml index ccfa88439..13762dd50 100644 --- a/tex/context/interface/mkii/keys-de.xml +++ b/tex/context/interface/mkii/keys-de.xml @@ -453,6 +453,7 @@  		<cd:variable name='printable' value='druckbar'/>  		<cd:variable name='process' value='process'/>  		<cd:variable name='product' value='produkt'/> +		<cd:variable name='profile' value='profile'/>  		<cd:variable name='program' value='programm'/>  		<cd:variable name='project' value='projekt'/>  		<cd:variable name='protected' value='geschuetzt'/> @@ -594,6 +595,7 @@  		<cd:variable name='temporary' value='temporaer'/>  		<cd:variable name='test' value='test'/>  		<cd:variable name='text' value='text'/> +		<cd:variable name='textdisplay' value='textdisplay'/>  		<cd:variable name='textnote' value='textnote'/>  		<cd:variable name='three' value='drei'/>  		<cd:variable name='thursday' value='donnerstag'/> @@ -724,6 +726,7 @@  		<cd:constant name='bookmark' value='bookmark'/>  		<cd:constant name='bottom' value='unten'/>  		<cd:constant name='bottomafter' value='bottomafter'/> +		<cd:constant name='bottomalign' value='bottomalign'/>  		<cd:constant name='bottombefore' value='bottombefore'/>  		<cd:constant name='bottomcolor' value='bottomcolor'/>  		<cd:constant name='bottomcommand' value='bottomcommand'/> @@ -835,6 +838,7 @@  		<cd:constant name='exitoffset' value='exitoffset'/>  		<cd:constant name='expansion' value='expansion'/>  		<cd:constant name='export' value='export'/> +		<cd:constant name='extradata' value='extradata'/>  		<cd:constant name='extras' value='extras'/>  		<cd:constant name='factor' value='faktor'/>  		<cd:constant name='fallback' value='fallback'/> @@ -958,6 +962,7 @@  		<cd:constant name='lastpage' value='letzteseite'/>  		<cd:constant name='lastpagesep' value='lastpagesep'/>  		<cd:constant name='lastpubsep' value='lastpubsep'/> +		<cd:constant name='lasttextseparator' value='lasttextseparator'/>  		<cd:constant name='layout' value='layout'/>  		<cd:constant name='left' value='links'/>  		<cd:constant name='leftclass' value='leftclass'/> @@ -1338,6 +1343,7 @@  		<cd:constant name='toffset' value='toffset'/>  		<cd:constant name='tolerance' value='toleranz'/>  		<cd:constant name='top' value='oben'/> +		<cd:constant name='topalign' value='topalign'/>  		<cd:constant name='topcolor' value='topcolor'/>  		<cd:constant name='topcommand' value='topcommand'/>  		<cd:constant name='topdistance' value='obenabstand'/> diff --git a/tex/context/modules/mkxl/m-tikz.mkxl b/tex/context/modules/mkxl/m-tikz.mkxl index 3d6c649d6..21544d14e 100644 --- a/tex/context/modules/mkxl/m-tikz.mkxl +++ b/tex/context/modules/mkxl/m-tikz.mkxl @@ -67,6 +67,12 @@  \overloadmode\zerocount +\newtoks\everytikzpicture + +% \appendtoks +%     \resetcharacterspacing +% \to \everytikzpicture +  \permanent\protected\def\starttikzsettings    {\pushoverloadmode     \pushmacro\meaning @@ -81,6 +87,7 @@  \permanent\protected\def\starttikzpicture    {\dontleavehmode     \hcontainer\bgroup +   \the\everytikzpicture     \autoparagraphmode\zerocount     \pushmacro\meaning     \let\meaning\meaningless diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index b7a72ccc0..614793314 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@  -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua  -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date  : 2023-03-06 23:15 +-- merge date  : 2023-03-10 12:15  do -- begin closure to overcome local limits and interference diff --git a/web2c/contextcnf.lua b/web2c/contextcnf.lua index 6bb6acf44..5ad9ea6d8 100644 --- a/web2c/contextcnf.lua +++ b/web2c/contextcnf.lua @@ -1,13 +1,16 @@ --- winmerge e:\tex-context\tex\texmf-mine\web2c\contextcnf.lua e:\tex-context\tex\texmf-context\web2c\contextcnf.lua e:\tex-context\tex\texmf\web2c\texmfcnf.lua +-- todo: come up with an auto-texlive identification (texmf-dist) + +---- hiddentexlivepath = ".texlive2023"  return {      type    = "configuration", -    version = "1.1.2",      -- "1.1.1", -    date    = "2021-05-12", -- "2011-06-02" +    version = "1.1.3", +    date    = "2023-03-10", -- 2021-05-12 2011-06-02      time    = "14:59:00",      comment = "ConTeXt MkIV and LMTX configuration file",      author  = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +    target  = "standalone",      content = { @@ -41,7 +44,16 @@ return {              -- We have only one cache path but there can be more. The first writable one will be taken              -- but there can be more readable paths. +            -- standalone: +                          TEXMFCACHE      = "$SELFAUTOPARENT/texmf-cache", +             +            -- texlive + +         -- TEXMFVAR        = "home:" .. hiddentexlivepath .. "/texmf-var", +         -- TEXMFCONFIG     = "home:" .. hiddentexlivepath .. "/texmf-config", +         -- TEXMFSYSVAR     = "selfautoparent:texmf-var", +         -- TEXMFCACHE      = "$TEXMFSYSVAR;$TEXMFVAR",              -- I don't like this texmf under home and texmf-home would make more sense. One never knows              -- what installers put under texmf anywhere and sorting out problems will be a pain. But on @@ -51,10 +63,21 @@ return {              -- tex root relocatable.              TEXMFOS         = "selfautodir:", +             +            -- standalone:  +                          TEXMFSYSTEM     = "selfautoparent:texmf-$SELFAUTOSYSTEM",              TEXMFMAIN       = "selfautoparent:texmf",              TEXMFCONTEXT    = "selfautoparent:texmf-context",              TEXMFMODULES    = "selfautoparent:texmf-modules", +             +            -- texlive: +                         +         -- TEXMFDIST       = "selfautoparent:texmf-dist", +         -- TEXMFSYSCONFIG  = "selfautoparent:texmf-config", +             +            -- The texmf-local path is only used for (maybe) some additional configuration file. +                          TEXMFLOCAL      = "selfautoparent:texmf-local",              TEXMFFONTS      = "selfautoparent:texmf-fonts",              TEXMFPROJECT    = "selfautoparent:texmf-project", @@ -65,7 +88,13 @@ return {              -- We need texmfos for a few rare files but as I have a few more bin trees a hack is needed.              -- Maybe other users also have texmf-platform-new trees, but so far I've never heard of it. +            -- standalone: +              TEXMF           = "{$TEXMFHOME,!!$TEXMFPROJECT,!!$TEXMFFONTS,!!$TEXMFLOCAL,!!$TEXMFMODULES,!!$TEXMFCONTEXT,!!$TEXMFSYSTEM,!!$TEXMFMAIN}", +             +            -- texlive: +             +         -- TEXMF           = "{$TEXMFCONFIG,$TEXMFHOME,!!$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFPROJECT,!!$TEXMFFONTS,!!$TEXMFLOCAL,!!$TEXMFDIST}",              TEXFONTMAPS     = ".;$TEXMF/fonts/data//;$TEXMF/fonts/map/{pdftex,dvips}//",              ENCFONTS        = ".;$TEXMF/fonts/data//;$TEXMF/fonts/enc/{dvips,pdftex}//", @@ -105,7 +134,14 @@ return {              -- A few special ones that will change some day.              FONTCONFIG_FILE = "fonts.conf", + +            -- standalone +                          FONTCONFIG_PATH = "$TEXMFSYSTEM/fonts/conf", +             +            --texlive  + +         -- FONTCONFIG_PATH = "$TEXMFSYSVAR/fonts/conf",          }, diff --git a/web2c/texlivecnf.lua b/web2c/texlivecnf.lua new file mode 100644 index 000000000..e14d5cbfc --- /dev/null +++ b/web2c/texlivecnf.lua @@ -0,0 +1,279 @@ +-- todo: come up with an auto-texlive identification (texmf-dist) + +local hiddentexlivepath = ".texlive2023" + +return { + +    type    = "configuration", +    version = "1.1.3", +    date    = "2023-03-10", -- 2021-05-12 2011-06-02 +    time    = "14:59:00", +    comment = "ConTeXt MkIV and LMTX configuration file", +    author  = "Hans Hagen, PRAGMA-ADE, Hasselt NL", +    target  = "texlive", + +    content = { + +        -- Originally there was support for engines and progname but I don't expect other engines to +        -- use this file, so first engines were removed. After that if made sense also to get rid of +        -- progname. In principle we could support multiple formats here (using subtables) but time +        -- has demonstrated that we only have one format (the original ideas was to make a base layer +        -- but I don't see it being used to it would be  waste of time). So, after a decade it was +        -- time to prune and update this file, also because LMTX has a few more features. + +        variables = { + +            -- The following variable is predefined (but can be overloaded) and in most cases you can +            -- leave this one untouched. The built-in definition permits relocation of the tree. +            -- +            --  if this_is_texlive then +            --      resolvers.luacnfspec = 'selfautodir:;selfautoparent:;{selfautodir:,selfautoparent:}{/share,}/texmf{-local,}/web2c' +            --  else +            --      resolvers.luacnfspec = 'home:texmf/web2c;selfautoparent:texmf{-local,-context,}/web2c' +            --  end +            -- +            -- more readable is: +            -- +            -- TEXMFCNF     = { +            --     "home:texmf/web2c, +            --     "selfautoparent:texmf-local/web2c", +            --     "selfautoparent:texmf-context/web2c", +            --     "selfautoparent:texmf/web2c", +            -- } + +            -- We have only one cache path but there can be more. The first writable one will be taken +            -- but there can be more readable paths. + +            -- standalone: + +         -- TEXMFCACHE      = "$SELFAUTOPARENT/texmf-cache", + +            -- texlive + +            TEXMFVAR        = "home:" .. hiddentexlivepath .. "/texmf-var", +            TEXMFCONFIG     = "home:" .. hiddentexlivepath .. "/texmf-config", +            TEXMFSYSVAR     = "selfautoparent:texmf-var", +            TEXMFCACHE      = "$TEXMFSYSVAR;$TEXMFVAR", + +            -- I don't like this texmf under home and texmf-home would make more sense. One never knows +            -- what installers put under texmf anywhere and sorting out problems will be a pain. But on +            -- the other hand ... home mess is normally the users own responsibility. +            -- +            -- By using prefixes we don't get expanded paths in the cache __path__ entry. This makes the +            -- tex root relocatable. + +            TEXMFOS         = "selfautodir:", + +            -- standalone: + +         -- TEXMFSYSTEM     = "selfautoparent:texmf-$SELFAUTOSYSTEM", +         -- TEXMFMAIN       = "selfautoparent:texmf", +         -- TEXMFCONTEXT    = "selfautoparent:texmf-context", +         -- TEXMFMODULES    = "selfautoparent:texmf-modules", + +            -- texlive: + +            TEXMFDIST       = "selfautoparent:texmf-dist", +            TEXMFSYSCONFIG  = "selfautoparent:texmf-config", + +            -- The texmf-local path is only used for (maybe) some additional configuration file. + +            TEXMFLOCAL      = "selfautoparent:texmf-local", +            TEXMFFONTS      = "selfautoparent:texmf-fonts", +            TEXMFPROJECT    = "selfautoparent:texmf-project", + +            TEXMFHOME       = "home:texmf", +         -- TEXMFHOME       = os.name == "macosx" and "home:Library/texmf" or "home:texmf", + +            -- We need texmfos for a few rare files but as I have a few more bin trees a hack is needed. +            -- Maybe other users also have texmf-platform-new trees, but so far I've never heard of it. + +            -- standalone: + +         -- TEXMF           = "{$TEXMFHOME,!!$TEXMFPROJECT,!!$TEXMFFONTS,!!$TEXMFLOCAL,!!$TEXMFMODULES,!!$TEXMFCONTEXT,!!$TEXMFSYSTEM,!!$TEXMFMAIN}", + +            -- texlive: + +            TEXMF           = "{$TEXMFCONFIG,$TEXMFHOME,!!$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFPROJECT,!!$TEXMFFONTS,!!$TEXMFLOCAL,!!$TEXMFDIST}", + +            TEXFONTMAPS     = ".;$TEXMF/fonts/data//;$TEXMF/fonts/map/{pdftex,dvips}//", +            ENCFONTS        = ".;$TEXMF/fonts/data//;$TEXMF/fonts/enc/{dvips,pdftex}//", +            VFFONTS         = ".;$TEXMF/fonts/{data,vf}//", +            TFMFONTS        = ".;$TEXMF/fonts/{data,tfm}//", +            PKFONTS         = ".;$TEXMF/fonts/{data,pk}//", +            T1FONTS         = ".;$TEXMF/fonts/{data,type1}//;$OSFONTDIR", +            AFMFONTS        = ".;$TEXMF/fonts/{data,afm}//;$OSFONTDIR", +            TTFONTS         = ".;$TEXMF/fonts/{data,truetype}//;$OSFONTDIR", +            OPENTYPEFONTS   = ".;$TEXMF/fonts/{data,opentype}//;$OSFONTDIR", +            FONTFEATURES    = ".;$TEXMF/fonts/{data,fea}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS", +            FONTCIDMAPS     = ".;$TEXMF/fonts/{data,cid}//", +            OFMFONTS        = ".;$TEXMF/fonts/{data,ofm,tfm}//", +            OVFFONTS        = ".;$TEXMF/fonts/{data,ovf,vf}//", + +            TEXINPUTS       = ".;$TEXMF/tex/{context,plain/base,generic}//", +            MPINPUTS        = ".;$TEXMF/metapost/{context,base,}//", + +            -- In the next variable the inputs path will go away. + +            TEXMFSCRIPTS    = ".;$TEXMF/scripts/context/{lua,ruby,python,perl}//;$TEXINPUTS", +            PERLINPUTS      = ".;$TEXMF/scripts/context/perl", +            PYTHONINPUTS    = ".;$TEXMF/scripts/context/python", +            RUBYINPUTS      = ".;$TEXMF/scripts/context/ruby", +            LUAINPUTS       = ".;$TEXINPUTS;$TEXMF/scripts/context/lua//", +            CLUAINPUTS      = ".;$SELFAUTOLOC/lib/$engine//", + +            -- Not really used by MkIV so they might go away. + +            BIBINPUTS       = ".;$TEXMF/bibtex/bib//;$TEXMF/tex/context//", +            BSTINPUTS       = ".;$TEXMF/bibtex/bst//;$TEXMF/tex/context//", + +            -- Experimental + +            ICCPROFILES     = ".;$TEXMF/colors/icc/{context,profiles}//;$OSCOLORDIR", + +            -- A few special ones that will change some day. + +            FONTCONFIG_FILE = "fonts.conf", + +            -- standalone +             +         -- FONTCONFIG_PATH = "$TEXMFSYSTEM/fonts/conf", +             +            --texlive  + +            FONTCONFIG_PATH = "$TEXMFSYSVAR/fonts/conf", + +        }, + +        -- We have a few reserved subtables. These control runtime behaviour. Some are frozen at +        -- at startup time, others can be changed any time. + +        directives = { + +            -- The default settings are actually set at startup so the values below overload +            -- them. You can also specify a plus field which will bump a value and in LMTX a +            -- step field that sets the incremental allocation of memory (because there we don't +            -- allocate all at once). + +            -- texconfig.max_print_line  =   100000 +            -- texconfig.function_size   =    32768 +            -- texconfig.properties_size =    10000 + +            -- These are for luametatex: + +            ["luametatex.errorlinesize"]     = { size =      250                 }, -- max =       255 +            ["luametatex.halferrorlinesize"] = { size =      250                 }, -- max =       255 +            ["luametatex.expandsize"]        = { size =    10000                 }, -- max =   1000000 +            ["luametatex.stringsize"]        = { size =   500000, step =  100000 }, -- max =   2097151 -- number of strings +            ["luametatex.poolsize"]          = { size = 10000000, step = 1000000 }, -- max = 100000000 -- chars in string +            ["luametatex.hashsize"]          = { size =   250000, step =  100000 }, -- max =   2097151 +            ["luametatex.nodesize"]          = { size = 50000000, step =  500000 }, -- max =  50000000 +            ["luametatex.tokensize"]         = { size = 10000000, step =  250000 }, -- max =  10000000 +            ["luametatex.buffersize"]        = { size = 10000000, step = 1000000 }, -- max = 100000000 +            ["luametatex.inputsize"]         = { size =   100000, step =   10000 }, -- max =    100000 -- aka stack +            ["luametatex.filesize"]          = { size =     2000, step =     200 }, -- max =      2000 +            ["luametatex.nestsize"]          = { size =    10000, step =    1000 }, -- max =     10000 +            ["luametatex.parametersize"]     = { size =   100000, step =   10000 }, -- max =    100000 +            ["luametatex.savesize"]          = { size =   500000, step =   10000 }, -- max =    500000 +            ["luametatex.fontsize"]          = { size =   100000, step =     250 }, -- max =    100000 +            ["luametatex.languagesize"]      = { size =      250, step =     250 }, -- max =     10000 +            ["luametatex.marksize"]          = { size =      250, step =      50 }, -- max =     10000 +            ["luametatex.insertsize"]        = { size =      250, step =      25 }, -- max =       250 + +            -- These are for luatex: + +            ["luatex.errorline"]         =    250, +            ["luatex.halferrorline"]     =    125, +            ["luatex.expanddepth"]       =  10000, +            ["luatex.hashextra"]         = 100000, +            ["luatex.nestsize"]          =   1000, +            ["luatex.maxinopen"]         =    500, +            ["luatex.maxprintline"]      =  10000, +            ["luatex.maxstrings"]        = 500000, +            ["luatex.paramsize"]         =  25000, +            ["luatex.savesize"]          = 100000, +            ["luatex.stacksize"]         = 100000, + +            -- A few process related variables come next. + +         -- ["system.checkglobals"]      = "10", +         -- ["system.nostatistics"]      = "yes", +            ["system.errorcontext"]      = "10", +            ["system.compile.cleanup"]   = "no",    -- remove tma files +            ["system.compile.strip"]     = "yes",   -- strip tmc files + +            -- The io modes are similar to the traditional ones. Possible values are all, paranoid +            -- and restricted. + +            ["system.outputmode"]        = "restricted", +            ["system.inputmode"]         = "any", + +            -- The following variable is under consideration. We do have protection mechanims but +            -- it's not enabled by default. + +            ["system.commandmode"]       = "any", -- any none list +            ["system.commandlist"]       = "mtxrun, convert, inkscape, gs, imagemagick, curl, bibtex, pstoedit", + +            -- The mplib library support mechanisms have their own configuration. Normally these +            -- variables can be left as they are. + +            ["mplib.texerrors"]          = "yes", + +            -- Normally you can leave the font related directives untouched as they only make sense +            -- when testing. + +         -- ["fonts.autoreload"]         = "no", +         -- ["fonts.otf.loader.cleanup"] = "0",     -- 0 1 2 3 + +            -- In an edit cycle it can be handy to launch an editor. The +            -- preferred one can be set here. + +         -- ["pdfview.method"]           = "sumatra", + +         -- ["system.engine"]            = "luajittex", +         -- ["fonts.usesystemfonts"]     = false, +         -- ["modules.permitunprefixed"] = false, +         -- ["resolvers.otherwise"]      = false, + +         -- Sandboxing has been available for a while but is probably never used to maybe that mechanism +         -- should be removed some day. Normally you will configure this in a local configuration file. By +         -- default we are rather permissive. The next list comes from my machine: + +         -- ["system.rootlist"]      = { "/data" }, -- { { "/data", "read" }, ... } + +      --    ["system.executionmode"] = "list", -- none | list | all +      --    ["system.executionlist"] = { +      --        "context", +      --        "bibtex", "mlbibcontext", +      --        "curl", +      --        "gswin64c", "gswin32c", "gs", +      --        "gm", "graphicmagick", +      --        "pdftops", +      --        "pstoedit", +      --        "inkscape", +      --        "woff2_decompress", +      --        "hb-shape", +      --    }, +      -- +      --    ["system.librarymode"]   = "list", -- none | list | all +      --    ["system.librarylist"]   = { +      --        "mysql", +      --        "sqlite3", +      --        "libharfbuzz", "libharfbuzz-0", +      --    }, +      -- -- ["system.librarynames"]  = { +      -- --     ["libcurl"] = { "libcurl", "libcurl-4" }, +      -- -- }, + +        }, + +        experiments = { +            ["fonts.autorscale"] = "yes", +        }, + +        trackers = { +        }, + +    }, + +} | 
