防止内联数学换行,但允许灵活间距

防止内联数学换行,但允许灵活间距

我怎样才能轻松地告诉 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 符号列表)。

相关内容