summaryrefslogtreecommitdiff
path: root/tex/context/base/page-brk.mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/page-brk.mkiv')
-rw-r--r--tex/context/base/page-brk.mkiv393
1 files changed, 393 insertions, 0 deletions
diff --git a/tex/context/base/page-brk.mkiv b/tex/context/base/page-brk.mkiv
new file mode 100644
index 000000000..0ee720662
--- /dev/null
+++ b/tex/context/base/page-brk.mkiv
@@ -0,0 +1,393 @@
+%D \module
+%D [ file=page-brk, % moved from page-ini
+%D version=2011.12.07, % 2000.10.20,
+%D title=\CONTEXT\ Page Macros,
+%D subtitle=Breaks,
+%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 / Breaks}
+
+\unprotect
+
+\ifdefined\resetcurrentstructuremarkswithpage \else \let\resetcurrentstructuremarkswithpage\relax \fi
+\ifdefined\noheaderandfooterlines \else \let\noheaderandfooterlines \relax \fi
+
+%D Page breaks.
+
+% \definepagebreak
+% [chapter]
+% [yes,header,right]
+%
+% \setuphead
+% [chapter]
+% [page=chapter,
+% header=empty,
+% footer=chapter]
+%
+% \definepagebreak % untested
+% [lastpage]
+% [left,{empty,right},{empty,left}]
+
+% public page handler, beware: definepage already in use (core-ref)
+%
+% \definepagebreak[instance][forsure]
+% \definepagebreak[forsure][yes,+4]
+
+\newconditional\c_page_breaks_enabled \settrue\c_page_breaks_enabled
+\newcount \c_page_breaks_prevpage
+
+\newtoks\everybeforepagebreak
+\newtoks\everyafterpagebreak
+
+\let\page_breaks_current_option \empty
+\let\page_breaks_current_options\empty
+
+\def\page_breaks_handle#1%
+ {\edef\page_breaks_current_options{#1}% handy for tracing
+ \processcommacommand[\page_breaks_current_options]\page_breaks_handle_indeed}
+
+\def\page_breaks_handle_indeed#1%
+ {\edef\page_breaks_current_option{#1}% can be used in handler
+ \ifcsname\??pe:\page_breaks_current_option\endcsname
+ \csname\??pe:\page_breaks_current_option\endcsname
+ \else\ifcsname\??pe::\page_breaks_current_option\endcsname
+ \expandafter\page_breaks_handle\csname\??pe::\page_breaks_current_option\endcsname
+ \else
+ \csname\??pe:\s!unknown\endcsname
+ \fi\fi}
+
+\def\page_breaks_handle_direct#1%
+ {\csname\??pe:#1\endcsname}
+
+\def\installpagebreakhandler#1#2% low level definer
+ {\setvalue{\??pe:#1}{#2}}
+
+\unexpanded\def\definepagebreak
+ {\dodoubleargument\page_breaks_define}
+
+\def\page_breaks_define[#1][#2]%
+ {\setvalue{\??pe::#1}{#2}}
+
+\unexpanded\def\pagebreak
+ {\dosingleempty\page_breaks_process}
+
+\let\page\pagebreak
+
+\appendtoks
+ \flushnotes
+\to \everybeforepagebreak
+
+\def\page_breaks_process[#1]% so, page ornaments are reset after a pagebreak command, unless set
+ {\par % always before group so that we clear hangs etc (as in side floats)
+ \ifvmode % extra check
+ \begingroup
+ \the\everybeforepagebreak
+ \c_page_breaks_prevpage\realpageno
+ \ifcase\pageornamentstate \or
+ % disable reset after shipout
+ \global\pageornamentstate\plustwo
+ \fi
+ \iffirstargument % or if empty i.e. []
+ \page_breaks_handle{#1}%
+ \else % so, no pagebreak when \pagebreak[] ! ! !
+ \page_breaks_handle_direct\v!yes
+ \fi
+ \relax
+ \ifnum\c_page_breaks_prevpage<\realpageno
+ \global\pageornamentstate\zerocount
+ \fi
+ \the\everyafterpagebreak
+ \endgroup
+ \fi}
+
+\def\resetpagebreak % used elsewhere too
+ {\global\settrue\c_page_breaks_enabled}
+
+\def\simplifypagebreak % to be used grouped !
+ {\def\page_breaks_process[##1]{\goodbreak}}
+
+\def\disablepagebreaks % to be used grouped !
+ {\def\page_breaks_process[##1]{}}
+
+\installpagebreakhandler \s!dummy
+ {\page_otr_flush_all_floats
+ \gotonextpage
+ \page_otr_insert_dummy_page}
+
+\installpagebreakhandler \v!frame
+ {\page
+ \begingroup
+ \showframe
+ \page[\v!empty]
+ \endgroup}
+
+\installpagebreakhandler \s!unknown
+ {\doifinstringelse{+}\page_breaks_current_option
+ {\page_otr_flush_all_floats
+ \gotonextpage
+ \dorecurse\page_breaks_current_option\page_otr_insert_dummy_page}
+ {\doifnumberelse\page_breaks_current_option
+ {\page_otr_flush_all_floats
+ \gotonextpage
+ \doloop
+ {\ifnum\userpageno<\page_breaks_current_option\relax
+ \page_otr_insert_dummy_page
+ \else
+ \exitloop
+ \fi}}
+ {}}}
+
+\installpagebreakhandler \s!default
+ {} % do nothing if empty
+
+\installpagebreakhandler \v!reset
+ {% better not: \global\pageornamentstate\zerocount
+ \resetpagebreak}
+
+\installpagebreakhandler \v!disable
+ {\global\setfalse\c_page_breaks_enabled}
+
+\installpagebreakhandler \v!yes
+ {\ifconditional\c_page_breaks_enabled
+ \page_otr_flush_all_floats
+ \gotonextpage
+ \ifinsidecolumns % this will move to MUL
+ \page_otr_eject_page % otherwise sometimes no change
+ \fi
+ \fi}
+
+\installpagebreakhandler \v!makeup
+ {\ifconditional\c_page_breaks_enabled
+ \page_otr_fill_and_eject_page
+ \fi}
+
+\installpagebreakhandler \v!blank
+ {\ifcase\pageornamentstate
+ \global\pageornamentstate\plusone
+ \fi}
+
+\installpagebreakhandler \v!no
+ {\ifconditional\c_page_breaks_enabled
+ \dosomebreak\nobreak
+ \fi}
+
+\installpagebreakhandler \v!preference
+ {\ifconditional\c_page_breaks_enabled
+ \ifinsidecolumns % this will move to MUL
+ \dosomebreak\goodbreak
+ \else
+ \testpage[3][\zeropoint]%
+ \fi
+ \fi}
+
+\installpagebreakhandler \v!bigpreference
+ {\ifconditional\c_page_breaks_enabled
+ \ifinsidecolumns % this will move to MUL
+ \dosomebreak\goodbreak
+ \else
+ \testpage[5][\zeropoint]%
+ \fi
+ \fi}
+
+% \installpagebreakhandler \v!empty {} % defined in page-txt.mkiv
+% \installpagebreakhandler \v!header{} % defined in page-txt.mkiv
+% \installpagebreakhandler \v!footer{} % defined in page-txt.mkiv
+% \installpagebreakhandler \v!left {} % defined in page-txt.mkiv
+
+\installpagebreakhandler \v!right
+ {\page_otr_flush_all_floats
+ \gotonextpageX % will become \gotonextpage
+ \doifbothsidesoverruled{}{}{\resetcurrentstructuremarkswithpage\page_otr_insert_dummy_page}}
+
+\installpagebreakhandler \v!even
+ {\page
+ \doifoddpageelse{\resetcurrentstructuremarkswithpage\page_otr_insert_dummy_page}\donothing}
+
+\installpagebreakhandler \v!odd
+ {\page
+ \doifoddpageelse\donothing{\resetcurrentstructuremarkswithpage\page_otr_insert_dummy_page}}
+
+\installpagebreakhandler \v!quadruple % not yet ok inside columnsets
+ {\ifdoublesided
+ \ifnum\numexpr\realpageno/4\relax=\numexpr\realpageno/2\relax\else
+ \page_breaks_handle_direct\v!yes
+ \page_breaks_handle_direct\v!empty
+ \page_breaks_handle_direct\v!empty
+ \fi
+ \fi}
+
+\installpagebreakhandler \v!last
+ {\page_otr_flush_all_floats
+ \gotonextpageX % will become \gotonextpage
+ \relax
+ \doifbothsidesoverruled
+ {\page_facings_flush}% hm
+ {}
+ {\noheaderandfooterlines
+ \page_otr_insert_dummy_page}%
+ \filluparrangedpages}
+
+\installpagebreakhandler \v!lastpage % handy for backpage preceded by empty pages
+ {\page_breaks_handle_direct\v!yes
+ \ifdoublesided
+ \page_breaks_handle_direct\v!left
+ \page_breaks_handle_direct\v!empty
+ \page_breaks_handle_direct\v!empty
+ \fi}
+
+\installpagebreakhandler \v!start {\global\settrue \c_otr_shipout_enabled}
+\installpagebreakhandler \v!stop {\global\setfalse\c_otr_shipout_enabled}
+
+% Column breaks.
+
+\newtoks\everybeforecolumnbreak
+\newtoks\everyaftercolumnbreak
+
+\let\page_breaks_columns_current_option \empty
+\let\page_breaks_columns_current_options\empty
+
+\def\page_breaks_columns_handle#1%
+ {\edef\page_breaks_columns_current_options{#1}%
+ \processcommacommand[#1]\page_breaks_columns_handle_indeed}
+
+\def\page_breaks_columns_handle_indeed#1%
+ {\edef\page_breaks_columns_current_option{#1}%
+ \ifcsname\??cn:\OTRidentifier:\page_breaks_columns_current_option\endcsname
+ \csname\??cn:\OTRidentifier:\page_breaks_columns_current_option\endcsname
+ \else\ifcsname\??cn::\page_breaks_columns_current_option\endcsname
+ \expandafter\csname\page_breaks_columns_handle\??cn::\page_breaks_columns_current_option\endcsname
+ \else
+ \csname\??cn:\OTRidentifier:\s!unknown\endcsname
+ \fi\fi}
+
+\def\page_breaks_columns_handle_direct#1%
+ {\csname\??cn:\OTRidentifier:#1\endcsname}
+
+\def\installcolumnbreakhandler#1#2#3% #1=otr-id #2=tag #3=action
+ {\setvalue{\??cn:#1:#2}{#3}}
+
+\unexpanded\def\definecolumnbreak
+ {\dodoubleargument\page_break_columns_define}
+
+\def\page_break_columns_define[#1][#2]%
+ {\setvalue{\??cn::#1}{#2}}
+
+\unexpanded\def\columnbreak
+ {\dosingleempty\page_breaks_columns_process}
+
+\let\column\columnbreak
+
+\def\page_breaks_columns_process[#1]% so, page ornaments are reset after a pagebreak command, unless set
+ {\begingroup
+ \the\everybeforecolumnbreak
+ \iffirstargument
+ \page_breaks_columns_handle{#1}%
+ \else
+ \page_breaks_columns_handle_direct\v!yes
+ \fi
+ \relax
+ \the\everyaftercolumnbreak
+ \endgroup}
+
+%D Test page breaks.
+
+\newdimen \d_page_tests_test
+\newconstant\c_page_tests_mode
+
+\newconstant\testpagemethod % todo: \testnewpage[method=,lines=,voffset=]
+\newconstant\testpagetrigger
+
+\unexpanded\def\testpage {\c_page_tests_mode\plusone \dodoubleempty\page_tests_test} %
+\unexpanded\def\testpageonly{\c_page_tests_mode\plustwo \dodoubleempty\page_tests_test} % no penalties added to the mvl
+\unexpanded\def\testpagesync{\c_page_tests_mode\plusthree\dodoubleempty\page_tests_test} % force sync
+
+\def\page_tests_test[#1][#2]% don't change, only add more methods
+ {\relax % needed before \if
+ \ifconditional\c_page_breaks_enabled
+ % new from here
+ \ifcase\testpagetrigger
+ \endgraf
+ \or\ifvmode
+ \dosomebreak\allowbreak
+ \else % indeed?
+ \vadjust{\allowbreak}%
+ \endgraf
+ \fi\fi
+ % till here
+ \ifdim\pagegoal<\maxdimen \relax
+ \ifdim\pagetotal<\pagegoal \relax
+ \d_page_tests_test\dimexpr
+ #1\lineheight
+ +\pagetotal
+ \ifdim\lastskip<\parskip+\parskip\fi
+ \ifthirdargument+#2\fi
+ \relax
+ \ifcase\testpagemethod
+ \ifdim\d_page_tests_test>.99\pagegoal
+ \penalty-\!!tenthousand\relax
+ \fi
+ \or
+ \ifdim\dimexpr\d_page_tests_test-\pagegoal\relax>-\lineheight
+ \penalty-\!!tenthousand\relax
+ \fi
+ \or
+ \getnoflines\pagegoal
+ \ifdim\dimexpr\d_page_tests_test-\noflines\lineheight\relax>-\lineheight
+ \penalty-\!!tenthousand\relax
+ \fi
+ \or % same as 0 but more accurate
+ \ifdim\dimexpr\d_page_tests_test-10\scaledpoint\relax>\pagegoal
+ \penalty-\!!tenthousand\relax
+ \fi
+ \fi
+ \else\ifnum\c_page_tests_mode=\plusthree
+ \page_tests_flush_so_far
+ \fi\fi
+ \else\ifnum\c_page_tests_mode=\plusone
+ \goodbreak
+ \fi\fi
+ \else
+ \endgraf
+ \fi}
+
+\def\page_tests_flush_so_far
+ {\endgraf
+ \ifdim\pagetotal>\pagegoal
+ \ifdim\dimexpr\pagetotal-\pageshrink\relax>\pagegoal
+ \goodbreak
+ \else
+ \page
+ \fi
+ \fi}
+
+%D Test column breaks.
+
+\def\testcolumn
+ {\dodoubleempty\page_tests_columns_test}
+
+\def\page_tests_columns_test[#1][#2]%
+ {\endgraf
+ \ifdim\pagegoal<\maxdimen
+ \ifdim\pagetotal<\pagegoal
+ \d_page_tests_test\dimexpr
+ \pagegoal
+ -\pagetotal
+ \ifdim\lastskip<\parskip+\parskip\fi
+ \ifsecondargument+#2\fi
+ \relax
+ \getrawnoflines\d_page_tests_test % (raw)
+ \ifnum#1>\noflines
+ \column
+ \fi
+ \else
+ \penalty-\plustenthousand % (untested)
+ \fi
+ \fi}
+
+\protect \endinput