TeXbook の「危険な曲げ演習」を `amsthm` で再現する方法

TeXbook の「危険な曲げ演習」を `amsthm` で再現する方法

私は今、文書を入力しており、warning定理環境を で作成していますamsthm。私が興味をそそられるのは、KnuthのTeXbook についてどうやら環境のように見えるものの前に「危険な曲がり」記号を配置することができましたexercise。記号はちょうど 2 行にまたがり、太字EXERCISEとそれに続くテキストがその記号を囲むため、3 行目が始まり、再び左余白になります。

私の質問は、これを望ましい(修正された)環境で再現できるかどうかですamsthmtrivlist環境の実装では問題が発生することはわかっていますが、amsthmなしで環境の外観を再現できる可能性がありますtrivlist。危険な曲がりはヘッダーの前でも発生することに注意してください(たとえば、TeXbook について)。

答え1

あなたの回答には非常に良いコードがありますが、改善の余地があります。特に、\clubpenaltiesではなくを使用している\clubpenaltyので、

  1. 2 行目以降でページを区切らないようにします。
  2. 殴られる心配はありません\clubpenalty
  3. \clubpenaltiesフックでリセットします。

ヘッダーもタイプセットします段落が始まるので、\labelスペースを気にせずに使用できます。

\prevgraf1 行の警告の場合、最初の段落の末尾を調べ、1 の場合はページ区切りのない空行が生成されます。

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

ここに画像の説明を入力してください

答え2

何度も調整した結果、満足のいく結果が得られたと思います。環境から基本パラメータを取得しamsthm、KnuthのTeXbook についてコード。

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

ここに画像の説明を入力してください

質問が2つあります。

  1. 現時点では、\clubpenalty=10000環境全体に適用されます。この環境内の最初の段落にのみ適用することはできますか?TeXbook についてクヌースは、それぞれの「危険な」段落に危険な曲がり記号を付けることを要求したため、この問題を解決しませんでした。
  2. ご覧の通り警告 0.3、単一の線はあまり見栄えがよくありません。これを改善する方法はありますか? 内に線が 1 本しかない場合は、の代わりにwhoose footwarningを使用し、その中心がベース ライン上にないことを提案します。これを検出するにはどうすればよいですか?\textdbend\dbend

amsthm元の環境に欠けている点や、上記のコードの改善点などがあれば、お気軽にフィードバックをお寄せください。

関連情報