% BACKGRound around block of text (e.g. several paragraphs), plain TeX macros
% Vit Zyka, 1999, v1.0
\message{Backgr package: block text emphesizing; 1999 v1.0, Vit Zyka}
%\tracingpages=1
%\tracingoutput=1
%\showboxdepth=2
%\showboxbreadth=300
%\errorcontextlines=10

\newif\ifbackgrstrut \backgrstruttrue

\newtoks\backgrlist \backgrlist={}
\newif\ifmiddlebg
\newif\ifbgoverpage
\newif\ifbgglueok
\newdimen\backgrcorrection
\newdimen\backgrconstcorr \backgrconstcorr=0pt
\newdimen\backgrbotcorrection
\newdimen\backgrbotconstcorr \backgrbotconstcorr=0pt
\newdimen\backgrtopcorrection
\newdimen\backgrtopconstcorr \backgrtopconstcorr=0pt
\newdimen\bgtmp \newdimen\bgtmpii

\newdimen\lastlinewidth
\newdimen\bgframewidth \bgframewidth=.2pt
\newskip\tmps
\newdimen\pgtotal \newdimen\pgdepth \newdimen\pggoal
\newdimen\pgshrink \newdimen\pgstretch \newdimen\pgfilstretch
\newdimen\pgfillstretch \newdimen\pgfilllstretch
\newdimen\pgshrinkins \newdimen\pgstretchins \newdimen\pgfilstretchins
\newdimen\pgfillstretchins \newdimen\pgfilllstretchins
\newdimen\previnsert

\newcount\tracingbackgr \tracingbackgr=1 % 0-no, 1-log file, 2-display
\def\bgmessage{\ifcase\tracingbackgr\let\next=\pozer\or%
  \def\next{\immediate\write-1}\or\let\next\message%\def\next{\immediate\write16}
  \fi\next}
\def\pozer#1{}

