$\LaTeX$中的那些坑

尽管我使用$\LaTeX$已经很多年了,也自信能解决遇到的大多数问题,就算解决不了也能在网上找到解决办法,但总有那么一些小错误,让我花费大量时间去找解决方法,找到了还要看半天才能看懂其中原理,甚至看不懂的。在此对这些深坑进行记录,以免以后再次跌入。

表格自定义列类型

$\LaTeX$自带的表格列类型有以下几种:

% l c r: 居左,居中,居右
% | ||: 列之间的线形,单线,双线
% @{decl.}: 在该列插入文本 decl.
% *{n}{type}: 重复列类型 type 内容 n 次
% p{width}: 将列放入一个 parbox 中,相当于指定列宽为 width,文字垂直方向靠顶部,水平居左

然而我们总会有些其他需求,比如又想指定列宽,又想使该列水平居中等等。当然,有很多宏包可以做到这一点,比如强大的 tabu 。然而再强大的包提供的功能也是有限的,有一些更一般化定义列类型的方法。首先,array 包提供了一些额外的列类型:

% m{width}: 与p{width}类似,相当于指定列宽为width,文字垂直居中,水平居左
% b{width}: 与p{width}类似,相当于指定列宽为width,文字靠底部,水平居左

然并卵,一旦设置了宽度,就不能水平居中。好在 array 包还提供了一些更方便自定义的功能:

>{decl.} % 可用在l,r,c,p,m,b之前,在该列每个条目之前插入decl.
<{decl.} % 可用在l,r,c,p,m,b之后,在该列每个条目之前插入decl.

举例来说,>{$}c<{$} 代表这样一种类型,居中,且为数学环境。所以我可以在输入表格内容时直接输入数学公式还不再需要打上 $ 符号。

很好,这样的话自定义能力大大增加。我想将指定宽度的列居中,就可以这样写列类型

>{\centering}p{width}

其中 p 也可以换成 m 或 b,width 写宽度。赶紧试一下,发现报错,什么 extra alignment tab.....看看代码,也没多打&啊。于是各种搜,原来还要加个 \arraybackslash,不知道为什么,先加上试试,于是写成

>{\centering\arraybackslash}p{width}

再试,真的行了。

不过这列类型写起来太长,多写几列还不得看花眼,好在 array 包还提供了个定义列类型的命令:

\newcolumntype{P}[1]{>{\centering\arraybackslash}p{#1}}

这就定义了新的列类型 P{width},可以指定列宽,并水平居中。

完整代码

\documentclass{standalone}
\usepackage{array}
\newcolumntype{P}[1]{>{\centering\arraybackslash}p{#1}}
\begin{document}
\begin{tabular}{|P{4cm}|P{.5\textwidth}|}
	\hline
	test & testtesttest \\
	\hline
	testtest & test \\
	\hline
\end{tabular}
\end{document}

到这里完了吗?完了,但不爽,因为不知道为啥要加个 \arraybackslash,于是又各种搜,找到的解释是这样的:关键在于每行结束的双反斜线 \\,虽然在各种意义上它都是换行,但在编译过程中却并不相同,它们其实分别是:

场景 定义
在普通文本中 \@normalcr
在居中的文本中 \@centercr
在表格环境中 \@tabularcr
tabbing 中 \@tabcr
array 中 \@arraycr
tabular 中 \@tabularcr
eqnarray 中 \@eqncr

当然可能还有更多,不过目前这样就已经清楚了,因为在列类型定义时使用了 \centering,所以行尾的 \\ 变成了 \@centercr,而不是需要的 \@tabularcr。于是用 \arraybackslash 命令让它变成正确的换行。

\\\newline 一样吗?

知道了符号和命令都有其定义的话,其实也好理解了,\\ 的定义刚才已经说了,在不同环境下不同,而 \newline 的定义无论在什么环境下都是 \@normalcr,这也说明了 \newline 仅在普通文本中与 \\ 相同,在其他地方不同甚至失效。另外 \\ 还有 \\*[<len>] 的用法,其中 * 是表示不另起一页,len 是指定行后的垂直距离。

在 frame 环境中使用#号报错

通常在beamer中很少写#号,所以这个坑也很少见。我是在写前面定义列类型时,把

\newcolumntype{P}[1]{>{\centering\arraybackslash}p{#1}}

写在了frame环境里,于是报错

Illegal parameter number in definition of \iterate. \end{frame}

怎么看也看不明白哪里有问题,后来把定义列类型的语句放 preamble 就好了。带这这个疑问又是各种搜,找到的解答是这样的。 frame 环境在编译时会把其中的内容多次传递给某个宏,在这个过程中,#号被作为特殊符号对待了,并没有起到指定参数序号的作用。如果要在 frame 环境中用#号,则有两种方法,一是把#写成####,可能前3个抵消了 frame 环境的处理;另外一种就是加上下面提到的 fragile 参数。当然,最好的解决办法还是不要在frame环境中用#号。

frame 的 fragile 参数

在 beamer 的 frame 中使用 minted、 lstlisting 或者基本的 verbatim 这些「抄录」环境时,统统都需要给 frame 加上 fragile 参数,形如:

\begin{frame}[fragile]
% verbatim-like environment.
\end{frame}

具体原理可见这里

另外,运用 fragile 参数也有一些缺陷,比如带 fragile 参数的 frame 在编译过程实际上是写入了一个 .vrb 文件,以待之后调用,这就导致编译较慢。除此之外,fragile 参数似乎可能好像和 allowframebreaks 参数有冲突?

评论

  1. Ryan
    6月前
    2020-5-22 17:27:36

    博主,latex失效了

    • jhan 博主
      6月前
      2020-5-24 13:52:11

      更新wordpress时禁用了mathjax,已启用

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