1

I have created some environments using

\newtheorem{theo}{Theorem}[section]
\newtheorem{defi}[theo]{Definition}
\newtheorem{obs}[theo]{Observation}
...

and a few more. I'd like to modify all of them adding \begin{samepage} before and \end{samepage} after each one.

I want something like this:

\newtheorem{pretheo}{Theorem}[section]
\newenvironment{theo}{\begin{samepage}\begin{pretheo}}{\end{pretheo}\end{samepage}}

but I have too many different environments and I think it's so rough to create two environments for each one. Is there any direct way to do it with all of them at the same time?

Thanks a lot!

Carbonard
  • 21
  • 4
  • 1
    Which theorem package do you use? This relates to how \newtheorem is defined. – muzimuzhi Z Jun 08 '20 at 06:38
  • I suppose it's the package amsthm, but then I have amsmath and amssymb too (Not sure how they work). – Carbonard Jun 08 '20 at 14:30
  • amsmath works with amsthm to control placement of equation numbers and the qed markere, but is neither related otherwise nor necessary for theorems. amssymb is totally separate and unrelated. – barbara beeton Oct 27 '22 at 17:52
  • Presumably none of your theorems will be longer than a full page. But even if they are more than a few lines long, and don't fit on the current page, you may end up with a spacy page if the entire theorem is moved to the next page. A possible compromise is to use \needspace{4\baselineskip} before theorem-class objects. – barbara beeton Oct 27 '22 at 17:59

2 Answers2

1

The following example patches the internal macro of \newtheorem (amsthm version) to collect the theorem environment name in a list, then redefines those environments at the beginning of document. Here the code execution order is significant, you must firstly patch the internal, then use \newtheorem, at last redefine theorems.

\documentclass{article}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{etoolbox}

%% codes added before every occurrances of \newtheorem \makeatletter % init a comma-seperated list \let\thm@list@empty

% patch @xnthm, collect theorem env names in \thm@list % This patch must be used before any use of \newtheorem. \patchcmd@xnthm {\global@xp\let} {\g@addto@macro\thm@list{,#2}\global@xp\let} {}{\fail}

% patch every theorem env defined before \begin{document} \AtBeginDocument{ % strip comma from left \def\lstrip@comma,#1@nil#2{\def#2{#1}} \expandafter\lstrip@comma\thm@list@nil\thm@list

% patch theorem envs @for@tempa:=\thm@list\do{% % backup \csletcs{@tempa @backup}{@tempa}% \csletcs{end@tempa @backup}{end@tempa}% % redefine \edef\temp{% \noexpand\renewenvironment{@tempa} {\noexpand\begin{samepage}\noexpand\begin{@tempa @backup}} {\noexpand\end{@tempa @backup}\noexpand\end{samepage}}% } \temp } } \makeatother

\newtheorem{thm}{Theorem}[section] \newtheorem{defn}[thm]{Definition}

\begin{document} \section{title} \begin{thm} content \end{thm}

\begin{defn} content \end{defn}

\begin{thm}[title] content \end{thm}

\begin{defn}[title] content \end{defn} \end{document}

PS: From document source2e, section 17.4, in LaTeX2e \samepage is no longer supported. So I'm not sure if it is recommended to use samepage environment in 2020. Normally you can use minipage environment, see Unbreakable block.

Update on 2023-05-27: The upcoming LaTeX2e 2023-06-01 release confirms \samepage is still supported. The sentence read in source2e.pdf

Since in 2e |\samepage| is no longer supported, ...

is deleted. Related links

  • commit ecf19e5a (Gh1022 (#1023), 2023-03-22)
    • pull request #1023 Gh1022
    • issue #1022 Resetting \predisplaypenalty in \samepage
  • commit a7187bb5 (update some documentation around "samepage"; it is still (reluctantly) supported after all [ci skip], 2023-05-26)
muzimuzhi Z
  • 26,474
  • I really appreciate your help, but as I don't understand latex at this level, I just copy-pasted it and it gives some errors before compiling after the line % redefine like "invalid environment command \begin{" or "unexpected close group } after \begin{samepage}". Moreover when I compile it doesn't work as expected, instead of keeping all the environment at the same page, I have the Theorem 3.7 at the end of the page, and the theorem itself on the following page. And anyway, do you recommend any alternative to the samepage environment? – Carbonard Jun 08 '20 at 20:09
  • 1
    @Carbonard If my example compiles on your side but the combination of your document + my code compiles with errors, then you need to provide an [MWE] showing your problem. If my example doesn't compile on your side, then you can check your latex installation version info and see if it is too old. I tested on Overleaf.com, and my example compiles from texlive 2014 to 2019. And you can use minipage instead of samepage, see https://tex.stackexchange.com/q/4471/79060. – muzimuzhi Z Jun 08 '20 at 23:46
  • It's strange, I'm using overleaf too. I will investigate better how latex works to see if I can adapt this to my code. Thank you very much anyway. – Carbonard Jun 09 '20 at 04:49
  • @muzimuzhiZ -- I've just reviewed an advance copy of LaTeX News for this year's LaTeX release. It reports adjustments to \samepage, so your note that this is obsolete isn't valid. I checked with Frank Mittelbach, and he recommended eliminating that comment. I'd rather you make the correction; if you would like details, send me email. – barbara beeton May 26 '23 at 15:11
  • @barbarabeeton Oh... I totally forgot I ever commented \samepage in one of my tex-sx answers. Instead of a simple elimination, I applied line through to my previous comment and added description about correct/latest state of \samepage with supporting links to the latex2e repo. Are such changes acceptable to you? – muzimuzhi Z May 27 '23 at 02:10
  • 1
    I knew you could do a better job than I could. Thanks. (I'm a fan of \samepage, and would hate to lose it.) – barbara beeton May 27 '23 at 12:42
1

You can recreate the infrastructure and define a \newstheorem that defines “samepage” theorems.

\documentclass{article}
\usepackage{amsthm} % not required, but better loading it

\usepackage{lipsum} % for mock text

\NewDocumentCommand{\newstheorem}{smomo}{% % #1 = optional * for unnumbered theorem % #2 = env name % #3 = shared counter % #4 = label % #5 = parent counter % define the true environment \newenvironment{#2} {\par\pagebreak[0]\begin{samepage}\UseName{#2@inner}} {\UseName{end#2@inner}\end{samepage}}% \IfBooleanTF{#1} {\newtheorem*{#2@inner}{#4}}% {% \IfNoValueTF{#5}{% % no parent counter \IfNoValueTF{#3}{% % no shared counter \newtheorem{#2@inner}{#4}% }{% shared counter \newtheorem{#2@inner}[#3@inner]{#4}% }% }{% parent counter \newtheorem{#2@inner}{#4}[#5]% }% }% }

\newtheorem{theonormal}{Theorem}[section]

\newstheorem{theo}{Theorem}[section] \newstheorem{defi}[theo]{Definition} \newstheorem{obs}[theo]{Observation}

\newstheorem*{foo}{Foo}

\begin{document}

\lipsum[1-4]

\begin{theonormal} \lipsum[5-6] \end{theonormal}

\clearpage

\lipsum[1-4]

\begin{theo} \lipsum[5-6] \end{theo}

\clearpage

\lipsum[1-3]

\begin{theo} \lipsum[5-8] \end{theo}

\end{document}

In the first two pages I show what normally would happen.

In the following two pages, the “samepage theorem” is used.

The last two pages show that if the statement is very long, samepage has no effect, but this should not be a real problem.

enter image description here

egreg
  • 1,121,712