
%D \module
%D   [       file=typo-pin,
%D        version=2026.01.06,
%D          title=\CONTEXT\ Typesetting Macros,
%D       subtitle=Paragraph Inserts,
%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 Typesetting Macros / Paragraph inserts}

%D An experiment turned feature by Mikael Sundqvist and Hans during cold and snowy
%D winter days in the first weekl of 2026. A sort of follow up on our par builder
%D experiments.

%D \starttyping
%D \setupexternalfigures
%D   [location={global,local,default}]
%D
%D \enabletrackers[parinsert]
%D
%D \starttext
%D
%D \samplefile{tufte}%
%D \space\leftparinsert[color=darkred]{An example.}\space
%D \samplefile{ward}%
%D \space\rightparinsert[color=darkgreen]{Another example.}\space
%D \samplefile{tufte}
%D
%D \page
%D
%D \samplefile{tufte}%
%D \space
%D \leftparinsert
%D   [lines=3]
%D   {\externalfigure[cow.pdf][height=3lh,location=top]}%
%D \rightparinsert
%D   [lines=4]
%D   {\mirror{\externalfigure[cow.pdf][height=4lh,location=top]}}%
%D \space
%D \samplefile{ward}%
%D \space
%D \rightparinsert
%D   [distance=2em,lines=2]
%D   {\mirror{\externalfigure[cow.pdf][height=2lh,location=top]}}%
%D \space
%D \samplefile{tufte}
%D \stoptyping

\unprotect

\installcorenamespace{parinsert}

\installcommandhandler \??parinsert {parinsert} \??parinsert

\setupparinsert
  [\c!location=\v!left,
   \c!distance=\emwidth,
   \c!xoffset=\zeropoint,
   \c!yoffset=\zeropoint,
   \c!option=,
   \c!lines=3]

