diff options
Diffstat (limited to 'Master/texmf-dist')
22 files changed, 797 insertions, 333 deletions
diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-a-a3input.pdf b/Master/texmf-dist/doc/latex/jnuexam/exam-a-a3input.pdf Binary files differdeleted file mode 100644 index c8828fdeff3..00000000000 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-a-a3input.pdf +++ /dev/null diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-a-a3input.tex b/Master/texmf-dist/doc/latex/jnuexam/exam-a-a3input.tex deleted file mode 100644 index ac2cc9aa317..00000000000 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-a-a3input.tex +++ /dev/null @@ -1,9 +0,0 @@ -% -*- coding: utf-8 -*- -% !TEX program = xelatex - -% 直接包含 A4 试卷的 PDF 文件,生成双栏的 A3 试卷 -\documentclass[a3input]{jnuexam} -\begin{document} -\includepdf[pages=-,nup=2x1,offset=0 0,delta=0 0]{exam-a-empty} -%\includepdf[pages=-,nup=2x1,offset=0 0,delta=0 0,frame]{exam-a} -\end{document} diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-a-a3split.pdf b/Master/texmf-dist/doc/latex/jnuexam/exam-a-a3split.pdf Binary files differdeleted file mode 100644 index 92430159e16..00000000000 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-a-a3split.pdf +++ /dev/null diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-a-a3split.tex b/Master/texmf-dist/doc/latex/jnuexam/exam-a-a3split.tex deleted file mode 100644 index 140cb573cac..00000000000 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-a-a3split.tex +++ /dev/null @@ -1,6 +0,0 @@ -% -*- coding: utf-8 -*- -% !TEX program = xelatex - -% 将原有的 A4 试卷改为 A3 试卷双栏排版 -\PassOptionsToClass{a3paper,noanswer}{jnuexam} -\input{exam-a} diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-a-answer.pdf b/Master/texmf-dist/doc/latex/jnuexam/exam-a-answer.pdf Binary files differnew file mode 100644 index 00000000000..030ffb6eec6 --- /dev/null +++ b/Master/texmf-dist/doc/latex/jnuexam/exam-a-answer.pdf diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-a.tex b/Master/texmf-dist/doc/latex/jnuexam/exam-a-answer.tex index 54b2d1ac404..28d7c755522 100644 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-a.tex +++ b/Master/texmf-dist/doc/latex/jnuexam/exam-a-answer.tex @@ -4,6 +4,12 @@ %\answerfalse %不显示答案 +\setexam{ + binding = 2, % 装订线,1 仅空白试卷有,2 试卷和答案都有 + scratch = 1, % 草稿纸数量,仅空白试卷有,A3 大小,双面印刷 + seed = 19061116, % 随机数种子,用于改变 B 卷小题的随机顺序 +} + \begin{document} \renewcommand{\niandu}{2017--2018} @@ -24,8 +30,6 @@ \answertable[3em]{6}{3} % 生成答题栏:行高3em,总共6题,每行3题 -\newpageb % B卷分页点 - \begin{problem} 设常数$k>0$,函数$f(x)=\ln x-\dfrac{x}{\e}+k$在$(0,+\infty)$内零点的个数为 \fillout{$2$}. \end{problem} @@ -67,14 +71,12 @@ \vfill -\newpagea % A卷分页点 +\newpage \makepart{单选题}{共~6~小题,每小题~3~分,共~18~分} \answertable{6}{6} % 生成答题栏:默认行高,总共8题,每行8题 -\newpageb % B卷分页点 - \begin{problem} 在下列等式中,正确的结果是\pickout{C} \begin{abcd} @@ -164,24 +166,22 @@ \bigskip -\newpagea % A卷分页点 +\newpage \makepart{计算题}{共~6~小题,每小题~8~分,共~48~分} -\newpageb % B卷分页点 - \begin{problem} 求不定积分$\displaystyle\int\e^{2x}\,(\tan x+1)^2\dx$。 \end{problem} -\bigskip +\smallskip \begin{solution} \everymath{\displaystyle}% -原式 \? $=\int\e^{2x}\,\sec^2 x\dx+2\int\e^{2x}\,\tan x\dx$ \score{2} -\+ $=\int\e^{2x}\,\d(\tan x)+ 2\int\e^{2x}\,\tan x\dx$ \score{4} -\+ $=\e^{2x}\,\tan x - 2\int\e^{2x}\,\tan x\dx+ 2\int\e^{2x}\,\tan x\dx$ \score{6} -\+ $=\e^{2x}\,\tan x + C$ \score{8} +原式 \? $=\int\e^{2x}\,\sec^2 x\dx+2\int\e^{2x}\,\tan x\dx$ \points{2} +\+ $=\int\e^{2x}\,\d(\tan x)+ 2\int\e^{2x}\,\tan x\dx$ \points{4} +\+ $=\e^{2x}\,\tan x - 2\int\e^{2x}\,\tan x\dx+ 2\int\e^{2x}\,\tan x\dx$ \points{6} +\+ $=\e^{2x}\,\tan x + C$ \points{8} \end{solution} \vfill @@ -190,23 +190,23 @@ 求过点$A(1,2,-1), B(2,3,0),C(3,3,2)$ 的三角形$\triangle ABC$ 的面积和它们确定的平面方程. \end{problem} -\bigskip +\smallskip \begin{solution} -由题设$\overrightarrow{AB}=(1,1,1),\overrightarrow{AC}=(2,1,3)$, \score{2} +由题设$\overrightarrow{AB}=(1,1,1),\overrightarrow{AC}=(2,1,3)$, \points{2} 故$\overrightarrow{AB}\times \overrightarrow{AC}=\begin{vmatrix} \vec{i}&\vec{j} &\vec{k}\\ 1&1&1\\ 2&1&3\\ -\end{vmatrix}=(2,-1,-1)$, \score{4} +\end{vmatrix}=(2,-1,-1)$, \points{4} 三角形$\triangle ABC$ 的面积为$S_{\triangle ABC}=\dfrac{1}{2}\big|\overrightarrow{AB}\times -\overrightarrow{AC}\big|=\dfrac{1}{2}\sqrt{6}.$ \score{6} -所求平面的方程为$2(x-2)-(y-3)-z=0$, 即$2x-y-z-1=0$ \score{8} +\overrightarrow{AC}\big|=\dfrac{1}{2}\sqrt{6}.$ \points{6} +所求平面的方程为$2(x-2)-(y-3)-z=0$, 即$2x-y-z-1=0$ \points{8} \end{solution} \vfill -\newpage % A,B卷共同分页点 +\newpage \begin{problem} 计算四阶行列式 $A = \left|\begin{array}{cccc} @@ -217,7 +217,7 @@ \end{array}\right|$ 的值. \end{problem} -\bigskip +\smallskip \begin{solution} $A \? = \left|\begin{array}{cccc} @@ -234,7 +234,7 @@ $A \? = \left|\begin{array}{cccc} 1 & 2 & 3\\ - 1 & - 6 & 1\\ - 6 & - 8 & 2 - \end{array}\right|$ \score{4} + \end{array}\right|$ \points{4} \+ $= -\left|\begin{array}{ccc} 1 & 2 & 3\\ 0 & - 4 & 4\\ @@ -242,31 +242,31 @@ $A \? = \left|\begin{array}{cccc} \end{array}\right| = - \left|\begin{array}{cc} - 4 & 4\\ 4 & 20 - \end{array}\right| = -(-4\cdot20-4\cdot4) = 96$ \score{8} + \end{array}\right| = -(-4\cdot20-4\cdot4) = 96$ \points{8} \end{solution} \vfill \begin{problem} -用配方法将二次型 $f = x_1^2 + 2 x_1 x_2 - 6 x_1 x_3 + 2 x_2^2 - 12 +利用配方法,将二次型 $f = x_1^2 + 2 x_1 x_2 - 6 x_1 x_3 + 2 x_2^2 - 12 x_2 x_3 + 9 x^2_3$ 化为标准形 $f = d_1 y^2_1 + d_2 y^2_2 + d_3 y^2_3$ . \end{problem} -\bigskip +\smallskip \begin{solution} $f \? = x_1^2 + 2 x_1 x_2 - 6 x_1 x_3 + 2 x_2^2 - 12 x_2 x_3 + 9 x^2_3$ \par \+ $= x_1^2 + 2 x_1 (x_2 - 3 x_3) + (x_2 - 3 x_3)^2 + x_2^2 - 6 x_2 x_3 $ \par - \+ $= (x_1 + x_2 - 3 x_3)^2 + x_2^2 - 6 x_2 x_3$ \score{3} + \+ $= (x_1 + x_2 - 3 x_3)^2 + x_2^2 - 6 x_2 x_3$ \points{3} \+ $= (x_1 + x_2 - 3 x_3)^2 + x_2^2 - 2 x_2 \cdot 3 x_3 + (3 x_3)^2 - 9x_3^2$ \par - \+ $= (x_1 + x_2 - 3 x_3)^2 + (x_2 - 3 x_3)^2 - 9 x_3^2$ \score{6} + \+ $= (x_1 + x_2 - 3 x_3)^2 + (x_2 - 3 x_3)^2 - 9 x_3^2$ \points{6} 令$y_1 = x_1 + x_2 - 3 x_3, y_2 = x_2 - 3 x_3, y_3 = x_3$, \newline -则$f = y_1^2 + y_2^2 - 9y_3^2$为标准形.\score{8} +则$f = y_1^2 + y_2^2 - 9y_3^2$为标准形.\points{8} \end{solution} \vfill -\newpage % A,B卷共同分页点 +\newpage \begin{problem} 设每发炮弹命中飞机的概率是0.2且相互独立,现在发射100发炮弹.\par @@ -274,15 +274,15 @@ $f \? = x_1^2 + 2 x_1 x_2 - 6 x_1 x_3 + 2 x_2^2 - 12 x_2 x_3 + 9 x^2_3$ \par (2) 用中心极限定理估计命中数目$\xi$在10发到30发之间的概率. \end{problem} -\bigskip +\smallskip \begin{solution} -$E\xi = n p = 100 \cdot 0.2 = 20, D\xi = n p q = 100 \cdot 0.2 \cdot 0.8 = 16$. \score{2} +$E\xi = n p = 100 \cdot 0.2 = 20, D\xi = n p q = 100 \cdot 0.2 \cdot 0.8 = 16$. \points{2} (1) $P (10 < \xi < 30) = P (|\xi - E\xi| < 10) \ge 1 - \frac{D\xi}{10^2} - = 1 - \frac{16}{100} = 0.84$. \score{4} + = 1 - \frac{16}{100} = 0.84$. \points{4} (2) $P (10 < \xi < 30) \? \approx \Phi_0\left(\frac{30 - 20}{\sqrt{16}}\right) - - \Phi_0\left(\frac{10 - 20}{\sqrt{16}}\right)$ \score{6} - \+ $= 2 \Phi_0(2.5) - 1 = 2 \cdot 0.9938 - 1 =0.9876$ \score{8} + - \Phi_0\left(\frac{10 - 20}{\sqrt{16}}\right)$ \points{6} + \+ $= 2 \Phi_0(2.5) - 1 = 2 \cdot 0.9938 - 1 =0.9876$ \points{8} \end{solution} \vfill @@ -292,19 +292,19 @@ $E\xi = n p = 100 \cdot 0.2 = 20, D\xi = n p q = 100 \cdot 0.2 \cdot 0.8 = 16$. 试检验假设$H_0:\mu=3140$是否成立($\alpha = 0.01$). \end{problem} -\bigskip +\smallskip \begin{solution} -(1) 待检假设 $H_0 : \mu = 3140$. \score{1} -(2) 选取统计量 $T = \frac{\widebar{X}-\mu}{S / \sqrt{n}} \sim t(n-1)$. \score{3} -(3) 查表得到 $t_{\alpha} = t_{\alpha} (n - 1) = t_{0.01} (15) =2.947$. \score{5} -(4) 计算统计值 $t = \frac{\widebar{x} - \mu_0}{s/\sqrt{n}} =\frac{3160-3140}{100/4} = 0.8$.\score{7} -(5) 由于 $| t | < t_{\alpha}$, 故接受 $H_0$, 即假设成立. \score{8} +(1) 待检假设 $H_0 : \mu = 3140$. \points{1} +(2) 选取统计量 $T = \frac{\widebar{X}-\mu}{S / \sqrt{n}} \sim t(n-1)$. \points{3} +(3) 查表得到 $t_{\alpha} = t_{\alpha} (n - 1) = t_{0.01} (15) =2.947$. \points{5} +(4) 计算统计值 $t = \frac{\widebar{x} - \mu_0}{s/\sqrt{n}} =\frac{3160-3140}{100/4} = 0.8$.\points{7} +(5) 由于 $| t | < t_{\alpha}$, 故接受 $H_0$, 即假设成立. \points{8} \end{solution} \vfill -\newpagea % A卷分页点 +\newpage \makepart{证明题}{共~2~小题,每小题~8~分,共~16~分} @@ -314,7 +314,7 @@ $E\xi = n p = 100 \cdot 0.2 = 20, D\xi = n p q = 100 \cdot 0.2 \cdot 0.8 = 16$. 设数列$\{x_n\}$满足$x_1=\sqrt2$,$x_{n+1}=\sqrt{2+x_n}$.证明数列收敛,并求出极限. \end{problem} -\bigskip +\smallskip \begin{solution} (1) 事实上,由于$x_1<2$,且$x_k<2$时 @@ -322,10 +322,10 @@ $$x_{k+1}=\sqrt{2+x_k}<\sqrt{2+2}=2,$$ 由数学归纳法知对所有$n$都有$x_n<2$,即数列有上界. 又由于 $$\frac{x_{n+1}}{x_n}=\sqrt{\frac{2}{x_n^2}+\frac{1}{x_n}}>\sqrt{\frac{2}{2^2}+\frac{1}{2}}=1,$$ -所以数列单调增加.由极限存在准则II,数列必定收敛.\score{4} +所以数列单调增加.由极限存在准则II,数列必定收敛.\points{4} (2) 设数列的极限为$A$,对递推公式两边同时取极限得到 $$A=\sqrt{2+A}.$$ -解得$A=2$,即数列$\{x_n\}$的极限为$2$.\score{8} +解得$A=2$,即数列$\{x_n\}$的极限为$2$.\points{8} \end{solution} \vfill @@ -334,13 +334,13 @@ $$A=\sqrt{2+A}.$$ 设事件$A$和$B$相互独立,证明$A$和$\widebar{B}$相互独立. \end{problem} -\bigskip +\smallskip \begin{solution} -\? $P (A \cdot \widebar{B}) = P (A - B) = P (A - A B)$ \score{2} -\< $= P (A) - P (A B) = P (A) - P (A) P (B)$ \score{4} -\< $= P (A) (1 - P (B)) = P (A) P (\widebar{B})$ \score{6} -所以$A$和$\widebar{B}$相互独立.\score{8} +\? $P (A \cdot \widebar{B}) = P (A - B) = P (A - A B)$ \points{2} +\< $= P (A) - P (A B) = P (A) - P (A) P (B)$ \points{4} +\< $= P (A) (1 - P (B)) = P (A) P (\widebar{B})$ \points{6} +所以$A$和$\widebar{B}$相互独立.\points{8} \end{solution} \vfill diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-a-empty.pdf b/Master/texmf-dist/doc/latex/jnuexam/exam-a-empty.pdf Binary files differindex af4317d58aa..c558560089c 100644 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-a-empty.pdf +++ b/Master/texmf-dist/doc/latex/jnuexam/exam-a-empty.pdf diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-a-empty.tex b/Master/texmf-dist/doc/latex/jnuexam/exam-a-empty.tex index 6da2c24a858..23099457379 100644 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-a-empty.tex +++ b/Master/texmf-dist/doc/latex/jnuexam/exam-a-empty.tex @@ -3,4 +3,4 @@ % 重新排版原有的 A4 试卷,不显示答案 \PassOptionsToClass{noanswer}{jnuexam} -\input{exam-a} +\input{exam-a-answer} diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-a.pdf b/Master/texmf-dist/doc/latex/jnuexam/exam-a.pdf Binary files differdeleted file mode 100644 index f612be7749d..00000000000 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-a.pdf +++ /dev/null diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-b-a3input.pdf b/Master/texmf-dist/doc/latex/jnuexam/exam-b-a3input.pdf Binary files differdeleted file mode 100644 index 6aec596569f..00000000000 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-b-a3input.pdf +++ /dev/null diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-b-a3input.tex b/Master/texmf-dist/doc/latex/jnuexam/exam-b-a3input.tex deleted file mode 100644 index eb2782fb3e9..00000000000 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-b-a3input.tex +++ /dev/null @@ -1,9 +0,0 @@ -% -*- coding: utf-8 -*- -% !TEX program = xelatex - -% 直接包含 A4 试卷的 PDF 文件,生成双栏的 A3 试卷 -\documentclass[a3input]{jnuexam} -\begin{document} -\includepdf[pages=-,nup=2x1,offset=0 0,delta=0 0]{exam-b-empty} -%\includepdf[pages=-,nup=2x1,offset=0 0,delta=0 0,frame]{exam-b} -\end{document} diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-b-a3split.pdf b/Master/texmf-dist/doc/latex/jnuexam/exam-b-a3split.pdf Binary files differdeleted file mode 100644 index 323a2b1eab2..00000000000 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-b-a3split.pdf +++ /dev/null diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-b-a3split.tex b/Master/texmf-dist/doc/latex/jnuexam/exam-b-a3split.tex deleted file mode 100644 index fd39ae4b490..00000000000 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-b-a3split.tex +++ /dev/null @@ -1,6 +0,0 @@ -% -*- coding: utf-8 -*- -% !TEX program = xelatex - -% 将原有的 A4 试卷改为 A3 试卷双栏排版 -\PassOptionsToClass{a3paper,noanswer}{jnuexam} -\input{exam-b} diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-b-answer.pdf b/Master/texmf-dist/doc/latex/jnuexam/exam-b-answer.pdf Binary files differnew file mode 100644 index 00000000000..7cd246095aa --- /dev/null +++ b/Master/texmf-dist/doc/latex/jnuexam/exam-b-answer.pdf diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-b-answer.tex b/Master/texmf-dist/doc/latex/jnuexam/exam-b-answer.tex new file mode 100644 index 00000000000..6925ea8fff7 --- /dev/null +++ b/Master/texmf-dist/doc/latex/jnuexam/exam-b-answer.tex @@ -0,0 +1,6 @@ +% -*- coding: utf-8 -*- +% !TEX program = xelatex + +% 从 A 卷自动生成 B 卷,将题目乱序排列 +\PassOptionsToClass{random}{jnuexam} +\input{exam-a-answer} diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-b-empty.pdf b/Master/texmf-dist/doc/latex/jnuexam/exam-b-empty.pdf Binary files differindex 363d080b0c8..b98b5e7df42 100644 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-b-empty.pdf +++ b/Master/texmf-dist/doc/latex/jnuexam/exam-b-empty.pdf diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-b-empty.tex b/Master/texmf-dist/doc/latex/jnuexam/exam-b-empty.tex index 41db22542c4..953a4aab9ff 100644 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-b-empty.tex +++ b/Master/texmf-dist/doc/latex/jnuexam/exam-b-empty.tex @@ -3,4 +3,4 @@ % 重新排版原有的 A4 试卷,不显示答案 \PassOptionsToClass{noanswer}{jnuexam} -\input{exam-b} +\input{exam-b-answer} diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-b.pdf b/Master/texmf-dist/doc/latex/jnuexam/exam-b.pdf Binary files differdeleted file mode 100644 index 169d679c221..00000000000 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-b.pdf +++ /dev/null diff --git a/Master/texmf-dist/doc/latex/jnuexam/exam-b.tex b/Master/texmf-dist/doc/latex/jnuexam/exam-b.tex deleted file mode 100644 index 78b04a6bd04..00000000000 --- a/Master/texmf-dist/doc/latex/jnuexam/exam-b.tex +++ /dev/null @@ -1,6 +0,0 @@ -% -*- coding: utf-8 -*- -% !TEX program = xelatex - -% 从 A 卷自动生成 B 卷,将题目逆序排列 -\PassOptionsToClass{reverse}{jnuexam} -\input{exam-a} diff --git a/Master/texmf-dist/doc/latex/jnuexam/jnuexam.pdf b/Master/texmf-dist/doc/latex/jnuexam/jnuexam.pdf Binary files differindex 495aed8bccc..b8a0d9e33b1 100644 --- a/Master/texmf-dist/doc/latex/jnuexam/jnuexam.pdf +++ b/Master/texmf-dist/doc/latex/jnuexam/jnuexam.pdf diff --git a/Master/texmf-dist/doc/latex/jnuexam/jnuexam.tex b/Master/texmf-dist/doc/latex/jnuexam/jnuexam.tex index bfc98e08349..891c0663eeb 100644 --- a/Master/texmf-dist/doc/latex/jnuexam/jnuexam.tex +++ b/Master/texmf-dist/doc/latex/jnuexam/jnuexam.tex @@ -77,6 +77,8 @@ \titlepage \end{frame} +\section{模板介绍} + \begin{framex} \frametitle{简单介绍} 本文档介绍 \verb!jnuexam! 文档类。这个文档类提供暨南大学考试试卷的 LaTeX 模板。 @@ -84,7 +86,7 @@ 这个模板将格式和内容分开,而且可以从一份 \verb!tex! 文件编译出四份试卷(A卷 / B卷 / A卷答案 / B卷答案),使用方便。 \par 这个模板的最新版本可以在下面地址下载:\newline - \href{https://lvjr.bitbucket.io/jnuexam.html?\the\year}{https://lvjr.bitbucket.io/jnuexam.html} + \color{blue}{\href{https://lvjr.bitbucket.io/jnuexam.html?\the\year}{\ttfamily https://lvjr.bitbucket.io/jnuexam.html}} \end{framex} \begin{framex} @@ -98,8 +100,39 @@ 推荐用较先进的 \verb!XeLaTeX! 编译。 \end{framex} +\section{试卷结构} + \begin{framex} \frametitle{试卷结构} +下面是 \verb!jnuexam! 试卷文档的基本结构: +\begin{code} +\documentclass{jnuexam} +% 导言区 +\begin{document} +% 正文区 +\end{document} +\end{code} +导言区用于设定装订线和草稿纸等等选项。\par +正文区用于填写试卷表头和输入试卷内容。 +\end{framex} + +\begin{framex} +\frametitle{装订草稿} +在文档的导言区可以设定装订线和草稿纸。比如: +\begin{code} +\setexam{ + binding = 2, % 装订线 + scratch = 1, % 草稿纸 +} +\end{code} +其中 \verb!binding! 取 0 表示没有装订线, +取 1 表示仅空白试卷有,取 2 表示空白试卷和试卷答案都有。\par +而 \verb!scratch! 的取值表示草稿纸数量,以 A3 大小双面印刷计算。 +草稿纸仅在空白试卷中出现,试卷答案里不会带草稿纸。 +\end{framex} + +\begin{framex} +\frametitle{试卷正文} \begin{code} \documentclass{jnuexam} \begin{document} @@ -145,14 +178,19 @@ \makepart{判断题}{题数分值} \begin{problem} -第一道判断题描述。\true +第一道判断题描述。\tickout{t} \end{problem} \begin{problem} -第二道判断题描述。\false +第二道判断题描述。\tickout{f} \end{problem} \end{code} -其中 \verb!\true! 和 \verb!\false! 命令分别表示正确和错误。 +其中 \verb!\tickout{t}! 和 \verb!\tickout{f}! +分别表示打勾(\textcolor{blue}{$\checkmark$})和打叉(\textcolor{blue}{\large$\times$})。 +还可用大写的 \verb!\tickout{T}! 和 \verb!\tickout{F}!, +分别表示输出 \textcolor{blue}{\textsf{T}} 和 \textcolor{blue}{\textsf{F}}。 +\par +答案必须放在 \verb!\tickout! 命令里;这样才能在生成空白试卷时隐藏它。 \end{framex} \begin{framex} @@ -274,14 +312,14 @@ \begin{framex} \frametitle{评分命令} 计算题和证明题等主观题的排版方法是完全一样的。在编写这些主观题的解答时, -可以用 \verb!\score! 命令给出各步骤得分。比如: +可以用 \verb!\points! 命令给出各步骤得分。比如: \begin{code} \begin{solution} -$1+1=2$ \score{4} -$2+2=4$ \score{8} +$1+1=2$ \points{4} +$2+2=4$ \points{8} \end{solution} \end{code} -评分命令 \verb!\score! 也可在 \verb!align*! 等数学环境中使用,此时评分显示在公式编号位置。 +评分命令 \verb!\points! 也可在 \verb!align*! 等数学环境中使用,此时评分显示在公式编号位置。 \end{framex} \begin{framex} @@ -289,11 +327,11 @@ $2+2=4$ \score{8} 此文档类提供几个对齐命令,用于在不同行之间对齐。比如 \vskip1em\hrule 我们有$(a+b)^2 = (a+b)(a+b)$ \par -\leavevmode\phantom{我们有$(a+b)^2$}${}= a^2 + 2ab + b^2$ \cdotfill 2分 +\leavevmode\phantom{我们有$(a+b)^2$}${}= a^2 + 2ab + b^2$ \hfill$\cdots\cdots$ 2分 \vskip0.6em\hrule\vskip1em \begin{code} 我们有$(a+b)^2 \? = (a+b)(a+b)$ \\ - \+$= a^2+2ab+b^2$ \score{2} + \+$= a^2+2ab+b^2$ \points{2} \end{code} 第一个公式内部的 \verb!\?! 保存当前水平位置, 而第二个公式前面的 \verb!\+! 表示跳到之前保存的位置。 @@ -306,11 +344,11 @@ $2+2=4$ \score{8} 此文档类提供几个对齐命令,用于在不同行的对齐。比如 \vskip1em\hrule 我们有$(a+b)^2 = (a+b)(a+b)$ \par -\leavevmode\phantom{我们\,}${}= a^2 + 2ab + b^2$ \cdotfill 2分 +\leavevmode\phantom{我们\,}${}= a^2 + 2ab + b^2$ \hfill$\cdots\cdots$ 2分 \vskip0.6em\hrule\vskip1em \begin{code} 我们有 \? $(a+b)^2 = (a+b)(a+b)$ \\ - \< $= a^2+2ab+b^2$ \score{2} + \< $= a^2+2ab+b^2$ \points{2} \end{code} 第一行公式前面的 \verb!\?! 保存当前水平位置, 而第二行公式前面的 \verb!\<! 表示跳到之前保存位置的左侧(左移一个等号的宽度)。 @@ -345,26 +383,28 @@ $2+2=4$ \score{8} 附录数据必须放在 \verb!\makedata! 命令后面;否则在从A卷生成B卷时会出问题。 \end{framex} +\section{模板选项} + \begin{framex} \frametitle{空白试卷} -假设 \verb!exam-a.tex! 是含答案的试卷。新建一个包含以下内容的 \verb!exam-a-empty.tex! 文档, +假设 \verb!exam-a-answer.tex! 是含答案的试卷。新建一个包含以下内容的 \verb!exam-a-empty.tex! 文档, 编译后将得到不含答案的空白试卷。 \begin{code} \PassOptionsToClass{noanswer}{jnuexam} -\input{exam-a} +\input{exam-a-answer} \end{code} 也就是说,给 \verb!jnuexam! 文档类加上 \verb!noanswer! 选项后,编译时将会自动隐藏试卷答案。 \end{framex} \begin{framex} -\frametitle{逆序出题} -假设 \verb!exam-a.tex! 是含答案的A卷。新建一个包含以下内容的 \verb!exam-b.tex! 文档, -编译后将得到逆序出题的B卷。 +\frametitle{乱序出题} +假设 \verb!exam-a-answer.tex! 是含答案的A卷。新建一个包含以下内容的 \verb!exam-b-answer.tex! 文档, +编译后将得到乱序出题的B卷。 \begin{code} -\PassOptionsToClass{reverse}{jnuexam} -\input{exam-a} +\PassOptionsToClass{random}{jnuexam} +\input{exam-a-answer} \end{code} -也就是说,给 \verb!jnuexam! 文档类加上 \verb!reverse! 选项后,编译时将会逆序排列各题型的小题。 +也就是说,给 \verb!jnuexam! 文档类加上 \verb!random! 选项后,编译时将会乱序排列各题型的小题。 \end{framex} \begin{framex} @@ -383,48 +423,35 @@ $2+2=4$ \score{8} \hline \end{tabularx}\par 当然,竖直空白命令可以连续使用多个,以得到所需的空白。 +\vfill +在试卷中可以使用分页命令 \verb!\newpage!, +\alert{不要}使用其他分页命令,比如 \verb!\clearpage! 等, +以免导致 B 卷格式错乱。 \end{framex} \begin{framex} -\frametitle{分页命令} -分页命令 \verb!\newpage! 同样可以使用。由于A卷和B卷的小题顺序相反, -其中的分页位置通常也不同。因此这里另外提供 \verb!\newpagea! 和 \verb!\newpageb! 命令, -分别只对 A 卷和 B 卷有效。 -\par -\renewcommand{\arraystretch}{1.3}% -\begin{tabularx}{\linewidth}{l<{\qquad}X} - \hline - \texttt{\string\newpage} & 分页,对A卷和B卷均有效 \\ - \hline - \texttt{\string\newpagea} & 分页,仅对A卷有效 \\ - \hline - \texttt{\string\newpageb} & 分页,仅对B卷有效 \\ - \hline -\end{tabularx}\par -在试卷中\alert{不要}使用其他分页命令,比如 \verb!\clearpage! 等。 +\frametitle{双栏试卷} +假设 \verb!exam-a-empty.tex! 是原来试卷的 TeX 文件。新建一个包含以下内容的文档, +编译后将得到的 A3 纸张的试卷。 +\begin{code} +\PassOptionsToClass{a3paper}{jnuexam} +\input{exam-a-empty} +\end{code} +也就是说,给 \verb!jnuexam! 文档类加上 \verb!a3paper! 选项后,编译时将会按照 A3 纸张排版出双栏试卷。 \end{framex} \begin{framex} -\frametitle{分页例子} -关于分页命令的使用,可以看下面的典型例子: -\begin{code} -\makepart{某题型}{题型分值} -\newpageb -\begin{problem}第一题\end{problem}\vfill -\begin{problem}第二题\end{problem}\vfill -\newpage -\begin{problem}第三题\end{problem}\vfill -\begin{problem}第四题\end{problem}\vfill -\newpagea -\end{code} -这样编译得到的A卷就是这样的顺序: +\frametitle{双栏试卷} +假设 \verb!exam-a-empty.pdf! 是原来试卷的 PDF 文件。新建一个包含以下内容的文档, +编译后将得到的 A3 纸张的试卷。 \begin{code} -第一题 第二题 分页 第三题 第四题 分页 -\end{code} -而编译得到的B卷就是这样的顺序: -\begin{code} -第四题 第三题 分页 第二题 第一题 分页 +\documentclass[a3input]{jnuexam} +\begin{document} +\includepdf[pages=-,nup=2x1]{exam-a-empty} +\end{document} \end{code} +%\includepdf[pages=-,nup=2x1,offset=0 0,delta=0 0]{exam-a-empty} +这种用法直接读入 A4 试卷的 PDF 文件,生成双栏的 A3 试卷,适合没有 TeX 文件时使用。 \end{framex} \end{document} diff --git a/Master/texmf-dist/tex/latex/jnuexam/jnuexam.cls b/Master/texmf-dist/tex/latex/jnuexam/jnuexam.cls index bace8c2a698..5b25fa01d69 100644 --- a/Master/texmf-dist/tex/latex/jnuexam/jnuexam.cls +++ b/Master/texmf-dist/tex/latex/jnuexam/jnuexam.cls @@ -6,25 +6,39 @@ % ---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e} -\ProvidesClass{jnuexam}[2020/11/06 v1.0 An exam class for Jinan University] - -\newif\ifmifengxian \mifengxiantrue % 是否加密封线 -\newif\ifsidebyside \sidebysidefalse % 是否 A3 纸张 -\newif\ifreverse \reversefalse % 是否逆序出题 -\newif\ifanswer \answertrue % 是否显示答案 -\newif\ifamsfonts \amsfontsfalse % 切换数学字体 -\newif\ifsourcehan \sourcehanfalse % 切换思源字体 -\newif\ifdisplay \displayfalse % 切换展示公式 -\newif\ifcollection \collectionfalse % 用于试卷题库 - -\DeclareOption{a3paper}{\sidebysidetrue} -\DeclareOption{a3input}{\sidebysidetrue\mifengxianfalse} -\DeclareOption{reverse}{\reversetrue} +\ProvidesClass{jnuexam}[2023/12/11 v2.0 An exam class for Jinan University] + +%% 旧版本的 LaTeX 不能识别 2022-11-01 这种日期格式 +%\@ifl@t@r\fmtversion{2022-11-01}{}{ +\@ifl@t@r\fmtversion{2022/11/01}{}{ + \ClassError{jnuexam}{% + Your current TeX distribution is quite old.\MessageBreak + We need CTeX 3.0+ or MiKTeX 2023+ or TeXLive 2023+% + }{Please update your TeX distribution first.} +} + +\newif\ifplain \plainfalse % 是否添加装订线和草稿纸 +\newif\iftwoinone \twoinonefalse % 是否使用 A3 纸张 +\newif\ifoneside \onesidefalse % 是否单面印刷试卷 +\newif\ifresetnumber \resetnumbertrue % 是否对各题型小题分别编号 +\newif\ifrandom \randomfalse % 是否乱序出题 +\newif\ifanswer \answertrue % 是否显示答案 +\newif\ifamsfonts \amsfontsfalse % 切换数学字体 +\newif\ifsourcehan \sourcehanfalse % 切换思源字体 +\newif\ifsolidot \solidotfalse % 是否替换空心句号为实心句号 +\newif\ifcellspace \cellspacefalse % 增加表格列间距 +\newif\ifmedmath \medmathfalse % 切换公式尺寸 + +\DeclareOption{plain}{\plaintrue} +\DeclareOption{a3paper}{\twoinonetrue} +\DeclareOption{a3input}{\twoinonetrue\plaintrue} +\DeclareOption{oneside}{\onesidetrue} +\DeclareOption{random}{\randomtrue} \DeclareOption{noanswer}{\answerfalse} \DeclareOption{amsfonts}{\amsfontstrue} \DeclareOption{sourcehan}{\sourcehantrue} -\DeclareOption{display}{\displaytrue} -\DeclareOption{collection}{\collectiontrue\mifengxianfalse} +\DeclareOption{solidot}{\solidottrue} +\DeclareOption{medmath}{\cellspacetrue\medmathtrue} \DeclareOption*{\PassOptionsToClass{\CurrentOption}{ctexart}} %其它选项 @@ -32,32 +46,61 @@ % 四号 小四号 五号 小五号 % 14bp 12bp 10.5bp 9bp +% 实际上,在旧版本 ctex 中只能用 cs4size 和 c5size 选项 +% 而新版本 ctex 中,可以利用 zihao 选项指定各种中文字号 +\PassOptionsToPackage{CJKnumber}{xeCJK} \LoadClass[cs4size,UTF8,noindent]{ctexart} -\ifamsfonts - \RequirePackage{amssymb} -\else - \RequirePackage[utopia]{mathdesign} % charter, utopia - \renewcommand\bfdefault{bx} - \let\oldoiint\oiint\renewcommand{\oiint}{\oldoiint\nolimits} - \DeclareTextCommandDefault{\nobreakspace}{\leavevmode\nobreak\ } +% 在旧版本 xeCJK 中,必须用 CJKnumber 选项载入 CJKnumb 包,后面才载入会报错 +% 但在新版本 xeCJK 中 CJKnumber 选项已经被废弃,需要在后面自行载入它 +% 在 xeCJK 中已经禁止载入 CJK,但是在新版本 ctex 宏包中却失效了 +% 我们假装 CJK 已经载入,再载入 CJKnumb,避免出现 \CJKglue 重复定义的问题 +% 注意用 PDFLaTeX 编译时需要用到 CJK,所以只在未定义时才作修改 +\ifdefined\else + \@namedef{ver@CJK.sty}{} + %\@namedef{opt@CJK.sty}{} \fi +\RequirePackage{CJKnumb} + +% 新版本 xeCJK 已经废弃并禁用 CJKfntef,改用 xeCJKfntef 取代,我们需要载入后者 +% 注意要保证能在较旧的 TeX 系统中编译,我们只能用 \ifXeTeX 而不能用 \ifxetex +% 因为旧版本 iftex 宏包只有 \ifXeTeX 命令,而 ifxetex 宏包才有 \ifxetex 命令 +% 在 2019 年 10 月,LaTeX 开发团队接管了 iftex 宏包,新版本同时提供这两个命令 +\RequirePackage{CJKfntef} +\RequirePackage{iftex} +\ifXeTeX\@ifpackagelater{xeCJK}{2020/02/10}{\RequirePackage{xeCJKfntef}}{}\fi -\ifsidebyside +\iftwoinone \RequirePackage[a3paper,landscape,twocolumn,columnsep=60mm,left=30mm,right=30mm,top=25mm,bottom=25mm]{geometry} \else \RequirePackage[a4paper,left=30mm,right=30mm,top=25mm,bottom=25mm]{geometry} \fi -\RequirePackage{tabularx} -\RequirePackage{lastpage} -\RequirePackage{fancyhdr} -\RequirePackage{xcolor} +\RequirePackage{amsmath} +\RequirePackage{array} +\RequirePackage{calc} \RequirePackage{comment} +\RequirePackage[inline]{enumitem} \RequirePackage{environ} \RequirePackage{etoolbox} -\RequirePackage{calc} -\RequirePackage{iftex} +\RequirePackage{fancyhdr} +\RequirePackage{zref-user,zref-lastpage} +\RequirePackage{tabularx} +\RequirePackage{xcolor} +\RequirePackage{xkeyval} + +\ifplain + \allowdisplaybreaks[4] +\fi + +\ifamsfonts + \RequirePackage{amssymb} +\else + \RequirePackage[utopia]{mathdesign} % charter, utopia + \renewcommand\bfdefault{bx} + \let\oldoiint\oiint\renewcommand{\oiint}{\oldoiint\nolimits} + \DeclareTextCommandDefault{\nobreakspace}{\leavevmode\nobreak\ } +\fi \newcolumntype{Y}{>{\centering\arraybackslash}X} \newcolumntype{n}[1]{>{\centering\arraybackslash}m{#1}} @@ -67,55 +110,151 @@ \setlength{\lineskip}{4pt} %% --------------------------------------------------------------------------- -%% 密封线命令 \mifengxian -%% 草稿纸命令 \caogaozhi -%% 这两个命令仅在 A3 纸张中用到,且需要编译两次才能得到正确结果 +%% 装订线命令 \addbindingline +%% 草稿纸命令 \addscratchpaper +%% 这两个命令需要编译两次才能得到正确结果 %% --------------------------------------------------------------------------- -\newcommand{\mifengxianleft}{ +\newcommand{\setexam}[1]{\setkeys{jnuexam@setup}{#1}} + +\ifplain\else + \RequirePackage{tikz} + \RequirePackage{everypage} +\fi + +\newcommand{\bindinglineleft}{ \path (current page.north west) +(25mm,-25mm) coordinate (a1); \path (current page.south west) +(25mm,25mm) coordinate (a2); \draw[dashed] (a1) -- node[left=1mm,text width=1em,inner sep=0pt]{\1{线}\0\1{订}\0\1{装}} (a2); } -\newcommand{\mifengxianright}{ +\newcommand{\bindinglineright}{ \path (current page.north east) +(-25mm,-25mm) coordinate (b1); \path (current page.south east) +(-25mm,25mm) coordinate (b2); \draw[dashed] (b1) -- node[right=1mm,text width=1em,inner sep=0pt]{\2{装}\0\2{订}\0\2{线}} (b2); } -\newcommand{\mifengxianone}{% +\newcommand{\bindinglineone}{% \def\0{\\[70mm]}\def\1{\rotatebox{90}}\def\2{\rotatebox{-90}}% \begin{tikzpicture}[remember picture,overlay,very thick] - \ifnumodd{\value{page}}{\mifengxianleft}{\mifengxianright} + \ifnumodd{\value{page}}{\bindinglineleft}{\bindinglineright} \end{tikzpicture}} -\newcommand{\mifengxiantwo}{% +\newcommand{\bindinglinetwo}{% \def\0{\\[70mm]}\def\1{\rotatebox{90}}\def\2{\rotatebox{-90}}% \begin{tikzpicture}[remember picture,overlay,very thick] - \mifengxianleft\mifengxianright + \bindinglineleft\bindinglineright +\end{tikzpicture}} + +\iftwoinone + \let\bindingline=\bindinglinetwo +\else + \let\bindingline=\bindinglineone +\fi + +\def\zhuangdingxian{1} +\define@key{jnuexam@setup}{binding}[2]{\def\zhuangdingxian{#1}} + +\newcommand{\addbindingline}{% + \ifcase\zhuangdingxian % 0 + \or % 1 + \ifbool{answer}{}{\bindingline}% + \or % 2 + \bindingline + \fi +} + +\ifplain\else + \AddEverypageHook{\addbindingline} +\fi + +\newcommand{\scratchpaperone}{% +\begin{tikzpicture}[remember picture,overlay,font=\sffamily\fontsize{120pt}{120pt}\selectfont] + \node[text=lightgray!40,text width=120pt] at (current page.center) {草\\ 稿\\ 纸}; \end{tikzpicture}} -\newcommand{\caogaozhi}{% +\newcommand{\scratchpapertwo}{% \begin{tikzpicture}[remember picture,overlay,font=\sffamily\fontsize{180pt}{180pt}\selectfont] \node[text=lightgray!40] at (current page.center) {草\quad 稿\quad 纸}; \end{tikzpicture}} -\ifmifengxian - \RequirePackage{tikz} - \RequirePackage{everypage} - \ifsidebyside - \AddEverypageHook{\mifengxiantwo} - % 在 twocolumn 文档中,\newpage 可能是到下一栏,\clearpage 才能保证到下一页 - \preto{\@enddocumenthook}{\clearpage\pagestyle{empty}\caogaozhi\clearpage\caogaozhi\addtocounter{page}{-2}} - % 在旧版本 ctex 宏包中不能用 \AtEndDocument 添加含中文的内容,即不能用 \appto 而要用 \preto - %\AtEndDocument{\clearpage\pagestyle{empty}\caogaozhi\clearpage\caogaozhi\addtocounter{page}{-2}} - \else - \AddEverypageHook{\mifengxianone} - \fi +\def\caogaozhi{0} +\define@key{jnuexam@setup}{scratch}[1]{\def\caogaozhi{#1}} + +\newcounter{my@empty@page} % 空白页数 +\newcounter{my@scratch@page} % 草稿页数 +\newcounter{my@extra@page} % 空白页数+草稿页数 + +% 添加空白页,使得草稿纸前页数在单面印刷时为偶数,双面印刷时为4的倍数 +% 添加草稿纸,页数在单面印刷时等于设置值的两倍,双面印刷时等于设置值的4倍 +\newcommand{\doscratchpaperone}{% + \clearpage\pagestyle{empty}\let\addbindingline=\relax + \ifnumgreater{\caogaozhi}{0}{% + \ifbool{oneside}{% + \ifnumodd{\value{page}}% + {\setcounter{my@empty@page}{0}}% + {\setcounter{my@empty@page}{1}}% + \setcounter{my@scratch@page}{\caogaozhi*2}% + }{% + \setcounter{my@empty@page}{(\value{page}+2)/4*4+1-\value{page}}% + \setcounter{my@scratch@page}{\caogaozhi*4}% + }% + \my@add@extra@page + }{}% +} + +% 注意在 twocolumn 文档中,\newpage 到下一栏,\clearpage 到下一页 +% 另外注意第一行的 \clearpage 等不能移动到 \my@add@extra@page 命令里 +% 因为 \clearpage 后本页已经结束,page 表示的是下一页的页码 +\newcommand{\doscratchpapertwo}{% + \clearpage\pagestyle{empty}\let\addbindingline=\relax + \ifnumgreater{\caogaozhi}{0}{% + \ifbool{oneside}{% + \setcounter{my@empty@page}{0}% + \setcounter{my@scratch@page}{\caogaozhi}% + }{% + \setcounter{my@empty@page}{(\value{page}/2)-(\value{page}/2)/2*2}% + \setcounter{my@scratch@page}{\caogaozhi*2}% + }% + \my@add@extra@page + }{}% +} + +\newcommand{\my@add@extra@page}{% + \setcounter{my@extra@page}{\value{my@empty@page}+\value{my@scratch@page}}% + \whileboolexpr{ + test{\ifnumgreater{\value{my@empty@page}}{0}} + }{% + \addtocounter{my@empty@page}{-1}% + \leavevmode\clearpage + }% + \whileboolexpr{ + test{\ifnumgreater{\value{my@scratch@page}}{0}} + }{% + \addtocounter{my@scratch@page}{-1}% + \leavevmode\scratchpaper\clearpage + }% + \addtocounter{page}{-\value{my@extra@page}}% +} + +\iftwoinone + \let\scratchpaper=\scratchpapertwo + \let\doscratchpaper=\doscratchpapertwo +\else + \let\scratchpaper=\scratchpaperone + \let\doscratchpaper=\doscratchpaperone \fi -\ifsidebyside +% 在旧版本 ctex 宏包中不能用 \AtEndDocument 添加含中文的内容,即不能用 \appto 而要用 \preto +\newcommand{\addscratchpaper}{% + \preto{\@enddocumenthook}{\doscratchpaper}% +} + +\ifplain\else\ifanswer\else + \addscratchpaper +\fi\fi + +\iftwoinone \RequirePackage{pdfpages} % 新版本 pdfpages 将 \includepdf 放在文档开头时会有命令未定义的错误 % 见 https://tex.stackexchange.com/questions/352007/ieeetran-and-pdfpages @@ -167,7 +306,7 @@ \hline \textbf{考试方式} \\ 开卷~[\isquad{\bijuan}]\quad 闭卷~[\ischeck{\bijuan}] \\ \hline - \textbf{试卷类别}~(\,A, B, C\,)\\\relax [\,\shijuan\,]\hfill 共~\pageref{LastPage}~页 + \textbf{试卷类别}~(\,A, B, C\,)\\\relax [\,\shijuan\,]\hfill 共~\zpageref{LastPage}~页 \end{tabular} } @@ -181,9 +320,12 @@ \newcommand{\makehead}{ \thispagestyle{plain} - \centerline{\LARGE\bfseries 暨\quad 南\quad 大\quad 学\quad 考\quad 试\quad 试\quad 卷} + \centerline{% + \LARGE\bfseries\ifanswer\color{red!80!black}\fi + 暨\quad 南\quad 大\quad 学\quad 考\quad 试\quad 试\quad 卷\ifanswer\quad 答\quad 案\fi + }% \vspace{2em}% - \ifreverse + \ifrandom \ifx\shijuan\my@temp@a\renewcommand{\shijuan}{B}\fi \ifx\shijuan\my@temp@c\renewcommand{\shijuan}{D}\fi \fi @@ -204,9 +346,9 @@ \hline \textbf{题\quad 号} & 一 & 二 & 三 & 四 & 五 & 六 & 总分\\ \hline - \textbf{得\quad 分} & & & & & & & \\ + \textbf{得\quad 分}\rule[-0.75em]{0pt}{2.5em} & & & & & & & \\ \hline - \textbf{评阅人} & & & & & & & \\ + \textbf{评阅人}\rule[-0.75em]{0pt}{2.5em} & & & & & & & \\ \hline \end{tabularx} } @@ -219,12 +361,27 @@ \newcommand{\my@headleft}{\hspace{-0.3em}《\kecheng》\kern-0.3em 试卷\,\shijuan} \newcommand{\my@headright}{姓名\hspace{6em}学号\hspace{6em}} \newcommand{\my@headtext}{\my@headleft\hfill \my@headright} -\newcommand{\my@foottext}{第~\thepage~页\quad 共~\pageref{LastPage}~页} +\newcommand{\my@foottext}{第~\thepage~页\quad 共~\zpageref{LastPage}~页} +% fancy page style +\fancyhf{} % 清空页眉页脚 +\iftwoinone + \renewcommand{\headrulewidth}{0pt}% + \lhead{\small\underline{\my@columnbox{\my@headtext}\strut}} + \rhead{\small\underline{\my@columnbox{\my@headtext}\strut}} + \lfoot{\small\my@columnbox{\my@foottext}} + \rfoot{\small\my@columnbox{\stepcounter{page}\my@foottext}} +\else + \lhead{\small\my@headleft} + \rhead{\small\my@headright} + \cfoot{\small\my@foottext} +\fi + +% plain page style \fancypagestyle{plain}{ \renewcommand{\headrulewidth}{0pt}% \fancyhf{} - \ifsidebyside + \iftwoinone \rhead{\small\underline{\my@columnbox{\my@headtext\strut}}} \lfoot{\small\my@columnbox{\my@foottext}} \rfoot{\small\my@columnbox{\stepcounter{page}\my@foottext}} @@ -232,18 +389,11 @@ \cfoot{\small\my@foottext} \fi } -\fancyhf{} -\pagestyle{fancy} -\ifsidebyside - \renewcommand{\headrulewidth}{0pt}% - \lhead{\small\underline{\my@columnbox{\my@headtext}\strut}} - \rhead{\small\underline{\my@columnbox{\my@headtext}\strut}} - \lfoot{\small\my@columnbox{\my@foottext}} - \rfoot{\small\my@columnbox{\stepcounter{page}\my@foottext}} + +\ifplain + \pagestyle{plain} \else - \lhead{\small\my@headleft} - \rhead{\small\my@headright} - \cfoot{\small\my@foottext} + \pagestyle{fancy} \fi %% --------------------------------------------------------------------------- @@ -251,44 +401,174 @@ %% 附录命令 \makedata %% 题目环境 problem %% 解答环境 solution -%% 逆序选项 reverse +%% 乱序选项 random %% --------------------------------------------------------------------------- +\newif\ifonlyoneproblem \onlyoneproblemfalse % 此部分仅有一道题时不显示题目编号 \xdef\allproblems{} \xdef\lastproblem{} -\newcounter{problem} +\newcounter{problem} % 当前题型的小题编号 +\newcounter{problemreal} % 实际显示的小题编号,在各题型小题统一编号时使用 +\newcounter{totalproblems} % 之前各题型小题总数,在各题型小题统一编号时使用 \newcommand{\solutionname}{解} \newcounter{choice} % 后面选择题的 abcd 环境要用到 -\newcounter{step} % 后面解答题的 \step 命令要用到 +\newcommand{\hangtext}{} +\newlength{\hanglength} +\colorlet{part number}{black} +\colorlet{problem number}{blue!80!black} +\colorlet{solution name}{blue!80!black} + +\ifrandom + \RequirePackage{pgf} + \RequirePackage{pgffor} +\fi + +\newcounter{my@shuffle@temp@cnt} +\newcounter{my@list@temp@cnt} + +\newcommand\my@list@print[1]{% + \par\renewcommand*{\do}[1]{(##1)}% + \dolistloop#1% +} + +\newcommand\my@list@remove[2]{% + %\my@list@print\my@shuffle@list + \setcounter{my@list@temp@cnt}{0}% + \global\let\my@tmpa@list=#1% + \gdef#1{}% + \par\renewcommand*{\do}[1]{% + \stepcounter{my@list@temp@cnt}% + \ifnumequal{\value{my@list@temp@cnt}}{#2}{% + \def\my@list@item{##1}% + %[##1]% + }{ + \listxadd#1{##1}% + }% + }% + \dolistloop\my@tmpa@list +} -\newcommand{\printproblems}{\ifreverse\lastproblem\allproblems\fi\xdef\allproblems{}\xdef\lastproblem{}} +%% 随机数种子不能超过 2147483647 = "7FFFFFFF +\def\my@random@seed{19061116} +\define@key{jnuexam@setup}{seed}[19061116]{\def\my@random@seed{#1}} + +\newcommand\my@shuffle@problems{% + %% 当\pgfmathrandom的参数为3的倍数时,对相邻种子生成的多个随机数分布不均匀 + %\pgfmathsetseed{\numexpr\my@random@seed+\value{section}-1\relax}% + %% 因此我们改用下面的方法,用随机数种子生成下一个随机数种子 + \pgfmathsetseed{\my@random@seed}% + \pgfmathrandominteger\my@random@seed{1}{2147483647}% + \ifnumgreater{\value{problem}}{2}{% + \gdef\my@shuffle@list{}% + \foreach \i in {1,...,\value{problem}} {\listxadd\my@shuffle@list{\i}}% + %% 首尾两个小题的位置总要改变 + \pgfmathrandom{2,\value{problem}}% + \my@list@remove\my@shuffle@list{\pgfmathresult}% + \global\csletcs{my@problem@b@1}{my@problem@a@\my@list@item}% + \ifnumequal{\my@list@item}{\value{problem}}{ + \pgfmathrandom{\numexpr\value{problem}-1\relax}% + \my@list@remove\my@shuffle@list{\pgfmathresult}% + \global\csletcs{my@problem@b@\the\value{problem}}{my@problem@a@\my@list@item}% + }{% + \pgfmathrandom{\numexpr\value{problem}-2\relax}% + \my@list@remove\my@shuffle@list{\pgfmathresult}% + \global\csletcs{my@problem@b@\the\value{problem}}{my@problem@a@\my@list@item}% + }% + %% 其他小题的位置没有任何限制 + \setcounter{my@shuffle@temp@cnt}{1}% + \whileboolexpr{% + test{\ifnumless{\value{my@shuffle@temp@cnt}}{\numexpr\value{problem}-1\relax}}% + }{% + \stepcounter{my@shuffle@temp@cnt}% + \pgfmathrandom{\numexpr\value{problem}-\value{my@shuffle@temp@cnt}\relax}% + \my@list@remove\my@shuffle@list{\pgfmathresult}% + \global\csletcs{my@problem@b@\the\value{my@shuffle@temp@cnt}}{% + my@problem@a@\my@list@item + }% + }% + }{% + \ifnumequal{\value{problem}}{2}{% + \global\csletcs{my@problem@b@1}{my@problem@a@2}% + \global\csletcs{my@problem@b@2}{my@problem@a@1}% + }{}% + }% +} + +\newcommand{\printproblems}{% + \ifrandom + \my@appto@problems + \my@shuffle@problems + \setcounter{problem}{0}% + \allproblems + \fi + \xdef\allproblems{}% + \xdef\lastproblem{}% +} \newcommand{\makepart}[2]{% \printproblems + \setcounter{totalproblems}{\value{totalproblems}+\value{problem}}% \setcounter{problem}{0}% \stepcounter{section}% \vspace{1em}% - \noindent\textbf{\Chinese{section}、#1}(#2)% - \par\vspace{1em}% + \noindent\textbf{\textcolor{part number}{\Chinese{section}}、#1}(#2)% + \par\nopagebreak + \if\relax\detokenize{#1}\relax % #1 is empty + \onlyoneproblemtrue + \else + \onlyoneproblemfalse + \vspace{1em}% + \fi + %其中设定了\@nobreaktrue,保证在列表前也不分页,详情见 source2e + \@afterheading } \newcommand{\makedata}[1]{% - \printproblems\my@stop@reverse + \printproblems\my@stop@random \centerline{\textbf{附录}\quad #1}\smallskip } -\preto{\@enddocumenthook}{\printproblems\my@stop@reverse} +\preto{\@enddocumenthook}{\printproblems\my@stop@random} \newcommand\ignorepars{\@ifnextchar\par{\expandafter\ignorepars\@gobble}{}} -\newenvironment{problemreal}{% - \stepcounter{problem}\setcounter{choice}{0}\setcounter{step}{0}% - \textbf{\textsf{{\color{blue}\arabic{problem}}.}}\;\,\ignorespaces -}{\par} +% 局部定义,仅在当前题目内有效 +\define@key{jnuexam@problem}{points}[-1]{\def\my@problem@points{#1}} +\define@key{jnuexam@problem}{level}[]{\def\my@problem@level{#1}} +\define@key{jnuexam@problem}{year}[]{\def\my@problem@year{#1}} + +\newcommand{\problempointstext}[1]{(#1 分)} + +\newcommand\my@hook@exec@other@keys{} + +\newcommand{\execute@problem@keys}[1]{% + \setkeys{jnuexam@problem}{#1}% + \my@hook@exec@other@keys + \ifdefvoid{\my@problem@points}{}{\problempointstext{\my@problem@points}}% +} + +\newenvironment{problemreal}[1][]{% + \stepcounter{problem}\setcounter{choice}{0}% + \ifresetnumber + \ifonlyoneproblem + \renewcommand{\hangtext}{\qquad}% + \else + \renewcommand{\hangtext}{\textbf{\textsf{\textcolor{problem number}{\arabic{problem}}.}}\;\,}% + \fi + \else + \setcounter{problemreal}{\value{totalproblems}+\value{problem}}% + \renewcommand{\hangtext}{\textbf{\textsf{\textcolor{problem number}{\arabic{problemreal}}.}}\;\,}% + \fi + \settowidth{\hanglength}{\hangtext}% + \description[leftmargin=\hanglength,labelwidth=0pt,labelsep=0pt,topsep=0pt,parsep=0pt] + \item[\hangtext]\execute@problem@keys{#1}% +}{\enddescription} \newenvironment{solutionreal}{% - \setcounter{step}{0}% - \textbf{\textsf{{\color{blue}\solutionname}.}}\;\,\ignorepars -}{\par} + \renewcommand{\hangtext}{\textbf{\textsf{\textcolor{solution name}{\solutionname}.}}\;\,}% + \settowidth{\hanglength}{\hangtext}% + \description[leftmargin=\hanglength,labelwidth=0pt,labelsep=0pt,topsep=0pt,parsep=0pt] + \item[\hangtext] +}{\enddescription} \let \oldnewpage = \newpage \let \oldvfill = \vfill @@ -296,42 +576,45 @@ \let \oldmedskip = \medskip \let \oldbigskip = \bigskip -\ifreverse +\ifrandom + \newcommand\my@appto@problems{% + \xappto\allproblems{\expandonce\lastproblem}% + }% \NewEnviron{problem}{% - \xdef\allproblems{% - \unexpanded\expandafter{\lastproblem}% - \unexpanded\expandafter{\allproblems}% - }% - \xdef\lastproblem{% + \stepcounter{problem}% + \my@appto@problems + \csxdef{my@problem@a@\the\value{problem}}{% \unexpanded{\begin{problemreal}}% \unexpanded\expandafter{\BODY}% \unexpanded{\end{problemreal}}% }% + \csxdef{my@problem@b@\the\value{problem}}{% + \expandonce{\csname my@problem@a@\the\value{problem}\endcsname}% + }% + \xdef\lastproblem{% + \expandonce{\csname my@problem@b@\the\value{problem}\endcsname}% + }% } \NewEnviron{solution}{% - \xdef\lastproblem{% - \unexpanded\expandafter{\lastproblem}% + \csxappto{my@problem@a@\the\value{problem}}{% \unexpanded{\begin{solutionreal}}% - \unexpanded\expandafter{\BODY}% + \expandonce{\BODY}% \unexpanded{\end{solutionreal}}% }% } - \renewcommand{\newpage}{\xdef\lastproblem{\noexpand\oldnewpage\unexpanded\expandafter{\lastproblem}}} - \renewcommand{\vfill}{\xdef\lastproblem{\unexpanded\expandafter{\lastproblem\oldvfill}}} - \renewcommand{\smallskip}{\xdef\lastproblem{\unexpanded\expandafter{\lastproblem\oldsmallskip}}} - \renewcommand{\medskip}{\xdef\lastproblem{\unexpanded\expandafter{\lastproblem\oldmedskip}}} - \renewcommand{\bigskip}{\xdef\lastproblem{\unexpanded\expandafter{\lastproblem\oldbigskip}}} - \let \newpagea = \relax - \let \newpageb = \newpage + \renewcommand{\newpage}{\gappto\lastproblem{\oldnewpage}} + \renewcommand{\vfill}{\csgappto{my@problem@a@\the\value{problem}}{\oldvfill}} + \renewcommand{\smallskip}{\csgappto{my@problem@a@\the\value{problem}}{\oldsmallskip}} + \renewcommand{\medskip}{\csgappto{my@problem@a@\the\value{problem}}{\oldmedskip}} + \renewcommand{\bigskip}{\csgappto{my@problem@a@\the\value{problem}}{\oldbigskip}} \else - \newenvironment{problem}{\problemreal}{\endproblemreal} - \newenvironment{solution}{\solutionreal}{\endsolutionreal} - \let \newpagea = \newpage - \let \newpageb = \relax + \newenvironment{problem}[1][]{\problemreal[#1]}{\endproblemreal} + %\newenvironment{solution}{\solutionreal}{\endsolutionreal} + \NewEnviron{solution}{\begin{solutionreal}\BODY\end{solutionreal}} \fi -\newcommand{\my@stop@reverse}{% - \ifreverse +\newcommand{\my@stop@random}{% + \ifrandom \renewenvironment{problem}{\problemreal}{\endproblemreal}% \renewenvironment{solution}{\solutionreal}{\endsolutionreal}% \let \newpage = \oldnewpage @@ -416,23 +699,34 @@ %% --------------------------------------------------------------------------- %% 答案切换命令 \answer -%% 判断命令 \true 和 \false +%% 判断命令 \tickin 和 \tickout %% 填空命令 \fillin 和 \fillout %% 选择命令 \pickin 和 \pickout %% --------------------------------------------------------------------------- \newcommand{\answer}[1]{\ifanswer#1\else\phantom{#1}\fi} -\newcommand{\cdotfill}{\leavevmode\xleaders\hbox to 0.5em{\hss$\cdot$\hss}\hfill\kern0pt\relax} -\newcommand{\true}{\unskip\nobreak\cdotfill(\makebox[1.5em]{\color{blue}\answer{$\checkmark$}})} -\newcommand{\false}{\unskip\nobreak\cdotfill(\makebox[1.5em]{\color{blue}\answer{\sffamily x}})} +\newcommand*{\cdotfill}{\leavevmode\xleaders\hbox to 0.5em{\hss$\cdot$\hss}\hfill\kern0pt\relax} + +\newcommand*{\tick@box}[1]{[\makebox[1.5em]{\color{blue}\answer{#1}}]} +\newcommand*{\tick@text@t}{$\checkmark$} +\newcommand*{\tick@text@f}{{\large$\times$}} +\newcommand*{\tick@text@T}{\sffamily T} +\newcommand*{\tick@text@F}{\sffamily F} +\newcommand*{\tickin}[1]{\tick@box{\csname tick@text@#1\endcsname}} +\newcommand*{\tickout}[1]{\unskip\nobreak\cdotfill\tick@box{\csname tick@text@#1\endcsname}} +% 过时命令,不要再使用 +%\newcommand*{\true}{\tickout{t}} +%\newcommand*{\false}{\tickout{f}} + +\newcommand*{\ulinefill}[1]{\xleaders\hbox{\underline{\vphantom{#1}\kern1pt}}\hfill\kern0pt} +\newcommand*{\minwidthbox}[2]{\makebox[{\ifdim#1<\width\width\else#1\fi}]{#2}} -\newcommand{\ulinefill}[1]{\xleaders\hbox{\underline{\vphantom{#1}\kern1pt}}\hfill\kern0pt} -\newcommand{\fillout}[1]{\allowbreak\hbox{}\nobreak\ulinefill{#1}\underline{\color{blue}\answer{#1}}\ulinefill{#1}} -\newcommand{\fillin}[1]{\underline{\hspace{1em}\color{blue}\answer{#1}\hspace{1em}}} +\newcommand*{\fillout}[1]{\allowbreak\hbox{}\nobreak\ulinefill{#1}\underline{\color{blue}\answer{#1}}\ulinefill{#1}} +\newcommand*{\fillin}[1]{\underline{\hspace{1em}\color{blue}\minwidthbox{2em}{\answer{#1}}\hspace{1em}}} -\newcommand{\pickout}[1]{\unskip\nobreak\cdotfill(\makebox[1.5em]{\color{blue}\answer{#1}})} -\newcommand{\pickin}[1]{\unskip\nobreak\hspace{0.3em}(\makebox[1.5em]{\color{blue}\answer{#1}})\hspace{0.3em}\ignorespaces} +\newcommand*{\pickout}[1]{\unskip\nobreak\cdotfill(\makebox[1.5em]{\color{blue}\answer{#1}})} +\newcommand*{\pickin}[1]{\unskip\nobreak\hspace{0.3em}(\makebox[1.5em]{\color{blue}\answer{#1}})\hspace{0.3em}\ignorespaces} %% --------------------------------------------------------------------------- %% 选择题四个选项排版环境,根据四个选项的长度自动排成一行、两行或四行 @@ -440,6 +734,7 @@ %% --------------------------------------------------------------------------- \newlength{\my@item@len} +\newlength{\my@label@len} \newcommand\my@item@temp{% \unskip\cr\stepcounter{choice}(\Alph{choice})\ % @@ -449,7 +744,13 @@ \stepcounter{choice}(\Alph{choice})\ \ignorespaces } \newcommand\my@item@par{% - \par\stepcounter{choice}(\Alph{choice})\ \ignorespaces + \stepcounter{choice}% + \def\my@label@text{(\Alph{choice})\ }% + \settowidth{\my@label@len}{\my@label@text}% + \par \parshape 2 \hanglength \linewidth + \dimexpr\hanglength + \my@label@len\relax + \dimexpr\linewidth - \my@label@len\relax + \my@label@text\ignorespaces } \NewEnviron{abcd}{ @@ -514,13 +815,14 @@ } %% --------------------------------------------------------------------------- -%% 解答题步骤命令 \step +%% 设定有序列表使用悬挂缩进,并指定前两级有序列表的标签格式 +%% 标签宽度按最宽者自动设定,左边距自动计算,竖直空白全部去掉 +%% 最后的 itemjoin 设定行内有序列表 enumerate* 两项之间的空白 %% --------------------------------------------------------------------------- -\newcommand{\step}{% - \stepcounter{step}% - \textsf{(\arabic{step})}\;\,% -} +\setlist[enumerate]{labelindent=0pt,labelsep=0.2em,itemindent=0pt,leftmargin=*,nosep,itemjoin=\quad} +\setlist[enumerate,1]{label=(\arabic*)} +\setlist[enumerate,2]{label=(\alph*),widest*=1} %% --------------------------------------------------------------------------- %% 自由对齐命令 \tabpoint, \tabto, \tableft @@ -593,48 +895,31 @@ \let \< = \tableft %% --------------------------------------------------------------------------- -%% 评分命令 \score +%% 评分命令 \points %% --------------------------------------------------------------------------- \PassOptionsToPackage{tbtags}{amsmath} \RequirePackage{amsmath} -\newcommand{\myscore}[1]{\textcolor{red}{#1\kern0.15em 分}} +\newcommand{\mypoints}[1]{\textcolor{red}{#1\kern0.15em 分}} -\newcommand{\scoretext}[1]{\mbox{}\nobreak\hfill$\cdots\cdots$\myscore{#1}\par\noindent\ignorespaces} -\newcommand{\scoreeqno}[1]{\eqno{\cdots\cdots\text{\myscore{#1}}}} -\newcommand{\scoretag}[1]{\tag*{$\cdots\cdots$\myscore{#1}}} +\newcommand{\pointstext}[1]{\mbox{}\nobreak\hfill$\cdots\cdots$\mypoints{#1}\par\noindent\ignorespaces} +\newcommand{\pointseqno}[1]{\eqno{\cdots\cdots\text{\mypoints{#1}}}} +\newcommand{\pointstag}[1]{\tag*{$\cdots\cdots$\mypoints{#1}}} -\newrobustcmd{\score}[1]{% +\newrobustcmd{\points}[1]{% \ifbool{mmode}{% - \ifdefstrequal{\tag}{\dft@tag}{\scoreeqno{#1}}{\scoretag{#1}}% + \ifdefstrequal{\tag}{\dft@tag}{\pointseqno{#1}}{\pointstag{#1}}% }{% - \scoretext{#1}% + \pointstext{#1}% }% } - -%% --------------------------------------------------------------------------- -%% 文档选项 display 将全部公式都设为展示公式 -%% 命令 \display 将当前环境的公式都设为展示公式 -%% --------------------------------------------------------------------------- - -\newcommand{\display}{\everymath\expandafter{\the\everymath\displaystyle}} -\ifbool{display}{ - \RequirePackage[math]{cellspace} - \setlength\cellspacetoplimit{2pt} - \setlength\cellspacebottomlimit{2pt} - \addparagraphcolumntypes{X} - % Fix cellspace bug before version 1.7 - % See https://tex.stackexchange.com/a/385581 - \@ifpackagelater{cellspace}{2017/08/12}{}{ - \patchcmd{\@endpbox}{\color@endgroup}{\expandafter\color@endgroup}{}{} - } - \display -}{} +%\let\score=\points % \score 命令已经废弃,不要再使用 %% --------------------------------------------------------------------------- %% 载入个人定制文件 jnuexam.cfg %% 中文字体切换选项 sourcehan +%% 实心句号替换选项 solidot %% --------------------------------------------------------------------------- \InputIfFileExists{jnuexam.cfg}{}{} @@ -647,50 +932,149 @@ %\setCJKsansfont{思源黑体} } -\ifbool{sourcehan}{ - % https://sourceforge.net/p/xetex/code/ci/master/tree/source/texk/web2c/xetexdir/NEWS - \ifbool{XeTeX}{ % TeXLive 2015 - \ifdimless{\the\XeTeXversion\XeTeXrevision pt}{0.99992pt}{}{\my@set@sourcehan} - }{} - \ifbool{LuaTeX}{\my@set@sourcehan}{} -}{} +\AtBeginDocument{% + \ifbool{sourcehan}{% + % https://sourceforge.net/p/xetex/code/ci/master/tree/source/texk/web2c/xetexdir/NEWS + \ifbool{XeTeX}{% TeXLive 2015 + \ifdimless{\the\XeTeXversion\XeTeXrevision pt}{0.99992pt}{}{\my@set@sourcehan}% + }{}% + \ifbool{LuaTeX}{\my@set@sourcehan}{}% + }{}% +} + +%% 这里不能用 \ifbool,因为涉及到 catcode 的改变 +\ifsolidot + \ifXeTeX + \catcode`。=\active\def。{.}% + \else\ifLuaTeX + \catcode`。=\active\def。{.}% + \fi + \fi +\fi %% --------------------------------------------------------------------------- -%% 试卷题库选项 collection +%% 在 tabular 和 array 等表格环境中添加列间距 +%% 避免单元格里出现的分式太过接近上面和下面行 %% --------------------------------------------------------------------------- -\ifcollection - \RequirePackage{hyperref} - \hypersetup{ - pdfstartview={FitH}, - bookmarksnumbered=true, - unicode=true, - hidelinks=true - %colorlinks=true, - %linkcolor=black - } - \appto{\endproblem}{\medskip} - \appto{\endsolution}{\medskip} - \preto{\problem}{\ifnum\value{problem}=9 \setcounter{problem}{-1}\fi} - \pagestyle{plain} - \let\chapter=\part - \@addtoreset{section}{part} - \RequirePackage{xkeyval} - \define@key{jnuexam}{level}[]{\def\my@collection@level{#1}} - \define@key{jnuexam}{year}[]{\def\my@collection@year{#1}} - \define@key{jnuexam}{name}[]{\def\my@collection@name{#1}} - \newcommand{\info}[1]{% - \setkeys{jnuexam}{level,year,name,#1}% 重置之前的数据 - \my@collection@info@do +\newcommand{\my@do@cellspace}{% + \RequirePackage[math]{cellspace}% + \setlength\cellspacetoplimit{2pt}% + \setlength\cellspacebottomlimit{2pt}% + \addparagraphcolumntypes{X}% + \newcolumntype{0}[1]{>{\bcolumn ##1\@nil}##1<{\ecolumn}}% + \newcolumntype{5}[1]{>{$}0{##1}<{$}}% + % Fix cellspace bug before version 1.7 + % See https://tex.stackexchange.com/a/385581 + \@ifpackagelater{cellspace}{2017/08/12}{}{% + \patchcmd{\@endpbox}{\color@endgroup}{\expandafter\color@endgroup}{}{}% + }% +} + +\AtBeginDocument{% + \ifcellspace \my@do@cellspace \fi +} + +%% --------------------------------------------------------------------------- +%% 统一行间公式和行内公式的巨算符和分式的尺寸 +%% 利用开头的 medmath 选项可以启用此部分设定 +%% --------------------------------------------------------------------------- + +\newcommand{\my@do@medmath}{% + \RequirePackage[mediummath]{nccmath}% + %% 补充 \oiint 命令的调整 + \ifdef{\oiint}{% + \let\NCC@op@oiint=\oiint + \DeclareRobustCommand{\oiintop}{\mathop{\medmath{\NCC@op@oiint}}}% + \def\oiint{\DOTSI\NCC@op@prepare{\oiintop}}% + }{}% + %% 设定 nccmath 的积分号校正尺寸 + %% 后面已经改用相对尺寸,不再需要 + %\ifamsfonts + % \medintcorr{0.5em} + %\else + % \medintcorr{0.3em} + %\fi + %% 使用 nccmath 宏包后,cases 环境包含定积分时将无法编译,这里重新定义此环境 + %% 注意相比 amsmath 的原始定义,我们这里将 \quad 从两列之间移动到第二列最前面 + %% 这是因为,我们常将 cases 用于只有一列的方程组,这样处理末尾不会有多余空白 + \ifbool{cellspace}{% + \renewenvironment{cases}{% + \left\{\linespread{1.0}\selectfont\def\arraystretch{1.2}% + \begin{array}{@{}5l@{}>{\quad}5l@{}}% + }{% + \end{array}\right.% + }% + }{% + \renewenvironment{cases}{% + \left\{\linespread{1.0}\selectfont\def\arraystretch{1.2}% + \begin{array}{@{}l@{}>{\quad}l@{}}% + }{% + \end{array}\right.% + }% } - \newcommand{\my@collection@info@do}{% - \bigskip\hrule\nopagebreak\vspace{0.4em}\nopagebreak - \ifdefempty{\my@collection@level}{}{Level = \my@collection@level\quad}% - \ifdefempty{\my@collection@year}{}{Year = \my@collection@year\quad}% - \ifdefempty{\my@collection@name}{}{Name = \my@collection@name\quad}% - \nopagebreak\vspace{0.4em}\nopagebreak\hrule\medskip + %% 当 minipage 或 \parbox 仅包含行间公式时,盒子的右边距丢失,这里修正它 + %% 其他类似问题的描述见 http://tex.stackexchange.com/q/22170 + \let\start@gather=\NCC@startgather + \let\start@align=\NCC@startalign + \let\start@multline=\NCC@startmultline + \let\mathdisplay=\NCC@startdisplay +} + +\newcommand{\my@do@medmath@fix}{% + %% 修正在角标处的非积分巨算符尺寸 + %% 参考了 scalerel 宏包对数学样式的保存方法 + % 非角标巨算符保持为 \displaystyle 巨算符的 80% 大小 + % 一级角标巨算符修改为 \textstyle 巨算符的 80% 大小 + % 二级角标巨算符修改为 \scriptstyle 巨算符的 80% 大小 + \def\@my@style@D{\displaystyle}% + \def\@my@style@T{\displaystyle}% + \def\@my@style@S{\textstyle}% + \def\@my@style@s{\scriptstyle}% + \def\my@style@saved{\csname @my@style@\@my@style@switch\endcsname}% + \newcommand{\my@style@this}[1]{% + \mathchoice{\def\@my@style@switch{D}##1}{\def\@my@style@switch{T}##1} + {\def\@my@style@switch{S}##1}{\def\@my@style@switch{s}##1}% + }% + \DeclareRobustCommand*\medmath[1]{\NCC@select@msize + \mathord{\my@style@this{\raise\@tempdima\hbox{\NCC@prepare@msize$\my@style@saved ##1$}}}% } -\fi + %% 修正在角标处的积分算符尺寸和上下限位置 + \newlength{\@my@em}% + \setlength{\@my@em}{1em}% + \ifamsfonts + \medintcorr{0.5\@my@em}% + \else + \medintcorr{0.3\@my@em}% + \fi + \newcommand{\my@style@unit}[1]{% + \mathchoice{\setlength{\@my@em}{1em}##1}{\setlength{\@my@em}{1em}##1} + {\setlength{\@my@em}{0.5em}##1}{\setlength{\@my@em}{0.3em}##1}% + }% + \let\my@saved@op@printm=\NCC@op@printm + \def\NCC@op@printm{\my@style@unit{\my@saved@op@printm}}% + %% 修正在角标位置的分式和嵌套分式 + %% 总是使用当前样式尺寸来排版分式的分子和分母 + \newcommand{\my@larger@frac}[2]{% + \mathchoice{\genfrac{}{}{}{0}{##1}{##2}}{\genfrac{}{}{}{0}{##1}{##2}}% + {\genfrac{}{}{}{1}{##1}{##2}}{\genfrac{}{}{}{2}{##1}{##2}}% + }% + \DeclareRobustCommand{\frac}[2]{% + \mathchoice{\mfrac{##1}{##2}}{\mfrac{##1}{##2}}% + {\my@larger@frac{##1}{##2}}{\my@larger@frac{##1}{##2}}% + }% + \patchcmd{\NCC@prepare@msize}{% + \def\frac{\protect\NCC@innerfrac{}}% + }{% + \let\frac=\my@larger@frac + }{}{}% +} + +\AtBeginDocument{% + \ifmedmath + \my@do@medmath \my@do@medmath@fix + \fi +} %% --------------------------------------------------------------------------- %% 载入常用宏包,定义常用命令 @@ -713,26 +1097,55 @@ \xeCJKsetcharclass{"2460}{"24FF}{1} % 带圈数字字母,括号数字字母,带点数字等 }{} -\RequirePackage{CJKfntef} \RequirePackage{multirow} -\RequirePackage{diagbox} \RequirePackage{tabu} +\RequirePackage{diagbox} +%% 修正 \diagbox 在 array 环境中使用的问题 +\newrobustcmd{\diagboxtwo}[3][]{% + \ifbool{mmode}{% + \hbox{\let\tabcolsep=\arraycolsep\diagbox[#1]{$#2$}{$#3$}}% + }{% + \diagbox[#1]{#2}{#3}% + } +} +\newrobustcmd{\diagboxthree}[4][]{% + \ifbool{mmode}{% + \hbox{\let\tabcolsep=\arraycolsep\diagbox[#1]{$#2$}{$#3$}{$#4$}}% + }{% + \diagbox[#1]{#2}{#3}{#4}% + } +} + +\RequirePackage{mathtools} % \mathllap 命令,pmatrix* 环境等 \RequirePackage{extarrows} \RequirePackage{relsize} \newcommand{\Int}{\mathop{\mathlarger{\int}}} +\AtBeginDocument{% + \let\my@saved@lim=\lim \def\lim{\my@saved@lim\limits}% + \let\my@saved@sum=\sum \def\sum{\my@saved@sum\limits}% + \let\my@saved@prod=\prod \def\prod{\my@saved@prod\limits}% +} +%\newcommand{\limit}{\lim\limits} % 废弃命令,不要再使用 + \newcommand{\e}{\mathrm{e}} -\newcommand{\limit}{\lim\limits} \newcommand{\R}{\mathbb{R}} +\DeclareMathOperator{\arccot}{arccot} \DeclareMathOperator{\Corr}{\rho} \DeclareMathOperator{\Cov}{Cov} +\DeclareMathOperator{\diag}{diag} \DeclareMathOperator{\grad}{grad} \DeclareMathOperator{\Prj}{Prj} +\DeclareMathOperator{\tr}{tr} \DeclareMathOperator{\Var}{Var} +\DeclareMathOperator{\diver}{div} +\let\division=\div +\let\div=\diver + \newcommand{\diff}{\mathop{}\!\mathrm{d}} \newcommand{\dx}{\diff x} \newcommand{\dy}{\diff y} @@ -750,6 +1163,23 @@ \renewrobustcmd{\d}{\ifbool{mmode}{\diff}{\oldd}}% } +\let\pd=\partial +\newcommand{\pdf}{\pd f} +\newcommand{\pdg}{\pd g} +\newcommand{\pdh}{\pd h} +\newcommand{\pdl}{\pd l} +\newcommand{\pdn}{\pd n} +\newcommand{\pdu}{\pd u} +\newcommand{\pdv}{\pd v} +\newcommand{\pdx}{\pd x} +\newcommand{\pdy}{\pd y} +\newcommand{\pdz}{\pd z} +\newcommand{\pdF}{\pd F} +\newcommand{\pdL}{\pd L} +\newcommand{\pdP}{\pd P} +\newcommand{\pdQ}{\pd Q} +\newcommand{\pdR}{\pd R} + % from mathabx package \DeclareFontFamily{U}{mathx}{\hyphenchar\font45} \DeclareFontShape{U}{mathx}{m}{n}{<-> mathx10}{} @@ -778,7 +1208,44 @@ \def\T{\mathrm{T}\kern-.5pt} -\newrobustcmd{\wfrac}[3][2pt]{% - {\begingroup\hspace{#1}#2\hspace{#1}\endgroup\over\hspace{#1}#3\hspace{#1}}% +% 分数线长一点的分数,\wfrac[2pt]{x}{y} 表示左右加 2pt +% 和前面的 medmath 一样,将代码放在 \AtBeginDocument 里 +\AtBeginDocument{% + \newrobustcmd{\wfrac}[3][2pt]{% + \frac{\hspace{#1}#2\hspace{#1}}{\hspace{#1}#3\hspace{#1}}% + }% + \newrobustcmd{\wdfrac}[3][2pt]{% + \dfrac{\hspace{#1}#2\hspace{#1}}{\hspace{#1}#3\hspace{#1}}% + }% + \newrobustcmd{\wtfrac}[3][2pt]{% + \tfrac{\hspace{#1}#2\hspace{#1}}{\hspace{#1}#3\hspace{#1}}% + }% } +% 使用 stix font 中的 white arrows +\ifxetex + %\IfFileExists{STIX-Regular.otf}{% 在 TeXLive 中无效 + \IfFileExists{stix.sty}{% + \newfontfamily{\mystix}{STIX} % stix v1.1 + }{% + \newfontfamily{\mystix}{STIXGeneral} % stix v1.0 + } + \newrobustcmd\leftwhitearrow{% + \mathrel{\text{\normalfont\mystix\symbol{"21E6}}}% + } + \newrobustcmd\upwhitearrow{% + \mathrel{\text{\normalfont\mystix\symbol{"21E7}}}% + } + \newrobustcmd\rightwhitearrow{% + \mathrel{\text{\normalfont\mystix\symbol{"21E8}}}% + } + \newrobustcmd\downwhitearrow{% + \mathrel{\text{\normalfont\mystix\symbol{"21E9}}}% + } +\else + \let \leftwhitearrow = \Leftarrow + \let \rightwhitearrow = \Rightarrow + \let \upwhitearrow = \Uparrow + \let \downwhitearrow = \Downarrow +\fi + |