我正在尝试创建一个应具有以下行为的宏:
\( \)
如果不引起overfull \hbox
警告,则使用内联模式编写数学表达式,- 如果第一个选项引起警告,则在
dmath
环境中(从包中)写入相同的表达式。breqn
overfull \hbox
我的问题是检测overfull \hbox
,然后将变量设置为 true 或 false,以便宏可以相应地执行。这是我的宏:
\newcommand{\mymath}[1]{%
\newif\iftest%
\testfalse
\iftest
\(#1\)
\else
: \begin{dmath}#1\end{dmath}
\fi}
\testfalse
为了实现所需的行为,我应该用什么来代替该行(这里仅用于示例目的)?
答案1
\overfull \hbox
感谢 egreg 的评论,我意识到在编译代码时检测警告并不容易。这就是为什么我决定开发一个小脚本来编译 .tex 文件,检测overfull \hbox
与使用宏相关的警告并在重新编译之前调整 .tex 文件。
用于演示的 TeX 文件
\documentclass[draft]{article}
\usepackage{lipsum}
\usepackage[demo]{graphicx}
\usepackage{breqn}
\newif\ifoverfullbox%
\newcommand{\mymath}[1]{%
\ifoverfullbox
: \begin{dmath}#1\end{dmath}
\else
\(#1\)
\fi}
\overfullboxfalse
\begin{document}
\lipsum[1]
Here-is-a-definition-of-a-long-long-long-math-environment,-a-long-one\mymath{f(x),g(y),h(z)}.
\begin{figure}[!h]
\includegraphics[width=15cm,height=3cm]{blabla}
\end{figure}
Here-is-a-\mymath{and again}-of-a-long-long-long-math-environment,-a-long-one\mymath{f(x),g(y),h(z)}.
\end{document}
使用脚本之前的输出
此示例产生 3 个警告:
- 第一个原因是在行尾使用了宏,而 TeX 不知道如何换行,
- 第二个是由于图形太宽,
- 第三个与第一个类似,但包含两次对宏的调用。
使用脚本后的 TeX 文件
序言完全一样
\begin{document}
\lipsum[1]
\overfullboxtrue Here-is-a-definition-of-a-long-long-long-math-environment,-a-long-one\mymath{f(x),g(y),h(z)}.\overfullboxfalse
\begin{figure}[!h]
\includegraphics[width=15cm,height=3cm]{blabla}
\end{figure}
Here-is-a-\mymath{and again}-of-a-long-long-long-math-environment,-a-long-one\mymath{f(x),g(y),h(z)}.
\end{document}
有两个新元素:变量overfullbox
在包含一次宏调用的行首设置为 true,并在此行末尾重置为 false。
使用脚本后的输出
由于该脚本,一个Overfull \hbox
警告消失了。
剧本
#!/bin/bash
FILENAME=$1
MYCMD=$2
TEXCMD="pdflatex -interaction=batchmode"
OUTFILE=${FILENAME}_overfull_correction.txt
eval "rm $OUTFILE"
echo "This is the report file from the overfull \hbox correction for the $FILENAME.tex file." >> $OUTFILE
eval "$TEXCMD $FILENAME.tex"
OBOXES=( $(fgrep 'Overfull' $FILENAME.log | grep -o 'lines.*--'| grep -P '\d*' -o) )
COUNTER=$(fgrep 'Overfull' $FILENAME.log | grep -o 'lines.*--'| grep -P '\d*' -oc)
echo " " >> $OUTFILE
for ((ii=0;ii<COUNTER;ii++))
do
TEST=$(sed "${OBOXES[$ii]}q;d" $FILENAME.tex | grep -o "$MYCMD" | wc -l)
if [ "$TEST" == "0" ]
then
echo "Overfull \hbox warning not due to $MYCMD line ${OBOXES[$ii]}" >> $OUTFILE
fi
if [ "$TEST" == "1" ]
then
eval "sed -i '${OBOXES[$ii]}s/^/\\\overfullboxtrue /' $FILENAME.tex"
eval "sed -i '${OBOXES[$ii]}s/$/\\\overfullboxfalse/' $FILENAME.tex"
echo "Overfull \hbox warning corrected line ${OBOXES[$ii]}" >> $OUTFILE
fi
if [ "$TEST" == "1" -a "$TEST" == "0" ]
then
echo "More than one occurence of the $MYCMD command line ${OBOXES[$ii]}" >> $OUTFILE
fi
done
eval "$TEXCMD $FILENAME.tex"
COUNTER2=$(fgrep 'Overfull' $FILENAME.log | grep -o 'lines.*--'| grep -P '\d*' -oc)
echo "Recompiled file, $COUNTER2 Overfull \hbox warning(s) remaining" >> $OUTFILE
echo "Process exited normally" >> $OUTFILE
exit
简要介绍一下它的工作原理:
- 首先,它编译.tex 文件并写入报告文件的标题。
- 它计算并存储引起警告的.tex 文件中的行,并将其存储
Overfull
在.log 文件中。 - 它对这些行执行循环,针对每个警告:
- 如果不是来自指定的命令,它会将其写入报告文件并进入下一次迭代,
- 如果相关行上有多个宏调用,它会将其写入报告文件并进入下一次迭代,
- 如果在关注的行中有一个宏调用,它会添加到
\overfullboxtrue
该行的开头和\overfullboxfalse
结尾。 - 它重新编译.tex 文件并在报告文件中写入剩余警告的数量
Overfull
。
优点和缺点
对于好的方面,我让你判断这可能如何有助于修复一些警告,但是我想强调一些缺点(也许你会有一些想法来修复它们?):
- 无论如何,您都需要去手动更改您的.tex 文件以修复所有其他警告......
dmath
就您围绕数学表达式编写句子的方式而言,从内联模式切换到环境可能看起来很尴尬,并且您可能需要重新措辞您的段落。- ...
如何使用脚本
将上述代码复制粘贴到与.sh
您的 .tex 文档位于同一目录中的文件中。从终端运行chmod +x <name>.sh
以修改文件的执行权限。最后,假设您的 .tex 文件名为 foo.tex,使用 在您的终端中调用它./<name>.sh foo <name_of_the_macro>
。
如果你有任何改进的建议,请不要犹豫(特别是如果它们涉及 b 代码,因为我是一个新手如果您发现有这种语言,我会很乐意更新它!