summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2018-03-10 19:29:49 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2018-03-10 19:29:49 +0100
commitf923c957a3b322ae3ee8e7a0b20df1580869bee7 (patch)
tree988b46f68add1068e6110a9b9223d0106a888e00
parent62185974cd9c16ad11788dbeebb30f466a2fb38c (diff)
downloadcontext-f923c957a3b322ae3ee8e7a0b20df1580869bee7.tar.gz
2018-03-10 15:02:00
-rw-r--r--doc/context/documents/general/manuals/nodes.pdfbin315323 -> 349282 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-cs.pdfbin844208 -> 844221 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-de.pdfbin844068 -> 844075 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-en.pdfbin848098 -> 848116 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-fr.pdfbin839769 -> 839780 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-it.pdfbin845612 -> 845621 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-cs.pdfbin358993 -> 358994 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-de.pdfbin438372 -> 438379 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-en.pdfbin356098 -> 356101 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-fr.pdfbin359081 -> 359078 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-it.pdfbin357919 -> 357924 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-nl.pdfbin357375 -> 357383 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-ro.pdfbin624169 -> 624173 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-nl.pdfbin836733 -> 836725 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-ro.pdfbin839704 -> 839721 bytes
-rw-r--r--doc/context/sources/general/manuals/nodes/nodes.tex1151
-rw-r--r--metapost/context/base/mpiv/mp-node.mpiv4
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkii/mult-ro.mkii1
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/grph-epd.lua4
-rw-r--r--tex/context/base/mkiv/grph-inc.lua9
-rw-r--r--tex/context/base/mkiv/lpdf-epa.lua84
-rw-r--r--tex/context/base/mkiv/spac-ver.lua1592
-rw-r--r--tex/context/base/mkiv/spac-ver.mkiv16
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin25855 -> 25856 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin253055 -> 252176 bytes
-rw-r--r--tex/context/base/mkiv/util-sql-loggers.lua1
-rw-r--r--tex/context/base/mkiv/util-sql-logins.lua136
-rw-r--r--tex/context/base/mkiv/util-sql-tickets.lua5
-rw-r--r--tex/context/interface/mkii/keys-ro.xml1
-rw-r--r--tex/context/interface/mkiv/context-en.xml1
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin848098 -> 848116 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60776 -> 60774 bytes
-rw-r--r--tex/context/interface/mkiv/i-vspace.xml3
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2
38 files changed, 1741 insertions, 1277 deletions
diff --git a/doc/context/documents/general/manuals/nodes.pdf b/doc/context/documents/general/manuals/nodes.pdf
index 343341b7a..8f0ec1b73 100644
--- a/doc/context/documents/general/manuals/nodes.pdf
+++ b/doc/context/documents/general/manuals/nodes.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf
index a16ac7c7f..de2869863 100644
--- a/doc/context/documents/general/qrcs/setup-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-de.pdf b/doc/context/documents/general/qrcs/setup-de.pdf
index e73757bcb..9d9163c15 100644
--- a/doc/context/documents/general/qrcs/setup-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-en.pdf b/doc/context/documents/general/qrcs/setup-en.pdf
index ac301f450..c53f0ae43 100644
--- a/doc/context/documents/general/qrcs/setup-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-fr.pdf b/doc/context/documents/general/qrcs/setup-fr.pdf
index 49aab661d..f6ff554ee 100644
--- a/doc/context/documents/general/qrcs/setup-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-it.pdf b/doc/context/documents/general/qrcs/setup-it.pdf
index 644d59f13..3c3616572 100644
--- a/doc/context/documents/general/qrcs/setup-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
index 846c88051..aa1ca8bfa 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-de.pdf b/doc/context/documents/general/qrcs/setup-mapping-de.pdf
index c22f14ecb..63f97a235 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-en.pdf b/doc/context/documents/general/qrcs/setup-mapping-en.pdf
index fd92bf8cb..a7cc85e52 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
index ae14bc0aa..42207c1f7 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-it.pdf b/doc/context/documents/general/qrcs/setup-mapping-it.pdf
index ff7fb5ba1..3225e3b6f 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
index 1e275416d..385ded7ae 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
index 3db6a6009..5398ef863 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf
index b7cb3b39e..43d452f7e 100644
--- a/doc/context/documents/general/qrcs/setup-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-ro.pdf b/doc/context/documents/general/qrcs/setup-ro.pdf
index 5e0a18b0a..3a9bd0822 100644
--- a/doc/context/documents/general/qrcs/setup-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-ro.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/nodes/nodes.tex b/doc/context/sources/general/manuals/nodes/nodes.tex
index 6875e043d..e9857f37e 100644
--- a/doc/context/sources/general/manuals/nodes/nodes.tex
+++ b/doc/context/sources/general/manuals/nodes/nodes.tex
@@ -20,7 +20,22 @@
% comment : This manual orginates in an article by Alan so anything wrong in here is Hans
% fault as he converted it.
%
-% comment : The conver images are from the NASA website.
+% comment : It is also being published as an article in TugBoat.
+%
+% comment : The cover images are from the NASA website.
+
+
+% Alan : There is no need for % before \startfootnote .. the less such crap the better
+% (as it might give disappearing content if one wraps).
+%
+% Alan : ḻṯ What is this? An editor glitch?
+%
+% Alan : $≠$ -> just use ≠ (also, soon the gyre fonts will have more symbols in text
+% that match text.
+%
+% Alan : You can use \typ {x = 0} for something that breaks accross lines.
+
+%\enabletrackers[metapost.showlog]
\definemeasure [layout:margin] [\paperheight/20]
@@ -71,6 +86,13 @@
\setupalign
[verytolerant,stretch]
+% \definesymbol [1] [$\cdot$]
+
+% Dot rather than bullet ... Alan hates bullets! Hans hates too small dots.
+
+\setupitemize
+ [symbol=2] % dash rather than bullet, I hate bullets!
+
\setupnote
[footnote]
[next={ },
@@ -96,7 +118,7 @@
\kindofpagetextareas\plusone % partial page. HH: low level, no high level switch (yet)
\definetextbackground
- [fiction]
+ [aside]
[location=paragraph,
frame=off,
leftoffset=1ex,
@@ -106,6 +128,13 @@
background=color,
backgroundcolor=lightgray]
+\definedescription
+ [description]
+ [location=hanging,
+ width=broad,
+ before={\blank},
+ after={\blank}]
+
\defineparagraphs
[two]
[n=2,
@@ -113,7 +142,7 @@
background=color,
backgroundcolor=gray]
-\setupframed
+\defineframed
[node]
[offset=1pt,
foregroundstyle=\tfa]
@@ -166,6 +195,16 @@
publisher = {American Physical Society},
XXurl = {http://link.aps.org/doi/10.1103/PhysRev.55.434}
}
+
+ @BOOK{Lawvere2009,
+ author = {Lawvere, F. William and Schanuel, Stephen H.},
+ title = {Conceptual Mathematics}
+ subtitle = {A first introduction to categories},
+ edition = {2\high{nd}},
+ publisher = {Cambridge University Press},
+ address = {Cambridge, UK},
+ year = {2009}
+ }
\stopbuffer
\usebtxdefinitions [apa]
@@ -173,27 +212,44 @@
\usebtxdataset [bib.buffer]
+% Say, MP math arrows rather than font arrows:
+
+\useMPlibrary[mat]
+
+\definemathstackers
+ [mp]
+ [alternative=mp]
+
+\definemathextensible [mp] [leftarrow] ["2190]
+\definemathextensible [mp] [rightarrow] ["2192]
+\definemathextensible [mp] [leftrightarrow] ["2194]
+\definemathextensible [mp] [longleftrightarrow] ["27F7]
+\definemathextensible [mp] [rightoverleftarrow] ["21C4]
+
+\startMPinitializations
+ ahlength := EmWidth ;
+ ahangle := 30 ;
+ ahvariant := 1 ; % dimpled curved
+ ahdimple := 4/5 ;
+
+ node_loopback_yscale := .7 ;
+\stopMPinitializations
+
+% Only here do we use the special nodes:: instance
+
\defineframed
[mynode]
[node]
[offset=1pt,
foregroundcolor=white]
-\startMPdefinitions
- ahlength := 12pt ;
- ahangle := 30 ;
- ahvariant := 1 ; % dimpled
-\stopMPdefinitions
-
-% Only here do we use the special nodes:: instance
-
\startreusableMPgraphic{nodes::krebs}
% The Bethe cycle for energy production in stars (1939), following
% Krebs (1946)
save p ; path p[] ;
- p1 := (for i=0 step 60 until 300: dir(90-i) .. endfor cycle) scaled 2.75cm ;
+ p1 := (for i=0 step 60 until 300: dir(90-i).. endfor cycle) scaled 2.75cm ;
p0 := p1 scaled .5 ;
p2 := p1 scaled 1.5 ;
@@ -272,6 +328,8 @@
\startsetups document:start
+ % We each have our preferred cover... ;-)
+
\doifmodeelse {atpragma} {
\startMPpage[imagename=nodes-sun-pia-03150]
\includeMPgraphic{CoverPage}
@@ -281,8 +339,15 @@
\includeMPgraphic{CoverPage}
\stopMPpage
}
+
\stopsetups
+\startsetups document:stop
+
+\stopsetups
+
+% And now, the document!
+
\startdocument
[title=Nodes,
author=Alan Braslau,
@@ -291,40 +356,86 @@
\startsubject [title=Introduction]
-The graphical representation of textual diagrams is an extremely useful tool in
-the communication of idea. These are composed of graphical objects and blocks of
-text or the combination of both, i.e. a decorated label or text block, in some
-spatial relation to one another. \footnote {The spatial relation may be a
-representation of a temporal relationship.} A simple example is shown \in {in
-figure} [fig:AB].
-
-\startplacefigure [reference=fig:AB]
- \startMPcode
- u := 1cm ;
- save nodepath ; path nodepath ;
- nodepath := (left -- right) scaled u ;
-
- draw node(0,"\node{A}") ;
- draw node(1,"\node{B}") ;
- drawarrow fromto(0,0,1) ;
- \stopMPcode
-\stopplacefigure
-
-One often speaks of placing text with their accompanying decorations on \emph
-{nodes}, points of intersection or branching or else points on a regular lattice.
-The nodes of the above diagram are the two endpoints of a straight segment.
+The graphical representation of textual diagrams is a very useful tool in the
+communication of ideas. In category and topos theory, for example, many key
+concepts, formulas, and theorems are expressed by means of \emph {commutative
+diagrams}; these involve objects and arrows between them. Certain concepts
+discovered by category theory, such as \emph {natural transformations}, are
+becoming useful in areas outside of mathematics and natural science, e.g., in
+philosophy. To make category and topos methods usable by both specialists and
+non|-|specialists, commutative diagrams are an indispensable tool.
+\startfootnote
+ For many examples of formal and informal commutative diagrams, see \cite
+ [authoryears] [Lawvere2009].
+\stopfootnote
+The use of nodal diagrams is not limited to category theory, for they may
+represent a flow diagram (of a process, for example), a chemical reaction
+sequence or pathways, or that of phases and phase transitions, a hierarchical
+structure (of anything), a timeline or sequence of events or dependencies, a tree
+of descendance or ascendance, etc.
+
+The basic units of a node|-|based diagram include \emph {node objects}, each
+attached to some point (= the \emph {node}) in some spatial relationship. Note
+that to a single node might be associated a set of objects. Given a node, it also
+stands in a spatial relation to some other node. The spatial relationship between
+the set of nodes of a diagram need not be in a regular network, although they
+quite often are. Note that the spatial relationship between nodes is graphical
+and may represent, e.g., a temporal or logical relationship, or a transformation
+of one object into another or into others (one interesting example might be that
+representing cell division or, mitosis).
+
+Given a spatial relation between any two nodes, a node|-|based diagram often
+includes some \emph {path segment} or segments (such as arrows or other curves)
+between two given nodes that \emph {relates} them. Each path segment may be
+augmented by some textual or graphical label.
+
+A very simple example of a node diagram is shown in \in{Figure} [fig:AB].
\startbuffer
\startMPcode
- save nodepath ; path nodepath ;
- nodepath := (left -- right) scaled .75u ;
+ clearnodepath ;
+ nodepath = (left -- right) scaled .75cm ;
draw node(0,"A") ;
draw node(1,"B") ;
drawarrow fromto(0,0,1) ;
\stopMPcode
\stopbuffer
-The code producing \inlinebuffer\ \emph {could} be:
+\startplacefigure [reference=fig:AB]
+ \getbuffer
+\stopplacefigure
+
+\startplacefigure [reference=fig:ID,
+ location={right,+2*hang}]
+\startMPcode
+ clearnodepath ; nodepath = origin ;
+ draw node(0,"$O$") ;
+ drawarrow fromto.urt (.75cm,0,0) ;
+ setbounds currentpicture to boundingbox currentpicture
+ enlarged (1.2cm,0) ;
+\stopMPcode
+\stopplacefigure
+
+More precisely, a \emph {node} is a point of intersection or branching of paths,
+often a point on a regular lattice. (The nodes of the above diagram are the two
+endpoints of a straight line segment.) Sometimes, however, a node might be a
+single point as in an \emph {identity map} of category theory, referring to
+itself:
+\startfootnote
+ The standard arrowhead in \METAPOST\ is a simple triangle, whose length and
+ angle can be adjusted. \METAFUN\ provides further options, allowing this
+ arrowhead to be barbed or dimpled. In the present article, we use the
+ settings: \type {ahlength := EmWidth ; ahangle := 30 ; ahvariant := 1 ;
+ ahdimple := 4/5 ;} The loop|-|back arrow paths used here deviate from a
+ circular segment, becoming ellipsoidal, through the value \type
+ {node_loopback_yscale := .7 ;} These are all set, of course, between a \type
+ {\startMPinitializations} … \type {\stopMPinitializations} pair.
+\stopfootnote
+
+In this article we discuss a new \METAPOST\ module designed for handling
+node|-|based graphics as well as a derivative simple \CONTEXT\ interface. To
+illustrate, the code producing \inlinebuffer\ {could} be, in \METAPOST\ and the
+\CONTEXT\ interface respectively:
\starttwo
\METAPOST
@@ -337,71 +448,89 @@ The code producing \inlinebuffer\ \emph {could} be:
\stopTEX
\two
\CONTEXT
- \startTEX
- \startnodes
- \node[0]{A}
- \node[1]{B}
- \fromto [0,1] [option=arrow]
- \stopnodes
- \stopTEX
+ \startbuffer
+ \startnodes [dx=1.5cm]
+ \placenode [0,0] {A}
+ \placenode [1,0] {B}
+ \connectnodes [0,1]
+ [alternative=arrow]
+ \stopnodes
+ \stopbuffer
+ \typebuffer [option=TEX]
\stoptwo
-drawing an arrow from A to B (or from node 0 to node 1).
+drawing an arrow from A to B (or from node 0 to node 1): \getbuffer
\startitemize[packed]
\startitem
- The \METAPOST\ code shown above has been simplified, as will be seen
- later.
+ The \METAPOST\ code shown above has been slightly simplified, as will be
+ seen later.
\stopitem
\startitem
- The \CONTEXT\ module has yet to be coded (and may not be useful).
+ The \CONTEXT\ interface as used here is limited and will be explained a
+ little later.
\stopitem
\stopitemize
+For beginners or casual users of \CONTEXT\ |<|including those who might be
+intimidated by \METAPOST\ syntax|>| the ability to construct simple diagrams by
+means of standard \CONTEXT\ syntax is very helpful. For those who have tried the
+\CONTEXT\ interface and/or want to draw more advanced diagrams, the \METAPOST\
+module is much more powerful and flexible.
+
\stopsubject
\startsubject [title=\METAPOST]
-\METAPOST\ is an inherently vectorial graphical language using \TEX\ to typeset
-text; the \METAPOST\ language is integrated natively as MPlib in \CONTEXT. This
-presents advantages over the use of an external graphical objects in providing a
-great coherence of style along with great flexibility without bloat. \METAPOST\
-has further advantages over many other graphical subsystems, namely high
-precision, high quality and the possibility to solve equations. This last point
-is little used but should not be overlooked.
-
-It is quite natural in \METAPOST\ to locate these text nodes along a path or on
-differing paths. This is a much more powerful concept than locating nodes at some
-pair of coordinates, on a square or rectangular lattice, for example, as in a
-table. These paths may be in three dimensions (or more); of course the printed
-page will only be some projection onto two dimensions. Nor must the nodes be
-located on the points defining a path: they may have as index any \emph {time}
-along the path \type {p} ranging from the first defining point ($t = 0$) up to
-the last point of a path ($t ≤ \mathtt{length(p)}$). \footnote {The time of a
-cyclic path is taken modulo the length of the path.}
-
-For a given path \type {p}, nodes are defined (implicitly) as \type {picture}
-elements: \typ {picture p.pic[] ;} This is a pseudo|-|array where the square
-brackets indicates a set of numerical tokens, as in \type {p.pic[0]} but also
-\type {p.pic0}. This number need not be an integer, and \type {p.pic[.5]} or
-\type {p.pic.5} (not to be confused with \type {p.pic5}) are also valid. These
-picture elements are taken to be located relative to the path \type {p}, with the
-index \type {t} corresponding to a time along the path, as in \typ {draw p.pic[t]
-shifted point t of p ;} (although one would not necessarily draw them in this
-way). This convention allows the \quote {nodes} to be oriented and offset with
-respect to the path in an arbitrary fashion.
-
-Note that a path can be defined and then nodes placed relative to this path, or
-else the path may be simply declared yet remain undefined, to be determined
-later, after the nodes are declared. Yet another possibility allows for the path
-to be adjusted as needed, as a function of whatever nodes are to be occupied.
-This will be illustrated through examples later.
+\METAPOST\ is a vector|-|graphics language which calls upon \TeX\ to typeset text
+(such as labels); in \CONTEXT, furthermore, \METAPOST\ is integrated natively
+through the library MPlib as well as the macro package \METAFUN. The tight
+integration of \CONTEXT\ and \METAPOST\ provides advantages over the use of
+other, external graphics engines. These advantages include ease of maintaining
+coherence of style, as well as extensive flexibility without bloat. \METAPOST\
+has further advantages over most other graphics engines, including a very high
+degree of precision as well as the possibility to solve certain types of
+algebraic equations. This last feature is rarely used but should not be
+overlooked.
+
+It is quite natural in \METAPOST\ to locate our node objects along a path or on
+differing paths. This is a much more powerful concept than merely locating a node
+at some pair of coordinates, e.g., on a square or a rectangular lattice, for
+example (as in a table). Furthermore, these paths may be in three dimensions (or
+more); of course the printed page will only involve some projection onto two
+dimensions. Nor are the nodes restricted to location on the points defining a
+path: they may have, as index, any \emph {time} along a given path \type {p}
+ranging from the first defining point ($t = 0$) up to the last point of that path
+($t ≤ \mathtt {length(p)}$), the number of defining points of a path.
+\startfootnote
+ Note that the time of a cyclic path is taken modulo the length of the path,
+ that is $t$ outside of the range $[\mathtt0,\mathtt{length(p)}]$ will return
+ the first or the last point of an open path, but will \quotation {wrap} for a
+ closed path.
+\stopfootnote
+
+Given a path \type {p}, nodes are defined (implicitly) as \type {picture}
+elements: \type {picture p.pic[] ;} This is a pseudo|-|array where the square
+brackets indicates a set of numerical tokens, as in \type {p.pic[0]} or \type
+{p.pic[i]} (for \type {i=0}), but also \type {p.pic0}. This number need not be an
+integer, and \type {p.pic[.5]} or \type {p.pic.5} (not to be confused with \type
+{p.pic5}) are also valid. These picture elements are taken to be located relative
+to the path \type {p}, with the index \type {t} corresponding to a time along the
+path, as in \type {draw p.pic[t] shifted point t of p;} (although it is not
+necessary to draw them in this way). This convention allows the nodes to be
+oriented and offset with respect to the path in an arbitrary manner.
+
+Note that a path can be defined, then nodes placed relative to this path. Or the
+path may be declared but remain undefined, to be determined only after the nodes
+are declared. In yet another possibility, the path may be adjusted as needed, as
+a function of whatever nodes are to be occupied. This will be illustrated through
+examples further down.
\stopsubject
\startsubject [title=A few simple examples]
-\startplacefigure [location=left,reference=fig:square]
+\startplacefigure [location=right,reference=fig:square]
\startMPcode
path p ; p := fullsquare scaled 3cm ;
draw p ;
@@ -412,17 +541,18 @@ This will be illustrated through examples later.
endfor ;
% this looks better in the figure placement:
setbounds currentpicture to boundingbox currentpicture
- rightenlarged 2mm ;
+ enlarged (.5cm,0) ;
\stopMPcode
\stopplacefigure
-This might sound a bit arbitrary, so let's begin with the illustration of a
-typical natural transformation of mathematics. A simple path and the points
-defining this path are drawn in red here. Although it is trivial, this example
-helps to introduce the \METAPOST\ syntax. (Of course, one should be able to use
-this system without having to learn much \METAPOST.)
+Let's begin with illustration of a typical commutative diagram from category
+theory. Although it may appear trivial, this example helps to introduce
+\METAPOST\ syntax. At the same time, a large part of the idea behind this module
+is to facilitate use of this system without having to learn much \METAPOST.
-\flushsidefloats
+A path is drawn as well as the points defining the path.
+
+%\flushsidefloats
\startTEX
\startMPcode
@@ -437,8 +567,8 @@ this system without having to learn much \METAPOST.)
\startbuffer
\startMPcode
- save nodepath ;
- path nodepath ; nodepath = p ;
+ clearnodepath ;
+ nodepath = p ;
draw node(0,"\node{$G(X)$}") ;
draw node(1,"\node{$G(Y)$}") ;
draw node(2,"\node{$F(Y)$}") ;
@@ -450,42 +580,51 @@ this system without having to learn much \METAPOST.)
\stopMPcode
\stopbuffer
-\startplacefigure [location=left,reference=fig:natural]
+\startplacefigure [location={right,+1*hang},reference=fig:natural,
+ title={Drawn using \METAPOST\ interface}]
\getbuffer
\stopplacefigure
-Given the named path \type {nodepath}, we can define and draw nodes as well as
-connections between them.
+Given the named path \type {nodepath}, we can now define and draw nodes as well
+as connections between them (see \in{Figure} [fig:natural]):
-\flushsidefloats
+%\flushsidefloats
\typebuffer [option=TEX]
-\startfiction
-It is an important good practice with \METAPOST\ to reset or clear a variable
-using the directive \type {save} as above for the suffix \type {nodepath}. The
-macros used here rely on the creation of certain internal variables and may not
-function correctly if the variable structure is not cleared. Indeed, any node may
-contain a combination of picture elements, added successively, so it is very
-important to \type {save} the variable, making its use local, rather than global.
-This point is particularly true under \CONTEXT, where a single MPlib instance is
-used and maintained over multiple runs.
-
-The \CONTEXT\ directives \type {\startMPcode} \unknown\ \type {\stopMPcode}
-include grouping (\METAPOST\ \type {begingroup ;} \unknown\ \type {endgroup ;})
-and the use of \type {save} will make the suffix local to this code block. In the
-examples above of \in{Figures} [fig:square] and \in [fig:natural], the path \type
-{p} is not declared local (through the use of a \type {save}) therefore remains
-available for other \METAPOST\ code blocks. We cannot do this with the default
-suffix name \type {nodepath} without getting other unwanted consequences.
-\stopfiction
+\startaside
+In working with \METAPOST, it is good practice to reset or clear a variable using
+the directive \type {save} for the \emph {suffix} (or variable name) \type
+{nodepath} contained in the directive \type {clearnodepath} (defined as
+\quotation {\type {save nodepath ; path nodepath}}). The macros used here rely on
+the creation of certain internal variables and may not function correctly if the
+variable structure is not cleared. Indeed, any node may contain a combination of
+picture elements, added successively, so it is very important to \type {save} the
+variable, making its use local, rather than global. This point is particularly
+true with \CONTEXT, where a single MPlib instance is used and maintained over
+multiple runs.
+
+The \CONTEXT\ directives \type {\startMPcode} … \type {\stopMPcode} include
+grouping (\METAPOST\ \type {begingroup ;}… \type {endgroup ;}) and the use of
+\type {save} (in \type {clearnodepath}) will make the suffix \type {nodepath}
+local to this code block. In the code for \in{Figures} [fig:square] and \in
+[fig:natural], the path \type {p} itself is not declared local (through the use
+of a \type {save}); it therefore remains available for other \METAPOST\ code
+blocks. We cannot do this with the default suffix name \type {nodepath} without
+undesired consequences.
+
+The directive \type {clearnodepath} used in the example above, much like the
+\METAPOST\ command \type {clearxy} clearing the \type {(x,y)} pair also known as
+\type {z}, uses \type {save} to clear the default suffix \type {nodepath}.
+\stopaside
Note that one should not confuse the \METAPOST\ function \type {node()} with the
-\CONTEXT\ command \type {\node{}}, defined as:
+\CONTEXT\ command \type {\node{}}, defined as follows:
\starttwo
\startTEX
- \setupframed
+ \defineframed
+ [node]
[frame=off,
offset=1pt]
\stopTEX
@@ -498,51 +637,127 @@ Note that one should not confuse the \METAPOST\ function \type {node()} with the
\stopTEX
\stoptwo
-placing the text within a \CONTEXT\ frame (with the frame border turned|-|off).
-The \METAPOST\ function \type {node(i,"...")} sets and returns a picture element
-associated with a point on path \type {nodepath} indexed by its first argument.
-The second argument here is a string that gets typeset by \TEX.
+\type {\node{}} places the text within a \CONTEXT\ frame (with the frame border
+turned|-|off), whereas the \METAPOST\ function \type {node(i,"…")} sets and
+returns a picture element associated with a point on path \type {nodepath}
+indexed by its first argument. The second argument here is a string that gets
+typeset by \TEX. (The use of \type {\node{}} adds an \type {offset}).
-The \METAPOST\ function \type {fromto()} returns a path segment going from two
-points of the path \type {nodepath}, by default. The first argument (\type {0} in
+By default, the \METAPOST\ function \type {fromto()} returns a path segment going
+between two points of the path \type {nodepath}. The first argument (\type {0} in
the example above) can be used as a displacement to skew the path away from a
-straight line. The last argument is a string to be typeset and placed midpoint of
-the segment. The \emph {suffix} appended to the function name gives an offset
-around this halfway point. This follows standard \METAPOST\ convention.
+straight line (by an amount in units of the straight path length). The last
+argument is a string to be typeset and placed midpoint of the segment. The
+{suffix} appended to the function name gives an offset around this halfway point.
+This follows standard \METAPOST\ conventions.
+
+It is important to draw or declare the nodes \emph {before} drawing the
+connections, using \type {fromto()}, in order to be able to avoid overlapping
+symbols, as one notices that the arrows drawn in the example above begin and end
+on the border of the frame (or bounding box) surrounding the node text. This
+would of course not be possible if the arrow were to be drawn before this text
+was known.
+
+As will be seen further on, one can actually specify the use of any defined path,
+without restriction to the built|-|in name \type {nodepath} that is used by
+default. Furthermore, a function \type {fromtopaths()} can be used to draw
+segments connecting any two paths which may be distinct. This too will be
+illustrated further on.
+
+The \CONTEXT\ syntax for the current example looks like this:
-\startfiction
- The \CONTEXT\ syntax might be:
- \startTEX
- \startuseMPgraphic{node:square}
- save nodepath ; path nodepath ;
- nodepath := fullsquare scaled 6cm ;
- \stopuseMPgraphic
-
- \setupfromto [option=arrow,position=auto]
-
- \startnodes [mp=node:square]
- \node [0] {$G(X)$}
- \node [1] {$G(Y)$}
- \node [2] {$F(Y)$}
- \node [3] {$F(X)$}
- \fromto [0,1] [label={\tfxx $G(f)$}]
- \fromto [3,2] [label={\tfxx $F(f)$}]
- \fromto [2,1] [label={\tfxx $η_Y$}}
- \fromto [3,0] [label={\tfxx $η_X$}]
- \stopnodes
- \stopTEX
-\stopfiction
+\startbuffer
+ \startnodes [dx=3cm,dy=3cm]
+ \placenode [0,0] {\node{$G(X)$}}
+ \placenode [1,0] {\node{$G(Y)$}}
+ \placenode [1,1] {\node{$F(Y)$}}
+ \placenode [0,1] {\node{$F(X)$}}
+ \connectnodes [0,1] [alternative=arrow,
+ label={\nodeSmall{$G(f)$}},position=bottom]
+ \connectnodes [3,2] [alternative=arrow,
+ label={\nodeSmall{$F(f)$}},position=top]
+ \connectnodes [2,1] [alternative=arrow,
+ label={\nodeSmall{$η_Y$}}, position=right]
+ \connectnodes [3,0] [alternative=arrow,
+ label={\nodeSmall{$η_X$}}, position=left]
+ \stopnodes
+\stopbuffer
+
+\startplacefigure [location=right,
+ title={Drawn using \CONTEXT\ interface}]
+ \getbuffer
+\stopplacefigure
+
+\typebuffer [option=TEX]
+
+\startplacefigure [reference=fig:indices,
+ location=right,
+ title={Coordinates and indices.\footnote{For variety, a rectangular oblique
+ lattice is drawn in \in{Figure} [fig:indices].}
+ }]
+\stopfootnote
+ \startframed [frame=off,width=.33\textwidth,align=flushright]
+ \startnodes [dx=3cm,dy=2cm,rotation=60]
+ \placenode [0,0] {\node{(0,0)}}
+ \placenode [1,0] {\node{(1,0)}}
+ \placenode [1,1] {\node{(1,1)}}
+ \placenode [0,1] {\node{(0,1)}}
+ \connectnodes [0,1] [alternative=arrow,
+ label={\nodeSmall{$0\rightarrow1$}},position=bottom]
+ \connectnodes [3,2] [alternative=arrow,
+ label={\nodeSmall{$3\rightarrow2$}},position=top]
+ \connectnodes [2,1] [alternative=arrow,
+ label={\nodeSmall{$~2\rightarrow1$}}, position=right]
+ \connectnodes [3,0] [alternative=arrow,
+ label={\nodeSmall{$3\rightarrow0$}}, position=upperleft]
+ \stopnodes
+ \stopframed
+\stopplacefigure
+
+This follows the more classic (and limited) approach of placing nodes on the
+coordinates of a regular lattice, here defined as a 3~cm square network.
+\footnote {The lattice can be square (\type {dx} $=$ \type {dy}), rectangular
+(\type {dx} $≠$ \type {dy}), or oblique (through \type {rotation} $≠$ 90).} The
+arguments are then $(x,y)$ coordinates of this lattice and the nodes are indexed
+0, 1, 2, … in the order that they are drawn. These are used as reference indices
+in the commands \type {\connectnodes} (rather than requiring two \emph {pairs} of
+coordinates); see \in {Figure} [fig:indices]. This might seem a bit confusing at
+first view, but it simplifies things in the end, really!
+
+An identity map, as shown in \in {Figure} [fig:ID], earlier, and, below, in \in
+{Figure} [fig:Me] is achieved by connecting a node to itself:
-Actually, as will be seen later, one can specify the use of any defined path, not
-restricted to the built||in name \type {nodepath} that is used by default.
-Furthermore, a function \type {fromtopaths()} can be used to draw segments
-connecting any two paths which may be distinct. This, too, will be illustrated
-later.
+\startbuffer
+\startnodes [dx=2cm,dy=1cm]
+ \placenode [0,0] {\node{Me}}
+ \placenode [1,-1] {\node{You}}
+ \connectnodes [0,0] [alternative=arrow,
+ offset=.75cm,position=topright,
+ label=myself]
+ \connectnodes [1,1] [alternative=arrow,
+ offset=.75cm,position=bottomright,
+ label=yourself]
+\stopnodes
+\stopbuffer
+
+\startplacefigure [reference=fig:Me,title=Identity maps,
+ location=right]
+ \getbuffer
+\stopplacefigure
+
+\typebuffer [option=TEX]
+
+The scale (diameter) of the circular loop|-|back is set by the keyword \type
+{offset=} (normally used to curve or bow|-|away a path connecting nodes from the
+straight|-|line segment between them), and the \type {position=} keyword sets its
+orientation.
+
+\page [yes]
\startbuffer
\startMPcode
-save nodepath ; path nodepath ;
-nodepath := fullsquare scaled 2cm ;
+clearnodepath ;
+nodepath = fullsquare scaled 2cm ;
save A ; A = 3 ; draw node(A,"\node{A}") ;
save B ; B = 2 ; draw node(B,"\node{B}") ;
save C ; C = 0 ; draw node(C,"\node{C}") ;
@@ -553,20 +768,29 @@ drawarrow fromto(0,A,D) crossingunder fromto(0,B,C) ;
\stopMPcode
\stopbuffer
-\startplacefigure [location=left,reference=fig:crossingunder]
- \getbuffer
+\startplacefigure [reference=fig:crossingunder,
+ location={right,+3*hang},
+ title=A$\rightarrow$D under B$\rightarrow$C]
+ \startframed [frame=off,width=5cm,align=middle]
+ \getbuffer
+ \stopframed
\stopplacefigure
-Consider now the following code illustrating the \METAFUN\ operator \type
-{crossingunder} that draws a path with segments cut|-|out surrounding the
-intersection(s) with a second path segment. This operator is of such general use
-that it has been added to the \METAFUN\ base.
-
-\flushsidefloats
+Let us now consider the following code which illustrates the \METAFUN\ operator
+\type {crossingunder}
+\startfootnote
+ The operator \type {crossingunder} is of such general use that it has been
+ added to the \METAFUN\ base.
+\stopfootnote
+(see \in {Figure}[fig:crossingunder]). The \type {nodepath} indices are put into
+variables \type {A}, \type {B}, \type {C}, and \type {D}, thus simplifying the
+code.
\typebuffer [option=TEX]
-\startplacefigure [reference=fig:sincos,location=left,title={\type{crossingunder}}]
+\startplacefigure [reference=fig:sincos,
+ location=right,
+ title={\type{crossingunder}}]
\startMPcode
save u ; u := 2cm ;
save p ; path p[] ;
@@ -586,82 +810,78 @@ that it has been added to the \METAFUN\ base.
Another illustration of the \type {crossingunder} operator in use is shown in \in
{figure} [fig:sincos]. Because the diagrams are all defined and drawn in
-\METAPOST, one can easily extend the simple mode drawing with any sort of
-graphical decoration using all the power of the \METAPOST\ language.
-
-This brings up a delicate point that has inhibited the development of a \CONTEXT\
-module up to now: \METAPOST\ is such a powerful language that it is difficult to
-design a set of commands having equivalent flexibility. Perhaps, as is done
-presently with the Chemistry package, one need only allow for the injection of
-arbitrary \METAPOST\ code when needed for such special cases.
-
-Should it be done like this?
-
-\startfiction
-\startTEX
-\startnodes [mp=node:square]
- \node [3] {A}
- \node [2] {B}
- \node [0] {C}
- \node [1] {D}
- \fromto [2,0]
- \fromto [3,1] [option={under[2,0]}] % ?
-\stopnodes
-\stopTEX
-\stopfiction
-
-Such a simple example illustrates why we favor a pure \METAPOST\ interface and
-why a \CONTEXT\ interface will not be developed, at least for now.
+\METAPOST, one can easily use the power of \METAPOST\ to extend a simple node
+drawing with any kind of graphical decoration.
+
+This brings up an important point that has limited the development of a
+full|-|featured \CONTEXT\ module up to now. A pure \METAPOST\ interface affords
+much more flexibility than can be conveniently reduced to a set of \TeX\ macros;
+the \CONTEXT\ interface has been written to maintain only basic functionality.
+\startfootnote
+ One can use \type {\nodeMPcode{}} to inject arbitrary \METAPOST\ code within
+ a \type {\startnode} … \type {\stopnode} pair, although in this example one
+ is probably better off using the straight \METAPOST\ interface.
+\stopfootnote
\stopsubject
\startsubject [title=Cyclic diagrams]
-In a slightly more complicated example, that of a catalytic process given in the
-\cite[authoryears] [Krebs1946] representation, where the input is indicated
-coming into the cycle from the center of a circle and the products of the cycle
-are spun|-|off from the outside of the circle, we start by defining a circular
-path where each point corresponds to a step in the cyclic process. Our example
-will use six steps.
+For a somewhat more complicated example, let us consider the representation of a
+catalytic process such as that given by \cite [author] [Krebs1946]. \cite
+[Krebs1946] The input is shown coming into the cycle from the center of a circle;
+the products of the cycle are spun|-|off from the outside of the circle. We start
+by defining a circular path where each point corresponds to a step in the cyclic
+process. Our example will use six steps (see \in {Figure} [fig:circles]).
-We will want to define a second circular path with the same number of points at
-the interior of this first circle for the input and a third circular path at the
-exterior for the output. Thus,
+We also want to define a second circular path with the same number of points at
+the interior of this first circle for the input, and a third circular path at the
+exterior for the output.
-\startTEX
+The code is as follows:
+
+\page [yes]
+
+\startbuffer
\startMPcode
save p ; path p[] ;
% define a fullcircle path with nodes at 60° (rather than 45°)
- p1 := (for i=0 step 60 until 300: dir(90-i) .. endfor cycle) scaled 2.75cm ;
+ p1 := (for i=0 step 60 until 300: dir(90-i) .. endfor cycle) scaled 2.5cm ;
p0 := p1 scaled .5 ;
p2 := p1 scaled 1.5 ;
-\stopMPcode
-\stopTEX
-\startplacefigure [location=left,title={The paths that we will use for anchoring for nodes.}]
-\startMPcode
- save p ; path p[] ;
- p1 := (for i=0 step 60 until 300: dir(90-i) .. endfor cycle) scaled 2.75cm ;
- p0 := p1 scaled .5 ;
- p2 := p1 scaled 1.5 ;
- for i=0 upto 2:
- draw p[i] ;
- for j=0 upto length p[i]:
- draw point j of p[i] withpen currentpen scaled 5 withcolor red ;
- endfor
- label.bot("p" & decimal i, point 0 of p[i]) ;
+ for i=0 upto 2:
+ draw p[i] ;
+ label.bot("\bf p" & decimal i, point 0 of p[i]) ;
+ for j=1 upto length p[i]:
+ draw point j of p[i] withpen currentpen scaled 10 withcolor red ;
+ if i=1:
+ label.autoalign(angle point j of p[i]) (decimal j, point j of p[i])
+ withcolor red ;
+ fi
endfor
+ endfor
\stopMPcode
+\stopbuffer
+
+\typebuffer [option=TEX]
+
+\startplacefigure [reference=fig:circles,
+ location=right,
+ title={The paths that we will use for the anchoring of nodes.}]
+ \getbuffer
\stopplacefigure
+[\type {autoalign()} is a feature defined within \METAFUN.]
+
Nodes will then be drawn on each of these three circles and arrows will be used
to connect these various nodes, either on the same path or else between paths.
-The \METAPOST\ function \type {fromto()} is used to give a segment pointing
-between nodes. It \emph {assumes} the path \type {nodepath}, and in fact calls
-the function \type {fromtopaths} that explicitly takes path names as arguments,
-i.e. \type {fromto (d, i, j, ...)} is equivalent to \type {fromtopaths (d,
-nodepath, i, nodepath, j, ...)}.
+The \METAPOST\ function \type {fromto()} is used to give a path segment that
+points from one node to another. It \emph {assumes} the path \type {nodepath},
+and in fact calls the function \type {fromtopaths} that explicitly takes path
+names as arguments. That is, \type {fromto (d, i, j, …)} is equivalent to \type
+{fromtopaths (d, nodepath, i, nodepath, j, …)}.
As stated above, this segment can be a straight line or else a path that can be
bowed|-|away from this straight line by a transverse displacement given by the
@@ -672,12 +892,42 @@ behavior is obtained by using any non|-|numeric value (such as \type {true}) in
place of the first argument. Of course, this cannot work if the two nodes are not
located on the same path.
+The circular arc segments labeled \emph {\darkgreen a–f} are drawn on \in
+{figure} [fig:Bethe] using the following:
+
+\startTEX
+drawarrow fromtopaths.urt (true,p1,0,p1,1,"\nodeGreen{a}") ;
+\stopTEX
+
+for example, where \type {\nodeGreen} is a frame that inherits from \type
+{\node}, changing style and color:
+
+\startTEX
+\defineframed
+ [nodeGreen]
+ [node]
+ [foregroundcolor=darkgreen,
+ foregroundstyle=italic]
+\stopTEX
+
+The bowed|-|arrows feeding into the cyclic process and leading out to the
+products, thus between different paths, from the path \type {p0} to the path
+\type {p1} and from the path \type {p1} to the path \type {p2}, respectively, are
+drawn using the deviations \type {+3/10} and \type {-1/10} (to and from
+half|-|integer indices, thus mid|-|step, on path \type {p1}):
+
+\startTEX
+drawarrow fromtopaths( 3/10,p0,0,p1,0.5) withcolor .6white ;
+drawarrow fromtopaths(-1/10,p1,0.5,p2,1) withcolor .6white ;
+\stopTEX
+
\startplacefigure [reference=fig:Bethe,
title={The \cite[author] [Bethe1939a] cycle for the energy production in stars
\cite[alternative=year,left=(,right=)] [Bethe1939a+Bethe1939b] in a
- \cite[authoryears] [Krebs1946] representation of a catalytic process.}]
+ \cite[author] [Krebs1946] representation of a catalytic process
+ \cite[alternative=year,left=(,right=)] [Krebs1946].}]
\startMPcode
-
+
% differs slightly from \reuseMPgraphic{nodes::krebs}
% The Bethe cycle for energy production in stars (1939), following Krebs (1946)
@@ -730,62 +980,103 @@ located on the same path.
\stopMPcode
\stopplacefigure
-The circular arc segments labeled \emph {\darkgreen a–f} are drawn on \in
-{figure} [fig:Bethe] using
+\startsubsubject [title={A lesson in \METAPOST}]
-\startTEX
-drawarrow fromtopaths.urt (true,p1,0,p1,1,"\nodeGreen{a}") ;
-\stopTEX
+An \quote {array} of paths is declared through \type {path p[] ;} it is not a
+formal array, but rather a syntactic definition of a collection of path variables
+\type {p0}, \type {p1}, … each of whose name is prefixed with the tag \quotation
+{p} followed by any number, not necessarily an integer (e.g., \type {p3.14} is a
+valid path name). The syntax allows enclosing this \quotation {index} within
+square brackets, as in \type {p[0]} or, more typically, \type {p[i]}, where \type
+{i} would be a numeric variable or the index of a loop. Note that the use of
+brackets is required when using a negative index, as in \type {p[-1]} (for \type
+{p-1} is interpreted as three tokens, representing a subtraction). Furthermore,
+the variable \type {p} itself, would here be a numeric (by default), so \type
+{p[p]} would be a valid syntactic construction! One could, additionally, declare
+a set of variables \type {path p[][] ;} and so forth, defining also \type
+{p[0][0]} (equivalently, \type {p0 0}) for example as a valid path, coexisting
+with yet different from the path \type {p0}.
+
+\METAPOST\ also admits variable names reminiscent of a structure: \type {picture
+p.pic[] ;} for example is used internally in the \type {node} macros, but this
+becomes \type {picture p[]pic[] ;} when using a path \quote {array} syntax. These
+variable names are associated with the suffix \type {p} and become all undefined
+by \type {save p ;}.
-for example, where \type {\nodeGreen} is a frame that inherits from \type
-{\node}, changing style and color:
+\stopsubsubject
-\startTEX
-\defineframed
- [nodeGreen]
- [node]
- [foregroundcolor=darkgreen,
- foregroundstyle=italic]
-\stopTEX
-\stopfootnote
+\startsubsubject [title={Putting it together}]
-The bowed|-|arrows feeding into the cyclic process and leading out to the
-products, thus between different paths, from the path \type {p0} to the path
-\type {p1} and from the path \type {p1} to the path \type {p2}, respectively, are
-drawn using the deviations \type {+3/10} and \type {-1/10} (to and from
-half|-|integer indices, thus mid|-|step, on path \type {p1}):
+What follows is simple example of a natural transformation, discovered and
+articulated in the course of a philosophical research project (by Idris Samawi
+Hamid). \in {Figure} [fig:NT] represents what is called the Croce Topos [named
+after the Italian philosopher Benedetto Croce (1866–1952)]:
-\startTEX
-drawarrow fromtopaths( 3/10,p0,0,p1,0.5) withcolor .6white ;
-drawarrow fromtopaths(-1/10,p1,0.5,p2,1) withcolor .6white ;
-\stopTEX
+\startbuffer
+\startMPcode
+ save nodepath ;
+ path nodepath ;
+ nodepath = ((0,0) -- (1,0) -- (3,0) --
+ (3,1) -- (1,1) -- (0,1) --
+ cycle) scaled 4cm ;
+ draw node(0,"\node{Practical}") ;
+ draw node(1,"\node{Economic}") ;
+ draw node(2,"\node{Moral}") ;
+ draw node(3,"\node{Conceptual}") ;
+ draw node(4,"\node{Aesthetic}") ;
+ draw node(5,"\node{Theoretical}") ;
+
+ drawarrow fromto.rt (.1,5,0,"\node{$γ$}") ;
+ drawarrow fromto.lft(.1,0,5,"\node{$γ'$}") ;
+ drawarrow fromto.rt (.1,4,1,"\node{$Fγ$}") ;
+ drawarrow fromto.lft(.1,1,4,"\node{$Fγ'$}") ;
+ drawarrow fromto.rt (.1,3,2,"\node{$Gγ$}") ;
+ drawarrow fromto.lft(.1,2,3,"\node{$Gγ'$}") ;
+
+ drawarrow fromto.top( 0,4,3,"\node{\it concretization$_1$}") ;
+ drawarrow fromto.bot(.1,3,4,"\node{\it abstraction$_1$}")
+ dashed evenly ;
+ drawarrow fromto.top( 0,1,2,"\node{\it concretization$_2$}") ;
+ drawarrow fromto.bot(.1,2,1,"\node{\it abstraction$_2$}")
+ dashed evenly ;
+\stopMPcode
+\stopbuffer
-\startsubsubject [title={A lesson in \METAPOST}]
+% Let's forget that and rather use \startnodes...
-An \quote {array} of paths is declared through \typ {path p[] ;} it is not a
-formal array, rather a syntactic definition of a collection of path variables
-\type {p0}, \type {p1}, \unknown\ named beginning with the tag \quote {p}
-followed by any number, not necessarily an integer (i.e. \type {p3.14} is a valid
-path name). The syntax allows enclosing this \quote {index} within square
-brackets, as in \type {p[0]} or, more typically, \type {p[i]}, where \type {i}
-would be a numeric variable or the index of a loop. Note that the use of brackets
-is required when using a negative index, as in \type {p[-1]} (for \type {p-1} is
-interpreted as three tokens, representing a subtraction). Furthermore, the
-variable \type {p} itself, would here be a numeric (by default), so \type {p[p]}
-would be a valid syntactic construction! One could, additionally, declare a set
-of variables \typ {path p[][] ;} and so forth, defining also \type {p[0][0]}
-(equivalently, \type {p0 0}) for example as a valid path, coexisting with yet
-different from the path \type {p0}.
-
-\METAPOST\ also admits variable names reminiscent of a structure: \typ {picture
-p.pic[] ;} for example is used internally in the \type {node} macros, but this
-becomes \typ {picture p[]pic[] ;} when using a path \quote {array} syntax. These
-variable names are associated with the suffix \type {p} and become all undefined
-by \typ {save p ;}.
+\startbuffer
+\startnodes [dx=4cm,dy=4cm,alternative=arrow]
+ \placenode [0,0] {\node{Practical}}
+ \placenode [1,0] {\node{Economic}}
+ \placenode [3,0] {\node{Moral}}
+ \placenode [3,1] {\node{Conceptual}}
+ \placenode [1,1] {\node{Aesthetic}}
+ \placenode [0,1] {\node{Theoretical}}
+
+ \connectnodes [5,0] [offset=.1,position=right, label={\node{$γ$}}]
+ \connectnodes [0,5] [offset=.1,position=left, label={\node{$γ'$}}]
+ \connectnodes [4,1] [offset=.1,position=right, label={\node{$Fγ$}}]
+ \connectnodes [1,4] [offset=.1,position=left, label={\node{$Fγ'$}}]
+ \connectnodes [3,2] [offset=.1,position=right, label={\node{$Gγ$}}]
+ \connectnodes [2,3] [offset=.1,position=left, label={\node{$Gγ'$}}]
+
+ \connectnodes [4,3] [position=top, label={\node{\it concretization$_1$}}]
+ \connectnodes [3,4] [postition=bottom,offset=.1, option=dashed,
+ label={\node{\it abstraction$_1$}}]
+ \connectnodes [1,2] [position=top, label={\node{\it concretization$_2$}}]
+ \connectnodes [2,1] [position=bottom,offset=.1, option=dashed,
+ label={\node{\it abstraction$_2$}}]
+\stopnodes
+\stopbuffer
+
+\startplacefigure [reference=fig:NT,
+ title={A representation of the Croce Topos}]
+ \getbuffer
+\stopplacefigure
-The \type {node} macros use the default name \type {nodepath} when no path is
-explicitly specified. It is the user's responsibility to ensure the local or
-global validity of this path if used.
+Here we use the \CONTEXT\ interface to the node package:
+
+\typebuffer [option=TEX]
\stopsubsubject
@@ -793,10 +1084,11 @@ global validity of this path if used.
\startsubject [title=Tree diagrams]
-The tree diagram shown below is drawn using four paths, each one defining a row
-or generation in the branching. The definition of the spacing of nodes was
-crafted by hand and is somewhat arbitrary: 3.8, 1.7, and 1 for the first, second
-and third generations.
+The tree diagram shown in \in {Figure} [fig:DNA] is drawn using four paths, each
+one defining a row or generation in the branching. The definition of the spacing
+of nodes was crafted by hand and is somewhat arbitrary: 3.8, 1.7, and 1 for the
+first, second and third generations. This might not be the best approach, but
+this is how I was thinking when I first created this figure.
\startplacefigure [location=force,reference=fig:DNA]
\startMPcode
@@ -843,25 +1135,28 @@ and third generations.
\stopMPcode
\stopplacefigure
-One can do better by allowing \METAPOST\ to solve equations and to determine this
-spacing automatically. This will be illustrated by a very simple example where
-nodes are first placed on a declared but undefined path.
+Ultimately, one can do better by allowing \METAPOST\ to solve the relevant
+equations and to determine this spacing automatically. Because it is a somewhat
+advanced procedure, this approach will be first illustrated through a very simple
+example of a diagram where the nodes will be placed on a declared but undefined
+path:
\startTEX
save p ; % path p ;
\stopTEX
-The \type {save p ;} assures that the path is undefined. This path will later get
+The \type {save p ;} assures that the path is undefined. This path will later ḻṯ
defined based on the contents of the nodes and a desired relative placement. In
fact, it is not even necessary to declare that the suffix will be a path, as the
path will be declared and automatically built once the positions of all the nodes
-are determined, which is why the \type {path} declaration is commented|-|out
-above.
+are determined. To emphasize this point, the \type {path} declaration above is
+commented|-|out.
-The user is to be warned that solving equations in \METAPOST\ can be
-non|-|trivial for those who are less mathematically inclined. One needs to
-establish a coupled set of equations that is solvable: that is, fully but not
-over|-|determined.
+\startdescription {Warning:}
+Solving equations in \METAPOST\ can be non|-|trivial for those who are less
+mathematically inclined. One needs to establish a coupled set of equations that
+is solvable: that is, fully but not over|-|determined.
+\stopdescription
A few helper functions have been defined: \type {makenode()} returns a suffix
(variable name) corresponding to the node's position. The first such node can be
@@ -869,7 +1164,7 @@ placed at any finite point, for example the drawing's origin. The following node
can be placed in relation to this first node:
% \startframed [frame=off,align=text,offset=overlay] % keep this together on one page.
-\startTEX [style=small]
+\startTEX
save nodepath ;
save first, second, third, fourth ;
pair first, second, third, fourth ;
@@ -892,15 +1187,18 @@ The helper function \type {betweennodes()} returns a vector pointing in a certai
direction, here following the standard \METAPOST\ suffixes: \type {urt}, \type
{lft}, and \type {bot}, that takes into account the bounding boxes of the
contents of each node, plus an (optional) additional distance (here given in
-units of the arrow||head length, \type {ahlength}). Using the keyword \type
+units of the arrow|-|head length, \type {ahlength}). Using the keyword \type
{whatever} tells \METAPOST\ to adjust this distance as necessary. The above set
of equations is incomplete as written, so a fifth and final relation needs to be
added; the fourth node is also to be located directly to the left of the very
-first node: \footnote {Equivalently, we could declare that the first node located
-to the right of the fourth node: \typ {first = fourth + betweennodes.rt
-(nodepath, first.i, nodepath, fourth.i, 3ahlength) ;}}
+first node:
+\startfootnote
+ Equivalently, we could declare that the first node located to the right of
+ the fourth node: \type {first = fourth + betweennodes.rt (nodepath, first.i,
+ nodepath, fourth.i, 3ahlength) ;}
+\stopfootnote
-\startTEX [style=small]
+\startTEX
fourth = first
+ betweennodes.lft(nodepath,fourth.i,nodepath,first.i,3ahlength) ;
\stopTEX
@@ -908,24 +1206,12 @@ fourth = first
Note that the helper function \type {makenode()} can be used as many times as
needed; if given no content, only returning the node's position. Additional nodes
can be added to this diagram along with appropriate relational equations, keeping
-in mind that the equations must be solvable, of course. This last point is the
-one challenge that most users might face.
-
-The function \type {node()} that was used previously and returning a picture
-element to be drawn itself calls the function \type {makenode()}, used here. The
-nodes have not been drawn as yet:
+in mind that the equations must, of course, be solvable. This last issue is the
+one challenge that most users might face. The function \type {node()} that was
+used previously and returning a picture element to be drawn itself calls the
+function \type {makenode()}, used here. The nodes have not yet been drawn:
-\startTEX
-for i = first.i, second.i, third.i, fourth.i :
- draw node(i) ;
- drawarrow fromto(0,i,i+1) ;
-endfor
-\stopTEX
-
-resulting in \in{figure} [fig:relative]. The path is now defined as one running
-through the position of all of the defined nodes, and is cyclic.
-
-\startplacefigure [location=here,reference=fig:relative]
+\startplacefigure [location=right,reference=fig:relative]
\startMPcode
save nodepath ;
save first, second, third, fourth ;
@@ -948,24 +1234,38 @@ through the position of all of the defined nodes, and is cyclic.
\stopMPcode
\stopplacefigure
+\startTEX
+for i = first.i, second.i, third.i, fourth.i :
+ draw node(i) ;
+ drawarrow fromto(0,i,i+1) ;
+endfor
+\stopTEX
+
+This results in \in {Figure} [fig:relative]. The path is now defined as one
+running through the position of all of the defined nodes, and is cyclic.
+
Using this approach, that of defining but not drawing the nodes until a complete
set of equations defining their relative positions has been constructed, imposes
-several limitations: firstly, the nodes are expected to be numbered from $0$ up
-to $n$, continuously, without any gaps for each defined path. This is just an
-implicit convention of the path construction heuristic. Secondly, when finally
+several limitations. First, the nodes are expected to be numbered from $0$ up to
+$n$, continuously and without any gaps for each defined path. This is just an
+implicit, heuristic convention of the path construction. Second, when finally
defining all the nodes and their positions, the path needs to be constructed. A
-function, \type {makenodepath(p) ;} accomplishing this gets implicitly called
+function, \type {makenodepath(p) ;} accomplishes this; it gets implicitly called
(once) upon the drawing of any \type {node()} or connecting \type {fromto}. Of
-course, \type {makenodepath()} can always be explicitly called once the set of
+course, \type {makenodepath()} can always be called explicitly once the set of
equations determining the node positions is completely defined.
\startparagraph [style=bold]
-We again stress that the writing of a solvable yet not over|-|determined set of
-equations can be a common source of error for many \METAPOST\ users.
+We once again stress that the writing of a solvable yet not over|-|determined set
+of equations can be a common source of error for many \METAPOST\ users.
+\startfootnote
+ The generous use of descriptive variables as we try to illustrate in the
+ examples here can help tremendously in keeping track of multiple equations.
+\stopfootnote
\stopparagraph
Another such example is the construction of a simple tree of descendance or
-family tree. There are many ways to draw such a tree; in \in{figure}
+family tree. There are many ways to draw such a tree; in \in {figure}
[fig:descendance] we will show only three generations.
\startplacefigure [location=here,reference=fig:descendance,
@@ -1042,26 +1342,30 @@ family tree. There are many ways to draw such a tree; in \in{figure}
We leave it as an exercise to the reader to come|-|up with the equations used to
determine this tree (one can look at source of this document, if necessary).
-The set of equations could be hidden from the user wishing to construct simple,
-pre|-|defined types of diagrams. However, such cases would imply a loss of
-generality and flexibility. Nevertheless, the \emph {node} module will probably
-be extended in the future to provide a few simple models. One might be a
-branching tree structure, yet even the above example as drawn does not fit into a
-simple, general model.
+The requisite set of equations could be hidden from the user wishing to construct
+simple, pre|-|defined types of diagrams. However, such cases would involve a loss
+of generality and flexibility. Nevertheless, the \ConTeXt-Nodes module \emph
+{could} be extended in the future to provide a few simple models. One might be a
+branching tree structure, although even the above example (as drawn) does not
+easily fit into a simple, general model.
+
+\blank
-A user on the mailing list asked if it is possible to make structure trees for
-English sentences with categorical grammar, an example of which is shown in \in
-{Figure} [fig:grammar].
+A user on the \CONTEXT\ mailing list asked if it is possible to make structure
+trees for English sentences with categorical grammar, an example of which is
+shown in \in {Figure} [fig:grammar].
\startbuffer
\startMPcode
- save p ; path p[] ; % we work first with unit paths.
+ save p ; path p[] ;
save n ; n = 0 ;
+ % rather than parsing a string, we can use "suffixes":
forsuffixes $=People,from,the,country,can,become,quite,lonely :
- p [n] = makenode(p[n],0,"\node{\it" & (str $) & "}") = (n,0) ;
+ p[n] = makenode(p[n],0,"\node{\it" & (str $) & "}")
+ = (n,0) ; % we work first with unit paths.
n := n + 1 ;
endfor
- save u ; u := TextWidth/n ;
+ save u ; u := MakeupWidth/n ; %(columns) TextWidth/n ;
% build upward tree
@@ -1135,50 +1439,72 @@ English sentences with categorical grammar, an example of which is shown in \in
\stopbuffer
\startplacefigure [reference=fig:grammar,
- title=A categorical grammer structure tree]
+ title={A categorical grammer structure tree}]
\getbuffer
\stopplacefigure
-I chose to define a series of parallel paths, one per word, with one path
+Here, I chose to define a series of parallel paths, one per word, with one path
terminating whenever it joins another path (or paths) at a common parent.
-Labeling each branch of the tree structure requires, of course, a knowledge of
-the tree structure.
+Naturally, labeling each branch of the tree structure requires a knowledge of the
+tree structure. The code is not short, but hopefully it is mostly clear.
\typebuffer [option=TEX]
+Note that diagrams such as those constructed here will each be significantly
+different, making the writing of a general mechanism rather complex. For example,
+one might need to construct a tree branching up rather than down, or to the right
+(or left), or even following an arbitrary path, such as a random walk. These can
+all be achieved individually in \METAPOST\ without too much difficulty.
+
\stopsubject
\startsubject [title=A 3D projection]
-% This special instance could become part of the base distribution...
+Although \METAPOST\ is a 2D drawing language, it can be easily extended to work
+in 3D. Several attempts have been made in the past ranging from simple to
+complicated. Here, we will take a simple approach.
+
+The \METAPOST\ language includes a triplet variable type, used to handle \type
+{rgb} colors (it also has a quadruplet type used for \type {cmyk} colors). We
+will use this \type {triplet} type to hold 3D coordinates. There is a separate
+\CONTEXT\ module, entitled \type {three}, which creates a new \METAPOST\ instance
+(also named \type {three}), which loads a set of macros that can be used to
+manipulate these triplet coordinates.
\usemodule [three]
-%\defineMPinstance [three] [format=metafun,extensions=yes,initializations=yes,method=double]
+\startTEX
+\usemodule [three]
-%\startMPdefinitions{three}
-%input mp-p-3d.mpiv ;
-%\stopMPdefinitions
+\startMPcode{three}
+ % code here
+\stopMPcode
+\stopTEX
-\startMPcalculation{three}
- ahlength := 12pt ;
- ahangle := 30 ;
- ahvariant := 1 ; % dimpled
-\stopMPcalculation
+For our purposes here, only one function is really necessary: \type
+{projection()} that maps a 3D coordinate to a 2D projection on the page. This
+will not be a perspective projection having a viewpoint and a focus point, but
+rather a very simple oblique projection, useful for, e.g., pseudo|-|3D schematic
+drawings. The \type {Z} coordinate is taken to be \type {up} and the \type {Y}
+coordinate taken to be \type {right}, both in the page of the paper. The third
+coordinate \type {X} is an oblique projection in a right|-|hand coordinate
+system.
-\startplacefigure [location=left]
+\page [yes]
+\startbuffer
\startMPcode{three}
- nodepath :=
- (projection Origin --
- projection (1,0,0) --
- projection (1,1,0) --
- projection (0,1,0) --
- projection (0,1,1) --
- projection (1,1,1) --
- projection (1,0,1) --
- projection (0,0,1) --
- cycle) scaled 5cm ;
+ save nodepath ;
+ path nodepath ;
+ nodepath = (projection Origin --
+ projection (1,0,0) --
+ projection (1,1,0) --
+ projection (0,1,0) --
+ projection (0,1,1) --
+ projection (1,1,1) --
+ projection (1,0,1) --
+ projection (0,0,1) --
+ cycle) scaled 5cm ;
draw node(0,"\node{${\cal C}_{i\cal P}^{\mathrm{nt}}$}") ;
draw node(1,"\node{${\cal C}_{i\cal G}^{\mathrm{nt}}$}") ;
@@ -1197,29 +1523,36 @@ the tree structure.
drawdoublearrows fromto(0,7,6) ;
drawdoublearrows fromto(0,6,5) ;
- drawdoublearrows fromto.lft(0,5,4,"\node{$τ_j$~}") ;
- drawdoublearrows fromto.top(0,7,4,"\node{$σ$}") ;
+ drawdoublearrows fromto.ulft(0,5,4,"\node{$τ_j$~}") ;
+ drawdoublearrows fromto.top (0,7,4,"\node{$σ$}") ;
drawdoublearrows fromto.lrt(0,0,7,"\node{$Ψ^{\mathrm{nt}}$}")
- crossingunder fromto(0,6,5) ;
+ crossingunder fromto(0,6,5) ;
drawdoublearrows fromto(0,1,6) ;
drawdoublearrows fromto(0,2,5) ;
drawdoublearrows fromto(0,3,4) ;
\stopMPcode
+\stopbuffer
+\startplacefigure [location=right,
+ reference=fig:cube]
+ \getbuffer
\stopplacefigure
+Intended for schematic drawings, there is no automatic hidden|-|line removal nor
+effects like shading, and line crossings need to be handled manually (using \type
+{crossingunder} introduced previously). In \in{Figure} [fig:cube] we draw a
+simple cubical commutative diagram, with a node at each corner.
+
+\typebuffer [option=TEX]
+
+Note the use of \type {drawdoublearrows}, a new \METAFUN\ command that is
+introduced here.
+
\stopsubject
\startsubject [title=Two final examples]
-\defineframed
- [smallnode]
- [node]
- [foregroundstyle=\tfxx,
- background=color,
- backgroundcolor=white]
-
\startbuffer[mp:tikz-cd]
\startMPcode
save nodepath ; save l ; l = 5ahlength ;
@@ -1239,39 +1572,61 @@ the tree structure.
for i = XxY.i, X.i, Z.i, Y.i, T.i:
draw node(i) ;
endfor
- drawarrow fromto.top(0, XxY.i,X.i,"\smallnode{$p$}") ;
- drawarrow fromto.rt (0, X.i,Z.i,"\smallnode{$f$}") ;
- drawarrow fromto.top(0, Y.i,Z.i,"\smallnode{$g$}") ;
- drawarrow fromto.rt (0, XxY.i,Y.i,"\smallnode{$q$}") ;
- drawarrow fromto.top( .13,T.i,X.i,"\smallnode{$x$}") ;
- drawarrow fromto.urt(-.13,T.i,Y.i,"\smallnode{$y$}") ;
- drawarrow fromto (0, T.i,XxY.i,"\smallnode{$(x,y)$}")
+ drawarrow fromto.top(0, XxY.i,X.i, "\nodeSmall{$p$}") ;
+ drawarrow fromto.rt (0, X.i,Z.i, "\nodeSmall{$f$}") ;
+ drawarrow fromto.top(0, Y.i,Z.i, "\nodeSmall{$g$}") ;
+ drawarrow fromto.rt (0, XxY.i,Y.i, "\nodeSmall{$q$}") ;
+ drawarrow fromto.top( .13,T.i,X.i, "\nodeSmall{$x$}") ;
+ drawarrow fromto.urt(-.13,T.i,Y.i, "\nodeSmall{$y$}") ;
+ drawarrow fromto (0, T.i,XxY.i,"\nodeSmall{$(x,y)$}")
dashed withdots scaled .5
withpen currentpen scaled 2 ;
\stopMPcode
\stopbuffer
-\startplacefigure [location=left,reference=fig:tikz-cd]
+% Rather, let's do it similarly to TikZ.
+
+\startbuffer[mp:tikz-cd]
+\startnodes [dx=2.5cm,dy=2cm,alternative=arrow]
+ \placenode [0, 0] {\node{$X\times_Z Y$}}
+ \placenode [1, 0] {\node{$X$}}
+ \placenode [1,-1] {\node{$Z$}}
+ \placenode [0,-1] {\node{$Y$}}
+ \placenode [-1,1] {\node{$T$}}
+
+ \connectnodes [0,1] [position=top, label={\nodeSmall{$p$}}]
+ \connectnodes [1,2] [position=right, label={\nodeSmall{$f$}}]
+ \connectnodes [0,3] [position=right, label={\nodeSmall{$q$}}]
+ \connectnodes [3,2] [position=top, label={\nodeSmall{$g$}}]
+ \connectnodes [4,0] [option=dotted,rulethickness=1pt,
+ label={\nodeSmall{$(x,y)$}}]
+ \connectnodes [4,1] [offset=+.13,position=top,
+ label={\nodeSmall{$x$}}]
+ \connectnodes [4,3] [offset=-.13,position=topright,
+ label={\nodeSmall{$y$}}]
+\stopnodes
+\stopbuffer
+
+\startplacefigure [reference=fig:tikz-cd,
+ location={right,+3*hang}]
\getbuffer[mp:tikz-cd]
\stopplacefigure
-The following example, shown in \in{figure} [fig:tikz-cd] and drawn here using
-the present \METAPOST\ \type {node} macros, is inspired from the TikZ CD
-(commutative diagrams) package. \footnote {The TikZ-CD package uses a totally
-different approach: the diagram is defined and laid|-|out as a table with
-decorations (arrows) running between cells.} The nodes are again given relative
-positions rather than being placed on a predefined path. The arrow labeled \quote
-{$(x,y)$} is drawn \typ {dashed withdots} and illustrates how the line gets
-broken, here \type {crossingunder} its centered label.
-
-\startparagraph [style=small]
- \typebuffer[mp:tikz-cd] [option=TEX]
-\stopparagraph
+We end this manual with two examples of more advanced commutative diagrams. The
+following example, shown in \in {Figure} [fig:tikz-cd], illustrates what in
+category theory is called a \emph {pullback}. It is inspired from an example
+given in the TikZ CD (commutative diagrams) package.
-% \doifmode {screen} {\page [yes]}
+The arrow labeled \quotation {$(x,y)$} is drawn \type {dashed withdots} and
+illustrates how the line gets broken, implicitly \type {crossingunder} its
+centered label.
-\in {Figure} [fig:tikz-cd2] is another \quotation{real|-|life} example, also
-inspired by TikZ-CD.
+\typebuffer[mp:tikz-cd] [option=TEX]
+
+The previous diagram was drawn using the \CONTEXT\ interface. Our final example,
+shown in \in {Figure} [fig:tikz-cd2], gives another \quotation {real|-|life}
+example of a categorical pullback, also inspired by TikZ-CD, but this time drawn
+through the \METAPOST\ interface and solving for positions.
\startbuffer[mp:tikz-cd2]
\startMPcode
@@ -1279,7 +1634,8 @@ inspired by TikZ-CD.
save A, B, C, D, E ;
pair A, B, C, D, E ;
A.i = 0 ; A = makenode(A.i,"\node{$\pi_1(U_1\cap U_2)$}") ;
- B.i = 1 ; B = makenode(B.i,"\node{$\pi_1(U_1)\ast_{\pi_1(U_1\cap U_2)}\pi_1(U_2)$}") ;
+ B.i = 1 ; B = makenode(B.i,
+ "\node{$\pi_1(U_1)\ast_{\pi_1(U_1\cap U_2)}\pi_1(U_2)$}") ;
C.i = 2 ; C = makenode(C.i,"\node{$\pi_1(X)$}") ;
D.i = 3 ; D = makenode(D.i,"\node{$\pi_1(U_2)$}") ;
E.i = 4 ; E = makenode(E.i,"\node{$\pi_1(U_1)$}") ;
@@ -1308,33 +1664,34 @@ inspired by TikZ-CD.
\getbuffer[mp:tikz-cd2]
\stopplacefigure
-\startparagraph [style=small]
- \typebuffer[mp:tikz-cd2] [option=TEX]
-\stopparagraph
-
-\placefloats
+\typebuffer[mp:tikz-cd2] [option=TEX]
\stopsubject
\startsubject [title=Conclusions]
-It was decided at the 2017 \CONTEXT\ Meeting in Maibach, Germany where this
-package was presented that there was little use of developing a purely \CONTEXT\
-interface. Rather, the \METAPOST\ package should be sufficiently accessible.
+There was initial consensus at the 2017 \CONTEXT\ Meeting in Maibach, Germany,
+where a version of this package was presented, that there was little use of
+developing a purely \CONTEXT\ interface. Rather, the \METAPOST\ package should be
+sufficiently accessible. Since then, however, we decided that the development of
+a derivative \CONTEXT\ interface implementing some basic functionality could
+indeed be useful for many users, although it will necessarily remain somewhat
+limited. Users are recommended to turn to the pure \METAPOST\ interface when more
+sophisticated functionality is needed.
\stopsubject
\startsubject [title=Acknowledgements]
This module was inspired by a request made by Idris Samawi Hamid to draw a
-natural transformation diagram (\in{Figure} [fig:natural]). The \METAPOST\
-macros that were developed then benefited from improvements suggested by Hans
-Hagen as well as inspiration provided by Taco Hoekwater.
+natural transformation diagram (\in{Figure} [fig:natural]). The \METAPOST\ macros
+that were developed then benefited from improvements suggested by Hans Hagen as
+well as inspiration provided by Taco Hoekwater.
The cover artwork one can recognize as coming under the hand of Hans Hagen that
he produced when I mentioned that I wanted to do something along these lines. It
fits very well into the style of manual covers that we distribute with \CONTEXT.
-This manual therefore has been co||written by Hans and Alan.
+This manual therefore has been co|-|written by Hans and Alan.
\stopsubject
diff --git a/metapost/context/base/mpiv/mp-node.mpiv b/metapost/context/base/mpiv/mp-node.mpiv
index fe6b40c64..79391220b 100644
--- a/metapost/context/base/mpiv/mp-node.mpiv
+++ b/metapost/context/base/mpiv/mp-node.mpiv
@@ -135,6 +135,8 @@ vardef mfun_node@#(suffix p)(expr i)(text t) =
fi
enddef ;
+newinternal node_loopback_yscale ; node_loopback_yscale := 1 ;
+
% returns a path
vardef fromtopaths@#(expr d)(suffix p)(expr f)(suffix q)(text s) =
@@ -159,7 +161,7 @@ vardef fromtopaths@#(expr d)(suffix p)(expr f)(suffix q)(text s) =
save deviation ;
deviation := if numeric d: d else: 0 fi ;
r1 = if (point 0 of r0) = (point length r0 of r0) :
- (fullcircle rotated 180
+ (fullcircle yscaled node_loopback_yscale rotated 180
if mfun_laboff@# <> origin :
rotated angle mfun_laboff@#
shifted .5mfun_laboff@#
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 55741083b..51b6ba7e2 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{2018.03.07 12:18}
+\newcontextversion{2018.03.10 14:52}
%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 f2fce340e..4d00fa41e 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{2018.03.07 12:18}
+\edef\contextversion{2018.03.10 14:52}
%D For those who want to use this:
diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii
index de3a8c84a..46b61c882 100644
--- a/tex/context/base/mkii/mult-ro.mkii
+++ b/tex/context/base/mkii/mult-ro.mkii
@@ -1077,6 +1077,7 @@
\setinterfaceconstant{preview}{previzualizare}
\setinterfaceconstant{previous}{precendent}
\setinterfaceconstant{previousnumber}{numarprecedent}
+\setinterfaceconstant{print}{print}
\setinterfaceconstant{printable}{tiparibil}
\setinterfaceconstant{process}{process}
\setinterfaceconstant{profile}{profile}
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index ae8748f0f..79be46772 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2018.03.07 12:18}
+\newcontextversion{2018.03.10 14:52}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 8cf5eff00..482a24192 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -42,7 +42,7 @@
%D has to match \type {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2018.03.07 12:18}
+\edef\contextversion{2018.03.10 14:52}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/grph-epd.lua b/tex/context/base/mkiv/grph-epd.lua
index a189a8706..7855ce891 100644
--- a/tex/context/base/mkiv/grph-epd.lua
+++ b/tex/context/base/mkiv/grph-epd.lua
@@ -11,6 +11,10 @@ local settings_to_hash = utilities.parsers.settings_to_hash
-- todo: page, name, file, url
+-- I have some experimental code for including comments and fields but it's
+-- unfinished and not included as it was just a proof of concept to get some idea
+-- about what is needed and possible. But the placeholders are here already.
+
local codeinjections = backends.codeinjections
local function mergegoodies(optionlist)
diff --git a/tex/context/base/mkiv/grph-inc.lua b/tex/context/base/mkiv/grph-inc.lua
index 71ee2f7ea..47eb7bbbb 100644
--- a/tex/context/base/mkiv/grph-inc.lua
+++ b/tex/context/base/mkiv/grph-inc.lua
@@ -1923,6 +1923,15 @@ function figures.getinfo(name,page)
end
end
+function figures.getpdfinfo(name,page,metadata)
+ -- not that useful but as we have it for detailed inclusion we can as
+ -- we expose it
+ if type(name) ~= "table" then
+ name = { name = name, page = page, metadata = metadata }
+ end
+ return codeinjections.getinfo(name)
+end
+
-- interfacing
implement {
diff --git a/tex/context/base/mkiv/lpdf-epa.lua b/tex/context/base/mkiv/lpdf-epa.lua
index d17ae5065..89b2c6e0e 100644
--- a/tex/context/base/mkiv/lpdf-epa.lua
+++ b/tex/context/base/mkiv/lpdf-epa.lua
@@ -14,6 +14,7 @@ local formatters = string.formatters
local abs = math.abs
local expandname = file.expandname
local allocate = utilities.storage.allocate
+local isfile = lfs.isfile
----- lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
@@ -21,6 +22,8 @@ local trace_links = false trackers.register("figures.links", function(v)
local trace_outlines = false trackers.register("figures.outliness", function(v) trace_outlines = v end)
local report_link = logs.reporter("backend","link")
+local report_comment = logs.reporter("backend","comment")
+local report_field = logs.reporter("backend","field")
local report_outline = logs.reporter("backend","outline")
local epdf = epdf
@@ -324,7 +327,7 @@ function codeinjections.getbookmarks(filename)
local document = nil
- if lfs.isfile(filename) then
+ if isfile(filename) then
document = loadpdffile(filename)
else
report_outline("unknown file %a",filename)
@@ -467,3 +470,82 @@ function codeinjections.mergebookmarks(specification)
end
end
end
+
+-- placeholders:
+
+function codeinjections.mergecomments(specification)
+ report_comment("unfinished experimental code, not used yet")
+end
+
+function codeinjections.mergefields(specification)
+ report_field("unfinished experimental code, not used yet")
+end
+
+-- A bit more than a placeholder but in the same perspective as
+-- inclusion of comments and fields:
+--
+-- getinfo{ filename = "tt.pdf", metadata = true }
+-- getinfo{ filename = "tt.pdf", page = 1, metadata = "xml" }
+-- getinfo("tt.pdf")
+
+function codeinjections.getinfo(specification)
+ if type(specification) == "string" then
+ specification = { filename = specification }
+ end
+ local filename = specification.filename
+ if type(filename) == "string" and isfile(filename) then
+ local pdffile = loadpdffile(filename)
+ if pdffile then
+ local pagenumber = specification.page or 1
+ local metadata = specification.metadata
+ local catalog = pdffile.Catalog
+ local info = pdffile.Info
+ local pages = pdffile.pages
+ local nofpages = pages.n
+ if metadata then
+ local m = catalog.Metadata
+ if m then
+ m = m()
+ if metadata == "xml" then
+ metadata = xml.convert(m)
+ else
+ metadata = m
+ end
+ else
+ metadata = nil
+ end
+ else
+ metadata = nil
+ end
+ if pagenumber > nofpages then
+ pagenumber = nofpages
+ end
+ local nobox = { 0, 0, 0, 0 }
+ local crop = nobox
+ local media = nobox
+ local page = pages[pagenumber]
+ if page then
+ crop = page.CropBox or nobox
+ media = page.MediaBox or crop or nobox
+ crop.n = nil -- nicer
+ media.n = nil -- nicer
+ end
+ local bbox = crop or media or nobox
+ return {
+ filename = filename,
+ pdfversion = tonumber(catalog.Version),
+ nofpages = nofpages,
+ title = info.Title,
+ creator = info.Creator,
+ producer = info.Producer,
+ creationdate = info.CreationDate,
+ modification = info.ModDate,
+ metadata = metadata,
+ width = bbox[4] - bbox[2],
+ height = bbox[3] - bbox[1],
+ cropbox = { crop[1], crop[2], crop[3], crop[4] }, -- we need access
+ mediabox = { media[1], media[2], media[3], media[4] } , -- we need access
+ }
+ end
+ end
+end
diff --git a/tex/context/base/mkiv/spac-ver.lua b/tex/context/base/mkiv/spac-ver.lua
index 3d263dafd..288630a5d 100644
--- a/tex/context/base/mkiv/spac-ver.lua
+++ b/tex/context/base/mkiv/spac-ver.lua
@@ -195,6 +195,8 @@ local belowdisplayskip_code = skipcodes.belowdisplayskip
local abovedisplayshortskip_code = skipcodes.abovedisplayshortskip
local belowdisplayshortskip_code = skipcodes.belowdisplayshortskip
+local properties = nodes.properties.data
+
local vspacing = builders.vspacing or { }
builders.vspacing = vspacing
@@ -699,45 +701,43 @@ local function snap_topskip(current,method)
return w, 0
end
-do
-
- local categories = allocate {
- [0] = 'discard',
- [1] = 'largest',
- [2] = 'force' ,
- [3] = 'penalty',
- [4] = 'add' ,
- [5] = 'disable',
- [6] = 'nowhite',
- [7] = 'goback',
- [8] = 'together', -- not used (?)
- [9] = 'overlay',
- [10] = 'notopskip',
- }
+local categories = {
+ [0] = "discard",
+ [1] = "largest",
+ [2] = "force",
+ [3] = "penalty",
+ [4] = "add",
+ [5] = "disable",
+ [6] = "nowhite",
+ [7] = "goback",
+ [8] = "packed",
+ [9] = "overlay",
+ [10] = "enable",
+ [11] = "notopskip",
+}
- vspacing.categories = categories
+categories = allocate(table.swapped(categories,categories))
+vspacing.categories = categories
- function vspacing.tocategories(str)
- local t = { }
- for s in gmatch(str,"[^, ]") do -- use lpeg instead
- local n = tonumber(s)
- if n then
- t[categories[n]] = true
- else
- t[b] = true
- end
- end
- return t
- end
-
- function vspacing.tocategory(str) -- can be optimized
- if type(str) == "string" then
- return set.tonumber(vspacing.tocategories(str))
+function vspacing.tocategories(str)
+ local t = { }
+ for s in gmatch(str,"[^, ]") do -- use lpeg instead
+ local n = tonumber(s)
+ if n then
+ t[categories[n]] = true
else
- return set.tonumber({ [categories[str]] = true })
+ t[b] = true
end
end
+ return t
+end
+function vspacing.tocategory(str) -- can be optimized
+ if type(str) == "string" then
+ return set.tonumber(vspacing.tocategories(str))
+ else
+ return set.tonumber({ [categories[str]] = true })
+ end
end
vspacingdata.map = vspacingdata.map or { } -- allocate ?
@@ -783,6 +783,7 @@ do -- todo: interface.variables and properties
local ctx_flushblankhandling = context.flushblankhandling
local ctx_addpredefinedblankskip = context.addpredefinedblankskip
local ctx_addaskedblankskip = context.addaskedblankskip
+ local ctx_setblankpacked = context.setblankpacked
local ctx_pushlogger = context.pushlogger
local ctx_startblankhandling = context.startblankhandling
@@ -791,6 +792,8 @@ do -- todo: interface.variables and properties
local pattern = nil
+ local packed = categories.packed
+
local function handler(amount, keyword, detail)
if not keyword then
report_vspacing("unknown directive %a",s)
@@ -804,7 +807,9 @@ do -- todo: interface.variables and properties
ctx_flexibleblankskip()
elseif keyword == k_category then
local category = tonumber(detail)
- if category then
+ if category == packed then
+ ctx_setblankpacked()
+ elseif category then
ctx_setblankcategory(category)
ctx_flushblankhandling()
end
@@ -961,14 +966,14 @@ function vspacing.snapbox(n,how)
end
else
local h, d, ch, cd, lines, extra = snap_hlist("box",box,sv,ht,dp)
-setprop(box,"snapper",{
- ht = h,
- dp = d,
- ch = ch,
- cd = cd,
- extra = extra,
- current = current,
-})
+ setprop(box,"snapper",{
+ ht = h,
+ dp = d,
+ ch = ch,
+ cd = cd,
+ extra = extra,
+ current = current,
+ })
setwhd(box,wd,ch,cd)
if trace_vsnapping then
report_snapper("box list snapped from (%p,%p) to (%p,%p) using method %a (%s) for %a (%s lines): %s",
@@ -993,702 +998,702 @@ end
-- We can register and copy the rule instead.
-local w, h, d = 0, 0, 0
------ w, h, d = 100*65536, 65536, 65536
+do
-local function forced_skip(head,current,width,where,trace) -- looks old ... we have other tricks now
- if head == current then
- if getsubtype(head) == baselineskip_code then
- width = width - getwidth(head)
+ local w, h, d = 0, 0, 0
+ ----- w, h, d = 100*65536, 65536, 65536
+
+ local function forced_skip(head,current,width,where,trace) -- looks old ... we have other tricks now
+ if head == current then
+ if getsubtype(head) == baselineskip_code then
+ width = width - getwidth(head)
+ end
end
+ if width == 0 then
+ -- do nothing
+ elseif where == "after" then
+ head, current = insert_node_after(head,current,new_rule(w,h,d))
+ head, current = insert_node_after(head,current,new_kern(width))
+ head, current = insert_node_after(head,current,new_rule(w,h,d))
+ else
+ local c = current
+ head, current = insert_node_before(head,current,new_rule(w,h,d))
+ head, current = insert_node_before(head,current,new_kern(width))
+ head, current = insert_node_before(head,current,new_rule(w,h,d))
+ current = c
+ end
+ if trace then
+ report_vspacing("inserting forced skip of %p",width)
+ end
+ return head, current
end
- if width == 0 then
- -- do nothing
- elseif where == "after" then
- head, current = insert_node_after(head,current,new_rule(w,h,d))
- head, current = insert_node_after(head,current,new_kern(width))
- head, current = insert_node_after(head,current,new_rule(w,h,d))
- else
- local c = current
- head, current = insert_node_before(head,current,new_rule(w,h,d))
- head, current = insert_node_before(head,current,new_kern(width))
- head, current = insert_node_before(head,current,new_rule(w,h,d))
- current = c
- end
- if trace then
- report_vspacing("inserting forced skip of %p",width)
- end
- return head, current
-end
-
--- penalty only works well when before skip
-local discard = 0
-local largest = 1
-local force = 2
-local penalty = 3
-local add = 4
-local disable = 5
-local nowhite = 6
-local goback = 7
-local together = 8 -- not used (?)
-local overlay = 9
-local enable = 10
+ -- penalty only works well when before skip
--- [whatsits][hlist][glue][glue][penalty]
+ local discard = categories.discard
+ local largest = categories.largest
+ local force = categories.force
+ local penalty = categories.penalty
+ local add = categories.add
+ local disable = categories.disable
+ local nowhite = categories.nowhite
+ local goback = categories.goback
+ local packed = categories.packed
+ local overlay = categories.overlay
+ local enable = categories.enable
+ local notopskip = categories.notopskip
-local special_penalty_min = 32250
-local special_penalty_max = 35000
-local special_penalty_xxx = 0
+ -- [whatsits][hlist][glue][glue][penalty]
--- this is rather messy and complex: we want to make sure that successive
--- header don't break but also make sure that we have at least a decent
--- break when we have succesive ones (often when testing)
+ local special_penalty_min = 32250
+ local special_penalty_max = 35000
+ local special_penalty_xxx = 0
--- todo: mark headers as such so that we can recognize them
+ -- this is rather messy and complex: we want to make sure that successive
+ -- header don't break but also make sure that we have at least a decent
+ -- break when we have succesive ones (often when testing)
-local specialmethods = { }
-local specialmethod = 1
+ -- todo: mark headers as such so that we can recognize them
-local properties = nodes.properties.data
+ local specialmethods = { }
+ local specialmethod = 1
-specialmethods[1] = function(pagehead,pagetail,start,penalty)
- --
- if not pagehead or penalty < special_penalty_min or penalty > special_penalty_max then
- return
- end
- local current = pagetail
- --
- -- nodes.showsimplelist(pagehead,0)
- --
- if trace_specials then
- report_specials("checking penalty %a",penalty)
- end
- while current do
- local id = getid(current)
- if id == penalty_code then
- local p = properties[current]
- if p then
- local p = p.special_penalty
- if not p then
- if trace_specials then
- report_specials(" regular penalty, continue")
- end
- elseif p == penalty then
- if trace_specials then
- report_specials(" context penalty %a, same level, overloading",p)
- end
- return special_penalty_xxx
- elseif p > special_penalty_min and p < special_penalty_max then
- if penalty < p then
+ specialmethods[1] = function(pagehead,pagetail,start,penalty)
+ --
+ if not pagehead or penalty < special_penalty_min or penalty > special_penalty_max then
+ return
+ end
+ local current = pagetail
+ --
+ -- nodes.showsimplelist(pagehead,0)
+ --
+ if trace_specials then
+ report_specials("checking penalty %a",penalty)
+ end
+ while current do
+ local id = getid(current)
+ if id == penalty_code then
+ local p = properties[current]
+ if p then
+ local p = p.special_penalty
+ if not p then
if trace_specials then
- report_specials(" context penalty %a, lower level, overloading",p)
+ report_specials(" regular penalty, continue")
end
- return special_penalty_xxx
- else
+ elseif p == penalty then
if trace_specials then
- report_specials(" context penalty %a, higher level, quitting",p)
+ report_specials(" context penalty %a, same level, overloading",p)
end
- return
- end
- elseif trace_specials then
- report_specials(" context penalty %a, higher level, continue",p)
- end
- else
- local p = getpenalty(current)
- if p < 10000 then
- -- assume some other mechanism kicks in so we seem to have content
- if trace_specials then
- report_specials(" regular penalty %a, quitting",p)
+ return special_penalty_xxx
+ elseif p > special_penalty_min and p < special_penalty_max then
+ if penalty < p then
+ if trace_specials then
+ report_specials(" context penalty %a, lower level, overloading",p)
+ end
+ return special_penalty_xxx
+ else
+ if trace_specials then
+ report_specials(" context penalty %a, higher level, quitting",p)
+ end
+ return
+ end
+ elseif trace_specials then
+ report_specials(" context penalty %a, higher level, continue",p)
end
- break
else
- if trace_specials then
- report_specials(" regular penalty %a, continue",p)
+ local p = getpenalty(current)
+ if p < 10000 then
+ -- assume some other mechanism kicks in so we seem to have content
+ if trace_specials then
+ report_specials(" regular penalty %a, quitting",p)
+ end
+ break
+ else
+ if trace_specials then
+ report_specials(" regular penalty %a, continue",p)
+ end
end
end
end
+ current = getprev(current)
end
- current = getprev(current)
- end
- -- none found, so no reson to be special
- if trace_specials then
- if pagetail then
- report_specials(" context penalty, discarding, nothing special")
- else
- report_specials(" context penalty, discarding, nothing preceding")
+ -- none found, so no reson to be special
+ if trace_specials then
+ if pagetail then
+ report_specials(" context penalty, discarding, nothing special")
+ else
+ report_specials(" context penalty, discarding, nothing preceding")
+ end
end
+ return special_penalty_xxx
end
- return special_penalty_xxx
-end
--- specialmethods[2] : always put something before and use that as to-be-changed
---
--- we could inject a vadjust to force a recalculation .. a mess
---
--- So, the next is far from robust and okay but for the moment this overlaying
--- has to do. Always test this with the examples in spac-ver.mkvi!
-
-local function check_experimental_overlay(head,current)
- local p = nil
- local c = current
- local n = nil
- local function overlay(p,n,mvl)
- local p_wd, p_ht, p_dp = getwhd(p)
- local n_wd, n_ht, n_dp = getwhd(n)
- local skips = 0
- --
- -- We deal with this at the tex end .. we don't see spacing .. enabling this code
- -- is probably harmless but then we need to test it.
- --
- -- we could calculate this before we call
- --
- -- problem: prev list and next list can be unconnected
- --
- local c = getnext(p)
- local l = c
- while c and c ~= n do
- local id = getid(c)
- if id == glue_code then
- skips = skips + getwidth(c)
- elseif id == kern_code then
- skips = skips + getkern(c)
+ -- This will be replaced after 0.80+ when we have a more robust look-back and
+ -- can look at the bigger picture.
+
+ -- todo: look back and when a special is there before a list is seen penalty keep ut
+
+ -- we now look back a lot, way too often
+
+ -- userskip
+ -- lineskip
+ -- baselineskip
+ -- parskip
+ -- abovedisplayskip
+ -- belowdisplayskip
+ -- abovedisplayshortskip
+ -- belowdisplayshortskip
+ -- topskip
+ -- splittopskip
+
+ -- we could inject a vadjust to force a recalculation .. a mess
+ --
+ -- So, the next is far from robust and okay but for the moment this overlaying
+ -- has to do. Always test this with the examples in spac-ver.mkvi!
+
+ local function check_experimental_overlay(head,current)
+ local p = nil
+ local c = current
+ local n = nil
+ local function overlay(p,n,mvl)
+ local p_wd, p_ht, p_dp = getwhd(p)
+ local n_wd, n_ht, n_dp = getwhd(n)
+ local skips = 0
+ --
+ -- We deal with this at the tex end .. we don't see spacing .. enabling this code
+ -- is probably harmless but then we need to test it.
+ --
+ -- we could calculate this before we call
+ --
+ -- problem: prev list and next list can be unconnected
+ --
+ local c = getnext(p)
+ local l = c
+ while c and c ~= n do
+ local id = getid(c)
+ if id == glue_code then
+ skips = skips + getwidth(c)
+ elseif id == kern_code then
+ skips = skips + getkern(c)
+ end
+ l = c
+ c = getnext(c)
end
- l = c
- c = getnext(c)
- end
- local c = getprev(n)
- while c and c ~= n and c ~= l do
- local id = getid(c)
- if id == glue_code then
- skips = skips + getwidth(c)
- elseif id == kern_code then
- skips = skips + getkern(c)
+ local c = getprev(n)
+ while c and c ~= n and c ~= l do
+ local id = getid(c)
+ if id == glue_code then
+ skips = skips + getwidth(c)
+ elseif id == kern_code then
+ skips = skips + getkern(c)
+ end
+ c = getprev(c)
end
- c = getprev(c)
- end
- --
- local delta = n_ht + skips + p_dp
- texsetdimen("global","d_spac_overlay",-delta) -- for tracing
- -- we should adapt pagetotal ! (need a hook for that) .. now we have the wrong pagebreak
- local k = new_kern(-delta)
- head = insert_node_before(head,n,k)
- if n_ht > p_ht then
- local k = new_kern(n_ht-p_ht)
- head = insert_node_before(head,p,k)
- end
- if trace_vspacing then
- report_vspacing("overlaying, prev height: %p, prev depth: %p, next height: %p, skips: %p, move up: %p",p_ht,p_dp,n_ht,skips,delta)
+ --
+ local delta = n_ht + skips + p_dp
+ texsetdimen("global","d_spac_overlay",-delta) -- for tracing
+ -- we should adapt pagetotal ! (need a hook for that) .. now we have the wrong pagebreak
+ local k = new_kern(-delta)
+ head = insert_node_before(head,n,k)
+ if n_ht > p_ht then
+ local k = new_kern(n_ht-p_ht)
+ head = insert_node_before(head,p,k)
+ end
+ if trace_vspacing then
+ report_vspacing("overlaying, prev height: %p, prev depth: %p, next height: %p, skips: %p, move up: %p",p_ht,p_dp,n_ht,skips,delta)
+ end
+ return remove_node(head,current,true)
end
- return remove_node(head,current,true)
- end
- -- goto next line
- while c do
- local id = getid(c)
- if id == glue_code or id == penalty_code or id == kern_code then
- -- skip (actually, remove)
- c = getnext(c)
- elseif id == hlist_code then
- n = c
- break
- else
- break
- end
- end
- if n then
- -- we have a next line, goto prev line
- c = current
+ -- goto next line
while c do
local id = getid(c)
- if id == glue_code or id == penalty_code then -- kern ?
- c = getprev(c)
+ if id == glue_code or id == penalty_code or id == kern_code then
+ -- skip (actually, remove)
+ c = getnext(c)
elseif id == hlist_code then
- p = c
+ n = c
break
else
break
end
end
- if not p then
- if a_snapmethod == a_snapvbox then
- -- quit, we're not on the mvl
- else
- -- inefficient when we're at the end of a page
- local c = tonut(texlists.page_head)
- while c and c ~= n do
- local id = getid(c)
- if id == hlist_code then
- p = c
- end
- c = getnext(c)
+ if n then
+ -- we have a next line, goto prev line
+ c = current
+ while c do
+ local id = getid(c)
+ if id == glue_code or id == penalty_code then -- kern ?
+ c = getprev(c)
+ elseif id == hlist_code then
+ p = c
+ break
+ else
+ break
end
- if p and p ~= n then
- return overlay(p,n,true)
+ end
+ if not p then
+ if a_snapmethod == a_snapvbox then
+ -- quit, we're not on the mvl
+ else
+ -- inefficient when we're at the end of a page
+ local c = tonut(texlists.page_head)
+ while c and c ~= n do
+ local id = getid(c)
+ if id == hlist_code then
+ p = c
+ end
+ c = getnext(c)
+ end
+ if p and p ~= n then
+ return overlay(p,n,true)
+ end
end
+ elseif p ~= n then
+ return overlay(p,n,false)
end
- elseif p ~= n then
- return overlay(p,n,false)
end
+ -- in fact, we could try again later ... so then no remove (a few tries)
+ return remove_node(head, current, true)
end
- -- in fact, we could try again later ... so then no remove (a few tries)
- return remove_node(head, current, true)
-end
-
--- This will be replaced after 0.80+ when we have a more robust look-back and
--- can look at the bigger picture.
-
--- todo: look back and when a special is there before a list is seen penalty keep ut
--- we now look back a lot, way too often
-
--- userskip
--- lineskip
--- baselineskip
--- parskip
--- abovedisplayskip
--- belowdisplayskip
--- abovedisplayshortskip
--- belowdisplayshortskip
--- topskip
--- splittopskip
-
-local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also pass tail
- if trace then
- reset_tracing(head)
- end
- local current, oldhead = head, head
- local glue_order, glue_data, force_glue = 0, nil, false
- local penalty_order, penalty_data, natural_penalty, special_penalty = 0, nil, nil, nil
- local parskip, ignore_parskip, ignore_following, ignore_whitespace, keep_together = nil, false, false, false, false
- local lastsnap = nil
- --
- -- todo: keep_together: between headers
- --
- local pagehead = nil
- local pagetail = nil
-
- local function getpagelist()
- if not pagehead then
- pagehead = texlists.page_head
- if pagehead then
- pagehead = tonut(pagehead)
- pagetail = find_node_tail(pagehead) -- no texlists.page_tail yet-- no texlists.page_tail yet
- end
- end
- end
- --
- local function compensate(n)
- local g = 0
- while n and getid(n) == glue_code do
- g = g + getwidth(n)
- n = getnext(n)
+ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also pass tail
+ if trace then
+ reset_tracing(head)
end
- if n then
- local p = getprop(n,"snapper")
- if p then
- local extra = p.extra
- if extra and extra < 0 then -- hm, extra can be unset ... needs checking
- local h = p.ch -- getheight(n)
- -- maybe an extra check
- -- if h - extra < g then
- setheight(n,h-2*extra)
- p.extra = 0
- if trace_vsnapping then
- report_snapper("removed extra space at top: %p",extra)
- end
- -- end
+ local current, oldhead = head, head
+ local glue_order, glue_data, force_glue = 0, nil, false
+ local penalty_order, penalty_data, natural_penalty, special_penalty = 0, nil, nil, nil
+ local parskip, ignore_parskip, ignore_following, ignore_whitespace, keep_together = nil, false, false, false, false
+ local lastsnap = nil
+ --
+ -- todo: keep_together: between headers
+ --
+ local pagehead = nil
+ local pagetail = nil
+
+ local function getpagelist()
+ if not pagehead then
+ pagehead = texlists.page_head
+ if pagehead then
+ pagehead = tonut(pagehead)
+ pagetail = find_node_tail(pagehead) -- no texlists.page_tail yet-- no texlists.page_tail yet
end
end
- return n
end
- end
- --
- local function removetopsnap()
- getpagelist()
- if pagehead then
- local n = pagehead and compensate(pagehead)
- if n and n ~= pagetail then
- local p = getprop(pagetail,"snapper")
+ --
+ local function compensate(n)
+ local g = 0
+ while n and getid(n) == glue_code do
+ g = g + getwidth(n)
+ n = getnext(n)
+ end
+ if n then
+ local p = getprop(n,"snapper")
if p then
- local e = p.extra
- if e and e < 0 then
- local t = texget("pagetotal")
- if t > 0 then
- local g = texget("pagegoal") -- 1073741823 is signal
- local d = g - t
- if d < -e then
- local penalty = new_penalty(1000000)
- setlink(penalty,head)
- head = penalty
- report_snapper("force pagebreak due to extra space at bottom: %p",e)
+ local extra = p.extra
+ if extra and extra < 0 then -- hm, extra can be unset ... needs checking
+ local h = p.ch -- getheight(n)
+ -- maybe an extra check
+ -- if h - extra < g then
+ setheight(n,h-2*extra)
+ p.extra = 0
+ if trace_vsnapping then
+ report_snapper("removed extra space at top: %p",extra)
end
- end
+ -- end
end
end
+ return n
end
- elseif head then
- compensate(head)
end
- end
- --
- local function getavailable()
- getpagelist()
- if pagehead then
- local t = texget("pagetotal")
- if t > 0 then
- local g = texget("pagegoal")
- return g - t
+ --
+ local function removetopsnap()
+ getpagelist()
+ if pagehead then
+ local n = pagehead and compensate(pagehead)
+ if n and n ~= pagetail then
+ local p = getprop(pagetail,"snapper")
+ if p then
+ local e = p.extra
+ if e and e < 0 then
+ local t = texget("pagetotal")
+ if t > 0 then
+ local g = texget("pagegoal") -- 1073741823 is signal
+ local d = g - t
+ if d < -e then
+ local penalty = new_penalty(1000000)
+ setlink(penalty,head)
+ head = penalty
+ report_snapper("force pagebreak due to extra space at bottom: %p",e)
+ end
+ end
+ end
+ end
+ end
+ elseif head then
+ compensate(head)
end
end
- return false
- end
- --
- local function flush(why)
- if penalty_data then
- local p = new_penalty(penalty_data)
- if trace then
- trace_done("flushed due to " .. why,p)
- end
- if penalty_data >= 10000 then -- or whatever threshold?
- local prev = getprev(current)
- if getid(prev) == glue_code then -- maybe go back more, or maybe even push back before any glue
- -- tricky case: spacing/grid-007.tex: glue penalty glue
- head = insert_node_before(head,prev,p)
- else
- head = insert_node_before(head,current,p)
+ --
+ local function getavailable()
+ getpagelist()
+ if pagehead then
+ local t = texget("pagetotal")
+ if t > 0 then
+ local g = texget("pagegoal")
+ return g - t
end
- else
- head = insert_node_before(head,current,p)
- end
- -- if penalty_data > special_penalty_min and penalty_data < special_penalty_max then
- local props = properties[p]
- if props then
- props.special_penalty = special_penalty or penalty_data
- else
- properties[p] = {
- special_penalty = special_penalty or penalty_data
- }
end
- -- end
+ return false
end
- if glue_data then
- if force_glue then
+ --
+ local function flush(why)
+ if penalty_data then
+ local p = new_penalty(penalty_data)
if trace then
- trace_done("flushed due to forced " .. why,glue_data)
+ trace_done("flushed due to " .. why,p)
end
- head = forced_skip(head,current,getwidth(glue_data,width),"before",trace)
- flush_node(glue_data)
- else
- local width, stretch, shrink = getglue(glue_data)
- if width ~= 0 then
- if trace then
- trace_done("flushed due to non zero " .. why,glue_data)
+ if penalty_data >= 10000 then -- or whatever threshold?
+ local prev = getprev(current)
+ if getid(prev) == glue_code then -- maybe go back more, or maybe even push back before any glue
+ -- tricky case: spacing/grid-007.tex: glue penalty glue
+ head = insert_node_before(head,prev,p)
+ else
+ head = insert_node_before(head,current,p)
end
- head = insert_node_before(head,current,glue_data)
- elseif stretch ~= 0 or shrink ~= 0 then
+ else
+ head = insert_node_before(head,current,p)
+ end
+ -- if penalty_data > special_penalty_min and penalty_data < special_penalty_max then
+ local props = properties[p]
+ if props then
+ props.special_penalty = special_penalty or penalty_data
+ else
+ properties[p] = {
+ special_penalty = special_penalty or penalty_data
+ }
+ end
+ -- end
+ end
+ if glue_data then
+ if force_glue then
if trace then
- trace_done("flushed due to stretch/shrink in" .. why,glue_data)
+ trace_done("flushed due to forced " .. why,glue_data)
end
- head = insert_node_before(head,current,glue_data)
- else
- -- report_vspacing("needs checking (%s): %p",skipcodes[getsubtype(glue_data)],w)
+ head = forced_skip(head,current,getwidth(glue_data,width),"before",trace)
flush_node(glue_data)
+ else
+ local width, stretch, shrink = getglue(glue_data)
+ if width ~= 0 then
+ if trace then
+ trace_done("flushed due to non zero " .. why,glue_data)
+ end
+ head = insert_node_before(head,current,glue_data)
+ elseif stretch ~= 0 or shrink ~= 0 then
+ if trace then
+ trace_done("flushed due to stretch/shrink in" .. why,glue_data)
+ end
+ head = insert_node_before(head,current,glue_data)
+ else
+ -- report_vspacing("needs checking (%s): %p",skipcodes[getsubtype(glue_data)],w)
+ flush_node(glue_data)
+ end
end
end
- end
+ if trace then
+ trace_node(current)
+ end
+ glue_order, glue_data, force_glue = 0, nil, false
+ penalty_order, penalty_data, natural_penalty = 0, nil, nil
+ parskip, ignore_parskip, ignore_following, ignore_whitespace = nil, false, false, false
+ end
+ --
+ if trace_vsnapping then
+ report_snapper("global ht/dp = %p/%p, local ht/dp = %p/%p",
+ texgetdimen("globalbodyfontstrutheight"),
+ texgetdimen("globalbodyfontstrutdepth"),
+ texgetdimen("bodyfontstrutheight"),
+ texgetdimen("bodyfontstrutdepth")
+ )
+ end
if trace then
- trace_node(current)
+ trace_info("start analyzing",where,what)
end
- glue_order, glue_data, force_glue = 0, nil, false
- penalty_order, penalty_data, natural_penalty = 0, nil, nil
- parskip, ignore_parskip, ignore_following, ignore_whitespace = nil, false, false, false
- end
- --
- if trace_vsnapping then
- report_snapper("global ht/dp = %p/%p, local ht/dp = %p/%p",
- texgetdimen("globalbodyfontstrutheight"),
- texgetdimen("globalbodyfontstrutdepth"),
- texgetdimen("bodyfontstrutheight"),
- texgetdimen("bodyfontstrutdepth")
- )
- end
- if trace then
- trace_info("start analyzing",where,what)
- end
- if snap and where == "page" then
- removetopsnap()
- end
- while current do
- local id = getid(current)
- if id == hlist_code or id == vlist_code then
- -- needs checking, why so many calls
- if snap then
- lastsnap = nil
- local list = getlist(current)
- local s = getattr(current,a_snapmethod)
- if not s then
- -- if trace_vsnapping then
- -- report_snapper("mvl list not snapped")
- -- end
- elseif s == 0 then
- if trace_vsnapping then
- report_snapper("mvl %a not snapped, already done: %s",nodecodes[id],listtoutf(list))
- end
- else
- local sv = snapmethods[s]
- if sv then
- -- check if already snapped
- local done = list and already_done(id,list,a_snapmethod)
- if done then
- -- assume that the box is already snapped
- if trace_vsnapping then
- local w, h, d = getwhd(current)
- report_snapper("mvl list already snapped at (%p,%p): %s",h,d,listtoutf(list))
- end
- else
- local h, d, ch, cd, lines, extra = snap_hlist("mvl",current,sv,false,false)
- lastsnap = {
- ht = h,
- dp = d,
- ch = ch,
- cd = cd,
- extra = extra,
- current = current,
- }
- setprop(current,"snapper",lastsnap)
- if trace_vsnapping then
- report_snapper("mvl %a snapped from (%p,%p) to (%p,%p) using method %a (%s) for %a (%s lines): %s",
- nodecodes[id],h,d,ch,cd,sv.name,sv.specification,where,lines,listtoutf(list))
+ if snap and where == "page" then
+ removetopsnap()
+ end
+ while current do
+ local id = getid(current)
+ if id == hlist_code or id == vlist_code then
+ -- needs checking, why so many calls
+ if snap then
+ lastsnap = nil
+ local list = getlist(current)
+ local s = getattr(current,a_snapmethod)
+ if not s then
+ -- if trace_vsnapping then
+ -- report_snapper("mvl list not snapped")
+ -- end
+ elseif s == 0 then
+ if trace_vsnapping then
+ report_snapper("mvl %a not snapped, already done: %s",nodecodes[id],listtoutf(list))
+ end
+ else
+ local sv = snapmethods[s]
+ if sv then
+ -- check if already snapped
+ local done = list and already_done(id,list,a_snapmethod)
+ if done then
+ -- assume that the box is already snapped
+ if trace_vsnapping then
+ local w, h, d = getwhd(current)
+ report_snapper("mvl list already snapped at (%p,%p): %s",h,d,listtoutf(list))
+ end
+ else
+ local h, d, ch, cd, lines, extra = snap_hlist("mvl",current,sv,false,false)
+ lastsnap = {
+ ht = h,
+ dp = d,
+ ch = ch,
+ cd = cd,
+ extra = extra,
+ current = current,
+ }
+ setprop(current,"snapper",lastsnap)
+ if trace_vsnapping then
+ report_snapper("mvl %a snapped from (%p,%p) to (%p,%p) using method %a (%s) for %a (%s lines): %s",
+ nodecodes[id],h,d,ch,cd,sv.name,sv.specification,where,lines,listtoutf(list))
+ end
end
+ elseif trace_vsnapping then
+ report_snapper("mvl %a not snapped due to unknown snap specification: %s",nodecodes[id],listtoutf(list))
end
- elseif trace_vsnapping then
- report_snapper("mvl %a not snapped due to unknown snap specification: %s",nodecodes[id],listtoutf(list))
+ setattr(current,a_snapmethod,0)
end
- setattr(current,a_snapmethod,0)
+ else
+ --
end
- else
- --
- end
- -- tex.prevdepth = 0
- flush("list")
- current = getnext(current)
- elseif id == penalty_code then
- -- natural_penalty = getpenalty(current)
- -- if trace then
- -- trace_done("removed penalty",current)
- -- end
- -- head, current = remove_node(head, current, true)
- current = getnext(current)
- elseif id == kern_code then
- if snap and trace_vsnapping and getkern(current) ~= 0 then
- report_snapper("kern of %p kept",getkern(current))
- end
- flush("kern")
- current = getnext(current)
- elseif id == glue_code then
- local subtype = getsubtype(current)
- if subtype == userskip_code then
- local sc = getattr(current,a_skipcategory) -- has no default, no unset (yet)
- local so = getattr(current,a_skiporder) or 1 -- has 1 default, no unset (yet)
- local sp = getattr(current,a_skippenalty) -- has no default, no unset (yet)
- if sp and sc == penalty then
- if where == "page" then
- getpagelist()
- local p = specialmethods[specialmethod](pagehead,pagetail,current,sp)
- if p then
- -- todo: other tracer
- --
- -- if trace then
- -- trace_skip("previous special penalty %a is changed to %a using method %a",sp,p,specialmethod)
- -- end
- special_penalty = sp
- sp = p
+ -- tex.prevdepth = 0
+ flush("list")
+ current = getnext(current)
+ elseif id == penalty_code then
+ -- natural_penalty = getpenalty(current)
+ -- if trace then
+ -- trace_done("removed penalty",current)
+ -- end
+ -- head, current = remove_node(head, current, true)
+ current = getnext(current)
+ elseif id == kern_code then
+ if snap and trace_vsnapping and getkern(current) ~= 0 then
+ report_snapper("kern of %p kept",getkern(current))
+ end
+ flush("kern")
+ current = getnext(current)
+ elseif id == glue_code then
+ local subtype = getsubtype(current)
+ if subtype == userskip_code then
+ local sc = getattr(current,a_skipcategory) -- has no default, no unset (yet)
+ local so = getattr(current,a_skiporder) or 1 -- has 1 default, no unset (yet)
+ local sp = getattr(current,a_skippenalty) -- has no default, no unset (yet)
+ if sp and sc == penalty then
+ if where == "page" then
+ getpagelist()
+ local p = specialmethods[specialmethod](pagehead,pagetail,current,sp)
+ if p then
+ -- todo: other tracer
+ --
+ -- if trace then
+ -- trace_skip("previous special penalty %a is changed to %a using method %a",sp,p,specialmethod)
+ -- end
+ special_penalty = sp
+ sp = p
+ end
end
- end
- if not penalty_data then
- penalty_data = sp
- elseif penalty_order < so then
- penalty_order, penalty_data = so, sp
- elseif penalty_order == so and sp > penalty_data then
- penalty_data = sp
- end
- if trace then
- trace_skip("penalty in skip",sc,so,sp,current)
- end
- head, current = remove_node(head, current, true)
- elseif not sc then -- if not sc then
- if glue_data then
- if trace then
- trace_done("flush",glue_data)
+ if not penalty_data then
+ penalty_data = sp
+ elseif penalty_order < so then
+ penalty_order, penalty_data = so, sp
+ elseif penalty_order == so and sp > penalty_data then
+ penalty_data = sp
end
- head = insert_node_before(head,current,glue_data)
if trace then
- trace_natural("natural",current)
+ trace_skip("penalty in skip",sc,so,sp,current)
end
- current = getnext(current)
- else
- -- not look back across head
- -- todo: prev can be whatsit (latelua)
- local previous = getprev(current)
- if previous and getid(previous) == glue_code and getsubtype(previous) == userskip_code then
- local pwidth, pstretch, pshrink, pstretch_order, pshrink_order = getglue(previous)
- local cwidth, cstretch, cshrink, cstretch_order, cshrink_order = getglue(current)
- if pstretch_order == 0 and pshrink_order == 0 and cstretch_order == 0 and cshrink_order == 0 then
- setglue(previous,pwidth + cwidth, pstretch + cstretch, pshrink + cshrink)
- if trace then
- trace_natural("removed",current)
- end
- head, current = remove_node(head, current, true)
- if trace then
- trace_natural("collapsed",previous)
+ head, current = remove_node(head, current, true)
+ elseif not sc then -- if not sc then
+ if glue_data then
+ if trace then
+ trace_done("flush",glue_data)
+ end
+ head = insert_node_before(head,current,glue_data)
+ if trace then
+ trace_natural("natural",current)
+ end
+ current = getnext(current)
+ else
+ -- not look back across head
+ -- todo: prev can be whatsit (latelua)
+ local previous = getprev(current)
+ if previous and getid(previous) == glue_code and getsubtype(previous) == userskip_code then
+ local pwidth, pstretch, pshrink, pstretch_order, pshrink_order = getglue(previous)
+ local cwidth, cstretch, cshrink, cstretch_order, cshrink_order = getglue(current)
+ if pstretch_order == 0 and pshrink_order == 0 and cstretch_order == 0 and cshrink_order == 0 then
+ setglue(previous,pwidth + cwidth, pstretch + cstretch, pshrink + cshrink)
+ if trace then
+ trace_natural("removed",current)
+ end
+ head, current = remove_node(head, current, true)
+ if trace then
+ trace_natural("collapsed",previous)
+ end
+ else
+ if trace then
+ trace_natural("filler",current)
+ end
+ current = getnext(current)
end
else
if trace then
- trace_natural("filler",current)
+ trace_natural("natural (no prev)",current)
end
current = getnext(current)
end
- else
+ end
+ glue_order, glue_data = 0, nil
+ elseif sc == disable or sc == enable then
+ local next = getnext(current)
+ if next then
+ ignore_following = sc == disable
if trace then
- trace_natural("natural (no prev)",current)
+ trace_skip(sc == disable and "disable" or "enable",sc,so,sp,current)
end
- current = getnext(current)
+ head, current = remove_node(head, current, true)
+ else
+ current = next
end
- end
- glue_order, glue_data = 0, nil
- elseif sc == disable or sc == enable then
- local next = getnext(current)
- if next then
- ignore_following = sc == disable
+ elseif sc == packed then
if trace then
- trace_skip(sc == disable and "disable" or "enable",sc,so,sp,current)
+ trace_skip("packed",sc,so,sp,current)
end
+ -- can't happen !
head, current = remove_node(head, current, true)
- else
- current = next
- end
- elseif sc == together then
- local next = getnext(current)
- if next then
- keep_together = true
+ elseif sc == nowhite then
+ local next = getnext(current)
+ if next then
+ ignore_whitespace = true
+ head, current = remove_node(head, current, true)
+ else
+ current = next
+ end
+ elseif sc == discard then
if trace then
- trace_skip("together",sc,so,sp,current)
+ trace_skip("discard",sc,so,sp,current)
end
head, current = remove_node(head, current, true)
- else
- current = next
- end
- elseif sc == nowhite then
- local next = getnext(current)
- if next then
- ignore_whitespace = true
- head, current = remove_node(head, current, true)
- else
- current = next
- end
- elseif sc == discard then
- if trace then
- trace_skip("discard",sc,so,sp,current)
- end
- head, current = remove_node(head, current, true)
- elseif sc == overlay then
- -- todo (overlay following line over previous
- if trace then
- trace_skip("overlay",sc,so,sp,current)
- end
- -- beware: head can actually be after the affected nodes as
- -- we look back ... some day head will the real head
- head, current = check_experimental_overlay(head,current,a_snapmethod)
- elseif ignore_following then
- if trace then
- trace_skip("disabled",sc,so,sp,current)
- end
- head, current = remove_node(head, current, true)
- elseif not glue_data then
- if trace then
- trace_skip("assign",sc,so,sp,current)
- end
- glue_order = so
- head, current, glue_data = remove_node(head, current)
- elseif glue_order < so then
- if trace then
- trace_skip("force",sc,so,sp,current)
- end
- glue_order = so
- flush_node(glue_data)
- head, current, glue_data = remove_node(head, current)
- elseif glue_order == so then
- -- is now exclusive, maybe support goback as combi, else why a set
- if sc == largest then
- local cw = getwidth(current)
- local gw = getwidth(glue_data)
- if cw > gw then
- if trace then
- trace_skip("largest",sc,so,sp,current)
- end
- flush_node(glue_data)
- head, current, glue_data = remove_node(head,current)
- else
- if trace then
- trace_skip("remove smallest",sc,so,sp,current)
- end
- head, current = remove_node(head, current, true)
+ elseif sc == overlay then
+ -- todo (overlay following line over previous
+ if trace then
+ trace_skip("overlay",sc,so,sp,current)
end
- elseif sc == goback then
+ -- beware: head can actually be after the affected nodes as
+ -- we look back ... some day head will the real head
+ head, current = check_experimental_overlay(head,current,a_snapmethod)
+ elseif ignore_following then
if trace then
- trace_skip("goback",sc,so,sp,current)
+ trace_skip("disabled",sc,so,sp,current)
end
- flush_node(glue_data)
- head, current, glue_data = remove_node(head,current)
- elseif sc == force then
- -- last one counts, some day we can provide an accumulator and largest etc
- -- but not now
+ head, current = remove_node(head, current, true)
+ elseif not glue_data then
if trace then
- trace_skip("force",sc,so,sp,current)
+ trace_skip("assign",sc,so,sp,current)
end
- flush_node(glue_data)
+ glue_order = so
head, current, glue_data = remove_node(head, current)
- elseif sc == penalty then
+ elseif glue_order < so then
if trace then
- trace_skip("penalty",sc,so,sp,current)
+ trace_skip("force",sc,so,sp,current)
end
+ glue_order = so
flush_node(glue_data)
- glue_data = nil
- head, current = remove_node(head, current, true)
- elseif sc == add then
- if trace then
- trace_skip("add",sc,so,sp,current)
+ head, current, glue_data = remove_node(head, current)
+ elseif glue_order == so then
+ -- is now exclusive, maybe support goback as combi, else why a set
+ if sc == largest then
+ local cw = getwidth(current)
+ local gw = getwidth(glue_data)
+ if cw > gw then
+ if trace then
+ trace_skip("largest",sc,so,sp,current)
+ end
+ flush_node(glue_data)
+ head, current, glue_data = remove_node(head,current)
+ else
+ if trace then
+ trace_skip("remove smallest",sc,so,sp,current)
+ end
+ head, current = remove_node(head, current, true)
+ end
+ elseif sc == goback then
+ if trace then
+ trace_skip("goback",sc,so,sp,current)
+ end
+ flush_node(glue_data)
+ head, current, glue_data = remove_node(head,current)
+ elseif sc == force then
+ -- last one counts, some day we can provide an accumulator and largest etc
+ -- but not now
+ if trace then
+ trace_skip("force",sc,so,sp,current)
+ end
+ flush_node(glue_data)
+ head, current, glue_data = remove_node(head, current)
+ elseif sc == penalty then
+ if trace then
+ trace_skip("penalty",sc,so,sp,current)
+ end
+ flush_node(glue_data)
+ glue_data = nil
+ head, current = remove_node(head, current, true)
+ elseif sc == add then
+ if trace then
+ trace_skip("add",sc,so,sp,current)
+ end
+ local cwidth, cstretch, cshrink = getglue(current)
+ local gwidth, gstretch, gshrink = getglue(glue_data)
+ setglue(old,gwidth + cwidth, gstretch + cstretch, gshrink + cshrink)
+ -- toto: order
+ head, current = remove_node(head, current, true)
+ else
+ if trace then
+ trace_skip("unknown",sc,so,sp,current)
+ end
+ head, current = remove_node(head, current, true)
end
- local cwidth, cstretch, cshrink = getglue(current)
- local gwidth, gstretch, gshrink = getglue(glue_data)
- setglue(old,gwidth + cwidth, gstretch + cstretch, gshrink + cshrink)
- -- toto: order
- head, current = remove_node(head, current, true)
else
if trace then
trace_skip("unknown",sc,so,sp,current)
end
head, current = remove_node(head, current, true)
end
- else
- if trace then
- trace_skip("unknown",sc,so,sp,current)
+ if sc == force then
+ force_glue = true
end
- head, current = remove_node(head, current, true)
- end
- if sc == force then
- force_glue = true
- end
- elseif subtype == lineskip_code then
- if snap then
- local s = getattr(current,a_snapmethod)
- if s and s ~= 0 then
- setattr(current,a_snapmethod,0)
- setwidth(current,0)
- if trace_vsnapping then
- report_snapper("lineskip set to zero")
+ elseif subtype == lineskip_code then
+ if snap then
+ local s = getattr(current,a_snapmethod)
+ if s and s ~= 0 then
+ setattr(current,a_snapmethod,0)
+ setwidth(current,0)
+ if trace_vsnapping then
+ report_snapper("lineskip set to zero")
+ end
+ else
+ if trace then
+ trace_skip("lineskip",sc,so,sp,current)
+ end
+ flush("lineskip")
end
else
if trace then
@@ -1696,21 +1701,21 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also
end
flush("lineskip")
end
- else
- if trace then
- trace_skip("lineskip",sc,so,sp,current)
- end
- flush("lineskip")
- end
- current = getnext(current)
- elseif subtype == baselineskip_code then
- if snap then
- local s = getattr(current,a_snapmethod)
- if s and s ~= 0 then
- setattr(current,a_snapmethod,0)
- setwidth(current,0)
- if trace_vsnapping then
- report_snapper("baselineskip set to zero")
+ current = getnext(current)
+ elseif subtype == baselineskip_code then
+ if snap then
+ local s = getattr(current,a_snapmethod)
+ if s and s ~= 0 then
+ setattr(current,a_snapmethod,0)
+ setwidth(current,0)
+ if trace_vsnapping then
+ report_snapper("baselineskip set to zero")
+ end
+ else
+ if trace then
+ trace_skip("baselineskip",sc,so,sp,current)
+ end
+ flush("baselineskip")
end
else
if trace then
@@ -1718,53 +1723,53 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also
end
flush("baselineskip")
end
- else
- if trace then
- trace_skip("baselineskip",sc,so,sp,current)
- end
- flush("baselineskip")
- end
- current = getnext(current)
- elseif subtype == parskip_code then
- -- parskip always comes later
- if ignore_whitespace then
- if trace then
- trace_natural("ignored parskip",current)
- end
- head, current = remove_node(head, current, true)
- elseif glue_data then
- local w = getwidth(current)
- if (w ~= 0) and (w > getwidth(glue_data)) then
- glue_data = current
+ current = getnext(current)
+ elseif subtype == parskip_code then
+ -- parskip always comes later
+ if ignore_whitespace then
if trace then
- trace_natural("taking parskip",current)
+ trace_natural("ignored parskip",current)
+ end
+ head, current = remove_node(head, current, true)
+ elseif glue_data then
+ local w = getwidth(current)
+ if (w ~= 0) and (w > getwidth(glue_data)) then
+ glue_data = current
+ if trace then
+ trace_natural("taking parskip",current)
+ end
+ head, current = remove_node(head, current)
+ else
+ if trace then
+ trace_natural("removed parskip",current)
+ end
+ head, current = remove_node(head, current, true)
end
- head, current = remove_node(head, current)
else
if trace then
- trace_natural("removed parskip",current)
+ trace_natural("honored parskip",current)
end
- head, current = remove_node(head, current, true)
+ head, current, glue_data = remove_node(head, current)
end
- else
- if trace then
- trace_natural("honored parskip",current)
+ elseif subtype == topskip_code or subtype == splittopskip_code then
+ local next = getnext(current)
+ if next and getattr(next,a_skipcategory) == notopskip then
+ nuts.setglue(current) -- zero
end
- head, current, glue_data = remove_node(head, current)
- end
- elseif subtype == topskip_code or subtype == splittopskip_code then
- local next = getnext(current)
- if next and getattr(next,a_skipcategory) == 10 then -- no top skip
- nuts.setglue(current) -- zero
- end
- if snap then
- local s = getattr(current,a_snapmethod)
- if s and s ~= 0 then
- setattr(current,a_snapmethod,0)
- local sv = snapmethods[s]
- local w, cw = snap_topskip(current,sv)
- if trace_vsnapping then
- report_snapper("topskip snapped from %p to %p for %a",w,cw,where)
+ if snap then
+ local s = getattr(current,a_snapmethod)
+ if s and s ~= 0 then
+ setattr(current,a_snapmethod,0)
+ local sv = snapmethods[s]
+ local w, cw = snap_topskip(current,sv)
+ if trace_vsnapping then
+ report_snapper("topskip snapped from %p to %p for %a",w,cw,where)
+ end
+ else
+ if trace then
+ trace_skip("topskip",sc,so,sp,current)
+ end
+ flush("topskip")
end
else
if trace then
@@ -1772,130 +1777,124 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also
end
flush("topskip")
end
- else
+ current = getnext(current)
+ elseif subtype == abovedisplayskip_code and remove_math_skips then
+ --
if trace then
- trace_skip("topskip",sc,so,sp,current)
+ trace_skip("above display skip (normal)",sc,so,sp,current)
end
- flush("topskip")
- end
- current = getnext(current)
- elseif subtype == abovedisplayskip_code and remove_math_skips then
- --
- if trace then
- trace_skip("above display skip (normal)",sc,so,sp,current)
- end
- flush("above display skip (normal)")
- current = getnext(current)
- --
- elseif subtype == belowdisplayskip_code and remove_math_skips then
- --
- if trace then
- trace_skip("below display skip (normal)",sc,so,sp,current)
- end
- flush("below display skip (normal)")
- current = getnext(current)
- --
- elseif subtype == abovedisplayshortskip_code and remove_math_skips then
- --
- if trace then
- trace_skip("above display skip (short)",sc,so,sp,current)
- end
- flush("above display skip (short)")
- current = getnext(current)
- --
- elseif subtype == belowdisplayshortskip_code and remove_math_skips then
- --
- if trace then
- trace_skip("below display skip (short)",sc,so,sp,current)
- end
- flush("below display skip (short)")
- current = getnext(current)
- --
- else -- other glue
- if snap and trace_vsnapping then
- local w = getwidth(current)
- if w ~= 0 then
- report_snapper("glue %p of type %a kept",w,skipcodes[subtype])
+ flush("above display skip (normal)")
+ current = getnext(current)
+ --
+ elseif subtype == belowdisplayskip_code and remove_math_skips then
+ --
+ if trace then
+ trace_skip("below display skip (normal)",sc,so,sp,current)
end
+ flush("below display skip (normal)")
+ current = getnext(current)
+ --
+ elseif subtype == abovedisplayshortskip_code and remove_math_skips then
+ --
+ if trace then
+ trace_skip("above display skip (short)",sc,so,sp,current)
+ end
+ flush("above display skip (short)")
+ current = getnext(current)
+ --
+ elseif subtype == belowdisplayshortskip_code and remove_math_skips then
+ --
+ if trace then
+ trace_skip("below display skip (short)",sc,so,sp,current)
+ end
+ flush("below display skip (short)")
+ current = getnext(current)
+ --
+ else -- other glue
+ if snap and trace_vsnapping then
+ local w = getwidth(current)
+ if w ~= 0 then
+ report_snapper("glue %p of type %a kept",w,skipcodes[subtype])
+ end
+ end
+ if trace then
+ trace_skip(formatters["glue of type %a"](subtype),sc,so,sp,current)
+ end
+ flush("some glue")
+ current = getnext(current)
end
- if trace then
- trace_skip(formatters["glue of type %a"](subtype),sc,so,sp,current)
- end
- flush("some glue")
+ else
+ flush(formatters["node with id %a"](id))
current = getnext(current)
end
- else
- flush(formatters["node with id %a"](id))
- current = getnext(current)
end
- end
- if trace then
- trace_info("stop analyzing",where,what)
- end
- -- if natural_penalty and (not penalty_data or natural_penalty > penalty_data) then
- -- penalty_data = natural_penalty
- -- end
- if trace and (glue_data or penalty_data) then
- trace_info("start flushing",where,what)
- end
- local tail
- if penalty_data then
- tail = find_node_tail(head)
- local p = new_penalty(penalty_data)
if trace then
- trace_done("result",p)
+ trace_info("stop analyzing",where,what)
end
- setlink(tail,p)
- -- if penalty_data > special_penalty_min and penalty_data < special_penalty_max then
- local props = properties[p]
- if props then
- props.special_penalty = special_penalty or penalty_data
- else
- properties[p] = {
- special_penalty = special_penalty or penalty_data
- }
- end
+ -- if natural_penalty and (not penalty_data or natural_penalty > penalty_data) then
+ -- penalty_data = natural_penalty
-- end
- end
- if glue_data then
- if not tail then tail = find_node_tail(head) end
- if trace then
- trace_done("result",glue_data)
- end
- if force_glue then
- head, tail = forced_skip(head,tail,getwidth(glue_data),"after",trace)
- flush_node(glue_data)
- glue_data = nil
- elseif tail then
- setlink(tail,glue_data)
- else
- head = glue_data
+ if trace and (glue_data or penalty_data) then
+ trace_info("start flushing",where,what)
end
- texnest[texnest.ptr].prevdepth = 0 -- appending to the list bypasses tex's prevdepth handler
- end
- if trace then
- if glue_data or penalty_data then
- trace_info("stop flushing",where,what)
+ local tail
+ if penalty_data then
+ tail = find_node_tail(head)
+ local p = new_penalty(penalty_data)
+ if trace then
+ trace_done("result",p)
+ end
+ setlink(tail,p)
+ -- if penalty_data > special_penalty_min and penalty_data < special_penalty_max then
+ local props = properties[p]
+ if props then
+ props.special_penalty = special_penalty or penalty_data
+ else
+ properties[p] = {
+ special_penalty = special_penalty or penalty_data
+ }
+ end
+ -- end
+ end
+ if glue_data then
+ if not tail then tail = find_node_tail(head) end
+ if trace then
+ trace_done("result",glue_data)
+ end
+ if force_glue then
+ head, tail = forced_skip(head,tail,getwidth(glue_data),"after",trace)
+ flush_node(glue_data)
+ glue_data = nil
+ elseif tail then
+ setlink(tail,glue_data)
+ else
+ head = glue_data
+ end
+ texnest[texnest.ptr].prevdepth = 0 -- appending to the list bypasses tex's prevdepth handler
end
- show_tracing(head)
- if oldhead ~= head then
- trace_info("head has been changed from %a to %a",nodecodes[getid(oldhead)],nodecodes[getid(head)])
+ if trace then
+ if glue_data or penalty_data then
+ trace_info("stop flushing",where,what)
+ end
+ show_tracing(head)
+ if oldhead ~= head then
+ trace_info("head has been changed from %a to %a",nodecodes[getid(oldhead)],nodecodes[getid(head)])
+ end
end
+ return head, true
end
- return head, true
-end
--- alignment after_output end box new_graf vmode_par hmode_par insert penalty before_display after_display
--- \par -> vmode_par
---
--- status.best_page_break
--- tex.lists.best_page_break
--- tex.lists.best_size (natural size to best_page_break)
--- tex.lists.least_page_cost (badness of best_page_break)
--- tex.lists.page_head
--- tex.lists.contrib_head
+ -- alignment after_output end box new_graf vmode_par hmode_par insert penalty before_display after_display
+ -- \par -> vmode_par
+ --
+ -- status.best_page_break
+ -- tex.lists.best_page_break
+ -- tex.lists.best_size (natural size to best_page_break)
+ -- tex.lists.least_page_cost (badness of best_page_break)
+ -- tex.lists.page_head
+ -- tex.lists.contrib_head
-do
+ -- do
local stackhead, stacktail, stackhack = nil, nil, false
@@ -1933,13 +1932,14 @@ do
elseif subtype == parskip_code then
-- if where == new_graf then ... end
if texgetcount("c_spac_vspacing_ignore_parskip") > 0 then
- texsetcount("c_spac_vspacing_ignore_parskip",0)
+-- texsetcount("c_spac_vspacing_ignore_parskip",0)
setglue(n)
-- maybe removenode
end
end
end
end
+ texsetcount("c_spac_vspacing_ignore_parskip",0)
if flush then
if stackhead then
if trace_collect_vspacing then report("%s > appending %s nodes to stack (final): %s",where,newhead) end
@@ -1973,10 +1973,6 @@ do
return nil
end
-end
-
-do
-
local ignore = table.tohash {
"split_keep",
"split_off",
diff --git a/tex/context/base/mkiv/spac-ver.mkiv b/tex/context/base/mkiv/spac-ver.mkiv
index 98e46fa39..a1bc0559f 100644
--- a/tex/context/base/mkiv/spac-ver.mkiv
+++ b/tex/context/base/mkiv/spac-ver.mkiv
@@ -1956,6 +1956,7 @@
\newconditional\c_space_vspacing_done
\newconditional\c_space_vspacing_fixed
+\newconditional\c_space_ignore_parskip
\appendtoks
\s_spac_vspacing_temp\zeropoint
@@ -1978,6 +1979,9 @@
\relax
\to \everyafterblankhandling
+\unexpanded\def\setblankpacked
+ {\settrue\c_space_ignore_parskip}
+
\unexpanded\def\setblankcategory#1%
{\settrue\c_space_vspacing_done
\attribute\skipcategoryattribute#1\relax}
@@ -2016,6 +2020,7 @@
\def\dostartblankhandling
{\begingroup
\setfalse\c_space_vspacing_done
+ \setfalse\c_space_ignore_parskip
\the\everybeforeblankhandling}
\unexpanded\def\stopblankhandling
@@ -2023,7 +2028,11 @@
\ifconditional\c_space_vspacing_done
\vskip\s_spac_vspacing_temp
\fi
- \endgroup}
+ \ifconditional\c_space_ignore_parskip
+ \endgroup\ignoreparskip
+ \else
+ \endgroup
+ \fi}
\unexpanded\def\flushblankhandling
{\the\everyafterblankhandling
@@ -2210,10 +2219,13 @@
\definevspacing[\v!disable] [category:5]
\definevspacing[\v!nowhite] [category:6]
\definevspacing[\v!back] [category:7]
-% together [category:8]
+\definevspacing[\v!packed] [category:8] % noparskip (kind of special)
\definevspacing[\v!overlay] [category:9]
\definevspacing[\v!enable] [category:10]
+%definevspacing[\v!noparskip] [category:8]
+%definevspacing[\v!notopskip] [category:11]
+
\definevspacing[\v!weak] [order:0]
\definevspacing[\v!strong] [order:100]
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index b5094c116..319680a90 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 5ee29c774..767fa89ad 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/util-sql-loggers.lua b/tex/context/base/mkiv/util-sql-loggers.lua
index 7e64a435a..7cf4f6175 100644
--- a/tex/context/base/mkiv/util-sql-loggers.lua
+++ b/tex/context/base/mkiv/util-sql-loggers.lua
@@ -78,6 +78,7 @@ local sqlite_template = [[
function loggers.createdb(presets,datatable)
local db = checkeddb(presets,datatable)
+
db.execute {
template = (db.usedmethod == "sqlite" or db.usedmethod == "sqlffi") and sqlite_template or template,
variables = {
diff --git a/tex/context/base/mkiv/util-sql-logins.lua b/tex/context/base/mkiv/util-sql-logins.lua
index e4329ecc2..9717a8175 100644
--- a/tex/context/base/mkiv/util-sql-logins.lua
+++ b/tex/context/base/mkiv/util-sql-logins.lua
@@ -27,7 +27,13 @@ logins.cooldowntime = logins.cooldowntime or 10 * 60
logins.purgetime = logins.purgetime or 1 * 60 * 60
logins.autopurge = true
-local template_create = [[
+local function checkeddb(presets,datatable)
+ return sql.usedatabase(presets,datatable or presets.datatable or "logins")
+end
+
+logins.usedb = checkeddb
+
+local template = [[
CREATE TABLE
`logins`
(
@@ -46,6 +52,42 @@ CREATE TABLE
COMMENT='state: 0=unset 1=known 2=unknown'
]]
+function logins.createdb(presets,datatable)
+
+ local db = checkeddb(presets,datatable)
+
+ local data, keys = db.execute {
+ template = template,
+ variables = {
+ basename = db.basename,
+ },
+ }
+
+ report_logins("datatable %a created in %a",db.name,db.base)
+
+ return db
+
+end
+
+local template =[[
+ DROP TABLE IF EXISTS %basename% ;
+]]
+
+function logins.deletedb(presets,datatable)
+
+ local db = checkeddb(presets,datatable)
+
+ local data, keys = db.execute {
+ template = template,
+ variables = {
+ basename = db.basename,
+ },
+ }
+
+ report_logins("datatable %a removed in %a",db.name,db.base)
+
+end
+
local states = {
[0] = "unset",
[1] = "known",
@@ -105,58 +147,54 @@ local template_purge = [[
local cache = { } setmetatable(cache, { __mode = 'v' })
-local function usercreate(presets)
- sqlexecute {
- template = template_create,
- presets = presets,
- }
-end
+-- local function usercreate(presets)
+-- sqlexecute {
+-- template = template_create,
+-- presets = presets,
+-- }
+-- end
-local function userunknown(presets,name)
+function logins.userunknown(db,name)
local d = {
name = name,
state = 2,
time = ostime(),
n = 0,
}
- sqlexecute {
+ db.execute {
template = template_update,
- presets = presets,
variables = d,
}
cache[name] = d
report_logins("user %a is registered as unknown",name)
end
-local function userknown(presets,name)
+function logins.userknown(db,name)
local d = {
name = name,
state = 1,
time = ostime(),
n = 0,
}
- sqlexecute {
+ db.execute {
template = template_update,
- presets = presets,
variables = d,
}
cache[name] = d
report_logins("user %a is registered as known",name)
end
-local function userreset(presets,name)
- sqlexecute {
+function logins.userreset(db,name)
+ db.execute {
template = template_delete,
- presets = presets,
}
cache[name] = nil
report_logins("user %a is reset",name)
end
-local function userpurge(presets,delay)
- sqlexecute {
+local function userpurge(db,delay)
+ db.execute {
template = template_purge,
- presets = presets,
variables = {
time = ostime() - (delay or logins.purgetime),
}
@@ -165,6 +203,8 @@ local function userpurge(presets,delay)
report_logins("users are purged")
end
+logins.userpurge = userpurge
+
local function verdict(okay,...)
if not trace_logins then
-- no tracing
@@ -178,11 +218,11 @@ end
local lasttime = 0
-local function userpermitted(presets,name)
+function logins.userpermitted(db,name)
local currenttime = ostime()
if logins.autopurge and (lasttime == 0 or (currenttime - lasttime > logins.purgetime)) then
report_logins("automatic purge triggered")
- userpurge(presets)
+ userpurge(db)
lasttime = currenttime
end
local data = cache[name]
@@ -190,9 +230,8 @@ local function userpermitted(presets,name)
report_logins("user %a is cached",name)
else
report_logins("user %a is fetched",name)
- data = sqlexecute {
+ data = db.execute {
template = template_fetch,
- presets = presets,
converter = converter_fetch,
variables = {
name = name,
@@ -206,9 +245,8 @@ local function userpermitted(presets,name)
time = currenttime,
n = 1,
}
- sqlexecute {
+ db.execute {
template = template_insert,
- presets = presets,
variables = d,
}
cache[name] = d
@@ -237,9 +275,8 @@ local function userpermitted(presets,name)
time = currenttime,
n = 1,
}
- sqlexecute {
+ db.execute {
template = template_update,
- presets = presets,
variables = d,
}
cache[name] = d
@@ -251,9 +288,8 @@ local function userpermitted(presets,name)
time = currenttime,
n = n + 1,
}
- sqlexecute {
+ db.execute {
template = template_update,
- presets = presets,
variables = d,
}
cache[name] = d
@@ -261,46 +297,4 @@ local function userpermitted(presets,name)
end
end
-logins.create = usercreate
-logins.known = userknown
-logins.unknown = userunknown
-logins.reset = userreset
-logins.purge = userpurge
-logins.permitted = userpermitted
-
return logins
-
--- --
-
--- sql.setmethod("client")
-
--- local presets = {
--- database = "test",
--- username = "root",
--- password = "something",
--- }
-
--- logins.cooldowntime = 2*60
--- logins.maxnoflogins = 3
-
--- sql.logins.purge(presets,0)
-
--- for i=1,6 do
--- print("")
--- sql.logins.permitted(presets,"hans")
--- sql.logins.permitted(presets,"kees")
--- sql.logins.permitted(presets,"ton")
--- if i == 1 then
--- -- sql.logins.unknown(presets,"hans")
--- -- sql.logins.known(presets,"kees")
--- end
--- end
-
--- if loginpermitted(presets,username) then
--- if validlogin(username,...) then
--- -- sql.logins.known(presets,username)
--- elseif unknownuser(username) then
--- sql.logins.unknown(presets,username)
--- end
--- end
-
diff --git a/tex/context/base/mkiv/util-sql-tickets.lua b/tex/context/base/mkiv/util-sql-tickets.lua
index f392c0b91..68e54a015 100644
--- a/tex/context/base/mkiv/util-sql-tickets.lua
+++ b/tex/context/base/mkiv/util-sql-tickets.lua
@@ -18,6 +18,8 @@ local ostime, uuid, osfulltime = os.time, os.uuid, os.fulltime
local random = math.random
local concat = table.concat
+if not utilities.sql then require("util-sql") end
+
local sql = utilities.sql
local tickets = { }
sql.tickets = tickets
@@ -27,7 +29,6 @@ local report = logs.reporter("sql","tickets")
local serialize = sql.serialize
local deserialize = sql.deserialize
-local execute = sql.execute
tickets.newtoken = sql.tokens.new
@@ -87,7 +88,9 @@ local template =[[
]]
function tickets.createdb(presets,datatable)
+
local db = checkeddb(presets,datatable)
+
local data, keys = db.execute {
template = template,
variables = {
diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml
index 89f2650f2..c0308086c 100644
--- a/tex/context/interface/mkii/keys-ro.xml
+++ b/tex/context/interface/mkii/keys-ro.xml
@@ -1083,6 +1083,7 @@
<cd:constant name='preview' value='previzualizare'/>
<cd:constant name='previous' value='precendent'/>
<cd:constant name='previousnumber' value='numarprecedent'/>
+ <cd:constant name='print' value='print'/>
<cd:constant name='printable' value='tiparibil'/>
<cd:constant name='process' value='process'/>
<cd:constant name='profile' value='profile'/>
diff --git a/tex/context/interface/mkiv/context-en.xml b/tex/context/interface/mkiv/context-en.xml
index 83ef9fb62..bc8e96fbf 100644
--- a/tex/context/interface/mkiv/context-en.xml
+++ b/tex/context/interface/mkiv/context-en.xml
@@ -44488,6 +44488,7 @@
<cd:constant type="enable"/>
<cd:constant type="disable"/>
<cd:constant type="nowhite"/>
+ <cd:constant type="packed"/>
<cd:constant type="back"/>
<cd:constant type="overlay"/>
<cd:constant type="always"/>
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index ac301f450..c53f0ae43 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index d7c363731..39d5fb89d 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-vspace.xml b/tex/context/interface/mkiv/i-vspace.xml
index 9e1836dbc..ce6d5ac08 100644
--- a/tex/context/interface/mkiv/i-vspace.xml
+++ b/tex/context/interface/mkiv/i-vspace.xml
@@ -31,6 +31,7 @@
<cd:constant type="enable"/>
<cd:constant type="disable"/>
<cd:constant type="nowhite"/>
+ <cd:constant type="packed"/>
<cd:constant type="back"/>
<cd:constant type="overlay"/>
<cd:constant type="always"/>
@@ -212,4 +213,4 @@
<cd:command name="bigskip" level="system" category="whitespace" file="spac-ver.mkiv"/>
-</cd:interface> \ No newline at end of file
+</cd:interface>
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 1670e68e3..b8aa715ed 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 : 03/07/18 12:18:24
+-- merge date : 03/10/18 14:52:21
do -- begin closure to overcome local limits and interference