% -*- coding: utf-8 -*-
% ----------------------------------------------------------------------------
% Author:  Jianrui Lyu <tolvjr@163.com>
% Website: https://lvjr.bitbucket.io/jnuexam.html
% License: Creative Commons Attribution-ShareAlike 4.0 International License
% ----------------------------------------------------------------------------

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{jnuexam}[2018/06/29 v0.2 An exam class for Jinan University]

\newif\ifsidebyside \sidebysidefalse % 是否 A3 纸张
\newif\ifreverse    \reversefalse    % 是否逆序出题
\newif\ifanswer     \answertrue      % 是否显示答案

\DeclareOption{a3paper}{\sidebysidetrue}
\DeclareOption{reverse}{\reversetrue}
\DeclareOption{noanswer}{\answerfalse}

\DeclareOption*{\PassOptionsToClass{\CurrentOption}{ctexart}} %其它选项

\ProcessOptions %不可省略

% 四号    小四号    五号      小五号
% 14bp    12bp      10.5bp    9bp
\LoadClass[cs4size,UTF8,noindent]{ctexart}

\ifsidebyside
  \RequirePackage[a3paper,landscape,twocolumn,columnsep=40mm,left=50mm,right=30mm,top=25mm,bottom=25mm]{geometry}
\else
  \RequirePackage[a4paper,left=30mm,right=30mm,top=25mm,bottom=25mm]{geometry}
\fi

\newcommand{\mifengxian}{%
\def\1{\\[50mm]}\def\2{\\[15mm]}%
\begin{tikzpicture}[remember picture,overlay,very thick,font=\large]
  \path (current page.south west) +(2cm,1cm)  coordinate (a1);
  \path (current page.north west) +(2cm,-1cm) coordinate (a2);
  \path (current page.south west) +(3cm,1cm)  coordinate (b1);
  \path (current page.north west) +(3cm,-1cm) coordinate (b2);
  \draw[dashed] (a1) -- node[left=1mm,text width=1em]{装\1订\1线}
     node[right=1mm,text width=1em]{学\2生\2答\2卷\2不\2要\2超\2过\2此\2线} (a2);
  \draw (b1) -- (b2);
\end{tikzpicture}}

\newcommand{\caogaozhi}{%
\begin{tikzpicture}[remember picture,overlay,font=\sffamily\fontsize{180pt}{180pt}\selectfont]
  \node[text=lightgray!40] at (current page.center) {草\quad 稿\quad 纸};
\end{tikzpicture}}

\RequirePackage{amsmath}
\RequirePackage{tabu}
\RequirePackage{multirow}
\RequirePackage{pifont}
\RequirePackage{lastpage}
\RequirePackage{fancyhdr}
\RequirePackage{xcolor}
\RequirePackage{comment}
\RequirePackage{environ}
\RequirePackage{etoolbox}
\RequirePackage{CJKfntef}

\ifsidebyside
  \RequirePackage{tikz}
  \RequirePackage{everypage}
  \AddEverypageHook{\mifengxian}
  % 在 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}}
  \RequirePackage{pdfpages}
  % 新版本 pdfpages 将 \includepdf 放在文档开头时会有命令未定义的错误
  % 见 https://tex.stackexchange.com/questions/352007/ieeetran-and-pdfpages
  \@ifundefined{@setmarks}{}{}
\fi

\setlength{\parindent}{0em}
\setlength{\lineskiplimit}{3pt}
\setlength{\lineskip}{3pt}

\newcommand{\niandu}{2016-2017}
\newcommand{\xueqi}{2}
\newcommand{\kecheng}{数学课程}
\newcommand{\zhuanye}{}  % 专业学分
\newcommand{\jiaoshi}{吕荐瑞}
\newcommand{\shijian}{}  % 考试日期
\newcommand{\bixiu}{1}   % 1 为必修，0 为选修
\newcommand{\bijuan}{1}  % 1 为闭卷，0 为开卷
\newcommand{\shijuan}{A} % A 或 B 或 C 卷
\newcommand{\neizhao}{1} % 1 打勾，0 不勾
\newcommand{\waizhao}{1} % 1 打勾，0 不勾

