Primer método: parchear\@startsection

Primer método: parchear\@startsection

Estoy intentando restablecer el contador cada vez que encuentro algo sectionbasado en esto.doc.

\documentclass{article} 

\newcounter{example}[section]  % This line reset the counter every time meet a section
\newenvironment{example}[1][]
{\refstepcounter{example}\par\medskip
   \subsection*{Example~\theexample. #1} \rmfamily}
{\medskip}

\begin{document}

\section{Section}

\begin{example}
A
\end{example}

\begin{example}
B
\end{example}

\section{Another section}

\begin{example}
C
\end{example}

\end{document}

Esto generará

ingrese la descripción de la imagen aquí

lo que significa que funciona.

Sin embargo, ahora quiero eliminar el número antes de la sección, así que agregué *después section.

\documentclass{article} 

\newcounter{example}[section]  % Tried to change `section*`, but throws error
\newenvironment{example}[1][]
{\refstepcounter{example}\par\medskip
   \subsection*{Example~\theexample. #1} \rmfamily}
{\medskip}

\begin{document}

\section*{Section}

\begin{example}
A
\end{example}

\begin{example}
B
\end{example}

\section*{Another section}

\begin{example}
C 
\end{example}

\end{document}

Sin embargo, esta vez, el contador no se reiniciará como

ingrese la descripción de la imagen aquí

Si cambié a

\newcounter{example}[section*]

arrojará error

No hay ningún contador 'sección*' definido.

¿Cómo restablecer el contador cuando nos reunimos section*?

Respuesta1

Obtuviste un error \newcounter{example}[section*]porque section*no es un contador en LaTeX. sectionlo es, pero no section*.

Primer método: parchear\@startsection

Puede parchear \@startsectionpara que \section*se llame cuando (que es un comando de sección de nivel 1) y solo en este caso, su examplecontador se reinicie a 0. Lo siguiente funciona porque \@ssectsolo se llama para comandos de sección no numerados, y solo reiniciamos el contador cuando el nivel del comando de seccionamiento es 1 ( \sectiono \section*).

\documentclass{article}
\usepackage{etoolbox}

\newcounter{example}[section]
\newenvironment{example}[1][]
  {\refstepcounter{example}\par\medskip
   \subsection*{Example~\theexample. #1}%
   \rmfamily}
  {\medskip}

\makeatletter
\patchcmd{\@startsection}
  {\@ssect}{\ifnum#2=1 \setcounter{example}{0}\fi\@ssect}
  {}{\FAILED}
\makeatother

\begin{document}

\section*{Section}

\begin{example}
A
\end{example}

\begin{example}
B
\end{example}

\section*{Another section}

\begin{example}
C
\end{example}

\begin{example}
D
\end{example}

\section{Numbered section}

\begin{example}
E
\end{example}

\begin{example}
F
\end{example}

\end{document}

Segundo método: usar xparsepara redefinir\section

Otra forma de lograr el mismo resultado es usar xparsepara redefinir \section, como lo hizo egreg enesta respuesta. La ventaja de esta técnica es que no depende de los detalles de implementación de \sectiony \@startsection, por lo tanto, siempre debería funcionar incluso si \sectionse ha redefinido y \sectionya no es un comando de LaTeX2e; este puede ser el caso si redefine \sectionusando un paquete como titlesec, o simplemente si intentas acumular varias redefiniciones hechas con la primera técnica. Por tanto, diría que este segundo método es mejor desde el punto de vista de la ingeniería.

\documentclass{article}
\usepackage{xparse}

\newcounter{example}[section]
\newenvironment{example}[1][]
  {\refstepcounter{example}\par\medskip
   \subsection*{Example~\theexample. #1}%
   \rmfamily}
  {\medskip}

% Save the original \section command
\let\latexsection\section

% Simple redefinition of \section (including \section*)
\RenewDocumentCommand{\section}{sO{#3}m}{%
  \IfBooleanTF{#1}
    {\setcounter{example}{0}%
     \latexsection*{#3}}
    {\latexsection[#2]{#3}}%
}

\begin{document}

\section*{Section}

\begin{example}
A
\end{example}

\begin{example}
B
\end{example}

\section*{Another section}

\begin{example}
C
\end{example}

\begin{example}
D
\end{example}

\section{Numbered section}

\begin{example}
E
\end{example}

\begin{example}
F
\end{example}

\end{document}

Ambas técnicas conducen al siguiente resultado:

Captura de pantalla

Comentarios sobre la implementación de entornos definidos por el usuario

En su entorno real, es posible que desee hacer algo como esto (o una variante) para asegurarse de que su entrada no introduzca espacios no deseados. Esta es una observación general sobre entornos definidos por el usuario; ya que \subsection*normalmente comienza un nuevo párrafo, a menos que esté utilizando elentrar corriendotipo de diseño: \ignorespacesprobablemente no sea necesario aquí, por ejemplo. De manera similar, \ignorespacesafterendno debería ser necesario after \par\medskip, ya que \parcoloca TeX en modo vertical donde se ignoran los espacios, pero de todos modos no debería hacer daño.

\newenvironment{example}[1][]
  {\refstepcounter{example}\par\medskip
   \subsection*{Example~\theexample. #1}%
   \rmfamily
   \ignorespaces}
  {\unskip
   \par\medskip
   \ignorespacesafterend}

información relacionada