%\let\origwrite=\write
%\def\write#1#{\writetohbox{#1}}
%\def\writetohbox#1#2{\ifvmode\bgroup\dimen0=\prevdepth\kern-\dimen0
%  \nointerlineskip\hbox{\origwrite#1{#2}\vrule width0pt height0pt depth\dimen0}
%  \global\prevdepth=\dimen0 \egroup\else\hbox{\origwrite#1{#2}}\fi}

% --------------------------------------------------------------- Blocks marks
\def\backgr{\startbackgr%
  \ifdim\pagegoal=\maxdimen\bgtmp=0pt\else%
    \bgtmp=\pagetotal
    \ifbackgrstrut \advance\bgtmp by\dp\strutbox%
    \else \ifdim\prevdepth>-1000pt\advance\bgtmp by\prevdepth\fi\fi%
    %\advance\bgtmp by\vsize \advance\bgtmp by-\pagegoal
  \fi%
  \advance\bgtmp by \backgrcorrection\global\backgrcorrection=\backgrconstcorr%
  \edef\act{\global\backgrlist={\the\backgrlist\noexpand\backgrbox\backgrstyle
       \noexpand\outbg\noexpand{\bgwd\noexpand}\noexpand{\bgind\noexpand}%
       \noexpand{\the\bgtmp\noexpand}%
       \the\pagestretch\noexpand\and\the\pagefilstretch\noexpand\and%
     \the\pagefillstretch\noexpand\and\the\pagefilllstretch\noexpand\and%
     \the\pageshrink\noexpand\endp}}%
  \act\middlebgtrue\bgbuser}

\def\endbackgr{\startbackgr\global\bgtmp=\backgrcorrection\bgeuser%
  \ifdim\pagegoal=\maxdimen\else%
    \advance\bgtmp by\pagetotal
    \ifbackgrstrut \advance\bgtmp by\dp\strutbox%
    \else \ifdim\prevdepth>-1000pt\advance\bgtmp by\prevdepth\fi\fi%
    %\advance\bgtmp by\vsize \advance\bgtmp by-\pagegoal
  \fi%
  \global\backgrcorrection=\backgrconstcorr%
  \edef\act{\global\backgrlist={\the\backgrlist\noexpand{\the\bgtmp\noexpand}%
     \the\pagestretch\noexpand\and\the\pagefilstretch\noexpand\and%
     \the\pagefillstretch\noexpand\and\the\pagefilllstretch\noexpand\and%
     \the\pageshrink\noexpand\endp\noexpand\outbg}}%
  \act\middlebgfalse}
%\def\startbackgr{\ifhmode\par\fi\penalty-1 }
\def\startbackgr{\ifhmode\par\else%
  {\dimen0=\prevdepth\kern-\dimen0\nointerlineskip%
   \hbox{\vrule width0pt height0pt depth\dimen0}%
   \global\prevdepth=\dimen0}\fi}

\def\bgbuser{\bgroup\leftskip=4pt \rightskip=4pt \advance\parindent by-4pt }
\def\bgeuser{\egroup}

% ------------------------------------------------------------- Output rutine
\edef\bgoutput{\the\output}
\output={\setbox255=\vbox{\unvbox255} \pgtotal=\ht255\pgdepth=\dp255
  \pgstretch=0pt \pgfilstretch=0pt \pgfillstretch=0pt \pgfilllstretch=0pt
  \pgshrink=0pt  \countglue{255}{\tmps}
  \ifbgglueok \getpgregisters{\tmps} \else
    \pgstretch=\pagestretch \pgfilstretch=\pagefilstretch
    \pgfillstretch=\pagefillstretch \pgfilllstretch=\pagefilllstretch
    \pgshrink=\pageshrink \fi
  \countprevinsertcorr\previnsert%
  \countpggoal\pggoal \ifvoid\footins\else%
    \advance\pggoal by\dp\footins \advance\pggoal by-\pgdepth\fi%
  \bgmessage{PgTotal=\the\pgtotal\space PgGoal=\the\pggoal}%
  \bgmessage{Pg: \the\pgstretch\space \the\pgfilstretch\space
    \the\pgfillstretch\space \the\pgfilllstretch\space \the\pgshrink}%
  \bgmessage{PgIns: \the\pgstretchins\space \the\pgfilstretchins\space
    \the\pgfillstretchins\space \the\pgfilllstretchins\space \the\pgshrinkins}%
  \bgoutput}
\def\pagebody{\vbox to\vsize{\boxmaxdepth=\maxdepth \backgroutput\pagecontents}}
\def\backgroutput{%
%  \bgmessage{PageTotal=\the\pagetotal\space PageGoal=\the\pagegoal\space
%    Page: \the\pagestretch\space\the\pagefilllstretch\space
%    \the\pagefillstretch\space\the\pagefilstretch\space\the\pageshrink}%
  \ifmiddlebg%
     \bgtmp=\pgtotal
     \ifbackgrstrut\advance\bgtmp by\dp\strutbox\else\advance\bgtmp by\pgdepth\fi%
     \advance\bgtmp by\backgrbotcorrection
     \edef\act{\global\backgrlist={\the\backgrlist\noexpand{\the\bgtmp\noexpand}%
     \the\pgstretch\noexpand\and\the\pgfilstretch\noexpand\and\the\pgfillstretch%
     \noexpand\and\the\pgfilllstretch\noexpand\and\the\pgshrink\noexpand\endp%
     \noexpand\inbg}}\act\fi%
  \bgoverpagefalse%
  \the\backgrlist%
  \ifmiddlebg\edef\act{\global\backgrlist={\noexpand\backgrbox\backgrstyle%
     \ifbgoverpage\noexpand\outbg\else\noexpand\inbg\fi%
     \noexpand{\bgwd\noexpand}\noexpand{\bgind\noexpand}%
     \noexpand{\the\backgrtopcorrection\noexpand}0pt\noexpand\and0pt%
     \noexpand\and0pt\noexpand\and0pt\noexpand\and0pt\noexpand\endp}}\act%
  \else\global\backgrlist={}\fi%
  \global\backgrbotcorrection=\backgrbotconstcorr%
  \global\backgrtopcorrection=\backgrtopconstcorr}

% -------------------------------------------- Predefined emphesizing styles
% \backgrbox parametry:
% 1) macro; styl zvyrazneni (napr. \bgframe, \bgzigzag, ap.)
% 2) ifinbg; pozadi pokracuje z predchozi strany
% 3) dimen; sirka pozadi (\textwidth)
% 4) dimen; horizontalni odsazeni vuci levemu okraji (-1cm: posune levy okraj
%           o 1cm vlevo pred text)
% 5) dimen; vyska pocatku pozadi
% 6) tokens; roztazeni/stazeni pocatku pozadi: \page[fil[l[l]]]stretch
%                                              \pageshrink
% 7) dimen; vyska konce pozadi
% 8) tokens; roztazeni/stazeni konce pozadi: \page[fil[l[l]]]stretch
%                                            \pageshrink
% 9) ifinbg; pozadi pokracuje na dalsi stranu
\let\inbg=\relax
\def\bgstyleempty{\def\backgrstyle{\noexpand\backgrempty}}
\def\backgrempty#1#2#3#4#5#6{}
\newif\ifPDF
\ifx\pdfoutput\undefined\else\ifnum\pdfoutput>0 \PDFtrue\fi\fi
\ifPDF
  \def\bggray{\pdfliteral{0 0 0 .05 k}}
  \def\bgblack{\pdfliteral{0 0 0 1 k}}
