summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/anch-pgr.mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/anch-pgr.mkiv')
-rw-r--r--tex/context/base/mkiv/anch-pgr.mkiv512
1 files changed, 512 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/anch-pgr.mkiv b/tex/context/base/mkiv/anch-pgr.mkiv
new file mode 100644
index 000000000..a7ad26dff
--- /dev/null
+++ b/tex/context/base/mkiv/anch-pgr.mkiv
@@ -0,0 +1,512 @@
+%D \module
+%D [ file=anch-pgr, % split off core-pos
+%D version=1999.08.01,
+%D title=\CONTEXT\ Anchoring Macros,
+%D subtitle=Positioning Graphics,
+%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 / Grapics}
+
+%D Before we come to graphics support, we have to make sure of
+%D the reference point on the page. The next macros do so and
+%D are hooked into the page building routine.
+
+\registerctxluafile{anch-pgr}{1.001}
+
+\unprotect
+
+%D A few more low level macros take care of defining and recalling
+%D actions. Actions are saved globally! The lists can become quite
+%D long because there can be lots of parameters passed on so we
+%D clean up the list afterwards.
+
+\newtoks\everypositionaction
+\newtoks\everyinsertpositionaction
+\newtoks\everycleanpositionaction
+
+\installcorenamespace{positionaction}
+\installcorenamespace{positioncleanup}
+
+\unexpanded\def\anch_positions_set_action#1%
+ {\expandafter\gdef\csname\??positionaction#1\endcsname} % nicely gobbles spaces
+
+\unexpanded\def\doifpositionaction#1%
+ {\ifcsname\??positionaction#1\endcsname
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\unexpanded\def\doifelsepositionaction#1%
+ {\ifcsname\??positionaction#1\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\let\doifpositionactionelse\doifelsepositionaction
+
+\unexpanded\def\dopositionaction#1%
+ {\edef\currentpositionaction{#1}%
+ \ifcsname\??positionaction\currentpositionaction\endcsname
+ \anch_positions_action_indeed
+ \fi}
+
+\def\anch_positions_action_indeed
+ {\doifelseposition\currentpositionaction
+ \anch_positions_action_indeed_yes
+ \anch_positions_action_indeed_nop}
+
+\def\anch_positions_action_indeed_nop
+ {\anch_positions_trace_action_nop}
+
+\def\anch_positions_action_indeed_yes % we need a way to figure out if we have actions
+ {\begingroup
+ \setbox\scratchbox\hbox
+ {\anch_positions_trace_action_yes
+ \the\everyinsertpositionaction
+ \the\everypositionaction
+ \csname\??positionaction\currentpositionaction\endcsname
+ \anch_positions_cleanup_action}%
+ \smashedbox\scratchbox % smashing is really needed else we get problems with too big overlays
+ \endgroup}
+
+\unexpanded\def\anch_positions_trace_action_nop_indeed
+ {\anch_positions_trace\clap\darkred{<\currentpositionaction>}}
+
+\unexpanded\def\anch_positions_trace_action_yes_indeed
+ {\anch_positions_trace\clap\darkgreen{<\currentpositionaction>}}
+
+\let\anch_positions_trace_action_nop\relax
+\let\anch_positions_trace_action_yes\relax
+
+\appendtoks
+ \let\anch_positions_trace_action_nop\anch_positions_trace_action_nop_indeed
+ \let\anch_positions_trace_action_yes\anch_positions_trace_action_yes_indeed
+\to \t_anch_positions_tracers
+
+%D Here the complication has to do with collecting actions
+%D for later execution. This collection is especially handy
+%D when we want to move actions to a specific layer. Such
+%D series of actions are stored in a macro that is cleaned up
+%D after each invocation.
+
+\def\anch_positions_cleanup_action % not in trialtypesetting
+ {\ifcsname\??positioncleanup\currentpositionaction\endcsname
+ \the\everycleanpositionaction
+ % \iflocalpositioning
+ % % erase
+ % \expandafter\let\csname\??positioncleanup\currentpositionaction\endcsname\empty
+ % \else
+ % globalize expansion cleans up
+ \setxvalue{\??positioncleanup\currentpositionaction}{\csname\??positioncleanup\currentpositionaction\endcsname}%
+ % \fi
+ \fi}
+
+\def\handlepositionaction#1\with#2\on#3% ugly
+ {\begingroup
+ \edef\currentpositionanchor
+ {\ifx\currentpositionoverlay\empty#3\else\currentpositionoverlay::\MPanchoridentifier\fi}%
+ \normalexpanded{\anch_positions_set_action{\currentpositionanchor}{\noexpand\getvalue{\??positioncleanup\currentpositionanchor}}}%
+ \let#1\relax
+ \ifcsname\??positioncleanup\currentpositionanchor\endcsname
+ \setxvalue{\??positioncleanup\currentpositionanchor}%
+ {\csname\??positioncleanup\currentpositionanchor\endcsname#1#2}%
+ \else
+ \setxvalue{\??positioncleanup\currentpositionanchor}%
+ {#1#2}%
+ \fi
+ \endgroup}
+
+%D The first version of this module implemented head and tail
+%D anchors. Currently we stick to just one anchor and derive
+%D the head and tail anchors from this one. We set these
+%D anchors before and after each page.
+
+\newdimen\c_anch_page_width
+\newdimen\c_anch_page_height
+
+\unexpanded\def\anch_positions_register_page#1% this one is flushed first ! ... can't we avoid this one
+ {\ifpositioning\ifcase\realpageno\or
+ \ifdim\c_anch_page_height=\paperheight
+ \ifdim\c_anch_page_width=\paperwidth
+ % no change
+ \else
+ \c_anch_page_width \paperwidth
+ \c_anch_page_height\paperheight
+ \anch_make_page_box{#1}% \ifvbox#1\setbox#1\hbox{\box#1}\fi
+ \fi
+ \else
+ \c_anch_page_width \paperwidth
+ \c_anch_page_height\paperheight
+ \anch_make_page_box{#1}% \ifvbox#1\setbox#1\hbox{\box#1}\fi
+ \fi
+ \fi\fi}
+
+\unexpanded\def\anch_positions_place_anchors
+ {\ifpositioning
+ \anch_positions_place_anchors_yes
+ \else
+ \anch_positions_place_anchors_nop
+ \fi}
+
+\def\anch_positions_place_anchors_yes % todo : depth pagebox
+ {\begingroup
+ \setbox\scratchbox\emptyhbox
+ \ht\scratchbox\textheight
+ \dp\scratchbox\zeropoint
+ \wd\scratchbox\makeupwidth
+ \anch_mark_text_box\scratchbox
+ \box\scratchbox
+ \endgroup}
+
+\def\anch_positions_place_anchors_nop
+ {\vskip\textheight}
+
+%D \macros
+%D {positionoverlay,startpositionoverlay}
+%D
+%D As long as we're dealing with graphics it makes much sense
+%D to use the available overlay mechanism. For this purpose, we
+%D define some dedicated overlay extensions.
+%D
+%D \startbuffer[sample]
+%D \defineoverlay [sample] [\positionoverlay{sample}]
+%D
+%D \startpositionoverlay{sample}
+%D \setMPpositiongraphic{A-1}{connectcenter}{from=A-1,to=A-2}
+%D \stoppositionoverlay
+%D \stopbuffer
+%D
+%D \typebuffer[sample]
+%D
+%D \startbuffer[graphic]
+%D \startMPpositiongraphic{connectcenter}
+%D path pa, pb ; pair ca, cb ;
+%D initialize_box(\MPpos{\MPvar{from}}) ; pa := pxy ; ca := cxy ;
+%D initialize_box(\MPpos{\MPvar{to}}) ; pb := pxy ; cb := cxy ;
+%D draw pa withcolor red ;
+%D draw pb withcolor red ;
+%D draw ca -- cb withcolor blue ;
+%D anchor_box(\MPanchor{\MPvar{from}}) ;
+%D \stopMPpositiongraphic
+%D \stopbuffer
+%D
+%D We can best demonstrate this in an example, say:
+%D
+%D \startbuffer[text]
+%D \framed
+%D [backgroundachtergrond=sample,align=middle,width=7cm]
+%D {We want to connect \hpos {A-1} {this} word with its
+%D grammatical cousin \hpos {A-2} {that}.}
+%D \stopbuffer
+%D
+%D \typebuffer[text]
+%D
+%D \startlinecorrection
+%D %\getbuffer[graphic,sample,text]
+%D \stoplinecorrection
+%D
+%D The graphic is defined in the following way, using some
+%D macros defined in an auxiliary \METAPOST\ module that is
+%D preloaded.
+%D
+%D \typebuffer[graphic]
+
+\def\MPanchoridentifier{mpa} % {mp-anchor}
+
+%D The rest of the definitions concerning such overlays may
+%D look complicated,
+
+\let\currentpositionoverlay\empty
+
+%D Position actions are automatically executed when a position
+%D is set.
+
+% \newcount\localpositionnumber % incremented elsewhere
+% \newif\iflocalpositioning
+%
+% \def\textbackgroundoverlay#1{\iflocalpositioning\v!local\else\v!text\fi#1}
+% \def\MPanchornumber {\the\iflocalpositioning\localpositionnumber\else\realpageno\fi}
+
+\def\textbackgroundoverlay#1{\v!text#1}
+\def\MPanchornumber {\the\realpageno}
+
+\unexpanded\def\positionoverlay % the test prevents too many redundant positions
+ {\ifpositioning % in (not used) text* position layers
+ \expandafter\anch_positions_overlay_indeed
+ \else % also \iftrialtypesetting test here?
+ \expandafter\gobbleoneargument
+ \fi}
+
+\def\anch_positions_overlay_indeed#1%
+ {\begingroup
+ \edef\currentpositionoverlay{#1}%
+ \ifcsname\??positionaction\currentpositionoverlay::\MPanchoridentifier\endcsname
+ \anch_positions_overlay_compose
+ \fi
+ \endgroup}
+
+\def\MPoverlayanchor#1{\MPpos\MPanchorid}
+
+\def\anch_positions_overlay_compose
+ {\vpack to \d_overlay_height
+ {%\writestatus{!!!}{\currentpositionoverlay/\MPanchoridentifier/\MPanchornumber}%
+ \edef\MPanchorid{\currentpositionoverlay::\MPanchoridentifier:\MPanchornumber}% realpageno
+ % \edef\MPanchor##1{\MPpos\MPanchorid}%
+ \let\MPanchor\MPoverlayanchor % no need to fetch it already, seldom used
+ \the\everyinsertpositionaction
+ \copyposition{\currentpositionoverlay::\MPanchoridentifier}\MPanchorid
+ \setbox\scratchbox\hbox to \d_overlay_width
+ {\dopositionaction{\currentpositionoverlay::\MPanchoridentifier}\hss}%
+ \ht\scratchbox\d_overlay_height
+ \dp\scratchbox\zeropoint
+ \anch_mark_tagged_box\scratchbox\MPanchorid % needs an hbox
+ \box\scratchbox
+ \vfill}}
+
+\unexpanded\def\positionregionoverlay % shares regions
+ {\ifpositioning
+ \expandafter\anch_positions_region_overlay_indeed
+ \else % also \iftrialtypesetting test here?
+ \expandafter\gobbletwoarguments
+ \fi}
+
+\let\currentpositionregion\empty
+
+\def\anch_positions_region_overlay_indeed#1#2%
+ {\begingroup
+ \edef\currentpositionregion {#1}%
+ \edef\currentpositionoverlay{#2}%
+ \ifcsname\??positionaction\currentpositionoverlay::\MPanchoridentifier\endcsname
+ \anch_positions_region_overlay_compose
+ \fi
+ \endgroup}
+
+\def\anch_positions_region_overlay_compose
+ {\vpack to \d_overlay_height
+ {\let\MPanchorid\currentpositionregion
+ \let\MPanchor\MPoverlayanchor % no need to fetch it already, seldom used
+ \the\everyinsertpositionaction
+ \copyposition{\currentpositionoverlay::\MPanchoridentifier}\MPanchorid
+ \setbox\scratchbox\hbox to \d_overlay_width
+ {\dopositionaction{\currentpositionoverlay::\MPanchoridentifier}\hss}%
+ \ht\scratchbox\d_overlay_height
+ \dp\scratchbox\zeropoint
+ \box\scratchbox
+ \vfill}}
+
+% \let\anch_positions_overlay_nop\gobbleoneargument
+
+\unexpanded\def\startpositionoverlay
+ {\iftrialtypesetting
+ \expandafter\anch_positions_overlay_start_nop
+ \else
+ \expandafter\anch_positions_overlay_start_yes
+ \fi}
+
+\let\stoppositionoverlay\relax
+
+\def\anch_positions_overlay_start_nop#1\stoppositionoverlay
+ {}
+
+\ifdefined\checkpositionoverlays \else \let\checkpositionoverlays\relax \fi
+
+\let\currentpositionoverlay\empty
+
+\def\anch_positions_overlay_start_yes#1%
+ {\checkpositionoverlays
+ \edef\currentpositionoverlay{#1}}
+
+\unexpanded\def\stoppositionoverlay
+ {\let\currentpositionoverlay\empty}
+
+% needs checking if still needed
+%
+% \def\resetpositionoverlay#1%
+% {\anch_positions_set_action{#1::\MPanchoridentifier::}{}}
+%
+% \def\handlepositionboxes#1#2#3%
+% {\handlepositionaction\dohandlepositionboxes\with{#1}{#2}{#3}\on{#2}}
+%
+% \def\doinsertpositionboxes#1#2#3% pos tag setups
+% {\ifnum\MPp{#1}=\realpageno\relax % can be sped up
+% \executeifdefined{\MPoverlayposprefix#1}\gobblethreearguments{#1}{#2}{#3}% not used
+% \fi}
+%
+% \appendtoks
+% \let\dohandlepositionboxes\doinsertpositionboxes % was handle ?
+% \to \everyinsertpositionaction
+%
+% \def\docleanpositionboxes#1#2#3% pos tag setups
+% {\ifnum\MPp{#1}<\realpageno \else
+% \noexpand \dohandlepositionboxes{#1}{#2}{#3}% reinsert
+% \fi}
+%
+% \appendtoks
+% \let\dohandlepositionboxes\docleanpositionboxes
+% \to \everycleanpositionaction
+
+%D A position graphic is a normal (non||reused) \METAPOST\
+%D graphic, used immediately, with zero dimensions, so that a
+%D sequence of them does not harm.
+
+\installcorenamespace{positiongraphic}
+\installcorenamespace{positionmethod}
+%installcorenamespace{graphicvariable}
+
+\newbox\b_anch_positions_graphic
+
+\def\startMPpositiongraphic % id setups
+ {\dodoublegroupempty\anch_positions_meta_graphic_start}
+
+\def\anch_positions_meta_graphic_start#1#2#3\stopMPpositiongraphic % tag list mpcode
+ {\setgvalue{\??positiongraphic#1}{\anch_positions_meta_graphic_use{#1}{#2}{#3}}}
+
+\let\stopMPpositiongraphic\relax
+
+\def\anch_positions_meta_graphic_prepare
+ {\ifcsname\??graphicvariable\currentmpvariableclass:self\endcsname \else
+ \letvalue{\??graphicvariable\currentmpvariableclass:self}\currentposition
+ \fi
+ \ifcsname\??graphicvariable\currentmpvariableclass:from\endcsname \else
+ \letvalue{\??graphicvariable\currentmpvariableclass:from}\currentposition
+ \fi}
+
+\def\anch_positions_meta_graphic_use#1#2#3%
+ {\begingroup
+ \meta_prepare_variables{#2}%
+ \anch_positions_meta_graphic_prepare
+ \startMPcode#3\stopMPcode
+ \endgroup}
+
+\unexpanded\def\MPpositiongraphic
+ {\dodoublegroupempty\anch_positions_meta_graphic_direct}
+
+\def\anch_positions_meta_graphic_direct#1% tag setups
+ {\ifcsname\??positionmethod#1\endcsname % method
+ \expandafter\anch_positions_meta_graphic_direct_indeed_method
+ \else\ifcsname\??positiongraphic#1\endcsname
+ \doubleexpandafter\anch_positions_meta_graphic_direct_indeed_normal
+ \else
+ \doubleexpandafter\anch_positions_meta_graphic_direct_indeed_unknown
+ \fi\fi{#1}}
+
+\let\anch_positions_meta_graphic_direct_indeed_unknown\gobbletwoarguments
+
+\def\anch_positions_meta_graphic_direct_indeed_method
+ {\anch_positions_meta_graphic_direct_indeed\??positionmethod}
+
+\def\anch_positions_meta_graphic_direct_indeed_normal
+ {\anch_positions_meta_graphic_direct_indeed\??positiongraphic}
+
+\def\anch_positions_meta_graphic_direct_indeed#1#2#3% what tag setups
+ {\begingroup
+ \setupMPvariables[#2][#3]%
+ \edef\currentmpvariableclass{#2}%
+ \anch_positions_meta_graphic_prepare
+ \obeyMPboxorigin % do we also set the size ? when needed this must be done in mp ... might change
+ \def\anch_positions_meta_graphic_direct{\anch_positions_meta_graphic_nested{#3}}% takes two extra arguments
+ \setbox\b_anch_positions_graphic\hbox
+ {\ignorespaces\csname#1#2\endcsname\removelastspace}%
+ \smashbox\b_anch_positions_graphic
+ \box\b_anch_positions_graphic
+ \endgroup}
+
+\def\anch_positions_meta_graphic_nested#1#2#3% nesting used in prikkels / pascal (might go away)
+ {\begingroup
+ \setupMPvariables[#2][#1,#3]%
+ \edef\currentmpvariableclass{#2}%
+ \anch_positions_meta_graphic_prepare
+ \csname\??positiongraphic#2\endcsname
+ \endgroup}%
+
+\def\startMPpositionmethod#1#2\stopMPpositionmethod
+ {\setgvalue{\??positionmethod#1}{#2}} % todo: var list here
+
+\let\stopMPpositionmethod\relax
+
+%D Simple one position graphics.
+
+\unexpanded\def\setMPpositiongraphic
+ {\dotriplegroupempty\anch_positions_meta_graphic_set}
+
+\def\anch_positions_meta_graphic_set#1#2#3% pos tag vars
+ {\ifx\currentpositionoverlay\empty
+ \anch_positions_set_action{#1}{\MPpositiongraphic{#2}{#3}}%
+ \else % silly can be one
+ \anch_positions_meta_graphic_handle{#1}{#2}{#3}%
+ \fi}
+
+\def\anch_positions_meta_graphic_handle#1#2#3% combine with boxes
+ {\handlepositionaction\anch_positions_meta_graphic_handle_indeed\with{#1}{#2}{#3}\on{#2}}
+
+\def\anch_positions_meta_graphic_insert#1#2#3% pos tag setups
+ {\ifnum\MPp{#1}=\realpageno\relax % extra saveguard
+ \def\currentposition{#1}\MPpositiongraphic{#2}{#3}%
+ \fi}
+
+\let\anch_positions_meta_graphic_handle_indeed\relax
+
+\appendtoks
+ \let\anch_positions_meta_graphic_handle_indeed\anch_positions_meta_graphic_insert
+\to \everyinsertpositionaction
+
+\def\anch_positions_meta_graphic_cleanup#1#2#3% pos tag setups
+ {\ifnum\MPp{#1}<\realpageno \else
+ \noexpand\anch_positions_meta_graphic_handle_indeed{#1}{#2}{#3}%
+ \fi}
+
+\appendtoks
+ \let\anch_positions_meta_graphic_handle_indeed\anch_positions_meta_graphic_cleanup
+\to \everycleanpositionaction
+
+%D Graphics that span two positions (beware, does not cross pages).
+
+\unexpanded\def\setMPpositiongraphicrange
+ {\doquadruplegroupempty\anch_positions_meta_graphic_set_range}
+
+\def\anch_positions_meta_graphic_set_range#1#2#3#4% bpos epos tag vars
+ {\ifx\currentpositionoverlay\empty
+ \anch_positions_set_action{#1}{\MPpositiongraphic{#3}{#4}}%
+ \else
+ \anch_positions_meta_graphic_handle_range{#1}{#2}{#3}{#4}%
+ \fi}
+
+\def\anch_positions_meta_graphic_handle_range#1#2#3#4%
+ {\handlepositionaction\anch_positions_meta_graphic_handle_range_indeed\with{#1}{#2}{#3}{#4}\on{#2}}
+
+\def\anch_positions_meta_graphic_insert_range#1#2#3#4% pos pos tag setups
+ {\clf_doifelserangeonpage{#1}{#2}\realpageno
+ {\def\currentposition{#1}%
+ \MPpositiongraphic{#3}{#4}}%
+ {}}
+
+\appendtoks
+ \let\anch_positions_meta_graphic_handle_range_indeed\anch_positions_meta_graphic_insert_range
+\to \everyinsertpositionaction
+
+\def\anch_positions_meta_graphic_cleanup_range#1#2#3#4% pos tag setups
+ {\ifnum\MPp{#2}<\realpageno \else
+ \noexpand \anch_positions_meta_graphic_handle_range_indeed{#1}{#2}{#3}{#4}%
+ \fi}
+
+\appendtoks
+ \let\anch_positions_meta_graphic_handle_range_indeed\anch_positions_meta_graphic_cleanup_range
+\to \everycleanpositionaction
+
+\let\anch_positions_meta_graphic_handle_range_indeed\gobblefourarguments
+
+% Helpers:
+
+\def\MPgetposboxes #1#2{\clf_fetchposboxes {#1}{#2}\realpageno}
+\def\MPgetmultipars #1#2{\clf_fetchmultipar {#1}{#2}\realpageno}
+\def\MPgetmultishapes#1#2{\clf_fetchmultishape{#1}{#2}\realpageno}
+
+\protect \endinput