├── BHCexam.cfg ├── BHCexam.cls ├── README.md ├── examtest.m └── 题库.xlsx /BHCexam.cfg: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `BHCexam.cfg', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% BHCexam.dtx (with options: `cfg') 8 | %% 9 | %% This is a generated file. 10 | %% 11 | %% Copyright (C) 2014 by Charles Bao 12 | %% 13 | %% This file was generated from file(s) of the BHCexam package project. 14 | %% ---------------------------------------------------------------------- 15 | %% 16 | %% It may be distributed and/or modified under the 17 | %% conditions of the LaTeX Project Public License, either version 1.2 18 | %% of this license or (at your option) any later version. 19 | %% The latest version of this license is in 20 | %% http://www.latex-project.org/lppl.txt 21 | %% and version 1.2 or later is part of all distributions of LaTeX 22 | %% version 1999/12/01 or later. 23 | %% 24 | %% This is the configuration file of the BHCexam package with LaTeX2e. 25 | %% 26 | \ProvidesFile{BHCexam.cfg} 27 | [2015/10/10 v0.4 BHCexam 28 | configuration file] 29 | 30 | 31 | 32 | \def\@biaoti{2011年全国普通高等学校招生统一考试(上海卷)} 33 | \def\@fubiaoti{数学(理科)} 34 | \def\@zongfen{150} 35 | \def\@shijian{120} 36 | \def\@tiankong@zongfen{56} 37 | \def\@tiankong@tishu{14} 38 | \def\@tiankong@fen{4} 39 | \def\@xuanze@zongfen{16} 40 | \def\@xuanze@tishu{4} 41 | \def\@xuanze@fen{4} 42 | \def\@jianda@zongfen{78} 43 | \def\@jianda@tishu{5} 44 | \endinput 45 | %% 46 | %% End of file `BHCexam.cfg'. 47 | -------------------------------------------------------------------------------- /BHCexam.cls: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `BHCexam.cls', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% BHCexam.dtx (with options: `cls') 8 | %% 9 | %% This is a generated file. 10 | %% 11 | %% Copyright (C) 2011 by Charles Bao 12 | %% 13 | %% This file was generated from file(s) of the BHCexam package project. 14 | %% ---------------------------------------------------------------------- 15 | %% 16 | %% It may be distributed and/or modified under the 17 | %% conditions of the LaTeX Project Public License, either version 1.2 18 | %% of this license or (at your option) any later version. 19 | %% The latest version of this license is in 20 | %% http://www.latex-project.org/lppl.txt 21 | %% and version 1.2 or later is part of all distributions of LaTeX 22 | %% version 1999/12/01 or later. 23 | %% 24 | %% This file may only be distributed together with a copy of original 25 | %% source files. You may however distribute original source files 26 | %% without such generated files. Copying of this file is authorized 27 | %% only if either: 28 | %% (1) you make absolutely no changes to your copy, including name; OR 29 | %% (2) if you do make changes, you first rename it to some other name. 30 | %% 31 | %% To produce the documentation run the original source files ending 32 | %% with `.dtx' through LaTeX. 33 | %% 34 | %% \CharacterTable 35 | %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z 36 | %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z 37 | %% Digits \0\1\2\3\4\5\6\7\8\9 38 | %% Exclamation \! Double quote \" Hash (number) \# 39 | %% Dollar \$ Percent \% Ampersand \& 40 | %% Acute accent \' Left paren \( Right paren \) 41 | %% Asterisk \* Plus \+ Comma \, 42 | %% Minus \- Point \. Solidus \/ 43 | %% Colon \: Semicolon \; Less than \< 44 | %% Equals \= Greater than \> Question mark \? 45 | %% Commercial at \@ Left bracket \[ Backslash \\ 46 | %% Right bracket \] Circumflex \^ Underscore \_ 47 | %% Grave accent \` Left brace \{ Vertical bar \| 48 | %% Right brace \} Tilde \~} 49 | %% 50 | \NeedsTeXFormat{LaTeX2e}[1995/12/01] 51 | \ProvidesClass{BHCexam} 52 | [2015/10/10 v0.4 BHCexam 53 | document class] 54 | 55 | 56 | \newif\if@sixteenkpaper \@sixteenkpaperfalse 57 | \DeclareOption{16kpaper}{\@sixteenkpapertrue} 58 | \newif\if@marginline \@marginlinefalse 59 | \DeclareOption{marginline}{\@marginlinetrue} 60 | \newif\if@noindent \@noindentfalse 61 | \DeclareOption{noindent}{\@noindenttrue} 62 | \DeclareOption{answers}{\PassOptionsToClass{\CurrentOption}{exam}} 63 | 64 | \newif\if@printbox \@printboxfalse 65 | \DeclareOption{printbox}{\@printboxtrue} 66 | \DeclareOption*{\PassOptionsToClass{\CurrentOption}{exam}} 67 | \ProcessOptions 68 | \LoadClass[addpoints]{exam} 69 | \RequirePackage{ctex} 70 | \RequirePackage{ifpdf,ifxetex} 71 | \RequirePackage{amsmath,amssymb,amsthm,bm,bbding,pifont,dsfont} 72 | \RequirePackage{mathtools} 73 | \RequirePackage{paralist,cases,tabularx} 74 | \RequirePackage{pstricks,pst-plot,xcolor,graphicx} 75 | \if@marginline 76 | \marginparwidth = 2cm 77 | \if@sixteenkpaper 78 | \RequirePackage[papersize={184mm,260mm},hmargin={3cm,2cm}, 79 | vmargin={2cm,2cm},marginparsep=0.5cm,hoffset=0cm,voffset=0cm, 80 | footnotesep=0.5cm,headsep=0.5cm,twoside]{geometry} 81 | \else 82 | \RequirePackage[paper=a4paper,hmargin={3cm,2cm},vmargin={2cm,2cm}, 83 | marginparsep=0.5cm,hoffset=0cm,voffset=0cm,footnotesep=0.5cm, 84 | headsep=0.5cm,twoside]{geometry} 85 | \fi 86 | \else 87 | \if@sixteenkpaper 88 | \RequirePackage[papersize={184mm,260mm},hmargin={2cm,2cm}, 89 | vmargin={2cm,2cm},marginparsep=0.5cm,hoffset=0cm,voffset=0cm, 90 | footnotesep=0.5cm,headsep=0.5cm]{geometry} 91 | \else 92 | \RequirePackage[papersize={210mm,297mm},hmargin={2cm,2cm},vmargin={2cm,2cm}, 93 | marginparsep=0.5cm,hoffset=0cm,voffset=0cm,footnotesep=0.5cm, 94 | headsep=0.5cm]{geometry} 95 | \fi 96 | \fi 97 | \renewcommand{\baselinestretch}{1.5} 98 | \pagestyle{headandfoot} 99 | \header{}{}{} 100 | \footer{}{\small \quad 第~\thepage~页(共~\numpages~页)}{} 101 | \pointname{分} 102 | \pointformat{\kaishu (\thepoints)} 103 | \renewcommand{\questionshook}{ 104 | \settowidth{\leftmargin}{22.\hskip\labelsep} 105 | \if@noindent \setlength\leftmargin{0pt} \fi 106 | } 107 | \renewcommand{\thepartno}{\arabic{partno}} 108 | \renewcommand{\partlabel}{(\thepartno)} 109 | \renewcommand{\partshook}{ 110 | \settowidth{\leftmargin}{(3).\hskip\labelsep} 111 | \if@noindent \setlength\leftmargin{0pt} \fi 112 | } 113 | \newif\if@cancelspace \@cancelspacetrue 114 | \renewcommand{\solutiontitle}{\noindent 解:\noindent} 115 | \renewenvironment{solution}% 116 | {% 117 | \ifprintanswers 118 | \begingroup 119 | \Solution@Emphasis 120 | \begin{TheSolution}% 121 | \else 122 | \if@cancelspace 123 | %\unskip 124 | \else 125 | \par 126 | \penalty 0 127 | \vfill% 128 | \if@printbox \if@houpinfen \houpinfen \fi \fi 129 | \fi 130 | \setbox\z@\vbox\bgroup 131 | \fi 132 | }{% 133 | \ifprintanswers 134 | \end{TheSolution}% 135 | \endgroup 136 | \else 137 | \egroup 138 | \fi 139 | }% 140 | \if@marginline 141 | \newsavebox{\zdxl} 142 | \sbox{\zdxl}{ 143 | \begin{minipage}{0.7\paperheight} 144 | \begin{center} 145 | \heiti 班级\underline{\hspace{15ex}} \quad 146 | 姓名 \underline{\hspace{15ex}} \quad 147 | 学号 \underline{\hspace{15ex}} \quad \\ 148 | \vspace{3ex} 149 | \dotfill 装 \dotfill 订 \dotfill 线 \dotfill 150 | \end{center} 151 | \end{minipage} 152 | } 153 | \newsavebox{\zdxr} 154 | \sbox{\zdxr}{ 155 | \begin{minipage}{0.7\paperheight} 156 | \begin{center} 157 | \heiti \hfill 请 \hfill 不 \hfill 要 \hfill 在 \hfill 158 | 装 \hfill 订 \hfill 线 \hfill 内 \hfill 答 \hfill 题 \hfill \\ 159 | \vspace{3ex} 160 | \dotfill 装 \dotfill 订 \dotfill 线 \dotfill 161 | \end{center} 162 | \end{minipage} 163 | } 164 | \newcommand{\printmlol}{ 165 | \marginpar{\rotatebox{90}{\usebox{\zdxl}}} 166 | } 167 | \newcommand{\printmlor}{ 168 | \marginpar{\rotatebox{-90}{\usebox{\zdxr}}} 169 | } 170 | \reversemarginpar 171 | \fi 172 | \newcommand\biaoti[1]{\def\@biaoti{#1}} 173 | \newcommand\fubiaoti[1]{\def\@fubiaoti{#1}} 174 | \renewcommand\maketitle{ 175 | \begin{center}{\heiti \Large{\@biaoti}}\end{center} 176 | \begin{center}{\heiti \Large{\@fubiaoti}}\end{center} 177 | } 178 | \newcommand\xinxi[2]{ 179 | \def\@zongfen{#1} 180 | \def\@shijian{#2} 181 | } 182 | \newcommand\mininotice{ 183 | \begin{center}{ 184 | \kaishu (本试卷满分~\@zongfen~分, 考试时间~\@shijian~分钟)} 185 | \end{center} 186 | } 187 | \newcommand{\notice}{ 188 | \heiti 注意事项: \songti 189 | \begin{enumerate} 190 | \item 答卷前, 考生务必将姓名、高考准考证号、校验码等填写清楚. 191 | \item 本试卷共~\numquestions{}~道试题, 满分~\@zongfen~分,考试时间~\@shijian~分钟. 192 | \end{enumerate} 193 | } 194 | \newlength\@boxwidth 195 | \setlength\@boxwidth{0ex} 196 | \if@printbox \setlength\@boxwidth{18ex} \fi 197 | \newcommand\pinfen{ 198 | \heiti 199 | \begin{minipage}{\@boxwidth} 200 | \begin{tabular}{|c|c|} 201 | \hline 202 | 得分 & 评卷人\\ 203 | \hline 204 | & \\ 205 | \hline 206 | \end{tabular} 207 | \end{minipage} 208 | } 209 | \newcommand{\houpinfen}{ 210 | \hfill 211 | \begin{tabular}{|l|l|} 212 | \hline 213 | 得分 & \hspace*{1.5cm}\\ 214 | \hline 215 | \end{tabular} 216 | \bigskip 217 | } 218 | \newcounter{@dati} 219 | \newif\if@houpinfen \@houpinfenfalse 220 | \newcommand\settk[3]{ 221 | \def\@tiankong@zongfen{#1} 222 | \def\@tiankong@tishu{#2} 223 | \def\@tiankong@fen{#3} 224 | } 225 | \newcommand\tiankong{ 226 | \@houpinfenfalse 227 | \stepcounter{@dati} 228 | \fullwidth{ 229 | \if@printbox \pinfen \fi 230 | \begin{minipage}{\textwidth-\@boxwidth} 231 | \heiti \chinese{@dati}. 填空题:本大题共~\@tiankong@tishu~题,满分~\@tiankong@zongfen~分. 请在横线上方填写最终的、最准确的、最完整的结果. 每题填写正确得~\@tiankong@fen~分,否则一律得0分. 232 | \end{minipage} 233 | } 234 | } 235 | \newcommand{\stk}[1]{ 236 | \ifprintanswers 237 | \underline{~#1~} 238 | \else 239 | \underline{~\hspace{1cm}~} 240 | \fi} 241 | \newcommand{\mtk}[1]{ 242 | \ifprintanswers 243 | \underline{~#1~} 244 | \else 245 | \underline{~\hspace{2cm}~} 246 | \fi} 247 | \newcommand{\ltk}[1]{ 248 | \ifprintanswers 249 | \underline{~#1~} 250 | \else 251 | \underline{~\hspace{3cm}~} 252 | \fi} 253 | \newcommand\setxz[3]{ 254 | \def\@xuanze@zongfen{#1} 255 | \def\@xuanze@tishu{#2} 256 | \def\@xuanze@fen{#3} 257 | } 258 | \newcommand\xuanze{ 259 | \@houpinfenfalse 260 | \stepcounter{@dati} 261 | \fullwidth{ 262 | \if@printbox \pinfen \fi 263 | \begin{minipage}{\textwidth-\@boxwidth} 264 | \heiti \chinese{@dati}. 选择题:本大题共~\@xuanze@tishu~题,满分~\@xuanze@zongfen~分. 请选择你认为最正确的答案(每小题有且只有一个)写在括号内. 每题填写正确得~\@xuanze@fen~分,否则得0分. 265 | \end{minipage} 266 | } 267 | } 268 | \newcommand{\onech}[4]{ 269 | \renewcommand\arraystretch{1.4} 270 | \begin{tabularx}{\linewidth}{XXXX} 271 | \setlength\tabcolsep{0pt} 272 | (A) #1 & (B) #2 & (C) #3 & (D) #4 \\ 273 | \end{tabularx} 274 | \unskip \unskip} 275 | \newcommand{\twoch}[4]{ 276 | \renewcommand\arraystretch{1.4} 277 | \begin{tabularx}{\linewidth}{XX} 278 | \setlength\tabcolsep{0pt} 279 | (A) #1 & (B) #2 \\ 280 | (C) #3 & (D) #4 281 | \end{tabularx} 282 | \unskip \unskip} 283 | \newcommand{\fourch}[4]{ 284 | \renewcommand\arraystretch{1.4} 285 | \begin{tabularx}{\linewidth}{X} 286 | \setlength\tabcolsep{0pt} 287 | (A) #1 \\ 288 | (B) #2 \\ 289 | (C) #3 \\ 290 | (D) #4 \\ 291 | \end{tabularx} 292 | \unskip \unskip} 293 | \newcommand\setjd[2]{ 294 | \def\@jianda@zongfen{#1} 295 | \def\@jianda@tishu{#2} 296 | } 297 | \newcommand\jianda{ 298 | \@cancelspacefalse 299 | \@houpinfentrue 300 | \stepcounter{@dati} 301 | \fullwidth{ 302 | \if@printbox \pinfen \fi 303 | \begin{minipage}{\textwidth-\@boxwidth} 304 | \heiti \chinese{@dati}. 简答题:本大题共~\@jianda@tishu~题,满分~\@jianda@zongfen~分. 请在题后空处写出必要的推理计算过程. 305 | \end{minipage} 306 | } 307 | } 308 | \delimitershortfall-1sp 309 | \newcommand\abs[1]{\left|#1\right|} 310 | \renewcommand{\geq}{\geqslant} 311 | \renewcommand{\ge}{\geqslant} 312 | \renewcommand{\leq}{\leqslant} 313 | \renewcommand{\le}{\leqslant} 314 | \AtEndOfPackage{\makeatletter\input{BHCexam.cfg}\makeatother} 315 | 316 | \endinput 317 | %% 318 | %% End of file `BHCexam.cls'. 319 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mathexamgen 2 | MathExamGen:科学快速的生成中学数学试卷(Matlab+Texlive). 大体思路就是利用Matlab科学的整合数学题库中的题目,然后生成相应的tex文件,最后借助自带的xelatex编译器编译成pdf文件。 3 | 4 | ## 1. bhcexam 安装 5 | 6 | windows 下的安装方法 7 | 8 | ``` 9 | tlmgr bhcexam 10 | ``` 11 | 12 | 如果安装不了,可以使用项目附带的`BHCexam.cls`和`BHCexam.cfg`. 13 | 14 | 15 | 项目介绍: 16 | 17 | ### 2. 数学题库 18 | 19 | 存储类型:csv或者数据库 20 | 变量列表: 21 | 22 | |变量|变量名|描述|取值| 23 | | ---- |:----:| :---:|:---| 24 | |1| ID| 题目编号| 6位数字 | 25 | |2|qtype| 题目类型|1代表填空题,2代表选择题等| 26 | |3|question| 题目内容| 题目的latex代码| 27 | |4|options| 题目相关信息|选择题的四个选项等信息| 28 | |5|answer| 题目答案| | 29 | |6| topic| 题目的考点| 分级考点,如:高二-数列-递推| 30 | 31 | ### 3.主要思路 32 | 33 | 结合Matlab的数据处理与分析功能,我们可以做很多事,例如 34 | 35 | 1. 根据给定的类型要求和考点要求,随机生成一张试卷; 36 | 2. 结合单个同学的历史数据,生成适合他/她的试卷,在这份试卷中易错点出现的频次更高一些; 37 | 3. 由于所有试卷都是生成的,我们可以更科学快捷的评估单次考试。 38 | 39 | -------------------------------------------------------------------------------- /examtest.m: -------------------------------------------------------------------------------- 1 | [~,~,dta]=xlsread('题库.xlsx'); 2 | % dta: qtpye,question,options,answer 3 | dta=dta(2:end,2:end); 4 | 5 | if ~isdir('pdf') 6 | mkdir('pdf'); 7 | end 8 | savepath=[pwd,'\pdf\']; 9 | filename=[savepath,'examtest.tex']; 10 | fileID = fopen(filename,'w','n','UTF-8'); 11 | 12 | 13 | e='\\documentclass[printbox,marginline,noindent]{BHCexam}'; 14 | e=[e,char(10),'\\begin{document}',char(10)]; 15 | e=[e,'\\printmlol',char([10,10]),'\\maketitle',char(10)]; 16 | e=[e,'\\begin{questions}',char(10)]; 17 | fprintf(fileID,e); 18 | 19 | % 填空题 20 | tiankong_ind=find(cell2mat(dta(:,1))==1); 21 | if ~isempty(tiankong_ind) 22 | nn=length(tiankong_ind); 23 | tiankong=['\tiankong',char(10)]; 24 | for i=1:nn 25 | tiankong=[tiankong,char(10),'\question ',dta{tiankong_ind(i),2}]; 26 | tiankong=[tiankong,'\stk{',dta{tiankong_ind(i),4},'}.',char(10)]; 27 | end 28 | end 29 | tiankong = regexprep(tiankong,'\\','\\\'); 30 | fprintf(fileID,tiankong); 31 | 32 | % 选择题 33 | xuanze_ind=find(cell2mat(dta(:,1))==2); 34 | if ~isempty(xuanze_ind) 35 | nn=length(xuanze_ind); 36 | xuanze=['\xuanze',char(10)]; 37 | for i=1:nn 38 | xuanze=[xuanze,char(10),'\question ',dta{xuanze_ind(i),2}]; 39 | xuanze=[xuanze,'\stk{',dta{xuanze_ind(i),4},'}.']; 40 | xuanze=[xuanze,char([10,10]),dta{xuanze_ind(i),3},char(10)]; 41 | end 42 | end 43 | xuanze = regexprep(xuanze,'\\','\\\'); 44 | fprintf(fileID,xuanze); 45 | 46 | % 简答题 47 | question_ind=find(cell2mat(dta(:,1))==3); 48 | if ~isempty(question_ind) 49 | nn=length(question_ind); 50 | question=['\jianda',char(10)]; 51 | for i=1:nn 52 | question=[question,char(10),'\question ',dta{question_ind(i),2}]; 53 | question=[question,'\stk{',dta{question_ind(i),4},'}.']; 54 | question=[question,char([10,10]),'\begin{solution}',... 55 | char(10),dta{question_ind(i),4},char(10),'\end{solution}',char(10)]; 56 | end 57 | end 58 | question = regexprep(question,'\\','\\\'); 59 | fprintf(fileID,question); 60 | 61 | % 结束 62 | e=['\\end{questions}',char(10),'\\end{document}']; 63 | fprintf(fileID,e); 64 | 65 | fclose(fileID); 66 | 67 | eval(['!xelatex ',filename]); 68 | movefile('examtest.pdf',[savepath,'examtest.pdf']); 69 | delete('examtest.aux','examtest.log'); 70 | winopen([savepath,'examtest.pdf']); 71 | 72 | 73 | -------------------------------------------------------------------------------- /题库.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/mathexamgen/797a37a3d345612fa8ee2040e3ae2406efb5604a/题库.xlsx --------------------------------------------------------------------------------