\else
  \def\bggray{\special{ps: .95 setgray}}
  \def\bgblack{\special{ps: 0 setgray}}
\fi
\def\bgstylegray{\def\backgrstyle{\noexpand\backgrgray}}
\def\backgrgray#1#2#3#4#5#6{%
  \nointerlineskip\moveright#3
  \vbox to0pt{\vskip#4
    \hbox to#2{\bggray\leaders\vrule height#5\hfil\bgblack}
    \vss}}
\def\bgstylegrayframe{\def\backgrstyle{\noexpand\backgrgrayframe}}
\let\bgstyleframegray=\bgstylegrayframe
\def\backgrgrayframe#1#2#3#4#5#6{\bgtmp=#5 \advance\bgtmp by-2\bgframewidth
  \nointerlineskip\moveright#3
  \vbox to0pt{\vskip#4
    \ifx#1\relax\vskip\bgframewidth\else\hrule height\bgframewidth width#2\fi%
    \hbox to#2{\vrule height\bgtmp width\bgframewidth%
      \bggray%
      \leaders\vrule height\bgtmp\hfil%
      \bgblack%
      \vrule height\bgtmp width\bgframewidth}%
    \ifx#6\relax\vskip\bgframewidth\else\hrule height\bgframewidth width#2\fi\vss}}
