summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/spac-par.mkxl
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/spac-par.mkxl')
-rw-r--r--tex/context/base/mkiv/spac-par.mkxl339
1 files changed, 339 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/spac-par.mkxl b/tex/context/base/mkiv/spac-par.mkxl
new file mode 100644
index 000000000..b136b5bce
--- /dev/null
+++ b/tex/context/base/mkiv/spac-par.mkxl
@@ -0,0 +1,339 @@
+%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}
+
+\registerctxluafile{spac-par}{autosuffix}
+
+\unprotect
+
+%D New experimental stuff:
+
+\let\spac_paragraph_freeze\relax
+
+\protected\def\freezeparagraphproperties {\snapshotpar\maxcount}
+\protected\def\defrostparagraphproperties{\snapshotpar\zerocount}
+
+\protected\def\setparagraphfreezing {\let\spac_paragraph_freeze\freezeparagraphproperties}
+\protected\def\forgetparagraphfreezing{\let\spac_paragraph_freeze\relax}
+
+\installcorenamespace {bparwrap}
+\installcorenamespace {eparwrap}
+
+\let\spac_paragraph_wrap\relax
+
+\protected\def\spac_paragraph_update
+ {\ifcsname\??bparwrap\the\currentgrouplevel\endcsname
+ \the\lastnamedcs
+ \wrapuppar{\the\csname\??eparwrap\the\currentgrouplevel\endcsname}%
+ \fi}
+
+
+\protected\def\spac_paragraph_install
+ {\expandafter\newtoks\csname\??bparwrap\the\currentgrouplevel\endcsname
+ \expandafter\newtoks\csname\??eparwrap\the\currentgrouplevel\endcsname}
+
+% \protected\def\registerparwrapper#1#2%
+% {\ifcsname\??bparwrap\the\currentgrouplevel\endcsname \else
+% \spac_paragraph_install
+% \fi
+% \toksapp\csname\??bparwrap\the\currentgrouplevel\endcsname{#1}%
+% \tokspre\csname\??eparwrap\the\currentgrouplevel\endcsname{#2}%
+% \let\spac_paragraph_wrap\spac_paragraph_update}
+
+% \protected\def\registerparwrapperreverse#1#2%
+% {\ifcsname\??bparwrap\the\currentgrouplevel\endcsname \else
+% \spac_paragraph_install
+% \fi
+% \tokspre\csname\??bparwrap\the\currentgrouplevel\endcsname{#1}%
+% \toksapp\csname\??eparwrap\the\currentgrouplevel\endcsname{#2}%
+% \let\spac_paragraph_wrap\spac_paragraph_update}
+
+\protected\def\registerparwrapper#1#2#3%
+ {\ifcsname\??bparwrap\the\currentgrouplevel\endcsname \else
+ \spac_paragraph_install
+ \fi
+ \clf_newparwrapper{#1}%
+ \toksapp\csname\??bparwrap\the\currentgrouplevel\endcsname{\clf_setparwrapper{#1}#2}%
+ \tokspre\csname\??eparwrap\the\currentgrouplevel\endcsname{#3}%
+ \let\spac_paragraph_wrap\spac_paragraph_update}
+
+\protected\def\registerparwrapperreverse#1#2#3%
+ {\ifcsname\??bparwrap\the\currentgrouplevel\endcsname \else
+ \spac_paragraph_install
+ \fi
+ \clf_newparwrapper{#1}%
+ \tokspre\csname\??bparwrap\the\currentgrouplevel\endcsname{\clf_setparwrapper{#1}#2}%
+ \toksapp\csname\??eparwrap\the\currentgrouplevel\endcsname{#3}%
+ \let\spac_paragraph_wrap\spac_paragraph_update}
+
+\protected\def\forgetparwrapper
+ {\csname\??bparwrap\the\currentgrouplevel\endcsname\emptytoks
+ \csname\??eparwrap\the\currentgrouplevel\endcsname\emptytoks}
+
+% \getparwrapper % defined in lua
+% \lastparwrapper % defined in lua
+
+\protected\def\showparwrapperstate#1%
+ {\begingroup
+ \infofont ΒΆ#1\hilo
+ {\smallinfofont\getparwrapper {#1}}%
+ {\smallinfofont\lastparwrapper{#1}}%
+ \endgroup}
+
+\appendtoks \updateparwrapperindeed \to\everypar
+\appendtoks\let\updateparwrapperindeed\relax\to\everyforgetall
+
+\installtexexperiment
+ {paragraphs.freeze}
+ {\setparagraphfreezing
+ \appendtoksonce\spac_paragraph_wrap \to \everypar
+ \appendtoksonce\spac_paragraph_freeze\to \everypar}
+ {\forgetparagraphfreezing
+ \removetoks \spac_paragraph_wrap \from\everypar
+ \removetoks \spac_paragraph_freeze\from\everypar}
+
+%D In due time, the code below will be upgraded using the above mechanisms.
+
+%D The dreadful sequence \type {\bgroup} \unknown\ \type {\carryoverpar} \unknown\
+%D \type {\egroup} is needed when for instance sidefloats are used in combination
+%D with something that starts with a group. This is because otherwise the
+%D indentation as set (by the output routine) inside the group are forgotten
+%D afterwards. (I must not forget its existence).
+
+% Todo (maybe):
+%
+% \parshape \getparshape\relax
+% \interlinepenalties \getinterlinepenalties\relax
+% \clubpenalties \getclubpenalties\relax
+% \widowpenalties \getwidowpenalties\relax
+% \displaywidowpenalties\getdisplaywidowpenalties\relax
+
+\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}
+
+%D Beware, changing this will break some code (like pos/backgrounds) but it has been
+%D 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 registers to
+%D feed a nice stream into the paragraph.)
+
+\unexpanded\def\spac_paragraphs_flush_intro % we make sure that the token lists expand directly
+ {\normalexpanded{% % after another 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. By using
+%D 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