%D \module
%D   [       file=page-ini,
%D        version=2000.10.20,
%D          title=\CONTEXT\ Page Macros,
%D       subtitle=Initializations,
%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 / Initializations}

\registerctxluafile{page-ini}{}

%D The \type {\processpage} command has become obsolete. It's original
%D purpose was to flush only parts of a document but nowadays we have
%D project structure and modes. This is just one of those very early
%D features that no longer makes sense.

%D The \type {\couplepage} command has become obsolete. It's original
%D purpose was to provide hooks for printer directives (like choosing
%D different paper trays).

\unprotect

%D Shipout control.

\newcount\nofshipouts

\appendtoks
    \global\advance\nofshipouts\plusone
\to \everyaftershipout

\newconditional\c_otr_shipout_enabled \settrue\c_otr_shipout_enabled

\unexpanded\def\page_otr_shipout % not used at all
  {\ifconditional\c_otr_shipout_enabled
     \expandafter\page_otr_shipout_yes
   \else
     \expandafter\page_otr_shipout_nop
   \fi}

\let\page_otr_shipout_yes\normalshipout

\unexpanded\def\page_otr_shipout_nop
  {\writestatus\m!system{ignoring shipout of real page \the\realpageno}%
   \global\advance\realpageno\minusone % else no flush of resources
   \dowithnextbox{\deadcycles\zerocount}}

% We don't support direct user \shipouts (weird: this does not work, bug?)
%
% \let\shipout\page_otr_shipout_nop

%D Building pages.

\newbox\pagebox

% \ifdefined\page_postprocessors_column \else \let\page_postprocessors_column\gobbleoneargument \fi
% \ifdefined\page_postprocessors_page   \else \let\page_postprocessors_page  \gobbleoneargument \fi
% \ifdefined\page_postprocessors_box    \else \let\page_postprocessors_box   \gobbleoneargument \fi

\newtoks\t_page_postprocessors_box
\newtoks\t_page_postprocessors_page
\newtoks\t_page_postprocessors_column

\newconstant\b_page_postprocessor

\def\page_apply_postprocessors_box#1%
  {\b_page_postprocessor#1\relax
   \the\t_page_postprocessors_box}

\def\page_apply_postprocessors_page#1%
  {\b_page_postprocessor#1\relax
   \the\t_page_postprocessors_page}

\def\page_apply_postprocessors_column#1%
  {\b_page_postprocessor#1\relax
   \the\t_page_postprocessors_column}

%D Floats.

\def\page_otr_flush_all_floats
  {%\flushnotes already done
   \ifconditional\c_page_floats_some_waiting
     \page_otr_command_flush_all_floats
   \fi}

\def\page_otr_insert_dummy_page
  {\par
   \ifvmode
     \page_otr_flush_all_floats
     \fixedspace
     \vfill
     \page_otr_command_next_page
   \fi}

\def\page_otr_flush_pending_content
  {\vkern\zeropoint\relax
   \ifvoid\normalpagebox \else
     \unvbox\normalpagebox
     \penalty\outputpenalty
   \fi}

\newconstant\c_page_postponed_mode % \c_page_postponed_mode\plusone
\newbox     \b_page_otr_saved

\installoutputroutine\savepagecontent
  {\global\setbox\b_page_otr_saved\box\normalpagebox}

\unexpanded\def\flushpagecontent
  {\ifvoid\b_page_otr_saved\else\unvbox\b_page_otr_saved\fi}

