% This file is part of the CTAN package named plain-grid.
% 
%   plaingridI.tex: text, math,
%                   and support for insertions and a ragged bottom
%   Version 1.0, 05.05.2026
%
%   Copyright (C) 2026  Udo Wermuth (author)
%
%   This program is free software: you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation, either version 3 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public License
%   along with this program.  If not, see <http://www.gnu.org/licenses/>.
%

\input plaingridM.tex
{\toks255=\expandafter{\gridrestoreparams}%
 \let\\=\noexpand \xdef\gridrestoreparams{%
  \the\toks255 \skip\topins=\the\skip\topins
  \skip\footins=\the\skip\footins
  \\\GRIDrestorefootnotes
  \let\\\pagecontents=\\\GRIDpagecontents}}
\skip\topins=0pt \skip\footins=\GRIDgrid
\let\gridtopinsert=\topinsert  % these three
\let\gridmidinsert=\midinsert  % macros call
\let\gridpageinsert=\pageinsert% macro \@ins
\catcode`@=11 % we access plain.tex's macros
\def\gridendinsert{% end top/mid/pageinsert
 \egroup   % \bgroup is in \@ins; ends \box0
 \if@mid \p@gefalse \GRIDboxheight0(:\vfil)%
  \GRIDdim=\ht0 \advance\GRIDdim by\dp0
  \advance\GRIDdim by \pagetotal
  \ifdim\pagegoal>\GRIDdim \gridskiponeline
   \box0 \gridsnaptonextbaseline
  \else \GRIDtopinsert1\fi % mid becomes top
 \else \GRIDtopinsert0\fi   % page/topinsert
 \endgroup}    % finish \begingroup of \@ins
\def\GRIDtopinsert#1{% #1: 0/1=n/y box known
 \insert\topins{\penalty0 \floatingpenalty=0
  \splittopskip=0pt \splitmaxdepth=\maxdimen
  \ifp@ge \GRIDdim=\dp0 \vbox to \vsize{%
    \unvbox0 \kern-\GRIDdim}%
  \else \GRIDboxheight0(:\ifnum#1=0 \vfil\fi
   \kern\grideotspace\GRIDgrid)\box0 \fi}}
\def\grideotspace{0.5}% times leading at end
\let\GRID@vfn=\vfootnote \let\GRID@f=\@foot
\def\GRIDrestorefootnotes{\let\@foot=\GRID@f
 \let\vfootnote=\GRID@vfn}
\def\vfootnote#1{\insert\footins\bgroup
 \interlinepenalty=0 \floatingpenalty\@MM
 \splitmaxdepth=\dp\GRIDsbox % use our strut
 \splittopskip=\ht\GRIDsbox \leftskip\z@skip
 \rightskip\z@skip \xspaceskip\z@skip
 \spaceskip\z@skip \textindent{#1}\footstrut
 \futurelet\next\fo@t}
\def\@foot{\unhcopy\GRIDsbox\egroup}%  ditto
\let\gridfootnote=\footnote    \catcode`@=12
\newif\ifgridragged    % true: accept shifts
\let\GRIDpagecontents=\pagecontents %to undo
\def\pagecontents{% make grid-aware \footins
 \ifdim\pagefillstretch=1pt %`\dosupereject'
  \GRIDdim=0pt \else \GRIDgetpagestatus \fi
 \ifvoid\topins\else\unvbox\topins\fi
 \unvbox255 \GRIDpgreport     % analyze page
 \ifvoid\footins \else \leftline{\unhcopy
   \GRIDsbox \gridrule(width 2truein)}%
  \vbox to \ht\footins{\unvbox\footins}\fi}
\def\GRIDpgreport{\GRIDpgtype % set \GRIDcnt
 \ifnum\GRIDcnt=0 \GRIDpgerr \else
  \vss% use own msg not TeX's underfull vbox
  \ifnum\GRIDcnt>2 \ifgridragged\else
   \GRIDlog0{GRID: page ends ragged; fix}\fi
  \fi \ifodd\GRIDcnt\else \GRIDfnchk \fi
 \fi \edef\GRIDtmp{has a \ifgridragged
   ragged bottom \else shift \fi}%
 \edef\GRIDnext{\ifcase\GRIDcnt is bad\or
   is okay\or with footnote\or \GRIDtmp\or
   with footnote \GRIDtmp\fi}\GRIDlog2{%
  GRID: page (\the\GRIDdim) \GRIDnext}}
\def\GRIDchkii{% test two dimens; \GRIDcnt>0
 \ifdim\GRIDdim=\dimen0 \else\ifdim\GRIDdim=
  \dimen2 \else \GRIDcnt=0 \fi\fi}
\def\GRIDchkiii{% same with three dimensions
 \ifdim\GRIDdim=\dimen0 \else\ifdim\GRIDdim=
  \dimen2 \else\ifdim\GRIDdim=\dimen4 \else
  \GRIDcnt=0 \fi\fi\fi}
\def\GRIDadd(#1){% add #1 to \dimen 0, 2, 4
 \advance\dimen0 by #1\advance \dimen2 by
 #1\advance\dimen4 by #1\ignorespaces}
\def\GRIDpgtype{% set dimen for \GRIDchkii/i
 % Test 1: good page breaks
 \dimen0=-\GRIDgrid \dimen2=0pt
 \GRIDcnt=1 \GRIDchkii
 % 2: footnote +(\dp\strutbox+\baselineskip)
 \ifnum\GRIDcnt=0 \dimen0=\dp\GRIDsbox
  \dimen2=\dimen0\advance\dimen2 by\GRIDgrid
  \GRIDcnt=2 \GRIDchkii
 % Tests 3 & 4: shifts; three values
 \ifnum\GRIDcnt=0 \dimen0=-0.25\GRIDgrid
  \dimen2=-0.33333\GRIDgrid
  \dimen4=-0.5\GRIDgrid
  \GRIDcnt=3 \GRIDchkiii
 \ifnum\GRIDcnt=0 \GRIDadd(\GRIDgrid)
  \GRIDcnt=3 \GRIDchkiii
 % Tests 5 & 6: footnote and shift
 \ifnum\GRIDcnt=0 \GRIDadd(\dp\GRIDsbox)
  \GRIDcnt=4 \GRIDchkiii
 \ifnum\GRIDcnt=0 \GRIDadd(\GRIDgrid)
  \GRIDcnt=4 \GRIDchkiii \fi\fi\fi\fi\fi}
\def\GRIDgetpagestatus{\GRIDdim=\vsize
 \advance\GRIDdim by -\pagetotal    % - text
 \advance\GRIDdim by -\ht\topins    % - tops
 \advance\GRIDdim by -\ht\footins}%  - foots
\def\GRIDfnchk{{% check if footnote is moved
 \advance\GRIDdim by -\dp\GRIDsbox
 \ifdim\GRIDdim<\GRIDgrid \else % > one line
  \ifdim\pagetotal>\pagegoal \GRIDlog0{%
   GRID: page too short; fix}\GRIDlog1{The
   page is a line too short because a line
   with a footnote must be moved.}\fi\fi}}
\def\GRIDpgerr{\GRIDlog0{GRID: ugly page;
 fix}\GRIDlog1{The page is not filled as
 expected. Maybe a text line with footnotes
 is moved to the next page, a skip violates
 the grid, or a forbidden command was used.
 Check the \vbox shown in TeX's warning.}}
