如何检查标题是否有结束句号?

如何检查标题是否有结束句号?

我正在修改一些宏来强制以句号结尾的节样式。句号是自动添加的,但有时人们会添加句号,而我得到的是两个句号。我该如何修改代码来检测标点符号并仅在需要时添加它?我想我需要使用 Futurelet,但我不知道如何使用它。

答案1

首先,最好发布 MWE。由于您尚未发布,因此我发布了一个通用答案,要精确格式化该部分,您需要添加自己的格式化命令。

您不需要\futurelet。TeX 会跟踪字母和标点符号的特殊代码,以便在停止符后放置适当的空格。我们可以检查\spacefactor宏的值并添加停止符,如果已经存在,则不执行任何操作。

\newcommand\@addpunctuation[1]{\ifnum\spacefactor>1000\else#1\fi}

代码的其余部分都是次要细节。这是 MWE。

\documentclass{article}
\makeatletter
\newcommand\@addpunctuation[1]{\ifnum\spacefactor>1000\else#1\fi}
\newcommand\buildhead[1]{#1\@addpunctuation.}
\DeclareRobustCommand{\addhead}[1]{\buildhead{#1}}
\DeclareRobustCommand\Section[1]{\addhead{#1}}
\def\section{\secdef \starcmd \unstarcmd}
\def\starcmd[#1]#2{\bfseries\Large\addhead{#2}}
\newcommand\unstarcmd[1]{\bfseries\setcounter{section}{O}\renewcommand\thesection{\Alph{section} \addhead{#1}}}
\makeatother
\parindent0pt
\begin{document}
\makeatletter

\section[small title]{Testing}\\
\section{Testing}\\ % remains as is 
\Section{Testing}\\
\Section{Testing.}
\end{document}

如果您希望宏对\frenchspacing和都起作用\nonfrenchspacing,您可以尝试:

\newcommand\@addpunctuation[1]{%
   \nonfrenchspacing
   \ifnum\sfcode`.=1000
     \ifnum\spacefactor>1000\else#1\fi
   \else
      \ifnum\spacefactor>1000\else#1\fi
      \nonfrenchspacing
  \fi
}

并测试

\frenchspacing

Test. \fbox{A test test}

\nonfrenchspacing

Test. \fbox{A test test}

您也可以访问引用的链接菲利普·古特在下面的评论中。

答案2

这个问题可以在宏观层面得到解决,而不需要“干预”空间因素。

\documentclass{article}
\makeatletter
\usepackage{catoptions}
\robust@def*\newsection#1{%
  \begingroup
  \edef\currtitle{\cpttrimspaces{#1}}%
  \def\currlabel{}\def\lasttok{}%
  \xifinsetFT{\detokenize{\label}}{\cptoxdetok\currtitle}{}{%
    \def\reserved@a##1\label##2##3\cpt@nil{%
      \def\currtitle{##1##3}%
      \def\currlabel{\noexpand\label{##2}}%
    }%
    \expandafter\reserved@a\currtitle\cpt@nil
  }%
  \def\getlasttok##1{%
    \expandafter\ifx\@car##1\@nil\cpt@nnil
    \else
      \edef\lasttok{\unexpanded{##1}}%
      \expandafter\getlasttok
    \fi
  }%
  \expandafter\getlasttok\currtitle\cpt@nnil
  \s@expandarg\ifinsetTF\lasttok{\dots\ldots\textellipsis}{%
    \@tempswatrue
  }{%
    \begingroup
    \lccode`\X=133
    \lowercase{\endgroup\expandafter\expandafter\expandafter
      \ifstrcmpTF\expandafter\@car\lasttok\@nil X}{%
      \@tempswatrue
    }{%
      \@tempswafalse\let\elt\relax
      \def\siso@do##1{%
        \xifinsetFT{\detokenize{##1}\elt}{\cptoxdetok\currtitle\elt}{}{%
          \@tempswatrue\loopbreak
        }%
      }%
      \siso@@loop{.!?:\dots\ldots\textellipsis}%
    }%
  }%
  \def\elt{\expandcsonce\currtitle}%
  \cptexpandarg{\endgroup\section}{\if@tempswa\elt\else\elt.\fi\currlabel}%
}
\makeatother

\begin{document}
\newsection{Test section.\label{sec:1}}
As seen later in Section~\ref{sec:this} \ldots.
\newsection{Test section}
\newsection{Test section.}
\newsection{Is this a test section?}
\newsection{Heh, this is test section!}
\newsection{Test section\dots}
\newsection{Test section\ldots}
\newsection{Test section\textellipsis}
\newsection{Test section\label{sec:this}\ldots}
As seen earlier in Section~\ref{sec:1} \ldots.

% I have accounted for the ASCII character 133 but you may not get it to print:
\newsection{Test section …}
\end{document}

相关内容