【公式】进行一个 LaTeX 的滥用

· · 个人记录

\def\w{28em} \def\h{7em} \def\t{.1px} \begin{gathered} \textcolor{000000}{\rule{\w}{\h}} \cr[-8em] \textcolor{gold}{\rule{\w}{\t}} \cr[-.3em] \textcolor{gold}{\large\texttt{Caution!!! \qquad Caution!!! \qquad Caution!!!}} \cr[-1em] \textcolor{gold}{\rule{\w}{\t}} \cr[.3em] \textcolor{gold}{\Large\text{\LaTeX\ 滥 用 警 告!}} \cr [-1.1em] \textcolor{gold}{ \Huge \text{☢}\kern{8em}\Huge \text{☢}} \cr[-1em] \textcolor{gold}{\rule{\w}{\t}} \cr[-.3em] \textcolor{gold}{\large\texttt{Caution!!! \qquad Caution!!! \qquad Caution!!!}} \cr[-1em] \textcolor{gold}{\rule{\w}{\t}} \cr[.3em] \end{gathered} ## F&Q - $\mathsf{Q_1}$:这篇文章是写给哪些人看的? $\mathsf{A_1}$:请注意,这篇文章并不是给一般通过谷民看的。对于公式的一般写法/用途,我相信在你谷已经有了充足的[参考资料](https://www.luogu.com.cn/discuss/show/210950),因此这里并不会赘述很多公式的用法。此处已经默认读者掌握了大多数 $\LaTeX$ 的基本操作,也就是说,这篇文章的目标受众应该是~~闲的没事~~喜欢拿 $\LaTeX$ 乱搞的人(比如我)看的。 - $\mathsf{Q_2}$:这篇文章的内容? $\mathsf{A_2}$:针对近来有一车人问形如[这场比赛](https://www.luogu.com.cn/contest/35209)的 $\LaTeX$ 头图是怎么做出来的,同时也是作为原作者不大希望被人莫名其妙地抄袭,所以写了这篇文章,主要就是讲讲一些乱七八糟的东西。 - $\mathsf{Q_3}$:为什么有些代码在讨论区/博客编辑界面显示不出来? $\mathsf{A_3}$:$\KaTeX$ 版本不同步所致。这两个地方 $\KaTeX$ 版本比较落后,一些公式是无法正确翻译成 $\texttt{html}$ 的,望周知。 ## 绘制空白 进行一个单位转换表的放。 $$ \def\arraystretch{1.5} \begin{array}{c|c|c|c}\hline\hline \textbf{KaTeX Unit} & \textbf{Value} & \textbf{KaTeX Unit} &\textbf{Value}\cr\hline \text{em} & \text{CSS em} & \text{bp} & 1/72 \text{ inch} \times F \times G\cr\hline \text{ex} & \text{CSS ex} & \text{pc} & 12 \text{ KaTeX pt}\cr\hline \text{mu} & 18^{-1} \text{CSS em} & \text{dd} & 1238/1157 \text{ KaTeX pt}\cr\hline \text{pt} & 72.27^{-1} \text{ inch} \times F \times G & \text{cc} & 14856/1157 \text{ KaTeX pt}\cr\hline \text{mm} & 1 \text{ mm} \times F \times G & \text{nd} &685/642 \text{ KaTeX pt}\cr\hline \text{cm} & 1 \text{ cm} \times F \times G & \text{nc} &1370/107 \text{ KaTeX pt}\cr\hline \text{in} & 1 \text{ inch} \times F \times G & \text{sp} &1/65536 \text{ KaTeX pt}\cr\hline\hline \end{array}$$ - $F$ 的值为周围 $\text{HTML}$ 文字的字体大小除以 $10\text{pt}$。 - $G$ 的值默认为 $1.21$,可以在配置文件中更改。当然,作为用户就别想着改配置文件了。 --- - 使用 `\kern{distance}` 可以绘制一个长度为 $\text{distance}$ 的空白。$\text{distance}$ 的单位可以是上述转换表中的任意一个。特别地,$\text{distance}$ 可以为负数,这为排版提供了便利。例如,$\kern{1em}$(`\kern{1em}`) - 使用 `\phantom{something}` 相当于生成了这样一个空白,它的长度和宽度与 $\text{something}$ 相同。例如,$\phantom{\text{qwq}}$(`\phantom{\text{qwq}}`)。同时 $\KaTeX$ 还提供了 `\hphantom` 和 `\vphantom` 两个版本,分别决定生成的空白的长度与宽度。 - 另外还可以使用 $\text{CSS}$ 提供的透明色($\text{transparent}$)实现类似 `\phantom` 的效果。例如 $\textcolor{transparent}{\text{qaq}}$(`\textcolor{transparent}{\text{qaq}}`)。 ## 常用绘图公式 这里默认读者已经掌握了大多数基础公式,所以不会赘述太多内容。 - $\KaTeX$ 提供了 `\rule{length}{width}` 来绘制一个长度恰好为 $\text{length}$,宽度恰好为 $\text{width}$ 的矩形。例如,$\rule{2em}{10pt}$(`\rule{2em}{10pt}`)就是一个长度为 $2\text{em}$,宽度为 $10\text{pt}$ 的矩形。配合上 `\color` 一类的公式可以改变颜色。 不过,`\rule` 存在缺点。在某些浏览器(比如 $\text{Chrome}$)里,绘制出来的矩形可能会莫名其妙地丢掉一个像素。此外,如果长度或者宽度过小,也可能出现实际绘制出来的矩形失真的状况。 - 接着谈谈水平线条。`\overline` 和 `\underline` 可以用来绘制水平线段,例如 $\underline{\kern{3em}}$(`\underline{\kern{3em}}`),不过由于线段并不在画面中央,所以可能要一些小技巧进行调整。此外,虽然我写了个 `\kern{3em}`,但实际绘制的线段会略长于它,因此需要微调。 - 然后说说竖直线条。使用 `\left` 和 `\right` 放置在括号前可以让 $\KaTeX$ 自动适配括号的大小。例如 $\left\lfloor\dfrac{114}{514}\right\rfloor$(`\left\lfloor\dfrac{114}{514}\rfloor\right)`),可以利用这一点,配合上刚刚的 `\rule`,拉长绝对值符号的长度来达到竖直线段的效果。例如,$\left|\vphantom{\rule{1em}{1.5em}}\right.$(`\left|\vphantom{\rule{1em}{1.5em}}\right.`)。同样,实际长度可能比你需要的长,并且如果想要的线段过短也会产生问题。 - 最后提下斜线。如果你有认真看官方文档,你会发现 `\cancel` 和 `\bcancel` 这两个公式。那么在里面放个透明的 `\rule` 不就能做到斜线效果了?例如,$\cancel{\phantom{\rule{3em}{1em}}}$(`\cancel{\phantom{\rule{3em}{1em}}}`) 和 $\bcancel{\phantom{\rule{2em}{.8em}}}$(`\bcancel{\phantom{\rule{2em}{.8em}}}`)。当然这也不可避免需要进行微调。 ## 简化操作流程 如果你接触过小波早期作品,你就会发现其中有大量的冗余代码(将相同的代码片段写很多遍导致源码长度巨大长)。这都是由于早期小波啥都不会,于是堆积了大量屎山代码。这样带来的后果就是,代码长度长、调试困难、编辑困难。例如,你现在需要实现这样一个简单的代码,可以生成一堆彩色的条子: $$ \begin{aligned} \textsf{\textcolor{fe4c61}{\textbf{红}}:} & \fcolorbox{black}{fe4c61}{$\kern{-3pt}\phantom{\rule{2em}{.5em}\kern{-3pt}}$} \cr \textsf{\textcolor{f39c11}{\textbf{橙}}:} & \fcolorbox{black}{f39c11}{$\kern{-3pt}\phantom{\rule{3em}{.5em}\kern{-3pt}}$} \cr \textsf{\textcolor{ffc116}{\textbf{黄}}:} & \fcolorbox{black}{ffc116}{$\kern{-3pt}\phantom{\rule{5em}{.5em}\kern{-3pt}}$} \cr \textsf{\textcolor{52c41a}{\textbf{绿}}:} & \fcolorbox{black}{52c41a}{$\kern{-3pt}\phantom{\rule{10em}{.5em}\kern{-3pt}}$} \cr \textsf{\textcolor{3498db}{\textbf{蓝}}:} & \fcolorbox{black}{3498db}{$\kern{-3pt}\phantom{\rule{8em}{.5em}\kern{-3pt}}$} \cr \textsf{\textcolor{9d3dcf}{\textbf{紫}}:} & \fcolorbox{black}{9d3dcf}{$\kern{-3pt}\phantom{\rule{4em}{.5em}\kern{-3pt}}$} \cr \textsf{\textcolor{0e1d69}{\textbf{黑}}:} & \fcolorbox{black}{0e1d69}{$\kern{-3pt}\phantom{\rule{1em}{.5em}\kern{-3pt}}$} \cr \end{aligned} $$ 一种可能的实现方法如下: ```latex \begin{aligned} \textsf{\textcolor{fe4c61}{\textbf{红}}:} & \fcolorbox{black}{fe4c61}{$\kern{-3pt}\phantom{\rule{2em}{.5em}\kern{-3pt}}$} \cr \textsf{\textcolor{f39c11}{\textbf{橙}}:} & \fcolorbox{black}{f39c11}{$\kern{-3pt}\phantom{\rule{3em}{.5em}\kern{-3pt}}$} \cr \textsf{\textcolor{ffc116}{\textbf{黄}}:} & \fcolorbox{black}{ffc116}{$\kern{-3pt}\phantom{\rule{5em}{.5em}\kern{-3pt}}$} \cr \textsf{\textcolor{52c41a}{\textbf{绿}}:} & \fcolorbox{black}{52c41a}{$\kern{-3pt}\phantom{\rule{10em}{.5em}\kern{-3pt}}$} \cr \textsf{\textcolor{3498db}{\textbf{蓝}}:} & \fcolorbox{black}{3498db}{$\kern{-3pt}\phantom{\rule{8em}{.5em}\kern{-3pt}}$} \cr \textsf{\textcolor{9d3dcf}{\textbf{紫}}:} & \fcolorbox{black}{9d3dcf}{$\kern{-3pt}\phantom{\rule{4em}{.5em}\kern{-3pt}}$} \cr \textsf{\textcolor{0e1d69}{\textbf{黑}}:} & \fcolorbox{black}{0e1d69}{$\kern{-3pt}\phantom{\rule{1em}{.5em}\kern{-3pt}}$} \cr \end{aligned} ``` 可以发现,其中出现了大量的重复片段。这里就可以使用**宏定义**的方式简化操作流程。这里介绍一下 $\KaTeX$ 提供的三种宏定义: - `\newcommand{\name}[argc]{definition}`:定义一个新的公式,名字叫做 $\text{name}$,接受的参数个数为 $\text{argc}$(可以为 $0$),定义为 $\text{definition}$。**不能和已有的公式重名**。 - `\newcommand{\name}[argc]{definition}`:**重新**定义一个公式,名字叫做 $\text{name}$,接受的参数个数为 $\text{argc}$(可以为 $0$),定义为 $\text{definition}$。**在定义之前必须已有名字叫** $\textbf{name}$ **的公式**。 - `\newcommand{\name}[argc]{definition}`:提供一个公式,名字叫做 $\text{name}$,接受的参数个数为 $\text{argc}$(可以为 $0$),定义为 $\text{definition}$。如果先前已有名叫 $\text{name}$ 的公式,则重新定义;否则新定义一个名字叫 $\text{name}$ 的公式。 特别地,由于技术原因 $\text{argc}$ 的值只能为 $0\sim 9$。也就是说,不能传入大于 $9$ 个参数。在定义里,参数依次使用 `#1`、`#2`、`#3` 等替代。 那么上述代码可以进行简化: ```latex \newcommand{\block}[3]{\textsf{\textcolor{#1}{\textbf{#2}}:} & \fcolorbox{black}{#1}{$\kern{-3pt}\phantom{\rule{#3}{.5em}\kern{-3pt}}$}} \begin{aligned} \block{fe4c61}{红}{2em}\cr \block{f39c11}{橙}{3em}\cr \block{ffc116}{黄}{5em}\cr \block{52c41a}{绿}{10em}\cr \block{3498db}{蓝}{8em}\cr \block{9d3dcf}{紫}{4em}\cr \block{0e1d69}{黑}{1em}\cr \end{aligned} ``` 这样就能清爽很多。 ## 正确使用字体 数学模式: - $\mathrlap{\mathbb{Ab0}} \kern{2em}$ `\mathbb{Ab0}`$\kern{11pt}$:双线字体。仅对大写字母有效。 - $\mathrlap{\mathcal{Ab0}} \kern{2em}$ `\mathcal{Ab0}`$\kern{6.5pt}$:一种花体。仅对大写字母和数字有效。 - $\mathrlap{\mathscr{Ab0}} \kern{2em}$ `\mathscr{Ab0}`$\kern{6.5pt}$:一种花体。仅对大写字母有效。 - $\mathrlap{\mathfrak{Ab0}} \kern{2em}$ `\mathfrac{Ab0}` :欧拉字体。对于大小写字母和数字都有效。 - $\mathrlap{\mathrm{Ab0}} \kern{2em}$ `\mathrm{Ab0}`$\kern{11pt}$:有衬线字体。对于大小写字母和数字都有效。 - $\mathrlap{\mathtt{Ab0}} \kern{2em}$ `\mathtt{Ab0}`$\kern{11pt}$:打字机字体。对于大小写字母和数字都有效。 - $\mathrlap{\mathsf{Ab0}} \kern{2em}$ `\mathsf{Ab0}`$\kern{11pt}$:无衬线字体。对于大小写字母和数字都有效。 - $\mathrlap{\mathit{Ab0}} \kern{2em}$ `\mathit{Ab0}`$\kern{11pt}$:意大利斜体字体。对于大小写字母和数字都有效。 文本模式: $$ \def\arraystretch{1.5} \begin{array}{c|c|c|c}\hline\hline & \textbf{无衬线} & \textbf{有衬线} & \textbf{打字机} \cr\hline \textbf{无} & \textsf{Ab0} & \textrm{Ab0} & \texttt{Ab0}\cr\hline \textbf{斜体}&\textsf{\textit{Ab0}} & \textrm{\textit{Ab0}} & \texttt{\textit{Ab0}}\cr\hline \textbf{粗体}&\textsf{\textbf{Ab0}} & \textrm{\textbf{Ab0}} & -\cr\hline \hline \end{array} $$ 文本模式下的字体是这样渲染的:首先是字体家族,在 $\LaTeX$ 里有这样三种,衬线字体($\text{Roman}$)、无衬线字体($\text{Sans-serif}$)、打字机字体($\text{Typewriter}$),对应文字模式下的公式为 `\textrm`、`\textsf`、`\texttt`;接着有两个公式可以调整字形是否加粗,为 `\textbf` 和 `\textmd`;最后有两个公式可以调整字形是否倾斜,为 `\textit` 和 `\textup`。文本模式下它们是可以嵌套的。例如,$\textsf{\textbf{H}}$(`\textsf{\textbf{H}}`)。 请正确处理好数学模式和文本模式的关系。当使用美元符号包裹公式时就进入了数学模式;数学模式下使用 `\text{}` 系列的公式,花括号内的内容即为文本模式。特别地,如果使用双美元包裹公式(`$$...$$`),那么可以在 `\text{}` 的花括号内使用美元符号再返回数学模式。 ## 文本排版 要善用各种环境。常用的是 $\text{aligned},\text{gathered},\text{array}$。 因为默认读者都知道了,所以不再赘述。 ## 文本修饰 - 正确调整字体大小。 - 正确使用字体。 因为默认读者都知道了,所以不再赘述。 ## 最后 - 多翻翻[官方文档](https://katex.org/docs/supported.html#math-operators),这对你有好处。 - 多翻翻[官方源码](https://github.com/KaTeX/KaTeX),这对你有好处。