3

I'd like to forbid the \qed symbol to go on the next page in a proof, as the result is ugly:

enter image description here

Any idea how I could solve the problem, ideally by only modifying the proof and/or subproof environments? (I don't want to manually insert \qed).

Thanks!

MWE

% https://tex.stackexchange.com/questions/532948/robustly-add-a-border-to-the-left-of-a-text-spanning-several-pages
\documentclass[a4paper,12pt]{memoir}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc,tikzmark}
\usepackage{lipsum}
%\usepackage{showframe}
\usepackage{everypage}
\usepackage{changepage}
\usepackage{environ}


\newlength{\oldbaselineskip}
\newlength{\oldlineskip}
\newlength{\oldlineskiplimit}

\long\def\addZeroWidthLine#1{%
  \oldbaselineskip=\baselineskip%
  \oldlineskip=\lineskip%
  \oldlineskiplimit=\lineskiplimit%
  \baselineskip=0pt%
  \lineskip=0pt%
  \lineskiplimit=0pt%
  \noindent#1\par\nobreak%
  \baselineskip=\oldbaselineskip%
  \lineskip=\oldlineskip%
  \lineskiplimit=\oldlineskiplimit%
}

\NewEnviron{subproof}{%
  \begin{adjustwidth}{1cm}{0cm}%
    \addZeroWidthLine{\tikzmark{Hello0}}%
    % Ensures a group is inserted around the BODY
    { \noindent \BODY \par\nobreak }% nobreak is used to ensure the tikzmark is not pushed on a new page.
    \addZeroWidthLine{\tikzmark{Bye0}}%
    \tikz[remember picture, overlay] \draw ([xshift=-5mm]pic cs:Hello0) -- ([xshift=-5mm]pic cs:Bye0);
  \end{adjustwidth}%
}%

\begin{document}

\thispagestyle{empty}

\begin{proof}~% Use '~' to ensure  the subproof starts on a new line.
  \begin{subproof}
    \lipsum[1-3]

    Bla bla bla bla  Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla

    Bla bla bla bla  Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla
  \end{subproof}
\end{proof}


\end{document}

In case you want a more complete example (the above has been simplified as much as possible):

% https://tex.stackexchange.com/questions/532948/robustly-add-a-border-to-the-left-of-a-text-spanning-several-pages
\documentclass[a4paper,12pt]{memoir}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc,tikzmark}
\usepackage{lipsum}
%\usepackage{showframe}
\usepackage{everypage}
\usepackage{changepage}
\usepackage{environ}

\def\subproofsDefaultShift{5mm}
% Shift towards the center of the line
\def\subproofsDefaultFirstPointYShift{.3em}
\def\subproofsDefaultSecondPointYShift{0em}

