% 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 . % \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.}}