%D \module %D [ file=spac-par, %D version=2009.10.16, % 1997.03.31, was core-spa.tex %D title=\CONTEXT\ Spacing Macros, %D subtitle=Paragraphs, %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 Spacing Macros / Paragraphs} \unprotect %D The dreadful sequence \type {\bgroup} \unknown\ %D \type {\carryoverpar} \unknown\ \type {\egroup} is needed %D when for instance sidefloats are used in combination with %D something that starts with a group. This is because %D otherwise the indentation as set (by the output routine) %D inside the group are forgotten afterwards. (I must %D not forget its existence). \def\carryoverpar#1% #1 can be \endgroup or \egroup or ... expandable ! {\normalexpanded {\noexpand#1% \hangindent\the\hangindent \hangafter \the\hangafter \parskip \the\parskip \leftskip \the\leftskip \rightskip \the\rightskip}} \unexpanded\def\pushparagraphproperties {\edef\currentparagraphproperties{\carryoverpar\relax}% \pushmacro\currentparagraphproperties} \unexpanded\def\popparagraphproperties {\popmacro\currentparagraphproperties \currentparagraphproperties} \unexpanded\def\flushparagraphproperties {\popmacro\currentparagraphproperties} % Beware, changing this will break some code (like pos/backgrounds) but % it has been changed anyway so let's see where things go wrong. \installcorenamespace{paragraphintro} \let\insertparagraphintro\relax % hook into everypar \newtoks\t_spac_paragraphs_intro_first \newtoks\t_spac_paragraphs_intro_next \newtoks\t_spac_paragraphs_intro_each \newconditional\c_spac_paragraphs_intro_first \newconditional\c_spac_paragraphs_intro_next \newconditional\c_spac_paragraphs_intro_each \unexpanded\def\setupparagraphintro {\dodoubleempty\spac_paragraphs_intro} \unexpanded\def\spac_paragraphs_intro[#1][#2]% {\def\spac_paragraphs_intro_step##1% {\csname\??paragraphintro\ifcsname\??paragraphintro##1\endcsname##1\fi\endcsname{#2}}% \processcommacommand[#1]\spac_paragraphs_intro_step} \letvalue{\??paragraphintro\empty}\gobbleoneargument \setvalue{\??paragraphintro\v!reset}#1% {\global\setfalse\c_spac_paragraphs_intro_first \global\setfalse\c_spac_paragraphs_intro_next \global\setfalse\c_spac_paragraphs_intro_each \global\t_spac_paragraphs_intro_first\emptytoks \global\t_spac_paragraphs_intro_next \emptytoks \global\t_spac_paragraphs_intro_each \emptytoks \glet\insertparagraphintro\relax} \setvalue{\??paragraphintro\v!first}#1% {\global\settrue\c_spac_paragraphs_intro_first \gtoksapp\t_spac_paragraphs_intro_first{#1}% \glet\insertparagraphintro\spac_paragraphs_flush_intro} \setvalue{\??paragraphintro\v!next}#1% {\global\settrue\c_spac_paragraphs_intro_next \gtoksapp\t_spac_paragraphs_intro_next{#1}% \glet\insertparagraphintro\spac_paragraphs_flush_intro} \setvalue{\??paragraphintro\v!each}#1% {\global\settrue\c_spac_paragraphs_intro_each \gtoksapp\t_spac_paragraphs_intro_each{#1}% \glet\insertparagraphintro\spac_paragraphs_flush_intro} %D We can say: %D %D \starttyping %D \setupparagraphintro[first][\index{Knuth}] %D \stoptyping %D %D Maybe more convenient is: %D %D \starttyping %D \flushatparagraph{\index{Zapf}} %D \stoptyping %D %D \starttyping %D \setupparagraphintro[first][\hbox to 3.5em{\tt FIRST \hss}] %D \setupparagraphintro[first][\hbox to 3.5em{\tt TSRIF \hss}] %D \setupparagraphintro[next] [\hbox to 3.5em{\tt NEXT \hss}] %D \setupparagraphintro[next] [\hbox to 3.5em{\tt TXEN \hss}] %D \setupparagraphintro[each] [\hbox to 3.0em{\tt EACH \hss}] %D \setupparagraphintro[each] [\hbox to 3.0em{\tt HCEA \hss}] %D %D some paragraph \par %D some paragraph \par %D some paragraph \par %D some paragraph \par %D %D \setupparagraphintro[first][\hbox to 3.5em{\tt FIRST \hss}] %D \setupparagraphintro[first][\hbox to 3.5em{\tt TSRIF \hss}] %D %D some paragraph \par %D some paragraph \par %D %D \setupparagraphintro[reset] %D %D some paragraph \par %D \stoptyping \unexpanded\def\flushatparagraph#1% {\global\c_spac_paragraphs_intro_first\plusone \gtoksapp\t_spac_paragraphs_intro_first{#1}% \glet\insertparagraphintro\spac_paragraphs_flush_intro} %D Here comes the flusher (we misuse the one level expansion of token %D registers to feed a nice stream into the paragraph.) \unexpanded\def\spac_paragraphs_flush_intro % we make sure that the token lists expand directly after another {\normalexpanded{% % so the first code is there twice \ifconditional\c_spac_paragraphs_intro_each \ifconditional\c_spac_paragraphs_intro_next \glet\insertparagraphintro\spac_paragraphs_flush_intro_next \else \glet\insertparagraphintro\spac_paragraphs_flush_intro_each \fi \ifconditional\c_spac_paragraphs_intro_first \global\setfalse\c_spac_paragraphs_intro_first \global\t_spac_paragraphs_intro_first\emptytoks \the\t_spac_paragraphs_intro_first \fi \the\t_spac_paragraphs_intro_each \else \ifconditional\c_spac_paragraphs_intro_next \glet\insertparagraphintro\spac_paragraphs_flush_intro_next \fi \ifconditional\c_spac_paragraphs_intro_first \global\setfalse\c_spac_paragraphs_intro_first \global\t_spac_paragraphs_intro_first\emptytoks \the\t_spac_paragraphs_intro_first \fi \fi}} \unexpanded\def\spac_paragraphs_flush_intro_next {\normalexpanded{% \global\setfalse\c_spac_paragraphs_intro_next \global\t_spac_paragraphs_intro_next\emptytoks \ifconditional\c_spac_paragraphs_intro_each \glet\insertparagraphintro\spac_paragraphs_flush_intro_each \the\t_spac_paragraphs_intro_next \the\t_spac_paragraphs_intro_each \else \glet\insertparagraphintro\relax \the\t_spac_paragraphs_intro_next \fi}} \unexpanded\def\spac_paragraphs_flush_intro_each {\the\t_spac_paragraphs_intro_each} %D \macros %D {flushatnextpar} %D %D This macro collects data that will be flushed at the next paragraph. %D By using this macro you can avoid interfering nodes (writes, etc). \let\flushpostponednodedata\relax % hook into everypar \newbox \b_spac_postponed_data %newcount\c_spac_postponed_data % \installcorenamespace {postponednodesstack} % % \initializeboxstack\??postponednodesstack % % \unexpanded\def\pushpostponednodedata % {\global\advance\c_spac_postponed_data\plusone % \savebox\??postponednodesstack{\the\c_spac_postponed_data}{\box\b_spac_postponed_data}} % % \unexpanded\def\poppostponednodedata % {\global\setbox\b_spac_postponed_data\hbox{\foundbox\??postponednodesstack{\the\c_spac_postponed_data}}% % \global\advance\c_spac_postponed_data\minusone % \ifvoid\b_spac_postponed_data\else % \glet\flushpostponednodedata\spac_postponed_data_flush % \fi} \newtoks\everyflushatnextpar \unexpanded\def\pushpostponednodedata {\globalpushbox\b_spac_postponed_data} \unexpanded\def\poppostponednodedata {\globalpopbox\b_spac_postponed_data \ifvoid\b_spac_postponed_data\else \glet\flushpostponednodedata\spac_postponed_data_flush \fi} \unexpanded\def\flushatnextpar {\begingroup \the\everyflushatnextpar \glet\flushpostponednodedata\spac_postponed_data_flush \dowithnextboxcs\spac_postponed_data_finish\hpack} \def\spac_postponed_data_finish {\global\setbox\b_spac_postponed_data\hpack % to\zeropoint {\box\b_spac_postponed_data\box\nextbox}% \endgroup} \def\spac_postponed_data_flush {%\iftrialtypesetting \else \ifvoid\b_spac_postponed_data\else \hpack{\smashedbox\b_spac_postponed_data}% \box\b_spac_postponed_data \fi \glet\flushpostponednodedata\relax }%\fi} \unexpanded\def\doflushatpar % might be renamed {\ifvmode \expandafter\flushatnextpar \else \expandafter\firstofoneargument \fi} \protect \endinput