summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/anch-pos.mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/anch-pos.mkiv')
-rw-r--r--tex/context/base/mkiv/anch-pos.mkiv459
1 files changed, 459 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/anch-pos.mkiv b/tex/context/base/mkiv/anch-pos.mkiv
new file mode 100644
index 000000000..5d9c2fd34
--- /dev/null
+++ b/tex/context/base/mkiv/anch-pos.mkiv
@@ -0,0 +1,459 @@
+%D \module
+%D [ file=anch-pos, % was core-pos
+%D version=1999.08.01,
+%D title=\CONTEXT\ Anchoring Macros,
+%D subtitle=Positioning Support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Anchoring Macros / Positioning}
+
+%D In \MKIV\ there was already a different housekeeping model for positions quite
+%D early, but starting in 2012 more dramatic changes started to happen, especially
+%D in relation to background graphics. It will probably take some time to settle.
+
+\registerctxluafile{anch-pos}{1.001}
+
+\unprotect
+
+%D The first application of positional information was embedded graphics. Since we
+%D are interacting with text, it made sense to take the current line height and
+%D depth into account too. This is why we have position macros for simple positions
+%D and one boxes.
+%D
+%D \starttyping
+%D \dosetposition {identifier}
+%D \dosetpositionwhd {identifier} {width} {height} {depth}
+%D \dosetpositionplus {identifier} {width} {height} {depth} {list}
+%D \stoptyping
+
+\def\dosaveposition #1#2#3#4{\clf_dosaveposition {#1}#2 #3 #4\relax}
+\def\dosavepositionwhd #1#2#3#4#5#6#7{\clf_dosavepositionwhd {#1}#2 #3 #4 #5 #6 #7\relax}
+\def\dosavepositionplus#1#2#3#4#5#6#7#8{\clf_dosavepositionplus{#1}#2 #3 #4 #5 #6 #7{#8}}
+
+\def\dosetposition #1{\clf_dosetposition {#1}} % {} expands
+\def\dosetpositionwhd #1#2#3#4{\clf_dosetpositionwhd {#1}#2 #3 #4\relax}
+\def\dosetpositionplus#1#2#3#4#5{\clf_dosetpositionplus {#1}#2 #3 #4{#5}}
+\def\dosetpositionbox #1#2{\clf_dosetpositionbox {#1}#2\relax}
+\def\dosetpositionstrut #1{\clf_dosetpositionstrut{#1}}
+
+\newbox\b_anch_position
+\newif \ifpositioning % sort of public
+
+%D Sometimes we want to trick the position handler a bit:
+
+\def\replacepospxywhd#1#2#3#4#5#6#7% when used we can better make a helper
+ {\clf_replacepospxywhd{#1}#2 #3 #4 #5 #6 #7\relax}
+
+%D \macros
+%D {MPp, MPx, MPy, MPw, MPh, MPd, MPxy, MPll, MPlr, MPur, MPul, MPpos, MPanchor}
+%D
+%D Access to the positional information is provided by macros with short names
+%S that are clearly meant for \METAPOST\ but nowadays also used for other purposes.
+
+\def\MPp #1{\clf_MPp {#1}}
+\def\MPr #1{\clf_MPr {#1}}
+\def\MPc #1{\clf_MPc {#1}}
+\def\MPn #1{\clf_MPn {#1}}
+\def\MPx #1{\clf_MPx {#1}}
+\def\MPy #1{\clf_MPy {#1}}
+\def\MPw #1{\clf_MPw {#1}}
+\def\MPh #1{\clf_MPh {#1}}
+\def\MPd #1{\clf_MPd {#1}}
+\def\MPxy #1{\clf_MPxy {#1}}
+\def\MPll #1{\clf_MPll {#1}}
+\def\MPlr #1{\clf_MPlr {#1}}
+\def\MPur #1{\clf_MPur {#1}}
+\def\MPul #1{\clf_MPul {#1}}
+\def\MPpos #1{\clf_MPpos {#1}}
+\def\MPls #1{\clf_MPls {#1}}
+\def\MPrs #1{\clf_MPrs {#1}}
+\def\MPpardata#1{\clf_MPpardata{#1}}
+\def\MPxywhd #1{\clf_MPxywhd {#1}}
+\def\MPposset #1{\clf_MPposset {#1}}
+
+\let\MPpage \MPp
+\let\MPregion \MPr
+\let\MPcolumn \MPc
+\let\MPparagraph\MPn
+
+\let\MPanchor \MPpos % overloaded locally when needed
+\let\MPleftskip \MPls % compatible feature
+\let\MPrightkip \MPrs % compatible feature
+
+%D \macros
+%D {MPplus, MPrest, MPv, MPvv}
+%D
+%D Since we will probably keep on extending, we provide a general extension
+%D macro. The plus alternative takes an extra argument, denoting what additional
+%D parameter to pick up. So, the third extra is fetched with,
+%D
+%D \starttyping
+%D \MPplus{identifier}{3}{default}
+%D \stoptyping
+%D
+%D All extras (comma separated) are fetched with:
+%D
+%D \starttyping
+%D \MPrest{identifier}
+%D \stoptyping
+%D
+%D The extra parameters are not treated.
+
+\def\MPplus#1#2#3{\clf_MPplus{#1}#2{#3}} \let\MPv \MPplus
+\def\MPrest #1#2{\clf_MPrest{#1}{#2}} \let\MPvv\MPrest
+
+%D There are two low level positioning macros. Both store the position as well
+%D as execute an action associated with that position.
+
+\let\dopositionaction\gobbleoneargument % implemented later
+
+\def\anch_positions_initialize
+ {\ifpositioning \else
+ \global\positioningtrue
+ \fi}
+
+\unexpanded\def\setpositiononly
+ {\iftrialtypesetting
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\anch_positions_set_only_indeed
+ \fi}
+
+\def\anch_positions_set_only_indeed#1%
+ {\anch_positions_initialize
+ \edef\currentposition{#1}%
+ \dosetposition\currentposition}
+
+\unexpanded\def\setposition
+ {\iftrialtypesetting
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\anch_positions_set_indeed
+ \fi}
+
+\def\anch_positions_set_indeed#1%
+ {\anch_positions_initialize
+ \edef\currentposition{#1}%
+ \dosetposition\currentposition
+ \anch_positions_trace_left
+ \dopositionaction\currentposition}
+
+\unexpanded\def\setpositiondata
+ {\iftrialtypesetting
+ \expandafter\gobblefourarguments
+ \else
+ \expandafter\anch_positions_set_data_indeed
+ \fi}
+
+\def\anch_positions_set_data_indeed#1#2#3#4%
+ {\anch_positions_initialize
+ \hbox
+ {\edef\currentposition{#1}%
+ \dosetpositionwhd\currentposition{#2}{#3}{#4}% already \the\dimexpr
+ \anch_positions_trace_left
+ \dopositionaction\currentposition
+ \hss}}
+
+\unexpanded\def\setpositionbox
+ {\iftrialtypesetting
+ \expandafter\anch_positions_set_box_nop
+ \else
+ \expandafter\anch_positions_set_box_yes
+ \fi}
+
+\def\anch_positions_set_box_nop#1%
+ {\dowithnextboxcs\flushnextbox}
+
+\def\anch_positions_set_box_yes#1%
+ {\dowithnextbox{\anch_positions_set_box_finish{#1}}}
+
+\def\anch_positions_set_box_finish#1%
+ {\anch_positions_initialize
+ \hbox to \wd\nextbox
+ {\edef\currentposition{#1}%
+ \dosetpositionbox\currentposition\nextbox
+ \anch_positions_trace_left
+ \setbox\b_anch_position\box\nextbox
+ \dopositionaction\currentposition
+ \box\b_anch_position
+ \hss}}
+
+\unexpanded\def\setpositionstrut
+ {\iftrialtypesetting
+ \expandafter\anch_positions_set_strut_nop
+ \else
+ \expandafter\anch_positions_set_strut_yes
+ \fi}
+
+\def\anch_positions_set_strut_nop#1%
+ {\strut}
+
+\def\anch_positions_set_strut_yes#1%
+ {\anch_positions_initialize
+ \hbox to \zeropoint
+ {\edef\currentposition{#1}%
+ \dosetpositionstrut\currentposition
+ \anch_positions_trace_left
+ \dopositionaction\currentposition
+ \strut
+ \hss}}
+
+\unexpanded\def\setpositiondataplus
+ {\iftrialtypesetting
+ \expandafter\gobblefivearguments
+ \else
+ \expandafter\anch_positions_set_plus_indeed
+ \fi}
+
+\def\anch_positions_set_plus_indeed#1#2#3#4#5%
+ {\anch_positions_initialize
+ \hbox % just package
+ {\edef\currentposition{#1}%
+ \dosetpositionplus\currentposition{#2}{#3}{#4}{#5}% already \the\dimexpr
+ \anch_positions_trace_right
+ \dopositionaction\currentposition
+ \hss}}
+
+\unexpanded\def\setpositionplus
+ {\iftrialtypesetting
+ \expandafter\anch_positions_set_plus_nop
+ \else
+ \expandafter\anch_positions_set_plus_yes
+ \fi}
+
+\def\anch_positions_set_plus_nop#1#2%
+ {\dowithnextboxcs\flushnextbox}
+
+\def\anch_positions_set_plus_yes#1#2%
+ {\dowithnextbox{\anch_positions_set_plus_yes_finish{#1}{#2}}}
+
+\def\anch_positions_set_plus_yes_finish#1#2%
+ {\anch_positions_initialize
+ \hbox to \nextboxwd
+ {\edef\currentposition{#1}%
+ \dosetpositionplus\currentposition{\wd\nextbox}{\ht\nextbox}{\dp\nextbox}{#2}%
+ \anch_positions_trace_right
+ \setbox\b_anch_position\flushnextbox
+ \dopositionaction\currentposition
+ \box\b_anch_position
+ \hss}}
+
+\let\currentposition\s!unknown
+
+%D A few special ones .. will be cleaned up
+
+\def\pageanchor {page:\the\realpageno} % for the moment only one pagesize
+\def\textanchor {text:\the\realpageno}
+\def\regionanchor{region:0}
+
+\newcount\c_anch_column % will be delegated to lua
+\newcount\c_anch_text % will be delegated to lua
+
+% beware we need to pass \somethingexpanded or { }
+
+\unexpanded\def\anch_mark_column_box#1%
+ {\global\advance\c_anch_column\plusone
+ \clf_markregionboxtagged#1{columnarea:\the\c_anch_column}} % extra height
+
+\unexpanded\def\anch_mark_region_box
+ {\iftrialtypesetting
+ \singleexpandafter\gobbleoneargument
+ \else\ifpositioning
+ \doubleexpandafter\anch_mark_region_box_indeed
+ \else
+ \doubleexpandafter\gobbleoneargument
+ \fi\fi}
+
+\unexpanded\def\anch_mark_region_box_indeed#1%
+ {\clf_markregionbox#1\relax}
+
+\unexpanded\def\anch_mark_flow_box#1% will be extended / renamed
+ {\hbox\bgroup
+ \global\advance\c_anch_text\plusone
+ \clf_markregionboxtagged#1{textarea:\the\c_anch_text}%
+ \box#1%
+ \egroup}
+
+\unexpanded\def\anch_mark_tagged_box#1#2%
+ {\clf_markregionboxtagged#1{#2}}
+
+\unexpanded\def\anch_mark_flow_only#1% will be extended / renamed
+ {\global\advance\c_anch_text\plusone
+ \clf_markregionboxcorrected#1{textarea:\the\c_anch_text}}
+
+\unexpanded\def\anch_make_page_box#1% maybe like text
+ {\clf_setregionboxtagged#1{page:\the\realpageno}}
+
+\unexpanded\def\anch_mark_text_box#1%
+ {\clf_markregionboxtagged#1{text:\the\realpageno}} % needs an hbox
+
+%D We can copy a position with:
+%D
+%D \starttyping
+%D \copyposition {to} {from}
+%D \stoptyping
+%D
+%D Again, this is a global operation.
+
+\unexpanded\def\copyposition#1#2%
+ {\clf_copyposition{#1}{#2}}
+
+%D The fact that handling positions is a two pass operation, is one of the
+%D reasons why we need to be able to test for existence, using:
+%D
+%D \starttyping
+%D \doifpositionelse {identifier} {found action} {not found action}
+%D \stoptyping
+
+\unexpanded\def\doifposition #1{\clf_doifposition {#1}}
+\unexpanded\def\doifelseposition #1{\clf_doifelseposition {#1}}
+\unexpanded\def\doifelsepositiononpage#1#2{\clf_doifelsepositiononpage{#1}#2\relax}
+
+\let\doifpositionelse \doifelseposition
+\let\doifpositiononpageelse\doifelsepositiononpage
+
+%D \macros
+%D {xypos}
+%D
+%D We have several macros available to save positions. Later we will see
+%D applications.
+%D
+%D \starttabulate[|l|l||]
+%D \NC \type {\xypos} \NC \NC simple position with no dimensions \NC \NR
+%D \NC \type {\hpos} \NC \NC position and characteristics of a \type {\hbox} \NC \NR
+%D \NC \type {\vpos} \NC \NC position and characteristics of a \type {\vbox} \NC \NR
+%D \NC \type {\bpos} \NC b: \NC begin point in a line \NC \NR
+%D \NC \type {\epos} \NC e: \NC end point in a line \NC \NR
+%D \stoptabulate
+%D
+%D Each macro takes an identifier as argument, and the \type {\hpos} and
+%D \type {\vpos} also expect box content.
+
+\let\xypos\setpositiononly
+
+\unexpanded\def\hpos#1{\dontleavehmode\setpositionbox{#1}\hbox}
+\unexpanded\def\vpos#1{\setpositionbox{#1}\vbox}
+\unexpanded\def\bpos#1{\dontleavehmode \setpositionstrut{b:#1}\ignorespaces}
+\unexpanded\def\epos#1{\removeunwantedspaces\setpositionstrut{e:#1}}
+
+%D When we want to calculate more complex backgrounds, we need to know what the
+%D current indentation scheme is. At the cost of many positions and memory, we
+%D can keep track of them. This mechanism is activated automatically based on
+%D information collected in the previous pass.
+
+\newtoks \t_anch_positions_tracers
+\newcount\c_anch_positions_paragraph
+
+\unexpanded\def\tracepositions
+ {\the\t_anch_positions_tracers}
+
+\unexpanded\def\enableparpositions % global
+ {\global\let\registerparoptions\doregisterparoptions
+ \global\positioningtrue}
+
+\let\disableparpositions\relax
+
+\let\registerparoptions\relax
+
+\unexpanded\def\doregisterparoptions
+ {\iftrialtypesetting \else
+ \ifinpagebody \else \ifmmode \else \ifinformula \else
+ \anch_positions_register_par_options
+ \fi \fi \fi
+ \fi}
+
+\def\anch_positions_register_par_options_normal
+ {\dontleavehmode\clf_parpos}
+
+\def\anch_positions_register_par_options_traced
+ {\anch_positions_register_par_options_normal
+ \smashedhbox to \zeropoint
+ {\hss
+ \startcolor[blue]%
+ \llap{\infofont\number\c_anch_positions_paragraph}%
+ \vrule
+ \s!width 4\onepoint
+ \s!height2\onepoint
+ \s!depth 2\onepoint
+ \stopcolor
+ \hss}}
+
+\let\anch_positions_register_par_options\anch_positions_register_par_options_normal
+
+\appendtoks
+ \let\anch_positions_register_par_options\anch_positions_register_par_options_traced
+\to \t_anch_positions_tracers
+
+\unexpanded\def\anch_positions_trace#1#2#3%
+ {\smashedhbox
+ {#1{\infofont#2#3}%
+ \kern-\onepoint
+ \vrule\s!width2\onepoint\s!height\halfapoint\s!depth\halfapoint}}
+
+\unexpanded\def\anch_positions_trace_left_indeed
+ {\anch_positions_trace\llap\darkmagenta{\currentposition>}}
+
+\unexpanded\def\anch_positions_trace_right_indeed
+ {\anch_positions_trace\rlap\darkcyan{<\currentposition}}
+
+\let\anch_positions_trace_left \relax
+\let\anch_positions_trace_right\relax
+
+\appendtoks
+ \let\anch_positions_trace_left \anch_positions_trace_left_indeed
+ \let\anch_positions_trace_right \anch_positions_trace_right_indeed
+\to \t_anch_positions_tracers
+
+% \appendtoks \registerparoptions \to \everypar
+
+%D \macros
+%D {doifoverlappingelse}
+%D
+%D A first application of positional information, is to determine if two
+%D boxes do overlap:
+%D
+%D \starttyping
+%D \doifoverlappingelse{point a}{point b}
+%D {action when overlapping}
+%D {action when not overlapping}
+%D \stoptyping
+
+\unexpanded\def\doifelseoverlapping#1#2{\clf_doifelseoverlapping{#1}{#2}}
+
+\let\doifoverlappingelse\doifelseoverlapping
+
+%D \macros
+%D {doifpositionsonsamepageelse,
+%D doifpositionsonthispageelse}
+%D
+%D Instead of letting the user handle fuzzy expansion, we provide a simple test on
+%D positions being on the same page.
+%D
+%D \starttyping
+%D \doifpositionsonsamepageelse{point a}{point b}
+%D {action when on same page}
+%D {action when not on same page}
+%D \doifpositionsonthispageelse{point a}{point b}
+%D {action when on this page}
+%D {action when not on this page}
+%D \stoptyping
+
+\unexpanded\def\doifelsepositionsonsamepage#1{\clf_doifelsepositionsonsamepage{#1}}
+\unexpanded\def\doifelsepositionsonthispage#1{\clf_doifelsepositionsonthispage{#1}}
+
+\let\doifpositionsonsamepageelse\doifelsepositionsonsamepage
+\let\doifpositionsonthispageelse\doifelsepositionsonthispage
+
+%D Moved here:
+
+\unexpanded\def\doifelsepositionsused{\clf_doifelsepositionsused}
+
+\let\doifpositionsusedelse\doifelsepositionsused
+
+\protect \endinput