我怎样才能轻松地告诉 Latex防止行内公式部分内出现换行,但不影响字间间距?
在 Latex 中编写类似的东西$ab(c+d)$
是不好的:Latex 可能会在后面添加换行符+
。但我会不是想要禁用换行符+
全球;在 中换行是完全没问题的$abc+def$
。因此我遵循了此主题: 简单地添加额外的括号。
原则上,这很棒。我可以编写诸如${ab(c+d)}$
和之类的内容$abc+{de(f+g)}$
来控制内联方程式的哪些部分是“原子的”,即 Latex 不得在其中添加换行符。
不幸的是,似乎有一个不必要的副作用:乳胶排版${a+b}$
和$a+b$
完全正式的文本中间,如果我写的话$a+b$
,乳胶似乎添加了。“灵活”空间周围+
:就像常规的单词间空格一样,Latex 可以稍微调整间距,以便完全对齐的段落看起来不错。但是,如果我写${a+b}$
,Latex 似乎会在 周围使用固定宽度的空格+
。
这个答案提到一种可能的方法是编写类似 的内容$a+\nobreak b$
,但这很繁琐且容易出错,即使使用某些宏也是如此。我想将内联方程的某个部分“标记”为“nobreak-zone”。我怎样才能用最少的额外代码做到这一点?
理想情况下,我想写一些类似的东西$abc + \x{de(f+g)}$
,在哪里\x
可以防止线路断裂但允许灵活的间距。
一个例子:
\documentclass[a4paper]{article}
\begin{document}
Foobar $aaaa+bbbb+cccc+dddd+eeee+ffff+gggg$ foobar foobar foobar foobar
foobar $aaaa+bbbb+cccc+dddd+eeee+ffff+gggg$ foobar foobar foobar.
Foobar ${aaaa+bbbb+cccc+dddd+eeee+ffff+gggg}$ foobar foobar foobar foobar
foobar ${aaaa+bbbb+cccc+dddd+eeee+ffff+gggg}$ foobar foobar foobar.
\end{document}
生成:
答案1
我会说
\newcommand{\x}[1]{%
{}$% get out of math
\kern-2\mathsurround % in case it's non zero
$% reenter math
\binoppenalty10000 \relpenalty10000 #1% typeset the subformula
{}$% get out of math
\kern-2\mathsurround % in case it's non zero
$% reenter math for the rest of the formula
}
TeX 仅在二元运算符或关系符号之后中断公式,这种中断的可取性由上述两个参数来衡量。但是,惩罚使用的值是公式末尾有效的值,因此简单地将其括起来#1
并\begingroup...\endgroup
设置值不会产生任何作用。
当然,这只能在公式的合适位置使用,例如,$a+\x{b+c}$
在第一个公式之后将具有正确的间距+
(由于空的子形式);
我的看法仍然是,必须使用适当放置的\nobreak
命令来解决糟糕的休息。
一些例子:
\documentclass[a4paper,draft]{book}
\newcommand{\x}[1]{{}$\kern-2\mathsurround${}
\binoppenalty10000 \relpenalty10000 #1{}$\kern-2\mathsurround${}}
\begin{document}
\parbox{5cm}{
A formula \(a+\x{c+d}\)\break showing that spaces are right
A new formula \(a+\x{c+d}\) showing that spaces are right
A brand new formula x \(a+\x{c+d}\) showing that spaces are right
A brand new formula xx \(a+\x{c+d}\) showing that spaces are right
A brand new formula xxx \(a+\x{c+d}\) showing that spaces are right
A brand new formula xxxx \(a+\x{c+d}\) showing that spaces are right
Another brand new formula \(a+\x{c+d}\) showing that spaces are right
Right: $\sin(\x{a+b})$
Wrong: $\sin\x{(a+b)}$
\mathsurround=30pt
A formula xxxxxxx \(a+\x{c+d}\) showing mathsurround
A formula xxxxxxx \(a+c+d\) showing mathsurround
}
\end{document}
关于用法的补充
宏\x
(可能具有更具描述性的名称)应在特定位置使用。其内容必须
(1)以普通符号开头或前面有一个普通符号;
(2)以普通符号结尾或后面有一个普通符号。
它不支持样式的声明\displaystyle
,\textstyle
或者\scriptstyle
;\scriptscriptstyle
\displaystyle
它不支持\left
或\right
:不允许这样的东西
$...\left(\x{a+b}\right)...$
但这不是问题,因为没有公式可以在和之间的关系或运算符号处分裂\left
,\right
并且这些符号周围的空间永远不会参与拉伸或收缩。
答案2
基于与Philippe相同的想法(替换+
)+\nobreak
,可以使用更强大的解决方案"8000
。
+
对于此应用程序,我们可以定义要扩展为的活动字符+\nobreak
...但这会失败:结果+
,现在具有数学代码,"8000
被视为活动,并将扩展,等等。\let
像控制序列那样使用是行不通的:它应该只是构建一个隐式字符,在执行时其行为与其他相同+
,即扩展为+\nobreak
,等等。正确的解决方案是使用\mathchar<integer>
正确的整数:\the\mathcode`\+
。\edef
需要一个来获取\mathcode`\+
分配的值"8000
。
\x
如果用一组定义,则解决方案将更简单
\newcommand{\x}[1]{\begingroup\defineplusminus #1\endgroup}
但我发现最好不要使用组。原则上,它稍微更通用一些,因为可以想象\defineplusminus a + \mathrm{b + c \undefineplusminus - d}
……但是,没有组意味着活动的+
和-
在此过程中被重新定义。所以也许这不是一个好主意。然后只需删除所有出现的,并按上述方式\undefineplusminus
定义。\x
\documentclass{article}
\makeatletter
\begingroup
\catcode`\+ = \active
\catcode`\- = \active
\@firstofone{\endgroup
\newcommand{\defineplusminus}
{%
\edef\undefineplusminus{%
\mathcode`\noexpand\+=\the\mathcode`\+
\mathcode`\noexpand\-=\the\mathcode`\-
}%
\edef+{\mathchar\the\mathcode`\+\nobreak}%
\mathcode`\+="8000\relax
\edef-{\mathchar\the\mathcode`\-\nobreak}%
\mathcode`\-="8000\relax
}
}
\newcommand{\undefineplusminus}{}% just declare it.
\newcommand{\x}[1]{%
\defineplusminus
#1%
\undefineplusminus
}
%% Test document taken from Philippe Goutet
\begin{document}
\parindent=0cm
\hsize=5cm
A formula \(a+\x{c+d}\)\break showing that spaces are right
A new formula \(a+\x{c+d}\) showing that spaces are right
A brand new formula xxxx \(a+\x{c+d}\) showing that spaces are right
Right: $\sin\x{(a+b)}$
A formula \(a+\x{c-d}\)\break showing that spaces are right
A new formula \(a+\x{c-d}\) showing that spaces are right
A brand new formula xxxx \(a+\x{c-d}\) showing that spaces are right
Right: $\sin\x{(a-b)}$
\end{document}
答案3
这与我之前的方法完全不同,因此需要单独回答。只需遍历参数,并将其放置在\nobreak
需要的位置。使用 检测括号组\@ifnextchar\bgroup
,并将其不加修改地复制到结果中(在 中\nobr@toks
),因为它们通常不需要\nobreak
插入其中。对于单个标记,\nobr@next@N@do
检查它们是否在给定列表中(此处+-=\cdot\times
,但可以扩展)。如果在,则\nobreak
添加。否则,只需将标记放在结果中。
这种方法允许\displaystyle
和朋友,并且可以\x
在任何地方使用(即不一定用作原子\def\PP{c-d}
)\x{\PP}
。
我仅更改了下面EGREG的第一个示例,以显示其他功能。
\documentclass[a4paper,draft]{book}
\makeatletter
\newtoks\nobr@toks
\long\def\nobr@put@right#1{\nobr@toks\expandafter{\the\nobr@toks#1}}
\long\def\nobr@next
{\@ifnextchar\bgroup \nobr@next@bgroup \nobr@next@N }
\long\def\nobr@next@bgroup#1{\nobr@put@right{{#1}}\nobr@next}
\long\def\nobr@next@N#1%
{%
\ifx\nobr@end #1%
\expandafter\@gobbletwo
\fi
\nobr@next@N@do #1%
}%
\long\def\nobr@next@N@do#1%
{%
\nobr@put@right{#1}%
\in@{#1}{+-=\cdot\times}% extensible list.
\ifin@\nobr@put@right{\nobreak}\fi
\nobr@next
}
\def\nobr@end\nobr@end{\nobr@end}
\newcommand{\x}[1]{%
\nobr@toks={}%
\nobr@next #1\nobr@end
\ifnobr@show\showthe\nobr@toks\fi
\the\nobr@toks
}
\newif\ifnobr@show
% \nobr@showtrue to show the result each time.
\makeatother
\begin{document}
\parbox{5cm}{
A formula \(\displaystyle a \x{ + c^{2+3} + \sum d} \)\break showing that spaces are right
A new formula \(a+\x{c+d}\) showing that spaces are right
A brand new formula x \(a+\x{c+d}\) showing that spaces are right
A brand new formula xx \(a+\x{c+d}\) showing that spaces are right
A brand new formula xxx \(a+\x{c+d}\) showing that spaces are right
A brand new formula xxxx \(a+\x{c+d}\) showing that spaces are right
Another brand new formula \(a+\x{c+d}\) showing that spaces are right
Right: $\sin(\x{a+b})$
Wrong: $\sin\x{(a+b)}$
\mathsurround=30pt
A formula xxxxxxx \(a+\x{c+d}\) showing mathsurround
A formula xxxxxxx \(a+c+d\) showing mathsurround
}
\end{document}
答案4
一种浪费的解决方案(它会多次读取公式)但不会破坏间距或样式声明,就是将 替换为+
、+\nobreak
替换-
为-\nobreak
等。这可以通过字符串包裹 :
\documentclass{article}
\usepackage{xstring}
\newcommand{\x}[1]{%
\begingroup
\expandarg
\def\result{#1}
\StrSubstitute{\result}{+}{+\nobreak }[\result]%
\StrSubstitute{\result}{-}{-\nobreak }[\result]%
\result
\endgroup
}
\begin{document}
\parindent=0cm
\hsize=5cm
A formula \(a+\x{c+d}\)\break showing that spaces are right
A new formula \(a+\x{c+d}\) showing that spaces are right
A brand new formula xxxx \(a+\x{c+d}\) showing that spaces are right
Right: $\sin\x{(a+b)}$
A formula \(a+\x{c-d}\)\break showing that spaces are right
A new formula \(a+\x{c-d}\) showing that spaces are right
A brand new formula xxxx \(a+\x{c-d}\) showing that spaces are right
Right: $\sin\x{(a-b)}$
\end{document}
该方法的缺点是,更改了宏代码中指定的符号\x
(我只处理了+
上-
一个示例,但可以轻松地扩展代码)。全面的 LaTeX 符号列表)。