% Test case: assumes one group level for output routine, todo:
% a toks.
%
% \starttext
%
% \startbuffer[makeup]
% \startpagemakeup[pagestate=start,page=no]
%     \color[red]{
%         \vfill
%         \dorecurse{3}{
%             \samplefile{klein}
%             \vfill
%         }
%     }
% \stoppagemakeup
% \stopbuffer
%
% \startcolor[green]
%     \dorecurse{10}{
%         \dontleavehmode{\bf 1:#1:} \samplefile{sapolsky}\par
%     }
% \stopcolor
%
% \startpostponing % [+3]
%     \getbuffer[makeup]
% \stoppostponing
%
% \startcolor[blue]
%     \dorecurse{25}{
%         \dontleavehmode{\bf 2:#1:} \samplefile{sapolsky}\par
%     }
% \stopcolor
%
% \stoptext

\def\page_otr_construct_and_shipout#1#2#3%
  {\forgetall
   \page_boxes_shipout{\page_boxes_constructed_page#1#2}% \hbox removed
   \page_otr_flush_pending_content
   % not really needed, replaced by \flushsavedfloats
   \page_otr_check_for_pending_inserts
   % but does not hurt either (we're still in the otr!)
   \inpagebodytrue      % needed for enabling \blank ! brrr
   \pagebodymode\plusone % todo: \plustwo when spread
   \page_otr_command_flush_saved_floats
   \page_otr_command_set_vsize   % this is needed for interacting components, like floats and multicolumns
   \strc_pagenumbers_increment_counters % should hook into an every
   \page_adapts_synchronize
   \page_otr_check_for_pending_inserts
   \page_otr_command_flush_facing_floats
   \page_floats_flush_page_floats % before postponed blocks
   \page_spread_flush % defined later
   \ifnum#3=\plusone
     % this is tricky! we need to make sure we are in the output group
     \ifnum\c_page_postponed_mode=\plusone
       \aftergroup\page_postponed_blocks_flush
     \else
       \page_postponed_blocks_flush
     \fi
   \else
     \page_postponed_blocks_flush
   \fi}

% Can't we get rid of this hackery? It's used in some widgets
% stuff so probably not.

\newbox\b_page_otr_special

\def\page_otr_flush_special_content
  {\ifvoid\b_page_otr_special \else
     \box\b_page_otr_special
   \fi}

\def\page_otr_add_special_content
  {\dowithnextboxcs\page_otr_add_special_content_indeed\hbox}

\def\page_otr_add_special_content_indeed
  {\wd\nextbox\zeropoint
   \ht\nextbox\zeropoint
   \dp\nextbox\zeropoint
   \global\setbox\b_page_otr_special\hbox
     {%\hskip-\maxdimen                    % not here, fails in acrobat (clips)
      \box\b_page_otr_special\box\nextbox}}% was \unhbox, is now box again

\let\flushatshipout\page_otr_add_special_content

\maxdeadcycles=1000

\newtoks\afterpage     \newtoks\aftereverypage
\newtoks\beforepage    \newtoks\beforeeverypage

\newif\ifarrangingpages \arrangingpagesfalse

\newconstant\pageornamentstate % 0=on 1=one-off 2=always-off

% \appendtoks
%     \ifcase\pageornamentstate \or
%         \pageornamentstate\zerocount
%     \fi
% \to \everyaftershipout

\appendtoks
    \ifcase\pageornamentstate \or
        \global\pageornamentstate\zerocount
    \fi
\to \everyaftershipout

% Mark synchronization

\newconditional\c_page_marks_building_successive_pages \settrue\c_page_marks_building_successive_pages

\def\page_marks_synchronize_page#1% box
  {\strc_markings_synchronize[\v!page][#1][\ifconditional\c_page_marks_building_successive_pages\v!keep\fi]}

\def\page_marks_synchronize_column#1#2#3#4% first last column box
  {\ifnum#3=#1\relax
     \strc_markings_synchronize[\number#3,\v!column:\number#3,\v!first,\v!column:\v!first][#4][]%
   \else\ifnum#3=#2\relax
     \strc_markings_synchronize[\number#3,\v!column:\number#3,\v!last, \v!column:\v!last ][#4][]%
   \else
     \strc_markings_synchronize[\number#3,\v!column:\number#3                            ][#4][]%
   \fi\fi}

% Page body building

\newconditional\c_page_boxes_save_page_body
\newbox        \b_page_boxes_saved_page_body

\def\page_boxes_constructed_page_body#1#2%
  {\ifconditional\c_page_boxes_save_page_body \global\setbox\b_page_boxes_saved_page_body \fi \vpack \bgroup
      \boxmaxdepth\maxdimen % new
      \dontcomplain
      \page_marks_synchronize_page                    {#2}%  we could consider doing this for \pagebox (needs testing)
      \page_boxes_construct_content       \pagebox{#1}{#2}%
      \page_backgrounds_add_to_main       \pagebox
      \page_boxes_apply_offsets           \pagebox
      \page_info_add_to_box               \pagebox
      \ifcase\pageornamentstate
        \page_backgrounds_add_to_paper    \pagebox
      \fi
      \anch_positions_register_page       \pagebox
      \ifarrangingpages
        \page_boxes_apply_shift_paper     \pagebox % \v!paper
      \else
        \page_boxes_apply_clip_paper      \pagebox
        \page_marks_add_page              \pagebox
        \page_boxes_apply_replicate       \pagebox
        \page_boxes_apply_scale           \pagebox
        \page_boxes_apply_mirror_paper    \pagebox
        \page_boxes_apply_orientate_paper \pagebox
        \page_marks_add_more              \pagebox
        \page_boxes_apply_center          \pagebox
        \page_backgrounds_add_to_print    \pagebox
        \page_boxes_apply_mirror_print    \pagebox
        \page_boxes_apply_orientate_print \pagebox
        \page_boxes_apply_shift_print     \pagebox % \v!page
        \page_boxes_apply_offset          \pagebox
        \page_boxes_apply_negate_print    \pagebox
      \fi
      \box\pagebox
   \egroup \ifconditional\c_page_boxes_save_page_body \copy\b_page_boxes_saved_page_body \fi}

\appendtoks
    \restoreglobalbodyfont
    \pickupattributes
\to \everybeforepagebody

\ifdefined\nestednewbox \else \newbox\nestednextbox \fi % hm, still needed?

\prependtoks
    \let\nextbox\nestednextbox
\to \everybeforepagebody

\def\page_boxes_constructed_page#1#2%
  {\vpack\bgroup % intercept spurious spaces
     \the\everybeforepagebody
     \starttextproperties
     \checkmarginblocks
     \the\beforeeverypage
     \normalexpanded{\global\beforepage\emptytoks\the\beforepage}%
     \inpagebodytrue
     \pagebodymode\plusone % todo: \plustwo when spread
     \page_boxes_constructed_page_body#1#2%
     \normalexpanded{\global\afterpage \emptytoks\the\afterpage }%
     \the\aftereverypage
     \resetpagebreak
     \resetlayouttextlines % will go to \aftereverypage
     \stoptextproperties
     \the\everyafterpagebody
   \egroup}

\def\doifelsetopofpage
  {\ifdim\pagegoal=\maxdimen
     \expandafter\firstoftwoarguments
   \else\ifdim\pagegoal=\vsize
     \doubleexpandafter\firstoftwoarguments
   \else
     \doubleexpandafter\secondoftwoarguments
   \fi\fi}

\let\doiftopofpageelse\doifelsetopofpage

% %D Idea:
%
% \newinsert\thispageinsert % <- installinsertion
%
% \def\flushatthispage
%   {\bgroup
%    \dowithnextbox{\insert\thispageinsert{\box\nextbox}\egroup}%
%    \hbox}
%
% \appendtoks
%     \ifvoid\thispageinsert\else\hbox{\smashedbox\thispageinsert}\fi
% \to \everyshipout

% not yet in i-* file

\installcorenamespace{markedpage}

\unexpanded\def\markpage
  {\dotripleempty\page_mark}

\def\page_mark[#1][#2][#3]%
  {\clf_markpage{#1}{#2}{#3}}

\def\markedpages[#1]% expandable
  {\clf_markedpages{#1}}

\unexpanded\def\doifelsemarkedpage#1%
  {\clf_doifelsemarkedpage{#1}}

\unexpanded\def\doifmarkedpage#1%
  {\clf_doifmarkedpage{#1}}

\unexpanded\def\startmarkpages
  {\dodoubleempty\page_start_marked}

\def\page_start_marked[#1][#2]%
  {\clf_startmarkpages{#1}{#2}}

\unexpanded\def\stopmarkpages
  {\clf_stopmarkpages}

\unexpanded\def\checkmarkedpages
  {\clf_checkmarkedpages}

\def\markedpageparameter#1#2%
  {\clf_markedpageparameter{#1}{#2}}

\appendtoks
    \checkmarkedpages
\to \everyaftershipout

%D Experimental:

\newconstant\c_page_force_strut_depth_trace_mode

\installtextracker
  {otr.forcestrutdepth}
  {\c_page_force_strut_depth_trace_mode\plusone}
  {\c_page_force_strut_depth_trace_mode\zerocount}

\installoutputroutine\forcestrutdepth
  {\clf_forcestrutdepth\normalpagebox\strutdp\c_page_force_strut_depth_trace_mode
   \unvbox\normalpagebox}

\installoutputroutine\forcestrutdepthplus % experimental
  {\clf_forcestrutdepthplus\normalpagebox\strutdp\c_page_force_strut_depth_trace_mode
   \unvbox\normalpagebox}

% maybe better:
%
% \installoutputroutine\doforcestrutdepth
%   {\clf_forcestrutdepth\normalpagebox\strutdp\c_page_force_strut_depth_trace_mode
%    \unvbox\normalpagebox}
%
% \unexpanded\def\forcestrutdepth
%   {\par\ifvmode\ifinner\else\doforcestrutdepth\fi\fi}

% Also experimental:

\unexpanded\def\doifelsependingpagecontent{\clf_doifelsependingpagecontent}

\protect \endinput

