diff options
Diffstat (limited to 'tex/context/base/mkiv/page-otr.mkvi')
-rw-r--r-- | tex/context/base/mkiv/page-otr.mkvi | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/page-otr.mkvi b/tex/context/base/mkiv/page-otr.mkvi new file mode 100644 index 000000000..ec38a06c1 --- /dev/null +++ b/tex/context/base/mkiv/page-otr.mkvi @@ -0,0 +1,296 @@ +%D \module +%D [ file=page-otr, +%D version=2012.01.25, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Output Routines, +%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 Page Macros / Output Routines} + +%D This module will get some of the code from other modules. At the +%D same time we provide a bit more control. + +% When issuing two \par\penalty-\plustenthousand's, only the first +% triggers the otr. Is this an obscure feature or an optimization? + +\registerctxluafile{page-otr}{1.001} + +\unprotect + +\let\triggerpagebuilder\clf_triggerpagebuilder + +\def\m!otr{otr} % todo + +\installcorenamespace{outputroutine} + +\installswitchcommandhandler \??outputroutine {outputroutine} \??outputroutine + +\newtoks\t_page_otr_commands +\newtoks\t_page_otr_tracers + +\unexpanded\def\defineoutputroutinecommand[#name]% doing multiple on one go saves syncing + {\processcommalist[#name]\page_otr_commands_define} + +\unexpanded\def\page_otr_commands_define#name% + {\ifcsname#name\endcsname \else + \expandafter\let\csname#name\endcsname\relax + \normalexpanded{\t_page_otr_commands{\the\t_page_otr_commands\noexpand\page_otr_commands_process{#name}}}% + \fi} + +\let\page_otr_commands_process\gobbleoneargument + +\appendtoks + \let\page_otr_commands_process\page_otr_specifics_preset + \the\t_page_otr_commands + \let\page_otr_commands_process\gobbleoneargument +\to \everyswitchoutputroutine + +\unexpanded\def\page_otr_specifics_preset#name% + {\edef\page_otr_specifics_command{\strictoutputroutineparameter{#name}}% no inheritance of commands + \ifx\page_otr_specifics_command\empty + \writestatus{\currentoutputroutine}{- \expandafter\strippedcsname\csname#name\endcsname}% + \expandafter\let\csname#name\endcsname\relax + \else + \writestatus{\currentoutputroutine}{+ \expandafter\strippedcsname\csname#name\endcsname}% + \expandafter\let\csname#name\expandafter\endcsname\page_otr_specifics_command + \fi} + +\unexpanded\def\page_otr_specifics_preset_normal#name% + {\edef\page_otr_specifics_command{\strictoutputroutineparameter{#name}}% no inheritance of commands + \ifx\page_otr_specifics_command\empty + \expandafter\let\csname#name\endcsname\relax + \else + \expandafter\let\csname#name\expandafter\endcsname\page_otr_specifics_command + \fi} + +\unexpanded\def\page_otr_specifics_preset_traced#name% + {\edef\page_otr_specifics_command{\strictoutputroutineparameter{#name}}% no inheritance of commands + \ifx\page_otr_specifics_command\empty + \writestatus{\currentoutputroutine}{preset: - \expandafter\strippedcsname\csname#name\endcsname}% + \expandafter\let\csname#name\endcsname\relax + \else + \writestatus{\currentoutputroutine}{preset: + \expandafter\strippedcsname\csname#name\endcsname}% + \expandafter\let\csname#name\expandafter\endcsname\page_otr_specifics_command + \fi} + +\let\page_otr_specifics_preset\page_otr_specifics_preset_normal + +\unexpanded\def\traceoutputroutines + {\the\t_page_otr_tracers} + +\appendtoks + \let\page_otr_specifics_preset\page_otr_specifics_preset_traced +\to \t_page_otr_tracers + +%D We have a couple of output routines and the default one is +%D the single column routine. Then there is a multicolumn variant +%D that can be used mixed, and a columnset variant that is more +%D exclusive. + +\installcorenamespace{otrtriggers} + +\newconstant\c_page_otr_eject_penalty \c_page_otr_eject_penalty -\plustenthousand +\newconstant\c_page_otr_super_penalty \c_page_otr_super_penalty -\plustwentythousand +\newcount \c_page_otf_trigger_penalty \c_page_otf_trigger_penalty -100010 + +\newif \ifinotr % we keep this (name) for old times sake + +\unexpanded\def\page_otr_message_b{\page_otr_message_s+} +\unexpanded\def\page_otr_message_e{\page_otr_message_s-} + +\unexpanded\def\page_otr_message_s#sign#what% + {\writestatus + \currentoutputroutine + {#sign\space \space + #what\space \space + p:\the\outputpenalty,\space + r:\the\realpageno ,\space + c:\number\mofcolumns,\space + v:\the\vsize ,\space + g:\the\pagegoal ,\space + t:\the\pagetotal ,\space + \ifdim\pagetotal>\pagegoal + d:\the\dimexpr\pagetotal-\pagegoal\relax + \fi}} + +\unexpanded\def\page_otr_trigger#penalty% + {\begingroup + \par + \penalty#penalty% + \endgroup} + +\unexpanded\def\installoutputroutine#invoke#action% \invoke \action + {\global\advance\c_page_otf_trigger_penalty\minusone + \edef#invoke{\page_otr_trigger{\number\c_page_otf_trigger_penalty}}% + \setvalue{\??otrtriggers\number\c_page_otf_trigger_penalty}{#action}} + +\unexpanded\def\page_otr_triggered_output_routine_traced + {\ifcsname\??otrtriggers\the\outputpenalty\endcsname + \page_otr_message_b{special}% + \csname\??otrtriggers\the\outputpenalty\endcsname % \lastnamedcs can be gone + \page_otr_message_e{special}% + \else + \page_otr_message_b{normal}% + \page_otr_command_routine + \page_otr_message_e{normal}% + \fi} + +\unexpanded\def\page_otr_triggered_output_routine_normal + {\ifcsname\??otrtriggers\the\outputpenalty\endcsname + \lastnamedcs + \else + \page_otr_command_routine + \fi} + +\let\page_otr_triggered_output_routine\page_otr_triggered_output_routine_normal + +\appendtoks + \let\page_otr_triggered_output_routine\page_otr_triggered_output_routine_traced +\to \t_page_otr_tracers + +%D The real routine handler: + +\ifdefined\everybeforeoutput \else \newtoks\everybeforeoutput \fi +\ifdefined\everyafteroutput \else \newtoks\everyafteroutput \fi + +\def\page_otf_set_engine_output_routine#content% + {\global\output + {\inotrtrue + \the\everybeforeoutput + #content\relax + \the\everyafteroutput}} + +\page_otf_set_engine_output_routine\page_otr_triggered_output_routine + +\installoutputroutine\synchronizeoutput + {\ifvoid\normalpagebox\else + \unvbox\normalpagebox + \pagediscards + \fi} + +\installoutputroutine\discardpage + {\setbox\scratchbox\box\normalpagebox} + +% todo: \resetpagebreak -> everyejectpage + +\def\page_otr_trigger_output_routine + {\par + \ifvmode + \penalty\c_page_otr_eject_penalty + \fi + \resetpagebreak} + +\def\page_otr_fill_and_eject_page + {\par + \ifvmode + \vfill + \penalty\c_page_otr_eject_penalty + \fi + \resetpagebreak} + +\def\page_otr_eject_page + {\par + \ifvmode + \ifdim\pagetotal>\pagegoal \else + \normalvfil + \fi + \penalty\c_page_otr_eject_penalty + \fi + \resetpagebreak} + +\def\page_otr_eject_page_and_flush_inserts % can be an installed one + {\par + \ifvmode + \ifdim\pagetotal>\pagegoal \else + \normalvfil + \fi + \penalty\c_page_otr_super_penalty + \fi + \resetpagebreak} + +\def\page_otr_check_for_pending_inserts + {\ifnum\outputpenalty>\c_page_otr_super_penalty \else + \ifnum\insertpenalties>\zerocount + % something is being held over so we force a new page + \page_otr_force_another_page + \fi + \fi} + +\def\page_otr_force_another_page + {% we should actually remove the dummy line in the otr + \hpack to \hsize{}% + \kern-\topskip + \nobreak + \vfill + \penalty\c_page_otr_super_penalty + \resetpagebreak} + +%D For those who've read the plain \TEX\ book, we provide the next +%D macro: + +\unexpanded\def\bye + {\writestatus\m!system{Sorry, you're not done yet, so no goodbye!}} + +%D We define a few constants because that (1) provides some checking +%D and (2) is handier when aligning definitions (checks nicer). + +\definesystemconstant{page_otr_command_routine} +\definesystemconstant{page_otr_command_package_contents} +\definesystemconstant{page_otr_command_set_vsize} +\definesystemconstant{page_otr_command_set_hsize} +\definesystemconstant{page_otr_command_synchronize_hsize} +\definesystemconstant{page_otr_command_next_page} +\definesystemconstant{page_otr_command_next_page_and_inserts} +\definesystemconstant{page_otr_command_set_top_insertions} +\definesystemconstant{page_otr_command_set_bottom_insertions} +\definesystemconstant{page_otr_command_flush_top_insertions} +\definesystemconstant{page_otr_command_flush_bottom_insertions} +\definesystemconstant{page_otr_command_check_if_float_fits} +\definesystemconstant{page_otr_command_set_float_hsize} +\definesystemconstant{page_otr_command_flush_float_box} +\definesystemconstant{page_otr_command_side_float_output} +\definesystemconstant{page_otr_command_synchronize_side_floats} +\definesystemconstant{page_otr_command_flush_floats} +\definesystemconstant{page_otr_command_flush_side_floats} +\definesystemconstant{page_otr_command_flush_saved_floats} +\definesystemconstant{page_otr_command_flush_margin_blocks} +\definesystemconstant{page_otr_command_test_column} + +\definesystemconstant{singlecolumn} +\definesystemconstant{multicolumn} % will move +\definesystemconstant{columnset} % will move + +\defineoutputroutinecommand + [\s!page_otr_command_routine, + \s!page_otr_command_package_contents, + \s!page_otr_command_set_vsize, + \s!page_otr_command_set_hsize, + \s!page_otr_command_synchronize_hsize, % for columns of different width + \s!page_otr_command_next_page, + \s!page_otr_command_next_page_and_inserts, + \s!page_otr_command_set_top_insertions, + \s!page_otr_command_set_bottom_insertions, + \s!page_otr_command_flush_top_insertions, + \s!page_otr_command_flush_bottom_insertions, + \s!page_otr_command_check_if_float_fits, + \s!page_otr_command_set_float_hsize, + \s!page_otr_command_flush_float_box, + \s!page_otr_command_side_float_output, % name will change as will hooks + \s!page_otr_command_synchronize_side_floats, + \s!page_otr_command_flush_floats, + \s!page_otr_command_flush_side_floats, + \s!page_otr_command_flush_saved_floats, + \s!page_otr_command_flush_margin_blocks, + \s!page_otr_command_test_column] + +\appendtoks + \setupoutputroutine[\s!singlecolumn]% +\to \everydump + +\protect \endinput |