diff options
author | Karl Berry <karl@freefriends.org> | 2023-12-11 21:08:45 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2023-12-11 21:08:45 +0000 |
commit | 607ed556f1f9c4e573ade023f3ec7d4d66799db8 (patch) | |
tree | 8bfaa9823b0c4865b867d626f947533a2df92a3c /Master/texmf-dist/tex/latex/jnuexam | |
parent | c4c08d41114a16394510c0cf62dfd55eaf3581d7 (diff) |
jnuexam (11dec23)
git-svn-id: svn://tug.org/texlive/trunk@69089 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/jnuexam')
-rw-r--r-- | Master/texmf-dist/tex/latex/jnuexam/jnuexam.cls | 853 |
1 files changed, 660 insertions, 193 deletions
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 + |