\def\bgstylezigzag{\def\backgrstyle{\noexpand\backgrzigzag}}
\def\backgrzigzag#1#2#3#4#5#6{\bgtmp=#3
  %\ifodd\count0\bgtmp=#2\advance\bgtmp by1em\else\bgtmp=-1em\fi%
  \advance\bgtmp by-1em
  \nointerlineskip\moveright\bgtmp
  \vbox to0pt{\vskip#4\offinterlineskip
    \cleaders\vbox{\ialign{##\cr$\langle$\cr$\langle$\cr}}\vskip#5\vss}}
\def\bgstyleframe{\def\backgrstyle{\noexpand\backgrframe}}
\def\backgrframe#1#2#3#4#5#6{\bgtmp=#5 \advance\bgtmp by-2\bgframewidth
  \nointerlineskip\moveright#3
  \vbox to0pt{\vskip#4
    \ifx#1\relax\vskip\bgframewidth\else\hrule height\bgframewidth width#2\fi%
    \hbox to#2{\vrule height\bgtmp width\bgframewidth\hfil%
      \vrule height\bgtmp width\bgframewidth}%
    \ifx#6\relax\vskip\bgframewidth\else\hrule height\bgframewidth width#2\fi\vss}}
\def\backgrbox#1#2#3#4#5#6\endp#7#8\endp#9{%
  \bgtmpii=#5 \countstretchshrinkcorr\bgtmpii#6\endp\edef\messtmpa{\messtmpb}%
  \advance\bgtmpii by\previnsert%
  \bgtmp=#7 \countstretchshrinkcorr\bgtmp#8\endp%
  \advance\bgtmp by\previnsert%
  \advance\bgtmp by-\bgtmpii %\advance\bgtmp by-2\bgframewidth
  \bgmessage{Backgr (\the\count0): \ifx#2\relax(\else<\fi#5+\messtmpa,
    #7+\messtmpb\ifx#9\relax)\else>\fi}%
  % Only begin mark is realized for overcomming:
  \ifdim\bgtmpii>\vsize {\dimen0=\bgtmpii \advance\dimen0 by-\vsize%
    \ifmiddlebg\global\bgoverpagetrue\fi%
    \bgmessage{Backgr over \vsize about \the\dimen0}}%
  \else#1{#2}{#3}{#4}\bgtmpii\bgtmp{#9}\fi}
% Default
\bgstyleframe
{\advance\hsize by0pt\xdef\bgwd{\the\hsize}}
\def\bgind{0pt}
\def\nopt#1pt{#1}

% ----------------------------------------- Calculation of shrink and stretch
% Nasledujici vypocet korekce je jen priblizenim, protoze neni znama
% hodnota \pageshrink atd. v miste zlomu, ale az v tam, kam dospel alg.
% plneni strany, tj. vesmes dal! Hodnota tak casto vychazi mensi nez
% skutecna. Reseni: nacitat .log s vypisem \tracingpages=1 nebo definovat
% behem plneni strany (napr. pomoci \everyhbox, \everyvbox, \everypar
% predefinovanim \penalty a \par) makra \csname total\thetotal\endcsname
% s okamzitymi hodnotami \pageshrink atd. V output rutine vzit ty
% z total\pgtotal.
\def\countstretchshrinkcorr#1#2\and#3\and#4\and#5\and#6\endp{{%
  \advance\pgstretchins by#2 \advance\pgfilstretchins by#3
  \advance\pgfillstretchins by#4 \advance\pgfilllstretchins by#5
  \advance\pgshrinkins by#6
  % tmp=tmp+(PageMarkShrink/\pgshrink)*(\pggoal-\pgtotal)
  \dimen0=\pggoal \advance\dimen0 by-\pgtotal
  \count0=1000 \dimen1=0pt% default zadna korekce
  \bgmessage{Dfr=\the\dimen0 \space PageMark: #2 #3 #4 #5 #6}%
  \bgmessage{PgIns+PageMark: \the\pgstretchins\space \the\pgfilstretchins\space
    \the\pgfillstretchins\space \the\pgfilllstretchins\space \the\pgshrinkins}%
  \ifdim\dimen0<0pt%  \pgtotal>\pggoal -> shrink:
    \ifdim\pgshrink>0pt \count0=\pgshrink \dimen1=\pgshrinkins \fi
  \else
     \ifdim\pgfilllstretch>0pt \count0=\pgfilllstretch \dimen1=\pgfilllstretchins
     \else
        \ifdim\pgfillstretch>0pt \count0=\pgfillstretch \dimen1=\pgfillstretchins
        \else
           \ifdim\pgfilstretch>0pt \count0=\pgfilstretch \dimen1=\pgfilstretchins
           \else
             \ifdim\pgstretch>0pt \count0=\pgstretch \dimen1=\pgstretchins \fi
  \fi\fi\fi\fi
  \divide\count0 by1000 \count1=\dimen1 \divide\count1 by\count0
%  \bgmessage{C0:\the\count0\space D1:\the\dimen1\space Pomer:\the\count1}
  \dimen1=0.001\dimen0 \multiply\dimen1 by\count1
  \global\advance#1 by\dimen1
  \xdef\messtmpb{\the\dimen1}}}

% ----------------------------------------- Recalculation of \page* registers
% Count all glue in vertical box #1 and save it in #2 glue register
\newif\ifchangeincyc
\catcode`\@=11
{\catcode`\p=12 \catcode`\t=12 \xdef\@z@{0.0pt}}
\def\countglue#1#2{{\setbox1=\vbox{\unvcopy#1 \tracingbackgr=0
  #2=\lastskip \bgmessage{G=\the#2 }\unskip
  \loop \changeincycfalse
     \advance#2 by\lastskip\edef\bglastskip{\the\lastskip} \skip0=\lastskip
       \ifx\bglastskip\@z@\else\changeincyctrue\bgmessage{G=\the\skip0 }\fi \unskip
     \advance#2 by\lastskip\edef\bglastskip{\the\lastskip} \skip0=\lastskip
       \ifx\bglastskip\@z@\else\changeincyctrue\bgmessage{G=\the\skip0 }\fi \unskip
     \count0=\lastpenalty
     \ifnum\lastpenalty=0\else\changeincyctrue\bgmessage{P=\the\count0}\fi \unpenalty
     \ifnum\lastpenalty=0\else\changeincyctrue\bgmessage{P=\the\count0}\fi \unpenalty
     \advance#2 by\lastkern \skip0=\lastkern
       \ifdim\lastkern=0pt\else\changeincyctrue\bgmessage{K=\the\skip0}\fi \unkern
     \setbox0=\lastbox \ifvoid0 \else\changeincyctrue\bgmessage{B=\the\ht0}\fi
  \ifchangeincyc \repeat \global#2=#2}%
  \ifdim\ht1>0pt \global\bgglueokfalse%
    \bgmessage{!! Glue not correct in \number#1 on page \the\count0}
  \else \global\bgglueoktrue%
    \ifdim#2=0pt\else\bgmessage{Glue in \number#1: \the#2}\fi\fi}}
\catcode`\@=12

% Extraction of \page* registers from skip #1
\let\ex=\expandafter
{\let\:=\catcode \let\!=\gdef
 \:`\p=12 \:`\t=12 \:`\l=12 \:`\m=12 \:`\i=12 \:`\n=12 \:`\u=12 \:`\s=12 \:`\f=12
 \!\PT{##1pt##2} \!\PTe#1{#1plus} \!\PTv#1{#1pt} \!\PLUSe{##1plus##2}
 \!\MINUSv#1{#1 minus} \!\MINUSe{##1minus} \!\MINUS{##1 minus##2}
 \!\PLUS{##1plus##2} \!\FIL{##1fil##2} \!\PLUSPT{##1pt##2}}

\ex\def\ex\elimfil\FIL\ends{\def\tmp{#2}%
  \ifx\tmp\empty\global\advance\pgfilstretch by#1pt\else%
    \if#2\relax\global\advance\pgfilllstretch by#1pt\else%
      \global\advance\pgfillstretch by#1pt\fi\fi}
\ex\def\ex\elimpt\PLUSPT\ends{\def\tmp{#2}%
  \ifx\tmp\empty\elimfil#1\ends\else\global\advance\pgstretch by#1pt\fi}
\ex\def\ex\elimplus\PLUSe\ends{\ex\elimpt\PTv{#1}\ends}
\ex\def\ex\separplus\PLUS\ends{\def\tmp{#2}%
  \ifx\tmp\empty\else\elimplus#2\ends\fi}
\ex\def\ex\elimminus\MINUSe\ends{\global\advance\pgshrink by#1}
\ex\def\ex\separminus\MINUS\ends{%
  \def\tmp{#2} \ifx\tmp\empty\else\elimminus#2\ends\fi%
  \def\tmp{#1} \ifx\tmp\empty\else\ex\separplus\PTe{#1}\ends\fi}
\ex\def\ex\separglue\PT\ends{%
  \def\tmp{#2} \ifx\tmp\empty\else\ex\separminus\MINUSv{#2}\ends\fi}
\def\getpgregisters#1{\ex\separglue \the#1 \ends}

% Recount \pagegoal
\catcode`\@=11
\def\countpggoal#1{{%
  \dimen0=\vsize
  \loop\ifnum\insc@unt<255
%    \bgmessage{Insert \the\insc@unt: Count=\the\count\insc@unt\space
%      Ht=\the\ht\insc@unt\space Dp=\the\dp\insc@unt\space
%      Skip=\the\skip\insc@unt}
    \ifnum\count\insc@unt=1000
      \advance\dimen0 by-\ht\insc@unt
      \advance\dimen0 by-\dp\insc@unt
    \else%
      \dimen1=0.01\ht\insc@unt \multiply\dimen1 by\count\insc@unt
      \advance\dimen0 by-.1\dimen1
      \dimen1=0.01\dp\insc@unt \multiply\dimen1 by\count\insc@unt
      \advance\dimen0 by-.1\dimen1
    \fi%
    \ifdim\ht\insc@unt=0pt
      \ifdim\dp\insc@unt=0pt\else \advance\dimen0 by-\skip\insc@unt \fi
    \else \advance\dimen0 by-\skip\insc@unt \fi
    \advance\insc@unt by 1
  \repeat%
  \global#1=\dimen0 }}

% -------------------------------------------------------- floats corrections
% Correction due to inserts in front of text and add glues from inserts
% to \pg* registers
\def\addprevins#1{\expandafter\def\csname ifprevinsert\number#1\endcsname{}}
\def\removeprevins#1{%
  \expandafter\let\csname ifprevinsert\number#1\endcsname\relax}
\addprevins\topins
\def\countprevinsertcorr#1{{%
  \dimen0=0pt                                           % vsize of prev inserts
  \pgstretchins=0pt \pgfilstretchins=0pt                % glue in prev inserts
  \pgfillstretchins=0pt \pgfilllstretchins=0pt \pgshrinkins=0pt
  \loop\ifnum\insc@unt<255
    \dimen2=\pgshrink \dimen3=\pgstretch \dimen4=\pgfilstretch
    \dimen5=\pgfillstretch \dimen6=\pgfilllstretch
    \countglue{\insc@unt}{\tmps}%
    \getpgregisters{\tmps}%
    \expandafter\ifx\csname ifprevinsert\the\insc@unt\endcsname\relax\else%
      \ifnum\count\insc@unt=1000
        \advance\dimen0 by\ht\insc@unt
        \advance\dimen0 by\dp\insc@unt
      \else%
        \dimen1=0.01\ht\insc@unt \multiply\dimen1 by\count\insc@unt
        \advance\dimen0 by.1\dimen1
        \dimen1=0.01\dp\insc@unt \multiply\dimen1 by\count\insc@unt
        \advance\dimen0 by.1\dimen1
      \fi%
      \setpgprevins%
    \fi%
    \advance\insc@unt by 1
  \repeat%
%  \bgmessage{PrevIns:\the\dimen0}%
  \global#1=\dimen0 }}
\def\setpgprevins{%
  \global\advance\pgshrinkins by-\dimen2
    \global\advance\pgshrinkins by\pgshrink
  \global\advance\pgstretchins by-\dimen3
    \global\advance\pgstretchins by\pgstretch
  \global\advance\pgfilstretchins by-\dimen4
    \global\advance\pgfilstretchins by\pgfilstretch
  \global\advance\pgfillstretchins by-\dimen5
    \global\advance\pgfillstretchins by\pgfillstretch
  \global\advance\pgfilllstretchins by-\dimen6
    \global\advance\pgfilllstretchins by\pgfilllstretch}
\catcode`\@=12

\endinput