\newcommand{\underspace}[1]{\underline{\hspace{#1}}}
\newcommand{\underbox}[2]{\underline{\makebox[#1]{#2}}}

\newcommand{\ischeck}[1]{\ifnum#1>0\,\ding{51}\,\else\quad\fi}
\newcommand{\isquad}[1]{\ifnum#1=0\,\ding{51}\,\else\quad\fi}

\newcommand\my@temp@a{A}
\newcommand\my@temp@c{C}
\newcommand\my@empty{}

\newcommand{\head@table@a}{%
  \begin{tabular}{l}
    教学年度：\underbox{8em}{\niandu} 年度第 \underbox{3.5em}{\xueqi} 学期 \\
    课程名称：\underbox{17.5em}{\kecheng\ifx\zhuanye\my@empty\else\kern0pt(\zhuanye)\fi} \\
    授课教师：\underbox{17.5em}{\jiaoshi} \\
    考试时间：\underbox{17.5em}{\shijian} \\
  \end{tabular}
}

\newcommand{\head@table@b}{%
  \renewcommand{\arraystretch}{1}%
  \begin{tabular}{l}
    \textbf{课程类别} \\ 必修~[\ischeck{\bixiu}]\quad 选修~[\isquad{\bixiu}] \\
    \hline
    \textbf{考试方式} \\ 开卷~[\isquad{\bijuan}]\quad 闭卷~[\ischeck{\bijuan}] \\
    \hline
    \textbf{试卷类别}~(\,A, B, C\,)\\\relax [\,\shijuan\,]\hfill 共~\pageref{LastPage}~页
  \end{tabular}
}

\newcommand{\head@table@c}{%
  \begin{tabular}{l}
    \underspace{10em} 学院 \underspace{8em} 专业 \underspace{5.5em}~班~(级) \\[1em]
    姓名\underspace{8em} 学号 \underspace{10em}\hfill
    \bfseries 内招~[\ischeck{\neizhao}] 外招~[\ischeck{\waizhao}] %\\[0.8em]
  \end{tabular}
}

\newcommand{\makehead}{
  \thispagestyle{plain}
  \centerline{\LARGE\bfseries 暨\quad 南\quad 大\quad 学\quad 考\quad 试\quad 试\quad 卷}
  \vspace{2em}%
  \ifreverse
    \ifx\shijuan\my@temp@a\renewcommand{\shijuan}{B}\fi
    \ifx\shijuan\my@temp@c\renewcommand{\shijuan}{D}\fi
  \fi
  \noindent
  \begin{tabu}{|@{}X@{}|}
    \hline\renewcommand{\arraystretch}{1.5}%
    \begin{tabu}{@{}>{\bfseries}l@{}|@{}X@{}|@{}l@{}}
      \begin{tabular}{l}教\\ 师\\ 填\\ 写\end{tabular} & \head@table@a & \head@table@b
    \end{tabu}\\
    \hline\renewcommand{\arraystretch}{0.9}%
    \begin{tabu}{@{}>{\bfseries}l@{}|@{}X@{}}
      \begin{tabular}{l}考\\ 生\\ 填\\ 写\end{tabular} & \head@table@c
    \end{tabu}\\
    \hline
  \end{tabu}
  \vspace{1em}
  \noindent\begin{tabu}{|*{8}{X[c]|}}
    \hline
    \bfseries{题 号} & 一 & 二 & 三 & 四 & 五 & 六 & 总 分\\
    \hline
    \bfseries{得 分} &  &  &  &  &  &  & \\
    \hline
  \end{tabu}
}

\newcommand{\my@columnbox}[1]{\makebox[\columnwidth]{#1}}
\newcommand{\my@headleft}{暨南大学\kern-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}~页}

\fancypagestyle{plain}{
  \renewcommand{\headrulewidth}{0pt}%
  \fancyhf{}
  \ifsidebyside
    \rhead{\small\underline{\my@columnbox{\my@headtext\strut}}}
    \lfoot{\small\my@columnbox{\my@foottext}}
    \rfoot{\small\my@columnbox{\stepcounter{page}\my@foottext}}
  \else
    \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}}
\else
  \lhead{\small\my@headleft}
  \rhead{\small\my@headright}
  \cfoot{\small\my@foottext}
\fi

\xdef\allproblems{}
\xdef\lastproblem{}
\newcounter{problem}
\newcounter{choice}

\newcommand{\printproblems}{\ifreverse\lastproblem\allproblems\fi\xdef\allproblems{}\xdef\lastproblem{}}

\newcommand{\makepart}[2]{%
    \printproblems
    \setcounter{problem}{0}%
    \stepcounter{section}%
    \vspace{1em}%
    \noindent\begin{tabu}{|X[c]|X[c]|X[6]}
      \cline{1-2}
      得分 & 评阅人 & \textbf{\Chinese{section}、#1}\\
      \cline{1-2}
      &  & (#2) \\
      \cline{1-2}
    \end{tabu}
    \vspace{1em}
}

\newcommand{\makedata}[1]{%
  \printproblems\my@stop@reverse
  \centerline{\textbf{附录}\quad #1}\smallskip
}

\preto{\@enddocumenthook}{\printproblems\my@stop@reverse}

\newcommand{\answer}[1]{\ifanswer#1\else\phantom{#1}\fi}

\newcommand{\ulinefill}[1]{\xleaders\hbox{\underline{\vphantom{#1}\kern1pt}}\hfill\kern0pt}
\newcommand{\fillout}[1]{\ulinefill{#1}\underline{\color{blue}\answer{#1}}\ulinefill{#1}}
\newcommand{\fillin}[1]{\underline{\hspace{1em}\color{blue}\answer{#1}\hspace{1em}}}

\newcommand{\pickout}[1]{\hfill(\makebox[1.5em]{\color{blue}\answer{#1}})}
\newcommand{\pickin}[1]{(\makebox[1.5em]{\color{blue}\answer{#1}})}

\newcommand{\my@item}{\ifnum\value{choice}=0\par\fi\stepcounter{choice}}
\newcommand{\fullitem}[1]{\my@item\makebox[\linewidth][l]{(\Alph{choice})\ #1}\break\ignorespaces}
\newcommand{\halfitem}[1]{\my@item\makebox[0.502\linewidth][l]{(\Alph{choice})\ #1}\allowbreak\ignorespaces}
\newcommand{\quaditem}[1]{\my@item\makebox[0.251\linewidth][l]{(\Alph{choice})\ #1}\allowbreak\ignorespaces}

\newcommand\ignorepars{\@ifnextchar\par{\expandafter\ignorepars\@gobble}{}}

\newenvironment{problemreal}{%
  \stepcounter{problem}\setcounter{choice}{0}%
  \textsf{\color{blue}\arabic{problem}}.\;\,\ignorespaces
}{\par}
\newenvironment{solutionreal}{\textsf{\color{blue}解答}\quad\ignorepars}{\par}
\newenvironment{proofreal}{\textsf{\color{blue}证明}\quad\ignorepars}{\par}

\let \oldnewpage   = \newpage
\let \oldvfill     = \vfill
\let \oldsmallskip = \smallskip
\let \oldmedskip   = \medskip
\let \oldbigskip   = \bigskip

\ifreverse
  \NewEnviron{problem}{%
    \xdef\allproblems{%
      \unexpanded\expandafter{\lastproblem}%
      \unexpanded\expandafter{\allproblems}%
    }%
    \xdef\lastproblem{%
      \unexpanded{\begin{problemreal}}%
      \unexpanded\expandafter{\BODY}%
      \unexpanded{\end{problemreal}}%
    }%
  }
  \NewEnviron{solution}{%
    \xdef\lastproblem{%
      \unexpanded\expandafter{\lastproblem}%
      \unexpanded{\begin{solutionreal}}%
      \unexpanded\expandafter{\BODY}%
      \unexpanded{\end{solutionreal}}%
    }%
  }
  \NewEnviron{proof}{%
    \xdef\lastproblem{%
      \unexpanded\expandafter{\lastproblem}%
      \unexpanded{\begin{proofreal}}%
      \unexpanded\expandafter{\BODY}%
      \unexpanded{\end{proofreal}}%
    }%
  }
  \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
\else
  \newenvironment{problem}{\problemreal}{\endproblemreal}
  \newenvironment{solution}{\solutionreal}{\endsolutionreal}
  \newenvironment{proof}{\proofreal}{\endproofreal}
  \let \newpagea = \newpage
  \let \newpageb = \relax
\fi

\newcommand{\my@stop@reverse}{%
  \ifreverse
    \renewenvironment{problem}{\problemreal}{\endproblemreal}%
    \renewenvironment{solution}{\solutionreal}{\endsolutionreal}%
    \renewenvironment{proof}{\proofreal}{\endproofreal}%
    \let \newpage   = \oldnewpage
    \let \vfill     = \oldvfill
    \let \smallskip = \oldsmallskip
    \let \medskip   = \oldmedskip
    \let \bigskip   = \oldbigskip
  \fi
}

\def\CommentCutFile{\jobname.cut}

\AtBeginDocument{%
  \ifanswer\else
    \excludecomment{solution}
    \excludecomment{proof}
  \fi
}