\tikzset{
  /subproofs/defaultStyle/.style={
    black!30!white,
    line width=.4pt,
    transform canvas={xshift=-\subproofsDefaultShift/2-.5pt},
  }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Deal with drawings and marking.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Warning: tikz does not like ExplSyntax since it removes spaces
\def\addTikzmarkAndPagesInfo#1{%
  \tikzmark{beginTikzmark#1}%
  \tikz[remember picture, overlay] \coordinate (pageInfoNWOf#1) at (current page text area.north west);%
  \tikz[remember picture, overlay] \coordinate (pageInfoSEOf#1) at (current page text area.south east);%
}


\def\drawLinesOfTikzmarkSamePage#1{%
  \tikz[remember picture, overlay]%
  \draw[/subproofs/defaultStyle] ([yshift=-\subproofsDefaultFirstPointYShift]pic cs:beginTikzmark#1) to ([yshift=\subproofsDefaultSecondPointYShift]{{pic cs:endTikzmark#1}-|{pic cs:beginTikzmark#1}});%
}

\def\drawLinesOfTikzmarkStart#1{%
  \tikz[remember picture, overlay]%
  \draw[/subproofs/defaultStyle] ([yshift=-\subproofsDefaultFirstPointYShift]pic cs:beginTikzmark#1) to ({pic cs:beginTikzmark#1}|-{current page text area.south west});%
}

\def\drawLinesOfTikzmarkMiddle#1{%
  \tikz[remember picture,overlay] \draw[/subproofs/defaultStyle] %
  let%
    \p1=(pic cs:beginTikzmark#1),%
    \p2=(pageInfoNWOf#1),%
    \p3=(current page text area.north west),%
    \p4=(current page text area.south east) in%
    (\x1-\x2+\x3,\y3) to (\x1-\x2+\x3,\y4);%
}

\def\drawLinesOfTikzmarkEnd#1{%
  \tikz[remember picture,overlay] \draw[/subproofs/defaultStyle] %
  let%
    \p1=(pic cs:beginTikzmark#1),%
    \p2=(pageInfoNWOf#1),%
    \p3=(current page text area.north west),%
    \p4=(current page text area.south east),%
    \p5=([yshift=\subproofsDefaultSecondPointYShift]pic cs:endTikzmark#1) in %
    (\x1-\x2+\x3,\y3) to (\x1-\x2+\x3,\y5);%
}

\makeatletter
% \checkmarkpage{label}{if before}{if same page}{if after}
% Apply different codes if we are on a page before, the current page,
\newcommand{\checkmarkpage}[4]% #1 = tikzmark label, #2 = less, #3 = equal, #4 = greater
{\@ifundefined{save@pt@#1}{#2}{%
  \edef\markid{\csname save@pt@#1\endcsname}%
  \edef\markpage{\csname save@pg@\markid\endcsname}%
  \ifnum\thepage<\markpage\relax #2%
  \else
    \ifnum\thepage=\markpage\relax #3%
    \else #4%
    \fi
  \fi}%
}
\makeatother

%%% Starts expl3 syntax https://mirrors.concertpass.com/tex-archive/macros/latex/contrib/l3kernel/expl3.pdf
%%% For the list of modules and everything http://linorg.usp.br/CTAN/macros/latex/contrib/l3kernel/interface3.pdf
%%% (this also provides a quickstart at the beginning)
%%% For functions https://tex.stackexchange.com/questions/492794/how-to-define-two-expl3-functions-with-the-same-base-name-and-different-signatur
%%% This code is certainly not an example of LaTeX programming as it's the first time I use expl3...
\ExplSyntaxOn

% l=local, name, type. Note that this is only convention, it could be named "\foo" instead.
% clist are list separated by commas.
% To remove stuff https://tex.stackexchange.com/questions/5754/delete-an-element-from-a-comma-delimited-list
\seq_new:N\l_ListOfLinesToDraw_seq{}

\newcounter{nextMarkId}

% Inspired by https://tex.stackexchange.com/questions/528774/excess-vertical-space-in-vdots/528775#528775
% See also https://tex.stackexchange.com/questions/622881/align-element-tikzmark-with-top-of-the-current-line-instead-of-baseline/622936#622936
% TODO: Read also https://fr.overleaf.com/learn/latex/Articles/Boxes_and_Glue%3A_A_Brief%2C_but_Visual%2C_Introduction_Using_LuaTeX

\newlength{\oldbaselineskip}
\newlength{\oldlineskip}
\newlength{\oldlineskiplimit}

\long\def\addZeroWidthLine#1{%
  \oldbaselineskip=\baselineskip%
  \oldlineskip=\lineskip%
  \oldlineskiplimit=\lineskiplimit%
  \baselineskip=0pt%
  \lineskip=0pt%
  \lineskiplimit=0pt%
  \noindent#1\par\nobreak%
  \baselineskip=\oldbaselineskip%
  \lineskip=\oldlineskip%
  \lineskiplimit=\oldlineskiplimit%
}


\NewEnviron{subproof}{%
  \edef\thisMarkId{\thenextMarkId}% Temporary variable to use at the end.
  \seq_gput_right:NV \l_ListOfLinesToDraw_seq \thisMarkId % Add it to the list
  \begin{adjustwidth}{\subproofsDefaultShift}{0cm}%
    \dealWithOneLine:V{\thisMarkId}% Draw the line for the current one.
    \addZeroWidthLine{\addTikzmarkAndPagesInfo{\thenextMarkId}}%
    \stepcounter{nextMarkId}%
    % Ensures a group is inserted around the BODY
    { \noindent \BODY \par\nobreak }%
    \addZeroWidthLine{\tikzmark{endTikzmark\thisMarkId}}%
  \end{adjustwidth}%
}%

%% Create a new function (see http://linorg.usp.br/CTAN/macros/latex/contrib/l3kernel/interface3.pdf page 14)

\cs_new:Nn \dealWithOneLine:n{
  \checkmarkpage{beginTikzmark#1}{%
    %%%%%%%%%% We have not yet seen the beginTikzMark... Don't care.
  }{ %%%%%%%%%% We are on the page of the start.
    \checkmarkpage{endTikzmark#1}%
    {%%%%%%%%%% The end is later
      \drawLinesOfTikzmarkStart{#1}%
      %\printList:N{} Size is \seq_count:N \l_ListOfLinesToDraw_seq%
    }%
    {%%%%%%%%%% The end is on the same page
      \drawLinesOfTikzmarkSamePage{#1}%
      %% We can remove the item from the list so that we don't process it anymore.
      \seq_gremove_all:Nn \l_ListOfLinesToDraw_seq {#1}%
      %\printList:N{} Size is \seq_count:N \l_ListOfLinesToDraw_seq%
    }{% The end was on a previous page... impossible
    }%
  }{ %%%%%%%%%% The start point is on a previous page
    \checkmarkpage{endTikzmark#1}%
    {%%%%%%%%%% The end is later
      \drawLinesOfTikzmarkMiddle{#1}%
      %\printList:N{} Size is \seq_count:N \l_ListOfLinesToDraw_seq%
    }%
    {%%%%%%%%%% The end is on the same page
      \drawLinesOfTikzmarkEnd{#1}%
      %% We can remove the item from the list so that we don't process it anymore.
      \seq_gremove_all:Nn \l_ListOfLinesToDraw_seq {#1}%
      %\printList:N{} Size is \seq_count:N \l_ListOfLinesToDraw_seq%
    }{%%%%%%%%%% The end has already been seen... I don't care
    }%
  }%
}

% defines \dealWithOneLine:V that expands its argument
\cs_generate_variant:Nn \dealWithOneLine:n { V }

%% Create a new function (see http://linorg.usp.br/CTAN/macros/latex/contrib/l3kernel/interface3.pdf page 14)
\cs_new:Nn \dealWithAllLines:N {
  \seq_map_inline:Nn \l_ListOfLinesToDraw_seq {
    \dealWithOneLine:n{##1}
  }
}
%% Create a new function (see http://linorg.usp.br/CTAN/macros/latex/contrib/l3kernel/interface3.pdf page 14)
\cs_new:Nn \printList:N {
  [
  \seq_map_inline:Nn \l_ListOfLinesToDraw_seq {
    ##1,
  }
  ]
}

\AddEverypageHook{\dealWithAllLines:N{}}

\ExplSyntaxOff

\begin{document}

\newpage

\thispagestyle{empty}

\lipsum[1]

% \begin{subproof}
%   ABC
% \end{subproof}

\begin{proof}~% Use '~' to ensure  the subproof starts on a new line.
  % See also https://tex.stackexchange.com/questions/122954/starting-a-proof-with-paragraph
  \begin{subproof}%
    We prove now that $1+1+1 = 3$. First we will prove that $1+1+1=3$:
    \begin{subproof}%
      In order to prove that $1+1+1=3$, we first prove that $1+1=2$.
      \begin{subproof}%
        By definition $2 = 1+1$.
      \end{subproof}%
      But we can show that $1+1+1=2+1$.
      \begin{subproof}%
        Indeed, by associativity of the addition, we know that
        \begin{align}
          1+1+1=(1+1)+1\label{eq:abc}
        \end{align}
        But we saw above that $1+1=2$ so $1+1+1=2+1$
      \end{subproof}%
      It is now possible to see that $1+1+1=3$
      \begin{subproof}%
        We can use now Eq.~\ref{eq:abc} and the definition of $3$:
        \[1+1+1=2+1=3\]
      \end{subproof}%
      As you can see, the spacing issues are now solved. See \texttt{\subproofsDefaultFirstPointYShift} to move more or less the first point on the y axis (to ensure it's not too close to the above line). It defaults to \texttt{0.3em}.
      \begin{subproof}
        Also the line adapts to height and depth \rule[-1cm]{2cm}{3cm}.
      \end{subproof}%
      \lipsum[1-4]
      Bla bla bla bla blaBla bla bla bla blaBla bla bla bla blaBla bla bla bla blaBla bla bla bla blaBla bla bla bla blaBla bla bla bla blaBla bla bla bla blaBla bla bla bla blaBla bla bla bla blaBla bla bla bla blaBla bla bla bla blaBla bla bla bla blaBla bla bla bla bla
    \end{subproof}\nobreak%
  \end{subproof}\nobreak\
\end{proof}
Hello

\begin{subproof}
  Coucou
\end{subproof}


\end{document}
4
  • 1
    Just an idea: Can you put the proof in a minipage? Then there will be no pagebreak. Or maybe the samepage environment is helpful. Commented Nov 18, 2021 at 14:24
  • 2
    @Dr.ManuelKuehner no: actually all the difficulty is that the proofs can span multiple pages. For now I found a solution which semi-works: the user needs to put \qedhere in the last paragraph (too bad I can't find another approach, but I think it's quite fundamental especially because we usually want the qed symbol to be on the same line as the text). I'm still doing some tests.
    – tobiasBora
    Commented Nov 18, 2021 at 14:50
  • 2
    What is happening here is that the subproof definition effectively inserts a \par before the \end{proof}. Why this is happening isn't immediately obvious to me, and I haven't the energy to trace what's happening. But even if the proof isn't near the bottom of the page, that would force the qed box onto a line by itself. So \qedhere is an appropriate remedy for every proof with a subproof. Commented Nov 18, 2021 at 23:18
  • 1
    I've added the amsthm tag since that's where \qedhere is defined. Commented Nov 18, 2021 at 23:23

1 Answer 1

0

I can confirm that \qedhere worked greatly in my case since it also alignes the qed symbol with the text, and I think it's fundamentally hard to avoid it. enter image description here

MWE

% https://tex.stackexchange.com/questions/532948/robustly-add-a-border-to-the-left-of-a-text-spanning-several-pages
\documentclass[a4paper,12pt]{memoir}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc,tikzmark}
\usepackage{lipsum}
%\usepackage{showframe}
\usepackage{everypage}
\usepackage{changepage}
\usepackage{environ}


\newlength{\oldbaselineskip}
\newlength{\oldlineskip}
\newlength{\oldlineskiplimit}

\long\def\addZeroWidthLine#1{%
  \oldbaselineskip=\baselineskip%
  \oldlineskip=\lineskip%
  \oldlineskiplimit=\lineskiplimit%
  \baselineskip=0pt%
  \lineskip=0pt%
  \lineskiplimit=0pt%
  \noindent#1\par\nobreak%
  \baselineskip=\oldbaselineskip%
  \lineskip=\oldlineskip%
  \lineskiplimit=\oldlineskiplimit%
}

\NewEnviron{subproof}{%
  \begin{adjustwidth}{1cm}{0cm}%
    \addZeroWidthLine{\tikzmark{Hello0}}%
    % Ensures a group is inserted around the BODY
    { \noindent \BODY \par\nobreak }% nobreak is used to ensure the tikzmark is not pushed on a new page.
    \addZeroWidthLine{\tikzmark{Bye0}}%
    \tikz[remember picture, overlay] \draw ([xshift=-5mm]pic cs:Hello0) -- ([xshift=-5mm]pic cs:Bye0);
  \end{adjustwidth}%
}%

\begin{document}

\thispagestyle{empty}

\begin{proof}~% Use '~' to ensure  the subproof starts on a new line.
  \begin{subproof}
    \lipsum[1-3]

    Bla bla bla bla  Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla

    Bla bla bla bla  Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla bla Bla bla bla\qedhere
  \end{subproof}
\end{proof}


\end{document}
1
  • You can accept own answer and by this tell audience that your problem is solved (by comments of @barbara beeton).
    – Zarko
    Commented Dec 19, 2021 at 8:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .