悠闲数学娱乐论坛(第2版)'s Archiver

kuing 发表于 2016-2-21 20:37

关于《撸题集》的 LaTeX(2022-3-19 重新编辑)

[s]由于这里的 MathJax 会影响代码,所以我将代码发了在:kuing.is-programmer.com/posts/205617.html[/s]
那边博客编辑时有问题弄坏了,而这边早已解决“MathJax 会影响代码”的问题,所以还是发回来这里,顺便作一些改进。

目录(点击跳转)
$\href{#sec0}{\text{零、文档类与编译方式}}$
$\href{#sec1}{\text{一、加载宏包}}$
$\href{#sec2}{\text{二、一些设置}}$
$\href{#sec3}{\text{三、定理类环境、题目环境的定制}}$
$\href{#sec4}{\text{四、为懒人而设(其实也不完全是)的各种命令,请按需而取之,慎用}}$
$\href{#sec5}{\text{五、带圈数字和脚注}}$
$\href{#sec6}{\text{六、用 tikz 画 LaTeX 里没有的符号、用 mdframed 宏包定制引用环境}}$
$\href{#sec7}{\text{七、选择题、填空题}}$
$\href{#sec8}{\text{八、图片并排放置}}$
$\href{#sec9}{\text{九、引号替换——输入 “  ” 输出 「  」}}$
$\href{#secA}{\text{十、begin{document} 之后}}$

时常有网友向我要《撸题集》的 LaTeX 模板,由于我觉得:
[list][*]我的 LaTeX 水平还不算太好,怕一些烂代码误人子弟;
[*]有很多自定义命令比较个人化,只适用于我的书上,并不适合他人使用;
[*]如果直接给出一个能编译的模板,恐怕很多人就不会再用心去看里头的代码了。
[/list]所以我决定不将完整代码给出,仅抽取一些大众适用的,应该没太大问题的代码贴出来,仅供大家参考。

我希望的是,我提供各种各样的零件,你们自己动手组装,喜欢哪些就装哪些。
同时还可以把你平时用惯的代码也装进去,最终制成你自己了解的模板。
当然,这需要你对 LaTeX 有一定基础,所以如果还没入门的,建议先看点基本教程再说。

我会尽量给出代码的说明,各位请先仔细阅读后再按需取用,[b]切勿随便抄了就算[/b],否则极容易出现问题。

[mao]sec0[/mao]
[size=5][b]零、文档类与编译方式[/b][/size]

建议使用 ctex 系列的文档类——小论文之类用 ctexart,写书用 ctexbook,这样就基本不用自己去设置中文。
(唯一缺点是总有字体警告,虽然无关痛痒,但对强逼症者就……)
如果不用 ctex 的文档类,就需要用 xeCJK 宏包设置字体,并自行修改标题等各种格式为中文风格,比较麻烦,这里不作介绍。
(其实当年我就是这样做的,因为我追求“三0”——Errors: 0   Warnings: 0   Bad Boxes: 0)

编译方式:XeLaTeX[code]% !Mode:: "TeX:UTF-8"
\documentclass[UTF8,fontset=windows]{ctexbook}
\ctexset{
section/format+=\raggedright,
}
[/code]第一行是编码标识,避免 WinEdt 打开乱码,有些编辑器的编码标识写法可能不同,有见过用[inlinecode]%# -*- coding:utf-8 -*-[/inlinecode]的。
选项里[inlinecode]fontset=windows[/inlinecode]表示使用 windows 系统里的中文字体,之后的是让节标题左对齐。
更多选项及设置请阅读 ctex 宏集手册,建议读下。

[mao]sec1[/mao]
[size=5][b]一、加载宏包[/b][/size][code]\usepackage{amsmath,amssymb}
%数学必备宏包

\usepackage{mathtools}
%amsmath 的拓展包

\usepackage{amsthm}
%定理和证明环境,如果想要更自由的定制,可改用 ntheorem 包

\usepackage{bm}
%数学粗体,用于向量等,命令是\bm

\usepackage{mathrsfs}
%数学花体,命令是\mathscr

\usepackage{esvect}
%好看的向量箭头符号,命令是\vv

\usepackage{centernot}
%用于较长符号(如\iff)的否定形式,命令是\centernot(后文自定义命令中有用到)

\usepackage{tikz}
%画图
\usetikzlibrary{calc,angles,quotes}%加载一些 library(请按需添加)
\tikzset{every picture/.style={line join=round,>=latex,}}%tikz 全局设置

\usepackage[framemethod=tikz]{mdframed}
%制作各种花式框框,这里我用来定制引用环境(见后文)

\usepackage{enumitem}
%枚举环境增强包,方便设置条目格式

\usepackage{graphicx}
%插图包

\usepackage{fancyhdr}
%页眉页脚包

\usepackage[perpage]{footmisc}
%脚注包,perpage 选项表示按页编号

\usepackage{caption}
%修改图表标题格式

\usepackage[a4paper,top=1in,bottom=1in,left=0.8in,right=0.8in,headheight=13pt]{geometry}
%页面设置,请根据你的喜好修改之

\usepackage{hyperref}
%PDF 链接等设置
\hypersetup{%
pdfstartview=FitH,      %PDF 打开时=页面适合窗口
CJKbookmarks=true,      %中文书签支持
bookmarksnumbered=true, %书签中章节编号
bookmarksopen=true,     %书签目录展开
colorlinks,             %彩色链接
%下面几个请根据你的喜好修改之,不设也可以,颜色自有默认值
%linkcolor=颜色名,      %内部链接颜色,我书上设的是 violet
%urlcolor=颜色名,       %url 链接颜色,我书上设的是 blue
%citecolor=颜色名,      %参考文献链接颜色,我书上设的是 teal
%pdftitle={XXX},         %文件标题
%pdfauthor={XXX},        %文件作者
%pdfsubject={XXX},       %文件主题
%pdfkeywords={XXX}       %文件关键字
}[/code]要了解某宏包的用法,只需在命令行运行:[inlinecode]texdoc 宏包名称[/inlinecode],比如
[inlinecode]texdoc mathtools[/inlinecode]
就可以打开系统自带的 mathtools 宏包的使用手册。

[mao]sec2[/mao]
[size=5][b]二、一些设置[/b][/size][code]%限制两行之间的实际距离至少 3pt
\lineskiplimit=3pt
\lineskip=3pt

%允许页尾多行公式换页
\allowdisplaybreaks

%空白偶数页去除页眉页脚
\makeatletter
\def\cleardoublepage{\clearpage\if@twoside\ifodd\c@page\else
\thispagestyle{empty}\hbox{}\newpage\if@twocolumn\hbox{}\newpage\fi\fi\fi}
\makeatother

%定义弧符号,命令是 \hu
\DeclareSymbolFont{yh}{OMX}{yhex}{m}{n}
\DeclareMathAccent{\hu}{\mathord}{yh}{"F3}

%一些默认没有的数学函数命令需要新建
\DeclareMathOperator\arccot{arccot}
\DeclareMathOperator\arcsec{arcsec}
\DeclareMathOperator\arccsc{arccsc}
\DeclareMathOperator\sech{sech}
\DeclareMathOperator\csch{csch}
\DeclareMathOperator\arcsinh{arcsinh}
\DeclareMathOperator\arccosh{arccosh}
\DeclareMathOperator\arctanh{arctanh}
\DeclareMathOperator\arccoth{arccoth}
\DeclareMathOperator\arcsech{arcsech}
\DeclareMathOperator\arccsch{arccsch}

\newcommand\px{\mathrel{/\mkern-5mu/}}  %斜的平行符号
\newcommand\rmd{\mathop{}\!\mathrm{d}}  %微分直立 d

\newcommand\relph[1][=]{\mathrel{\phantom{#1}}}
%二元关系符“幻影”,用于多行公式右边太长需再换行时要空出的位置(常为=,故以此为默认参数)[/code]最后那个 \relph 的用法示例如下
$\newcommand\relph[1][=]{\mathrel{\phantom{#1}}}$[precode]\begin{align*}
A &= loooooooooooooooooooo \\
& \relph ooooong ~ equation \\
&= \cdots\\
&= \cdots
\end{align*}[/precode]\begin{align*}
A &= loooooooooooooooooooo \\
& \relph ooooong ~ equation \\
&= \cdots\\
&= \cdots
\end{align*}

[mao]sec3[/mao]
[size=5][b]三、定理类环境、题目环境的定制[/b][/size][code]%自定义定理样式
\newtheoremstyle{moren}{}{}{\normalfont}{\parindent}{\bfseries}{.}{ }{}
\theoremstyle{moren}
\newtheorem{thm}{定理}[section]   %定理类环境按节计数
\newcommand\thmautorefname{定理}   %设置用 \autoref 引用时显示的名称
\newtheorem{lem}{引理}[section]
\newcommand\lemautorefname{引理}
%命题、猜想等类似,不再详写
\newtheorem{cor}{推论}[thm]       %推论按定理计数
\newcommand\corautorefname{推论}

%方程、图表按节计数,修改图表 \autoref 引用名称
\numberwithin{equation}{section}
\numberwithin{figure}{section}
\numberwithin{table}{section}
\renewcommand\figureautorefname{图}
\renewcommand\tableautorefname{表}

%题目专用样式
\newtheoremstyle{tmstyle}{}{}{\normalfont}{\parindent}{\bfseries}{}{ }
{\colorbox{gray!25}{\thmname{#1} \thmnumber{#2}\thmnote{(#3)}.}}
\theoremstyle{tmstyle}
\newtheorem{problem}{题目}[section]
\newcommand\problemautorefname{题目}

%修改 proof 证明环境
\makeatletter
\renewcommand\proofname{证明}
\renewenvironment{proof}[1][\proofname]{\par
\pushQED{\qed}%
\normalfont \topsep6\p@\@plus6\p@ \labelsep1em\relax
\trivlist
\item[\hskip\labelsep\indent
\bfseries #1]\ignorespaces
}{%
\popQED\endtrivlist\@endpefalse
}
\makeatother[/code]如需用到 定理' 、定理'' 之类的,请见:
[url]http://kuing.orzweb.net/viewthread.php?tid=356[/url]

书中用于分隔题目的四种循环花色的设计,请见:
[url]http://kuing.orzweb.net/viewthread.php?tid=3814[/url]

[mao]sec4[/mao]
[size=5][b]四、为懒人而设(其实也不完全是)的各种命令,请按需而取之,慎用[/b][/size]

注:有些与悠闲论坛上的自定义命令是一致的,故此有些命令在 [url]http://kuing.orzweb.net/viewthread.php?tid=6[/url] 里也能找到例子。[code]\let\le\leqslant
\let\leq\leqslant
\let\ge\geqslant
\let\geq\geqslant

\let\iff\Longleftrightarrow
\let\implies\Longrightarrow
\let\impliedby\Longleftarrow
\let\riff\implies
\let\liff\impliedby
\newcommand\niff{\centernot\iff}    %否定形式,需要 centernot 宏包
\newcommand\nriff{\centernot\riff}
\newcommand\nliff{\centernot\liff}

\let\mbb\mathbb
\newcommand\inR{\in\mbb R}
\newcommand\inN{\in\mbb N}
\newcommand\inZ{\in\mbb Z}
\newcommand\inC{\in\mbb C}
\newcommand\inQ{\in\mbb Q}

\let\veps\varepsilon
\let\kongji\varnothing  %空集
\let\buji\complement    %补集

\newcommand\du{^\circ}  %角度

%将 \S 重定义为三角形面积所用,需要用原来的 \S 时可以用 \oldS
\let\oldS\S
\renewcommand\S[1]{S_{\triangle #1}}

%批量生成数列命令 \an \bn \Sn 等,在文本模式或数学模式下均可使用
\newcommand\slcmds{a,b,c,d,x,y,z,A,B,C,D,F,S,T}
\newcommand\getslcmd[1]{%
\expandafter\newcommand\csname #1n\endcsname{\ensuremath{\{#1_n\}}}}
\makeatletter
\@for\slcmdtmp:=\slcmds\do{\expandafter\getslcmd\expandafter{\slcmdtmp}}
\makeatother

\newcommand\holder{H\"older}
\newcommand\schur{Sch\"ur}
\newcommand\LHS{\text{LHS}}
\newcommand\RHS{\text{RHS}}

\newcommand\Rtt{\text{Rt}\triangle}
\newcommand\sumcyc{\sum_{\mathrm{cyc}}}
\newcommand\sumsym{\sum_{\mathrm{sym}}}
\newcommand\prodcyc{\prod_{\mathrm{cyc}}}
\newcommand\prodsym{\prod_{\mathrm{sym}}}

\newenvironment{led}{\left\{\begin{aligned}\relax}{\end{aligned}\right.}
%带左大括号的aligned,用于方程组等[/code]最后那个 led 环境虽然也可以用于写分段函数,但写法稍麻烦(包括但不限于多几个 &)。
分段函数建议用 mathtools 宏包提供的 dcases 环境来写。

[mao]sec5[/mao]
[size=5][b]五、带圈数字和脚注[/b][/size]

(这部分重写过,原先需要 tikz,现已不需要)

首先将带圈数字归为 CJK 类:[code]\xeCJKsetcharclass{9312}{9331}{1}% 圈1至圈20
\XeTeXcharclass9450=1% 圈0[/code]这样在源码直接用输入法输入的 ①②③……⑩ 才能正常显示。

然后设置一个命令输入带圈数字(用于脚注或枚举环境等),这里分两种情况(二选一):
(1)简易情况:如果你能确定你不需要输入超过 ⑩ 的带圈数字,则:[code]\newcommand\quan[1]{%
\ifnum#1>0\relax\ifnum#1<11\relax
\symbol{\numexpr9311+#1\relax}%
\else#1\fi\else#1\fi
}[/code]这样,用 \quan{1},...,\quan{10} 就可以输出 ① 至 ⑩;
(2)如果有需要输入“圈0”或“圈11”以上,由于默认的宋体没有这些字符,则需先设置一个有这些字符的字体。
比如,Cambria 字体有“圈0”及“圈11”以上,则:[code]\newCJKfontfamily\Cam{Cambria}
\newcommand\quan[2][Cam]{%
\ifnum#2=0\relax{\CJKfamily{#1}\symbol{9450}}%
\else\ifnum#2>0\relax\ifnum#2<21\relax
{\CJKfamily{#1}\symbol{\numexpr9311+#2\relax}}%
\else#2\fi\else#2\fi\fi
}[/code]这样,用 \quan{0},...,\quan{20} 就可以输出 Cambria 字体的“圈0”至“圈20”。

最后改脚注改为带圈数字:[code]\renewcommand\thefootnote{\protect\quan{\value{footnote}}}[/code]如果不喜欢这套方法,也可以考虑完全用 tikz 来画,就无需考虑字体,见:
[url]http://kuing.orzweb.net/viewthread.php?tid=3125[/url]

[mao]sec6[/mao]
[size=5][b]六、用 tikz 画 LaTeX 里没有的符号、用 mdframed 宏包定制引用环境[/b][/size][code]\newlength\Aheight%用作临时高度
%画平行四边形
\newcommand\pxsbx{\mathord{\text{%
\begin{tikzpicture}[baseline,line width=0.1ex,line join=round]
\settoheight\Aheight{$A$}
\addtolength\Aheight{-.05ex}
\draw (0,.05ex)--(.74em,.05ex)--(.9em,\Aheight)--(.16em,\Aheight) -- cycle;
\end{tikzpicture}}}}
%画平行且等于
\newcommand\pqd{\mathrel{\text{%
\begin{tikzpicture}[baseline,line width=0.1ex,line cap=round]
\draw (0,0) -- (.7em,0)
(0,.3ex) -- (.7em,.3ex)
(.2em,.55ex) -- (.4em,1.8ex)
(.35em,.55ex) -- (.55em,1.8ex);
\end{tikzpicture}}}}

%引用环境
\mdfsetup{skipbelow=3pt plus 3pt minus 3pt}
\newenvironment{squote}[1][引用]{\begin{mdframed}[%
hidealllines=true,
singleextra={
  \draw[gray,line cap=rect] (O|-P) -- +(3cm,0pt);
  \draw[gray,line cap=rect] (O|-P) -- +(0pt,-1cm);
  \draw[gray,line cap=rect] (O-|P) -- +(-3cm,0pt);
  \draw[gray,line cap=rect] (O-|P) -- +(0pt,1cm);
  },
firstextra={
  \draw[gray,line cap=rect] (O|-P) -- +(3cm,0pt);
  \draw[gray,line cap=rect] (O|-P) -- +(0pt,-1cm);
},
secondextra={
  \draw[gray,line cap=rect] (O-|P) -- +(-3cm,0pt);
  \draw[gray,line cap=rect] (O-|P) -- +(0pt,1cm);
}]
#1\par}{\end{mdframed}}[/code][mao]sec7[/mao]
[size=5][b]七、选择题、填空题[/b][/size]
(代码可能比较烂,欢迎批评)
先是选择题右边的括号以及填空题的横线:[code]\newcommand\fkh[1][ ]{\nolinebreak\hfill\mbox{(#1}\nolinebreak )} %选择题括号
\newcommand\tk[1][3]{\nolinebreak\mbox{\underline{\hspace{#1em}}}} %填空题横线,默认线长 3em
[/code]然后是重点内容:选择题选项自动排列。
(这部分代码重写过,原先依赖 calc 包,现已不需要,原先的代码不但长,也没考虑到当选项长到一行写不完时,应当用 itemize 使换行有缩进,因而重写后的代码又依赖 enumitem 宏包)[code]\newlength\onelen
\newlength\twolen
\newcommand\onech[4]{\par
\parbox{\onelen}{A. #1}%
\parbox{\onelen}{B. #2}%
\parbox{\onelen}{C. #3}%
\parbox{\onelen}{D. #4}\par
}
\newcommand\twoch[4]{\par
\parbox{\twolen}{A. #1}%
\parbox{\twolen}{B. #2}\par
\parbox{\twolen}{C. #3}%
\parbox{\twolen}{D. #4}\par
}
\newlength\bhwd
\newcommand\fourch[4]{%
\settowidth\bhwd{A. }\addtolength\bhwd{\parindent}%
\begin{itemize}[nosep,labelsep=0pt,leftmargin=\bhwd]
\item[A. ]#1
\item[B. ]#2
\item[C. ]#3
\item[D. ]#4
\end{itemize}}
%
%自动选择上述方式
\newlength\xxwd
\newcommand\xx[4]{%
\settowidth\xxwd{\vbox{\halign{##\cr #1\cr #2\cr #3\cr #4\crcr}}}%
\addtolength\xxwd{2.5em}%
\setlength\onelen{\dimexpr(\linewidth-\parindent)/4\relax}%
\setlength\twolen{\dimexpr(\linewidth-\parindent)/2\relax}%
\ifdim\xxwd<\onelen\relax
\onech{#1}{#2}{#3}{#4}%
\else\ifdim\xxwd<\twolen\relax
\twoch{#1}{#2}{#3}{#4}%
\else\fourch{#1}{#2}{#3}{#4}%
\fi\fi
}[/code]用法:[inlinecode]\xx{选项一}{选项二}{选项三}{选项四}[/inlinecode],将会自动选择合适的排列方式。
(这里仅限四个选项,如有其他数目的需求或更多变的格式,可考虑使用 tasks 宏包)

[mao]sec8[/mao]
[size=5][b]八、图片并排放置[/b][/size][code]%单图 \onetu{图},“图”里面可以写 \caption 和 \label,下同
\newcommand\onetu[1]{%
\begin{figure}[!ht]
\centering
#1
\end{figure}}

\newcommand\mnpgb[2]{%
\begin{minipage}[b]{\dimexpr#1\relax}
\centering
#2
\end{minipage}}

%两图(可调宽度比)\twotu[x]{图}{图},0<x<1为宽比例,默认0.5即平分
\newcommand\twotu[3][0.5]{%
\begin{figure}[!ht]
\mnpgb{#1\linewidth}{#2}%
\mnpgb{\linewidth-#1\linewidth}{#3}%
\end{figure}}

%三图、四图,\threetu{图}{图}{图},\fourtu{图}{图}{图}{图}
\newcommand\threetu[3]{%
\begin{figure}[!ht]
\mnpgb{\linewidth/3}{#1}%
\mnpgb{\linewidth/3}{#2}%
\mnpgb{\linewidth/3}{#3}%
\end{figure}}
\newcommand\fourtu[4]{%
\begin{figure}[!ht]
\mnpgb{\linewidth/4}{#1}%
\mnpgb{\linewidth/4}{#2}%
\mnpgb{\linewidth/4}{#3}%
\mnpgb{\linewidth/4}{#4}%
\end{figure}}

%一行四项的图形选项专用,\fourtuxx{图}{图}{图}{图}
\newcommand\fourtuxx[4]{%
\mnpgb{(\linewidth-\parindent)/4}{#1\par A}%
\mnpgb{(\linewidth-\parindent)/4}{#2\par B}%
\mnpgb{(\linewidth-\parindent)/4}{#3\par C}%
\mnpgb{(\linewidth-\parindent)/4}{#4\par D}%
}[/code][mao]sec9[/mao]
[size=5][b]九、引号替换——输入 “  ” 输出 「  」[/b][/size][code]\let\oldsyhl=“
\let\oldsyhr=”
\let\olddyhl=‘
\let\olddyhr=’
\catcode`\“=\active %或者=13
\catcode`\”=\active
\catcode`\‘=\active
\catcode`\’=\active
\newcommand{“}{「}
\newcommand{”}{」}
\newcommand{‘}{『}
\newcommand{’}{』}[/code][mao]secA[/mao]
[size=5][b]十、begin{document} 之后[/b][/size]
封面、前言之类的东西就不说了。
至于页眉页脚,ctex 的文档类默认已设置好,如果不喜欢,可以在目录之前自己重设,比如:[code]\pagestyle{fancy}
\fancyhf{}
\fancyhead[RE]{\nouppercase\leftmark} %字母默认会全变大写,加 \nouppercase 使之保持原样
\fancyhead[LO]{\nouppercase\rightmark}
\fancyhead[LE,RO]{撸撸撸}
\fancyfoot[LE,RO]{\thepage}
\fancypagestyle{plain}{
\fancyhf{}
\fancyfoot[LE,RO]{\thepage} %将plain的页码设为与上面一致(新章页为plain)
\renewcommand{\headrulewidth}{0pt}
}[/code]最后就是目录,通常目录页码为罗马数字,所以大概可以这样:[code]\pagenumbering{roman}
\renewcommand\contentsname{目  录}
\tableofcontents
\cleardoublepage
\pagenumbering{arabic}[/code]之后就可以开始正文啦。


[size=5][b]完。[/b][/size]

kuing 发表于 2022-3-20 01:41

重发{:victory:}

kuing 发表于 2022-3-23 17:38

说一些不足之处:

第八部分(图形并排放置)最后的 \fourtuxx 只能四图选项并排,缺少了 2x2 的图形选项,只是我书上没遇到过,所以当时懒得弄。

大题的小问(I)(II)这些,我书上是直接手写的,懒,其实应该定制一个环境用 enumerate 来写。

页: [1]

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.