% \permanent\tolerant\protected\def\typo_parinsert_handle#1#*[#2]#*#:#3%
%   {\begingroup
%    \cdef\currentparinsert{#1}%
%    \ifparameter#2\or
%       \setupcurrentparinsert[#2]%
%    \fi
%    \setbox\scratchbox\hbox
%       \s!xoffset {\parinsertparameter\c!xoffset}%
%       \s!yoffset {\parinsertparameter\c!yoffset}%
%    \bgroup
%       \useparinsertstyleandcolor\c!style\c!color
%       #3%
%    \egroup
%    \scratchdistance{\parinsertparameter\c!distance}%
%    \scratchwidth{\wd\scratchbox+\scratchdistance}%
%    \scratchcounter{\parinsertparameter\c!lines}%
%    \ifzero\scratchcounter
%      \getnoflines{\htdp\scratchbox}%
%      \scratchcounter\noflines
%    \fi
%    \ifcstok{\parinsertparameter\c!location}\v!right
%      \atrightmargin{\llap{\box\scratchbox}}%
%      \scratchwidth-\scratchwidth
%    \else
%      \atleftmargin{\rlap{\box\scratchbox}}%
%    \fi
%    \localhangindent\scratchwidth
%    \localhangafter \scratchcounter
%    \typo_par_insert_trace
%    \ifcstok{\parinsertparameter\c!option}\v!depth
%      \optionspar\plusone % todo: symbolic
%    \fi
%    \endgroup}

% \permanent\tolerant\protected\def\typo_parinsert_handle#1#*[#2]%
%   {\begingroup
%    \cdef\currentparinsert{#1}%
%    \ifparameter#2\or
%       \setupcurrentparinsert[#2]%
%    \fi
%    \dowithnextboxcontent
%      {\useparinsertstyleandcolor\c!style\c!color}%
%      {\scratchxoffset{\parinsertparameter\c!xoffset}%
%       \scratchyoffset{\parinsertparameter\c!yoffset}%
%       \scratchdistance{\parinsertparameter\c!distance}%
%       \scratchwidth{\wd\nextbox+\scratchdistance}%
%       \scratchcounter{\parinsertparameter\c!lines}%
%       %
%       \advance\scratchxoffset\ifnum\hangindent<\zeropoint-\fi\hangindent
%       \boxxoffset\nextbox\scratchxoffset
%       \boxyoffset\nextbox\scratchyoffset
%       %
%       \ifzero\scratchcounter
%         \getnoflines{\htdp\nextbox}%
%         \scratchcounter\noflines
%       \fi
%       \ifcstok{\parinsertparameter\c!location}\v!right
%         \scratchwidth-\scratchwidth
%         \atrightmargin{\llap{\box\nextbox}}%
%       \else
%         \atleftmargin {\rlap{\box\nextbox}}%
%       \fi
%       \localhangindent\scratchwidth
%       \localhangafter \scratchcounter
%       \typo_par_insert_trace
%       \ifcstok{\parinsertparameter\c!option}\v!depth
%         \optionspar\plusone % todo: symbolic
%       \fi
%       \endgroup}\hbox}

\permanent\tolerant\protected\def\typo_parinsert_handle#1#*[#2]%
  {\begingroup
   \cdef\currentparinsert{#1}%
   \ifparameter#2\or
      \setupcurrentparinsert[#2]%
   \fi
   \dowithnextboxcontent
     {\useparinsertstyleandcolor\c!style\c!color}%
     {\scratchxoffset{\parinsertparameter\c!xoffset}%
      \scratchyoffset{\parinsertparameter\c!yoffset}%
      \scratchdistance{\parinsertparameter\c!distance}%
      \scratchwidth{\wd\nextbox+\scratchdistance}%
      \scratchcounter{\parinsertparameter\c!lines}%
      \ifzero\scratchcounter
        \getnoflines{\htdp\nextbox}%
        \scratchcounter\noflines
      \fi
      \setbox\nextbox\hpack{\box\nextbox}% keep inner dimensions
      \ht\nextbox\strutht
      \dp\nextbox\strutdp
      %
      \ifcstok{\parinsertparameter\c!location}\v!right
        \donefalse
        \advance\scratchxoffset\scratchdistance
        \scratchwidth-\scratchwidth
      \else
        \donetrue
        \advance\scratchxoffset-\scratchwidth
      \fi
      \boxxoffset\nextbox\scratchxoffset
      \boxyoffset\nextbox\scratchyoffset
      \localhangindent\scratchwidth
      \localhangafter \scratchcounter
      \typo_par_insert_trace
      \ifcstok{\parinsertparameter\c!option}\v!depth
        \optionspar\plusone % todo: symbolic
      \fi
      % We use an "always" local par node that gets injected after and before
      % the hang related anchors. Par nodes flagged as such are ignored by the
      % par builder and only seen in the (wrapup) packager.
      \dontleavehmode
      \ifdone\localleftbox\else\localrightbox\fi \s!always
        \bgroup \hpack to \zeropoint \bgroup
          \box\nextbox
        \egroup \egroup
      \endgroup
     }\hbox}

\def\typo_par_insert_trace_indeed
  {\begingroup
     \darkgray
     \scratchwidth.125\emwidth
     \kern-\scratchwidth
     \vrule \s!width 2\scratchwidth \s!pair \strutht \strutdp
     \kern-\scratchwidth
   \endgroup}

\installtextracker
  {parinsert}
  {\let\typo_par_insert_trace\typo_par_insert_trace_indeed}
  {\lettonothing\typo_par_insert_trace}

\lettonothing\typo_par_insert_trace

\appendtoks
    \protected\instance\edefcsname\currentparinsert\endcsname{\typo_parinsert_handle{\currentparinsert}}
\to \everydefineparinsert

%D In case we ended a paragraph and want to continue:

\permanent\protected\def\pickupparinsert
  {\expanded{%
     \ifcase{\breaklasthangleftslack+\breaklasthangrightslack}\else
       \strut
       \ifcase\breaklasthangleftslack\else
         \localhangindent\the\breaklasthangleftindent
         \localhangafter \the\breaklasthangleftslack
       \fi
       \ifcase\breaklasthangrightslack\else
         \localhangindent -\the\breaklasthangrightindent
         \localhangafter   \the\breaklasthangrightslack
       \fi
     \fi}}

\permanent\protected\def\wrapupparinsert
  {\ifvmode
     \ifcase{\breaklasthangleftslack+\breaklasthangrightslack}\else
       \vskip
         \ifnum\breaklasthangleftslack>\breaklasthangrightslack
           \breaklasthangleftslack
         \else
           \breaklasthangrightslack
         \fi
         \lineheight
       \relax
     \fi
   \fi}

%D Not yet interfaced:

\defineparinsert[leftparinsert]
\defineparinsert[rightparinsert]

\setupparinsert[leftparinsert] [\c!location=\v!left]
\setupparinsert[rightparinsert][\c!location=\v!right]

\protect \endinput
