Como recriar o “exercício de curva perigosa” no TeXbook com `amsthm`

Como recriar o “exercício de curva perigosa” no TeXbook com `amsthm`

Estou digitando um documento agora e tenho um warningambiente de teorema, criado comamsthm . O que me intriga é que KnuthO TeXbookconseguiu colocar o símbolo da “curva perigosa” na frente do que parece ser um exerciseambiente. O símbolo abrange exatamente duas linhas, e o EXERCISEtexto em negrito e o seguinte envolvem esse símbolo, de modo que a terceira linha comece e a margem esquerda novamente.

Minha pergunta é se posso recriar isso com amsthmambientes preferencialmente (modificados). Eu sei que trivlistna implementação dos ambientes causa problemas, mas talvez seja possível recriar o visual dos amsthmambientes semtrivlist . Observe que a curva perigosa vem antes mesmo do cabeçalho (por exemplo, página 5 doO TeXbook).

Responder1

Código muito bom em sua resposta, mas pode ser melhorado. Em particular, eu uso \clubpenaltiesem vez de \clubpenalty, para que possamos

  1. desencoraje uma quebra de página após a segunda linha;
  2. não se preocupe com a derrota \clubpenalty;
  3. redefinir \clubpenaltiescom um gancho.

Eu também escrevi o cabeçalhodepoiso parágrafo começa, para que possamos usar \labele não nos preocupar com espaços.

Para um aviso de uma linha, examinamos \prevgrafno final do primeiro parágrafo e, se for 1, é gerada uma linha vazia sem possível quebra de página.

\documentclass{article}

\usepackage{manfnt} % for \dbend
\usepackage{lipsum} % for testing

\counterwithin{equation}{section}

\newlength{\dangerwidth} % width of \dbend
\settowidth{\dangerwidth}{\dbend}
\addtolength{\dangerwidth}{1em} % add any extra space between \dbend and text

\NewDocumentEnvironment{warning}{o}{%
  % I mostly use equation counter, feel free to use any other one
  % default \topsep before theorem environment
  \par\addvspace{\topsep}
  % no line break after first line and discourage after second line
  \clubpenalties=3 10000 5000 0 
  % after first paragraph, reset \clubpenalties
  \AddToHookNext{para/end}{\clubpenalties=0 }%
  % after first paragraph, count the number of lines, if one add an empty line and no page break
  \AddToHookNext{para/after}{\ifnum\prevgraf=1 \nopagebreak\hbox{}\fi}%
  % specifying indentation of first two lines
  \hangindent=\dangerwidth \hangafter=-2 
  % step the associated counter
  \refstepcounter{equation}%
  % store the start so to allow for \label
  \everypar\expandafter{%
    % remove the indentation box
    {\setbox0=\lastbox}% <----  !!!!!!!
    % zero width \dbend, shifted to left border
    \makebox[0pt]{\hspace*{-\hangindent}\dbend\hfill}%
    % theorem name and number
    \textbf{Warning \theequation}%
    % the attribution, if given
    \IfValueT{#1}{ (#1)}%
    % punctuation and space after
    \textbf{.}\hspace*{5pt plus 1pt minus 1pt}%
    % reset \everypar
    \everypar{}%
  }%
  % ignore spaces at the beginning
  \ignorespaces
}{
  % end the paragraph
  \par
  % default space after the environment
  \addvspace{\topsep}%
}

\begin{document}

\lipsum[66]

\begin{warning}[a note]\label{xyz}
    \lipsum[66]

    \lipsum[66]
\end{warning}

\begin{warning}
    \lipsum[66]
\end{warning}

\lipsum[66]

\begin{warning}
    One single line looks weird.
\end{warning}

Let's see the reference \ref{xyz}

\lipsum[66]

\end{document}

insira a descrição da imagem aqui

Responder2

Depois de muito mexer, acho que tenho um resultado satisfatório. Peguei os parâmetros básicos deamsthm ambientes e me inspirei nos de KnuthO TeXbookcódigo.

\documentclass{article}

\usepackage{manfnt} % for \dbend
\usepackage{lipsum} % for testing

\newlength{\dangerwidth} % width of \dbend
\settowidth{\dangerwidth}{\dbend}
\addtolength{\dangerwidth}{1em} % add any extra space between \dbend and text

\newenvironment{warning}[1][]{
    \begingroup % local definition
    \stepcounter{equation} % I mostly use equation counter, feel free to use any other one
    \par\addvspace{\topsep} % default \topsep before theorem environment
    \clubpenalty=10000 % no line break after first line
    \hangindent=\dangerwidth \hangafter=-2 % specifying indentation of first two lines
    \noindent\makebox[0pt]{\hspace*{-\hangindent}\dbend\hfill}% % zero width \dbend, shifted to left boarder
    \textbf{Warning \thesection.\theequation}% % theorem name and number
    \if\relax\detokenize{#1}\relax\else % optional argument, check if empty
        \space(#1)% % if so, type optional argument in parenthesis
    \fi
    \textbf{.}\hspace*{5pt plus 1pt minus 1pt}\ignorespaces % add default rubber after theorem header
}{
    \par\addvspace{\topsep}\endgroup % default \topsep after environment
}

\begin{document}

\lipsum[66]

\begin{warning}[a note]
    \lipsum[66]

    \lipsum[66]
\end{warning}

\begin{warning}
    \lipsum[66]
\end{warning}

\lipsum[66]

\begin{warning}
    One single line looks weird.
\end{warning}

\end{document}

insira a descrição da imagem aqui

Eu tenho duas perguntas:

  1. A partir de agora, o\clubpenalty=10000 aplica-se a todo o ambiente. Posso de alguma forma aplicá-lo apenas ao primeiro parágrafo dentro deste ambiente? EmO TeXbook, Knuth não resolveu esse problema, pois exigia que cada parágrafo "perigoso" recebesse um símbolo de dobra perigosa.
  2. Como você pode ver emAviso 0,3, uma única linha não parece muito bonita. Existe uma maneira de remediar isso? Eu sugeriria que se houver apenas uma linha interna warning, pode-se usar \textdbendem vez de \dbendcujo pé e não seu centro está na linha de base. Como faço para detectar isso?

Sinta-se à vontade para dar feedback sobre qualquer coisa que esteja faltando nos amsthmambientes originais ou melhorias no código acima.

informação relacionada