用于隐藏空白部分的宏无法正常工作

用于隐藏空白部分的宏无法正常工作

为了能够通过添加新部分来概述我的文档的大部分内容,但又不使编译后的文档中出现我未写任何内容的部分,我基于来自的宏定义了五个宏当部分为空时隐藏部分标题

\newcommand{\showpart}[2]{%
    \ifstrequal{ #2}{ }{}{\part{#1} #2}%
}
\newcommand{\showchapter}[2]{%
    \ifstrequal{ #2}{ }{}{\chapter{#1} #2}%
}
\newcommand{\showsection}[2]{%
    \ifstrequal{ #2}{ }{}{\section{#1} #2}%
}
\newcommand{\showsubsection}[2]{%
    \ifstrequal{ #2}{ }{}{\subsection{#1} #2}%
}
\newcommand{\showsubsubsection}[2]{%
    \ifstrequal{ #2}{ }{}{\subsubsection{#1} #2}%
}

现在我在整个源文件中都使用它们,而不是正常的、、\part和。我还添加了序言以获取宏。但是,我尚未开始编写任何内容的所有部分仍然显示在编译后的文档中。我做错了什么?\chapter\section\subsection\subsubsection\usepackage{etoolbox}ifstrequal

答案1

您似乎遇到的问题是\showxxxx宏的第二个参数中有空行。这些空行会导致段落中断,即\par添加了一个。这意味着您必须测试三种不同的东西:参数完全为空、参数为空格、参数为空格加\par。您可以使用以下代码执行此操作:

\documentclass{article}

\makeatletter
\newcommand{\showsection}[2]{%
    \begingroup
    \def\@tempa{#2}%
    \def\@tempb{ \par}%
    \ifcase0%
       \ifx\@tempa\@empty 1\else
       \ifx\@tempa\space  1\else
       \ifx\@tempa\@tempb 1\fi\fi\fi
    \relax
       \endgroup
       \section{#1} #2%
    \else
       \endgroup
    \fi
}
\makeatother

\begin{document}

\showsection{test1}{
    Some text
}

\showsection{test2}{}

\showsection{test3}{
}

\showsection{test4}{

}

\end{document}

如果您需要将其用于多个不同的分段命令,我会将其转变为通用宏,而不是为每个命令复制代码。

\makeatletter
\newcommand{\showsectioning}[3]{%
    \begingroup
    \def\@tempa{#3}%
    \def\@tempb{ \par}%
    \ifcase0%
       \ifx\@tempa\@empty 1\else
       \ifx\@tempa\space  1\else
       \ifx\@tempa\@tempb 1\fi\fi\fi
    \relax
       \endgroup
       #1{#2} #3%
    \else
       \endgroup
    \fi
}
\makeatother
\newcommand\showsection{\showsectioning\section}
\newcommand\showsubsection{\showsectioning\subsection}
\newcommand\showsubsubsection{\showsectioning\subsubsection}
\newcommand\showchapter{\showsectioning\chapter}
\newcommand\showpart{\showsectioning\part}

替代更好的解决方案

由于您还想忽略较高的分段命令,而只使用空的较低分段命令,因此上述解决方案并不合理。(如果您发布了正常使用示例,那就更好了。)您必须检查很多组合。我建议采用不同的方法。您可以让宏\show...向前查看并检查是否还有\par其他宏以外的内容,而不是将整个(子..)部分作为宏参数读取,这无论如何都非常低效\show...。如果此宏是较低的分段宏,请使用缓冲区记住当前宏,并在找到某些内容或较高宏时重复此操作\show...。在 TeX 的强大功能范围内编写类似的东西,但是一个高级主题。

这里是我建议的解决方案包括示例/测试代码:

\documentclass{article}

\newcommand{\showpart}{%
    \showsectioning{1}\part
}
\newcommand{\showchapter}{%
    \showsectioning{2}\chapter
}
\newcommand{\showsection}{%
    \showsectioning{3}\section
}
\newcommand{\showsubsection}{%
    \showsectioning{4}\subsection
}
\newcommand{\showsubsubsection}{%
    \showsectioning{5}\subsubsection
}
\makeatletter
\expandafter\let\csname showsectioning@buffer@1\endcsname\@empty
\expandafter\let\csname showsectioning@buffer@2\endcsname\@empty
\expandafter\let\csname showsectioning@buffer@3\endcsname\@empty
\expandafter\let\csname showsectioning@buffer@4\endcsname\@empty
\expandafter\let\csname showsectioning@buffer@5\endcsname\@empty
\chardef\showsectioning@highestlevel=0\relax
\newcommand{\showsectioning}[3]{%
    \@ifnextchar\par{%
        \@firstoftwo{\showsectioning{#1}{#2}{#3}}%
    }{%
        \@showsectioning{#1}{#2}{#3}%
    }%
}
% Own macro for efficiency
% The next token is in \@let@token
\newcommand{\@showsectioning}[3]{%
        % Store highest level
        \ifnum\showsectioning@highestlevel=0
            \chardef\showsectioning@highestlevel=#1\relax
        \fi
        % Store number of next sectioning macro (0 = no sectioning macro)
        \chardef\showsectioning@number=0%
            \ifx\@let@token\showpart 1\else
            \ifx\@let@token\showchapter 2\else
            \ifx\@let@token\showsection 3\else
            \ifx\@let@token\showsubsection 4\else
            \ifx\@let@token\showsubsubsection 5\fi
            \fi\fi\fi\fi\relax
        \ifcase0%
            \ifnum#1<\showsectioning@number 1\else
            \ifnum\showsectioning@number>\showsectioning@highestlevel 2\else
            \ifnum\showsectioning@number>0 3\else
            \ifx\@let@token\end 3\fi
            \fi\fi\fi
        \relax% case 0
            % Some content found
            % Pasting and clearing all buffers
            \@tempcnta=\showsectioning@highestlevel
            \loop
                \csname showsectioning@buffer@\number\@tempcnta\endcsname
                \global\expandafter\let\csname showsectioning@buffer@\number\@tempcnta\endcsname\@empty
                \advance\@tempcnta\@ne
                \ifnum\@tempcnta<6
            \repeat
            #2{#3}%
        \or% case 1
            % Lower sectioning command found, buffering current level
            \global\@namedef{showsectioning@buffer@#1}{#2{#3}}%
        \or% case 2
            % Higher sectioning command found, but still a lower one than the highest level
            % Clearing all buffers up to this level
            \@tempcnta=\showsectioning@number
            \loop
                \global\expandafter\let\csname showsectioning@buffer@\number\@tempcnta\endcsname\@empty
                \advance\@tempcnta\@ne
                \ifnum\@tempcnta<6
            \repeat
        \else% case 3
            % Some end delimiter found (\end, \show... command of higher level)
            % Therefore no content, clearing all buffers
            \@tempcnta=\showsectioning@highestlevel
            \loop
                \global\expandafter\let\csname showsectioning@buffer@\number\@tempcnta\endcsname\@empty
                \advance\@tempcnta\@ne
                \ifnum\@tempcnta<6
            \repeat
        \fi
}
\makeatother

\begin{document}

\showsection{Not empty}
test
\showsection{empty}



\showsection{Not empty again}

Hello

\showsection{With empty subsection}

\showsubsection{empty subsection}

\showsection{With non empty subsection}

\showsubsection{Non empty subsection}
Not empty


\showsection{With empty subsection and empty subsubsection}

\showsubsection{empty subsection}

\showsubsubsection{empty subsubsection}

\showsection{Not empty, but with empty subsection}
Stuff

\showsubsection{empty subsection}

\showsection{With \texttt{\string\empty}}
\empty

\showsection{With \texttt{\string\relax}}
\relax


\showsection{Multiple levels 1}
\showsubsection{Multiple levels 1a}
\showsubsection{Multiple levels 1b}
\showsubsubsection{Multiple levels 1bI}
\showsubsubsection{Multiple levels 1bII}
\showsubsection{Multiple levels 1c}
    test

\showsection{trailing}

\end{document}

相关内容