diff options
33 files changed, 12645 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/CHANGELOG.md b/Master/texmf-dist/doc/xelatex/exam-zh/CHANGELOG.md new file mode 100644 index 00000000000..a8d56a3d528 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/CHANGELOG.md @@ -0,0 +1,352 @@ +# Changelog + +此处记载了项目中所有值得留意的改动。 + +格式参照 [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +并且此项目遵守 [Semantic Versioning](https://semver.org/spec/v2.0.0.html)。 + + +## [0.1.13] - 2022-07-28 + +### Changed + +- 优化 `question/combine-fillin` 的效果 + +## [0.1.12] - 2022-07-27 + +### Added + +- 增加 `\fillin*` 命令实现自动换行 + +### Changed + +- `exam-zh-chinese` 模块改名为 `exam-zh-chinese-english` + + +### Fixed + +- 修复 `chapter` 下的 `question` 的序号从0开始问题 +- 修复页脚 `lastpage` 前的空格自动化的问题 + + + +## [0.1.12] - 2022-07-26 + +### Added + +- 增加 `writingbox` 环境 +- 增加 `question/combine-fillin`, `question/combine-fillin-args`, `question/label-align` 键值 +- 增加密封线的范围值 + + +## [0.1.12] - 2022-07-25 + +### Added + +- 增加第一层级 `enumerate` 的设置 +- 增加 `notice` 环境的键值 `label`, `label-format`, `top-sep`, `bottom-sep` + +### Changed + +- 给 `notice` 环境增加参数 + +## [0.1.12] - 2022-07-24 + +### Added + +- 增加密封线 `text-width`, `text-format`, `text-xscale`,`text-yscale`, `text-direction-vertical` 键值 +- 增加 `select` 环境的 `above` 和 `below` 键值 +- 增加 `sealline/scope` 同效键值 `sealline/type` +- 增加脚注设置 +- 增加 `\subject` 的可选参数 +- 增加 `scoringbox/position` 键值 +- 增加 `material` 环境 +- 增加 `style/footnote-style` 键值 + +### Changed + +- `foot-style` 改为 `foot-type` +- 修改 `solution`, `choices` 的 `top-sep`, `bottom-sep` 的默认值 + + +### Fixed + +- 更正 `select/seperator` 为 `select/separator` +- 修复 `question` 环境的 `index` 减一问题 + +## [0.1.12] - 2022-07-23 + +### Changed + +- 修改 `square` 键值名称 +- 将 `select` 环境的 `\item` 改为 `\sitem` 以兼容 `choices` 环境 + +### Removed + +- 去掉 `sealline/text-align` 键值 + + +## [0.1.12] - 2022-07-22 + +- 修复 `fullwidth-stop` 的失效问题 + +## [0.1.11] - 2022-07-22 + +### Added + +- 实现师生两版 + + +## [0.1.11] - 2022-07-21 + +### Added + +- `\fillin` 不显示答案时增加 `counter` 类型的显示 +- `question/label` 增加基于 `TiKZ` 的带圈数字 `\tikzcirclednumber` 类型计数器 +- 增加 `select/show-mark` 键值控制 `select` 环境的 mark 显示 +- 增加 `fillin/no-answer-counter-label` 键值 + +### Changed + +- `fillin/show-blacktriangle` 键值改为 `no-answer-type` +- `questioncirclednumber` 改为 `circlednumber` +- `\circlednumber` 命令增加 `\circlednumber*` 类型 +- 将 `question` 环境的上下方间距从 `\addvspace` 改为 `\vspace*` + +## [0.1.11] - 2022-07-20 + +### Added + +- 增加 `question` 和 `problem` 环境的 `label` 键值 +- 增加 `solution` 环境的 `parbreak` 键值 + +### Changed + +- 完善 `question/blank-type=hide` 的效果 + +## [0.1.11] - 2022-07-19 + +### Added + +- 增加手册 `choices` 环境方形和圆形 label 的示例 +- 增加 `solution` 不显示解答时的垂直空白 `blank-type` 和 `blank-sep` 键值 +- 增加 `solution` 的 `top-sep` 和 `bottom-sep` 键值 +- 增加 `fullwidth-stop` 键值 + +### Changed + +- 更改 `solution` 环境接口 +- 修改 `change-frac-style`, `change-dfrac-style` 默认值为 `false` + + +### Fixed + +- 修复 `missing \item` 问题(#I5HUUV) + +## [0.1.10] - 2022-07-19 + +### Added + +- 新增 `exam-zh-chinese.sty` 模块 +- 新增 `select` 环境(#I5HG8K) +- 新增 `lineto` 连线环境(#I5FXOX) + +## [0.1.10] - 2022-07-17 + +### Added + +- 增加不同字体命令的效果展示 +- 增加 `\frac` 和 `\dfrac` 分子分母额外间距的控制(#I5H51B) + +## [0.1.9] - 2022-07-17 + +### Added + +- 增加手册“符号”的部分 + +## [0.1.9] - 2022-07-16 + +### Added + +- 密封线增加 `first-and-last` 类型 + +### Changed + +- 去掉 `\fillin[type=paren]` 的基线调整 +- 去掉 `\fillin[type=blank]` 的基线调整 +- 将 `example.tex` 改为 `example-single.tex` 和 `example-multiple.tex` 分别作为单份和多份试卷排版示例 + + +### Fixed + +- 修复 `solution` 环境的列表嵌套的空格问题 +- 修复 `a4paper` 无 `\chapter` 下的页面格式问题 + +## [0.1.9] - 2022-07-15 + +### Added + +- 增加 `\fillin` 的 `type/blank` 值 +- 增加 `\fillin` 的颜色控制 +- 增加 `\paren` 的 `type` 键值 +- 增加 `solution` 环境的 `text-color` 键值 + +### Changed + +- 修改所有页面(目录除外)为统一的页眉页脚 +- 将 `answer-color` 拆成 `\fillin` 和 `\paren` 的颜色分别控制 + + +## [0.1.8] - 2022-07-14 + +### Fixed + +- 修复了 `a3paper` 和 `foot-style=separate` 的目录页码问题 + + +## [0.1.8] - 2022-07-12 + +### Fixed + +- 修复 `missing number` 问题 +- 修复“目录”二字重复问题 + +## [0.1.7] - 2022-07-08 + +### Added + +- 将文类改为 `ctexbook`,并修改 `\chapter` 样式(#I5G2QM) +- 增加 `show-chapter` 键值控制 `\chapter` 的显示 + +## [0.1.7] - 2022-07-08 + +### Fixed + +- 去掉 `.str_set:N` 使得模版兼容 TeXLive 2021 (#I5G7X2) + +## [0.1.7] - 2022-07-07 + +### Added + +- 增加 `exam-zh-symbols.sty` 模块绘制部分中国化的数学符号 + +### Changed + +- 修改 `\complement` 的效果 + +### Fixed + +- 修复 `a3paper` 的分数框问题(#I5FZWW) + +## [0.1.7] - 2022-07-06 + +### Added + +- 增加 `\fillin` 的 `width` 键值 + +## [0.1.6] - 2022-07-05 + +### Added + +- `\fillin` 命令增加一个 `circle` 类型(#I5FMPP) + +### Changed + +- 将 `\paren` 和 `\fillin` 的答案控制单独分离 + + +## [0.1.6] - 2022-07-04 + +### Added + +- 增加 `\examsquare` 方格命令 +- 增加 `step`、`method`、`case` 环境 +- 增加页脚内容定制接口 `page/foot-content` + +## [0.1.6] - 2022-07-03 + +### Added + +- 增加标题的控制接口 +- 增加顶部的个人信息接口 +- 增加 `\warning` 命令 +- 增加草稿纸 `\draftpaper` 以及相关接口 + +### Changed + +- 将 `\goodluck` 命令改为参数式 + + +## [0.1.5] - 2022-07-02 + +### Added + +- 增加 `solution` 环境和 `score` 命令 + +## [0.1.4] - 2022-06-27 + +### Added + +- 基本完成用户手册的编写 + +## [0.1.4] - 2022-06-24 + +### Added + +- 给 `\fillin` 命令增加了可选参数接口 +- `choices` 环境增加 `index` 接口 + +## [0.1.3] - 2022-06-22 + +### Added + +- 增加密封线奇偶统一控制接口 + +### Fixed + +- 修复密封线接口失效问题 + + +## [0.1.2] - 2022-06-16 + +- 完成密封线的所有接口设计 + +## [0.1.2] - 2022-06-15 + +- 增加密封线 + + +## [0.1.2] - 2022-06-14 + +### Added + +- 新增页面尺寸 `a4paper` 和 `a3paper` 的控制 +- 新增 `a3paper` 页面的“是否共用页脚”控制 + + +## [0.1.1] - 2022-06-09 + +### Added + +- 新增 `question` 环境的 `top-sep` 和 `bottom-sep` 选项控制前后距离([#I4SLWN](https://gitee.com/zepinglee/exam-zh/issues/I4SLWN))。 +- 新增 `question` 环境的 `index` 选项设置题号([#I4SQLI](https://gitee.com/zepinglee/exam-zh/issues/I4SQLI))。 +- 新增 `question` 环境的 `answer-color` 选项控制答案颜色([#I4SW79](https://gitee.com/zepinglee/exam-zh/issues/I4SW79))。 +- 新增 `choices` 环境的 `label` 选项控制标签格式([#I4SXC1](https://gitee.com/zepinglee/exam-zh/issues/I4SXC1))。 +- 新增 `\circlednumber` 使用中文字体生成带圈数字。 +- 新增 `choices` 环境的 `label-align` 选项控制标签的对齐方式([#I4TDSA](https://gitee.com/zepinglee/exam-zh/issues/I4TDSA))。 +- 新增 `exam-zh-font` 模块,提供西文字体 `font` 和数学字体 `math-font` 选项([#I512EV](https://gitee.com/zepinglee/exam-zh/issues/I512EV))。 +- 新增 `fillin` 命令的 `type` 选项控制下划线和括号类型 + +### Fixed + +- 答案的内容较高时调整深度([#I4SXC1](https://gitee.com/zepinglee/exam-zh/issues/I4SXC1))。 + +## [v0.1.0] - 2022-02-04 + +### Added + +- 在 Gitee 发布。 + +[Unreleased]: https://gitee.com/zepinglee/exam-zh/compare/v0.1.0...HEAD +[v0.1.0]: https://gitee.com/zepinglee/exam-zh/releases/v0.1.0 +[v0.1.1]: https://gitee.com/zepinglee/exam-zh/releases/v0.1.1 diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/LICENSE b/Master/texmf-dist/doc/xelatex/exam-zh/LICENSE new file mode 100644 index 00000000000..22443139013 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/LICENSE @@ -0,0 +1,416 @@ +The LaTeX Project Public License +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +LPPL Version 1.3c 2008-05-04 + +Copyright 1999 2002-2008 LaTeX3 Project + Everyone is allowed to distribute verbatim copies of this + license document, but modification of it is not allowed. + + +PREAMBLE +======== + +The LaTeX Project Public License (LPPL) is the primary license under +which the LaTeX kernel and the base LaTeX packages are distributed. + +You may use this license for any work of which you hold the copyright +and which you wish to distribute. This license may be particularly +suitable if your work is TeX-related (such as a LaTeX package), but +it is written in such a way that you can use it even if your work is +unrelated to TeX. + +The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE', +below, gives instructions, examples, and recommendations for authors +who are considering distributing their works under this license. + +This license gives conditions under which a work may be distributed +and modified, as well as conditions under which modified versions of +that work may be distributed. + +We, the LaTeX3 Project, believe that the conditions below give you +the freedom to make and distribute modified versions of your work +that conform with whatever technical specifications you wish while +maintaining the availability, integrity, and reliability of +that work. If you do not see how to achieve your goal while +meeting these conditions, then read the document `cfgguide.tex' +and `modguide.tex' in the base LaTeX distribution for suggestions. + + +DEFINITIONS +=========== + +In this license document the following terms are used: + + `Work' + Any work being distributed under this License. + + `Derived Work' + Any work that under any applicable law is derived from the Work. + + `Modification' + Any procedure that produces a Derived Work under any applicable + law -- for example, the production of a file containing an + original file associated with the Work or a significant portion of + such a file, either verbatim or with modifications and/or + translated into another language. + + `Modify' + To apply any procedure that produces a Derived Work under any + applicable law. + + `Distribution' + Making copies of the Work available from one person to another, in + whole or in part. Distribution includes (but is not limited to) + making any electronic components of the Work accessible by + file transfer protocols such as FTP or HTTP or by shared file + systems such as Sun's Network File System (NFS). + + `Compiled Work' + A version of the Work that has been processed into a form where it + is directly usable on a computer system. This processing may + include using installation facilities provided by the Work, + transformations of the Work, copying of components of the Work, or + other activities. Note that modification of any installation + facilities provided by the Work constitutes modification of the Work. + + `Current Maintainer' + A person or persons nominated as such within the Work. If there is + no such explicit nomination then it is the `Copyright Holder' under + any applicable law. + + `Base Interpreter' + A program or process that is normally needed for running or + interpreting a part or the whole of the Work. + + A Base Interpreter may depend on external components but these + are not considered part of the Base Interpreter provided that each + external component clearly identifies itself whenever it is used + interactively. Unless explicitly specified when applying the + license to the Work, the only applicable Base Interpreter is a + `LaTeX-Format' or in the case of files belonging to the + `LaTeX-format' a program implementing the `TeX language'. + + + +CONDITIONS ON DISTRIBUTION AND MODIFICATION +=========================================== + +1. Activities other than distribution and/or modification of the Work +are not covered by this license; they are outside its scope. In +particular, the act of running the Work is not restricted and no +requirements are made concerning any offers of support for the Work. + +2. You may distribute a complete, unmodified copy of the Work as you +received it. Distribution of only part of the Work is considered +modification of the Work, and no right to distribute such a Derived +Work may be assumed under the terms of this clause. + +3. You may distribute a Compiled Work that has been generated from a +complete, unmodified copy of the Work as distributed under Clause 2 +above, as long as that Compiled Work is distributed in such a way that +the recipients may install the Compiled Work on their system exactly +as it would have been installed if they generated a Compiled Work +directly from the Work. + +4. If you are the Current Maintainer of the Work, you may, without +restriction, modify the Work, thus creating a Derived Work. You may +also distribute the Derived Work without restriction, including +Compiled Works generated from the Derived Work. Derived Works +distributed in this manner by the Current Maintainer are considered to +be updated versions of the Work. + +5. If you are not the Current Maintainer of the Work, you may modify +your copy of the Work, thus creating a Derived Work based on the Work, +and compile this Derived Work, thus creating a Compiled Work based on +the Derived Work. + +6. If you are not the Current Maintainer of the Work, you may +distribute a Derived Work provided the following conditions are met +for every component of the Work unless that component clearly states +in the copyright notice that it is exempt from that condition. Only +the Current Maintainer is allowed to add such statements of exemption +to a component of the Work. + + a. If a component of this Derived Work can be a direct replacement + for a component of the Work when that component is used with the + Base Interpreter, then, wherever this component of the Work + identifies itself to the user when used interactively with that + Base Interpreter, the replacement component of this Derived Work + clearly and unambiguously identifies itself as a modified version + of this component to the user when used interactively with that + Base Interpreter. + + b. Every component of the Derived Work contains prominent notices + detailing the nature of the changes to that component, or a + prominent reference to another file that is distributed as part + of the Derived Work and that contains a complete and accurate log + of the changes. + + c. No information in the Derived Work implies that any persons, + including (but not limited to) the authors of the original version + of the Work, provide any support, including (but not limited to) + the reporting and handling of errors, to recipients of the + Derived Work unless those persons have stated explicitly that + they do provide such support for the Derived Work. + + d. You distribute at least one of the following with the Derived Work: + + 1. A complete, unmodified copy of the Work; + if your distribution of a modified component is made by + offering access to copy the modified component from a + designated place, then offering equivalent access to copy + the Work from the same or some similar place meets this + condition, even though third parties are not compelled to + copy the Work along with the modified component; + + 2. Information that is sufficient to obtain a complete, + unmodified copy of the Work. + +7. If you are not the Current Maintainer of the Work, you may +distribute a Compiled Work generated from a Derived Work, as long as +the Derived Work is distributed to all recipients of the Compiled +Work, and as long as the conditions of Clause 6, above, are met with +regard to the Derived Work. + +8. The conditions above are not intended to prohibit, and hence do not +apply to, the modification, by any method, of any component so that it +becomes identical to an updated version of that component of the Work as +it is distributed by the Current Maintainer under Clause 4, above. + +9. Distribution of the Work or any Derived Work in an alternative +format, where the Work or that Derived Work (in whole or in part) is +then produced by applying some process to that format, does not relax or +nullify any sections of this license as they pertain to the results of +applying that process. + +10. a. A Derived Work may be distributed under a different license + provided that license itself honors the conditions listed in + Clause 6 above, in regard to the Work, though it does not have + to honor the rest of the conditions in this license. + + b. If a Derived Work is distributed under a different license, that + Derived Work must provide sufficient documentation as part of + itself to allow each recipient of that Derived Work to honor the + restrictions in Clause 6 above, concerning changes from the Work. + +11. This license places no restrictions on works that are unrelated to +the Work, nor does this license place any restrictions on aggregating +such works with the Work by any means. + +12. Nothing in this license is intended to, or may be used to, prevent +complete compliance by all parties with all applicable laws. + + +NO WARRANTY +=========== + +There is no warranty for the Work. Except when otherwise stated in +writing, the Copyright Holder provides the Work `as is', without +warranty of any kind, either expressed or implied, including, but not +limited to, the implied warranties of merchantability and fitness for a +particular purpose. The entire risk as to the quality and performance +of the Work is with you. Should the Work prove defective, you assume +the cost of all necessary servicing, repair, or correction. + +In no event unless required by applicable law or agreed to in writing +will The Copyright Holder, or any author named in the components of the +Work, or any other party who may distribute and/or modify the Work as +permitted above, be liable to you for damages, including any general, +special, incidental or consequential damages arising out of any use of +the Work or out of inability to use the Work (including, but not limited +to, loss of data, data being rendered inaccurate, or losses sustained by +anyone as a result of any failure of the Work to operate with any other +programs), even if the Copyright Holder or said author or said other +party has been advised of the possibility of such damages. + + +MAINTENANCE OF THE WORK +======================= + +The Work has the status `author-maintained' if the Copyright Holder +explicitly and prominently states near the primary copyright notice in +the Work that the Work can only be maintained by the Copyright Holder +or simply that it is `author-maintained'. + +The Work has the status `maintained' if there is a Current Maintainer +who has indicated in the Work that they are willing to receive error +reports for the Work (for example, by supplying a valid e-mail +address). It is not required for the Current Maintainer to acknowledge +or act upon these error reports. + +The Work changes from status `maintained' to `unmaintained' if there +is no Current Maintainer, or the person stated to be Current +Maintainer of the work cannot be reached through the indicated means +of communication for a period of six months, and there are no other +significant signs of active maintenance. + +You can become the Current Maintainer of the Work by agreement with +any existing Current Maintainer to take over this role. + +If the Work is unmaintained, you can become the Current Maintainer of +the Work through the following steps: + + 1. Make a reasonable attempt to trace the Current Maintainer (and + the Copyright Holder, if the two differ) through the means of + an Internet or similar search. + + 2. If this search is successful, then enquire whether the Work + is still maintained. + + a. If it is being maintained, then ask the Current Maintainer + to update their communication data within one month. + + b. If the search is unsuccessful or no action to resume active + maintenance is taken by the Current Maintainer, then announce + within the pertinent community your intention to take over + maintenance. (If the Work is a LaTeX work, this could be + done, for example, by posting to comp.text.tex.) + + 3a. If the Current Maintainer is reachable and agrees to pass + maintenance of the Work to you, then this takes effect + immediately upon announcement. + + b. If the Current Maintainer is not reachable and the Copyright + Holder agrees that maintenance of the Work be passed to you, + then this takes effect immediately upon announcement. + + 4. If you make an `intention announcement' as described in 2b. above + and after three months your intention is challenged neither by + the Current Maintainer nor by the Copyright Holder nor by other + people, then you may arrange for the Work to be changed so as + to name you as the (new) Current Maintainer. + + 5. If the previously unreachable Current Maintainer becomes + reachable once more within three months of a change completed + under the terms of 3b) or 4), then that Current Maintainer must + become or remain the Current Maintainer upon request provided + they then update their communication data within one month. + +A change in the Current Maintainer does not, of itself, alter the fact +that the Work is distributed under the LPPL license. + +If you become the Current Maintainer of the Work, you should +immediately provide, within the Work, a prominent and unambiguous +statement of your status as Current Maintainer. You should also +announce your new status to the same pertinent community as +in 2b) above. + + +WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE +====================================================== + +This section contains important instructions, examples, and +recommendations for authors who are considering distributing their +works under this license. These authors are addressed as `you' in +this section. + +Choosing This License or Another License +---------------------------------------- + +If for any part of your work you want or need to use *distribution* +conditions that differ significantly from those in this license, then +do not refer to this license anywhere in your work but, instead, +distribute your work under a different license. You may use the text +of this license as a model for your own license, but your license +should not refer to the LPPL or otherwise give the impression that +your work is distributed under the LPPL. + +The document `modguide.tex' in the base LaTeX distribution explains +the motivation behind the conditions of this license. It explains, +for example, why distributing LaTeX under the GNU General Public +License (GPL) was considered inappropriate. Even if your work is +unrelated to LaTeX, the discussion in `modguide.tex' may still be +relevant, and authors intending to distribute their works under any +license are encouraged to read it. + +A Recommendation on Modification Without Distribution +----------------------------------------------------- + +It is wise never to modify a component of the Work, even for your own +personal use, without also meeting the above conditions for +distributing the modified component. While you might intend that such +modifications will never be distributed, often this will happen by +accident -- you may forget that you have modified that component; or +it may not occur to you when allowing others to access the modified +version that you are thus distributing it and violating the conditions +of this license in ways that could have legal implications and, worse, +cause problems for the community. It is therefore usually in your +best interest to keep your copy of the Work identical with the public +one. Many works provide ways to control the behavior of that work +without altering any of its licensed components. + +How to Use This License +----------------------- + +To use this license, place in each of the components of your work both +an explicit copyright notice including your name and the year the work +was authored and/or last substantially modified. Include also a +statement that the distribution and/or modification of that +component is constrained by the conditions in this license. + +Here is an example of such a notice and statement: + + %% pig.dtx + %% Copyright 2005 M. Y. Name + % + % This work may be distributed and/or modified under the + % conditions of the LaTeX Project Public License, either version 1.3 + % of this license or (at your option) any later version. + % The latest version of this license is in + % http://www.latex-project.org/lppl.txt + % and version 1.3 or later is part of all distributions of LaTeX + % version 2005/12/01 or later. + % + % This work has the LPPL maintenance status `maintained'. + % + % The Current Maintainer of this work is M. Y. Name. + % + % This work consists of the files pig.dtx and pig.ins + % and the derived file pig.sty. + +Given such a notice and statement in a file, the conditions +given in this license document would apply, with the `Work' referring +to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being +generated from `pig.dtx' using `pig.ins'), the `Base Interpreter' +referring to any `LaTeX-Format', and both `Copyright Holder' and +`Current Maintainer' referring to the person `M. Y. Name'. + +If you do not want the Maintenance section of LPPL to apply to your +Work, change `maintained' above into `author-maintained'. +However, we recommend that you use `maintained', as the Maintenance +section was added in order to ensure that your Work remains useful to +the community even when you can no longer maintain and support it +yourself. + +Derived Works That Are Not Replacements +--------------------------------------- + +Several clauses of the LPPL specify means to provide reliability and +stability for the user community. They therefore concern themselves +with the case that a Derived Work is intended to be used as a +(compatible or incompatible) replacement of the original Work. If +this is not the case (e.g., if a few lines of code are reused for a +completely different task), then clauses 6b and 6d shall not apply. + + +Important Recommendations +------------------------- + + Defining What Constitutes the Work + + The LPPL requires that distributions of the Work contain all the + files of the Work. It is therefore important that you provide a + way for the licensee to determine which files constitute the Work. + This could, for example, be achieved by explicitly listing all the + files of the Work near the copyright notice of each file or by + using a line such as: + + % This work consists of all files listed in manifest.txt. + + in that place. In the absence of an unequivocal list it might be + impossible for the licensee to determine what is considered by you + to comprise the Work and, in such a case, the licensee would be + entitled to make reasonable conjectures as to which files comprise + the Work. + diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/README.md b/Master/texmf-dist/doc/xelatex/exam-zh/README.md new file mode 100644 index 00000000000..d3bd71fab2e --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/README.md @@ -0,0 +1,261 @@ +# exam-zh: LaTeX template for Chinese exam + +Provides a class exam-zh.cls and its several module packages like exam-zh-question.sty and exam-zh-choices.sty, where these module packages can be used individually. + +Although there are several excellent exam packages or classes uploaded before like exam and bhcexam , they don't fit the chinese style very well or they cannot be customized easily for chinese exam of all types like exams in primary school, junior high school, senior high school and even college. Those are the main reason why exam-zh was created. + +In exam-zh, you can + +- seperate the format and the content very well; +- use choices environment to typeset choice items easily and automatically; +- design the sealline easily; +- use it in Windows, macOS and Linux; +- ... (for more that you can do with it, please read the manual(in Chinese): `exam-zh-doc.pdf` + + +Repository: https://gitee.com/zepinglee/exam-zh +Author: Zeping Lee +Maintainer: Kangwei Xia, Lijun Guo +Issues and pull requests are welcome: [issues]( https://gitee.com/zepinglee/exam-zh/issues) and [pulls](https://gitee.com/zepinglee/exam-zh/pulls) + +# exam-zh:中国试卷 LaTeX 模板 + +- 项目主页:<https://gitee.com/zepinglee/exam-zh> +- 作者:Zeping Lee +- 维护者:Kangwei Xia, Lijun Guo +- 授权:[LaTeX Project Public License 1.3c](https://www.latex-project.org/lppl.txt) + + +本项目提供了一个中国高考试卷样式的 LaTeX 模板,旨在帮助中小学教师更方便地使用 LaTeX。模板具有以下特性: + +1. 样式与内容尽可能分离; +2. 选择题选项可以自动排版成合适的列数; +3. 通过用户接口可以方便更改密封线样式; +4. 在 Windows, macOS 和 Linux 跨平台编译。 + +使用前请仔细阅读 [发行版](https://gitee.com/zepinglee/exam-zh/releases) 的用户手册 `exam-zh-doc.pdf`。 + +## 示例(simple example) + +```latex +\section{选择题:本题共 8 小题,每小题 5 分,共 40 分。} + +\begin{question} + 设集合 $A = \{x \mid -1 < x < 4\}$,$B = \{2, 3, 4, 5\}$,则 $A \cap B = $ \paren + \begin{choices} + \item $\{2\}$ + \item $\{2, 3\}$ + \item $\{3, 4\}$ + \item $\{2, 3, 4\}$ + \end{choices} +\end{question} + +\section{填空题:本题共 4 小题,每小题 5 分,共 20 分。} + +\begin{question} + 已知函数 $f(x) = x^3 (a \cdot 2^x - 2^{-x})$ 是偶函数,则 $a = $ \fillin 。 +\end{question} + +\section{解答题:本题共 6 小题,共 70 分。解答应写出文字说明、证明过程或者演算步骤。} + +\begin{problem}[points = 12] + 已知函数 $f(x) = x (1 - \ln x)$。讨论 $f(x)$ 的单调性。 + 设 $a$,$b$ 为两个不相等的正数,且 $b \ln a - a \ln b = a - b$, + 证明:$2 < \frac{1}{a} + \frac{1}{b} < \eu$。 +\end{problem} +``` + + +## 使用方法 + +下面简要叙述 `exam-zh` 的使用方法,**更多使用细节请阅读手册 `exam-zh-doc.pdf`。** +### 西文和数学字体 + +模板中可以设置西文和数学的字体。 + +```tex +\examsetup{ + font = times, + math-font = xits, +} +``` + +西文字体 `font` 有以下选项: +- `newcm`(默认)New Computer Modern +- `lm` Latin Modern +- `times` Times New Roman +- `termes` TeX Gyre Termes +- `stix` STIX Two +- `xits` XITS +- `libertinus` Libertinus + +数学字体 `math-font` 有以下选项: +- `newcm`(默认)New Computer Modern Math +- `lm` Latin Modern Math +- `termes` TeX Gyre Termes Math +- `stix` STIX Two Math +- `xits` XITS Math +- `libertinus` Libertinus Math +- `cambria` Cambria Math + +注意数学字体使用了 `unicode-math` 宏包进行配置。 + + +### 题目环境 `question` 和 `problem` + +选择题和填空题使用 `question` 环境,解答题使用 `problem` 环境。两者的内容对齐方式不同。 + +`question` 和 `problem` 环境还接受一个可选参数,其中可以使用以下 key—value 进行设置。 +- `answer-color` 答案的颜色(默认:`black`)。 +- `index` 题号。 +- `points` 题目的分数(默认:`0`)。 +- `show-paren` 是否显示选择题的括号(默认 `false`)。 +- `show-points` 是否显示题目的分数(默认 `auto`:选择题和填空题默认 `false`,解答题默认 `true`)。 +- `show-answer` 是否显示答案(默认:`false`)。 +- `top-sep` 题目上方垂直方向的空白距离(默认:`.5em plus .5em minus .2em`)。 +- `bottom-sep` 题目下方垂直方向的空白距离,与 `top-sep` 不叠加(默认:`.5em plus .5em minus .2em`)。 + +其中 `index`、`show-points`、`show-answer`、`top-sep` 和 `bottom-sep` 可以使用 `\examsetup` 命令的 `choices` 层级进行全局设置。比如设置同一层级的多个选项: +```latex +\examsetup{ + choices = { + show-points = true, + show-answer = true, + }, +} +``` +也可以用斜线“/”表示层级并设置单项。 +```latex +\examsetup{ + question/show-points = true, + question/show-answer = true, +} +``` + + +### 选择题的括号 `\paren` 和填空 `\fillin` + +`\paren` 和 `\fillin` 命令分别生成选择题的括号和填空题的横线。这两个命令还分别接受一个可选参数作为题目的答案,如 `\paren[B]` 或 `\fillin[foo]`。当 `show-answer = true` 时则将答案显示在其中。 + +需要注意的是,如果 `\fillin` 的参数中含有不配对的中括号时会报错,如 `\fillin[$(−\infty, 1]$]`。这时需要使用大括号将内容保护起来:`\fillin[{$(−\infty, 1]$}]`。 + +`\fillin` 提供了样式的切换(目前就是下划线和括号两种): +```latex +\examsetup{ + fillin = { + type = paren % 括号风格 + % type = line % 下划线风格 + } +} +``` +也可以局部更改单个 `\fillin` 的样式:`\fill[type = paren][foo]`(有答案)或`\fill[type = paren][]`(无答案) + + +### 选项环境 `choices` + +选择题的选项使用 `choices` 环境排版,可以自动根据内容的长度选择合适的列数并对齐。该环境的设计主要参考了 @xkwxdyy 的 [choices-l3](https://gitee.com/xkwxdyy/choices-l3) 和 [xchoices](https://gitee.com/xkwxdyy/xchoices) 项目。 +```latex +\begin{choices}[label-pos = top-left] + \item $\{2\}$ + \item $\{2, 3\}$ + \item $\{3, 4\}$ + \item $\{2, 3, 4\}$ +\end{choices} +``` +其中的可选参数使用 key–value 的方式进行设置,除了 `label-pos` 外还包括以下选项。 +- `index` 第一个选项标签的计数器的数字值(默认为 `1`)。 +- `column-sep` 选项列之间的最小间隔(默认 `1em`)。 +- `columns` 强制按照该列数排版选项,如果为 0 则自动选择合适的列数(默认 `0`)。 +- `label-align`(可选:`left`, `center`, `right`;默认 `right`)标签内容的对齐方式。 +- `label` 标签的格式,类似 `enumitem` 可以在 `\Roman` 等命令后加 `*` 生成数字(默认 `\Alph*.`)。 +- `label-pos` 标签相对于选项内容的位置;`auto` 表示自动选择:如果内容高度超过两行时(通常是图片)标签位于左居中 `left`,否则位于左上角跟首行文字对齐(`top-left`)(可选:`auto`, `top-left`, `left`, `bottom`;默认 `auto`)。 +- `label-align` 标签内部的对齐方式。(可选:`left`, `center`, `right`;默认 `right`) +- `label-sep` 标签与选项之间的距离(默认 `0.5em`)。 +- `label-width` 标签的宽度;如果宽度不足会自动调整为最长标签的宽度(默认 `0pt`)。 +- `max-columns` 选项的最大列数;排版选项时会优先尝试该列数,如果无法排下内容,依次将列数除以 2 并取整再进行尝试,直到可以排下全部选项(默认 `4`)。 + +这些选项可以使用 `\examsetup` 命令的 `choices` 层级进行全局设置,类似 `question`。 + +`exam-zh-choices` 模块还提供了 `\circlednumber` 命令调用中文字体生成带圈数字,该命令既可以接受 LaTeX2e 计数器的名字(如 `section`)作为参数,也可以接受数值表达式,比如 `\circlednumber{7}`,但仅限 0~50 的整数。而且有的字体可能没有提供 10 以上的字形,建议只对 10 以内的值使用。 + +如果用户需要使用其他形式的数字作为 `choices` 的标签,需要使用 `\AddChoicesCounter` 命令将其添加进 `label` 选项的识别范围内(类似 `enumitem` 的 `\AddEnumerateCounter`)。它的格式是 `\AddChoicesCounter{⟨LaTeX command⟩}{⟨internal command⟩}{⟨widest label⟩}`,其中 `⟨LaTeX command⟩` 是在 `label` 选项中的形式,`⟨internal command⟩` 是内部的实现,`⟨widest label⟩` 是最宽的标签。比如带圈数字的添加方法:`\AddChoicesCounter{\circlednumber}{\__examzh_choices_circled_number:n}{1}`。 + + +### 解答环境 `solution` 和分数命令 `\score` + +```latex +\begin{solution} + 函数的定义域为 $(0, +\infty)$, + 又 \[f^{\prime}(x) = 1 - \ln x-1 = -\ln x, \score{2}\] + 当 $x \in(0, 1)$ 时, $f^{\prime}(x) > 0$, 当 $x \in(1, +\infty)$ 时, $f^{\prime}(x) < 0$, + 故 $f(x)$ 的递增区间为 $(0,1)$, 递减区间为 $(1, +\infty)$. +\end{solution} +``` +用于解答题的解答环境,以及 `\score` 命令输出给分点,具体使用和相关键值请阅读手册。 + +### 正体的数学常数 + +按照国标,数学常数应使用正体。模板中提供了命令 `\eu` 和 `\iu` 分别表示自然对数的底“e”和虚数单位“i”。`\eu` 可以理解为 “e upright” 的缩写或者 “Euler's number” 的首字母,`\iu` 可以理解为 “i upright” 或 “imaginary unit” 的缩写,这样更方便记忆。圆周率“π”直接使用 `\uppi` 命令。 + + +### 密封线 + +```latex + \examsetup{ + sealline = { + show = true, + % scope = firstpage, + % scope = oddpage, + scope = everypage, + line-thickness = 1pt, + line-xshift = 8mm, + line-yshift = 0mm, + line-type = densely-dashed, + text = 密封线内不得答题, + text-xshift = 11mm, + text-yshift = 30mm, + circle-show = true, + circle-start = 0.07, + circle-end = 0.92, + circle-step = 3.5em, + circle-diameter = 3mm, + circle-xshift = 8mm, + odd-info-content = { + {\kaishu 姓名}:{\underline{\hspace*{8em}}}, + {\kaishu 准考证号}:{\underline{\hspace*{8em}}}, + {\kaishu 考场号}:{\underline{\hspace*{8em}}}, + {\kaishu 座位号}:{\underline{\hspace*{8em}}}, + }, + odd-info-seperator = \hspace*{3em}, + odd-info-align = center, + odd-info-xshift = 20mm, + odd-info-yshift = 0mm + } + } +``` + +具体密封线参数含义从参数名称基本可以知道,具体的可以看手册 `exam-zh-doc.pdf`。 + +## 反馈 + +欢迎反馈项目的问题或者改进建议。推荐使用发 issue 的形式,并且附上相关的代码和截图。 + + + +## 使用授权 + +本项目以 LaTeX Project Public License v1.3 协议发布。 + + + + +## 相关项目 + +- Philip Hirschhorn, `exam`: <https://www.ctan.org/pkg/exam> +- 鲍宏昌 `BHCexam`: <https://github.com/mathedu4all/bhcexam> +- 吕荐瑞 `jnuexam`: <https://www.ctan.org/pkg/jnuexam> +- @htharoldht `USTBExam`: <https://github.com/htharoldht/USTBExam> +- 唐绍东 `GEEexam`: <https://github.com/shaodongtang/gaokao_exam> +- 唐绍东 `CMC`: <https://github.com/shaodongtang/CMC> +- @sd44 `DANexam`: <https://github.com/sd44/DANexam> +- 胡振震 `simplexam`: <https://github.com/hushidong/simplexam> diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/back/about-author.tex b/Master/texmf-dist/doc/xelatex/exam-zh/doc/back/about-author.tex new file mode 100644 index 00000000000..0c37bb676c5 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/back/about-author.tex @@ -0,0 +1,9 @@ +% !TeX root = ../exam-zh-doc.tex + +\section{关于模版作者和维护者} + +\href{https://github.com/zepinglee}{zepinglee} 开发了模版前期的大框架和主要功能(\file{exam-zh-choices.sty}、\file{exam-zh-question.sty}、\file{exam-zh-font.sty} 等)。 + +\href{https://github.com/xkwxdyy}{xkwxdyy} 和 \href{https://github.com/ljguo1020}{ljguo} 为模版的后期维护者。 + +非常感谢 \href{https://github.com/syvshc}{syvshc} 在开发中提供的帮助!
\ No newline at end of file diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/back/development.tex b/Master/texmf-dist/doc/xelatex/exam-zh/doc/back/development.tex new file mode 100644 index 00000000000..a2ae5b67372 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/back/development.tex @@ -0,0 +1,14 @@ +% !TeX root = ../exam-zh-doc.tex + +\section{参与开发} + +\begin{itemize} + \item 如果您有任何改进意见或者功能需求,欢迎前往 \href{https://gitee.com/zepinglee/exam-zh/issues}{gitee 仓库 issues} 提交 issue + \item 欢迎 \cmd{fork} 本项目,提 \cmd{pr} 的形式参与开发 + \item 建议阅读 \href{https://zhuanlan.zhihu.com/typography-and-latex/}{muzimuzhi} 写的 \href{https://gitee.com/ustctug/ustcthesis/wiki/%E5%8F%82%E4%B8%8E%E5%BC%80%E5%8F%91}{参与开发} + \item 参考阅读 + \begin{itemize} + \item \href{https://www.zhihu.com/question/27017364/answer/34932199}{知乎:开发一个 LaTeX 宏包需要多少知识?} + \item \href{https://zhuanlan.zhihu.com/p/19669122}{The TeXbook 导读:从那头(多图杀猫的)狮子说起} + \end{itemize} +\end{itemize}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/back/main-changelog.tex b/Master/texmf-dist/doc/xelatex/exam-zh/doc/back/main-changelog.tex new file mode 100644 index 00000000000..381bbf0b135 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/back/main-changelog.tex @@ -0,0 +1,10 @@ +% !TeX root = ../exam-zh-doc.tex + +\section{主要更新} + +\begin{itemize} + \item 2022.2 开发基本框架和主要功能(题干、选择题) + \item 2022.4 开发字体模块 + \item 2022.6 开发密封线、草稿纸、评分框 + \item 2022.7 增加语文英语题型 +\end{itemize}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/back/package.tex b/Master/texmf-dist/doc/xelatex/exam-zh/doc/back/package.tex new file mode 100644 index 00000000000..e4373420b65 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/back/package.tex @@ -0,0 +1,25 @@ +% !TeX root = ../exam-zh-doc.tex + +\section{宏包依赖情况} + +\begin{itemize} + \item \pkg{expl3}:提供 \LaTeX3 环境 + \item \pkg{xparse}:自定义命令环境 + \item \pkg{filehook}:给宏包打补丁 + \item \cls{ctexbook}:\cls{exam-zh} 基于的文档类 + \item \pkg{etoolbox}:补丁 + \item \pkg{geometry}:页面设置 + \item \pkg{fontspec}:字体设置 + \item \pkg{xeCJK}、\pkg{xeCJKfntef}:中文相关 + \item \pkg{fancyhdr}:页眉页脚 + \item \pkg{lastpage}:总页数 + \item \pkg{amsmath}、\pkg{unicode-math}:数学类宏包 + \item \pkg{amsthm}:提供 \tn{qed} 相关 + \item \pkg{enumitem}:列表 + \item \pkg{tikz}、\pkg{tikzpagenodes}: \TikZ + \item \pkg{hyperref}:超链接 + \item \pkg{zref-savepos}:记录。用于 \tn{score} 命令 + \item \pkg{ulem}:下划线 + \item \pkg{tcolorbox}:彩框 + \item \pkg{varwidth}:“弹性”的 \env{minipage} +\end{itemize}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/body/cover.tex b/Master/texmf-dist/doc/xelatex/exam-zh/doc/body/cover.tex new file mode 100644 index 00000000000..c04f88a1f21 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/body/cover.tex @@ -0,0 +1,21 @@ +% !TeX root = ../exam-zh-doc.tex + +\begin{abstract} + 本项目提供了一个中国高考试卷样式的 \LaTeX 模板,旨在帮助中小学教师更方便地使用 \LaTeX。模板具有以下特性: + + \begin{enumerate} + \item 样式与内容尽可能分离; + \item 选择题选项可以自动排版成合适的列数; + \item 通过用户接口可以方便更改密封线样式; + \item 在 Windows, macOS 和 Linux 跨平台编译。 + \end{enumerate} +\end{abstract} + + +\begin{tikzpicture}[remember picture, overlay] + \node[opacity = 0.1,rotate = 30] at ([shift={(0,0)}]current page text area.center){ + \includegraphics[width=23cm]{firstpage.pdf} + }; +\end{tikzpicture} +\thispagestyle{plain} +\clearpage
\ No newline at end of file diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/body/installation.tex b/Master/texmf-dist/doc/xelatex/exam-zh/doc/body/installation.tex new file mode 100644 index 00000000000..dc0ac800147 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/body/installation.tex @@ -0,0 +1,153 @@ +% !TeX root = ../exam-zh-doc.tex + +\section{安装} + +\subsection{获取 \cls{exam-zh}} + +目前模块还处于开发阶段,用户目前以「下载发行版」的方式获取最新版本的 \cls{exam-zh}: + +\begin{enumerate} + \item 进入项目主页(\href{https://gitee.com/zepinglee/exam-zh}{gitee 项目主页} (界面见图~\ref{figure:gitee项目主页} ) + \item 在右侧一列有“发行版”(gitee),并且有一个标签图标并有“vx.x.x - 20xx-xx-xx”字样,表示最新的发行版版本和发布时间,点击即可查看相关信息(如果想查看历史所有发行版信息,可以点击“发行版”右侧的“全部”(gitee))。 + + 发行版中一般由以下信息构成(\href{https://gitee.com/zepinglee/exam-zh/releases}{gitee 发行版} 界面见图~\ref{figure:gitee发行版}) + \begin{itemize} + \item 更新文件的特别说明。如果没有,则表明此次更新只需要更新 \file{exam-zh.cls} 文件至最新\footnote{“更新 \meta{文件} 至最新”目前表示在发行版中下载最新版本的模板,并用其中所需要更新的 \meta{文件} 去替换本地的旧 \meta{文件}} 即可 + \item 更新日志。 主要为此次发行版与上次发行版的不同,一般为“Added”、“Changed”、“Fixed”等信息 + \item 模版及用户手册下载链接(“下载”部分)。一般用户只需要点击 \file{exam-zh-vx.x.x.zip} 进行模版下载即可,而下面的 \file{Source code} 为项目的整个源码,包括手册的源码,测试文件等,如果感兴趣的用户可以下载进行查看(当然,如果会使用 \cmd{git} 的用户也可以将整个 \cls{exam-zh} 项目 \cmd{clone} 下来查看) + \end{itemize} + \item 点击 \file{exam-zh-vx.x.x.zip} 进行下载,在本地解压即可 +\end{enumerate} + + +\begin{figure}[htbp] + \centering + \includegraphics[width = \textwidth]{gitee-main.png} + \caption{gitee 项目主页} + \label{figure:gitee项目主页} +\end{figure} + + +\begin{figure}[htbp] + \centering + \includegraphics[width = \textwidth]{gitee-release.png} + \caption{gitee 发行版} + \label{figure:gitee发行版} +\end{figure} + +% % \subsubsection{标准安装} + +% % 如果没有特殊理由,始终建议您使用宏包管理器安装 \cls{exam-zh}。 +% % 例如在 \TeXLive{} 中,执行(可能需要管理员权限) +% % \begin{shellexample}[morekeywords={tlmgr,install}] +% % tlmgr install exam-zh +% % \end{shellexample} +% % 即可完成安装。 + +% % 在 \TeXLive{} 和 \MiKTeX{} 中,您还可以通过图形界面进行安装, +% % 此处不再赘述。 + +% % \subsubsection{手动安装} + +% % 如果您需要从 CTAN 上自行下载并手动安装,较好的方法是使用 TDS +% % 安装包: +% % \begin{itemize} +% % \item 从 CTAN 上下载 \cls{exam-zh} 的 +% % \href{http://mirror.ctan.org/install/macros/latex/contrib/exam-zh.tds.zip}{TDS 安装包}; +% % \item 按目录结构将 \file{exam-zh.tds.zip} 中的文件复制到 \TeX{} +% % 发行版的本地 TDS 根目录; +% % \item 执行 \bashcmd{mktexlsr} 刷新文件名数据库以完成安装。 +% % \end{itemize} +% % % +% % 您也可以从源代码直接生成模板(不推荐): +% % \begin{itemize} +% % \item 打开 \href{https://gitee.com/stone-zeng/exam-zh}{项目主页}, +% % 点击“Code”按钮,并选择“Download ZIP”,下载 \file{exam-zh-main.zip}; +% % 如果您的电脑中安装有 git 程序,也可通过以下命令直接克隆代码仓库: +% % \begin{shellexample}[gobble=6,alsoletter={.},morekeywords={git,clone}] +% % git clone https://gitee.com/stone-zeng/exam-zh.git +% % \end{shellexample} +% % \item 解压并进入到 \file{source} 文件夹,执行以下命令以生成 +% % 模板的各组件: +% % \begin{shellexample}[gobble=6,morekeywords={xetex}] +% % xetex exam-zh.dtx +% % \end{shellexample} +% % \item 将生成的文档类(\file{.cls})、宏包(\file{.sty})以及 +% % 参数配置文件(\file{.def})复制到 \TeX{} 发行版本地 TDS 树 +% % 的 \path{texmf-local/tex/latex/exam-zh/} 目录下,并执行 +% % \bashcmd{mktexlsr} 刷新文件名数据库,方可完成安装。 +% % \item 使用 \cls{exam-zh} 撰写论文时,您还需要从代码仓库下的 +% % \file{testfiles/support} 目录中复制 \file{fudan-name.pdf} +% % 文件至工作目录,以确保封面中的校名图片可以正确显示。 +% % \end{itemize} + +% % \subsubsection{扁平化安装} + +% % 如果您不希望安装本模板,但需要立刻使用,也可以使用模板提供的安装脚本。 +% % 从 gitee 上获取代码仓库后,执行 \file{install-win.bat}(Windows 系统) +% % 或 \file{install-linux.sh}(Linux 系统),所有需要的文件便会在 +% % \file{thesis} 文件夹中生成。 + + +\subsection{模板组成} + +本模板主要包含核心文档类、参考文献格式文件以及用户文档等几个部分, +其具体组成见表~\ref{tab:exam-zh-main-components}。 + +\begin{table}[htbp] + \caption{\cls{exam-zh} 的主要组成部分} + \label{tab:exam-zh-main-components} + \centering + \small + \begin{tblr}{ + hline{1, 2, Z} = {1pt}, + width = \textwidth, + colspec = {X[3,l]X[5.5,l]}, + rows = {m} + } + \textbf{文件} & \textbf{功能说明} \\ + \file{exam-zh-doc.pdf} & 用户手册(本文档) \\ + \file{example-single.tex}、\file{example-multiple.tex} & 模板的主文件(同时也是示例文件),可据此为基础完成试卷编写 \\ + \file{exam-zh.cls} & 模板文档类 \\ + \file{exam-zh-choices.sty} & 模版的选择题模块宏包\\ + \file{exam-zh-question.sty} & 模版的题干模块宏包\\ + \file{exam-zh-font.sty} & 模版的字体模块宏包\\ + \file{exam-zh-symbols.sty} & 模版的符号模块宏包\\ + \file{exam-zh-chinese-english.sty} & 模版的语文英语模块宏包\\ + \file{README.md} & 简要自述 \\ + \file{CHANGELOG.md} & 模板更新日志 \\ + \file{LICENSE} & 模版发布许可证 + \end{tblr} +\end{table} + +% \begin{table}[htbp] +% \caption{\cls{exam-zh} 各目录的组成部分} +% \label{tab:exam-zh-sub-components} +% \centering +% \small +% \begin{tblr}{ +% hline{4,5,8,11,13} = {solid}, +% hline{1, 2, Z} = {1pt}, +% width = \textwidth, +% colspec = {X[1,l]X[3,l]X[3,l]}, +% rows = {m}, +% cell{2}{1} = {r=2}{m}, +% cell{5}{1} = {r=3}{m}, +% cell{8}{1} = {r=3}{m}, +% cell{11}{1} = {r=2}{m}, +% } +% \textbf{子目录} & \textbf{子目录中的文件} & \textbf{功能说明} \\ +% front & \file{abstract.tex} & 中英文摘要 \\ +% front & \file{notation.tex} & 符号表 \\ +% body & \file{chapter<number>.tex} & 正文的分文件 \\ +% back & \file{acknowledgements.tex} & 致谢 \\ +% back & \file{appendix.tex} & 附录 \\ +% back & \file{publications.tex} & 攻读学位期间取得的研究成果(博士)\\ +% logo & \file{ccnulogo.png} & “华中师范大学”字样 logo \\ +% logo & \file{masterlogo.png} & 硕士学位论文页眉 logo \\ +% logo & \file{doctorlogo.png} & 博士学位论文页眉 logo \\ +% copyright & \file{Originality_Copyright.pdf} & 本科学位论文原创性声明和使用授权说明 \\ +% copyright & \file{Originality_Copyright_master_doctor.pdf} & 硕博学位论文原创性声明和使用授权说明\\ +% figures & & 用户放置图片的目录\\ +% \end{tblr} +% \end{table}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/body/introduction.tex b/Master/texmf-dist/doc/xelatex/exam-zh/doc/body/introduction.tex new file mode 100644 index 00000000000..e072c02f8bc --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/body/introduction.tex @@ -0,0 +1,21 @@ +% !TeX root = ../exam-zh-doc.tex + +\section{介绍} + +试卷排版是中小学教师经常遇到的需求,目前在网上可以找到的试卷排版相关文类或宏包有: +\begin{itemize} + \item Philip Hirschhorn:\href{https://www.ctan.org/pkg/exam}{exam} + \item 吕荐瑞:\href{https://www.ctan.org/pkg/jnuexam}{jnuexam} + \item 胡振震:\href{https://github.com/hushidong/simplexam}{simplexam} + \item 鲍宏昌:\href{https://github.com/mathedu4all/bhcexam}{BHCexam} + \item htharoldht:\href{https://github.com/htharoldht/USTBExam}{USTBExam} + \item 唐绍东:\href{https://github.com/shaodongtang/gaokao_exam}{GEEexam} + \item 唐绍东:\href{https://github.com/shaodongtang/CMC}{CMC} + \item sd44:\href{https://github.com/sd44/DANexam}{DANexam} +\end{itemize} + +但是大部分没有经过系统设计以及后续进一步的维护,\href{https://www.ctan.org/pkg/exam}{exam} 大部分设置与国内习惯不同,调试配置起来增加用户的使用成本 \href{https://www.ctan.org/pkg/jnuexam}{jnuexam}、\href{https://github.com/shaodongtang/CMC}{CMC} 是比较“定制化”的,也无法顺利地进行迁移使用。 + +但是上述前人所做的工作值得参考,比如 \cls{exam-zh} 的 A4 和 A3 页面切换就参考了 \href{https://www.ctan.org/pkg/jnuexam}{jnuexam} 项目。 + +本模板将借鉴前辈经验,重新设计,并使用 \LaTeX3 编写,以适应 \TeX 技术发展潮流; 同时还将构建一套简洁的接口,方便用户使用。
\ No newline at end of file diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/body/usage.tex b/Master/texmf-dist/doc/xelatex/exam-zh/doc/body/usage.tex new file mode 100644 index 00000000000..264d618e53e --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/body/usage.tex @@ -0,0 +1,2578 @@ +% !TeX root = ../exam-zh-doc.tex + +\section{使用说明} + +\subsection{基本用法} + +以下是一份简单的 \TeX{} 文档,它演示了 \cls{exam-zh} 的最基本用法: + +\begin{latexcode}[deletetexcs={\documentclass}, + moretexcs={\chapter},morekeywords={\documentclass}, + emph={[2]document}] + % main.tex + \documentclass{exam-zh} + \begin{document} + \section{Welcome to exam-zh!} + 你好,\LaTeX{}! + \end{document} +\end{latexcode} + + +按照~\ref{subsec:编译方式} 小节中的方式编译,您应当得到一篇 1 页的文档。 + + +\subsection{编译方式} \label{subsec:编译方式} + +本模板不支持 \pdfTeX{} 引擎,仅支持使用 \XeLaTeX{} 。为了生成正确的目录、脚注以及交叉引用,您至少需要连续编译两次。 + +以下代码中,假设您的 \TeX{} 源文件名为 \file{example.tex}。请在命令行中执行 +\begin{shellcode}[morekeywords={xelatex}] + xelatex example +\end{shellcode} + + +\subsection{模板选项} + +所谓“模板选项”,指需要在引入文档类的时候指定的选项: +\begin{latexcode}[deletetexcs={\documentclass}, + morekeywords={\documentclass}] + \documentclass(*\oarg{模板选项}*){exam-zh} +\end{latexcode} + +有些模板选项为布尔型,它们只能在 \opt{true} 和 \opt{false} +中取值。对于这些选项,\kvopt{\meta{选项}}{true} 中的“|= true|” +可以省略。 + +\cls{exam-zh} 的模版选项接口与 \cls{ctexart} 相同,具体可 \cmd{texdoc ctex} 查阅 \pkg{ctex} 宏包文档。 + + +\subsection{命令和环境介绍} + +\subsubsection{正体的数学常数} + +\begin{function}{\eu} + 正体的自然对数的底“e”。 +\end{function} + +\begin{function}{\iu} + 正体的虚数单位“i”。 +\end{function} + +\tn{eu} 可以理解为 “e upright” 的缩写或者 “Euler's number” 的首字母,\tn{iu} 可以理解为 “i upright” 或 “imaginary unit” 的缩写,这样更方便记忆。 + +\begin{latexexample}{\tn{eu} 和 \tn{iu} 的效果} + $\eu \quad \iu$ +\end{latexexample} + + +\subsubsection{优化的命令环境} + +\cls{exam-zh} 对一些命令环境进行了优化,方便用户使用。 + +\begin{function}{\vec} + \begin{ccnusyntax}[emph={[1]vec}] + \vec(*\marg{content}*) + \end{ccnusyntax} + 向量命令。当只有一个字符的时候默认加粗斜体,两个及两个以上字符则加箭头。 +\end{function} + +\begin{latexexample}{\tn{vec} 示例} + $\vec{a} \quad \vec{AB}$ +\end{latexexample} + + +\subsubsection{中国化数学符号} + +中国的初高中教材中一些数学符号和 \LaTeX{} 默认的或者是 \pkg{amsmath} 等宏包提供的符号有差异,于是 \cls{exam-zh} 用 \TikZ 重新绘制了部分符号。 + +\begin{function}{\parallelogram} + 平行四边形。$\parallelogram$ +\end{function} + +\begin{function}{\parallel,\nparallel} + 平行和不平行。$\parallel \, \nparallel$ +\end{function} + +\begin{function}{\paralleleq} + 平行且相等。$\paralleleq$ + \examsetup{symbols/paralleleq-type = perpendicular} + \, $\paralleleq$。由~\ref{subsubsec:参数-中国化数学符号} 节的键值可以控制倾斜和垂直两个不同类型。 +\end{function} + +\begin{function}{\subset,\subset*} + 包含于(无横线)。|*| 表示不重定义。|\subset|: $\subset$, |\subset*|: $\subset*$ +\end{function} + +\begin{function}{\nsubset,\nsubset*} + 不包含于(无横线)。|*| 表示不重定义。|\nsubset|: $\nsubset$, |\nsubset*|: $\nsubset*$ +\end{function} + +\begin{function}{\subseteq,\subseteq*} + 包含于(有横线)。|*| 表示不重定义。|\subseteq|: $\subseteq$, |\subseteq*|: $\subseteq*$ +\end{function} + +\begin{function}{\nsubseteq,\nsubseteq*} + 不包含于(有横线)。|*| 表示不重定义。|\nsubseteq|: $\nsubseteq$, |\nsubseteq*|: $\nsubseteq*$ +\end{function} + +\begin{function}{\subsetneqq,\subsetneqq*} + 真子集。|*| 表示不重定义。|\subsetneqq|: $\subsetneqq$, |\subsetneqq*|: $\subsetneqq*$ +\end{function} + +\begin{function}{\nsubsetneqq} + 真子集的否定。|\nsubsetneqq|: $\nsubsetneqq$ +\end{function} + +\begin{function}{\supset,\supset*} + 反向包含于(无横线)。|*| 表示不重定义。|\supset|: $\supset$, |\supset*|: $\supset*$ +\end{function} + +\begin{function}{\nsupset,\nsupset*} + 反向不包含于(无横线)。|*| 表示不重定义。|\nsupset|: $\nsupset$, |\nsupset*|: $\nsupset*$ +\end{function} + +\begin{function}{\supseteq,\supseteq*} + 反向包含于(有横线)。|*| 表示不重定义。|\supseteq|: $\supseteq$, |\supseteq*|: $\supseteq*$ +\end{function} + +\begin{function}{\nsupseteq,\nsupseteq*} + 反向不包含于(有横线)。|*| 表示不重定义。|\nsupseteq|: $\nsupseteq$, |\nsupseteq*|: $\nsupseteq*$ +\end{function} + +\begin{function}{\supsetneqq,\supsetneqq*} + 反向真子集。|*| 表示不重定义。|\supsetneqq|: $\supsetneqq$, |\supsetneqq*|: $\supsetneqq*$ +\end{function} + +\begin{function}{\nsupsetneqq} + 反向真子集的否定。|\nsupsetneqq|: $\nsupsetneqq$ +\end{function} + +\begin{function}{\cap,\cap*} + 交集。|*| 表示不重定义。|\cap|: $\cap$, |\cap*|: $\cap*$。 +\end{function} + +\begin{function}{\cup,\cup*} + 并集。|*| 表示不重定义。|\cup|: $\cup$, |\cup*|: $\cup*$。 +\end{function} + + +\begin{function}{\sim,\sim*} + 相似。|*| 表示不重定义。|\sim|: $\sim$, |\sim*|: $\sim*$。 +\end{function} + + +\begin{function}{\nsim} + 不相似。|\nsim|: $\nsim$ +\end{function} + +\begin{function}{\cong,\cong*} + 全等。|*| 表示不重定义。|\cong|: $\cong$, |\cong*|: $\cong*$。 +\end{function} + + +\begin{function}{\ncong} + 不全等。|\ncong|: $\ncong$ +\end{function} + +% \begin{function}{} + +% \end{function} + +% \begin{function}{} + +% \end{function} + +% \begin{function}{} +% \begin{ccnusyntax}[emph={[1]}] + +% \end{ccnusyntax} +% \end{function} + + +% \subsubsection{中文字体} + +% 在语文试卷中可能需要不同的字体,比如楷体等,在 \cls{exam-zh} 中,不使用 \tn{kaiti} 等命令(一般会有报错),推荐使用 \tn{itshape} 等命令: +% \begin{latexexample}{不同字体命令效果} +% 测试 {\normalfont 测试} + +% 加粗 {\bfseries 测试} + +% 黑体 {\sffamily 测试} + +% 楷体 {\itshape 测试} +% \end{latexexample} + + +\subsubsection{抬头} \label{subsubsec:抬头} + +\begin{function}[added = 2022-07-03]{\information} + \begin{ccnusyntax}[emph={[1]information}] + \information(*\oarg{分隔符}*) + \end{ccnusyntax} + 水平的学生信息输入命令。\opt{分隔符} 默认为 |\quad|。使用示例: + \begin{latexcode}[gobble=4] + \information{ + 姓名\underline{\hspace{6em}}, + 座位号\underline{\hspace{15em}} + } + \end{latexcode} +\end{function} + +\begin{function}[added = 2022-07-03]{\warning} + \begin{ccnusyntax}[emph={[1]warning}] + \warning(*\marg{警告}*) + \end{ccnusyntax} + 警告命令。居中、黑体。使用示例: + \begin{latexcode}[gobble=4] + \warning{(在此卷上答题无效)} + \end{latexcode} +\end{function} + +\begin{function}[updated = 2022-07-03]{\secret} + \begin{ccnusyntax}[emph={[1]secret}] + \secret(*\oarg{格式命令}*) + \end{ccnusyntax} + “绝密 $\bigstar$ 启用前”。格式命令默认为 |\bfseries|。 +\end{function} + +\begin{function}[updated = 2022-07-03]{\goodluck} + \begin{ccnusyntax}[emph={[1]goodluck}] + \goodluck(*\oarg{祝福语}*) + \end{ccnusyntax} + 祝福语命令。祝福语默认为 |祝考试顺利|。 +\end{function} + +\begin{function}[updated = 2022-07-26]{notice 环境} + \begin{ccnusyntax}[emph={[2]notice}] + \begin{notice}(*\oarg{键值列表 1}\oarg{键值列表 2}*) + \item ... + \item ... + \end{notice} + \end{ccnusyntax} + 注意事项环境,是 \env{enumerate} 环境的包装,\meta{键值列表 2} 是传递给 \env{enumerate} 环境的可选参数。\meta{键值列表 1} 如下。 +\end{function} + +\begin{function}[added = 2022-07-26]{notice/label} + \begin{ccnusyntax}[emph={[1]label}] + label = (*\meta{label}*) + \end{ccnusyntax} + \env{notice} 环境的 \meta{label} 内容。默认为 |注意事项:|。 +\end{function} + +\begin{function}[added = 2022-07-26]{notice/label-format} + \begin{ccnusyntax}[emph={[1]label-format}] + label-format = (*\meta{format}*) + \end{ccnusyntax} + \env{notice} 环境的 \meta{label} 格式。默认为 |\sffamily \bfseries|。 +\end{function} + +\begin{function}[added = 2022-07-26]{notice/top-sep,notice/bottom-sep} + \begin{ccnusyntax}[emph={[1]top-sep,bottom-sep}] + top-sep = (*\meta{skip}*) + bottom-sep = (*\meta{skip}*) + \end{ccnusyntax} + \env{notice} 环境的上下方的弹性间距。默认均为 |.25em plus .25em minus .1em|。 +\end{function} + + +\begin{function}{\title} + \begin{ccnusyntax}[emph={[1]title}] + \title(*\marg{标题}*) + \end{ccnusyntax} + 标题。在 \tn{maketitle} 前使用。参数控制见~\ref{subsubsec:参数-抬头} 节。 +\end{function} + +\begin{function}[updated = 2022-07-24]{\subject} + \begin{ccnusyntax}[emph={[1]subject}] + \subject(*\oarg{宽度}\marg{科目}*) + \end{ccnusyntax} + 科目。在 \tn{maketitle} 前使用。可以为空或不写。\meta{科目} 内容在 \meta{宽度} 盒子内均匀分散。\meta{宽度} 默认为 \meta{科目} 宽度。参数控制见~\ref{subsubsec:参数-抬头} 节。 +\end{function} + +\begin{function}{\maketitle} + \begin{ccnusyntax}[emph={[1]maketitle}] + \maketitle + \end{ccnusyntax} + 生成标题和科目。 +\end{function} + + +\subsubsection{题干} \label{subsubsec:命令环境-题干} + +\begin{function}{question 环境} + \begin{ccnusyntax}[emph={[2]question}] + \begin{question}(*\oarg{键值列表}*) + <题干> + \end{question} + \end{ccnusyntax} + 选择题和填空题题干环境。 +\end{function} + +\begin{function}{problem 环境} + \begin{ccnusyntax}[emph={[2]problem}] + \begin{problem}(*\oarg{键值列表}*) + <题干> + \end{problem} + \end{ccnusyntax} + 解答题题干环境。 +\end{function} + +\cls{question} 和 \cls{problem} 环境的区别仅在于若 \kvopt{show-points}{true} (下面会介绍这个键值),则 \cls{question} 的题干会紧接在分数后而 \cls{problem} 的题干会在分数后新起一段后开始。 + +\ExplSyntaxOn +\keys_set:nn { exam-zh / question } + { + show-points = true + } +\ExplSyntaxOff +\begin{latexexample}{\cls{question} 和 \cls{problem} 环境的区别} + % \examsetup{ + % question/show-points = true + % } + \begin{question}[points = 1] + 题干测试 + \end{question} + \begin{problem}[points = 2] + 题干测试 + \end{problem} +\end{latexexample} + + +\ExplSyntaxOn +\keys_set:nn { exam-zh / question } + { + show-points = auto, + index = 0, + } +\keys_set:nn { exam-zh / paren } + { + show-paren = true + } +\ExplSyntaxOff +\begin{function}{\paren} + \begin{ccnusyntax}[emph={[2]\paren}] + \paren(*\oarg{答案}*) + \end{ccnusyntax} + 括号。\meta{答案} 可以受下面介绍的 \cmd{show-answer} 键值控制隐藏。会自动到行末尾,若单行内容较长会自动到下一行末尾 +\end{function} + + +\begin{latexexample}{\tn{paren} 的换行效果} + % \examsetup{ + % paren/show-paren = true + % } + \begin{question} + 短题干选项 \paren + \end{question} + \begin{question} + 长长长长长长长长长长长长长长长长长长长长长长长长长长长题干选项 \paren + \end{question} +\end{latexexample} + + +\begin{function}[added = 2022-07-20]{\AddQuestionCounter} + \begin{ccnusyntax}[emph={[2]\AddQuestionCounter}] + \AddQuestionCounter(*\marg{LaTeX command}*)(*\marg{internal command}*) + \end{ccnusyntax} + 如果用户需要使用其它形式的数字作为 \env{question} 环境和 \env{problem} 的标签,需要使用 \tn{AddQuestionCounter} 命令将其添加进 \opt{label} 选项的识别范围内(类似 \pkg{enumitem} 宏包的 \tn{AddEnumerateCounter} )。其中 \meta{LaTeX command} 是在 \opt{label} 选项中的形式,\meta{internal command} 是内部的实现,\meta{widest label} 是最宽的标签。比如带圈数字的添加方法: + \begin{latexcode}[gobble=4] + \AddQuestionCounter{\circlednumber}{\__examzh_question_circled_number:n} + \end{latexcode} +\end{function} + + + +\subsubsection{选择题} \label{subsubsec:命令环境-选择题} + +\begin{function}{choices 环境} + \begin{ccnusyntax}[emph={[2]choices}] + \begin{choices}(*\oarg{键值列表}*) + \item (*\meta{选项1}*) + \item (*\meta{选项2}*) + ... + \end{choices} + \end{ccnusyntax} + 选择题选项排版环境。\meta{键值列表} 见~\ref{subsubsec:参数-选择题}。 +\end{function} + +\begin{function}{\setchoices} + \begin{ccnusyntax}[emph={[2]\setchoices}] + \setchoices(*\marg{键值列表}*) + \end{ccnusyntax} + \env{choices} 环境的参数设置。和 + \begin{latexcode}[gobble=4] + \examsetup{ + choices = { + ... + } + } + \end{latexcode} + 效果相同。开发此命令原因是 \file{exam-zh-choices.sty} 是独立的模块,可以独立于 \cls{exam-zh} 外使用。 +\end{function} + +\begin{function}{\AddChoicesCounter} + \begin{ccnusyntax}[emph={[2]\AddChoicesCounter}] + \AddChoicesCounter(*\marg{LaTeX command}*)(*\marg{internal command}*) + \end{ccnusyntax} + 如果用户需要使用其它形式的数字作为 \env{choices} 环境的标签,需要使用 \tn{AddChoicesCounter} 命令将其添加进 \opt{label} 选项的识别范围内(类似 \pkg{enumitem} 宏包的 \tn{AddEnumerateCounter} )。其中 \meta{LaTeX command} 是在 \opt{label} 选项中的形式,\meta{internal command} 是内部的实现,\meta{widest label} 是最宽的标签。比如带圈数字的添加方法: + \begin{latexcode}[gobble=4] + \AddChoicesCounter{\circlednumber}{\__examzh_choices_circled_number:n} + \end{latexcode} +\end{function} + + +\begin{latexexample}{\tn{AddChoicesCounter} 使用示例} + \ExplSyntaxOn + \cs_new:Npn \test_counter:n #1 + { + \int_set:Nn \l_tmpa_int { \int_eval:n { #1 + 1 } } + \int_use:N \l_tmpa_int + } + \AddChoicesCounter \test \test_counter:n + \ExplSyntaxOff + \begin{choices}[label = \test*] + \item 1 + \item 2 + \end{choices} +\end{latexexample} + + +\begin{function}[updated = 2022-07-21]{\circlednumber,\circlednumber*} + \begin{ccnusyntax}[emph={[2]\circlednumber,\circlednumber*}] + \circlednumber(*\meta{数字或计数器名字}*) + \circlednumber*(*\meta{数字或计数器名字}*) + \end{ccnusyntax} + 带圈数字命令。不带星号的基于字体开发,带星号的基于 \TikZ 开发。|\circlednumber| 仅接受 0~50 的输入值,而 |\circlednumber*| 无限制。 + \begin{latexexample}{\tn{circlednumber} 的使用示例} + \circlednumber{1} \circlednumber{2} + \circlednumber*{1} \circlednumber*{2} + \circlednumber{page} \circlednumber{section} + \end{latexexample} +\end{function} + + +\subsubsection{填空题} + +\begin{function}[updated = 2022-07-27]{\fillin} + \begin{ccnusyntax}[emph={[2]\fillin}] + \fillin(*\oarg{键值列表}*)(*\oarg{答案}*) + \fillin*(*\oarg{键值列表}*)(*\oarg{答案}*) + \end{ccnusyntax} + 填空(下划线或括号)。\meta{答案} 可以受~\ref{subsubsec:参数-题干} 节的 \cmd{question/show-answer} 键值控制隐藏。\meta{键值列表} 见~\ref{subsubsec:参数-填空题} 节。\tn{fillin} 不可换行,但是会自动根据内容深度提升基线(比如排版分数不会“压线”);\tn{fillin*} 可以自动换行但是没有前者的功能,且 \tn{fillin*} 的换行功能只适用于 \kvopt{fillin/type}{line}、\kvopt{fillin/type}{paren} 和 \kvopt{fillin/type}{blank}。 +\end{function} + +注意,\tn{fillin} 命令经过处理,|\fillin[<1>]| 表示 |\fillin[<答案>]|(而不是通常定义两个可选参数命令,若只写一个的时候默认为第一个参数),而如果仅仅改变 \tn{fillin} 的类型(见下)而不输入答案,则需要使用 |\fillin[type=paren][]|。这样设计是考虑到:大部分时候都是无答案和输入答案两种情况,而单独改某一个 \tn{fillin} 的类型的情况很少,一般都是一些题目统一改,这个时候在需要修改的 \tn{fillin} 之前使用 + \begin{latexcode}[gobble=4] + \examsetup{ + fillin/type = paren + } + \end{latexcode} + 更改即可。如果后续需要换回来,则只需要使用 + \begin{latexcode}[gobble=4] + \examsetup{ + fillin/type = line + } + \end{latexcode} + 即可。 + +需要注意的是,如果 \tn{fillin} 的参数重含有不配对的中括号时会报错,如 |\fillin[$(−\infty, 1]$]|。这时需要使用大括号将内容保护起来:|\fillin[{$(−\infty, 1]$}]|。 + + +\begin{function}[added = 2022-07-21]{\AddFillinCounter} + \begin{ccnusyntax}[emph={[1]\AddFillinCounter}] + \AddFillinCounter(*\marg{LaTeX command}*)(*\marg{internal command}*) + \end{ccnusyntax} + 如果用户需要使用其它形式的数字作为 \kvopt{fillin/no-answer-type}{counter} 下 \opt{counter} 的标签,需要使用 \tn{AddFillinCounter} 命令将其添加进 \opt{label} 选项的识别范围内(类似 \pkg{enumitem} 宏包的 \tn{AddEnumerateCounter} )。其中 \meta{LaTeX command} 是在 \opt{label} 选项中的形式,\meta{internal command} 是内部的实现,\meta{widest label} 是最宽的标签。比如带圈数字的添加方法: + \begin{latexcode}[gobble=4] + \AddFillinCounter{\circlednumber}{\__examzh_fillin_circled_number:n} + \end{latexcode} +\end{function} + + +\subsubsection{判断题} + +作为 \tn{paren} 和 \tn{fillin} 命令的应用可以实现判断题效果: +\begingroup +\examsetup{ + question/index=0 +} +\begin{latexexample}{\tn{paren} 和 \tn{fillin} 命令的应用:判断题} + \examsetup{ + question/show-answer = true, + fillin/type = paren, + paren/show-paren = true + } + \newcommand{\true}{$\surd$} + \newcommand{\false}{$\times$} + + \begin{question} + $1 + 1 = 2$ \paren[对] + \end{question} + + \begin{question} + $1 + 1 = 3$ \fillin[错] + \end{question} + + \begin{question} + $1 + 1 = 2$ \paren[\true] + \end{question} + + \begin{question} + $1 + 1 = 3$ \fillin[\false] + \end{question} +\end{latexexample} +\endgroup + +由于使用“对错”还是“叉勾”因人而异,所以本模版没有固定,但结合上面的例子为用户提供一种“自定义”思路(基于 \tn{fillin} 为例): +\ExplSyntaxOn +\cs_undefine:N \true +\cs_undefine:N \false +\ExplSyntaxOff +\examsetup{ + question/index = 0 +} +\begingroup +\begin{latexexample}{填空题的自定义示例} +\examsetup{ + question/show-answer = true, + fillin/type = paren, + paren/show-paren = true +} + +\newcommand{\true}{\fillin[$\surd$]} +\newcommand{\false}{\fillin[$\times$]} + +\begin{question} + $1 + 1 = 2$ \true +\end{question} + +\begin{question} + $1 + 1 = 3$ \false +\end{question} +\end{latexexample} +\endgroup + + +\subsubsection{解答题} + +\begin{function}[added = 2022-07-01, updated = 2022-07-19]{solution 环境} + \begin{ccnusyntax}[emph={[2]solution}] + \begin{solution}(*\oarg{键值列表}*) + ... + \end{solution} + \end{ccnusyntax} + 解答题解答环境。\meta{键值列表} 见~\ref{subsubsec:参数-解答题} 节。 +\end{function} + + +下面所有和 \env{solution} 有关的示例都默认加载了 +\begin{latexcode} + \examsetup{solution/show-solution = true} +\end{latexcode} + +\examsetup{ + solution/show-solution=true +} + + +\begin{latexexample}{\env{solution} 环境示例} + \begin{solution} + 测试 + \end{solution} +\end{latexexample} + +\begin{function}[added = 2022-07-01]{\score} + \begin{ccnusyntax}[emph={[1]score}] + \score(*\marg{分数}*) + \end{ccnusyntax} + \env{solution} 环境中得分点的得分命令。若在行间公式使用,则需要编译两次产生虚线。 +\end{function} + +\begin{latexexample}{\tn{score} 命令示例} + \begin{solution} + 函数的定义域为 $(0, +\infty)$, + 又 \[f^{\prime}(x) = 1 - \ln x-1 = -\ln x, \score{2}\] + 当 $x \in(0, 1)$ 时, $f^{\prime}(x) > 0$, 当 $x \in(1, +\infty)$ 时, $f^{\prime}(x) < 0$. + + 故 $f(x)$ 的递增区间为 $(0,1)$, \score{1} 递减区间为 $(1, +\infty)$. \score{1} + \end{solution} +\end{latexexample} + + +\subsubsection{几个列表环境} + +\begin{function}[added = 2022-07-04]{step 环境} + \begin{ccnusyntax}[emph={[2]step}] + \begin{step} + \item ... + \item ... + \end{step} + \end{ccnusyntax} + “步骤”列表环境。 +\end{function} + +\begin{function}[added = 2022-07-04]{method 环境} + \begin{ccnusyntax}[emph={[2]method}] + \begin{method} + \item ... + \item ... + \end{method} + \end{ccnusyntax} + “方法”列表环境。 +\end{function} + +\begin{function}[added = 2022-07-04]{case 环境} + \begin{ccnusyntax}[emph={[2]case}] + \begin{case} + \item ... + \item ... + \end{case} + \end{ccnusyntax} + “情形”列表环境。 +\end{function} + +上述三个列表环境的参数控制见~\ref{subsubsec:参数-列表环境} + + + +\subsubsection{草稿纸} + +\begin{function}[added = 2022-07-03]{\draftpaper} + \begin{ccnusyntax}[emph={[1]draftpaper}] + \draftpaper(*\oarg{参数列表}*) + \end{ccnusyntax} + 草稿纸命令。使用一次产生一页的草稿纸。参数列表见~\ref{subsubsec:参数-草稿纸} +\end{function} + + +\subsubsection{方格} + +在密封线或者 \tn{information} 命令所输出的个人信息中,可能会需要输出方格(如 2021 年数学高考原卷),于是开发了下面的 \tn{examsquare} 命令。 + +\begin{function}[added = 2022-07-04]{\examsquare} + \begin{ccnusyntax}[emph={[1]examsquare}] + \examsquare(*\oarg{参数列表}\marg{方格个数}*) + \end{ccnusyntax} + 方格命令。参数列表见~\ref{subsubsec:参数-方格} +\end{function} + +\subsubsection{评分框} + +\begin{function}[added = 2022-07-04]{\scoringbox,\scoringbox*} + \begin{ccnusyntax}[emph={[1]scoringbox}] + \scoringbox + \scoringbox* + \end{ccnusyntax} + 评分框命令。可单独使用。相关键值见~\ref{subsubsec:参数-评分框} +\end{function} + +\begin{latexexample}{评分框示例} + \scoringbox \quad \scoringbox* +\end{latexexample} + + +\subsubsection{试卷合集} + +\cls{exam-zh} 不仅可以排版单份的试卷,也可以通过 \tn{chapter} 排版多份试卷,构成试卷合集。一般排版多份试卷会用到下面的命令: + +\begin{function}{\tableofcontents} + 目录 +\end{function} + +\begin{function}{\chapter} + 用于排一份的试卷标题。并可以用 \opt{page/show-chapter} 键值控制显示与否。 +\end{function} + +其余的见~\ref{subsubsec:抬头} 节。 + + +\subsubsection{选择标记题型} + +% 本节主要介绍 \file{exam-zh-chinese.sty} 模块中的命令环境的使用。要注意的是,此模块中大部分命令环境设计灵感和原因一般来自于语文学科,但是具体使用起来一般不限制于语文学科。 + +\begin{function}[added = 2022-07-19,updated = 2022-07-23]{select 环境} + \begin{ccnusyntax}[emph={[2]select}] + \begin{select}(*\oarg{键值列表}*) + \sitem (*\meta{未标记的选项}*) + \sitem (*\meta{未标记的选项}*) + \sitem* (*\meta{标记的选项}*) + ... + \end{select} + \end{ccnusyntax} + 选择标记环境。\meta{键值列表} 见~\ref{subsubsec:参数-选择标记题型} 节。 +\end{function} + +\begin{latexexample}{\env{select} 环境的基本使用} + 折 + \begin{select} + \sitem \pinyin{zhe2} + \sitem* \pinyin{she2} + \end{select} + 本 + + \begin{select} + \sitem* 疏 + \sitem 蔬 + \sitem 输 + \end{select} + 远 +\end{latexexample} + + +\subsubsection{连线题型} + +\begin{function}[added = 2022-07-19]{lineto 环境,\linelistset,\lineconnect} + \begin{ccnusyntax}[emph={[2]lineto,linelistset,lineconnect}] + \begin{lineto}(*\oarg{键值列表}*) + \linelistset(*\oarg{键值列表}\marg{list}*) + \linelistset(*\oarg{键值列表}\marg{list}*) + ... + \lineconnect(*\oarg{键值列表}\marg{list}*) + \lineconnect(*\oarg{键值列表}\marg{list}*) + ... + \end{lineto} + \end{ccnusyntax} + \env{lineto} 环境为连线环境,一个 \tn{linelistset} 命令设置一组内容,\tn{lineconnect} 连线。(\meta{list} 之间是西文逗号) + \begin{itemize} + \item \env{lineto} 环境: \meta{键值列表} 接口为 \env{tikzpicture} 环境的可选参数接口; + \item \tn{linelistset} 命令: \meta{键值列表} 见~\ref{subsubsec:参数-连线题型} 节; + \item \tn{lineconnect} 命令: \meta{键值列表} 接口为 \TikZ 的 \tn{draw} 命令的可选参数接口;\meta{list} 的格式为 |<name1>-<item num1>, <name2>-<item num2>, ...|,比如 |i-1, ii-3, iii-2| 等等(|<name>| 的含义见~\ref{subsubsec:参数-连线题型} 的 \opt{linto/name}),连接顺序为(以 |\lineconnect{i-1,ii-2,iii-3,iv-4}|为例): + \begin{itemize} + \item |i-1| 项的右侧与 |ii-2| 的左侧相连; + \item |ii-2| 项的右侧与 |iii-3| 的左侧相连; + \item |iii-3| 项的右侧与 |iv-4| 的左侧相连。 + \end{itemize} + 若 \tn{lineconnect} 的 \meta{list} 的内容变多也是同理。 + \end{itemize} +\end{function} + +示例见~\ref{subsubsec:参数-连线题型}。 + + + +\subsubsection{语文-材料文章} + + +\begin{function}[added = 2022-07-24]{material 环境} + \begin{ccnusyntax}[emph={[2]material}] + \begin{material}(*\oarg{键值列表}*) + <content> + \end{material} + \end{ccnusyntax} + 语文的材料/文章环境。\oarg{键值列表} 见~\ref{subsubsec:参数-语文} 节。 +\end{function} + +\begin{latexexample}{\env{material} 环境示例} + \begin{material}[title = \LaTeX{} 入门, author = 夏大鱼羊, format = {\sffamily \zihao{-4}},source={(摘自《夏大鱼羊自传》) \\ 2022年}] + 劳仑衣普桑,认至将指点效则机,最你更枝。想板整月正进好志次回总般,段然取向使张规军证回,世市总李率英茄持伴。用阶千样响领交出,器程办管据家元写,名其直金团。 + \end{material} +\end{latexexample} + + +\subsubsection{语文-古诗} + + +\begin{function}[added = 2022-07-24,updated = 2022-07-26]{poem 环境} + \begin{ccnusyntax}[emph={[2]poem}] + \begin{poem}(*\oarg{键值列表}*) + <content> + \end{poem} + \end{ccnusyntax} + 语文古诗环境。整体居中。\meta{content} 内置于 \env{tabular} 环境,所以建议用 |\\| 分行,且每行距离不能过长。\meta{键值列表} 见~\ref{subsubsec:参数-语文} 节。 +\end{function} + + +\begin{function}[added = 2022-07-24]{\zhu} + \begin{ccnusyntax}[emph={[2]zhu}] + \zhu(*\meta{注释}*) + \end{ccnusyntax} + 语文古诗环境的注释命令,只能在 \env{poem} 环境中使用。 +\end{function} + +\examsetup{ + poem/format = \itshape +} +\begin{latexexample}{\env{poem} 环境示例} + \begin{poem}[author = 杨巨源, title = {寄江州白司马\zhu{江州白司马:即白居易。}}] + 江州司马平安否? 惠远东林住得无 \zhu{惠远:东晋高僧,居庐山东林寺。}? \\ + 湓浦曾闻似衣带,庐峰见说胜香炉。\\ + 题诗岁晏离鸿断,望阙天遥病鹤孤。\\ + 莫谩拘牵雨花社\zhu{莫谩:不要。雨花社:指佛教讲经的集会。},青云依旧是前途。 + \end{poem} +\end{latexexample} + + +\subsubsection{英语-作文框} + +\begin{function}[added = 2022-07-26]{writingbox 环境} + \begin{ccnusyntax}[emph={[2]writingbox}] + \begin{writingbox}(*\oarg{键值列表}*) + <content> + \end{writingbox} + \end{ccnusyntax} + 英语作文框环境。\meta{键值列表} 接入 \env{tcolorbox} 环境的可选参数。 +\end{function} + +\begin{latexexample}{\env{writingbox} 环境示例} + \begin{writingbox}[title = {Youth and me}] + \vspace*{4em} + \end{writingbox} +\end{latexexample} + +\begin{latexexample}{\env{writingbox} 环境示例} + \begin{writingbox} + As the twins looked around them in disappointment, their father appeared. + + \vspace*{4em} + + The twins carried the breakfast upstairs and woke their mother up. + + \vspace*{4em} + \end{writingbox} +\end{latexexample} + + +\subsubsection{师生两版} \label{subsubsec:命令环境-师生两版} + +\begin{function}[added = 2022-07-21]{\ExamPrintAnswerSet} + \begin{ccnusyntax}[emph={[1]ExamPrintAnswerSet}] + \ExamPrintAnswerSet(*\oarg{cmd list}\marg{key-val list}*) + \end{ccnusyntax} + 设置用户对于师生两版的第二个版本 PDF 的导言区设置(可以自由选择第二个版本的键值设置,自由度高)。其中 \meta{cmd list} 和 \meta{key-val list} 的内容均用西文逗号分隔。\emph{注意第二个版本的设置是本 \file{.tex} 文件的设置基础之后加上 \tn{ExamPrintAnswerSet} 生成的,所以键值的使用要注意。(比如本 \file{.tex} 文件中设置了 \kvopt{fillin/show-answer}{true},如果 \tn{ExamPrintAnswerSet} 不写 \kvopt{fillin/show-answer}{false} 的话,则还是按照 \kvopt{fillin/show-answer}{true} 的设置编译的)} + \begin{itemize} + \item \meta{key-val list}:list 的项为 |foo/bar| 形式,为本手册中介绍的键值,会通过 \tn{ExamPrintAnswer} 传递给 \tn{examsetup} 命令; + \item \meta{cmd list}:list 的项为一般的命令 + \end{itemize} +\end{function} + +示例如下: +\begin{latexcode} + \ExamPrintAnswerSet[ + \geometry{showframe} + ]{ + page/size=a3paper, + solution/show-solution=true, + paren/show-paren=true, + paren/show-answer=true + } +\end{latexcode} + + +\begin{function}[added = 2022-07-21]{\ExamPrintAnswer} + \begin{ccnusyntax}[emph={[1]ExamPrintAnswer}] + \ExamPrintAnswer + \end{ccnusyntax} + 用于“生效” \tn{ExamPrintAnswerSet} 中的设置。可以在导言区使用,但是一般不需要用户单独使用(因为集成在师生两版的代码实现中)。 +\end{function} + +如何实现师生两版?在使用 \tn{ExamPrintAnswerSet} 设置完后,只需要通过编译方式的不同即可实现: +\begin{itemize} + \item 正常编译 +\begin{shellcode} + xelatex <jobname> +\end{shellcode} + \item 师生两版 +\begin{shellcode} + xelatex -shell-escape <jobname> +\end{shellcode} + +\end{itemize} + +关于师生两版的键值设置见~\ref{subsubsec:参数-师生两版} 节。 + + + +\subsection{参数设置} + +\begin{function}{\examsetup} + \begin{ccnusyntax}[morekeywords={\examsetup}] + \examsetup(*\marg{键值列表}*) + \end{ccnusyntax} + 本模板提供了一系列选项,可由您自行配置。载入文档类之后,以下所有选项均可通过统一的命令 \cs{examsetup} 来设置。 +\end{function} + +\cs{examsetup} 的参数是一组由(英文)逗号隔开的选项列表,列表中的 +选项通常是 \kvopt{\meta{key}}{\meta{value}} 的形式。部分选项的 +\meta{value} 可以省略。对于同一项,后面的设置将会覆盖前面的设置。 +在下文的说明中,将用\textbf{粗体}表示默认值。 + +\cs{examsetup} 采用 \LaTeX3 风格的键值设置,支持不同类型以及多种 +层次的选项设定。键值列表中,“|=|”左右的空格不影响设置;但需注意, +参数列表中\emph{不可以出现空行}。 + +与模板选项相同,布尔型的参数可以省略 \kvopt{\meta{选项}}{true} +中的“\kvopt{}{true}”。 + +另有一些选项包含子选项,如 \opt{page} 和 \opt{choices} 等。它们可以 +按如下两种等价方式来设定: + +\begin{latexcode}[morekeywords={\examsetup}, + emph={[1]page,size,choices,column-sep,label-pos,label-sep,max-columns}] + \examsetup{ + page = { + size = a3paper + }, + choices = { + column-sep = 1em, + label-pos = auto, + label-sep = 0.5em, + max-columns = 4 + } + } +\end{latexcode} + +或者 + +\begin{latexcode}[morekeywords={\examsetup}, + emph={[1]page,size,choices,column-sep,label-pos,label-sep,max-columns}] + \examsetup{ + page/size = a3paper, + choices/column-sep = 1em, + choices/label-pos = auto, + choices/label-sep = 0.5em, + choices/max-columns = 4 + } +\end{latexcode} + + +注意 “|/|” 的前后均不可以出现空白字符。 + + +\subsubsection{风格设置} + +\begin{function}[added = 2022-07-20]{style} + \begin{ccnusyntax}[emph={[1]style}] + style = (*\marg{键值列表}*) + style/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含许多子项目,具体内容见下。 +\end{function} + +\begin{function}[added = 2022-07-20]{style/fullwidth-stop} + \begin{ccnusyntax}[emph={[1]fullwidth-stop}] + fullwidth-stop = (*<(catcode)|false>*) + \end{ccnusyntax} + 是否将 |。| 映射为 |.|。\opt{catcode} 表示映射;\opt{false} 表示不映射。 +\end{function} + +\begin{function}[added = 2022-07-24]{style/footnote-style} + % 这里奇怪的东西是用来控制对齐的。ccnusyntax 会吃掉开头的几个空格,因此这里用 X 来占位。 + \begin{ccnusyntax}[emph={[1]footnote-style}] + footnote-style = (*<plain|\\ + XXXX\mbox{}~~~~~~~~~~~~~~~~~(libertinus)|libertinus*|libertinus-sans|\\ + XXXX\mbox{}~~~~~~~~~~~~~~~~~pifont|pifont*|pifont-sans|pifont-sans*|\\ + XXXX\mbox{}~~~~~~~~~~~~~~~~~xits|xits-sans|xits-sans*>*) + \end{ccnusyntax} + 设置脚注编号样式。西文字体设置会影响其默认取值。因此,要使得该选项生效,需将其放置在 \opt{font} 选项之后。带有 sans 的为相应的无衬线字体版本。带有 * 的为 阴文样式(即黑底白字)。 +\end{function} + + +\subsubsection{师生两版} \label{subsubsec:参数-师生两版} + +\begin{function}[added = 2022-07-22]{style/student-version-suffix} + \begin{ccnusyntax}[emph={[1]student-version-suffix}] + student-version-suffix = (*\meta{suffix}*) + \end{ccnusyntax} + 师生两版的第二个版本的 PDF 名称的后缀。即第二个 PDF 的名称为 |<jobname><suffix>.pdf|。默认值为 |_student_version|。 +\end{function} + +\begin{function}[added = 2022-07-22]{style/student-version-cleanaux} + \begin{ccnusyntax}[emph={[1]student-version-cleanaux}] + student-version-cleanaux = (*\TTF*) + \end{ccnusyntax} + 师生两版的编译是否自动清除中途文件。 +\end{function} + + + +\subsubsection{中国化数学符号} \label{subsubsec:参数-中国化数学符号} + + +\begin{function}{symbols} + \begin{ccnusyntax}[emph={[1]symbols}] + symbols = (*\marg{键值列表}*) + symbols/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含许多子项目,用于设置中国化符号。具体内容见下。 +\end{function} + +\begin{function}{symbols/paralleleq-type} + \begin{ccnusyntax}[emph={[1]paralleleq-type}] + paralleleq-type = (*<(slant)|perpendicular>*) + \end{ccnusyntax} + \tn{paralleleq} 命令的效果。\opt{slant} 表示上方的线是倾斜的;\opt{perpendicular} 表示上方的线是垂直的。 +\end{function} + +\begin{function}[added = 2022-07-17]{symbols/change-frac-style,symbols/change-dfrac-style} + \begin{ccnusyntax}[emph={[1]change-frac-style,change-dfrac-style}] + change-frac-style = (*<\TFF>*) + change-dfrac-style = (*<\TFF>*) + \end{ccnusyntax} + 是否重定义 \tn{frac} 命令和 \tn{dfrac} 命令。重定义后的 \tn{frac} 或 \tn{dfrac} 的分子分母两边会有额外间距。 +\end{function} + +\begin{function}[added = 2022-07-17]{symbols/frac-add,symbols/dfrac-add} + \begin{ccnusyntax}[emph={[1]frac-add,dfrac-add}] + frac-add = (*\meta{muskip}*) + dfrac-add = (*\meta{muskip}*) + \end{ccnusyntax} + 分别为 \kvopt{symbols/change-frac-style}{true} 和 \kvopt{symbols/change-dfrac-style}{true} 时,\tn{frac} 和 \tn{dfrac} 分子分母左右两边增加的额外间距,左右相同,默认为 |5mu|。 +\end{function} + + +\subsubsection{页面设置} + +\begin{function}{page} + \begin{ccnusyntax}[emph={[1]page}] + page = (*\marg{键值列表}*) + page/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含许多子项目,用于设置页面设置。具体内容见下。 +\end{function} + +\begin{function}{page/size} + \begin{ccnusyntax}[emph={[1]size}] + size = (*<a3paper|(a4paper)>*) + \end{ccnusyntax} + 试卷尺寸。\opt{a4paper} 表示一页为 A4 纸大小;\opt{a3paper} 表示一页为 A3 纸大小,内容为连续两页 A4 拼接。此设置只能放在导言区。 +\end{function} + +\begin{function}[updated = 2022-07-24]{page/foot-type} + \begin{ccnusyntax}[emph={[1]foot-type}] + foot-type = (*<common|(separate)>*) + \end{ccnusyntax} + \kvopt{page/size}{a3paper} 时页脚的类型。\opt{common} 表示两页 A4 纸(即一页 A3 纸)共用一个页脚;\opt{separate} 表示两页 A4 纸各自有一个页脚。 +\end{function} + +\begin{function}[added = 2022-07-04]{page/foot-content} + \begin{ccnusyntax}[emph={[1]foot-content}] + foot-content = (*\meta{页脚格式}*) + \end{ccnusyntax} + 页脚内容设置。 + \begin{itemize} + \item 若\meta{页脚格式} 中不含西文分号 |;|,则页脚内容为 \meta{页脚格式} 直接输出; + \item 若\meta{页脚格式} 中含一个西文分号 |;|,如 |foo;bar|,则页脚为 |foo<the page>bar|,即西文分号代替了页码的位置; + \item 若\meta{页脚格式} 中含两个西文分号 |;|,如 |foo;bar;baz|,则页脚为 |foo<the page>bar<total page>baz|,即第一个西文分号代替了页码的位置,第二个代替了总页码。 + \end{itemize} +\end{function} + +\begin{function}[added = 2022-07-04]{page/show-columnline} + \begin{ccnusyntax}[emph={[1]show-columnline}] + show-columnline = (*\TTF*) + \end{ccnusyntax} + \kvopt{page/size}{a3paper} 时是否显示两页 A4 之间的中间竖线。 +\end{function} + +\begin{function}[added = 2022-07-04]{page/columnline-width} + \begin{ccnusyntax}[emph={[1]columnline-width}] + columnline-width = (*\meta{dimension}*) + \end{ccnusyntax} + \kvopt{page/show-columnline}{true} 时竖线的宽度。默认为 |0.4pt|。 +\end{function} + + +\begin{function}[added = 2022-07-11]{page/show-chapter} + \begin{ccnusyntax}[emph={[1]show-chapter}] + show-chapter = (*\TTF*) + \end{ccnusyntax} + 是否显示 \tn{chapter} 的内容。\kvopt{show-chapter}{true} 表示 \tn{chapter} 的内容会正常出现以及录入目录并可以通过超链接跳转;\kvopt{show-chapter}{false} 表示 \tn{chapter} 的内容不出现但是会被录入目录并可以通过超链接跳转。 +\end{function} + + +\subsubsection{密封线} \label{subsubsec:参数-密封线} + +\begin{function}{sealline} + \begin{ccnusyntax}[emph={[1]sealline}] + sealline = (*\marg{键值列表}*) + sealline/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含许多子项目,用于设置密封线。具体内容见下。 +\end{function} + + +\begin{function}{sealline/show} + \begin{ccnusyntax}[emph={[1]show}] + show = (*\TFF*) + \end{ccnusyntax} + 是否显示密封线。 +\end{function} + +\begin{function}[updated = 2022-07-26]{sealline/scope,sealline/type} + \begin{ccnusyntax}[emph={[1]scope,type}] + scope = (*<firstpage|oddpage|(everypage)|first-and-last|mod-2|mod-3|mod-4|mod-6>*) + type = (*<firstpage|oddpage|(everypage)|first-and-last|mod-2|mod-3|mod-4|mod-6>*) + \end{ccnusyntax} + 密封线的作用范围。\opt{scope} 和 \opt{type} 同效。\opt{firstpage} 表示仅在第一页有密封线;\opt{oddpage} 表示仅有奇数页有密封线,在页面左侧;\opt{everypage} 表示每页都有密封线,奇数页密封线在页面左侧,偶数页密封线在页面右侧;\opt{first-and-last} 表示只有第一页和最后一页有;\opt{mod-x} 表示满足 $y \mod x \equiv 1$ 的页数 $y$ 中有密封线。 +\end{function} + + +下面介绍密封线的具体细节参数控制。在此之前,先对参数进行说明,若为: +\begin{latexcode} + foo = ... + odd-foo = ... + even-foo = ... +\end{latexcode} + +则 +\begin{itemize} + \item \opt{foo} 表示统一控制奇偶页的密封线参数; + \item \opt{odd-foo} 表示控制奇数页的密封线参数; + \item \opt{even-foo} 表示控制偶数页的密封线参数。 +\end{itemize} + +若仅有 +\begin{latexcode} + odd-foo = ... +\end{latexcode} + +则表示该参数仅作用于奇数页的密封线。 + +关于下面出现的“水平”或“垂直”,不额外说明就默认是正常的参考系,即“左右”为“水平”、“上下”为“垂直”。 + + +\begin{function}{sealline/line-thickness,sealline/odd-line-thickness,sealline/even-line-thickness} + \begin{ccnusyntax}[emph={[1]line-thickness,odd-line-thickness,even-line-thickness}] + line-thickness = (*\meta{dimension}*) + odd-line-thickness = (*\meta{dimension}*) + even-line-thickness = (*\meta{dimension}*) + \end{ccnusyntax} + 密封线的线厚度。 +\end{function} + +\begin{function}{sealline/line-xshift,sealline/odd-line-xshift,sealline/even-line-xshift} + \begin{ccnusyntax}[emph={[1]line-xshift,odd-line-xshift,even-line-xshift}] + line-xshift = (*\meta{dimension}*) + odd-line-xshift = (*\meta{dimension}*) + even-line-xshift = (*\meta{dimension}*) + \end{ccnusyntax} + 密封线的水平偏移量。默认为 |8mm|。\meta{dimension} 为正值时,奇数页密封线往左偏移,偶数页密封线往右偏移。 +\end{function} + +\begin{function}{sealline/line-yshift,sealline/odd-line-yshift,sealline/even-line-yshift} + \begin{ccnusyntax}[emph={[1]line-yshift,odd-line-yshift,even-line-yshift}] + line-yshift = (*\meta{dimension}*) + odd-line-yshift = (*\meta{dimension}*) + even-line-yshift = (*\meta{dimension}*) + \end{ccnusyntax} + 密封线的垂直伸缩量。默认为 |0mm|,奇偶页效果相同。\meta{dimension} 为正值时,密封线上下同时“往内缩 \meta{dimension} 长度”。0mm 的效果是密封线长度为版心高度。 +\end{function} + +\begin{function}{sealline/line-type,sealline/odd-line-type,sealline/even-line-type} + \begin{ccnusyntax}[emph={[1]line-type,odd-line-type,even-line-type}] + line-type = (*\meta{dimension}*) + odd-line-type = (*\meta{dimension}*) + even-line-type = (*\meta{dimension}*) + \end{ccnusyntax} + 密封线的类型。参考了 \TikZ 的线类型,主要有以下几种,从名称可以看出几种线的类型和效果,这里就不做解释: +\end{function} +\begin{choices}[label = \circlednumber*] + \item solid + \item dotted + \item densely-dotted + \item loosely-dotted + \item dashed + \item densely-dashed + \item loosely-dashed + \item dash-dot + \item densely-dash-dot + \item loosely-dash-dot + \item dash-dot-dot + \item densely-dash-dot-dot + \item loosely-dash-dot-dot +\end{choices} + + +\begin{function}{sealline/text,sealline/odd-text,sealline/even-text} + \begin{ccnusyntax}[emph={[1]text,odd-text,even-text}] + text = (*\meta{content}*) + odd-text = (*\meta{content}*) + even-text = (*\meta{content}*) + \end{ccnusyntax} + 沿着密封线的文字,效果为均匀分散,类似于 \tn{makebox} 的 \cmd{s} 选项。默认值为 |密封线内不得答题|。\meta{content} 中不能有命令,字体设置要通过 \opt{sealline/text-format} 设置。 +\end{function} + +\begin{function}[added = 2022-07-24]{sealline/text-width,sealline/odd-text-width,sealline/even-text-width} + \begin{ccnusyntax}[emph={[1]text-width,odd-text-width,even-text-width}] + text-width = (*\meta{dimension}*) + odd-text-width = (*\meta{dimension}*) + even-text-width = (*\meta{dimension}*) + \end{ccnusyntax} + 沿着密封线的文字的宽度(此时以试卷顺时针转 90 度为参考系)。默认值为 |0.8\textheight|。 +\end{function} + + +\begin{function}[added = 2022-07-24]{sealline/text-format,sealline/odd-text-format,sealline/even-text-format} + \begin{ccnusyntax}[emph={[1]text-format,odd-text-format,even-text-format}] + text-format = (*\meta{font}*) + odd-text-format = (*\meta{font}*) + even-text-format = (*\meta{font}*) + \end{ccnusyntax} + 沿着密封线的文字的字体设置。可以是 \tn{zihao} 或颜色或字体设置等。默认为 |\zihao{4}\sffamily|。 +\end{function} + + +\begin{function}{sealline/text-xshift,sealline/odd-text-xshift,sealline/even-text-xshift} + \begin{ccnusyntax}[emph={[1]text-xshift,odd-text-xshift,even-text-xshift}] + text-xshift = (*\meta{dimension}*) + odd-text-xshift = (*\meta{dimension}*) + even-text-xshift = (*\meta{dimension}*) + \end{ccnusyntax} + 沿着密封线的文字的水平偏移量。默认为 |11mm|。\meta{dimension} 为正值时,奇数页文字往左偏移,偶数页文字往右偏移。 +\end{function} + + +\begin{function}[updated = 2022-07-24]{sealline/text-yshift,sealline/odd-text-yshift,sealline/even-text-yshift} + \begin{ccnusyntax}[emph={[1]text-yshift,odd-text-yshift,even-text-yshift}] + text-yshift = (*\meta{dimension}*) + odd-text-yshift = (*\meta{dimension}*) + even-text-yshift = (*\meta{dimension}*) + \end{ccnusyntax} + 沿着密封线的文字的垂直偏移量。默认为 |0pt|。\meta{dimension} 为正时,奇数页的文字往上移动,而偶数页有两种情况: + \begin{itemize} + \item \kvopt{sealline/text-direction-vertical}{true} 时,方向和奇数页相同(因为此时文字排版效果奇偶相同); + \item \kvopt{sealline/text-direction-vertical}{false} 时,方向和奇数页相反(因为此时文字排版效果奇偶相反); + \end{itemize} +\end{function} + + +\begin{function}[added = 2022-07-24]{sealline/text-xscale,sealline/odd-text-xscale,sealline/even-text-xscale} + \begin{ccnusyntax}[emph={[1]text-xscale,odd-text-xscale,even-text-xscale}] + text-xscale = (*\meta{float point}*) + odd-text-xscale = (*\meta{float point}*) + even-text-xscale = (*\meta{float point}*) + \end{ccnusyntax} + 沿着密封线的文字的水平放缩(以旋转试卷为参考系)。默认为 |1.0|。 +\end{function} + +\begin{function}[added = 2022-07-24]{sealline/text-yscale,sealline/odd-text-yscale,sealline/even-text-yscale} + \begin{ccnusyntax}[emph={[1]text-yscale,odd-text-yscale,even-text-yscale}] + text-yscale = (*\meta{float point}*) + odd-text-yscale = (*\meta{float point}*) + even-text-yscale = (*\meta{float point}*) + \end{ccnusyntax} + 沿着密封线的文字的垂直放缩(以旋转试卷为参考系)。默认为 |0.8|。 +\end{function} + +\begin{function}[added = 2022-07-24]{sealline/text-direction-vertical,sealline/odd-text-direction-vertical,sealline/even-text-direction-vertical} + \begin{ccnusyntax}[emph={[1]text-direction-vertical,odd-text-direction-vertical,even-text-direction-vertical}] + text-direction-vertical = (*\TFF*) + odd-text-direction-vertical = (*\TFF*) + even-text-direction-vertical = (*\TFF*) + \end{ccnusyntax} + 沿着密封线的文字是否垂直从上往下不旋转显示文字内容。\opt{true} 表示奇偶页均为从上往下显示文字,且文字不旋转;\opt{false} 表示奇数页逆时针转 90 度并从下往上(若以旋转试卷为参考,即为从左往右)显示文字内容,偶数页顺时针转 90 度并从上往下显示文字内容。 +\end{function} + + +\begin{function}{sealline/circle-show,sealline/odd-circle-show,sealline/even-circle-show} + \begin{ccnusyntax}[emph={[1]circle-show,odd-circle-show,even-circle-show}] + circle-show = (*\TTF*) + odd-circle-show = (*\TTF*) + even-circle-show = (*\TTF*) + \end{ccnusyntax} + 密封线上的圆的显示与否。 +\end{function} + +\begin{function}{sealline/circle-start,sealline/odd-circle-start,sealline/even-circle-start,sealline/circle-end,sealline/odd-circle-end,sealline/even-circle-end} + \begin{ccnusyntax}[emph={[1]circle-start,odd-circle-start,even-circle-start,circle-end,odd-circle-end,even-circle-end}] + circle-start = (*\meta{float point}*) + odd-circle-start = (*\meta{float point}*) + even-circle-start = (*\meta{float point}*) + circle-end = (*\meta{float point}*) + odd-circle-end = (*\meta{float point}*) + even-circle-end = (*\meta{float point}*) + \end{ccnusyntax} + 密封线上的圈的起始点占线总场的比例,\meta{float point} 的范围为 $[0,1]$。分别默认为 |0.07| 和 |0.92| 。\opt{circle-start} 和 \opt{circle-end} 的值分别表示圆圈的起点和终点在线(以页面垂直的北到南方向为正方向)上的比例。 +\end{function} + +\begin{function}{sealline/circle-step,sealline/odd-circle-step,sealline/even-circle-step} + \begin{ccnusyntax}[emph={[1]circle-step,odd-circle-step,even-circle-step}] + circle-step = (*\meta{dimension}*) + odd-circle-step = (*\meta{dimension}*) + even-circle-step = (*\meta{dimension}*) + \end{ccnusyntax} + 密封线上的两个圈之间的距离。默认为 |3.5em|。若倒数第二个圈加上 \opt{circle-step} 的值“超出了密封线的范围”,则最后一个圈并不会显示。 +\end{function} + +\begin{function}{sealline/circle-diameter,sealline/odd-circle-diameter,sealline/even-circle-diameter} + \begin{ccnusyntax}[emph={[1]circle-diameter,odd-circle-diameter,even-circle-diameter}] + circle-diameter = (*\meta{dimension}*) + odd-circle-diameter = (*\meta{dimension}*) + even-circle-diameter = (*\meta{dimension}*) + \end{ccnusyntax} + 密封线上的圆的直径。默认为 |3mm|。 +\end{function} + + +\begin{function}{sealline/circle-xshift,sealline/odd-circle-xshift,sealline/even-circle-xshift} + \begin{ccnusyntax}[emph={[1]circle-xshift,odd-circle-xshift,even-circle-xshift}] + circle-xshift = (*\meta{dimension}*) + odd-circle-xshift = (*\meta{dimension}*) + even-circle-xshift = (*\meta{dimension}*) + \end{ccnusyntax} + 密封线上的圆的水平偏移量。默认为 |8mm|。 +\end{function} + +\begin{function}{sealline/odd-info-content} + \begin{ccnusyntax}[emph={[1]odd-info-content}] + odd-info-content = (*\marg{comma list}*) + \end{ccnusyntax} + 奇数页密封线旁的学生信息。输入内容需要用 |{}| 包起来并用西文逗号隔开。示例(也是默认)如下: + \begin{latexcode}[gobble=4] + \examsetup{ + odd-info-content = { + {\kaishu 姓名}:{\underline{\hspace*{8em}}}, + {\kaishu 准考证号}:{\underline{\hspace*{8em}}}, + {\kaishu 考场号}:{\underline{\hspace*{8em}}}, + {\kaishu 座位号}:{\underline{\hspace*{8em}}} + } + } + \end{latexcode} + 其中需要注意的是:由于接口沿用的是 \TikZ 的 \cmd{decoration} 的 \cmd{text} 接口,所以命令必须要用 |{}| 包起来(具体原因感兴趣的用户可以 \cmd{texdoc tikz} 自行查阅),如所示的 |{\underline{\hspace*{8em}}}| +\end{function} + + +\begin{function}{sealline/odd-info-separator} + \begin{ccnusyntax}[emph={[1]odd-info-separator}] + odd-info-separator = (*\meta{separator}*) + \end{ccnusyntax} + 奇数页密封线旁的学生信息的分隔符。即上方 \cmd{odd-info-content} 几个内容之间的分隔符,默认为 |\hspace*{3em}|,即用 |3em| 的空白分隔。一般为水平空白。 +\end{function} + + +\begin{function}{sealline/odd-info-align} + \begin{ccnusyntax}[emph={[1]odd-info-align}] + odd-info-align = (*<left|(center)|right>*) + \end{ccnusyntax} + 奇数页密封线旁的学生信息的对齐方式。将试卷顺时针方向旋转 90 度视角后为参考(即此时密封线为水平线)。 +\end{function} + +\begin{function}{sealline/odd-info-xshift} + \begin{ccnusyntax}[emph={[1]odd-info-xshift}] + odd-info-xshift = (*\meta{dimension}*) + \end{ccnusyntax} + 奇数页密封线旁的学生信息的水平偏移量。默认值为 |20mm| +\end{function} + +\begin{function}{sealline/odd-info-yshift} + \begin{ccnusyntax}[emph={[1]odd-info-yshift}] + odd-info-yshift = (*\meta{dimension}*) + \end{ccnusyntax} + 奇数页密封线旁的学生信息的垂直偏移量。默认值为 |0mm|,此时若 \kvopt{odd-info-align}{left} 则 \cmd{odd-info-content} 的左侧与版心底部对齐。 +\end{function} + + + +\subsubsection{方格} \label{subsubsec:参数-方格} + +\begin{function}{square} + \begin{ccnusyntax}[emph={[1]square}] + square = (*\marg{键值列表}*) + square/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含许多子项目,用于设置方格。具体内容见下。 +\end{function} + +\begin{function}[added = 2022-07-04,updated = 2022-07-23]{square/x-length} + \begin{ccnusyntax}[emph={[1]x-length}] + x-length = (*\meta{dimension}*) + \end{ccnusyntax} + \tn{examsquare} 命令单位方形的长。默认为 |1.4em|。 +\end{function} + +\begin{function}[added = 2022-07-04,updated = 2022-07-23]{square/y-length} + \begin{ccnusyntax}[emph={[1]y}] + y-length = (*\meta{dimension}*) + \end{ccnusyntax} + \tn{examsquare} 命令单位方形的宽。默认为 |1.2em|。 +\end{function} + + +\begin{function}[added = 2022-07-04,updated = 2022-07-23]{square/baseline} + \begin{ccnusyntax}[emph={[1]baseline}] + baseline = (*\meta{dimension}*) + \end{ccnusyntax} + \tn{examsquare} 命令的基线偏移。默认为 |3pt|。一般长宽有较大的改动的情况才会改此参数。 +\end{function} + +\begin{function}[added = 2022-07-04,updated = 2022-07-23]{square/linewidth} + \begin{ccnusyntax}[emph={[1]linewidth}] + linewidth = (*\meta{dimension}*) + \end{ccnusyntax} + \tn{examsquare} 命令单位方形的线宽。默认为 |0.4pt|。 +\end{function} + +\begin{function}[added = 2022-07-04,updated = 2022-07-23]{square/xshift} + \begin{ccnusyntax}[emph={[1]xshift}] + xshift = (*\meta{dimension}*) + \end{ccnusyntax} + \tn{examsquare} 命令必选参数大于 1 时,后面的方格相对于前面的水平偏移。默认和 \opt{linewidth} 的值相同,一般不需要自己修改。 +\end{function} + + +\subsubsection{字体} + + +\begin{function}{font} + \begin{ccnusyntax}[emph={[1]font}] + font = (*(newcm)|lm|times|termes|stix|xits|libertinus|none*) + \end{ccnusyntax} + 设置西文字体。具体配置见表~\ref{tab:font}。 +\end{function} + +\begin{function}{math-font} + \begin{ccnusyntax}[emph={[1]math-font}] + math-font = (*(newcm)|lm|termes|stix|xits|libertinus|cambria|none*) + \end{ccnusyntax} + 设置数学字体。具体配置见表~\ref{tab:math-font}。 +\end{function} + + +\begin{table}[htbp] + \centering + \begin{threeparttable} + \caption{西文字体配置} + \label{tab:font} + \small + \begin{tabular}{ccccc} + \toprule + & \textbf{正文字体} & \textbf{无衬线字体} & \textbf{等宽字体}\\ + \midrule + |newcm| & NewCM10 & NewCMSans10 & NewCMMono10 \\ + |lm| & lmroman10 & lmsans10 & lmmonolt10 \\ + |times| & Times New Roman & Arial & Courier New \\ + |termes| & texgyretermes & texgyreheros & texgyrecursor \\ + |stix| & STIXTwoText\tnote{a} & texgyreheros & texgyrecursor \\ + |xits| & XITS\tnote{b} & texgyreheros & texgyrecursor \\ + |libertinus| & LibertinusSerif\tnote{c} & LibertinusSans\tnote{d} & lmmonolt10 \\ + \bottomrule + \end{tabular} + \begin{tablenotes} + \item[a] 或 STIX2Text + \item[b] 或 xits + \item[c] 或 libertinusserif + \item[d] 或 libertinussans + \end{tablenotes} + \end{threeparttable} +\end{table} + +\begin{table}[htbp] + \centering + \begin{threeparttable} + \caption{数学字体配置} + \label{tab:math-font} + \small + \begin{tabular}{ccccc} + \toprule + & \textbf{mathfont} & \textbf{mathrm} & \textbf{mathsf} & \textbf{mathtt} \\ + \midrule + |newcm| & NewCMMath-Book & NewCM10 & NewCMSans10 & NewCMMono10 \\ + |lm| & latinmodern-math & lmroman10 & lmsans10 & lmmonolt10 \\ + |stix| & STIXTwoMath-Regular\tnote{a} & & & \\ + |xits| & XITSMath-Regular\tnote{b} & & & \\ + |libertinus| & LibertinusMath-Regular\tnote{c} & & & \\ + |cambria| & Cambria Math & & & \\ + \bottomrule + \end{tabular} + \begin{tablenotes} + \item[a] 或 STIX2Math + \item[b] 或 xits-math + \item[c] 或 libertinusmath-regular + \end{tablenotes} + \end{threeparttable} +\end{table} + + +\subsubsection{抬头} \label{subsubsec:参数-抬头} + +\begin{function}{title} + \begin{ccnusyntax}[emph={[1]title}] + title = (*\marg{键值列表}*) + title/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含许多子项目,用于设置抬头。具体内容见下。 +\end{function} + +\begin{function}[added = 2022-07-03]{title/title-format} + \begin{ccnusyntax}[emph={[1]title-format}] + title-format = (*\meta{格式命令}*) + \end{ccnusyntax} + \tn{title} 的格式命令。默认为 |\Large|。 +\end{function} + +\begin{function}[added = 2022-07-03]{title/subject-format} + \begin{ccnusyntax}[emph={[1]subject-format}] + subject-format = (*\meta{格式命令}*) + \end{ccnusyntax} + \tn{subject} 的格式命令。默认为 |\sffamily \bfseries \huge|。 +\end{function} + +\begin{function}[added = 2022-07-03]{title/top-sep} + \begin{ccnusyntax}[emph={[1]top-sep}] + top-sep = (*\meta{弹性长度}*) + \end{ccnusyntax} + \tn{title} 和 \tn{subject} 的整体上方间距。默认为 |-.5em plus 0.3em minus 0.2em|。 +\end{function} + +\begin{function}[added = 2022-07-03]{title/bottom-sep} + \begin{ccnusyntax}[emph={[1]bottom-sep}] + bottom-sep = (*\meta{弹性长度}*) + \end{ccnusyntax} + \tn{title} 和 \tn{subject} 的整体下方间距。默认为 |0em plus 0.3em minus 0.2em|。 +\end{function} + + +\subsubsection{题干} \label{subsubsec:参数-题干} + +\begin{function}{question} + \begin{ccnusyntax}[emph={[1]question}] + question = (*\marg{键值列表}*) + question/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含许多子项目,用于设置题干。具体内容见下。 +\end{function} + + +\begin{function}[updated = 2022-07-05]{question/show-answer} + \begin{ccnusyntax}[emph={[1]show-answer}] + show-answer = (*\TFF*) + \end{ccnusyntax} + 统一控制 \tn{paren} 和 \tn{fillin} 中答案的显示与否。 +\end{function} + + +\begin{function}{question/points} + \begin{ccnusyntax}[emph={[1]points}] + points = (*\meta{color}*) + \end{ccnusyntax} + \env{question} 和 \env{problem} 环境中的分数。出现在题号后,如果不满足格式或位置的,可以自己手动输入 |(xx 分)|。 +\end{function} + + +\env{question} 和 \env{problem} 环境的参数大部分通过 \tn{examsetup} 和本节的参数控制,但也有一般在 \env{question} 和 \env{problem} 环境的 \oarg{键值列表} 中使用的,比如 \cmd{points}。(很容易理解,每道题的分值很有可能不尽相同,所以一般都是采用“个性化”,而不是 \tn{examsetup} 的“全局化”。除非是选择题和填空题这种一般每道题分数一样的) + +\begin{function}{question/show-points} + \begin{ccnusyntax}[emph={[1]show-points}] + show-points = (*true|(auto)|false*) + \end{ccnusyntax} + 控制 \env{question} 和 \env{problem} 环境中的分数的显示与否。\opt{auto} 表示 \env{question} 环境的分数不显示(比如选择、填空题,因为每道题一般分数相同),而 \env{problem} 环境的分数显示(比如解答题,每道题一般分数不同);\opt{true} 和 \opt{false} 分别表示 \env{question} 和 \env{problem} 环境中的分数全都显示和全都不显示。 +\end{function} + +\begin{function}{question/points-separate-par} + \begin{ccnusyntax}[emph={[1]points-separate-par}] + points-separate-par = (*\TFF*) + \end{ccnusyntax} + \env{question} 和 \env{problem} 环境中的分数是否单独成段。\env{question} 环境默认为 \opt{false},\env{problem} 环境默认为 \opt{true}。 +\end{function} + + +\begin{function}{question/top-sep,question/bottom-sep} + \begin{ccnusyntax}[emph={[1]top-sep,bottom-sep}] + top-sep = (*\meta{skip}*) + bottom-sep = (*\meta{skip}*) + \end{ccnusyntax} + \env{question} 和 \env{problem} 环境的上下方的弹性间距。\opt{top-sep} 默认为 |.25em plus .25em minus .1em|;\opt{bottom-sep} 默认为 |0pt|。 +\end{function} + + +\begin{function}{question/index} + \begin{ccnusyntax}[emph={[1]index}] + index = (*\meta{integer}*) + \end{ccnusyntax} + 手动设置 \env{question} 和 \env{problem} 环境的计数器值。一般用于两个环境的 \meta{键值列表} 中。 +\end{function} + + +\begin{function}[added = 2022-07-20]{question/label} + \begin{ccnusyntax}[emph={[1]label}] + label = (*\meta{label}*) + \end{ccnusyntax} + \env{question} 和 \env{problem} 环境的标签的格式。默认值为 |\arabic*.|。\meta{label} 中可以使用的已定义的计数器样式主要有以下几种: +\end{function} + +\begin{choices}[label = \circlednumber*] + \item arabic(阿拉伯数字) + \item alph(小写英文) + \item Alph(大写英文) + \item roman(小写罗马数字) + \item Roman(大写罗马数字) + \item circlednumber(基于字体的带圈数字) + \item tikzcirclednumber(\TikZ 绘制的带圈数字) +\end{choices} + + +还可以使用~\ref{subsubsec:命令环境-题干} 节的 \tn{AddQuestionCounter} 命令自定义计数器样式,使用方式和~\ref{subsubsec:命令环境-选择题} 节的 \tn{AddChoicesCounter} 命令一样。 + +\begin{function}[added = 2022-07-26]{question/combine-fillin} + \begin{ccnusyntax}[emph={[1]combine-fillin}] + combine-fillin = (*\TFF*) + \end{ccnusyntax} + 是否将 \tn{fillin} 命令接入 \env{question} 环境。\opt{true} 表示 \tn{fillin} 会在 \env{question} 环境左侧。\kvopt{combine-fillin}{true} 下 \env{question} 和 \env{problem} 环境的缩进效果相同。 +\end{function} + +\begin{function}[added = 2022-07-26]{question/combine-fillin-args} + \begin{ccnusyntax}[emph={[1]combine-fillin-args}] + combine-fillin-args = (*\meta{\tn{fillin} 命令的参数}*) + \end{ccnusyntax} + \kvopt{combine-fillin}{true} 下 \tn{fillin} 接收的参数,和正常使用 \tn{fillin} 命令接收的参数相同。在此之前的 \opt{fillin/foo} 的相关键值会正常作用于接入 \env{question} 环境的 \tn{fillin}。 +\end{function} + +\examsetup{question/index=1} +\begin{latexexample}{\opt{combine-fillin} 和 \opt{combine-fillin-args} 的使用示例} + \examsetup{ + fillin/show-answer = true, + question/combine-fillin = true, + } + \begin{question}[combine-fillin-args = {[type = paren][A]}] + 设集合 $A = \{x \mid -1 < x < 4\}$,$B = \{2, 3, 4, 5\}$,则 $A \cap B = $ + \end{question} +\end{latexexample} +\examsetup{ + fillin/show-answer = false, + question/combine-fillin = false, +} + + +\subsubsection{选择题} \label{subsubsec:参数-选择题} + +\begin{function}{choices} + \begin{ccnusyntax}[emph={[1]choices}] + choices = (*\marg{键值列表}*) + choices/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含许多子项目,用于设置 \env{choices} 环境。具体内容见下,可以通过 \tn{examsetup} 进行统一处理,也可以用于 \env{choices} 环境的 \meta{键值列表} 针对某一 \env{choices} 环境调整。 +\end{function} + +\begin{function}{choices/index} + \begin{ccnusyntax}[emph={[1]index}] + index = (*\meta{integer}*) + \end{ccnusyntax} + 选项第一项 label 的计数器的起始值。 +\end{function} +\begin{latexexample}{\opt{choices/index} 示例} + \begin{choices} + \item 1 + \item 2 + \item 3 + \end{choices} + + \begin{choices}[index = 2] + \item 1 + \item 2 + \item 3 + \end{choices} +\end{latexexample} + + +\begin{function}{choices/column-sep} + \begin{ccnusyntax}[emph={[1]column-sep}] + column-sep = (*\meta{dimension}*) + \end{ccnusyntax} + 选项列之间的最小间隔。默认为 |1em|。 +\end{function} + + +\begin{function}{choices/columns} + \begin{ccnusyntax}[emph={[1]columns}] + columns = (*\meta{integer}*) + \end{ccnusyntax} + 强制按照该列数排版选项,如果为 0 则自动选择合适的列数。 + % 手动设置 \env{choices} 环境排出的选项的列数,否则会根据选项内容自动计算。一般用于 \env{choices} 环境的 \meta{参数列表}。 +\end{function} + + +\begin{function}{choices/label} + \begin{ccnusyntax}[emph={[1]label}] + label = (*\meta{label}*) + \end{ccnusyntax} + 标签的格式。默认值 |\Alph*.|。\meta{label} 中可以使用的已定义的计数器样式主要有以下几种: +\end{function} + +\begin{choices}[label = \circlednumber*] + \item arabic(阿拉伯数字) + \item alph(小写英文) + \item Alph(大写英文) + \item roman(小写罗马数字) + \item Roman(大写罗马数字) + \item circlednumber(带圈数字) +\end{choices} + +还可以使用~\ref{subsubsec:命令环境-选择题} 节的 \tn{AddChoicesCounter} 命令自定义计数器样式。 + +使用方式为(以 \opt{arabic} 为例):\kvopt{label}{<pre>\textbackslash arabic*<post>}(类似 \pkg{enumitem} 宏包),其中 \meta{pre} 和 \meta{post} 表示计数器前后的内容,举例: +\begin{latexexample}{\env{choices} 环境 label 的使用示例} + \begin{choices} + \item 第一项 + \item 第二项 + \item 第三项 + \item 第四项 + \end{choices} + + \begin{choices}[label = \arabic*)] + \item 第一项 + \item 第二项 + \item 第三项 + \item 第四项 + \end{choices} +\end{latexexample} + +如果想要隐藏或去掉 label 的话,可以使用 |label = {}|,但一般这个需求可能使用表格或其它方法会更好。 + +如果是问卷,那么可能会有 label 是正方形或圆形的需求: +\begin{latexexample}{label 为正方形} + \begin{choices}[label = $\square$] + \item 第一项 + \item 第二项 + \item 第三项 + \item 第四项 + \end{choices} +\end{latexexample} + +\begin{latexexample}{label 为圆形} + \begin{choices}[label = \textbigcircle] + \item 第一项 + \item 第二项 + \item 第三项 + \item 第四项 + \end{choices} +\end{latexexample} + + +\begin{function}{choices/label-pos} + \begin{ccnusyntax}[emph={[1]label-pos}] + label-pos = (*<(auto)|top-left|left|bottom>*) + \end{ccnusyntax} + 标签相对于选项内容的位置。\opt{auto} 会根据内容高度来判断,当高度到达一定程度时会判断为插图,并将 label 放置于 内容 的 \opt{bottom} 位置;\opt{top-left} 表示在内容左侧并置于顶部;\opt{top-left} 表示在内容左侧并置于中间;\opt{top-left} 表示在内容底部; +\end{function} + + +\begin{function}{choices/label-align} + \begin{ccnusyntax}[emph={[1]label-align}] + label-align = (*left|center|(right)*) + \end{ccnusyntax} + 标签内部的对齐方式。 +\end{function} + +\begin{latexexample}{\opt{label-align} 的效果示例} + \begin{choices}[index = 8, label = \arabic*.] + \item 1 + \item 2 + \item 3 + \item 4 + \end{choices} + \begin{choices}[index = 8, label = \arabic*., label-align = left] + \item 1 + \item 2 + \item 3 + \item 4 + \end{choices} + \begin{choices}[index = 8, label = \arabic*., label-align = center] + \item 1 + \item 2 + \item 3 + \item 4 + \end{choices} +\end{latexexample} + + +\begin{function}{choices/label-sep} + \begin{ccnusyntax}[emph={[1]label-sep}] + label-sep = (*\meta{dimension}*) + \end{ccnusyntax} + 标签与选项之间的距离。默认为 |0.5em|。 +\end{function} + +\begin{function}{choices/label-width} + \begin{ccnusyntax}[emph={[1]label-width}] + label-width = (*\meta{dimension}*) + \end{ccnusyntax} + 标签的宽度。如果宽度不足会自动调整为最长标签的宽度。默认 |0pt| +\end{function} + +\begin{function}{choices/max-columns} + \begin{ccnusyntax}[emph={[1]max-columns}] + max-columns = (*\meta{integer}*) + \end{ccnusyntax} + 选项的最大列数。排版选项时会优先尝试该列数,如果无法排下内容,依次将列数除以 2 并取整再进行尝试,直到可以排下全部选项。默认为 |4| 。 +\end{function} + + + +\begin{function}{paren} + \begin{ccnusyntax}[emph={[1]paren}] + paren = (*\marg{键值列表}*) + paren/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含一个子项目,用于设置 \tn{paren} 命令。具体内容见下。 +\end{function} + +\begin{function}[added = 2022-07-05]{paren/show-answer} + \begin{ccnusyntax}[emph={[1]show-answer}] + show-answer = (*\TFF*) + \end{ccnusyntax} + 控制 \tn{paren} 答案的显示与否。注意和 \opt{question/show-answer} 的先后顺序可能会影响结果。 +\end{function} + +\begin{function}[added = 2022-07-15]{paren/show-paren} + \begin{ccnusyntax}[emph={[1]show-paren}] + show-paren = (*\TFF*) + \end{ccnusyntax} + 是否显示 \tn{paren} 命令的括号。 +\end{function} + +\begin{function}[added = 2022-07-15]{paren/text-color} + \begin{ccnusyntax}[emph={[1]text-color}] + text-color = (*\meta{color}*) + \end{ccnusyntax} + 设置 \tn{paren} 中答案的颜色。 +\end{function} + +\begin{function}[added = 2022-07-15]{paren/type} + \begin{ccnusyntax}[emph={[1]text-color}] + type = (*<(hfill)|none>*) + \end{ccnusyntax} + \tn{paren} 产生的括号是否自动排到行尾。\opt{hfill} 表示自动根据行的长度排到行尾;\opt{none} 表示括号紧跟前面内容。 +\end{function} + +\examsetup{ + question/index=0 +} + +\begin{latexexample}{\opt{paren/type} 效果展示} + \examsetup{ + paren = { + show-paren = true + } + } + \begin{question} + 一共有 \paren 个苹果? + \begin{choices} + \item 1 + \item 2 + \item 3 + \item 4 + \end{choices} + \end{question} + + \examsetup{ + paren = { + type = none + } + } + + \begin{question} + 一共有 \paren 个苹果? + \begin{choices} + \item 1 + \item 2 + \item 3 + \item 4 + \end{choices} + \end{question} +\end{latexexample} + +(注:上面的例子中|)| 和 |个| 之间间距不正常是本手册的一个小 bug,\cls{exam-zh} 中使用是正常的) + + +\begin{function}[added = 2022-07-26]{question/label-align} + \begin{ccnusyntax}[emph={[1]label-align}] + label-align = (*left|center|(right)*) + \end{ccnusyntax} + \env{question} 标签的对齐方式。 +\end{function} + + +\subsubsection{填空题} \label{subsubsec:参数-填空题} + + +\begin{function}{fillin} + \begin{ccnusyntax}[emph={[1]fillin}] + fillin = (*\marg{键值列表}*) + fillin/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项暂时包含一个子项目,用于设置填空命令 \tn{fillin} 的类型。具体内容见下。 +\end{function} + +\begin{function}[updated = 2022-07-15]{fillin/type} + \begin{ccnusyntax}[emph={[1]type}] + type = (*<(line)|paren|circle|rectangle|blank>*) + \end{ccnusyntax} + 填空命令 \tn{fillin} 的类型。\opt{line} 表示下划线;\opt{paren} 表示括号;\opt{rectangle} 表示外包一个矩形;\opt{circle} 表示外包一个圆,当内容变多时,圆会“拉伸开变成椭圆”;\opt{blank} 表示没有任何的“装饰”。 +\begin{latexexample}{\tn{fillin} 的三个类型以及参数使用方式} + 答案是 \fillin \fillin[] + \fillin[type = paren][] + \fillin[type = circle][] + \fillin[type = blank][] +\end{latexexample} +\end{function} + + +\begin{function}[added = 2022-07-21]{fillin/no-answer-type} + \begin{ccnusyntax}[emph={[1]no-answer-type}] + no-answer-type = (*<(blacktriangle)|counter|none>*) + \end{ccnusyntax} + 填空命令 \tn{fillin} 在 \kvopt{show-answer}{false} 的情况下的显示情况: + \begin{itemize} + \item \opt{blacktriangle}:内容部分变成黑色三角形(即使已经输入了答案 |\fillin[foo]|) + \item \opt{counter}:内容部分变成计数器(每使用一次显示内容的数值加一),设计来源于英语学科的完形填空 + \item \opt{none}:除了 \tn{fillin} 的 \opt{type} 相关的显示(比如下划线,括号)和一定的间距外不显示其它 + \end{itemize} +\end{function} + +\begin{function}[added = 2022-07-21]{fillin/no-answer-counter-index} + \begin{ccnusyntax}[emph={[1]no-answer-counter-index}] + no-answer-counter-index = (*\meta{integer}*) + \end{ccnusyntax} + 填空命令 \tn{fillin} 在 \kvopt{show-answer}{false} 和 \kvopt{no-answer-type}{counter} 下的计数器的非负整数值。默认为 |1| +\end{function} + +\begin{function}[added = 2022-07-21]{fillin/no-answer-counter-label} + \begin{ccnusyntax}[emph={[1]no-answer-counter-label}] + no-answer-counter-label = (*\meta{label}*) + \end{ccnusyntax} + 填空命令 \tn{fillin} 在 \kvopt{show-answer}{false} 和 \kvopt{no-answer-type}{counter} 下的计数器的样式。默认为 |\arabic*|。\meta{label} 中可以使用的已定义的计数器样式主要有以下几种: +\end{function} + +\begin{choices}[label = \circlednumber*] + \item arabic(阿拉伯数字) + \item alph(小写英文) + \item Alph(大写英文) + \item roman(小写罗马数字) + \item Roman(大写罗马数字) + \item circlednumber(基于字体的带圈数字) + \item tikzcirclednumber(\TikZ 绘制的带圈数字) +\end{choices} + + + +\begin{function}[added = 2022-07-05]{fillin/show-answer} + \begin{ccnusyntax}[emph={[1]show-answer}] + show-answer = (*\TFF*) + \end{ccnusyntax} + 控制 \tn{fillin} 答案的显示与否。注意和 \opt{question/show-answer} 的先后顺序可能会影响结果。 +\end{function} + +\begin{function}[added = 2022-07-06]{fillin/width} + \begin{ccnusyntax}[emph={[1]width}] + width = (*<skip>*) + \end{ccnusyntax} + 控制 \kvopt{fillin/type}{line/paren/blank} 下 \tn{fillin} 不显示答案时的长度,可以为弹性长度,默认为 |3em plus 1em minus 1em|。 +\end{function} + +\begin{function}[added = 2022-07-15]{fillin/color} + \begin{ccnusyntax}[emph={[1]color}] + color = (*\meta{color}*) + \end{ccnusyntax} + 设置 \kvopt{fillin/type}{circle/rectangle} 类型的 \tn{fillin} 的边框颜色。 +\end{function} + + +\begin{function}[added = 2022-07-15]{fillin/text-color} + \begin{ccnusyntax}[emph={[1]text-color}] + text-color = (*\meta{color}*) + \end{ccnusyntax} + 设置 \tn{fillin} 中答案的颜色。 +\end{function} + + +\subsubsection{解答题} \label{subsubsec:参数-解答题} + +\begin{function}[added = 2022-07-01]{solution} + \begin{ccnusyntax}[emph={[1]solution}] + solution = (*\marg{键值列表}*) + solution/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含许多子项目,用于设置 \env{solution} 环境。具体内容见下,只能通过 \tn{examsetup} 进行处理。 +\end{function} + + +\begin{function}[added = 2022-07-01]{solution/show-solution} + \begin{ccnusyntax}[emph={[1]show-solution}] + show-solution = (*\TTF*) + \end{ccnusyntax} + 是否显示解答环境 \env{solution} 的内容。 +\end{function} + +\begin{function}[added = 2022-07-20]{solution/parbreak} + \begin{ccnusyntax}[emph={[1]parbreak}] + parbreak = (*\TFF*) + \end{ccnusyntax} + \env{solution} 环境的内容是否在 |label| (默认为 |解答|)后新起一段开始。 +\end{function} + +\begin{function}[added = 2022-07-01]{solution/show-qed} + \begin{ccnusyntax}[emph={[1]show-qed}] + show-qed = (*\TTF*) + \end{ccnusyntax} + 是否显示 \env{solution} 环境结束的结束符号。 +\end{function} + +\begin{function}[added = 2022-07-02]{solution/qedsymbol} + \begin{ccnusyntax}[emph={[1]qedsymbol}] + qedsymbol = (*\meta{symbol}*) + \end{ccnusyntax} + \env{solution} 环境结束的结束符号。默认为 |$\square$|。可以为文字等。 +\end{function} + +\begin{latexexample}{\opt{qedsymbol} 示例} + \begin{solution} + 测试 + \end{solution} + \examsetup{ + solution = { + qedsymbol = \# + } + } + \begin{solution} + 测试 + \end{solution} +\end{latexexample} + +\begin{function}[added = 2022-07-01,updated = 2022-07-02]{solution/label-content} + \begin{ccnusyntax}[emph={[1]label-content}] + label-content = (*\meta{content}*) + \end{ccnusyntax} + \env{solution} 环境开头的标签内容。默认为 |解答|。若用于 \tn{examsetup} 则作用于之后的所有 \env{solution} 环境。 +\end{function} + +\begin{function}[added = 2022-07-01,updated = 2022-07-02]{solution/label-punct} + \begin{ccnusyntax}[emph={[1]label-punct}] + label-punct = (*\meta{punct}*) + \end{ccnusyntax} + \env{solution} 环境开头的标签内容后的标点。默认为空。若用于 \tn{examsetup} 则作用于之后的所有 \env{solution} 环境。 +\end{function} + +\begin{function}[added = 2022-07-02]{solution/score-pre-content} + \begin{ccnusyntax}[emph={[1]score-pre-content}] + score-pre-content = (*\meta{content}*) + \end{ccnusyntax} + \tn{score} 命令的前置内容。默认为空。 +\end{function} + +\begin{function}[added = 2022-07-02]{solution/score-post-content} + \begin{ccnusyntax}[emph={[1]score-post-content}] + score-post-content = (*\meta{content}*) + \end{ccnusyntax} + \tn{score} 命令的后置内容。默认为 |分|。 +\end{function} + +\begin{latexexample}{\opt{score-pre-content} 和 \opt{score-post-content} 示例} + \examsetup{ + solution = { + score-pre-content = 这个点可以有, + score-post-content = 分的分数 + } + } + \begin{solution} + 函数的定义域为 $(0, +\infty)$, + 又 \[f^{\prime}(x) = 1 - \ln x-1 = -\ln x, \score{2}\] + 当 $x \in(0, 1)$ 时, $f^{\prime}(x) > 0$, 当 $x \in(1, +\infty)$ 时, $f^{\prime}(x) < 0$, + 故 $f(x)$ 的递增区间为 $(0,1)$, 递减区间为 $(1, +\infty)$. + \end{solution} +\end{latexexample} + +将 \opt{score-pre-content} 和 \opt{score-post-content} 设置为空就可以产生批注效果: +\begin{latexexample}{\opt{score-pre-content} 和 \opt{score-post-content} 为空产生批注效果} + \examsetup{ + solution = {score-pre-content = {}, score-post-content = {}} + } + \begin{solution} + 函数的定义域为 $(0, +\infty)$, + 又 \[f^{\prime}(x) = 1 - \ln x-1 = -\ln x, \score{这是关键点}\] + 当 $x \in(0, 1)$ 时, $f^{\prime}(x) > 0$, 当 $x \in(1, +\infty)$ 时, $f^{\prime}(x) < 0$, + 故 $f(x)$ 的递增区间为 $(0,1)$, 递减区间为 $(1, +\infty)$. + \end{solution} +\end{latexexample} + +\begin{function}[added = 2022-07-02, updated = 2022-07-03]{solution/score-format} + \begin{ccnusyntax}[emph={[1]score-format}] + score-format = (*\meta{风格设置}*) + \end{ccnusyntax} + \tn{score} 命令的内容的风格设置,可以是颜色或字体字号命令等。默认为 |\color{red}|。 +\end{function} + +\examsetup{ + solution = { + score-pre-content = {}, + score-post-content = 分 + } +} +\begin{latexexample}{\opt{score-format} 示例} + \examsetup{ + solution = { + score-format = {\sffamily \huge \color{blue}} + } + } + \begin{solution} + 测试 \score{2} + \end{solution} +\end{latexexample} + +\begin{function}[added = 2022-07-02]{solution/score-showleader} + \begin{ccnusyntax}[emph={[1]score-showleader}] + score-showleader = (*\TTF*) + \end{ccnusyntax} + \tn{score} 命令的引导线显示与否。 +\end{function} + +\begin{function}[added = 2022-07-15]{solution/text-color} + \begin{ccnusyntax}[emph={[1]text-color}] + text-color = (*\meta{color}*) + \end{ccnusyntax} + \env{solution} 环境内容的颜色。默认为 |black|。 +\end{function} + +\begin{function}[added = 2022-07-19]{solution/top-sep} + \begin{ccnusyntax}[emph={[1]top-sep}] + top-sep = (*\meta{dimension}*) + \end{ccnusyntax} + \env{solution} 环境上方间距。默认为 |.5em plus .5em minus .2em|。 +\end{function} + +\begin{function}[added = 2022-07-19]{solution/bottom-sep} + \begin{ccnusyntax}[emph={[1]bottom-sep}] + bottom-sep = (*\meta{dimension}*) + \end{ccnusyntax} + \env{solution} 环境下方间距。默认为 |.5em plus .5em minus .2em|。 +\end{function} + +\begin{function}[added = 2022-07-19]{solution/blank-type} + \begin{ccnusyntax}[emph={[1]blank-type}] + blank-type = (*<(none)|manual|hide>*) + \end{ccnusyntax} + \kvopt{solution/show-solution}{false} 的时候是否增加一段垂直空白。比如可以留白给学生答题。 + \begin{itemize} + \item \opt{none}: 不增加; + \item \opt{manual}: 增加,增加的高度由 \opt{solution/blank-vsep} 控制; + \item \opt{hide}: 增加,增加的高度和 \env{solution} 的内容几乎相同(因为使用了 \env{tcolorbox} 环境达到 \opt{hide} 效果,环境前后间距会造成干扰,但可忽略); + \end{itemize} +\end{function} + +\begin{function}[added = 2022-07-19]{solution/blank-vsep} + \begin{ccnusyntax}[emph={[1]blank-vsep}] + blank-vsep = (*\meta{skip}*) + \end{ccnusyntax} + \kvopt{solution/blank-type}{manual} 的时候增加的垂直空白长度,可以是弹性长度。默认为 |12ex plus 1ex minus 1ex|。 +\end{function} + + +\subsubsection{几个列表环境} \label{subsubsec:参数-列表环境} + +\begin{function}[added = 2022-07-04]{list} + \begin{ccnusyntax}[emph={[1]list}] + list = (*\marg{键值列表}*) + list/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含许多子项目。用于设置 \env{step}、\env{method}、\env{case} 环境。仅通过 \tn{examsetup} 进行统一处理。具体内容见下。 +\end{function} + +\begin{function}[added = 2022-07-04]{list/step-name,list/method-name,list/case-name} + \begin{ccnusyntax}[emph={[1]step-name,method-name,case-name}] + step-name = (*\meta{step 环境 label 名}*) + method-name = (*\meta{method 环境 label 名}*) + case-name = (*\meta{case 环境 label 名}*) + \end{ccnusyntax} + 分别设置 \env{step}、\env{method}、\env{case} 环境的 label 名,分别默认为 |步骤|、|方法|、|情形|。 +\end{function} + +\begin{function}[added = 2022-07-04]{list/step-punct,list/method-punct,list/case-punct} + \begin{ccnusyntax}[emph={[1]step-punct,method-punct,case-punct}] + step-punct = (*\meta{step 环境 label 后的标点}*) + method-punct = (*\meta{method 环境 label 后的标点}*) + case-punct = (*\meta{case 环境 label 后的标点}*) + \end{ccnusyntax} + 分别设置 \env{step}、\env{method}、\env{case} 环境的 label 后的标点,分别默认为 |.|、|{}|(无标点)、|.|。 +\end{function} + + + +\subsubsection{草稿纸} \label{subsubsec:参数-草稿纸} + +\begin{function}[added = 2022-07-03]{draft} + \begin{ccnusyntax}[emph={[1]draft}] + draft = (*\marg{键值列表}*) + draft/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含许多子项目。用于设置 \tn{draftpaper} 命令。下面所述的键值,如果不额外说明,则表示可以通过 \tn{examsetup} 进行统一处理,也可以用 于 \tn{draftpaper} 命令的 \meta{键值列表} 针对某一 \tn{draftpaper} 命令调整。具体内容见下。 +\end{function} + + +\begin{function}[added = 2022-07-03]{draft/watermark-size} + \begin{ccnusyntax}[emph={[1]watermark-size}] + watermark-size = (*\meta{dimension}*) + \end{ccnusyntax} + \tn{draftpaper} 命令的“草稿纸”水印的尺寸。A4 尺寸下默认为 |100pt|,A3 尺寸下默认为 |180pt|。 +\end{function} + +\begin{function}[added = 2022-07-03]{draft/show-watermark} + \begin{ccnusyntax}[emph={[1]show-watermark}] + show-watermark = (*\TTF*) + \end{ccnusyntax} + 是否显示\tn{draftpaper} 命令的“草稿纸”水印。若为 \opt{true},最多需要编译两次即可得到水印。 +\end{function} + + +\begin{function}[added = 2022-07-03]{draft/show-draft} + \begin{ccnusyntax}[emph={[1]show-draft}] + show-draft = (*<auto|(manual)>*) + \end{ccnusyntax} + 是否在文档最后自动添加两页的草稿纸。此键值只用于导言区的 \tn{examsetup} 命令。\opt{auto} 表示自动在末尾添加两页草稿纸,\opt{manual} 表示不在末尾添加草稿纸,如用户不需要草稿纸,或者是需要不止两页草稿纸的话,则需要改成 \opt{manual},后者需求则需要用户自己手动在文档末尾添加所需要的 \tn{draftpaper} 命令即可。注意,密封线的作用范围包括了草稿纸。根据经验看,试卷的草稿纸一般也有相应的密封线,所以暂时没有单独去掉草稿纸的密封线范围。但是可以实现一种效果:正文密封线正常,草稿纸页完全空白: + \begin{enumerate} + \item 先在导言区使用 \tn{examsetup} 用~\ref{subsubsec:参数-密封线} 节的 |sealline| 相应接口正常编译所需要的密封线 + \item 在导言区加入 \kvopt{draft/show-draft}{auto},编译 \emph{一次},即可的到空白的草稿纸(编译两次就是正常按照 |draft| 相关参数和密封线一起编译所得到的草稿纸) + \item 若需要不止两张或者只需要一张空白页,则把上一步的“在导言区加入 \kvopt{draft/show-draft}{auto}” 改为在正文中添加相应数量的 \tn{draftpaper} 命令,并编译 \emph{一次} 即可。 + \end{enumerate} +\end{function} + + +\subsubsection{评分框} \label{subsubsec:参数-评分框} + +\begin{function}[added = 2022-07-04]{scoringbox} + \begin{ccnusyntax}[emph={[1]scoringbox}] + scoringbox = (*\marg{键值列表}*) + scoringbox/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含一个子项目。用于设置评分框。仅可以通过 \tn{examsetup} 进行处理。 +\end{function} + +\begin{function}[added = 2022-07-04]{scoringbox/type} + \begin{ccnusyntax}[emph={[1]type}] + type = (*<onecolumn|twocolumn|(none)>*) + \end{ccnusyntax} + 该键值用于重定义 \tn{section} 命令,使得 \tn{scoringbox} 和 \tn{section} 结合起来。\opt{onecolumn} 表示单栏(即只有“得分”)的评分框和 \tn{section} 绑定,评分框置于左边;\opt{twocolumn} 表示双栏(即有“得分”和“评卷人”)的评分框和 \tn{section} 绑定,评分框置于左边;\opt{none} 表示不重定义 \tn{section} 命令,即不显示评分框。 +\end{function} + + +\begin{function}[added = 2022-07-24]{scoringbox/position} + \begin{ccnusyntax}[emph={[1]position}] + position = (*<(left)|right>*) + \end{ccnusyntax} + \kvopt{scoringbox/type}{onecolumn} 或 \kvopt{scoringbox/type}{twocolumn} 时,评分框相对于 \tn{section} 的位置。\opt{left} 表示评分框在 \tn{section} 的左边; \opt{right} 表示评分框在 \tn{section} 的右边。 +\end{function} + + +\subsubsection{选择标记题型} \label{subsubsec:参数-选择标记题型} + +\begin{function}[added = 2022-07-19]{select} + \begin{ccnusyntax}[emph={[1]chinese}] + select = (*\marg{键值列表}*) + select/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含一个子项目。用于设置 \env{select} 环境。 +\end{function} + +\begin{function}[added = 2022-07-19]{chinese/mark-symbol} + \begin{ccnusyntax}[emph={[1]mark-symbol}] + mark-symbol = (*\meta{symbol}*) + \end{ccnusyntax} + \env{select} 环境的标记符号。默认为 |$\checkmark$|。 +\end{function} + +\begin{latexexample}{\opt{mark-symbol} 使用示例} + \begin{select}[mark-symbol = {\textcolor{red}{$\times$}},show-mark = true] + \sitem 正确 + \sitem* 错误 + \sitem* 错误 + \end{select} +\end{latexexample} + +\begin{function}[added = 2022-07-21]{chinese/show-mark} + \begin{ccnusyntax}[emph={[1]show-mark}] + show-mark = (*\TFF*) + \end{ccnusyntax} + 是否显示 \env{select} 环境的标记符号。 +\end{function} + +\begin{function}[added = 2022-07-19, updated = 2022-07-24]{chinese/mark-position} + \begin{ccnusyntax}[emph={[1]mark-position}] + mark-position = (*top|above|below|bottom|left|(right)>*) + \end{ccnusyntax} + \env{select} 环境的标记符号相对于内容的位置。\opt{right} 表示 \opt{mark-symbol} 在内容的右侧,其余的含义同理。其中 \opt{top} 和 \opt{above} 等效,\opt{below} 和 \opt{bottom} 等效。 +\end{function} + +\begin{function}[added = 2022-07-19]{chinese/mark-xshift} + \begin{ccnusyntax}[emph={[1]mark-xshift}] + mark-xshift = (*\meta{dimension}*) + \end{ccnusyntax} + \env{select} 环境的标记符号的水平偏移量。 +\end{function} + +\begin{function}[added = 2022-07-19]{chinese/mark-yshift} + \begin{ccnusyntax}[emph={[1]mark-yshift}] + mark-yshift = (*\meta{dimension}*) + \end{ccnusyntax} + \env{select} 环境的标记符号的垂直偏移量。 +\end{function} + +\begin{function}[added = 2022-07-19]{chinese/separator} + \begin{ccnusyntax}[emph={[1]separator}] + separator = (*\meta{symbol}*) + \end{ccnusyntax} + \env{select} 环境内容的间隔符。 +\end{function} + +\begin{function}[added = 2022-07-19]{chinese/pre-content} + \begin{ccnusyntax}[emph={[1]pre-content}] + pre-content = (*\meta{content}*) + \end{ccnusyntax} + \env{select} 环境的内容 \emph{前} 的内容。 +\end{function} + +\begin{function}[added = 2022-07-19]{chinese/post-content} + \begin{ccnusyntax}[emph={[1]post-content}] + post-content = (*\meta{content}*) + \end{ccnusyntax} + \env{select} 环境的内容 \emph{后} 的内容。 +\end{function} + + +\begin{latexexample}{\env{select}相关键值的综合使用} + 折 + \begin{select}[pre-content = {[}, post-content = {\}}, mark-symbol = {\tiny $\triangle$}, separator = {, },mark-position = bottom, show-mark=true] + \sitem \pinyin{zhe1} + \sitem \pinyin{zhe2} + \sitem \pinyin{zhe3} + \sitem \pinyin{zhe4} + \sitem \pinyin{she1} + \sitem* \pinyin{she2} + \sitem \pinyin{she3} + \sitem \pinyin{she4} + \end{select} + 本 +\end{latexexample} + + + +\subsubsection{连线题型} \label{subsubsec:参数-连线题型} + +\begin{function}[updated = 2022-07-19]{lineto} + \begin{ccnusyntax}[emph={[1]lineto}] + lineto = (*\marg{键值列表}*) + lineto/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含一个子项目。用于设置 \env{lineto} 环境。 +\end{function} + +\begin{function}{lineto/xsep} + \begin{ccnusyntax}[emph={[1]xsep}] + xsep = (*\meta{dimension}*) + \end{ccnusyntax} + 设置 \env{lineto} 环境两列之间的距离。默认为 |0.25\linewidth|。只在 \tn{examsetup} 中设置。 +\end{function} + +\begin{function}{lineto/ysep} + \begin{ccnusyntax}[emph={[1]ysep}] + ysep = (*\meta{dimension}*) + \end{ccnusyntax} + 设置 \env{lineto} 环境两行之间的距离。默认为 |1cm|。只在 \tn{examsetup} 中设置。 +\end{function} + +\begin{function}{lineto/name} + \begin{ccnusyntax}[emph={[1]name}] + name = (*\meta{dimension}*) + \end{ccnusyntax} + \env{lineto} 环境中 \tn{linelistset} 命令设置的一组的名称。只在 \tn{lineconnect} 的 \oarg{键值列表} 中设置。默认为小写罗马数字,即第一次使用 \tn{lineconnect} 则该组数据的名称为 |i-*|,第二次使用的该组数据名称为 |ii-*|,其中 |*| 为该项在 \tn{linelistset} 的必选参数的列表的第几项(阿拉伯数字),比如 |i-1|,|ii-3|。 +\end{function} + + +\begin{latexexample}{\opt{lineto/name} 的效果及 \env{lineto} 环境使用示例} + \begin{lineto} + \linelistset{apple, banana, key} + \linelistset{香蕉, 钥匙, 苹果} + \lineconnect{i-1,ii-3} + \lineconnect{i-2,ii-1} + \lineconnect{i-3,ii-2} + \end{lineto} + + \begin{lineto} + \linelistset[name = a]{apple, banana, key} + \linelistset[name = b]{香蕉, 钥匙, 苹果} + \linelistset[name = c]{黄色, 红色,银色} + \lineconnect{a-1,b-3,c-2} + \lineconnect{a-2,b-1,c-1} + \lineconnect{a-3,b-2,c-3} + \end{lineto} +\end{latexexample} + + +\subsubsection{语文相关} \label{subsubsec:参数-语文} + +\begin{function}[updated = 2022-07-24]{material} + \begin{ccnusyntax}[emph={[1]material}] + material = (*\marg{键值列表}*) + material/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含多个子项目。用于设置 \env{material} 环境。可以在 \tn{examsetup} 中使用,也可以在 \env{material} 环境的可选参数中使用。 +\end{function} + + +\begin{function}[updated = 2022-07-24]{material/title} + \begin{ccnusyntax}[emph={[1]title}] + title = (*\meta{标题}*) + \end{ccnusyntax} + \env{material} 环境的上方标题的 \emph{内容}。可以为空或不写。 +\end{function} + +\begin{function}[updated = 2022-07-24]{material/title-format} + \begin{ccnusyntax}[emph={[1]title-format}] + title-format = (*\meta{格式}*) + \end{ccnusyntax} + \env{material} 环境的上方标题的 \emph{格式}。默认为 |\zihao{4}|。 +\end{function} + +\begin{function}[updated = 2022-07-24]{material/author} + \begin{ccnusyntax}[emph={[1]author}] + author = (*\meta{作者}*) + \end{ccnusyntax} + \env{material} 环境的上方作者的 \emph{作者名}。可以为空或不写。 +\end{function} + +\begin{function}[updated = 2022-07-24]{material/author-format} + \begin{ccnusyntax}[emph={[1]author-format}] + author-format = (*\meta{格式}*) + \end{ccnusyntax} + \env{material} 环境的上方作者的 \emph{格式}。默认为 |\small|。 +\end{function} + +\begin{function}[updated = 2022-07-24]{material/title-author-sep} + \begin{ccnusyntax}[emph={[1]title-author-sep}] + title-author-sep = (*\meta{弹性长度}*) + \end{ccnusyntax} + \env{material} 环境的上方标题和作者之间的距离。默认为 |2em|。 +\end{function} + + +\begin{function}[updated = 2022-07-24]{material/format} + \begin{ccnusyntax}[emph={[1]format}] + format = (*\meta{格式}*) + \end{ccnusyntax} + \env{material} 环境内容的格式。默认为 |\kaishu|。 +\end{function} + +\begin{function}[updated = 2022-07-24]{material/source} + \begin{ccnusyntax}[emph={[1]source}] + source = (*\meta{来源出处}*) + \end{ccnusyntax} + \env{material} 环境下方的来源出处。会新起一行并右对齐。 +\end{function} + +\begin{function}[updated = 2022-07-24]{material/source-format} + \begin{ccnusyntax}[emph={[1]source-format}] + source-format = (*\meta{格式}*) + \end{ccnusyntax} + \env{material} 环境下方的来源出处的格式。 +\end{function} + +\begin{function}[added = 2022-07-24]{material/top-sep} + \begin{ccnusyntax}[emph={[1]top-sep}] + top-sep = (*\meta{弹性长度}*) + \end{ccnusyntax} + \env{material} 环境和标题(如果有)的整体上方间距。默认为 |0pt|。 +\end{function} + +\begin{function}[added = 2022-07-24]{material/bottom-sep} + \begin{ccnusyntax}[emph={[1]bottom-sep}] + bottom-sep = (*\meta{弹性长度}*) + \end{ccnusyntax} + \env{material} 环境的下方间距。默认为 |0pt|。 +\end{function} + +\begin{function}[added = 2022-07-24]{material/title-material-sep} + \begin{ccnusyntax}[emph={[1]title-material-sep}] + title-material-sep = (*\meta{弹性长度}*) + \end{ccnusyntax} + \env{material} 环境和标题(如果有)的间距。默认为 |0pt|。 +\end{function} + + +\begin{function}[updated = 2022-07-24]{poem} + \begin{ccnusyntax}[emph={[1]material}] + poem = (*\marg{键值列表}*) + poem/(*\meta{key}*) = (*\meta{value}*) + \end{ccnusyntax} + 该选项包含多个子项目。用于设置 \env{poem} 环境。可以在 \tn{examsetup} 中使用,也可以在 \env{poem} 环境的可选参数中使用。 +\end{function} + +\begin{function}[updated = 2022-07-24]{poem/title} + \begin{ccnusyntax}[emph={[1]title}] + title = (*\meta{标题}*) + \end{ccnusyntax} + \env{poem} 环境的上方标题的 \emph{内容}。可以为空或不写。 +\end{function} + +\begin{function}[updated = 2022-07-24]{poem/title-format} + \begin{ccnusyntax}[emph={[1]title-format}] + title-format = (*\meta{格式}*) + \end{ccnusyntax} + \env{poem} 环境的上方标题的 \emph{格式}。默认为 |\zihao{5}|。 +\end{function} + +\begin{function}[updated = 2022-07-24]{poem/author} + \begin{ccnusyntax}[emph={[1]author}] + author = (*\meta{作者}*) + \end{ccnusyntax} + \env{poem} 环境的上方作者的 \emph{作者名}。可以为空或不写。 +\end{function} + +\begin{function}[updated = 2022-07-24]{poem/author-format} + \begin{ccnusyntax}[emph={[1]author-format}] + author-format = (*\meta{格式}*) + \end{ccnusyntax} + \env{poem} 环境的上方作者的 \emph{格式}。默认为 |\small|。 +\end{function} + +\begin{function}[updated = 2022-07-24]{poem/title-author-sep} + \begin{ccnusyntax}[emph={[1]title-author-sep}] + title-author-sep = (*\meta{弹性长度}*) + \end{ccnusyntax} + \env{poem} 环境的上方标题和作者之间的距离。默认为 |2em|。 +\end{function} + + +\begin{function}[added = 2022-07-24]{poem/format} + \begin{ccnusyntax}[emph={[1]format}] + format = (*\meta{格式}*) + \end{ccnusyntax} + \env{poem} 环境内容的格式。默认为 |\kaishu|。 +\end{function} + +\begin{function}[added = 2022-07-26]{poem/align} + \begin{ccnusyntax}[emph={[1]align}] + align = (*<(l)|c|r>*) + \end{ccnusyntax} + \env{poem} 环境内容的对齐方式。\opt{l} 表示左对齐;\opt{c} 表示居中对齐;\opt{r} 表示右对齐。 +\end{function} + +\begin{function}[added = 2022-07-24]{poem/top-sep} + \begin{ccnusyntax}[emph={[1]top-sep}] + top-sep = (*\meta{弹性长度}*) + \end{ccnusyntax} + \env{poem} 环境和标题(如果有)的整体上方间距。默认为 |0pt|。 +\end{function} + +\begin{function}[added = 2022-07-24]{poem/bottom-sep} + \begin{ccnusyntax}[emph={[1]bottom-sep}] + bottom-sep = (*\meta{弹性长度}*) + \end{ccnusyntax} + \env{poem} 环境的下方间距。默认为 |0pt|。 +\end{function} + +\begin{function}[added = 2022-07-24]{poem/title-poem-sep} + \begin{ccnusyntax}[emph={[1]title-poem-sep}] + title-poem-sep = (*\meta{弹性长度}*) + \end{ccnusyntax} + \env{poem} 环境和标题(如果有)的间距。默认为 |0pt|。 +\end{function} + +\begin{function}[added = 2022-07-25]{poem/type} + \begin{ccnusyntax}[emph={[1]type}] + type = (*<minipage|(chinese)>*) + \end{ccnusyntax} + \env{poem} 环境的类型(主要体现在页脚)。\opt{minipage} 表示 \env{poem} 环境的页脚是基于 \env{minipage} 环境形成的,脚注上方有横线,且两条脚注之间是分行的;\opt{chinese} 表示脚注不分行,连着显示,且最前方有 |[注]| 字(设计来源于“2021 年普通高等学校招生全国统一考试”语文真题卷)。 +\end{function} + +\begin{function}[added = 2022-07-26]{poem/zhu-circlednumber-base} + \begin{ccnusyntax}[emph={[1]zhu-circlednumber-base}] + zhu-circlednumber-base = (*<tikz|(font)>*) + \end{ccnusyntax} + 在 \kvopt{poem/type}{chinese} 键值下,\tn{zhu} 的带圈数字的源。\opt{tikz} 表示此时带圈数字基于 \TikZ,\opt{font} 表示此时带圈数字基于字体。 +\end{function}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/exam-zh-doc-setup.tex b/Master/texmf-dist/doc/xelatex/exam-zh/doc/exam-zh-doc-setup.tex new file mode 100644 index 00000000000..19b2ed0661d --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/exam-zh-doc-setup.tex @@ -0,0 +1,65 @@ +\usepackage{xeCJKfntef, xpinyin} +\usepackage{graphicx} +\usepackage{tabularray} +\usepackage{../exam-zh-choices} +\usepackage{../exam-zh-question} +\usepackage{../exam-zh-symbols} +\usepackage{../exam-zh-chinese-english} + +\ExplSyntaxOn +\NewDocumentCommand \examsetup { m } + { \keys_set:nn { exam-zh } {#1} } +\ExplSyntaxOff +% \usepackage[ +% backend = biber, +% style = gb7714-2015 +% ]{biblatex} +% \addbibresource{exam-zh.bib} +\graphicspath{{figures}} + +\hypersetup{ + pdftitle = {exam-zh: 高考试卷 LaTeX 模板}, + pdfauthor = {夏康玮} +} +% 全角标点放在引号中,需要改成半角式,否则间距过大,不好看 +\def\FSID{“{\xeCJKsetup{PunctStyle=banjiao}。}”} % U+3002 +\def\FSFW{“{\xeCJKsetup{PunctStyle=banjiao}.}”} % U+FF0E +\def\COFW{“{\xeCJKsetup{PunctStyle=banjiao}:}”} % U+FF1A +\def\SCFW{“{\xeCJKsetup{PunctStyle=banjiao};}”} % U+FF1B + + +\title{\textcolor{MaterialIndigo800}{% + \textbf{exam-zh: 高考试卷 \LaTeX \xpinyin[font=\sffamily,format=\color{MaterialIndigo800}]{模}{mu2}板}}} +\author{李泽平,夏康玮,郭李军} +\date{2022/07/28\quad v0.1.13% + \thanks{% + \url{https://gitee.com/zepinglee/exam-zh} + } +} + +\ExplSyntaxOn +\NewDocumentCommand \eu { } { \mathrm{ e } } +\NewDocumentCommand \iu { } { \mathrm{ i } } +\NewDocumentCommand { \scoringbox } { s } + { + \IfBooleanTF {#1} + { \__examzh_scoringbox_onecolumn: } + { \__examzh_scoringbox_twocolumn: } + } +\cs_new_protected:Nn \__examzh_scoringbox_twocolumn: + { + \begin{tabular}{|c|c|} + \hline + 得分 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline + 阅卷人 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline + \end{tabular} + } +\cs_new_protected:Nn \__examzh_scoringbox_onecolumn: + { + \begin{tabular}{|c|} + \hline + 得分\rule[-0.7em]{0pt}{2em} \\\hline + \rule[-0.7em]{0pt}{2em} \\\hline + \end{tabular} + } +\ExplSyntaxOff
\ No newline at end of file diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/exam-zh-doc.pdf b/Master/texmf-dist/doc/xelatex/exam-zh/doc/exam-zh-doc.pdf Binary files differnew file mode 100644 index 00000000000..e3cd445997f --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/exam-zh-doc.pdf diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/exam-zh-doc.tex b/Master/texmf-dist/doc/xelatex/exam-zh/doc/exam-zh-doc.tex new file mode 100644 index 00000000000..956a94c3df8 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/exam-zh-doc.tex @@ -0,0 +1,87 @@ +\documentclass{xdyydoc} +\input{exam-zh-doc-setup.tex} +\usepackage{amssymb} + +\begin{document} + +% 封面的页边距 + +\newgeometry{ + left = 2.2 in, + right = 1.25 in, + top = 1.25 in, + bottom = 1.00 in +} + +\maketitle + +\input{./body/cover.tex} + + +% 用户手册的页边距 + +\newgeometry{ + left = 1.75 in, + right = 0.80 in, + top = 1.25 in, + bottom = 1.00 in +} + +\tableofcontents + + +% 介绍 +\input{./body/introduction.tex} +% 安装 +\input{./body/installation.tex} + +% \clearpage +% 使用 +\input{./body/usage.tex} + + +% 宏包依赖情况 +\input{./back/package.tex} +% 主要更新 +\input{./back/main-changelog.tex} + +% 参与开发 +\input{./back/development.tex} + + +% 关于作者 +\input{./back/about-author.tex} + + + +\section{\cls{exam-zh}:TODO} + +\begin{itemize} + \item 增加试卷范例(语文,英语) + \item 答案控制 + \begin{itemize} + \item 选择题 + \begin{itemize} + \item 题目下方 + \item 括号内 + \item 最后:列表形式、表格形式 + \end{itemize} + \item 填空题 + \begin{itemize} + \item 题目下方 + \item 划线内 + \item 最后 + \end{itemize} + \item 解答题 + \begin{itemize} + \item 题目下方 + \item 移动到最后 + \end{itemize} + \end{itemize} + \item 选择题答案标记 + \item 图文排版(参考 xkwxdyy 的 \pkg{text-figure} 宏包和 qinglee 的 \pkg{wrapstuff} 宏包) + \item 测试兼容性 +\end{itemize} + + +\end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/figures/firstpage.pdf b/Master/texmf-dist/doc/xelatex/exam-zh/doc/figures/firstpage.pdf Binary files differnew file mode 100644 index 00000000000..43f80e7dccf --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/figures/firstpage.pdf diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/figures/gitee-main.png b/Master/texmf-dist/doc/xelatex/exam-zh/doc/figures/gitee-main.png Binary files differnew file mode 100644 index 00000000000..388dfaa66d8 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/figures/gitee-main.png diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/figures/gitee-release.png b/Master/texmf-dist/doc/xelatex/exam-zh/doc/figures/gitee-release.png Binary files differnew file mode 100644 index 00000000000..79ac0b13a77 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/figures/gitee-release.png diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/doc/xdyydoc.cls b/Master/texmf-dist/doc/xelatex/exam-zh/doc/xdyydoc.cls new file mode 100644 index 00000000000..cce615933d4 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/doc/xdyydoc.cls @@ -0,0 +1,1145 @@ +\NeedsTeXFormat{LaTeX2e}[2020/10/01] +\ProvidesExplClass{xdyydoc} + {2022-04-26}{0.1a}{Documentation class for CCNUthesis} +\@namedef{ver@thumbpdf.sty}{9999/99/99} +\LoadClass[a4paper, full]{l3doc} +\RequirePackage[heading, sub3section, fontset=none]{ctex} +\RequirePackage{% + caption, + geometry, + graphicx, + listings, + makecell, + siunitx, + tabularx, + threeparttable, + unicode-math, + xcolor, + ninecolors, + xcolor-material, + xunicode, + zref-base, + tikz, + tikzpagenodes, + tcolorbox, + accsupp, % PDF accessibility support + MnSymbol, + lstautogobble +} +\tcbuselibrary{listings} +\tcbuselibrary{hooks, skins, xparse, breakable} +% \tcbuselibrary{hooks, minted, skins, xparse, breakable} +\definecolor{main}{HTML}{5989cf} % setting main color to be used +\definecolor{sub}{HTML}{cde4ff} % setting sub color to be used +\def\macro@code{% + \topsep \MacrocodeTopsep + \@beginparpenalty \predisplaypenalty + \partopsep \z@skip + \trivlist \parskip \z@ \item[]% + \MacroFont + \leftskip\@totalleftmargin \advance\leftskip\MacroIndent + \rightskip\z@ \parindent\z@ \parfillskip\@flushglue + \blank@linefalse \def\par{\ifblank@line + \leavevmode\fi + \blank@linetrue\@@par + \penalty\interlinepenalty} + \obeylines + \let\do\do@noligs \verbatim@nolig@list + \let\do\@makeother \dospecials + \global\@newlistfalse + \global\@minipagefalse + \init@crossref} +\ExplSyntaxOn +\tl_new:N \l__fdudoc_tmpa_tl +\tl_new:N \l__fdudoc_tmpb_tl +\cs_new_protected:Npn \__fdudoc_patch_cmd:Nnn #1#2#3 + { + \ctex_patch_cmd_once:NnnnTF #1 { } {#2} {#3} + { } { \ctex_patch_failure:N #1 } + } +\cs_new_protected:Npn \__fdudoc_preto_cmd:Nn #1#2 + { + \ctex_preto_cmd:NnnTF #1 { } {#2} + { } { \ctex_patch_failure:N #1 } + } +\cs_new_protected:Npn \__fdudoc_appto_cmd:Nn #1#2 + { + \ctex_appto_cmd:NnnTF #1 { } {#2} + { } { \ctex_patch_failure:N #1 } + } +\cs_set_protected_nopar:Npn \xmacro@code + { \__fdudoc_marco_code:w } +\cs_set_protected_nopar:Npn \sxmacro@code + { + \fontspec_print_visible_spaces: + \xmacro@code + } +\cs_new_protected_nopar:Npn \__fdudoc_marco_code:w + { + \ifcodeline@index + \__fdudoc_marco_code_every_par:n { \__fdudoc_code_line_no: } + \else: + \__fdudoc_marco_code_every_par:n { } + \fi: + \__fdudoc_make_finish_tag:x { \@currenvir } + \__fdudoc_macro_code_start:w + } +\cs_new_protected:Npn \__fdudoc_marco_code_every_par:n #1 + { + \everypar + { + \everypar {#1} + \if@inlabel + \global \@inlabelfalse \@noparlistfalse + \llap { \box \@labels \hskip \leftskip } + \fi + #1 + } + } +\group_begin: + \int_set:Nn \tex_endlinechar:D { -1 } + \use:n + { + \char_set_catcode_active:n { 32 } + \tl_const:Nn \c__fdudoc_active_space_tl + } + { } +\group_end: +\group_begin: + \char_set_catcode_active:n { 13 } + \cs_new_protected:Npx \__fdudoc_make_finish_tag:n #1 + { + \tl_set:Nn \exp_not:N \l__fdudoc_macro_code_finish_tl + { + \c_percent_str + \prg_replicate:nn { 4 } + { \exp_not:o { \c__fdudoc_active_space_tl } } + \exp_not:o { \active@escape@char } end + \c_left_brace_str #1 \c_right_brace_str + \exp_not:N ^^M + } + } + \cs_generate_variant:Nn \__fdudoc_make_finish_tag:n { x } + \cs_new_protected:Npn \__fdudoc_macro_code_start:w #1 + { + \str_if_eq:nnTF {#1} { ^^M } + { \__fdudoc_macro_code_read_line:w } + { \__fdudoc_macro_code_read_line:w #1 } + } + \cs_new_protected:Npn \__fdudoc_macro_code_read_line:w #1 ^^M + { + \tl_set:Nn \l__fdudoc_macro_code_line_tl { #1 ^^M } + \tl_if_eq:NNTF + \l__fdudoc_macro_code_line_tl \l__fdudoc_macro_code_finish_tl + { \exp_args:Nx \end { \@currenvir } } + { + \__fdudoc_macro_code_process_line: + \__fdudoc_macro_code_read_line:w + } + } + \cs_new_protected:Npn \__fdudoc_swap_cr: + { + \exp_after:wN + \__fdudoc_swap_cr_aux:w \l__fdudoc_macro_code_line_tl + } + \cs_new_protected:Npn \__fdudoc_swap_cr_aux:w #1 ^^M + { + \group_insert_after:N ^^M + \tl_set:Nn \l__fdudoc_macro_code_line_tl {#1} + } + \tl_const:Nn \c__fdudoc_active_cr_tl { ^^M } +\group_end: +\tl_new:N \l__fdudoc_macro_code_line_tl +\tl_new:N \l__fdudoc_macro_code_finish_tl +\tl_new:N \g__fdudoc_macro_code_verbatim_stop_tl +\cs_new_protected_nopar:Npn \__fdudoc_process_normal_line: + { + \str_case_e:nnF + { \str_head:N \l__fdudoc_macro_code_line_tl } + { + { \c_percent_str } + { + \__fdudoc_check_angle:x + { \tl_tail:N \l__fdudoc_macro_code_line_tl } + } + { \c_hash_str } + { \__fdudoc_output_comment_line: } + } + { \__fdudoc_output_line: } + } +\cs_new_protected_nopar:Npn \__fdudoc_process_verbatim_line: + { + \tl_if_eq:NNTF \l__fdudoc_macro_code_line_tl + \g__fdudoc_macro_code_verbatim_stop_tl + { + \tl_gclear:N \g__fdudoc_macro_code_verbatim_stop_tl + \cs_gset_eq:NN \__fdudoc_macro_code_process_line: + \__fdudoc_process_normal_line: + \__fdudoc_output_module:nn + { \color { verb@guard } } + { + \__fdudoc_swap_cr: + \__fdudoc_module_pop:n { \l__fdudoc_macro_code_line_tl } + } + } + { \tl_use:N \l__fdudoc_macro_code_line_tl } + } +\cs_new_eq:NN \__fdudoc_macro_code_process_line: + \__fdudoc_process_normal_line: +\DeclareDocumentCommand \CheckModules { } + { + \cs_set_eq:NN \__fdudoc_macro_code_process_line: + \__fdudoc_process_normal_line: + } +\DeclareDocumentCommand \DontCheckModules { } + { + \cs_set_eq:NN \__fdudoc_macro_code_process_line: + \__fdudoc_output_line: + } +\cs_new_protected:Npn \__fdudoc_check_angle:n #1 + { + \str_if_eq:eeTF { \str_head:n {#1} } { < } + { \__fdudoc_check_module:x { \tl_tail:n {#1} } } + { \__fdudoc_output_comment_line: } + } +\cs_generate_variant:Nn \__fdudoc_check_angle:n { x } +\cs_new_protected:Npn \__fdudoc_check_module:n #1 + { + \str_case_e:nnF { \str_head:n {#1} } + { + { * } { \__fdudoc_module_star:w } + { / } { \__fdudoc_module_slash:w } + { @ } { \__fdudoc_module_at:w } + { < } { \__fdudoc_module_verb:w } + } + { \__fdudoc_module_pm:w } + #1 \q_stop + } +\cs_generate_variant:Nn \__fdudoc_check_module:n { x } +\group_begin: + \char_set_catcode_active:N \> + \cs_new_protected:Npn \__fdudoc_module_star:w #1 > #2 \q_stop + { + \tl_set:Nn \l__fdudoc_tmpa_tl {#2} + \tl_if_eq:NNTF \l__fdudoc_tmpa_tl \c__fdudoc_active_cr_tl + { + \__fdudoc_output_module:nn + { \__fdudoc_star_color: } + { + \__fdudoc_module_push:n + { \__fdudoc_module_angle:n {#1} } + } + } + { + \__fdudoc_output_module_left:nn + { \__fdudoc_star_color: } + { + \__fdudoc_module_push:n + { \__fdudoc_module_angle:n {#1} } + } + } + \__fdudoc_output_line:n {#2} + } + \cs_new_protected:Npn \__fdudoc_module_slash:w #1 > #2 \q_stop + { + \tl_set:Nn \l__fdudoc_tmpa_tl {#2} + \tl_if_eq:NNTF \l__fdudoc_tmpa_tl \c__fdudoc_active_cr_tl + { + \__fdudoc_output_module:nn + { \__fdudoc_slash_color: } + { + \__fdudoc_module_pop:n + { \__fdudoc_module_angle:n {#1} } + } + } + { + \__fdudoc_output_module_left:nn + { \__fdudoc_slash_color: } + { + \__fdudoc_module_pop:n + { \__fdudoc_module_angle:n {#1} } + } + } + \__fdudoc_output_line:n {#2} + } + \cs_new_protected:Npn \__fdudoc_module_at:w @ @ = #1 > #2 \q_stop + { + \__fdudoc_output_module:nn + { \color { at@guard } } + { \__fdudoc_module_angle:n { @ @ = #1 } } + \tl_gset:Nn \g__codedoc_module_name_tl {#1} + \__fdudoc_output_line:n {#2} + } + \cs_new_protected:Npn \__fdudoc_module_verb:w #1 \q_stop + { + \cs_gset_eq:NN \__fdudoc_macro_code_process_line: + \__fdudoc_process_verbatim_line: + \tl_gset:Nx \g__fdudoc_macro_code_verbatim_stop_tl + { \c_percent_str \tl_tail:n {#1} } + \__fdudoc_output_module:nn + { \color { verb@guard } } + { + \__fdudoc_swap_cr: + \__fdudoc_module_push:n { \l__fdudoc_macro_code_line_tl } + } + } + \cs_new_protected:Npn \__fdudoc_module_pm:w #1 > #2 \q_stop + { + \__fdudoc_output_module_left:nn + { \__fdudoc_pm_color: } + { \__fdudoc_module_angle:n {#1} } + \__fdudoc_output_line:n {#2} + } +\group_end: +\cs_new_protected:Npn \__fdudoc_output_line:n #1 + { + \tl_set:Nn \l__fdudoc_macro_code_line_tl {#1} + \tl_if_eq:NNTF + \l__fdudoc_macro_code_line_tl \c__fdudoc_active_cr_tl + { \tl_use:N \l__fdudoc_macro_code_line_tl } + { + \str_if_eq:eeTF + { \str_head:N \l__fdudoc_macro_code_line_tl } { \c_percent_str } + { \__fdudoc_output_comment_line: } { \__fdudoc_output_line: } + } + } +\cs_new_protected_nopar:Npn \__fdudoc_output_line: + { + \tex_noindent:D + \__fdudoc_replace_at_at:N \l__fdudoc_macro_code_line_tl + \tl_use:N \l__fdudoc_macro_code_line_tl + } +\cs_new_protected:Npn \__fdudoc_output_comment_line: + { + \tex_noindent:D + \group_begin: + \__fdudoc_swap_cr: + \color { code@gray } \slshape \__fdudoc_output_line: + \group_end: + } +\cs_new_protected:Npn \__fdudoc_replace_at_at:N #1 + { + \tl_if_empty:NF \g__codedoc_module_name_tl + { \__fdudoc_replace_at_at_aux:No #1 \g__codedoc_module_name_tl } + } +\cs_new_protected:Npn \__fdudoc_replace_at_at_aux:Nn #1#2 + { + \tl_replace_all:Nnn #1 { _ @ @ } { _ _ #2 } + \tl_replace_all:Nnn #1 { @ @ } { _ _ #2 } + } +\cs_generate_variant:Nn \__fdudoc_replace_at_at_aux:Nn { No } +\cs_new_protected_nopar:Npn \__fdudoc_module_push:n + { \__fdudoc_module_push_aux:on { \int_use:N \c@HD@hypercount } } +\cs_new_protected:Npn \__fdudoc_module_push_aux:nn #1 + { + \seq_gpush:Nn \g__fdudoc_module_dest_seq {#1} + \hypersetup { hidelinks } + \exp_args:Nx \hdclindex + { \zref@extractdefault { HD.#1 } { guard@end } { 1 } } { } + } +\cs_generate_variant:Nn \__fdudoc_module_push_aux:nn { on } +\cs_new_protected_nopar:Npn \__fdudoc_module_pop:n + { + \seq_gpop:NNTF \g__fdudoc_module_dest_seq \l__fdudoc_tmpa_tl + { \__fdudoc_module_pop_aux:on { \l__fdudoc_tmpa_tl } } + { \BOOM \use:n } + } +\cs_new_protected:Npn \__fdudoc_module_pop_aux:nn #1 + { + \zref@labelbylist { HD.#1 } { fdudoc } + \hypersetup { hidelinks } + \hdclindex {#1} { } + } +\cs_generate_variant:Nn \__fdudoc_module_pop_aux:nn { on } +\seq_new:N \g__fdudoc_module_dest_seq +\zref@newlist { fdudoc } +\zref@newprop { guard@end } [ 1 ] + { \int_eval:n { \c@HD@hypercount - 1 } } +\zref@addprop { fdudoc } { guard@end } +\cs_set_protected:Npn \MacroFont + { + \linespread { 1.05 } + \small \ttfamily \mdseries \upshape + \__fdudoc_verb_addon: + } +\cs_new_protected:Npn \__fdudoc_output_module:nn #1#2 + { + \tex_noindent:D + \group_begin: + #1 + \footnotesize \normalfont \sffamily #2 + \group_end: + } +\cs_new_protected:Npn \__fdudoc_output_module_left:nn #1#2 + { + \tex_noindent:D + \hbox_overlap_left:n + { + \__fdudoc_output_module:nn {#1} {#2} + \skip_horizontal:n { \leftskip + \smallskipamount } + } + } +\cs_new_protected_nopar:Npn \__fdudoc_star_color: + { + \seq_gpop:NNTF \g__fdudoc_star_color_seq \current@color + { \set@color } + { \__fdudoc_select_color: } + \seq_gpush:No \g__fdudoc_slash_color_seq { \current@color } + } +\cs_new_protected_nopar:Npn \__fdudoc_slash_color: + { + \seq_gpop:NNTF \g__fdudoc_slash_color_seq \current@color + { + \set@color + \seq_gpush:No \g__fdudoc_star_color_seq { \current@color } + } + { \BOOM } + } +\cs_new_protected_nopar:Npn \__fdudoc_pm_color: + { + \seq_get:NNTF \g__fdudoc_star_color_seq \current@color + { \set@color } + { + \__fdudoc_select_color: + \seq_gpush:No \g__fdudoc_star_color_seq { \current@color } + } + } +\seq_new:N \g__fdudoc_star_color_seq +\seq_new:N \g__fdudoc_slash_color_seq +\cs_new_protected_nopar:Npn \__fdudoc_select_color: + { \color { guard@series!!+ } } +\definecolorseries { guard@series } + { cmyk } { last } { blue } { purple } +\resetcolorseries [ 3 ] { guard@series } +\definecolor { verb@guard } { named } { MaterialLime600 } +\definecolor { at@guard } { named } { MaterialPink } +\definecolor { code@gray } { named } { MaterialGrey } +\cs_new_protected:Npn \__fdudoc_module_angle:n #1 + { < #1 > } +\cs_new_protected_nopar:Npn \__fdudoc_code_line_no: + { + \int_gincr:N \c@CodelineNo + \hbox_overlap_left:n + { + \hbox_to_wd:nn + { \MacroIndent } + { + \HD@target + \tex_hss:D \__fdudoc_code_line_no_style: + \theCodelineNo \enspace + } + \tex_kern:D \@totalleftmargin + } + } +\tl_set:Nn \theCodelineNo { \arabic { CodelineNo } } +\cs_new_protected_nopar:Npn \__fdudoc_code_line_no_style: + { \color { code@gray } \normalfont \sffamily \tiny } +\cs_set_protected:Npn \HD@SetMacroIndent #1 + { + \group_begin: + \settowidth \MacroIndent + { + \__fdudoc_code_line_no_style: + \prg_replicate:nn { \tl_count:n {#1} } { 0 } + \enspace + } + \dim_gset_eq:NN \MacroIndent \MacroIndent + \group_end: + } +\sys_if_engine_xetex:TF + { + \cs_set_eq:NN \__fdudoc_verb_addon: \xeCJKVerbAddon + \cs_set:Nn \__fdudoc_plain_punct_style: + { \xeCJKsetup { PunctStyle = plain } } + \cs_set:Nn \__fdudoc_disable_ecglue: + { \xeCJKsetup { CJKecglue } } + \__fdudoc_appto_cmd:Nn \meta@font@select + { \mode_if_inner:T { \__fdudoc_disable_ecglue: } } + } + { + \cs_set_eq:NN \__fdudoc_verb_addon: \prg_do_nothing: + \cs_set_eq:NN \__fdudoc_plain_punct_style: \prg_do_nothing: + \cs_set:Nn \__fdudoc_disable_ecglue: + { \ltjsetparameter { autoxspacing = false } } + \__fdudoc_appto_cmd:Nn \meta@font@select + { \__fdudoc_disable_ecglue: } + } +\BeforeBeginEnvironment { function } + { \par \nointerlineskip } +\AtEndEnvironment { function } + { + \par + \cs_gset:Nx \__fdudoc_fix_previous_depth: + { \prevdepth = \the \prevdepth \space } + } +\AfterEndEnvironment { function } + { \__fdudoc_fix_previous_depth: } +\AtBeginEnvironment { syntax } + { + \linespread { 1.2 } + \__fdudoc_plain_punct_style: + \__fdudoc_disable_ecglue: + } +\AtBeginEnvironment { ccnusyntax } + { + \cs_set:Npn \lparen { \textup { ( } } + \cs_set:Npn \rparen { \textup { ) } } + \char_set_catcode_active:N | + \char_set_catcode_active:N < + \char_set_catcode_active:N ( + \char_set_active_eq:NN | \orbar + \char_set_active_eq:NN < \syntaxopt@aux + \char_set_active_eq:NN ( \defaultval@aux + } +\cs_new_eq:NN \__fdudoc_ltx_changes:nnn \changes@ +\cs_set_protected:Npn \changes@ #1#2 + { + \__fdudoc_save_version_date:nn {#1} {#2} + \__fdudoc_ltx_changes:nnn {#1} {#2} + } +\prop_new:N \g__fdudoc_version_date_prop +\cs_new_protected:Npn \__fdudoc_save_version_date:nn #1#2 + { + \prop_get:NnNTF \g__fdudoc_version_date_prop + {#1} \l__fdudoc_tmpa_tl + { + \exp_after:wN + \__fdudoc_save_version_date_aux:nnnn \l__fdudoc_tmpa_tl + {#2} {#1} + } + { \__fdudoc_save_version_date_aux:nnn {#1} {#2} {#2} } + } +\cs_new_protected:Npn \__fdudoc_save_version_date_aux:nnnn #1#2#3#4 + { + \__fdudoc_if_date_later:nnTF {#1} {#3} + { \__fdudoc_save_version_date_aux:nnn {#4} {#3} {#2} } + { + \__fdudoc_if_date_later:nnT {#3} {#2} + { \__fdudoc_save_version_date_aux:nnn {#4} {#1} {#3} } + } + } +\cs_new_protected:Npn \__fdudoc_save_version_date_aux:nnn #1#2#3 + { \prop_gput:Nnn \g__fdudoc_version_date_prop {#1} { {#2} {#3} } } +\prg_new_conditional:Npnn \__fdudoc_if_date_later:nn #1#2 { TF, T } + { + \if_int_compare:w + \__fdudoc_parse_date:w #1 / / / 0 \q_stop > + \__fdudoc_parse_date:w #2 / / / 0 \q_stop \exp_stop_f: + \prg_return_true: + \else: + \prg_return_false: + \fi: + } +\cs_new:Npn \__fdudoc_parse_date:w #1/#2/#3/ #4 \q_stop + { #1#2#3 } +\cs_new_protected:Npn \CTEX@versionitem #1 \efill + { + \@idxitem + \prop_get:NnNTF \g__fdudoc_version_date_prop + {#1} \l__fdudoc_tmpa_tl + { + \exp_after:wN + \__fdudoc_print_version_date:nnn \l__fdudoc_tmpa_tl + {#1} + } + { \BOOM } + } +\cs_new_protected:Npn \__fdudoc_print_version_date:nnn #1#2#3 + { + \noindent + \Hy@raisedlink { \belowpdfbookmark {#3} { HD.#3 } } + \textbf {#3} \hfill + \hbox:n + { + \footnotesize + \str_if_eq:nnTF {#1} {#2} + { ( #1 ) } { ( #1 ~ -- ~ #2 ) } + } + \par \nopagebreak + } +\ctex_patch_cmd:Nnn \HDorg@theglossary + { \let \item \@idxitem } + { \let \item \CTEX@versionitem } +\ctex_patch_cmd:Nnn \@wrglossary + { hdpindex } + { + \ifnum \c@HD@hypercount = \z@ + hdpindex + \else + hdclindex { \the \c@HD@hypercount } + \fi + } +\ctex_patch_cmd:Nnn \@addtocurcol + { \vskip \intextsep } + { + \edef \save@first@penalty { \the \lastpenalty } \unpenalty + \ifnum \lastpenalty = \@M + \unpenalty + \else + \penalty \save@first@penalty \relax + \fi + \ifnum \outputpenalty < -\@Mii + \addvspace\intextsep + \vskip\parskip + \else + \addvspace\intextsep + \fi + } +\ctex_patch_cmd:Nnn \@addtocurcol + { + \vskip \intextsep + \ifnum \outputpenalty < -\@Mii + \vskip -\parskip + \fi + } + { + \ifnum \outputpenalty < -\@Mii + \aftergroup \vskip \aftergroup \intextsep + \aftergroup \nointerlineskip + \else + \vskip \intextsep + \fi + } +\ctex_patch_cmd:Nnn \@getpen { \@M } { \@Mi } +\ctex_patch_cmd:Nnn \l@section { 2.5em } { 1.5em } +\ctex_patch_cmd:Nnn \l@subsection { 2.5em } { 1.5em } +\__fdudoc_preto_cmd:Nn \@thehead + { \cs_set_eq:cN { MakeUppercase \space } \@iden } +\ctex_patch_cmd:Nnn \HDorg@thebibliography + { \section* } { \section } +\cs_set_eq:NN \thebibliography \HDorg@thebibliography +\__fdudoc_appto_cmd:Nn \GlossaryParms + { + \raggedcolumns + \cs_set_eq:NN \Hy@writebookmark \HDorg@writebookmark + \cs_set:Npn \@idxitem { \par \hangindent 2em } + \cs_set:Npn \subitem { \@idxitem \hspace* { 1em } } + \cs_set:Npn \subsubitem { \@idxitem \hspace* { 2em } } + } +\ctex_patch_cmd:Nnn \HoLogo@LaTeXe + { \hbox { \HOLOGO@MathSetup 2 $ _{ \textstyle \varepsilon } $ } } + { + \hbox + { + \mathsurround 0pt \relax + 2 + \if b \expandafter \@car \f@series \@nil + $ _{ \textstyle \symbf { \varepsilon } } $ + \else + $ _{ \textstyle \varepsilon } $ + \fi + } + } +\ctex_patch_cmd:Nnn \SpecialMainEnvIndex + { (environment) } { ~ 环境 } +\ctex_patch_cmd:Nnn \SpecialMainEnvIndex + { environments: } { 环境: } +\ctex_patch_cmd:Nnn \HDorg@SpecialEnvIndex + { (environment) } { ~ 环境 } +\ctex_patch_cmd:Nnn \HDorg@SpecialEnvIndex + { environments: } { 环境: } +\cs_set_eq:NN \list \__codedoc_oldlist:nn +\__fdudoc_patch_cmd:Nnn \__codedoc_function_descr_start:w + { \noindent } + { \skip_vertical:n { -\parskip } \noindent } +\__fdudoc_preto_cmd:Nn \__codedoc_function_assemble: + { + \box_if_empty:NTF \g__codedoc_syntax_box + { \skip_zero:N \medskipamount } + { \skip_add:Nn \medskipamount { \parskip } } + } +\__fdudoc_patch_cmd:Nnn \__codedoc_typeset_functions: + { \small \ttfamily } { \footnotesize \ttfamily } +\__fdudoc_preto_cmd:Nn \__codedoc_typeset_functions: + { \MacroFont } +\__fdudoc_patch_cmd:Nnn \__codedoc_macro_init: + { \hbox:n } { \MacroFont \hbox:n } +\__fdudoc_patch_cmd:Nnn \__codedoc_macro_dump: + { \hbox_unpack_drop:N } { \MacroFont \hbox_unpack_drop:N } +\__fdudoc_patch_cmd:Nnn \__codedoc_meta_original:n + { \ensuremath \langle } { \textlangle } +\__fdudoc_patch_cmd:Nnn \__codedoc_meta_original:n + { \ensuremath \rangle } { \textrangle } +\cs_set_eq:NN \__codedoc_macro_end_style:n \use_none:n +\cs_set_protected:Npn \__codedoc_typeset_TF: + { + \group_begin: + \exp_args:No \__codedoc_if_macro_internal:nT \l__codedoc_tmpa_tl + { \color [ gray ] { 0.5 } } + \itshape TF + \makebox [ 0 pt ] [ r ] + { + \color { red } + \underline { \phantom { \itshape TF } \kern -0.1 em } + } + \group_end: + } +\cs_set_protected:Npn \__codedoc_macro_typeset_one:nN #1#2 + { + \vbox_set:Nn \l__codedoc_macro_box + { + \MacroFont + \vbox_unpack_drop:N \l__codedoc_macro_box + \hbox_set:Nn \l_tmpa_box + { \__codedoc_print_macroname:nN {#1} #2 } + \dim_set:Nn \l_tmpa_dim + { \marginparwidth - \labelsep - \marginparsep } + \dim_compare:nNnT { \box_wd:N \l_tmpa_box } > \l_tmpa_dim + { + \box_resize_to_wd_and_ht:Nnn \l_tmpa_box + { \l_tmpa_dim } { \box_ht:N \l_tmpa_box } + } + \hbox_overlap_left:n + { + \box_use:N \l_tmpa_box + \skip_horizontal:n { \marginparsep - \labelsep } + } + } + \int_incr:N \l__codedoc_macro_int + } +\cs_set_protected:Npn \__codedoc_print_macroname:nN #1#2 + { + \strut + \__codedoc_get_hyper_target:xN + { + \exp_not:n {#1} + \bool_if:NT #2 { \tl_to_str:n {TF} } + } + \l__codedoc_tmpa_tl + \cs_if_exist:cTF { r@ \l__codedoc_tmpa_tl } + { \exp_args:NNo \label@hyperref [ \l__codedoc_tmpa_tl ] } + { \use:n } + { + \tl_set:Nn \l__codedoc_tmpa_tl {#1} + \tl_replace_all:Non \l__codedoc_tmpa_tl + { \c_catcode_other_space_tl } + { \fontspec_visible_space: } + \__codedoc_macroname_prefix:o \l__codedoc_tmpa_tl + \__codedoc_macroname_suffix:N #2 + } + } +\cs_set_protected:Npn \__codedoc_special_index_module:nnnnN #1#2#3#4#5 + { + \use:x + { + \exp_not:n { \__codedoc_special_index_aux:nnnnnnn {#1} {#2} } + \tl_if_empty:nTF {#3} + { { } { } { } { } } + { + \str_if_eq:eeTF {#3} { TeX } + { + { TeX~ and~ LaTeX2e } + { \string \TeX{}~ 和~ \string \LaTeXe{} } + } + { {#3} { \string \pkg {#3} } } + \bool_if:NTF #5 + { { commands~ internal } { ~ 内部命令: } } + { { commands } { ~ 命令: } } + } + } + {#4} + } +\cs_new_protected:Npn \__codedoc_special_index_aux:nnnnnnn #1#2#3#4#5#6#7 + { + \tl_set:Nn \l__codedoc_index_escaped_key_tl {#1} + \__codedoc_quote_special_char:N \l__codedoc_index_escaped_key_tl + \__codedoc_special_index_set:Nn + \l__codedoc_index_escaped_macro_tl {#2} + \str_if_eq:onTF { \@currenvir } { macrocode } + { \codeline@wrindex } + { + \str_case:nnF {#7} + { + { main } { \codeline@wrindex } + { usage } { \index } + } + { \HD@target \index } + } + { + \tl_if_empty:nF { #3 #4 #5 #6 } + { #3 #5 \actualchar #4 #6 \levelchar } + \l__codedoc_index_escaped_key_tl + \actualchar + { + \token_to_str:N \verbatim@font \c_space_tl + \l__codedoc_index_escaped_macro_tl + } + \encapchar + hdclindex { \the \c@HD@hypercount } {#7} + } + } +\DeclareDocumentCommand \StopSpecialIndexModule { } + { + \cs_set_eq:NN + \__codedoc_special_index_module:nnnnN \use_none:nnnnn + } +\tl_map_inline:nn { \actualchar \encapchar \levelchar } + { \exp_args:Nx \DoNotIndex { \bslash \tl_to_str:N #1 } } +\RenewDocumentCommand \meta { m } + { + \group_begin: + \sys_if_engine_xetex:T { \xeCJKsetup { CJKecglue = { } } } + \__codedoc_meta:n {#1} + \group_end: + } +\msg_redirect_name:nnn { l3doc } { foreign-internal } { log } +\msg_redirect_name:nnn { l3doc } { print-changes-howto } { log } +\msg_redirect_name:nnn { l3doc } { print-index-howto } { log } +\ExplSyntaxOff +\AtBeginDocument{% + \addtocontents{toc}{\StopSpecialIndexModule}} +\pdfstringdefDisableCommands{% + \let\path\meta + \let\opt\@firstofone} +\let\@multitoc@starttoc\@starttoc +\renewcommand*\@starttoc[1]{% + \begin{multicols}{2}% + \@multitoc@starttoc{#1}% + \end{multicols}} +\renewcommand\@makefntext[1]{\parindent 0em\noindent\@makefnmark~#1} +\IndexPrologue{% + \section{\indexname}% + \textit{意大利体的数字表示对应索引项出现的页码; + 带下划线的数字表示定义对应索引项的代码行号; + 其他则表示使用对应索引项的代码行号。}} +\def\IndexLayout{% + \newgeometry{% + left = 0.85 in, + right = 0.85 in, + top = 1.25 in, + bottom = 1.00 in}% + \setlength\IndexMin{0.5\textheight}% + \ctexset{section/numbering=false}% + \StopSpecialIndexModule} +\def\indexname{代码索引} +\GlossaryPrologue{\section{\glossaryname}} +\def\glossaryname{修订记录} +\setmainfont{LibertinusSerif}[% + Extension = .otf, + UprightFont = *-Regular, + BoldFont = *-Bold, + ItalicFont = *-Italic, + BoldItalicFont = *-BoldItalic, + Scale = 1.1] +\setsansfont{IBMPlexSansCondensed}[% + Extension = .otf, + UprightFont = *-Regular, + BoldFont = *-Bold, + ItalicFont = *-Italic, + BoldItalicFont = *-BoldItalic] +% \setmonofont{Iosevka Slab}[% +% UprightFont = * Light, +% BoldFont = * Semibold, +% ItalicFont = * Light Oblique, +% BoldItalicFont = * Semibold Oblique, +% Scale = MatchLowercase] +\setmonofont{cmun}[% + Extension = .otf, + UprightFont = *btl, + BoldFont = *tb, + ItalicFont = *bto, + BoldItalicFont = *tx, + HyphenChar = None] +\setmathfont{LibertinusMath-Regular.otf} +\setmathfont {NewCMMath-Book} + [ + Extension = .otf, + StylisticSet = 1, + range = { \subsetneqq, \supsetneqq, \checkmark} , + ] +\setCJKmainfont{Source Han Serif SC}[% + ItalicFont = FZKai-Z03, + CharacterWidth = Full] +\setCJKsansfont{Source Han Sans SC}[% + ItalicFont = *, + CharacterWidth = Full] +\setCJKmonofont{Source Han Sans SC}[% + UprightFont = * Normal, + BoldFont = * Bold, + AutoFakeSlant = 0.1763, % = tan(10 deg) + Scale = 0.8903, + CharacterWidth = Full] +\ctexset{% + section/name = {第,节}, + section/format+ = \raggedright, + paragraph/runin = false, + paragraph/numbering = false, + punct = kaiming} +\xeCJKsetwidth{·}{0.5em} +\setcounter{secnumdepth}{4} +\setcounter{tocdepth}{3} +\pagestyle{plain} +\sisetup{% + inter-unit-product = \ensuremath{{}\cdot{}}, + range-phrase = {--}, + uncertainty-mode = separate} +\hypersetup{% + bookmarksdepth = 4, + bookmarksnumbered = true, + colorlinks = true, + citecolor = MaterialGreen, + linkcolor = MaterialPink, + urlcolor = MaterialIndigo} +\captionsetup{labelsep=quad, font+=bf} +\newcolumntype{C}{>{\centering\arraybackslash}X} +\setlist{noitemsep, topsep=\smallskipamount} +\setlist[1]{labelindent=\parindent} +\setlist[enumerate]{leftmargin=*} +\setlist[itemize]{leftmargin=*} +\newlist{optdesc}{description}{3} +\setlist[optdesc]{% + font = \mdseries\small\ttfamily, + align = right, + listparindent = \parindent, + labelsep = \marginparsep, + labelindent = -\marginparsep, + leftmargin = *} +\renewlist{tablenotes}{description}{1} +\setlist[tablenotes]{% + format = \normalfont\itshape\tnote@item, + labelwidth = 0.5em, + itemindent = 0pt, + rightmargin = \tabcolsep, + leftmargin = \the\dimexpr\tabcolsep+1em\relax, + after = \@noparlisttrue} +\AtBeginEnvironment{tablenotes}{% + \setlength\parindent{2\ccwd}% + \normalfont\footnotesize} +\AtBeginEnvironment{threeparttable}{% + \stepcounter{tpt@id}% + \edef\curr@tpt@id{tpt@\arabic{tpt@id}}} +\newcounter{tpt@id} +\def\tnote@item#1{% + \Hy@raisedlink{\hyper@anchor{\curr@tpt@id-#1}}#1} +\def\TPTtagStyle#1{\textit{\hyperlink{\curr@tpt@id-#1}{#1}}} +\def\UrlAlphabet{% + \do\a\do\b\do\c\do\d\do\e\do\f\do\g\do\h\do\i\do\j% + \do\k\do\l\do\m\do\n\do\o\do\p\do\q\do\r\do\s\do\t% + \do\u\do\v\do\w\do\x\do\y\do\z\do\A\do\B\do\C\do\D% + \do\E\do\F\do\G\do\H\do\I\do\J\do\K\do\L\do\M\do\N% + \do\O\do\P\do\Q\do\R\do\S\do\T\do\U\do\V\do\W\do\X% + \do\Y\do\Z} +\def\UrlDigits{% + \do\1\do\2\do\3\do\4\do\5\do\6\do\7\do\8\do\9\do\0} +\g@addto@macro\UrlBreaks{\UrlOrds} +\g@addto@macro\UrlBreaks{\UrlAlphabet} +\g@addto@macro\UrlBreaks{\UrlDigits} +\DoNotIndex{\begin,\end, + \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, + \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, + \0,\1,\2,\3,\4,\5,\6,\7,\8,\9} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\newcommand*\exptarget{\Hy@raisedlink{\hypertarget{expstar}{}}} +\newcommand*\rexptarget{\Hy@raisedlink{\hypertarget{rexpstar}{}}} +\newcommand*\expstar{\hyperlink{expstar}{$^^^^263b$}} +\newcommand*\rexpstar{\hyperlink{rexpstar}{$^^^^263a$}} +\ExplSyntaxOn +\cs_set_eq:NN \__codedoc_typeset_exp: \expstar +\cs_set_eq:NN \__codedoc_typeset_rexp: \rexpstar +\ExplSyntaxOff +\renewcommand*\marg[1]{\{\meta{#1}\}} +\renewcommand*\oarg[1]{[\meta{#1}]} +\renewcommand*\parg[1]{(\meta{#1})} +\DeclareDocumentCommand\opt{m}{\texttt{#1}} +\DeclareDocumentCommand\kvopt{mm} + {\texttt{#1\breakablethinspace=\breakablethinspace#2}} +\def\breakablethinspace{\hskip 0.16667em\relax} +\def\syntaxopt#1{\textit{#1}} +\def\defaultval#1{\textbf{\textup{#1}}} +\def\syntaxopt@aux#1>{\syntaxopt{#1}} +\def\defaultval@aux#1){\defaultval{#1}} +\def\orbar{\textup{\textbar}} +\def\TF{true\orbar false} +\def\TTF{\defaultval{true}\orbar false} +\def\TFF{true\orbar\defaultval{false}} +\DeclareDocumentEnvironment{arguments}{} + {\enumerate[% + label={\texttt{\#\arabic*:~}}, labelsep=0pt, nolistsep]}% + {\endenumerate} +\def\TeX{\hologo{TeX}} +\def\LaTeX{\hologo{LaTeX}} +\def\LaTeXe{\hologo{LaTeXe}} +\def\pdfTeX{\hologo{pdfTeX}} +\def\pdfLaTeX{\hologo{pdfLaTeX}} +\def\XeTeX{\hologo{XeTeX}} +\def\XeLaTeX{\hologo{XeLaTeX}} +\def\LuaTeX{\hologo{LuaTeX}} +\def\LuaLaTeX{\hologo{LuaLaTeX}} +\def\AmSLaTeX{\hologo{AmSLaTeX}} +\def\TeXLive{\TeX\ Live} +\def\MiKTeX{\hologo{MiKTeX}} +\def\BibTeX{\hologo{BibTeX}} +\def\BibTeX{\hologo{BibTeX}} +\def\biber{\hologo{biber}} +\def\TikZ{Ti\emph{k}Z} +\renewcommand*\env[1]{\textbf{\texttt{#1}}} +\newcommand*\bashcmd[1]{\texttt{#1}} +\lst@CCPutMacro\lst@ProcessOther {"2D}{\lst@ttfamily{-{}}{-{}}} +\@empty\z@\@empty +\lstdefinestyle{style@base} + { + basewidth = 0.5 em, + gobble = 2, + lineskip = 2 pt, + frame = l, + framerule = 1 pt, + framesep = 3 pt, + escapeinside = {(*}{*)}, + basicstyle = \small\ttfamily\color{MaterialGrey900}, + keywordstyle = \bfseries\color{MaterialIndigo}, + commentstyle = \itshape\color{MaterialGrey600}, + stringstyle = \color{MaterialRed}, + backgroundcolor = \color{MaterialGrey50} + } +\lstdefinestyle{style@shell} + { + style = style@base, + rulecolor = \color{MaterialPink}, + language = bash, + alsoletter = {-}, + emphstyle = \color{MaterialGreen800} + } +\lstdefinestyle{style@latex} + { + style = style@base, + rulecolor = \color{MaterialIndigo}, + language = [LaTeX]TeX, + alsoletter = {*, -}, + texcsstyle = *\color{MaterialDeepOrange}, + emphstyle = [1]\color{MaterialGreen800}, + emphstyle = [2]\color{MaterialTeal} + } +\lstdefinestyle{style@syntax} + { + basewidth = 0.5 em, + gobble = 4, + escapeinside = {(*}{*)}, + language = [LaTeX]TeX, + alsoletter = {*, -}, + basicstyle = \footnotesize\ttfamily\color{MaterialGrey900}, + keywordstyle = \bfseries\color{MaterialIndigo}, + commentstyle = \itshape\color{MaterialGrey600}, + texcsstyle = *\color{MaterialDeepOrange}, + emphstyle = [1]\color{MaterialGreen800}, + emphstyle = [2]\color{MaterialTeal} + } +\lstnewenvironment{shellcode}[1][]{% + \lstset{style=style@shell, #1}}{} +\lstnewenvironment{latexcode}[1][]{% + \lstset{style=style@latex, breaklines = true, #1}}{} +\lstnewenvironment{ccnusyntax}[1][]{% + \lstset{style=style@syntax, #1}\vspace{-1.8ex}}{} +\lstdefinelanguage{mylatex}{ + language={[LaTeX]TeX}, + texcsstyle =*\color{azure4}\bfseries, + keywordstyle=\color{green5}\bfseries, + morekeywords={document}, + autogobble = true, + morecomment = [l][\color{gray6}\itshape]{\%}, +} + +\newtcblisting{latexexample}[2][]{% + % breakable, + skin = bicolor, + colbacklower = white, + fonttitle = \ttfamily, + boxrule = 1pt, + toprule = 1pt, % top rule weight + bottomrule = 1pt, % bottom rule weight + left = 2mm, + parbox = false, + before upper = \indent, + title = {#2}, + #1, + listing options = { + language = mylatex, + % style = tcblatex, + numbers = left, + % numberfirstline=true, + stepnumber=1, + numbersep =0pt, + numberstyle=\tiny\color{red!75!black}, + basicstyle = \small\ttfamily, + breaklines, + % breakatwhitespace, + prebreak = {\mbox{$ \rhookswarrow $}}, + postbreak = {\mbox{$ \lhookrightarrow $\quad}}, + breakindent = 10pt, + autogobble = true, + } +} + + + +% make line numbers unable to be selected +% ref: https://liam.page/2013/11/04/LaTeX-listings-copy/ +\ExplSyntaxOn +\newcommand\emptyaccsupp[1]{ + \BeginAccSupp{ActualText={}} #1 \EndAccSupp{} +} + +\renewcommand\theFancyVerbLine{ + \emptyaccsupp{ + \textcolor[rgb]{0.5, 0.5, 1.0}{ + \scriptsize\arabic{FancyVerbLine} + } + } +} +\ExplSyntaxOff + + +% option "minted options app" has been added to tcolorbox, +% "hooks" library since v4.21, see +% https://github.com/T-F-S/tcolorbox/issues/73 +% \makeatletter +% \tcbset{ +% % see tcbminted.code.tex, def of "minted options" +% % minted options/.store in=\kvtcb@minted@options, +% minted options app/.code=\appto\kvtcb@minted@options{,#1} +% } +% \makeatother + +% define new option +\fvset{gobble=0} +\tcbset{ + example options/.style={ + skin=bicolor, + colbacklower=white, + fonttitle=\sffamily, + % minted options app={ + % % line numbers + % linenos, + % numberfirstline=true, + % stepnumber=1, + % numbersep=5pt, + % % break point + % breakbefore=\\, + % } + }, + example title/.style 2 args={ + title=Example\ifblank{#1}{}{ #1}\ifblank{#2}{}{: #2} + } +} + + +% % new env: example +% % #1 - <kv list>, tcb-listing options +% % #2 - <token list>, title +% \NewTCBListing[auto counter]{latexexample}{ O{} m }{ +% example options, +% example title={\thetcbcounter}{#2}, +% #1 +% } + +% % new env: example* +% % like example, except that it is un-numbered +% \NewTCBListing{latexexample*}{ O{} m }{ +% example options, +% example title={}{#2}, +% #1 +% } +% %% diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-multiple.pdf b/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-multiple.pdf Binary files differnew file mode 100644 index 00000000000..c60c53e81ee --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-multiple.pdf diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-multiple.tex b/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-multiple.tex new file mode 100644 index 00000000000..7f8b6950268 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-multiple.tex @@ -0,0 +1,671 @@ +% !TeX encoding = UTF-8 +% !TeX program = xelatex +% !TeX spellcheck = en_US + + +\documentclass{exam-zh} +\usepackage{siunitx} + +\examsetup{ + page = { + size = a3paper, + show-columnline = false + }, + style/fullwidth-stop = catcode, + fillin/no-answer-type = none, + sealline = { + show = true, + scope = mod-2, + circle-show = false, + line-type = solid, + odd-info-content = { + {\heiti \zihao{4}姓名} {\underline{\hspace*{8em}}}, + {\heiti \zihao{4}准考证号} {\examsquare{9}}, + {\heiti \zihao{4}考场号} {\examsquare{2}}, + {\heiti \zihao{4}座位号} {\examsquare{2}}, + }, + odd-info-xshift = 12mm, + text = {此卷只装订不密封}, + text-width = 0.98\textheight, + text-format = \zihao{-3}\sffamily, + text-xshift = 20mm + }, + square = { + x-length = 1.8em, + y-length = 1.6em + } +} + + +% 行内公式统一按照行间的样式 +\everymath{\displaystyle} + +\title{2021 年普通高等学校招生全国统一考试} + +\subject{数学(理科)} + + +\begin{document} + +\tableofcontents + +\chapter{2021 年普通高等学校招生全国统一考试} + +% \information{ +% 姓名\underline{\hspace{6em}}, +% 座位号\underline{\hspace{15em}} +% } +% \warning{(在此卷上答题无效)} + +\secret + +\maketitle + +本试卷共 4 页,22 题。全卷满分 150 分。考试用时 120 分钟。 + +\goodluck + +\begin{notice} + \item 答题前,先将自己的姓名、准考证号、考场号、座位号填写在试卷和答题卡上, + 并将准考证号条形码粘贴在答题卡上的指定位置。 + \item 选择题的作答:每小题选出答案后,用 2B 铅笔把答题卡上对应题目的答案标号涂黑。 + 写在试卷、草稿纸和答题卡上的非答题区域均无效。 + \item 填空题和解答题的作答:用黑色签字笔直接答在答题卡上对应的答题区域内。 + 写在试卷、草稿纸和答题卡上的非答题区域均无效。 + \item 考试结束后,请将本试卷和答题卡一并上交。 +\end{notice} + + + +\section{% + 选择题:本题共 8 小题,每小题 5 分,共 40 分。 + 在每小题给出的四个选项中,只有一项是符合题目要求的。 +} + +% 1. +\begin{question}[points = 2] + 设集合 $A = \{x \mid -1 < x < 4\}$,$B = \{2, 3, 4, 5\}$,则 $A \cap B = $ \paren[B] + + \begin{choices} + \item $\{2\}$ + \item $\{2, 3\}$ + \item $\{3, 4\}$ + \item $\{2, 3, 4\}$ + \end{choices} +\end{question} + +% 2. +\begin{question} + 已知 $z = 2 - \iu$,则 $z (\bar{z} + \iu) = $ \paren + \begin{choices} + \item $6 - 2\iu$ + \item $2 - 2\iu$ + \item $6 + 2\iu$ + \item $4 + 2\iu$ + \end{choices} +\end{question} + +% 3. +\begin{question} + 已知圆锥的底面半径为 $\sqrt{2}$,其侧面展开图为一个半圆,则该圆锥的母线长为 \paren + \begin{choices} + \item $2$ + \item $2 \sqrt{2}$ + \item $4$ + \item $4 \sqrt{2}$ + \end{choices} +\end{question} + +% 4. +\begin{question} + 下列区间中,函数 $f(x) = 7 \sin \left( x - \frac{\uppi}{6} \right)$ 的单调递增区间是 \paren + \begin{choices} + \item $\left( 0 , \frac{\uppi}{2} \right)$ + \item $\left( \frac{\uppi}{2} , \uppi \right)$ + \item $\left( \uppi , \frac{3\uppi}{2} \right)$ + \item $\left( \frac{3\uppi}{2}, 2\uppi \right)$ + \end{choices} +\end{question} + +% 5. +\begin{question} + 已知 $F_1$,$F_2$ 是椭圆 $C \colon \frac{x^2}{9} + \frac{y^2}{4} = 1$ 的两个焦点, + 点 $M$ 在 $C$ 上,则 $|M F_1| \cdot |M F_2|$ 的最大值为 \paren + \begin{choices} + \item $13$ + \item $12$ + \item $9$ + \item $6$ + \end{choices} +\end{question} + +% 6. +\begin{question} + 若 $\tan\theta = -2$,则 $\frac{\sin\theta (1 + \sin 2\theta)}{\sin\theta + \cos\theta} = $ \paren + \begin{choices} + \item $-\frac{6}{5}$ + \item $-\frac{2}{5}$ + \item $\frac{2}{5}$ + \item $\frac{6}{5}$ + \end{choices} +\end{question} + +% 7. +\begin{question} + 若过点 $(a, b)$ 可作曲线 $y = \eu^x$ 的两条切线,则 \paren + \begin{choices} + \item $\eu^b < a$ + \item $\eu^a < b$ + \item $0 < a < \eu^b$ + \item $0 < b < \eu^a$ + \end{choices} +\end{question} + +% 8. +\begin{question} + 有 $6$ 个相同的球,分别标有数字 $1$,$2$,$3$,$4$,$5$,$6$,从中有放回地随机取两次,每次取 $1$ 个球, + 甲表示事件“第一次去出的球的数字是 $1$”, + 乙表示事件“第二次取出的球的数字是 $2$”, + 丙表示事件“两次取出的球的数字之和是 $8$”, + 丁表示事件“两次取出的球的数字之和是 $7$”,则 \paren + \begin{choices} + \item 甲与丙相互独立 + \item 甲与丁相互独立 + \item 乙与丙相互独立 + \item 丙与丁相互独立 + \end{choices} +\end{question} + + + +\section{% + 选择题:本题共 4 小题,每小题 5 分,共 20 分。 + 在每小题给出的选项中,有多项符合题目要求的。 + 全部选对的得 5 分,部分选择的得 2 分,有选错的得 0 分。 +} + +% 9. +\begin{question} + 有一组样本数据 $x_1, x_2, \dots, x_n$,由 这组数据的到新样本数据 $y_1, y_2, \dots, y_n$, + 其中 $y_i = x_i + c$($i = 1, 2, \dots, n$) 为非零常数,则 \paren + \begin{choices} + \item 两组样本数据的样本平均数相同 + \item 两组样本数据的样本中位数相同 + \item 两组样本数据的样本标准差相同 + \item 两组样本数据的样本极差相同 + \end{choices} +\end{question} + +% 10. +\begin{question} + 已知 $O$ 为坐标原点,点 + $P_1(\cos\alpha, \sin\alpha)$, + $P_2(\cos\beta , -\sin\alpha)$, + $P_3(\cos(\alpha + \beta), \sin(\alpha + \beta))$, + $A(1, 0)$ \paren + \begin{choices} + \item $|\overrightarrow{OP_1}| = |\overrightarrow{OP_2}|$ + \item $|\overrightarrow{AP_1}| = |\overrightarrow{AP_2}|$ + \item $\overrightarrow{OA} \cdot \overrightarrow{OP_3} + = \overrightarrow{OP_1} \cdot \overrightarrow{OP_2}$ + \item $\overrightarrow{OA} \cdot \overrightarrow{OP_1} + = \overrightarrow{OP_2} \cdot \overrightarrow{OP_3}$ + \end{choices} +\end{question} + +% 11. +\begin{question} + 已知点 $P$ 在圆 $(x - 5)^2 + (y - 5)^2 = 16$ 上,点 $A(4, 0)$,$B(0, 2)$,则 \paren + \begin{choices} + \item 点 $P$ 到直线 $AB$ 的距离小于 $10$ + \item 点 $P$ 到直线 $AB$ 的距离大于 $2$ + \item 点 $\angle PBA$ 最小时,$|PB| = 3 \sqrt{2}$ + \item 点 $\angle PBA$ 最大时,$|PB| = 3 \sqrt{2}$ + \end{choices} +\end{question} + +% 12. +\begin{question} + 在正三棱柱 $ABC$-$A_1 B_1 C_1$ 中,$AB = A A_1 = 1$,点 $P$ 满足 + $\overrightarrow{BP} = \lambda \overrightarrow{BC} + \mu \overrightarrow{BB_1}$, + 其中 $\lambda \in [0, 1]$,$\mu \in [0, 1]$,则 \paren + \begin{choices} + \item 当 $\lambda = 1$ 时,$\triangle A B_1 P$ 的周长为定值 + \item 当 $\mu = 1$ 时,三棱锥 $P$-$A_1 B C$ 的体积为定值 + \item 当 $\lambda = \frac{1}{2}$ 时,有且仅有一个点 $P$,使得 $A_1 P \perp BP$ + \item 当 $\mu = \frac{1}{2}$ 时,有且仅有一个点 $P$,使得 $A_1 B \perp \text{平面} A B_1 P$ + \end{choices} +\end{question} + + + +\section{填空题:本题共 4 小题,每小题 5 分,共 20 分。} + +% 13. +\begin{question} + 已知函数 $f(x) = x^3 (a \cdot 2^x - 2^{-x})$ 是偶函数,则 $a = $ \fillin[$1$] 。 +\end{question} + +% 14. +\begin{question} + 已知 $O$ 为坐标原点,抛物线 $C \colon y^2 = 2px$($p > 0$)的焦点为 $F$, + $P$ 为 $C$ 上一点,$PF$ 与 $x$ 轴垂直,$Q$ 为 $x$ 轴上一点,且 $PQ \perp OP$, + 若 $|FQ| = 6$,则 $C$ 的准线方程为 \fillin[$\dfrac{1}{3}$] 。 +\end{question} + +% 15. +\begin{question} + 函数 $f(x) = |2x - 1| - 2 \ln x$ 的最小值为 \fillin[width = 4em][] 。 +\end{question} + +% 16. +\begin{question} + 某校学生在研究民间剪纸艺术时,发现剪纸时经常会沿纸的某条对称轴把纸对折。 + 规格为 \qtyproduct{20 x 12}{dm} 的长方形纸,对折 $1$ 次共可以得到 + \qtyproduct{10 x 12}{dm}, \qtyproduct{20 x 6}{dm} 两种规格的图形, + 它们的面积之和 $S_1 = \qty{240}{dm^2}$, + 对折 $2$ 次共可以得到 \qtyproduct{5 x 12}{dm},\qtyproduct{10 x 6}{dm}, + \qtyproduct{20 x 3}{dm} 三种规格的图形,它们的面积之和 $S_2 = \qty{240}{dm^2}$, + 以此类推。则对折 $4$ 次共可以得到不同规格图形的种数为 \fillin ; + 如果对折 $n$ 次,那么 $\sum_{k=1}^n S_k = $ \fillin \unit{dm^2}。 +\end{question} + + + +\section{解答题:本题共 6 小题,共 70 分。解答应写出文字说明、证明过程或者演算步骤。} + +% 17. +\begin{problem}[points = 10] + 已知数列 $\{a_n\}$ 满足 $a_1 = 1$,$a_{n+1} = + \begin{cases} + a_n + 1, \quad \text{$n$ 为奇数,} \\ + a_n + 2, \quad \text{$n$ 为偶数。} + \end{cases}$ + \begin{enumerate} + \item 记 $b_n = a_{2n}$,写出 $b_1$,$b_2$,并求数列 $\{b_n\}$ 的通项公式; + \item 求 $\{a_n\}$ 的前 $20$ 项和。 + \end{enumerate} +\end{problem} + +% 18. +\begin{problem}[points = 12] + 某学校组织“一带一路”知识竞赛,有 A,B 两类问题。 + 每位参加比赛的同学现在两类问题中选择一类并从中随机抽取一个问题回答, + 若回答错误则该同学比赛结束; + 若回答正确则从另一类问题中再随机抽取一个问题回答,无论回答正确与否,该同学比赛结束。 + A 类问题中的每个问题回答正确的 $20$ 分,否则得 $0$ 分; + B 类问题中的每个问题回答正确的 $80$ 分,否则得 $0$ 分。 + + 已知小明能正确回答 A 类问题的概率为 $0.8$,能正确回答 B 类问题的概率为 $0.6$, + 且能正确回答问题的概率与回答次序无关。 + \begin{enumerate} + \item 若小明先回答 A 类问题,记 $X$ 为小明的累计得分,求 $X$ 的分布列; + \item 为使累计得分的期望最大,小明应选择先回答哪类问题?并说明理由。 + \end{enumerate} +\end{problem} + +% 19. +\begin{problem}[points = 12] + 记 $\triangle ABC$ 的内角 $A$,$B$,$C$ 的对边分别为 $a$,$b$,$c$。 + 已知 $b^2 = ac$,点 $D$ 在边 $AC$ 上,$BD \sin\angle ABC = a \sin C$。 + \nopagebreak + \begin{enumerate} + \item 证明:$BD = b$; + \item 若 $AD = 2 DC$,求 $\cos\angle ABC$。 + \end{enumerate} +\end{problem} + +% 20. +\begin{problem}[points = 12] + 如图,在三棱锥 $A$-$BCD$ 中,$\text{平面} ABD \perp \text{平面} BCD$, + $AB = AD$,$O$ 为 $BD$ 的重点。 + \begin{enumerate} + \item 证明:$OA \perp CD$; + \item 若 $\triangle OCD$ 是变长为 $1$ 的等边三角形,点 $E$ 在棱 $AD$ 上, + $DE = 2 EA$,且二面角 $E$-$BC$-$D$ 的大小为 \ang{45}, + 求三棱锥 $A$-$BCD$ 的体积。 + \end{enumerate} +\end{problem} + +% 21. +\begin{problem}[points = 12] + 在平面直角坐标系 $xOy$ 中,已知点 $F_1 (-\sqrt{17}, 0)$,$F_2 (\sqrt{17}, 0)$, + 点 $M$ 满足 $|M F_1| - |M F_2| = 2$。记 $M$ 的轨迹为 $C$。 + \begin{enumerate} + \item 求 $C$ 的方程; + \item 设点 $T$ 在直线 $x = \frac{1}{2}$ 上,过 $T$ 的两条直线分别交 $C$ 于 $A$, + $B$ 亮点和 $P$,$Q$ 亮点,且 $|TA| \cdot |TB| = |TP| \cdot |TQ|$, + 求直线 $AB$ 的斜率与直线 $PQ$ 的斜率之和。 + \end{enumerate} +\end{problem} + +% 22. +\begin{problem}[points = 12] + 已知函数 $f(x) = x (1 - \ln x)$。 + \begin{enumerate} + \item 讨论 $f(x)$ 的单调性; + \item 设 $a$,$b$ 为两个不相等的正数,且 $b \ln a - a \ln b = a - b$, + 证明:$2 < \frac{1}{a} + \frac{1}{b} < \eu$。 + \end{enumerate} +\end{problem} + +\begin{solution} + 函数的定义域为 $(0, +\infty)$, + 又 \[f^{\prime}(x) = 1 - \ln x-1 = -\ln x, \score{2}\] + 当 $x \in(0, 1)$ 时, $f^{\prime}(x) > 0$, 当 $x \in(1, +\infty)$ 时, $f^{\prime}(x) < 0$, + 故 $f(x)$ 的递增区间为 $(0,1)$, 递减区间为 $(1, +\infty)$. +\end{solution} + + + +\chapter{2023 年普通高等学校招生全国统一考试} + +% \information{ +% 姓名\underline{\hspace{6em}}, +% 座位号\underline{\hspace{15em}} +% } +% \warning{(在此卷上答题无效)} + +\secret + +\title{2023 年普通高等学校招生全国统一考试} + +\subject{数学(理科)} + +\maketitle + +本试卷共 4 页,22 题。全卷满分 150 分。考试用时 120 分钟。 + +\goodluck + +\begin{notice} + \item 答题前,先将自己的姓名、准考证号、考场号、座位号填写在试卷和答题卡上, + 并将准考证号条形码粘贴在答题卡上的指定位置。 + \item 选择题的作答:每小题选出答案后,用 2B 铅笔把答题卡上对应题目的答案标号涂黑。 + 写在试卷、草稿纸和答题卡上的非答题区域均无效。 + \item 填空题和解答题的作答:用黑色签字笔直接答在答题卡上对应的答题区域内。 + 写在试卷、草稿纸和答题卡上的非答题区域均无效。 + \item 考试结束后,请将本试卷和答题卡一并上交。 +\end{notice} + + + +\section{% + 选择题:本题共 8 小题,每小题 5 分,共 40 分。 + 在每小题给出的四个选项中,只有一项是符合题目要求的。 +} + +% 1. +\begin{question}[points = 2] + 设集合 $A = \{x \mid -1 < x < 4\}$,$B = \{2, 3, 4, 5\}$,则 $A \cap B = $ \paren[B] + + \begin{choices} + \item $\{2\}$ + \item $\{2, 3\}$ + \item $\{3, 4\}$ + \item $\{2, 3, 4\}$ + \end{choices} +\end{question} + +% 2. +\begin{question} + 已知 $z = 2 - \iu$,则 $z (\bar{z} + \iu) = $ \paren + \begin{choices} + \item $6 - 2\iu$ + \item $2 - 2\iu$ + \item $6 + 2\iu$ + \item $4 + 2\iu$ + \end{choices} +\end{question} + +% 3. +\begin{question} + 已知圆锥的底面半径为 $\sqrt{2}$,其侧面展开图为一个半圆,则该圆锥的母线长为 \paren + \begin{choices} + \item $2$ + \item $2 \sqrt{2}$ + \item $4$ + \item $4 \sqrt{2}$ + \end{choices} +\end{question} + +% 4. +\begin{question} + 下列区间中,函数 $f(x) = 7 \sin \left( x - \frac{\uppi}{6} \right)$ 的单调递增区间是 \paren + \begin{choices} + \item $\left( 0 , \frac{\uppi}{2} \right)$ + \item $\left( \frac{\uppi}{2} , \uppi \right)$ + \item $\left( \uppi , \frac{3\uppi}{2} \right)$ + \item $\left( \frac{3\uppi}{2}, 2\uppi \right)$ + \end{choices} +\end{question} + +% 5. +\begin{question} + 已知 $F_1$,$F_2$ 是椭圆 $C \colon \frac{x^2}{9} + \frac{y^2}{4} = 1$ 的两个焦点, + 点 $M$ 在 $C$ 上,则 $|M F_1| \cdot |M F_2|$ 的最大值为 \paren + \begin{choices} + \item $13$ + \item $12$ + \item $9$ + \item $6$ + \end{choices} +\end{question} + +% 6. +\begin{question} + 若 $\tan\theta = -2$,则 $\frac{\sin\theta (1 + \sin 2\theta)}{\sin\theta + \cos\theta} = $ \paren + \begin{choices} + \item $-\frac{6}{5}$ + \item $-\frac{2}{5}$ + \item $\frac{2}{5}$ + \item $\frac{6}{5}$ + \end{choices} +\end{question} + +% 7. +\begin{question} + 若过点 $(a, b)$ 可作曲线 $y = \eu^x$ 的两条切线,则 \paren + \begin{choices} + \item $\eu^b < a$ + \item $\eu^a < b$ + \item $0 < a < \eu^b$ + \item $0 < b < \eu^a$ + \end{choices} +\end{question} + +% 8. +\begin{question} + 有 $6$ 个相同的球,分别标有数字 $1$,$2$,$3$,$4$,$5$,$6$,从中有放回地随机取两次,每次取 $1$ 个球, + 甲表示事件“第一次去出的球的数字是 $1$”, + 乙表示事件“第二次取出的球的数字是 $2$”, + 丙表示事件“两次取出的球的数字之和是 $8$”, + 丁表示事件“两次取出的球的数字之和是 $7$”,则 \paren + \begin{choices} + \item 甲与丙相互独立 + \item 甲与丁相互独立 + \item 乙与丙相互独立 + \item 丙与丁相互独立 + \end{choices} +\end{question} + + + +\section{% + 选择题:本题共 4 小题,每小题 5 分,共 20 分。 + 在每小题给出的选项中,有多项符合题目要求的。 + 全部选对的得 5 分,部分选择的得 2 分,有选错的得 0 分。 +} + +% 9. +\begin{question} + 有一组样本数据 $x_1, x_2, \dots, x_n$,由 这组数据的到新样本数据 $y_1, y_2, \dots, y_n$, + 其中 $y_i = x_i + c$($i = 1, 2, \dots, n$) 为非零常数,则 \paren + \begin{choices} + \item 两组样本数据的样本平均数相同 + \item 两组样本数据的样本中位数相同 + \item 两组样本数据的样本标准差相同 + \item 两组样本数据的样本极差相同 + \end{choices} +\end{question} + +% 10. +\begin{question} + 已知 $O$ 为坐标原点,点 + $P_1(\cos\alpha, \sin\alpha)$, + $P_2(\cos\beta , -\sin\alpha)$, + $P_3(\cos(\alpha + \beta), \sin(\alpha + \beta))$, + $A(1, 0)$ \paren + \begin{choices} + \item $|\overrightarrow{OP_1}| = |\overrightarrow{OP_2}|$ + \item $|\overrightarrow{AP_1}| = |\overrightarrow{AP_2}|$ + \item $\overrightarrow{OA} \cdot \overrightarrow{OP_3} + = \overrightarrow{OP_1} \cdot \overrightarrow{OP_2}$ + \item $\overrightarrow{OA} \cdot \overrightarrow{OP_1} + = \overrightarrow{OP_2} \cdot \overrightarrow{OP_3}$ + \end{choices} +\end{question} + +% 11. +\begin{question} + 已知点 $P$ 在圆 $(x - 5)^2 + (y - 5)^2 = 16$ 上,点 $A(4, 0)$,$B(0, 2)$,则 \paren + \begin{choices} + \item 点 $P$ 到直线 $AB$ 的距离小于 $10$ + \item 点 $P$ 到直线 $AB$ 的距离大于 $2$ + \item 点 $\angle PBA$ 最小时,$|PB| = 3 \sqrt{2}$ + \item 点 $\angle PBA$ 最大时,$|PB| = 3 \sqrt{2}$ + \end{choices} +\end{question} + +% 12. +\begin{question} + 在正三棱柱 $ABC$-$A_1 B_1 C_1$ 中,$AB = A A_1 = 1$,点 $P$ 满足 + $\overrightarrow{BP} = \lambda \overrightarrow{BC} + \mu \overrightarrow{BB_1}$, + 其中 $\lambda \in [0, 1]$,$\mu \in [0, 1]$,则 \paren + \begin{choices} + \item 当 $\lambda = 1$ 时,$\triangle A B_1 P$ 的周长为定值 + \item 当 $\mu = 1$ 时,三棱锥 $P$-$A_1 B C$ 的体积为定值 + \item 当 $\lambda = \frac{1}{2}$ 时,有且仅有一个点 $P$,使得 $A_1 P \perp BP$ + \item 当 $\mu = \frac{1}{2}$ 时,有且仅有一个点 $P$,使得 $A_1 B \perp \text{平面} A B_1 P$ + \end{choices} +\end{question} + + + +\section{填空题:本题共 4 小题,每小题 5 分,共 20 分。} + +% 13. +\begin{question} + 已知函数 $f(x) = x^3 (a \cdot 2^x - 2^{-x})$ 是偶函数,则 $a = $ \fillin[$1$] 。 +\end{question} + +% 14. +\begin{question} + 已知 $O$ 为坐标原点,抛物线 $C \colon y^2 = 2px$($p > 0$)的焦点为 $F$, + $P$ 为 $C$ 上一点,$PF$ 与 $x$ 轴垂直,$Q$ 为 $x$ 轴上一点,且 $PQ \perp OP$, + 若 $|FQ| = 6$,则 $C$ 的准线方程为 \fillin[$\dfrac{1}{3}$] 。 +\end{question} + +% 15. +\begin{question} + 函数 $f(x) = |2x - 1| - 2 \ln x$ 的最小值为 \fillin[width = 4em][] 。 +\end{question} + +% 16. +\begin{question} + 某校学生在研究民间剪纸艺术时,发现剪纸时经常会沿纸的某条对称轴把纸对折。 + 规格为 \qtyproduct{20 x 12}{dm} 的长方形纸,对折 $1$ 次共可以得到 + \qtyproduct{10 x 12}{dm}, \qtyproduct{20 x 6}{dm} 两种规格的图形, + 它们的面积之和 $S_1 = \qty{240}{dm^2}$, + 对折 $2$ 次共可以得到 \qtyproduct{5 x 12}{dm},\qtyproduct{10 x 6}{dm}, + \qtyproduct{20 x 3}{dm} 三种规格的图形,它们的面积之和 $S_2 = \qty{240}{dm^2}$, + 以此类推。则对折 $4$ 次共可以得到不同规格图形的种数为 \fillin ; + 如果对折 $n$ 次,那么 $\sum_{k=1}^n S_k = $ \fillin \unit{dm^2}。 +\end{question} + + + +\section{解答题:本题共 6 小题,共 70 分。解答应写出文字说明、证明过程或者演算步骤。} + +% 17. +\begin{problem}[points = 10] + 已知数列 $\{a_n\}$ 满足 $a_1 = 1$,$a_{n+1} = + \begin{cases} + a_n + 1, \quad \text{$n$ 为奇数,} \\ + a_n + 2, \quad \text{$n$ 为偶数。} + \end{cases}$ + \begin{enumerate} + \item 记 $b_n = a_{2n}$,写出 $b_1$,$b_2$,并求数列 $\{b_n\}$ 的通项公式; + \item 求 $\{a_n\}$ 的前 $20$ 项和。 + \end{enumerate} +\end{problem} + +% 18. +\begin{problem}[points = 12] + 某学校组织“一带一路”知识竞赛,有 A,B 两类问题。 + 每位参加比赛的同学现在两类问题中选择一类并从中随机抽取一个问题回答, + 若回答错误则该同学比赛结束; + 若回答正确则从另一类问题中再随机抽取一个问题回答,无论回答正确与否,该同学比赛结束。 + A 类问题中的每个问题回答正确的 $20$ 分,否则得 $0$ 分; + B 类问题中的每个问题回答正确的 $80$ 分,否则得 $0$ 分。 + + 已知小明能正确回答 A 类问题的概率为 $0.8$,能正确回答 B 类问题的概率为 $0.6$, + 且能正确回答问题的概率与回答次序无关。 + \begin{enumerate} + \item 若小明先回答 A 类问题,记 $X$ 为小明的累计得分,求 $X$ 的分布列; + \item 为使累计得分的期望最大,小明应选择先回答哪类问题?并说明理由。 + \end{enumerate} +\end{problem} + +% 19. +\begin{problem}[points = 12] + 记 $\triangle ABC$ 的内角 $A$,$B$,$C$ 的对边分别为 $a$,$b$,$c$。 + 已知 $b^2 = ac$,点 $D$ 在边 $AC$ 上,$BD \sin\angle ABC = a \sin C$。 + \nopagebreak + \begin{enumerate} + \item 证明:$BD = b$; + \item 若 $AD = 2 DC$,求 $\cos\angle ABC$。 + \end{enumerate} +\end{problem} + +% 20. +\begin{problem}[points = 12] + 如图,在三棱锥 $A$-$BCD$ 中,$\text{平面} ABD \perp \text{平面} BCD$, + $AB = AD$,$O$ 为 $BD$ 的重点。 + \begin{enumerate} + \item 证明:$OA \perp CD$; + \item 若 $\triangle OCD$ 是变长为 $1$ 的等边三角形,点 $E$ 在棱 $AD$ 上, + $DE = 2 EA$,且二面角 $E$-$BC$-$D$ 的大小为 \ang{45}, + 求三棱锥 $A$-$BCD$ 的体积。 + \end{enumerate} +\end{problem} + +% 21. +\begin{problem}[points = 12] + 在平面直角坐标系 $xOy$ 中,已知点 $F_1 (-\sqrt{17}, 0)$,$F_2 (\sqrt{17}, 0)$, + 点 $M$ 满足 $|M F_1| - |M F_2| = 2$。记 $M$ 的轨迹为 $C$。 + \begin{enumerate} + \item 求 $C$ 的方程; + \item 设点 $T$ 在直线 $x = \frac{1}{2}$ 上,过 $T$ 的两条直线分别交 $C$ 于 $A$, + $B$ 亮点和 $P$,$Q$ 亮点,且 $|TA| \cdot |TB| = |TP| \cdot |TQ|$, + 求直线 $AB$ 的斜率与直线 $PQ$ 的斜率之和。 + \end{enumerate} +\end{problem} + +% 22. +\begin{problem}[points = 12] + 已知函数 $f(x) = x (1 - \ln x)$。 + \begin{enumerate} + \item 讨论 $f(x)$ 的单调性; + \item 设 $a$,$b$ 为两个不相等的正数,且 $b \ln a - a \ln b = a - b$, + 证明:$2 < \frac{1}{a} + \frac{1}{b} < \eu$。 + \end{enumerate} +\end{problem} + +\begin{solution} + 函数的定义域为 $(0, +\infty)$, + 又 \[f^{\prime}(x) = 1 - \ln x-1 = -\ln x, \score{2}\] + 当 $x \in(0, 1)$ 时, $f^{\prime}(x) > 0$, 当 $x \in(1, +\infty)$ 时, $f^{\prime}(x) < 0$, + 故 $f(x)$ 的递增区间为 $(0,1)$, 递减区间为 $(1, +\infty)$. +\end{solution} +\end{document} diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-single.pdf b/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-single.pdf Binary files differnew file mode 100644 index 00000000000..e5ed1a8d332 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-single.pdf diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-single.tex b/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-single.tex new file mode 100644 index 00000000000..04206986cd4 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-single.tex @@ -0,0 +1,337 @@ +\documentclass{exam-zh} +\usepackage{siunitx} + +\examsetup{ + page/size=a4paper, + paren/show-paren=true, + paren/show-answer=true, + fillin/show-answer=true, + solution/show-solution=true, +} + +\ExamPrintAnswerSet{ + sealline/show=true, + page/size=a3paper, + paren/show-answer=false, + fillin/show-answer=false, + solution/show-solution=false, +} + + +\everymath{\displaystyle} + +\title{2021 年普通高等学校招生全国统一考试} + +\subject{数学(理科)} + + + +\begin{document} + +\information{ + 姓名\underline{\hspace{6em}}, + 座位号\underline{\hspace{15em}} +} +\warning{(在此卷上答题无效)} + +\secret + +\maketitle + +本试卷共 4 页,22 题。全卷满分 150 分。考试用时 120 分钟。 + +\goodluck + +\begin{notice} + \item 答题前,先将自己的姓名、准考证号、考场号、座位号填写在试卷和答题卡上, + 并将准考证号条形码粘贴在答题卡上的指定位置。 + \item 选择题的作答:每小题选出答案后,用 2B 铅笔把答题卡上对应题目的答案标号涂黑。 + 写在试卷、草稿纸和答题卡上的非答题区域均无效。 + \item 填空题和解答题的作答:用黑色签字笔直接答在答题卡上对应的答题区域内。 + 写在试卷、草稿纸和答题卡上的非答题区域均无效。 + \item 考试结束后,请将本试卷和答题卡一并上交。 +\end{notice} + + + +\section{% + 选择题:本题共 8 小题,每小题 5 分,共 40 分。 + 在每小题给出的四个选项中,只有一项是符合题目要求的。 +} + +% 1. +\begin{question}[points = 2] + 设集合 $A = \{x \mid -1 < x < 4\}$,$B = \{2, 3, 4, 5\}$,则 $A \cap B = $ \paren[B] + + \begin{choices} + \item $\{2\}$ + \item $\{2, 3\}$ + \item $\{3, 4\}$ + \item $\{2, 3, 4\}$ + \end{choices} +\end{question} + +% 2. +\begin{question} + 已知 $z = 2 - \iu$,则 $z (\bar{z} + \iu) = $ \paren + \begin{choices} + \item $6 - 2\iu$ + \item $2 - 2\iu$ + \item $6 + 2\iu$ + \item $4 + 2\iu$ + \end{choices} +\end{question} + +% 3. +\begin{question} + 已知圆锥的底面半径为 $\sqrt{2}$,其侧面展开图为一个半圆,则该圆锥的母线长为 \paren + \begin{choices} + \item $2$ + \item $2 \sqrt{2}$ + \item $4$ + \item $4 \sqrt{2}$ + \end{choices} +\end{question} + +% 4. +\begin{question} + 下列区间中,函数 $f(x) = 7 \sin \left( x - \frac{\uppi}{6} \right)$ 的单调递增区间是 \paren + \begin{choices} + \item $\left( 0 , \frac{\uppi}{2} \right)$ + \item $\left( \frac{\uppi}{2} , \uppi \right)$ + \item $\left( \uppi , \frac{3\uppi}{2} \right)$ + \item $\left( \frac{3\uppi}{2}, 2\uppi \right)$ + \end{choices} +\end{question} + +% 5. +\begin{question} + 已知 $F_1$,$F_2$ 是椭圆 $C \colon \frac{x^2}{9} + \frac{y^2}{4} = 1$ 的两个焦点, + 点 $M$ 在 $C$ 上,则 $|M F_1| \cdot |M F_2|$ 的最大值为 \paren + \begin{choices} + \item $13$ + \item $12$ + \item $9$ + \item $6$ + \end{choices} +\end{question} + +% 6. +\begin{question} + 若 $\tan\theta = -2$,则 $\frac{\sin\theta (1 + \sin 2\theta)}{\sin\theta + \cos\theta} = $ \paren + \begin{choices} + \item $-\frac{6}{5}$ + \item $-\frac{2}{5}$ + \item $\frac{2}{5}$ + \item $\frac{6}{5}$ + \end{choices} +\end{question} + +% 7. +\begin{question} + 若过点 $(a, b)$ 可作曲线 $y = \eu^x$ 的两条切线,则 \paren + \begin{choices} + \item $\eu^b < a$ + \item $\eu^a < b$ + \item $0 < a < \eu^b$ + \item $0 < b < \eu^a$ + \end{choices} +\end{question} + +% 8. +\begin{question} + 有 $6$ 个相同的球,分别标有数字 $1$,$2$,$3$,$4$,$5$,$6$,从中有放回地随机取两次,每次取 $1$ 个球, + 甲表示事件“第一次去出的球的数字是 $1$”, + 乙表示事件“第二次取出的球的数字是 $2$”, + 丙表示事件“两次取出的球的数字之和是 $8$”, + 丁表示事件“两次取出的球的数字之和是 $7$”,则 \paren + \begin{choices} + \item 甲与丙相互独立 + \item 甲与丁相互独立 + \item 乙与丙相互独立 + \item 丙与丁相互独立 + \end{choices} +\end{question} + + + +\section{% + 选择题:本题共 4 小题,每小题 5 分,共 20 分。 + 在每小题给出的选项中,有多项符合题目要求的。 + 全部选对的得 5 分,部分选择的得 2 分,有选错的得 0 分。 +} + +% 9. +\begin{question} + 有一组样本数据 $x_1, x_2, \dots, x_n$,由 这组数据的到新样本数据 $y_1, y_2, \dots, y_n$, + 其中 $y_i = x_i + c$($i = 1, 2, \dots, n$) 为非零常数,则 \paren + \begin{choices} + \item 两组样本数据的样本平均数相同 + \item 两组样本数据的样本中位数相同 + \item 两组样本数据的样本标准差相同 + \item 两组样本数据的样本极差相同 + \end{choices} +\end{question} + +% 10. +\begin{question} + 已知 $O$ 为坐标原点,点 + $P_1(\cos\alpha, \sin\alpha)$, + $P_2(\cos\beta , -\sin\alpha)$, + $P_3(\cos(\alpha + \beta), \sin(\alpha + \beta))$, + $A(1, 0)$ \paren + \begin{choices} + \item $|\overrightarrow{OP_1}| = |\overrightarrow{OP_2}|$ + \item $|\overrightarrow{AP_1}| = |\overrightarrow{AP_2}|$ + \item $\overrightarrow{OA} \cdot \overrightarrow{OP_3} + = \overrightarrow{OP_1} \cdot \overrightarrow{OP_2}$ + \item $\overrightarrow{OA} \cdot \overrightarrow{OP_1} + = \overrightarrow{OP_2} \cdot \overrightarrow{OP_3}$ + \end{choices} +\end{question} + +% 11. +\begin{question} + 已知点 $P$ 在圆 $(x - 5)^2 + (y - 5)^2 = 16$ 上,点 $A(4, 0)$,$B(0, 2)$,则 \paren + \begin{choices} + \item 点 $P$ 到直线 $AB$ 的距离小于 $10$ + \item 点 $P$ 到直线 $AB$ 的距离大于 $2$ + \item 点 $\angle PBA$ 最小时,$|PB| = 3 \sqrt{2}$ + \item 点 $\angle PBA$ 最大时,$|PB| = 3 \sqrt{2}$ + \end{choices} +\end{question} + +% 12. +\begin{question} + 在正三棱柱 $ABC$-$A_1 B_1 C_1$ 中,$AB = A A_1 = 1$,点 $P$ 满足 + $\overrightarrow{BP} = \lambda \overrightarrow{BC} + \mu \overrightarrow{BB_1}$, + 其中 $\lambda \in [0, 1]$,$\mu \in [0, 1]$,则 \paren + \begin{choices} + \item 当 $\lambda = 1$ 时,$\triangle A B_1 P$ 的周长为定值 + \item 当 $\mu = 1$ 时,三棱锥 $P$-$A_1 B C$ 的体积为定值 + \item 当 $\lambda = \frac{1}{2}$ 时,有且仅有一个点 $P$,使得 $A_1 P \perp BP$ + \item 当 $\mu = \frac{1}{2}$ 时,有且仅有一个点 $P$,使得 $A_1 B \perp \text{平面} A B_1 P$ + \end{choices} +\end{question} + + + +\section{填空题:本题共 4 小题,每小题 5 分,共 20 分。} + +% 13. +\begin{question} + 已知函数 $f(x) = x^3 (a \cdot 2^x - 2^{-x})$ 是偶函数,则 $a = $ \fillin[$1$] 。 +\end{question} + +% 14. +\begin{question} + 已知 $O$ 为坐标原点,抛物线 $C \colon y^2 = 2px$($p > 0$)的焦点为 $F$, + $P$ 为 $C$ 上一点,$PF$ 与 $x$ 轴垂直,$Q$ 为 $x$ 轴上一点,且 $PQ \perp OP$, + 若 $|FQ| = 6$,则 $C$ 的准线方程为 \fillin[$\dfrac{1}{3}$] 。 +\end{question} + +% 15. +\begin{question} + 函数 $f(x) = |2x - 1| - 2 \ln x$ 的最小值为 \fillin[width = 4em][] 。 +\end{question} + +% 16. +\begin{question} + 某校学生在研究民间剪纸艺术时,发现剪纸时经常会沿纸的某条对称轴把纸对折。 + 规格为 \qtyproduct{20 x 12}{dm} 的长方形纸,对折 $1$ 次共可以得到 + \qtyproduct{10 x 12}{dm}, \qtyproduct{20 x 6}{dm} 两种规格的图形, + 它们的面积之和 $S_1 = \qty{240}{dm^2}$, + 对折 $2$ 次共可以得到 \qtyproduct{5 x 12}{dm},\qtyproduct{10 x 6}{dm}, + \qtyproduct{20 x 3}{dm} 三种规格的图形,它们的面积之和 $S_2 = \qty{240}{dm^2}$, + 以此类推。则对折 $4$ 次共可以得到不同规格图形的种数为 \fillin ; + 如果对折 $n$ 次,那么 $\sum_{k=1}^n S_k = $ \fillin \unit{dm^2}。 +\end{question} + + + +\section{解答题:本题共 6 小题,共 70 分。解答应写出文字说明、证明过程或者演算步骤。} + +% 17. +\begin{problem}[points = 10] + 已知数列 $\{a_n\}$ 满足 $a_1 = 1$,$a_{n+1} = + \begin{cases} + a_n + 1, \quad \text{$n$ 为奇数,} \\ + a_n + 2, \quad \text{$n$ 为偶数。} + \end{cases}$ + \begin{enumerate} + \item 记 $b_n = a_{2n}$,写出 $b_1$,$b_2$,并求数列 $\{b_n\}$ 的通项公式; + \item 求 $\{a_n\}$ 的前 $20$ 项和。 + \end{enumerate} +\end{problem} + +% 18. +\begin{problem}[points = 12] + 某学校组织“一带一路”知识竞赛,有 A,B 两类问题。 + 每位参加比赛的同学现在两类问题中选择一类并从中随机抽取一个问题回答, + 若回答错误则该同学比赛结束; + 若回答正确则从另一类问题中再随机抽取一个问题回答,无论回答正确与否,该同学比赛结束。 + A 类问题中的每个问题回答正确的 $20$ 分,否则得 $0$ 分; + B 类问题中的每个问题回答正确的 $80$ 分,否则得 $0$ 分。 + + 已知小明能正确回答 A 类问题的概率为 $0.8$,能正确回答 B 类问题的概率为 $0.6$, + 且能正确回答问题的概率与回答次序无关。 + \begin{enumerate} + \item 若小明先回答 A 类问题,记 $X$ 为小明的累计得分,求 $X$ 的分布列; + \item 为使累计得分的期望最大,小明应选择先回答哪类问题?并说明理由。 + \end{enumerate} +\end{problem} + +% 19. +\begin{problem}[points = 12] + 记 $\triangle ABC$ 的内角 $A$,$B$,$C$ 的对边分别为 $a$,$b$,$c$。 + 已知 $b^2 = ac$,点 $D$ 在边 $AC$ 上,$BD \sin\angle ABC = a \sin C$。 + \nopagebreak + \begin{enumerate} + \item 证明:$BD = b$; + \item 若 $AD = 2 DC$,求 $\cos\angle ABC$。 + \end{enumerate} +\end{problem} + +% 20. +\begin{problem}[points = 12] + 如图,在三棱锥 $A$-$BCD$ 中,$\text{平面} ABD \perp \text{平面} BCD$, + $AB = AD$,$O$ 为 $BD$ 的重点。 + \begin{enumerate} + \item 证明:$OA \perp CD$; + \item 若 $\triangle OCD$ 是变长为 $1$ 的等边三角形,点 $E$ 在棱 $AD$ 上, + $DE = 2 EA$,且二面角 $E$-$BC$-$D$ 的大小为 \ang{45}, + 求三棱锥 $A$-$BCD$ 的体积。 + \end{enumerate} +\end{problem} + +% 21. +\begin{problem}[points = 12] + 在平面直角坐标系 $xOy$ 中,已知点 $F_1 (-\sqrt{17}, 0)$,$F_2 (\sqrt{17}, 0)$, + 点 $M$ 满足 $|M F_1| - |M F_2| = 2$。记 $M$ 的轨迹为 $C$。 + \begin{enumerate} + \item 求 $C$ 的方程; + \item 设点 $T$ 在直线 $x = \frac{1}{2}$ 上,过 $T$ 的两条直线分别交 $C$ 于 $A$, + $B$ 亮点和 $P$,$Q$ 亮点,且 $|TA| \cdot |TB| = |TP| \cdot |TQ|$, + 求直线 $AB$ 的斜率与直线 $PQ$ 的斜率之和。 + \end{enumerate} +\end{problem} + +% 22. +\begin{problem}[points = 12] + 已知函数 $f(x) = x (1 - \ln x)$。 + \begin{enumerate} + \item 讨论 $f(x)$ 的单调性; + \item 设 $a$,$b$ 为两个不相等的正数,且 $b \ln a - a \ln b = a - b$, + 证明:$2 < \frac{1}{a} + \frac{1}{b} < \eu$。 + \end{enumerate} +\end{problem} + +\begin{solution} + 函数的定义域为 $(0, +\infty)$, + 又 \[f^{\prime}(x) = 1 - \ln x-1 = -\ln x, \score{2}\] + 当 $x \in(0, 1)$ 时, $f^{\prime}(x) > 0$, 当 $x \in(1, +\infty)$ 时, $f^{\prime}(x) < 0$, + 故 $f(x)$ 的递增区间为 $(0,1)$, 递减区间为 $(1, +\infty)$. +\end{solution} + + +\end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-single_student_version.pdf b/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-single_student_version.pdf Binary files differnew file mode 100644 index 00000000000..ffcc32d9f55 --- /dev/null +++ b/Master/texmf-dist/doc/xelatex/exam-zh/examples/example-single_student_version.pdf diff --git a/Master/texmf-dist/tex/latex/exam-zh/exam-zh-chinese-english.sty b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-chinese-english.sty new file mode 100644 index 00000000000..b27dfab271e --- /dev/null +++ b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-chinese-english.sty @@ -0,0 +1,665 @@ +% +% Copyright (c) 2022 Kangwei Xia, Lijun Guo +% Released under the LaTeX Project Public License v1.3c License. +% Repository: https://gitee.com/zepinglee/exam-zh +% + +\NeedsTeXFormat{LaTeX2e} + +\RequirePackage{expl3} + +\ProvidesExplPackage {exam-zh-chinese-english} {2022-07-28} {v0.1.13} + {exam-zh chinese and english module} + +\PassOptionsToPackage { tcolorbox } { most } +\RequirePackage { tcolorbox } +\RequirePackage { varwidth } + +\keys_define:nn { exam-zh } + { select .meta:nn = { exam-zh / select } {#1} } + + +% 选择环境 select +\str_new:N \l__examzh_select_mark_position_str % mark 的方位 + +\keys_define:nn { exam-zh / select } + { + mark-symbol .tl_set:N = \l__examzh_select_mark_symbol_tl, + mark-position .code:n = + { + \str_set:Nn \l__examzh_select_mark_position_str {#1} + }, + mark-xshift .dim_set:N = \l__examzh_select_mark_xshift_dim, + mark-yshift .dim_set:N = \l__examzh_select_mark_yshift_dim, + separator .tl_set:N = \l__examzh_select_separator_tl, + pre-content .tl_set:N = \l__examzh_select_pre_content_tl, + post-content .tl_set:N = \l__examzh_select_post_content_tl, + show-mark .bool_set:N = \l__examzh_select_show_mark_bool + } +\keys_set:nn { exam-zh / select } + { + mark-symbol = $\checkmark$, + mark-position = right, + mark-xshift = 0pt, + mark-yshift = 0pt, + separator = \hspace{1em}, + pre-content = (, + post-content = ), + show-mark = false + } + +\seq_new:N \l__examzh_select_seq % 储存输入的内容 + +\NewDocumentEnvironment { select } { O{ } +b } + { + % 可选参数 + \keys_set:nn { exam-zh / select } {#1} + } + { + % 检测 mark-position 的输入 + \__examzh_chinese_select_coffin_position_test: + % 对输入用 \item 进行分割 + \seq_set_split:Nnn \l__examzh_select_seq { \sitem } {#2} + \seq_if_empty:NF \l__examzh_select_seq + { \seq_pop_left:NN \l__examzh_select_seq \l_tmpa_tl } + % 将内容和 mark 符号存入 coffin 并拼接输出 + \__examzh_chinese_select_coffin_set_print:N + \l__examzh_select_seq + } +\cs_new:Npn \__examzh_chinese_select_coffin_set_print:N #1 +% #1:\l__examzh_select_seq + { + % 前置内容 + \l__examzh_select_pre_content_tl + % 主体部分 + \seq_map_indexed_inline:Nn #1 + % ##1: index + % ##2: content + { + % coffin 的声明 + \__examzh_chinese_select_coffin_new:n {##1} + % 看 seq 的项是否开头是 *,是的话去掉 * 和空格存到 content coffin 并且在 mark coffin 里加入 mark,不是的话就只存到 content coffin + \__examzh_chinese_select_coffin_set:nn {##1} {##2} + \bool_if:NT \l__examzh_select_show_mark_bool + { + % 拼接 content coffin 和 mark coffin + \__examzh_chinese_select_coffin_join:n {##1} + } + % 输出 content coffin + \__examzh_chinese_select_coffin_typeset:n {##1} + } + % 后置内容 + \l__examzh_select_post_content_tl + } +\cs_new:Npn \__examzh_chinese_select_coffin_new:n #1 + { + % 检测是否存在,没有的话就 new 一个 + \coffin_if_exist:cF { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin } + { \coffin_new:c { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin } } + \coffin_if_exist:cF { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin } + { \coffin_new:c { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin } } + } +\cs_new:Npn \__examzh_chinese_select_coffin_set:nn #1#2 +% #1: index +% #2: content + { + \tl_if_head_eq_meaning:nNTF {#2} * + { + % 将去掉 * 号后的内容保存进 \l_tmpa_tl + \tl_set:Nx \l_tmpa_tl { \tl_tail:n {#2} } + % 去掉 * 和内容之间的空格 + \tl_trim_spaces:N \l_tmpa_tl + % 将处理后的内容存到 content coffin 里 + \hcoffin_set:cn { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin } + { \l_tmpa_tl } + % 将 marksymbol 存到对应的第 #1 个 mark coffin 里 + \hcoffin_set:cn { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin } + { \l__examzh_select_mark_symbol_tl } + } + { + % 不带 * 的直接存 coffin + \hcoffin_set:cn { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin } + {#2} + } + } +\msg_new:nnn { exam-zh / chinese } { select-no-mark-position } + { + There~is~no~position~named~#1 .\\ + Please~read~the~manual~carefully. + } +\cs_new:Npn \__examzh_chinese_select_coffin_position_test: + { + \str_case:VnF \l__examzh_select_mark_position_str + { + { top } { } + { above } { } + { bottom } { } + { below } { } + { left } { } + { right } { } + } + { + \msg_error:nnx { exam-zh / chinese } { select-no-mark-position } { \l__examzh_select_mark_position_str } + } + } +\cs_new:Npn \__examzh_chinese_select_coffin_join:n #1 +% #1: index + { + \use:c { __examzh_chinese_select_coffin_join_ \l__examzh_select_mark_position_str :n } {#1} + } +\cs_new:Npn \__examzh_chinese_select_coffin_join_top:n #1 + { + \coffin_join:cnncnnnn + { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin } + { hc } { t } + { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin } + { hc } { b } + { \l__examzh_select_mark_xshift_dim } + { \l__examzh_select_mark_yshift_dim + 2pt } + } +\cs_set_eq:NN + \__examzh_chinese_select_coffin_join_above:n + \__examzh_chinese_select_coffin_join_top:n +\cs_new:Npn \__examzh_chinese_select_coffin_join_bottom:n #1 + { + \coffin_join:cnncnnnn + { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin } + { hc } { H } + { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin } + { hc } { t } + { \l__examzh_select_mark_xshift_dim } + { \l__examzh_select_mark_yshift_dim - 2pt } + } +\cs_set_eq:NN + \__examzh_chinese_select_coffin_join_below:n + \__examzh_chinese_select_coffin_join_bottom:n +\cs_new:Npn \__examzh_chinese_select_coffin_join_left:n #1 + { + \coffin_join:cnncnnnn + { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin } + { l } { H } + { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin } + { r } { H } + { \l__examzh_select_mark_xshift_dim } + { \l__examzh_select_mark_yshift_dim } + } +\cs_new:Npn \__examzh_chinese_select_coffin_join_right:n #1 + { + \coffin_join:cnncnnnn + { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin } + { r } { H } + { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin } + { l } { H } + { \l__examzh_select_mark_xshift_dim } + { \l__examzh_select_mark_yshift_dim } + } +\cs_new:Npn \__examzh_chinese_select_coffin_typeset:n #1 + { + \int_compare:nNnTF {#1} = {1} + { + \coffin_typeset:cnnnn + { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin } + {l} {H} {0pt} {0pt} + } + { + \l__examzh_select_separator_tl + \coffin_typeset:cnnnn + { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin } + {l} {H} {0pt} {0pt} + } + } + + +% 连线题 lineto +\clist_clear_new:N \l__examzh_lineto_list_set_clist +\int_zero_new:N \l__examzh_lineto_node_index_int + +\keys_define:nn { exam-zh } + { lineto .meta:nn = { exam-zh / lineto } {#1} } + +\keys_define:nn { exam-zh / lineto } + { + xsep .dim_set:N = \l__examzh_lineto_node_xsep_dim, + ysep .dim_set:N = \l__examzh_lineto_node_ysep_dim, + name .tl_set:N = \l__examzh_lineto_name_tl, + list-style .tl_set:N = \l__examzh_lineto_list_style_tl + } +\keys_set:nn { exam-zh / lineto } + { + xsep = .25\linewidth, + ysep = 1cm, + name = \int_to_roman:n { \l__examzh_lineto_node_index_int } + } + + +\NewDocumentEnvironment { lineto } { O{ } } + { + \begin{center} + \begin{tikzpicture}[#1] + } + { + \end{tikzpicture} + \end{center} + } + + +\NewDocumentCommand { \linelistset } { O{} m } + { + \int_incr:N \l__examzh_lineto_node_index_int + \group_begin: + \keys_set:nn { exam-zh / lineto } {#1} + \clist_set:Nn \l__examzh_lineto_list_set_clist {#2} + \int_step_inline:nnn {1} + { \clist_count:N \l__examzh_lineto_list_set_clist } + { + \use:x + { + \exp_not:N \node + [ + name = \l__examzh_lineto_name_tl - ##1, + \l__examzh_lineto_list_style_tl + ] + at + ( + \l__examzh_lineto_node_index_int * \l__examzh_lineto_node_xsep_dim, + - \int_eval:n { ##1 - 1 } * \l__examzh_lineto_node_ysep_dim + ) + { \clist_item:Nn \l__examzh_lineto_list_set_clist {##1} }; + } + } + \group_end: + } + +\NewDocumentCommand { \lineconnect }{ O{} +m } + { + \clist_set:Nn \l_tmpa_clist {#2} + \int_step_inline:nn { \clist_count:N \l_tmpa_clist - 1 } + { + \use:x + { + \exp_not:N \draw + [line~cap = round, #1] + ( \clist_item:Nn \l_tmpa_clist {##1} .east ) + -- + ( \clist_item:Nn \l_tmpa_clist { ##1 + 1 } .west ); + } + } + } + + +% 语文的文章 材料 +\keys_define:nn { exam-zh / material } + { + title .tl_set:N = \l__examzh_material_title_content_tl, + title-format .tl_set:N = \l__examzh_material_title_format_tl, + title-material-sep .skip_set:N = \l__examzh_material_title_material_sep_skip, + format .tl_set:N = \l__examzh_material_format_tl, + top-sep .skip_set:N = \l__examzh_material_top_sep_skip, + bottom-sep .skip_set:N = \l__examzh_material_bottom_sep_skip, + author .tl_set:N = \l__examzh_material_author_content_tl, + author-format .tl_set:N = \l__examzh_material_author_format_tl, + title-author-sep .skip_set:N = \l__examzh_material_title_author_sep_skip, + source .tl_set:N = \l__examzh_material_source_content_tl, + source-format .tl_set:N = \l__examzh_material_source_format_tl, + } + +\keys_set:nn { exam-zh / material } + { + title-format = \zihao{4}, + author-format = \small, + format = \kaishu, + title-author-sep = 2em, + top-sep = 0pt, + bottom-sep = 0pt, + title-material-sep = 0pt, + } + +\NewDocumentEnvironment { material } { O{ } +b } + { + \par + \keys_set:nn { exam-zh / material } {#1} + \addvspace { \l__examzh_material_top_sep_skip } + \__examzh_material_title_author_type: + \group_begin: + \l__examzh_material_format_tl + #2 + \group_end: + } + { + \tl_if_empty:NF \l__examzh_material_source_content_tl + { + \par + \group_begin: + \hfill + \begin{varwidth}{\textwidth} + \raggedleft + \l__examzh_material_source_format_tl + \l__examzh_material_source_content_tl + \end{varwidth} + \group_end: + } + \par + \addvspace { \l__examzh_material_bottom_sep_skip } + \par + } + +\cs_new:Npn \__examzh_material_title_author_type: + { + \tl_if_empty:NF \l__examzh_material_title_content_tl + { + \noindent \hfill + \group_begin: + \l__examzh_material_title_format_tl + \l__examzh_material_title_content_tl + \group_end: + \tl_if_empty:NF \l__examzh_material_author_content_tl + { + \hspace { \l__examzh_material_title_author_sep_skip } + \group_begin: + \l__examzh_material_author_format_tl + \l__examzh_material_author_content_tl + \group_end: + } + \hfill \null + \par + \addvspace { \l__examzh_material_title_material_sep_skip } + } + } + + +% 古诗 +\bool_new:N \l__examzh_poem_type_minipage_bool +\bool_set_true:N \l__examzh_poem_type_minipage_bool +\int_new:N \l__examzh_poem_zhu_index_int +\seq_new:N \g__examzh_poem_zhu_store_seq +\str_new:N \l__examzh_poem_zhu_circlednumber_base_str + +\keys_define:nn { exam-zh / poem } + { + title .tl_set:N = \l__examzh_poem_title_content_tl, + title-format .tl_set:N = \l__examzh_poem_title_format_tl, + title-poem-sep .skip_set:N = \l__examzh_poem_title_poem_sep_skip, + format .tl_set:N = \l__examzh_poem_format_tl, + top-sep .skip_set:N = \l__examzh_poem_top_sep_skip, + bottom-sep .skip_set:N = \l__examzh_poem_bottom_sep_skip, + author .tl_set:N = \l__examzh_poem_author_content_tl, + author-format .tl_set:N = \l__examzh_poem_author_format_tl, + title-author-sep .skip_set:N = \l__examzh_poem_title_author_sep_skip, + type .choice:, + type / minipage .code:n = { \bool_set_true:N \l__examzh_poem_type_minipage_bool }, + type / chinese .code:n = { \bool_set_false:N \l__examzh_poem_type_minipage_bool }, + align .choices:nn = + { l , c , r } + { \tl_set:Nx \l__examzh_poem_align_tl { \l_keys_choice_tl } }, + zhu-circlednumber-base .choices:nn = + { tikz, font } + { \str_set:Nx \l__examzh_poem_zhu_circlednumber_base_str { \l_keys_choice_tl } } + } + +\keys_set:nn { exam-zh / poem } + { + title-format = \zihao{5}, + author-format = \small, + format = \kaishu, + title-author-sep = 2em, + top-sep = 0pt, + bottom-sep = 0pt, + title-poem-sep = 0.25\baselineskip, + type = chinese, + align = l, + zhu-circlednumber-base = font + } + +\NewDocumentEnvironment { poem } { O{ } +b } + { + \par + \keys_set:nn { exam-zh / poem } {#1} + \addvspace { \l__examzh_poem_top_sep_skip } + \__examzh_poem_begin: + \__examzh_poem_title_author_type: + \group_begin: + \l__examzh_poem_format_tl + \use:x + { + \exp_not:N \tabular + { \l__examzh_poem_align_tl } + } + #2 + \endtabular + \group_end: + } + { + \__examzh_poem_end: + \par + \addvspace { \l__examzh_poem_bottom_sep_skip } + \par + } +\cs_new:Npn \__examzh_poem_title_author_type: + { + \tl_if_empty:NF \l__examzh_poem_title_content_tl + { + % \noindent \hfill + \group_begin: + \l__examzh_poem_title_format_tl + \l__examzh_poem_title_content_tl + \group_end: + \tl_if_empty:NF \l__examzh_poem_author_content_tl + { + \hspace { \l__examzh_poem_title_author_sep_skip } + \group_begin: + \l__examzh_poem_author_format_tl + \l__examzh_poem_author_content_tl + \group_end: + } + % \hfill \null + \par + \addvspace { \l__examzh_poem_title_poem_sep_skip } + } + } +\cs_new:Npn \__examzh_poem_begin: + { + \bool_if:NTF \l__examzh_poem_type_minipage_bool + { + \noindent + \minipage { \linewidth } + \cs_set:Npn \thempfootnote { \examzh_footnote_number:N \c@mpfootnote} + \center + } + { + \int_zero:N \l__examzh_poem_zhu_index_int + \seq_clear:N \g__examzh_poem_zhu_store_seq + \center + } + } +\cs_new:Npn \__examzh_poem_end: + { + \bool_if:NTF \l__examzh_poem_type_minipage_bool + { + \endcenter + \endminipage + } + { + \endcenter + \vspace*{-0.7em} + \small + \begin{description}[leftmargin = 2em] + \item[{[注]}] + \seq_map_indexed_inline:Nn \g__examzh_poem_zhu_store_seq + % ##1: index + % ##2: content + { + \__examzh_chinese_circled_number:n {##1} ~ ##2 + } + \end{description} + } + } + + +\NewDocumentCommand { \zhu } { o m } + { + \bool_if:NTF \l__examzh_poem_type_minipage_bool + { + \footnote {#2} + } + { + \IfNoValueF {#1} + { + \int_gset:Nn \l__examzh_poem_zhu_index_int {#1 - 1} + } + \__examzh_poem_type_chinese_zhu:n {#2} + } + } + +\cs_new:Npn \__examzh_poem_type_chinese_zhu:n #1 + { + \int_gincr:N \l__examzh_poem_zhu_index_int + \int_set_eq:NN \l_tmpa_int \l__examzh_poem_zhu_index_int + \unskip + % 输出符号 + \textsuperscript + { \__examzh_chinese_circled_number:n { \l__examzh_poem_zhu_index_int } } + % 将参数存起来 + \seq_gput_right:Nx \g__examzh_poem_zhu_store_seq + { #1 } + } + +\cs_new:Npn \__examzh_chinese_circled_number:n #1 + { + \str_case:Vn \l__examzh_poem_zhu_circlednumber_base_str + { + { tikz } { \__examzh_chinese_tikz_circled_number:n {#1} } + { font } { \__examzh_chinese_tikz_circled_number:n {#1} } + } + } +% 基于字体的带圈数字 +\cs_new:Npn \__examzh_chinese_font_circled_number:n #1 + { + \int_set:Nn \l_tmpa_int {#1} + \int_compare:nNnTF { \l_tmpa_int } = { 0 } + { \int_set:Nn \l_tmpa_int { "24EA } } + { + \int_compare:nNnTF { \l_tmpa_int } < { 21 } + { \int_add:Nn \l_tmpa_int { "245F } } + { + \int_compare:nNnTF { \l_tmpa_int } < { 36 } + { \int_add:Nn \l_tmpa_int { "3250 } } + { + \int_compare:nNnTF { \l_tmpa_int } < { 51 } + { \int_add:Nn \l_tmpa_int { "32B0 } } + { + \msg_error:nnn { exam-zh / poem } + { invalid-circled-number } { \int_use:N \l_tmpa_int } + } + } + } + } + \group_begin: + \CJKfamily+ { } + \symbol { \l_tmpa_int } + \group_end: + } + +\msg_new:nnn { exam-zh / poem } { invalid-circled-number } + { Invalid~ circled~ number~ #1. } + +% tikz 绘制带圈数字 +\fp_new:N \l__examzh_chinese_tikz_circled_number_xscale_fp % 水平压缩系数 +\fp_new:N \l__examzh_chinese_tikz_circled_number_yscale_fp % 垂直压缩系数 +\dim_new:N \l__examzh_chinese_tikz_circled_number_total_hegiht_dim % 数字的总高度 +\dim_new:N \l__examzh_chinese_tikz_circled_number_radius_dim % 半径 + +\cs_new:Npn \__examzh_chinese_tikz_circled_number_aux:n #1 + { + % 根据数字大小设置压缩系数 + \fp_set:Nn \l__examzh_chinese_tikz_circled_number_xscale_fp + { + \int_compare:nNnTF {#1} < { 10 } + { 0.9 } + { + \int_compare:nNnTF {#1} < { 100 } + { 0.7 } + { 0.5 } + } + } + \fp_set:Nn \l__examzh_chinese_tikz_circled_number_yscale_fp + { + \int_compare:nNnTF {#1} < { 10 } + { 0.9 } + { + \int_compare:nNnTF {#1} < { 100 } + { 0.8 } + { 0.6 } + } + } + % 获取数字的高度 + \hbox_set:Nn \l_tmpa_box {#1} + \dim_set:Nn \l__examzh_chinese_tikz_circled_number_total_hegiht_dim + { \box_ht:N \l_tmpa_box + \box_dp:N \l_tmpa_box } + % 设置圆的半径 + \dim_set:Nn \l__examzh_chinese_tikz_circled_number_radius_dim + { \dim_eval:n { \l__examzh_chinese_tikz_circled_number_total_hegiht_dim / 2 + 0.34 ex } } + % 绘制 + \tikz [ baseline ] + { + \node + [ inner~sep = 0pt, outer~sep = 0pt ] + at (0, \dim_use:N \l__examzh_chinese_tikz_circled_number_total_hegiht_dim / 2 ) + { + \hbox_set:Nn \l_tmpa_box + { + \int_compare:nNnTF {#1} > {9} + { \textbf {#1} } + {#1} + } + \makebox[0.35em][c] + { + % \scalebox { \fp_use:N \l__examzh_chinese_tikz_circled_number_xscale_fp } + % [ \fp_use:N \l__examzh_chinese_tikz_circled_number_yscale_fp ] + \box_scale:Nnn \l_tmpa_box + { \fp_use:N \l__examzh_chinese_tikz_circled_number_xscale_fp } + { \fp_use:N \l__examzh_chinese_tikz_circled_number_yscale_fp } + \box_use_drop:N \l_tmpa_box + } + }; + \draw (0, \l__examzh_chinese_tikz_circled_number_total_hegiht_dim / 2 ) + circle ( \l__examzh_chinese_tikz_circled_number_radius_dim ); + } + } +\cs_new:Npn \__examzh_chinese_tikz_circled_number:n #1 + { + \__examzh_chinese_tikz_circled_number_aux:n { \int_eval:n {#1} } + } + + +% 作文框 +\NewDocumentEnvironment { writingbox } { O{ } +b } + { + \begin{tcolorbox} + [ + % 直角 + sharp~corners = all, + % 颜色 + colback = white, + colbacktitle = white, + % colframe = white, + coltitle = black, + % 边框粗细 + boxrule = 1pt, + titlerule = 0pt, + % 间距 + toptitle = 4pt, + % 字体 + fonttitle = \centering, + % 首行缩进 + parbox = false, + before~upper = \indent, + % 跨页 + breakable, + enhanced~jigsaw, + #1 + ] + #2 + } + { + \end{tcolorbox} + }
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/exam-zh/exam-zh-choices.sty b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-choices.sty new file mode 100644 index 00000000000..6eccb24867a --- /dev/null +++ b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-choices.sty @@ -0,0 +1,555 @@ +% +% Copyright (c) 2022 Zeping Lee +% Released under the LaTeX Project Public License v1.3c License. +% Repository: https://gitee.com/zepinglee/exam-zh +% + +\NeedsTeXFormat{LaTeX2e} + +\RequirePackage{expl3} +\RequirePackage{xparse} + +\ProvidesExplPackage {exam-zh-choices} {2022-07-28} {v0.1.13} + {exam-zh choices module} + +\dim_new:N \l__examzh_choices_column_sep_dim +\int_new:N \l__examzh_choices_columns_int +\tl_new:N \l__examzh_choices_label_tl +\tl_new:N \l__examzh_choices_label_pos_tl +\tl_new:N \l__examzh_choices_label_align_tl +\dim_new:N \l__examzh_choices_label_sep_dim +\dim_new:N \l__examzh_choices_label_width_dim +\int_new:N \l__examzh_choices_max_columns_int + +\keys_define:nn { exam-zh } + { choices .meta:nn = { exam-zh / choices } {#1} } + +\keys_define:nn { exam-zh / choices } + { + column-sep .dim_set:N = \l__examzh_choices_column_sep_dim , + columns .int_set:N = \l__examzh_choices_columns_int , + label .tl_set:N = \l__examzh_choices_label_tl , + label-pos .choices:nn = + { auto , top-left , left , bottom } + { \tl_set_eq:NN \l__examzh_choices_label_pos_tl \l_keys_choice_tl } , + label-align .tl_set:N = \l__examzh_choices_label_align_tl , + label-sep .dim_set:N = \l__examzh_choices_label_sep_dim , + label-width .dim_set:N = \l__examzh_choices_label_width_dim , + max-columns .int_set:N = \l__examzh_choices_max_columns_int , + index .int_set:N = \l__examzh_choices_item_index_int + } + +\keys_set:nn { exam-zh / choices } + { + column-sep = 1em , + columns = 0 , + label = \Alph*. , + label-pos = auto , + label-align = right , + label-sep = .5em , + label-width = 0pt , + max-columns = 4 , + index = 1, + } + +\NewDocumentCommand \setchoices { m } + { \keys_set:nn { exam-zh / choices } {#1} } + + +\tl_new:N \l__examzh_choices_counters_tl + +\NewDocumentCommand \AddChoicesCounter { m m } + % #1: \Alph(用户接口) + % #2: \@Alph(具体实现的命令或函数(开发层)) + { + % TODO 这一步的作用是什么,为什么要把函数放在 tl 变量里而不是直接在某处使用? + % 猜测:put_right 而不是 set,是为了保证操作 label 的输入值前 + % 几个函数都被 set + \tl_put_right:Nn \l__examzh_choices_counters_tl + { \__examzh_choices_process_counter:NN #1 #2 } + \cs_set_eq:cN { __examzh_choices_save_ \cs_to_str:N #1 : } #2 + \cs_set_eq:cN { __examzh_choices_save_ \cs_to_str:N #2 : } #2 + } + +\AddChoicesCounter \arabic \@arabic +\AddChoicesCounter \alph \@alph +\AddChoicesCounter \Alph \@Alph +\AddChoicesCounter \roman \@roman +\AddChoicesCounter \Roman \@Roman + + +\dim_new:N \l__examzh_choices_total_width_dim +\seq_new:N \l__examzh_choices_seq + +\NewDocumentEnvironment { choices } { O { } +b } + { + \par \nopagebreak + % 严格禁止孤行和寡行 + \int_set:Nn \clubpenalty { 10000 } + \int_set:Nn \widowpenalty { 10000 } + % 尽量避免在选项中间换行 + \int_set:Nn \interlinepenalty { 301 } + \noindent + \dim_set_eq:NN \l__examzh_choices_total_width_dim \linewidth + \int_zero:N \l__examzh_choices_columns_int + \dim_zero:N \l__examzh_choices_label_width_dim + \keys_set:nn { exam-zh / choices } {#1} + } + { + % 用 \item 分割选项 + \seq_set_split:Nnn \l__examzh_choices_seq { \item } {#2} + % 把第一个空项去掉 + \seq_if_empty:NF \l__examzh_choices_seq + { \seq_pop_left:NN \l__examzh_choices_seq \l_tmpa_tl } + % 收集正确的选项 + \__examzh_choices_collect_correct_choices:N + \l__examzh_choices_seq + % 计算标签和选项内容的最大自然宽度 + \__examzh_choices_calc_max_width:N \l__examzh_choices_seq + % label-pos = auto 时自动选择标签位置 + \__examzh_choices_set_auto_label_pos: + % 如果用户没有声明列数,计算合适的列数 + % 「学习点」从默认值是否被改变来测试用户是否输入 + % 用户没有输入的话就采用自动计算列数 + \int_compare:nNnT { \l__examzh_choices_columns_int } < {1} + { \__examzh_choices_calc_columns: } + % 计算每个选项内容的宽度 \l__examzh_choices_item_width_dim + \__examzh_choices_calc_item_width: + % 输出选项 + \__examzh_print_choices:N \l__examzh_choices_seq + % 输出正确选项 + \__examzh_print_correctchoice: + } + +% 用来存正确选项的序号(entry) +\seq_new:N \l__examzh_choices_correct_choices_label_seq +% 用来存正确选项的内容 +\seq_new:N \l__examzh_choices_correct_choices_item_seq + +% 收集正确的选项,保存在 \l__examzh_choices_correct_choices_seq +\cs_new:Npn \__examzh_choices_collect_correct_choices:N #1 + % #1: \l__examzh_choices_seq + { + \seq_clear:N \l__examzh_choices_correct_choices_label_seq + \seq_clear:N \l__examzh_choices_correct_choices_item_seq + \seq_clear:N \l_tmpa_seq + \seq_map_indexed_inline:Nn #1 + { + % ##1: 选项序号 + % ##2: 选项内容 + % 如果分割后,第一个字符是 * 的,表明这是一个正确选项 + %(即用 \item* 来标记正确答案) + \tl_if_head_eq_meaning:nNTF {##2} * + { + \seq_put_right:Nn \l__examzh_choices_correct_choices_label_seq + { \__examzh_choices_correct_choices_label_transfrom:n {##1} } + % 将去掉 * 号后的内容保存进 \l_tmpa_tl + \tl_set:Nx \l_tmpa_tl { \tl_tail:n {##2} } + % 去掉 * 和内容之间的空格 + \tl_trim_spaces:N \l_tmpa_tl + \seq_put_right:NV \l__examzh_choices_correct_choices_item_seq + \l_tmpa_tl + \seq_put_right:NV \l_tmpa_seq \l_tmpa_tl + } + { + \seq_put_right:Nn \l_tmpa_seq { ##2 } + } + } + \seq_set_eq:NN #1 \l_tmpa_seq + } + +% 根据 label 的样式 \l__examzh_choices_label_tl 转化正确选项的样式 +\cs_new:Npn \__examzh_choices_correct_choices_label_transfrom:n #1 + { + \group_begin: + \int_set:Nn \l__examzh_choices_index_int {#1} + % 定义计数器转换函数(如 \Alph 等) + \l__examzh_choices_counters_tl + % 输出 + \l__examzh_choices_label_tl + \group_end: + } +% 输出正确的选项 +\cs_new:Nn \__examzh_print_correctchoice: + { + \seq_if_empty:NF \l__examzh_choices_correct_choices_item_seq + { + \par + 参考答案: + \seq_use:Nn \l__examzh_choices_correct_choices_label_seq {,~} + } + } + + +\dim_new:N \l__examzh_choices_item_width_dim +\dim_new:N \l__examzh_choices_item_min_height_dim + +% 计算标签和选项内容的最大宽度, +% 分别保存到 \l__examzh_choices_label_width_dim 和 \l__examzh_choices_item_width_dim +% #1: \l__examzh_choices_seq +\cs_new:Npn \__examzh_choices_calc_max_width:N #1 + { + % 下面这两个的想法是 xchoices 项目可以优化学习的地方 + % 因为 xchoices 是把变量先设置为第一项的参数,然后让后面的和前面的比 + % 这里相当于把“设置为第一项的参数”这一步,用默认的“端点量”来代替 + % 比如取最大的,就和 0 比,这样的话其实也会产生变量会变成第一项的参数的结果 + % 但是两者性质不同,此处处理让 第一项 「没有特殊性」 + % 后面的计算最小高度的也是如此 + \dim_zero:N \l__examzh_choices_item_width_dim + \dim_set_eq:NN \l__examzh_choices_item_min_height_dim \c_max_dim + \seq_map_indexed_inline:Nn #1 + { + % -- 标签 -- + % 把标签整体放进 \l_tmpa_box + \hbox_set:Nn \l_tmpa_box { \__examzh_choices_the_label:n {##1} } + % 测量宽度 + \dim_set:Nn \l_tmpa_dim { \box_wd:N \l_tmpa_box } + % 与当前最大值比较,最后效果是 \l__examzh_choices_label_width_dim 储存了所有标签中宽度最大的标签的宽度值 + \dim_compare:nNnT + { \l_tmpa_dim } > { \l__examzh_choices_label_width_dim } + { \dim_set_eq:NN \l__examzh_choices_label_width_dim \l_tmpa_dim } + % -- 选项内容 -- + % 把内容放进 \l_tmpa_box 中 + \hbox_set:Nn \l_tmpa_box {##2} + % 测量宽度 + \dim_set:Nn \l_tmpa_dim { \box_wd:N \l_tmpa_box } + % 与当前最大值比较,最后效果是 \l__examzh_choices_item_width_dim 储存了所有选项内容中宽度最大的内容的宽度值 + \dim_compare:nNnT + { \l_tmpa_dim } > { \l__examzh_choices_item_width_dim } + { + \dim_set_eq:NN \l__examzh_choices_item_width_dim + \l_tmpa_dim + } + % -- 找到最小高度 -- + % 把内容高度储存到 \l_tmpb_dim + \dim_set:Nn \l_tmpb_dim { \box_ht:N \l_tmpa_box } + % 与当前最小值比较,最后效果是 \l__examzh_choices_item_min_height_dim 储存了所有内容中高度最小的内容的高度值 + \dim_compare:nNnT + { \l_tmpb_dim } < { \l__examzh_choices_item_min_height_dim } + { \dim_set_eq:NN \l__examzh_choices_item_min_height_dim \l_tmpb_dim } + \box_clear:N \l_tmpa_box + } + } + +% TODO 没看懂怎么实现的 +\int_new:N \l__examzh_choices_index_int + +% \Alph* 形式生成正确的标签 +\cs_new:Npn \__examzh_choices_the_label:n #1 + { + \group_begin: + \int_set:Nn \l__examzh_choices_index_int + { + \int_eval:n + { + \l__examzh_choices_item_index_int + #1 - 1 + } + } + \l__examzh_choices_counters_tl + \l__examzh_choices_label_tl + \group_end: + } + +\cs_new:Npn \__examzh_choices_process_counter:NN #1#2 + % #1: \Alph + % #2: \@Alph + { + % 用户可以同时使用 #1 和 #2 两个函数(命令)作为 label 的操作函数 + % #1 的内核原理函数是 #2 + \cs_set:Npn #1 { \__examzh_choices_process_counter_aux:Nn #2 } + \cs_set:Npn #2 { \__examzh_choices_process_counter_aux:Nn #2 } + } + +\cs_new:Npn \__examzh_choices_process_counter_aux:Nn #1#2 + % #1: \@Alph + { + \tl_if_eq:nnTF {#2} { * } + { + % 如果是 \alph* 类型的,效果为 \alph{ \l__examzh_choices_index_int } + \use:c { __examzh_choices_save_ \cs_to_str:N #1 : } + { \l__examzh_choices_index_int } + } + { + % 否则就是 \alph{...} 效果 + \use:c { __examzh_choices_save_ \cs_to_str:N #1 : } {#2} + } + } + + +% 超过这一高度阈值的选项视为插图模式 +% 注意使用 tl +% TODO 为何要使用 tl 而不用 dim ? +\tl_new:N \l__examzh_choices_figure_mode_threshold_tl +\tl_set:Nn \l__examzh_choices_figure_mode_threshold_tl { 2 \baselineskip } + +\cs_new:Npn \__examzh_choices_set_auto_label_pos: + { + \tl_if_eq:NnT \l__examzh_choices_label_pos_tl { auto } + { + % 若最小高度超过阈值,推测其中包含插图,将标签位置改为左居中 + \dim_compare:nNnTF + { \l__examzh_choices_item_min_height_dim } > + { \l__examzh_choices_figure_mode_threshold_tl } + { \tl_set:Nn \l__examzh_choices_label_pos_tl { left } } + { \tl_set:Nn \l__examzh_choices_label_pos_tl { top-left } } + } + } + + +\int_new:N \l__examzh_tmp_int + +% 计算选项的合适列数,存到 \l__examzh_choices_columns_int +\cs_new:Npn \__examzh_choices_calc_columns: + { + % 若标签不在底部,将 label-width 和 label-sep 加到 \l__examzh_choices_item_width_dim 里面 + \tl_if_eq:NnF \l__examzh_choices_label_pos_tl { bottom } + { + \dim_add:Nn \l__examzh_choices_item_width_dim + { \l__examzh_choices_label_width_dim + \l__examzh_choices_label_sep_dim } + } + % [总宽度 / 最大的选项宽度] = 列数 + % 这个计算出来是作为「算出来的、可以排的最大列数」 + % 将要和下面的手动(或者默认的)最大列数进行比较,来确定最后排多少列 + \int_set:Nn \l__examzh_choices_columns_int + { + \int_div_truncate:nn + { \l__examzh_choices_total_width_dim + \l__examzh_choices_column_sep_dim } + { \l__examzh_choices_item_width_dim + \l__examzh_choices_column_sep_dim } + } + % 如果上面的计算算出来是 0 的话,就设置为 1 + \int_compare:nNnTF { \l__examzh_choices_columns_int } = {0} + { \int_set:Nn \l__examzh_choices_columns_int {1} } + % 从允许的最大列数开始,每次除以 2,直到行宽允许排下 + % 比如设置了最大列数是 4 , 但是算出来可以排 5 + % 那么就会将 [4 / 2] = 2 < 5 作为列数 + \int_set_eq:NN \l__examzh_tmp_int \l__examzh_choices_max_columns_int + \int_while_do:nNnn + { \l__examzh_tmp_int } > { \l__examzh_choices_columns_int } + { + \int_set:Nn \l__examzh_tmp_int + { \int_div_truncate:nn { \l__examzh_tmp_int } {2} } + } + \int_set_eq:NN \l__examzh_choices_columns_int \l__examzh_tmp_int + } + + +% 计算选项的最终宽度,保存到 \l__examzh_choices_item_width_dim +\cs_new:Npn \__examzh_choices_calc_item_width: + { + \dim_set:Nn \l__examzh_choices_item_width_dim + { + % TODO 不是很理解这里的算法 + ( \l__examzh_choices_total_width_dim + - \l__examzh_choices_columns_int \l__examzh_choices_column_sep_dim + + \l__examzh_choices_column_sep_dim + ) / \l__examzh_choices_columns_int + } + % 若标签不在底部,将 label-width 和 label-sep 算进来 + % TODO 算进来?那怎么还是 sub? + \tl_if_eq:NnF \l__examzh_choices_label_pos_tl { bottom } + { + \dim_sub:Nn \l__examzh_choices_item_width_dim + { \l__examzh_choices_label_width_dim + \l__examzh_choices_label_sep_dim } + } + } + + +\int_new:N \l__examzh_choices_current_col_int + +% #1: \l__examzh_choices_seq +\cs_new:Npn \__examzh_print_choices:N #1 + { + \int_zero:N \l__examzh_choices_current_col_int + \seq_map_indexed_inline:Nn \l__examzh_choices_seq + { + \int_incr:N \l__examzh_choices_current_col_int + % 当前列号重置为 1 + \int_compare:nNnT + { \l__examzh_choices_current_col_int } > { \l__examzh_choices_columns_int } + { + % \par \noindent + \newline + \int_set:Nn \l__examzh_choices_current_col_int {1} + } + % TODO 为什么 > 1 才加呢? 这样的话第 1 列和第 2 列之间就没有这个间距? + \int_compare:nNnT { \l__examzh_choices_current_col_int } > {1} + { + \skip_horizontal:N \l__examzh_choices_column_sep_dim + % 增加一点弹性 + \skip_horizontal:n {0pt plus 1pt minus 1pt} + } + \__examzh_print_single_choice:nn {##1} {##2} + } + \par + } + + +\coffin_new:N \l__examzh_choices_item_coffin +\coffin_new:N \l__examzh_choices_label_coffin + +\cs_new:Npn \__examzh_print_single_choice:nn #1#2 + { + % 选项标签 + \__examzh_choices_make_label_coffin:n {#1} + % 选项内容 + \__examzh_choices_make_item_coffin:n {#2} + % 合并选项的标签和内容 + \str_case:Vn \l__examzh_choices_label_pos_tl + { + { top-left } + { + \coffin_join:NnnNnnnn + \l__examzh_choices_item_coffin {l} {H} + \l__examzh_choices_label_coffin {r} {H} + { - \l__examzh_choices_label_sep_dim } + { 0pt } + } + { left } + { + \coffin_join:NnnNnnnn + \l__examzh_choices_item_coffin {l} {vc} + \l__examzh_choices_label_coffin {r} {vc} + { - \l__examzh_choices_label_sep_dim } + { 0pt } + } + { bottom } + { + \coffin_join:NnnNnnnn + \l__examzh_choices_item_coffin {hc} {b} + \l__examzh_choices_label_coffin {hc} {t} + { 0pt } + % { - \l__examzh_choices_label_sep_dim } + { 0pt } + } + } + % 输出合并后 + \coffin_typeset:Nnnnn \l__examzh_choices_item_coffin {l} {H} {0pt} {0pt} + \coffin_clear:N \l__examzh_choices_item_coffin + \coffin_clear:N \l__examzh_choices_label_coffin + } + +% 将标签内容存入 coffin +\cs_new:Npn \__examzh_choices_make_label_coffin:n #1 + { + \hcoffin_set:Nn \l__examzh_choices_label_coffin + { + \hbox_to_wd:nn { \l__examzh_choices_label_width_dim } + { \__examzh_choices_make_label:n {#1} \strut } + } + } + +\cs_new:Npn \__examzh_choices_make_label:n #1 + { + \str_case:Vn \l__examzh_choices_label_align_tl + { + { left } { \rlap { \__examzh_choices_the_label:n {#1} } \hss } + { center } { \hss \clap { \__examzh_choices_the_label:n {#1} } \hss } + { right } { \hss \llap { \__examzh_choices_the_label:n {#1} } } + } + } + +\bool_new:N \l__examzh_choices_figure_mode_bool + +% 将选项内容存入 coffin +\cs_new:Npn \__examzh_choices_make_item_coffin:n #1 + { + \hcoffin_set:Nn \l__examzh_choices_item_coffin + { + % 优先尝试使用 hbox,这是因为在 \vcoffin_set 外部能保留原来的 \linewidth 和 + % \textwidth,方便用户在 \includegraphics 中使用 + \hbox_set:Nn \l_tmpa_box {#1} + % 若盒子的自然高度大于 2 行,且深度为 0pt,设置为插图模式 + \bool_lazy_and:nnT + { + \dim_compare_p:nNn { \box_ht:N \l_tmpa_box } > + { \l__examzh_choices_figure_mode_threshold_tl } + } + { \dim_compare_p:nNn { \box_dp:N \l_tmpa_box } < { 1pt } } + { \bool_set_true:N \l__examzh_choices_figure_mode_bool } + \vcoffin_set:Nnn \l_tmpa_coffin + { \l__examzh_choices_item_width_dim } + { + \dim_set_eq:NN \parskip \c_zero_dim + \dim_set_eq:NN \parindent \listparindent + \noindent + % \strut + % 若标签在底部,将图片居中对齐。 + \tl_if_eq:NnT \l__examzh_choices_label_pos_tl { bottom } + { \centering } + \dim_compare:nNnTF + { \box_wd:N \l_tmpa_box } > { \l__examzh_choices_item_width_dim } + { #1 } + { \box_use_drop:N \l_tmpa_box } + % 使用 \strut 将行距撑开,防止跟下一行选项的间距过小 + \mode_if_horizontal:T { \strut } + } + \dim_set:Nn \l_tmpa_dim { \coffin_ht:N \l_tmpa_coffin } + \bool_if:NT \l__examzh_choices_figure_mode_bool + { + \coffin_set_horizontal_pole:Nnn \l_tmpa_coffin {T} + { \l_tmpa_dim - 0.7 \baselineskip } + } + \coffin_typeset:Nnnnn \l_tmpa_coffin {l} {T} {0pt} {0pt} + \coffin_clear:N \l_tmpa_coffin + } + } + + +% 使用中文字体直接输出 unicode 带圈数字 +% \circlednumber 的参数既可以接受 LaTeX2e 的 <counter>,也可以直接接受 <intexpr>。 +% \NewDocumentCommand \circlednumber { m } +% { +% \int_if_exist:cTF { c@ #1 } +% { \int_set_eq:Nc \l_tmpa_int { c@#1 } } +% { \int_set:Nn \l_tmpa_int { #1 } } +% \exp_args:Nx \__examzh_choices_circled_number:n { \int_use:N \l_tmpa_int } +% } + +\cs_new:Npn \__examzh_choices_circled_number:n #1 + { + \int_set:Nn \l_tmpa_int {#1} + \int_compare:nNnTF { \l_tmpa_int } = { 0 } + { \int_set:Nn \l_tmpa_int { "24EA } } + { + \int_compare:nNnTF { \l_tmpa_int } < { 21 } + { \int_add:Nn \l_tmpa_int { "245F } } + { + \int_compare:nNnTF { \l_tmpa_int } < { 36 } + { \int_add:Nn \l_tmpa_int { "3250 } } + { + \int_compare:nNnTF { \l_tmpa_int } < { 51 } + { \int_add:Nn \l_tmpa_int { "32B0 } } + { + \msg_error:nnn { exam-zh / choices } + { invalid-circled-number } { \int_use:N \l_tmpa_int } + } + } + } + } + \group_begin: + % TODO 为何要用 \CJKfamily+ { } + % xeCJK 宏包文档:当 \CJKfamily+ 参数为空时,则使用当前的 CJK 字体族。 + \CJKfamily+ { } + \symbol { \l_tmpa_int } + \group_end: + } + +\msg_new:nnn { exam-zh / choices } { invalid-circled-number } + { Invalid~ circled~ number~ #1. } + +\AddChoicesCounter \circlednumber \__examzh_choices_circled_number:n + + +% TODO 答案控制 + +% 选择题答案控制 +% - 直接在后面显示 +% - 在括号内显示 +% - 手动输入 +% - 能否通过写中途文件方式使得答案可以出现在前面的括号内 +% - 统一移动到最后 +% - 也是 choices 的形式 +% - 表格形式 + +% 答案确定 +% 通过 \item 是否带 * 判断,有的话则标记为正确答案
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/exam-zh/exam-zh-font.sty b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-font.sty new file mode 100644 index 00000000000..15b173c9ef7 --- /dev/null +++ b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-font.sty @@ -0,0 +1,580 @@ +% +% Copyright (c) 2022 Zeping Lee +% Released under the LaTeX Project Public License v1.3c License. +% Repository: https://gitee.com/zepinglee/exam-zh +% + +\NeedsTeXFormat{LaTeX2e} + +\RequirePackage{expl3} +\RequirePackage{xparse} + +\ProvidesExplPackage {exam-zh-font} {2022-07-28} {v0.1.13} + {exam-zh font module} + +\RequirePackage { unicode-math } +\RequirePackage { filehook } + +\tl_new:N \g__examzh_font_font_tl +\tl_new:N \g__examzh_font_math_font_tl + +\keys_define:nn { exam-zh } + { + font .choices:nn = + { + newcm , + lm , + times , + termes , + stix, + xits , + libertinus , + % newtx , + none + } + { + \tl_gset_eq:NN \g__examzh_font_font_tl \l_keys_choice_tl + \use:c { examzh_font_set_font_ \g__examzh_font_font_tl : } + } , + math-font .choices:nn = + { + newcm , + lm , + termes , + stix, + xits , + libertinus , + cambria , + % newtx , + none + } + { + \tl_gset_eq:NN \g__examzh_font_math_font_tl \l_keys_choice_tl + \use:c { examzh_font_set_math_font_ \g__examzh_font_math_font_tl : } + } , + } + + +% New Computer Modern +\cs_new:Npn \examzh_font_set_font_newcm: + { + \setmainfont { NewCM10 } + [ + Extension = .otf , + UprightFont = *-Book , + BoldFont = *-Bold , + ItalicFont = *-BookItalic , + BoldItalicFont = *-BoldItalic , + ] + \setsansfont { NewCMSans10 } + [ + Extension = .otf , + UprightFont = *-Book , + BoldFont = *-Bold , + ItalicFont = *-BookOblique , + BoldItalicFont = *-BoldOblique , + ] + \setmonofont { NewCMMono10 } + [ + Extension = .otf , + UprightFont = *-Book , + ItalicFont = *-BookItalic , + BoldFont = *-Bold , + BoldItalicFont = *-BoldOblique , + ] + } + + +% Latin Modern +\cs_new:Npn \examzh_font_set_font_lm: + { + \setmainfont { lmroman10 } + [ + Extension = .otf , + UprightFont = *-regular , + BoldFont = *-bold , + ItalicFont = *-italic , + BoldItalicFont = *-bolditalic , + ] + \setsansfont { lmsans10 } + [ + Extension = .otf , + UprightFont = *-regular , + BoldFont = *-bold , + ItalicFont = *-oblique , + BoldItalicFont = *-boldoblique , + ] + \setmonofont { lmmonolt10 } + [ + Extension = .otf , + UprightFont = *-regular , + BoldFont = *-bold , + ItalicFont = *-oblique , + BoldItalicFont = *-boldoblique , + ] + } + + +% Times New Roman + Arial +\cs_new:Npn \examzh_font_set_font_times: + { + \setmainfont { Times~ New~ Roman } + \setsansfont { Arial } [ Scale = MatchLowercase ] + \setmonofont { Courier~ New } [ Scale = MatchLowercase ] + } + + +% TeX Gyre Termes +\cs_new:Npn \examzh_font_set_font_termes: + { + \setmainfont { texgyretermes } + [ + Extension = .otf , + UprightFont = *-regular , + BoldFont = *-bold , + ItalicFont = *-italic , + BoldItalicFont = *-bolditalic , + ] + \examzh_font_set_tex_gyre_sans_mono: + } + +\cs_new:Npn \examzh_font_set_tex_gyre_sans_mono: + { + \setsansfont { texgyreheros } + [ + Extension = .otf , + UprightFont = *-regular , + BoldFont = *-bold , + ItalicFont = *-italic , + BoldItalicFont = *-bolditalic , + Scale = MatchLowercase , + ] + \setmonofont { texgyrecursor } + [ + Extension = .otf , + UprightFont = *-regular , + BoldFont = *-bold , + ItalicFont = *-italic , + BoldItalicFont = *-bolditalic , + Scale = MatchLowercase , + Ligatures = CommonOff , + ] + } + + +% STIX Two 字体。 +% STIX 文件名在 v2.10 2020-12-19 从 +% \file{STIX2Text-Regular.otf}、\file{STIX2Math.otf} 分别改为 +% \file{STIXTwoText-Regular.otf}、\file{STIXTwoMath-Regular.otf}。 +\tl_new:N \g__examzh_font_font_family_stix_tl +\tl_new:N \g__examzh_font_font_name_stix_math_tl +\cs_new:Npn \examzh_font_set_stix_names: + { + \tl_if_empty:NT \g__examzh_font_font_family_stix_tl + { + \fontspec_font_if_exist:nTF { STIXTwoText-Regular.otf } + { + \tl_gset:Nn \g__examzh_font_font_family_stix_tl { STIXTwoText } + \tl_gset:Nn \g__examzh_font_font_name_stix_math_tl { STIXTwoMath-Regular } + } + { + \tl_gset:Nn \g__examzh_font_font_family_stix_tl { STIX2Text } + \tl_gset:Nn \g__examzh_font_font_name_stix_math_tl { STIX2Math } + } + } + } + +\cs_new:Npn \examzh_font_set_font_stix: + { + \examzh_font_set_stix_names: + \setmainfont { \g__examzh_font_font_family_stix_tl } + [ + Extension = .otf , + UprightFont = *-Regular , + BoldFont = *-Bold , + ItalicFont = *-Italic , + BoldItalicFont = *-BoldItalic , + ] + \examzh_font_set_tex_gyre_sans_mono: + } + + +% XITS 字体。 +% XITS 的文件名在 v1.109 2018-09-30 +% 从 \file{xits-regular.otf}、\file{xits-math.otf} 分别改为 +% \file{XITS-Regular.otf}、\file{XITSMath-Regular.otf}。 +\tl_new:N \g__examzh_font_font_family_xits_tl +\tl_new:N \g__examzh_font_font_style_xits_rm_tl +\tl_new:N \g__examzh_font_font_style_xits_bf_tl +\tl_new:N \g__examzh_font_font_style_xits_it_tl +\tl_new:N \g__examzh_font_font_style_xits_bfit_tl +\tl_new:N \g__examzh_font_font_name_xits_math_tl + +\cs_new:Npn \examzh_font_set_xits_names: + { + \tl_if_empty:NT \g__examzh_font_font_family_xits_tl + { + \fontspec_font_if_exist:nTF { XITSMath-Regular.otf } + { + \tl_gset:Nn \g__examzh_font_font_family_xits_tl { XITS } + \tl_gset:Nn \g__examzh_font_font_style_xits_rm_tl { Regular } + \tl_gset:Nn \g__examzh_font_font_style_xits_bf_tl { Bold } + \tl_gset:Nn \g__examzh_font_font_style_xits_it_tl { Italic } + \tl_gset:Nn \g__examzh_font_font_style_xits_bfit_tl { BoldItalic } + \tl_gset:Nn \g__examzh_font_font_name_xits_math_tl { XITSMath-Regular } + } + { + \tl_gset:Nn \g__examzh_font_font_family_xits_tl { xits } + \tl_gset:Nn \g__examzh_font_font_style_xits_rm_tl { regular } + \tl_gset:Nn \g__examzh_font_font_style_xits_bf_tl { bold } + \tl_gset:Nn \g__examzh_font_font_style_xits_it_tl { italic } + \tl_gset:Nn \g__examzh_font_font_style_xits_bfit_tl { bolditalic } + \tl_gset:Nn \g__examzh_font_font_name_xits_math_tl { xits-math } + } + } + } + +\cs_new:Npn \examzh_font_set_font_xits: + { + \examzh_font_set_xits_names: + \setmainfont { \g__examzh_font_font_family_xits_tl } + [ + Extension = .otf , + UprightFont = *-\g__examzh_font_font_style_xits_rm_tl , + BoldFont = *-\g__examzh_font_font_style_xits_bf_tl , + ItalicFont = *-\g__examzh_font_font_style_xits_it_tl , + BoldItalicFont = *-\g__examzh_font_font_style_xits_bfit_tl , + ] + \examzh_font_set_tex_gyre_sans_mono: + } + + +% Libertinus 的文件名在 v6.7 2019-04-03 从小写改为驼峰式, +% 在大小写敏感的平台上需要进行判断。 +\tl_new:N \g__examzh_font_font_family_libertinus_serif_tl +\tl_new:N \g__examzh_font_font_family_libertinus_sans_tl +\tl_new:N \g__examzh_font_font_style_libertinus_rm_tl +\tl_new:N \g__examzh_font_font_style_libertinus_bf_tl +\tl_new:N \g__examzh_font_font_style_libertinus_it_tl +\tl_new:N \g__examzh_font_font_style_libertinus_bfit_tl +\tl_new:N \g__examzh_font_font_name_libertinus_math_tl + +\cs_new:Npn \examzh_font_set_libertinus_names: + { + \tl_if_empty:NT \g__examzh_font_font_family_libertinus_serif_tl + { + \fontspec_font_if_exist:nTF { LibertinusSerif-Regular.otf } + { + \tl_gset:Nn \g__examzh_font_font_family_libertinus_serif_tl { LibertinusSerif } + \tl_gset:Nn \g__examzh_font_font_family_libertinus_sans_tl { LibertinusSans } + \tl_gset:Nn \g__examzh_font_font_style_libertinus_rm_tl { Regular } + \tl_gset:Nn \g__examzh_font_font_style_libertinus_bf_tl { Bold } + \tl_gset:Nn \g__examzh_font_font_style_libertinus_it_tl { Italic } + \tl_gset:Nn \g__examzh_font_font_style_libertinus_bfit_tl { BoldItalic } + \tl_gset:Nn \g__examzh_font_font_name_libertinus_math_tl { LibertinusMath-Regular } + } + { + \tl_gset:Nn \g__examzh_font_font_family_libertinus_serif_tl { libertinusserif } + \tl_gset:Nn \g__examzh_font_font_family_libertinus_sans_tl { libertinussans } + \tl_gset:Nn \g__examzh_font_font_style_libertinus_rm_tl { regular } + \tl_gset:Nn \g__examzh_font_font_style_libertinus_bf_tl { bold } + \tl_gset:Nn \g__examzh_font_font_style_libertinus_it_tl { italic } + \tl_gset:Nn \g__examzh_font_font_style_libertinus_bfit_tl { bolditalic } + \tl_gset:Nn \g__examzh_font_font_name_libertinus_math_tl { libertinusmath-regular } + } + } + } + +\cs_new:Npn \examzh_font_set_font_libertinus: + { + \examzh_font_set_libertinus_names: + \setmainfont { \g__examzh_font_font_family_libertinus_serif_tl } + [ + Extension = .otf , + UprightFont = *-\g__examzh_font_font_style_libertinus_rm_tl , + BoldFont = *-\g__examzh_font_font_style_libertinus_bf_tl , + ItalicFont = *-\g__examzh_font_font_style_libertinus_it_tl , + BoldItalicFont = *-\g__examzh_font_font_style_libertinus_bfit_tl , + ] + \setsansfont { \g__examzh_font_font_family_libertinus_sans_tl } + [ + Extension = .otf , + UprightFont = *-\g__examzh_font_font_style_libertinus_rm_tl , + BoldFont = *-\g__examzh_font_font_style_libertinus_bf_tl , + ItalicFont = *-\g__examzh_font_font_style_libertinus_it_tl , + ] + \setmonofont { lmmonolt10 } + [ + Extension = .otf , + UprightFont = *-regular , + BoldFont = *-bold , + ItalicFont = *-oblique , + BoldItalicFont = *-boldoblique , + ] + } + + +% 数学字体 + +% 按照国标样式配置 unicode-math + +\tl_new:N \l__examzh_save_leq_tl +\tl_new:N \l__examzh_save_geq_tl + +\AtEndOfPackageFile* { unicode-math } + { + \unimathsetup + { + math-style = ISO , + bold-style = ISO , + partial = upright , + } + \AtBeginDocument + { + \tl_set_eq:NN \leq \l__examzh_save_leq_tl + \tl_set_eq:NN \geq \l__examzh_save_geq_tl + \tl_set_eq:NN \leq \leqslant + \tl_set_eq:NN \geq \geqslant + } + \cs_set_protected:Npn \mathellipsis { \mathinner { \unicodecdots } } + } + + +% 数学符号样式 + +% \tl_new:N \l__examzh_font_uppercase_greek_tl +% \tl_new:N \l__examzh_font_leq_style_tl +\tl_new:N \l__examzh_font_integral_style_tl +% \bool_new:N \l__examzh_font_integral_limits_bool +% \tl_new:N \l__examzh_font_partial_style_tl +% \tl_new:N \l__examzh_font_math_ellipsis_tl +% \tl_new:N \l__examzh_font_real_part_tl + +\tl_set:Nn \l__examzh_font_integral_style_tl { upright } + +% \keys_define:nn { exam-zh } +% { +% math-style .choices:nn = +% { GB , ISO , TeX } +% { \exp_args:NV \examzh_font_set_math_style:n \l_keys_choice_tl } , +% uppercase-greek .choices:nn = +% { italic , upright } +% { \tl_set_eq:NN \l__examzh_font_uppercase_greek_tl \l_keys_choice_tl } , +% less-than-or-equal .choices:nn = +% { slanted , horizontal } +% { \tl_set_eq:NN \l__examzh_font_leq_style_tl \l_keys_choice_tl } , +% integral .choices:nn = +% { upright , slanted } +% { \tl_set_eq:NN \l__examzh_font_integral_style_tl \l_keys_choice_tl } , +% integral-limits .bool_set:N = \l__examzh_font_integral_limits_bool , +% partial .choices:nn = +% { upright , slanted } +% { \tl_set_eq:NN \l__examzh_font_partial_style_tl \l_keys_choice_tl } , +% math-ellipsis .choices:nn = +% { centered , lower , AMS } +% { \tl_set_eq:NN \l__examzh_font_math_ellipsis_tl \l_keys_choice_tl } , +% real-part .choices:nn = +% { roman , fraktur } +% { \tl_set_eq:NN \l__examzh_font_real_part_tl \l_keys_choice_tl } , +% } + + + +% New Computer Modern Math + +\tl_new:N \l__examzh_font_stylistic_set_tl + +\cs_new:Npn \examzh_font_set_math_font_newcm: + { + % \examzh_font_load_unimath: + % \examzh_font_set_unimath_style: + \tl_if_eq:NnTF \l__examzh_font_integral_style_tl { upright } + { \tl_set:Nn \l__examzh_font_stylistic_set_tl { 2 } } + { \tl_clear:N \l__examzh_font_stylistic_set_tl } + \setmathfont { NewCMMath-Book } + [ + Extension = .otf, + StylisticSet = \l__examzh_font_stylistic_set_tl , + ] + \setmathfont { NewCMMath-Book } + [ + Extension = .otf, + StylisticSet = 1, + range = { scr , bfscr } , + ] + \examzh_font_set_stix_names: + \setmathfont { \g__examzh_font_font_name_stix_math_tl } + [ + Extension = .otf, + range = { \complement } , + ] + \setmathrm { NewCM10 } + [ + Extension = .otf, + UprightFont = *-Book, + BoldFont = *-Bold, + ItalicFont = *-BookItalic, + BoldItalicFont = *-BoldItalic, + ] + \setmathsf { NewCMSans10 } + [ + Extension = .otf, + UprightFont = *-Book, + BoldFont = *-Bold, + ItalicFont = *-BookOblique, + BoldItalicFont = *-BoldOblique, + ] + \setmathtt { NewCMMono10 } + [ + Extension = .otf, + UprightFont = *-Book, + ItalicFont = *-BookItalic, + BoldFont = *-Bold, + BoldItalicFont = *-BoldOblique, + ] + } + + +% Latin Modern Math +\cs_new:Npn \examzh_font_set_math_font_lm: + { + % \examzh_font_load_unimath: + % \examzh_font_set_unimath_style: + \setmathfont { latinmodern-math } [ Extension = .otf ] + \examzh_font_set_stix_names: + \setmathfont { \g__examzh_font_font_name_stix_math_tl } + [ + Extension = .otf, + range = { \complement } , + ] + \setmathrm { lmroman10 } + [ + Extension = .otf, + UprightFont = *-regular, + BoldFont = *-bold, + ItalicFont = *-italic, + BoldItalicFont = *-bolditalic, + ] + \setmathsf { lmsans10 } + [ + Extension = .otf, + UprightFont = *-regular, + BoldFont = *-bold, + ItalicFont = *-oblique, + BoldItalicFont = *-boldoblique, + ] + \setmathtt { lmmonolt10 } + [ + Extension = .otf, + UprightFont = *-regular, + BoldFont = *-bold, + ItalicFont = *-oblique, + BoldItalicFont = *-boldoblique, + ] + } + + +% STIX Two Math +\cs_new:Npn \examzh_font_set_math_font_stix: + { + % \examzh_font_load_unimath: + % \examzh_font_set_unimath_style: + \examzh_font_set_stix_names: + \tl_if_eq:NnTF \l__examzh_font_integral_style_tl { upright } + { \tl_set:Nn \l__examzh_font_stylistic_set_tl { 8 } } + { \tl_clear:N \l__examzh_font_stylistic_set_tl } + \setmathfont { \g__examzh_font_font_name_stix_math_tl } + [ + Extension = .otf, + StylisticSet = \l__examzh_font_stylistic_set_tl, + ] + \setmathfont { \g__examzh_font_font_name_stix_math_tl } + [ + Extension = .otf, + StylisticSet = 1, + range = { scr , bfscr }, + ] + } + + +% XITS Math +\cs_new:Npn \examzh_font_set_math_font_xits: + { + % \examzh_font_load_unimath: + % \examzh_font_set_unimath_style: + \examzh_font_set_xits_names: + \tl_if_eq:NnTF \l__examzh_font_integral_style_tl { upright } + { \tl_set:Nn \l__examzh_font_stylistic_set_tl { 8 } } + { \tl_clear:N \l__examzh_font_stylistic_set_tl } + \setmathfont { \g__examzh_font_font_name_xits_math_tl } + [ + Extension = .otf , + StylisticSet = \l__examzh_font_stylistic_set_tl , + ] + \setmathfont { \g__examzh_font_font_name_xits_math_tl } + [ + Extension = .otf , + StylisticSet = 1 , + range = { cal , bfcal } , + ] + } + +% Libertinus Math +\cs_new:Npn \examzh_font_set_math_font_libertinus: { + % \examzh_font_load_unimath: + % \examzh_font_set_unimath_style: + \examzh_font_set_libertinus_names: + \tl_if_eq:NnTF \l__examzh_font_integral_style_tl { slanted } + { \tl_set:Nn \l__examzh_font_stylistic_set_tl { 8 } } + { \tl_clear:N \l__examzh_font_stylistic_set_tl } + \setmathfont { \g__examzh_font_font_name_libertinus_math_tl } + [ + Extension = .otf, + StylisticSet = \l__examzh_font_stylistic_set_tl, + ] + \examzh_font_set_stix_names: + \setmathfont { \g__examzh_font_font_name_stix_math_tl } + [ + Extension = .otf, + range = { \complement } , + ] +} + + +% Cambria Math +\cs_new:Npn \examzh_font_set_math_font_cambria: { + % \examzh_font_load_unimath: + % \examzh_font_set_unimath_style: + \setmathfont { Cambria~ Math } + \examzh_font_set_stix_names: + \setmathfont { \g__examzh_font_font_name_stix_math_tl } + [ + Extension = .otf, + range = { \complement } , + ] +} + + + +\AtEndPreamble + { + \tl_if_empty:NT \g__examzh_font_font_tl + { \keys_set:nn { exam-zh } { font = newcm } } + \tl_if_empty:NT \g__examzh_font_math_font_tl + { \keys_set:nn { exam-zh } { math-font = newcm } } + } + + +% unicode-math 的配置 + +% 兼容旧的粗体命令:\pkg{bm} 的 \cs{bm} 和 \pkg{amsmath} 的 \cs{boldsymbol}。 +\AtEndOfPackageFile* { unicode-math } + { + \NewDocumentCommand \bm { m } { { \symbfit { ##1 } } } + \RenewDocumentCommand \boldsymbol { m } { { \symbfit { ##1 } } } + % 兼容 \pkg{amsfonts} 和 \pkg{amssymb} 中的一些命令。 + \NewDocumentCommand \square { } { \mdlgwhtsquare } + \NewDocumentCommand \blacksquare { } { \mdlgblksquare } + \AtBeginDocument + { \RenewDocumentCommand \checkmark { } { \ensuremath{ ✓ } } } + } diff --git a/Master/texmf-dist/tex/latex/exam-zh/exam-zh-question.sty b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-question.sty new file mode 100644 index 00000000000..825a6ad991b --- /dev/null +++ b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-question.sty @@ -0,0 +1,1260 @@ +% +% Copyright (c) 2022 Zeping Lee +% Released under the LaTeX Project Public License v1.3c License. +% Repository: https://gitee.com/zepinglee/exam-zh +% + +\NeedsTeXFormat{LaTeX2e} + +\RequirePackage{expl3} +\RequirePackage{xparse} + +\ProvidesExplPackage {exam-zh-question} {2022-07-28} {v0.1.13} + {exam-zh question module} + +\RequirePackage { amsthm } +\@ifpackageloaded { tcolorbox } + { \tcbuselibrary { breakable } } + { \RequirePackage [ most ] { tcolorbox } } +\RequirePackage { zref-savepos } +\RequirePackage { ulem } + +\ExplSyntaxOff +\usetikzlibrary{shapes.misc} +\ExplSyntaxOn + + + +\NewDocumentCommand \questionsetup { m } + { \keys_set:nn { exam-zh / question } { #1 } } +\NewDocumentCommand \fillinsetup { m } + { \keys_set:nn { exam-zh / fillin } { #1 } } + +% ulem 宏包重定义了 \emph,使用 \normalem 恢复 +\normalem + + +% question 环境相关变量 + +% 计数器 +\int_new:N \g__examzh_question_index_int +% 答案颜色 +\tl_new:N \l__examzh_question_answer_color_tl +% 题目分数 +\int_new:N \l__examzh_question_points_int +% 是否显示题目分数 +\bool_new:N \l__examzh_question_show_points_bool +\bool_new:N \l__examzh_question_show_points_auto_bool +% 题目分数是否单独成段,解答题需要单独成段 +\bool_new:N \l__examzh_question_points_separate_par_bool +% 是否显示括号 +\bool_new:N \l__examzh_question_show_paren_bool +% 是否显示答案 +\bool_new:N \l__examzh_question_show_answer_bool +\bool_new:N \l__examzh_question_show_fillin_answer_bool +\bool_new:N \l__examzh_question_show_paren_answer_bool +% 上下的间距 +\skip_new:N \l__examzh_question_top_sep_skip +\skip_new:N \l__examzh_question_bottom_sep_skip +% label 的对齐 +\tl_new:N \l__examzh_question_label_align_tl + + +\keys_define:nn { exam-zh } + { question .meta:nn = { exam-zh / question } {#1} } + + +\keys_define:nn { exam-zh / question } + { + % 手动调整 question 环境的计数器 + index .int_gset:N = \g__examzh_question_index_int , + % 分数 + points .int_set:N = \l__examzh_question_points_int , + % 分数显示控制 + show-points .choice: , + show-points / auto .code:n = + { \bool_set_true:N \l__examzh_question_show_points_auto_bool } , + show-points / true .code:n = + { + \bool_set_true:N \l__examzh_question_show_points_bool + \bool_set_false:N \l__examzh_question_show_points_auto_bool + } , + show-points / false .code:n = + { + \bool_set_false:N \l__examzh_question_show_points_bool + \bool_set_false:N \l__examzh_question_show_points_auto_bool + } , + % 分数是否单独成段 + points-separate-par .bool_set:N = \l__examzh_question_points_separate_par_bool , + % 是否显示答案 + % show-answer .bool_set:N = \l__examzh_question_show_answer_bool , + show-answer .choice: , + show-answer / true .code:n = + { + \bool_set_true:N \l__examzh_question_show_fillin_answer_bool + \bool_set_true:N \l__examzh_question_show_paren_answer_bool + }, + show-answer / false .code:n = + { + \bool_set_false:N \l__examzh_question_show_fillin_answer_bool + \bool_set_false:N \l__examzh_question_show_paren_answer_bool + }, + % 上方间距 + top-sep .skip_set:N = \l__examzh_question_top_sep_skip , + % 下方间距 + bottom-sep .skip_set:N = \l__examzh_question_bottom_sep_skip , + label .tl_set:N = \l__examzh_question_label_tl, + combine-fillin .bool_set:N = \l__examzh_question_combine_fillin_bool, + combine-fillin-args .tl_set:N = \l__examzh_question_combine_fillin_args_tl, + label-align .choices:nn = + { left, center, right } + { \tl_set_eq:NN \l__examzh_question_label_align_tl \l_keys_choice_tl } + } + +\keys_set:nn { exam-zh / question } + { + index = 1, + points = 0 , + show-points = auto , + points-separate-par = false , + show-answer = false , + top-sep = .25em plus .25em minus .1em , + bottom-sep = .25em plus .25em minus .1em , + label = \arabic*., + combine-fillin = false, + label-align = right + } + + + +% 是否按照解答题的格式排版 +\bool_new:N \l__examzh_question_problem_style_bool + + +% 选择题和填空题的题干 +\NewDocumentEnvironment { question } { O { } +b } + { + \bool_set_false:N \l__examzh_question_problem_style_bool + \__examzh_question_begin:nn {#1}{#2} + } + { \__examzh_question_end:nn {#1}{#2} } + +% 解答题 +\NewDocumentEnvironment { problem } { O { } +b } + { + \bool_set_true:N \l__examzh_question_problem_style_bool + \__examzh_question_begin:nn {#1}{#2} + } + { \__examzh_question_end:nn {#1}{#2} } + +\prg_generate_conditional_variant:Nnn \int_compare:nNn { xNn } { T } +\cs_new:Npn \__examzh_question_begin:nn #1#2 + { + \par + % 根据是否按解答题方式排版来设置是否分数要分段 + \bool_if:NTF \l__examzh_question_problem_style_bool + { \keys_set:nn { exam-zh / question } { points-separate-par = true } } + { \keys_set:nn { exam-zh / question } { points-separate-par = false } } + % \bool_if:NTF \l__examzh_question_combine_fillin_bool + % { \keys_set:nn { exam-zh / question } { label-align = left } } + % { \keys_set:nn { exam-zh / question } { label-align = right } } + % 设置键值 + \keys_set:nn { exam-zh / question } { #1 } + % 题干计数器的值加一 + \int_gincr:N \g__examzh_question_index_int + % 设置上方间距 + % \addvspace { \l__examzh_question_top_sep_skip } + \vspace { \l__examzh_question_top_sep_skip } + % 严格禁止孤行和寡行 + \int_set:Nn \clubpenalty { 10000 } + \int_set:Nn \widowpenalty { 10000 } + % 尽量避免在题目中间换行 + \int_set:Nn \interlinepenalty { 301 } + % 这部分是仿照 source2e 中 enumerate 的定义写的 + % \@enumdepth 主要控制 enumerate 不同层级的编号 + % 这样设置后,在 question 中使用 enumerate 会调用 level 2 的编号 + % 也就是 question 中的 enumerate 环境直接从第二层开始 + \int_incr:N \@enumdepth + % 如果 show-points = auto 那么解答题显示分数,选择题和填空题不显示分数 + % 这样设置考虑到选择题和填空题都是每道题一样的分数,在最开始的地方说明即可 + % 而解答题不太一样 + \bool_if:NT \l__examzh_question_show_points_auto_bool + { + \bool_if:NTF \l__examzh_question_problem_style_bool + { \bool_set_true:N \l__examzh_question_show_points_bool } + { \bool_set_false:N \l__examzh_question_show_points_bool } + } + % 使用列表环境输出 + \list + { + % \int_use:N \g__examzh_question_index_int . + \__examzh_question_make_label:n + { + \bool_if:NT \l__examzh_question_combine_fillin_bool + { + \tl_if_blank:VTF \l__examzh_question_combine_fillin_args_tl + { \fillin } + { + \use:x + { + \exp_not:N \fillin \l__examzh_question_combine_fillin_args_tl + } + } + } + \int_compare:xNnT { \g__examzh_question_index_int } < { 11 } + { \phantom {1} } + \__examzh_question_the_label: + } + } + { + % 用 group 是为了防止 combine-fillin 的 type 影响了环境里面的 fillin 的type + \group_begin: + \dim_gset:Nn \topsep { 0pt } + \dim_gset:Nn \partopsep { 0pt } + \dim_gset:Nn \itemsep { 0pt } + \dim_gset:Nn \parsep { 0pt } + % \group_begin: + % 上面 \fillin 里面的设置是局部的,这样的问题是 question 的可选参数改 type 的时候不会影响 \l__examzh_fillin_type_str 的值 + % 所以要把 \l__examzh_question_combine_fillin_args_tl 里关于 type 的选取出来 + \__examzh_question_begin_fillin_type_set: + \__examzh_question_begin_labelsep_labelwidth_set: + % \group_end: + \bool_if:NTF \l__examzh_question_problem_style_bool + { + % 解答题是正文 + 缩进 2em 的效果 + \bool_if:NTF \l__examzh_question_combine_fillin_bool + { + % 如果 combine 的话就和 question 一样的缩进 + \dim_gset:Nn \leftmargin { 6em } + \dim_gset:Nn \itemindent { 0pt } + } + { + \dim_gset:Nn \leftmargin { 0pt } + \dim_gset:Nn \itemindent { 2em } + } + } + { + % 选择和填空题是悬挂效果 + \bool_if:NTF \l__examzh_question_combine_fillin_bool + % { + % \str_case:VnF \l__examzh_question_label_align_tl + % { + % { left } { \dim_set:Nn \leftmargin { 8em } } + % } + { \dim_gset:Nn \leftmargin { 6em } } + % } + { \dim_gset:Nn \leftmargin { 2em } } + \dim_set:Nn \itemindent { 0pt } + } + \dim_gset_eq:NN \listparindent \itemindent + \group_end: + } + \item \relax + % 输出题目分数 + \bool_if:NT \l__examzh_question_show_points_bool + { + % 如果设置了分数且 show-points 的 bool 是 true 的话就显示 + \int_compare:nNnT { \l__examzh_question_points_int } > { 0 } + { ( \int_use:N \l__examzh_question_points_int ~ 分 ) } + % 是否分段(解答题需要分段) + \bool_if:NT \l__examzh_question_points_separate_par_bool + % \par 分段之后使用 \nopagebreak 避免分页导致序号和分数出现在页面最后一行 + { \par \nopagebreak } + } + } +\int_new:N \l__examzh_question_begin_fillin_args_bracket_num_int +\cs_generate_variant:Nn \regex_count:nnN { nVN } +\prg_generate_conditional_variant:Nnn \regex_extract_once:nnN { nxN } { F } +\cs_new:Npn \__examzh_question_begin_fillin_type_set: + { + \regex_count:nVN { \[ } %] + \l__examzh_question_combine_fillin_args_tl + \l__examzh_question_begin_fillin_args_bracket_num_int + % \int_use:N \l__examzh_question_begin_fillin_args_bracket_num_int + \int_compare:nNnT { \l__examzh_question_begin_fillin_args_bracket_num_int } = {2} + { + \regex_extract_once:nxNF { \[ (.*?) \] } { \l__examzh_question_combine_fillin_args_tl } \l_tmpa_seq { \fail } + \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl + % \seq_use:Nn \l_tmpa_seq {,} + \keys_set:nx { exam-zh / fillin } { \seq_use:Nn \l_tmpa_seq {,} } + } + } +\cs_new:Npn \__examzh_question_begin_labelsep_labelwidth_set: + { + \bool_if:NTF \l__examzh_question_combine_fillin_bool + { + \str_case:Vn \l__examzh_question_label_align_tl + { + { left } + { + \str_case:VnF \l__examzh_fillin_type_str + { + { paren } + { + % combin-left-paren + \dim_gset:Nn \labelsep { 2.8em } + \dim_gset:Nn \labelwidth { 4.2em } + } + { line } + { + % combin-left-line + \dim_gset:Nn \labelsep { 2.4em } + \dim_gset:Nn \labelwidth { 3.8em } + } + } + { + % combin-left-paren/line 外的 + \dim_gset:Nn \labelsep { 2.8em } + \dim_gset:Nn \labelwidth { 1.3em } + } + } + { center } + { + \str_case:VnF \l__examzh_fillin_type_str + { + { paren } + { + % combin-center-paren + \dim_gset:Nn \labelsep { 2em } + \dim_gset:Nn \labelwidth { 5em } + } + { line } + { + % combin-center-line + \dim_gset:Nn \labelsep { 2.8em } + \dim_gset:Nn \labelwidth { 4em } + } + } + { + % combin-center-paren/line 外的 + \dim_gset:Nn \labelsep { 2em } + \dim_gset:Nn \labelwidth { 1.3em } + } + } + { right } + { + \dim_gset:Nn \labelsep { .7em } + \dim_gset:Nn \labelwidth { 1.3em } + } + } + } + { + \str_case:Vn \l__examzh_question_label_align_tl + { + { left } + { + \dim_gset:Nn \labelsep { .7em } + \dim_gset:Nn \labelwidth { 1.8em } + } + { center } + { + \dim_gset:Nn \labelsep { .7em } + \dim_gset:Nn \labelwidth { 1.3em } + } + { right } + { + \dim_gset:Nn \labelsep { .7em } + \dim_gset:Nn \labelwidth { 1.3em } + } + } + + } + } + +\cs_new:Npn \__examzh_question_end:nn #1#2 + { + #2 + % 结束列表环境 + \endlist + % 增加下方间距 + % \addvspace { \l__examzh_question_bottom_sep_skip } + \vspace { \l__examzh_question_bottom_sep_skip } + } + +% 处理 question / problem 的 label +\tl_new:N \l__examzh_question_counters_commands_set_tl + +\cs_new:Npn \__examzh_question_the_label: + { + \group_begin: + % 定义计数器相关的命令函数 + \l__examzh_question_counters_commands_set_tl + % 输出处理后的 label + \l__examzh_question_label_tl + \group_end: + } +\cs_new:Npn \__examzh_question_make_label:n #1 + { + \str_case:Vn \l__examzh_question_label_align_tl + { + { left } { \rlap { #1 } \hss } + { center } { \hss \clap { #1 } \hss } + { right } { \hss \llap { #1 } } + } + } +\NewDocumentCommand \AddQuestionCounter { m m } + { + % 生成用户层命令 + \tl_put_right:Nn \l__examzh_question_counters_commands_set_tl + { \__examzh_process_counter:NNn #1 #2 { question } } + % 把核心函数存起来 + \cs_set_eq:cN { __examzh_question_save_ \cs_to_str:N #1 : } #2 + \cs_set_eq:cN { __examzh_question_save_ \cs_to_str:N #2 : } #2 + } + +\AddQuestionCounter \arabic \@arabic +\AddQuestionCounter \alph \@alph +\AddQuestionCounter \Alph \@Alph +\AddQuestionCounter \roman \@roman +\AddQuestionCounter \Roman \@Roman + +\cs_new:Npn \__examzh_process_counter:NNn #1#2#3 + % #1: \Alph + % #2: \@Alph + % #3: question / fillin + { + \cs_set:Npn #1 { \use:c { __examzh_ #3 _process_counter_aux:Nn } #2 } + \cs_set:Npn #2 { \use:c { __examzh_ #3 _process_counter_aux:Nn } #2 } + } + +\cs_new:Npn \__examzh_question_process_counter_aux:Nn #1#2 + { + \tl_if_eq:nnTF {#2} { * } + { + % \Alph* + \use:c { __examzh_question_save_ \cs_to_str:N #1 : } + { \int_eval:n { \g__examzh_question_index_int - 1 } } + } + { + % \Alph{...} + \use:c { __examzh_question_save_ \cs_to_str:N #1 : } + {#2} + } + } + + +% 处理 fillin/no-answer-type = counter 的 label +\tl_new:N \l__examzh_fillin_counters_commands_set_tl + + +\cs_new:Npn \__examzh_fillin_the_label: + { + \group_begin: + % 定义计数器相关的命令函数 + \l__examzh_fillin_counters_commands_set_tl + % 输出处理后的 label + \l__examzh_fillin_label_tl + \group_end: + } + +\NewDocumentCommand \AddFillinCounter { m m } + { + % 生成用户层命令 + \tl_put_right:Nn \l__examzh_fillin_counters_commands_set_tl + { \__examzh_process_counter:NNn #1 #2 { fillin } } + % 把核心函数存起来 + \cs_set_eq:cN { __examzh_fillin_save_ \cs_to_str:N #1 : } #2 + \cs_set_eq:cN { __examzh_fillin_save_ \cs_to_str:N #2 : } #2 + } + +\AddFillinCounter \arabic \@arabic +\AddFillinCounter \alph \@alph +\AddFillinCounter \Alph \@Alph +\AddFillinCounter \roman \@roman +\AddFillinCounter \Roman \@Roman + +\cs_new:Npn \__examzh_fillin_process_counter_aux:Nn #1#2 + { + \tl_if_eq:nnTF {#2} { * } + { + % \Alph* + \use:c { __examzh_fillin_save_ \cs_to_str:N #1 : } + { \int_eval:n { \g__examzh_fillin_no_answer_counter_int - 1 } } + } + { + % \Alph{...} + \use:c { __examzh_fillin_save_ \cs_to_str:N #1 : } + {#2} + } + } + +% 使用中文字体直接输出 unicode 带圈数字 +% \circlednumber 的参数既可以接受 LaTeX2e 的 <counter>,也可以直接接受 <intexpr>。 +\NewDocumentCommand \circlednumber { s m } + { + \int_if_exist:cTF { c@ #2 } + { \int_set_eq:Nc \l_tmpa_int { c@#2 } } + { \int_set:Nn \l_tmpa_int { #2 } } + \IfBooleanTF {#1} + { + \exp_args:Nx \__examzh_tikz_circled_number:n { \int_use:N \l_tmpa_int } + } + { + \exp_args:Nx \__examzh_question_circled_number:n { \int_use:N \l_tmpa_int } + } + } + +\cs_new:Npn \__examzh_circled_number:nn #1#2 + { + \int_set:Nn \l_tmpa_int {#1} + \int_compare:nNnTF { \l_tmpa_int } = { 0 } + { \int_set:Nn \l_tmpa_int { "24EA } } + { + \int_compare:nNnTF { \l_tmpa_int } < { 21 } + { \int_add:Nn \l_tmpa_int { "245F } } + { + \int_compare:nNnTF { \l_tmpa_int } < { 36 } + { \int_add:Nn \l_tmpa_int { "3250 } } + { + \int_compare:nNnTF { \l_tmpa_int } < { 51 } + { \int_add:Nn \l_tmpa_int { "32B0 } } + { + \msg_error:nnn { exam-zh / #2 } + { invalid-circled-number } { \int_use:N \l_tmpa_int } + } + } + } + } + \group_begin: + \CJKfamily+ { } + \symbol { \l_tmpa_int } + \group_end: + } + +\msg_new:nnn { exam-zh / question } { invalid-circled-number } +{ Invalid~ circled~ number~ #1. } + +\msg_new:nnn { exam-zh / fillin } { invalid-circled-number } +{ Invalid~ circled~ number~ #1. } + +\cs_new:Npn \__examzh_question_circled_number:n #1 + { \__examzh_circled_number:nn {#1} { question } } +\cs_new:Npn \__examzh_fillin_circled_number:n #1 + { \__examzh_circled_number:nn {#1} { fillin } } + +\AddQuestionCounter \circlednumber \__examzh_question_circled_number:n +\AddFillinCounter \circlednumber \__examzh_fillin_circled_number:n + +% tikz 绘制带圈数字 +\fp_new:N \l__examzh_tikz_circled_number_xscale_fp % 水平压缩系数 +\fp_new:N \l__examzh_tikz_circled_number_yscale_fp % 垂直压缩系数 +\dim_new:N \l__examzh_tikz_circled_number_total_hegiht_dim % 数字的总高度 +\dim_new:N \l__examzh_tikz_circled_number_radius_dim % 半径 + +\cs_new:Npn \__examzh_tikz_circled_number_aux:n #1 + { + % 根据数字大小设置压缩系数 + \fp_set:Nn \l__examzh_tikz_circled_number_xscale_fp + { + \int_compare:nNnTF {#1} < { 10 } + { 0.9 } + { + \int_compare:nNnTF {#1} < { 100 } + { 0.7 } + { 0.5 } + } + } + \fp_set:Nn \l__examzh_tikz_circled_number_yscale_fp + { + \int_compare:nNnTF {#1} < { 10 } + { 0.9 } + { + \int_compare:nNnTF {#1} < { 100 } + { 0.8 } + { 0.6 } + } + } + % 获取数字的高度 + \hbox_set:Nn \l_tmpa_box {#1} + \dim_set:Nn \l__examzh_tikz_circled_number_total_hegiht_dim + { \box_ht:N \l_tmpa_box + \box_dp:N \l_tmpa_box } + % 设置圆的半径 + \dim_set:Nn \l__examzh_tikz_circled_number_radius_dim + { \dim_eval:n { \l__examzh_tikz_circled_number_total_hegiht_dim / 2 + 0.34 ex } } + % 绘制 + \tikz [ baseline ] + { + \node + [ inner~sep = 0pt, outer~sep = 0pt ] + at (0, \dim_use:N \l__examzh_tikz_circled_number_total_hegiht_dim / 2 ) + { + \hbox_set:Nn \l_tmpa_box + { + \int_compare:nNnTF {#1} > {9} + { \textbf {#1} } + {#1} + } + \makebox[0.35em][c] + { + % \scalebox { \fp_use:N \l__examzh_tikz_circled_number_xscale_fp } + % [ \fp_use:N \l__examzh_tikz_circled_number_yscale_fp ] + \box_scale:Nnn \l_tmpa_box + { \fp_use:N \l__examzh_tikz_circled_number_xscale_fp } + { \fp_use:N \l__examzh_tikz_circled_number_yscale_fp } + \box_use_drop:N \l_tmpa_box + } + }; + \draw (0, \l__examzh_tikz_circled_number_total_hegiht_dim / 2 ) + circle ( \l__examzh_tikz_circled_number_radius_dim ); + } + } +\cs_new:Npn \__examzh_tikz_circled_number:n #1 + { + \__examzh_tikz_circled_number_aux:n { \int_eval:n {#1} } + } +\AddQuestionCounter \tikzcirclednumber \__examzh_tikz_circled_number:n +\AddFillinCounter \tikzcirclednumber \__examzh_tikz_circled_number:n + +% 选择题括号 +% 控制括号是否右对齐 +\bool_new:N \l__examzh_paren_type_hfill_bool +\keys_define:nn { exam-zh / paren } + { + show-answer .bool_set:N = \l__examzh_question_show_paren_answer_bool, + text-color .tl_set:N = \l__examzh_paren_text_color_tl , + % 是否显示选择题的括号 + show-paren .bool_set:N = \l__examzh_question_show_paren_bool , + type .choice:, + type / hfill .code:n = + { + \bool_set_true:N \l__examzh_paren_type_hfill_bool + }, + type / none .code:n = + { + \bool_set_false:N \l__examzh_paren_type_hfill_bool + }, + } +\keys_set:nn { exam-zh / paren } + { + show-answer = false, + text-color = black, + show-paren = false, + type = hfill + } +\keys_define:nn { exam-zh } + { paren .meta:nn = { exam-zh / paren } {#1} } +\NewDocumentCommand \paren { O { } } + { + % 如果开了 show answer 就默认 show paren + \bool_if:NT \l__examzh_question_show_paren_answer_bool + { \bool_set_true:N \l__examzh_question_show_paren_bool } + \bool_if:NT \l__examzh_question_show_paren_bool + { + % 使括号单独成行时居于右侧 + % \null -> \hbox{} + % 𝖅𝖊𝖕𝖎𝖓𝖌 𝕷𝖊𝖊, [Mar 19, 2022 at 22:47:07]: + % 这个写法是为了处理这样的情况:假设括号需要 3em 宽度,但是如果题干末尾只剩下了 2em 的空白,括号就必要另起一行,并且用 \hill 把括号推到最右侧 + % 所以中间用了两个 \hfill + % 至于 \nobreak 和 \allowbreak 大概是为了能够同时处理「括号不换行」和「括号换行」两种情况 + % 这里参考 source2e 的 \@dottedtocline(目录的格式) + % 控制是否 hfill 到行尾 + \bool_if:NT \l__examzh_paren_type_hfill_bool + { + \nobreak \hfill \allowbreak + \null \nobreak \hfill \nobreak + } + \hbox:n + { + ( + \hbox_to_wd:nn { 3em } + { + \bool_if:NT \l__examzh_question_show_paren_answer_bool + { \hfill \__examzh_paren_print_answer:n {#1} \hfill } + } + ) \kern -.4em + } + } + } +% “打印出”答案内容 因为 show 被用作“显示与否”的含义了,所以此处用 print +\cs_new:Npn \__examzh_fillin_print_answer:n #1 + { + % \group_begin: + \tl_if_eq:NnF \l__examzh_fillin_text_color_tl { black } + { \exp_args:NV \color \l__examzh_fillin_text_color_tl } + #1 + % \group_end: + } +\cs_new:Npn \__examzh_paren_print_answer:n #1 + { + \group_begin: + \tl_if_eq:NnF \l__examzh_paren_text_color_tl { black } + { \exp_args:NV \color \l__examzh_paren_text_color_tl } + #1 + \group_end: + } + + +% fillin 的下划线样式控制 +\str_new:N \l__examzh_fillin_type_str + +% 不显示答案时显示的类型 +\str_new:N \l__examzh_fillin_no_answer_type_str + +% no-answer-type = counter 的计数器 +\int_new:N \g__examzh_fillin_no_answer_counter_int + +\keys_define:nn { exam-zh / fillin } + { + type .code:n = + { + \str_set:Nn \l__examzh_fillin_type_str {#1} + }, + show-answer .bool_set:N = \l__examzh_question_show_fillin_answer_bool, + width .skip_set:N = \l__examzh_fillin_F_width_skip, + color .tl_set:N = \l__examzh_fillin_color_tl, + text-color .tl_set:N = \l__examzh_fillin_text_color_tl, + no-answer-type .choices:nn = + { blacktriangle, counter, none } + { \str_set:Nx \l__examzh_fillin_no_answer_type_str { \l_keys_choice_tl } }, + no-answer-counter-index .int_gset:N = \g__examzh_fillin_no_answer_counter_int, + no-answer-counter-label .tl_set:N = \l__examzh_fillin_label_tl + } +\keys_set:nn { exam-zh / fillin } + { + type = line, + show-answer = false, + width = 3em plus 1em minus 1em, + color = black, + text-color = black, + no-answer-type = blacktriangle, + no-answer-counter-index = 1, + no-answer-counter-label = \arabic* + } + +\keys_define:nn { exam-zh } + { fillin .meta:nn = { exam-zh / fillin } {#1} } + + +\dim_new:N \l__examzh_question_answer_depth_dim + +% 填空命令 +% \fillin \fillin[] \fillin[][] 在 show-answer = false 的情况下 +% no-answer-type = blacktriangle 就显示黑色三角形 +% no-answer-type = counter :计数器(设计来源于完形填空) +% no-answer-type = none :不显示 +\NewDocumentCommand \fillin { s O{} o } + { + \group_begin: + \IfNoValueTF {#3} + { + \bool_if:NTF \l__examzh_question_show_fillin_answer_bool + { + % 显示答案 + \IfBooleanTF {#1} + { + % \fillin*[] + \__examzh_fillin_breakline:n {#2} + } + { + % \fillin[] + \__examzh_fillin:n {#2} + } + } + { + % 不显示答案 + \__examzh_fillin_no_answer_typeset: + } + } + { + \keys_set:nn { exam-zh / fillin } + {#2} + \bool_if:NTF \l__examzh_question_show_fillin_answer_bool + { + % 显示答案 + \IfBooleanTF {#1} + { + % \fillin*[][] + \__examzh_fillin_breakline:n {#3} + } + { + % \fillin[][] + \__examzh_fillin:n {#3} + } + } + { + % 不显示答案 + \__examzh_fillin_no_answer_typeset: + } + } + \group_end: + \space \ignorespaces + } +\msg_new:nnn { exam-zh / fillin } { no-such-noanswertype } + { + There~is~no~such~noanswertype~named~#1!\\ + Please~read~the~manual~carefully! + } +\cs_new:Npn \__examzh_fillin_no_answer_typeset: + { + \str_case:VnF \l__examzh_fillin_no_answer_type_str + { + { blacktriangle } { \__examzh_fillin_no_answer_typeset_blacktriangle: } + { counter } { \__examzh_fillin_no_answer_typeset_counter: } + { none } { \__examzh_fillin_no_answer_typeset_none: } + } + { + \msg_error:nnx { exam-zh / fillin } { no-such-noanswertype } + { \l__examzh_fillin_no_answer_type_str } + } + } +\cs_new:Npn \__examzh_fillin_no_answer_typeset_blacktriangle: + { + \__examzh_fillin_without_judge:n { \__examzh_fillin_blacktriangle: } + } +\cs_new:Npn \__examzh_fillin_no_answer_typeset_counter: + { + \int_gincr:N \g__examzh_fillin_no_answer_counter_int + \__examzh_fillin_without_judge:n + { \__examzh_fillin_the_label: } + % { \int_eval:n { \g__examzh_fillin_no_answer_counter_int - 1 } } + } +\cs_new:Npn \__examzh_fillin_no_answer_typeset_none: + { + \__examzh_fillin_output_F: + } +\cs_new:Npn \__examzh_fillin_without_judge:n #1 + { + % \ULdepth 是 \uline 的下划线的深度 + \dim_set:Nn \ULdepth { 0.3em } + % lazy 版本是指需要判断时才去获取当前用于判断的 bool 值 + % 而不是类似于“提前展开”,和项子越在 LaTeX3 的 b站视频里讲到的 lazy evaluation 想法相同 + \hbox_set:Nn \l_tmpa_box { \__examzh_fillin_print_answer:n {#1} } + \dim_set:Nn \l__examzh_question_answer_depth_dim + { \box_dp:N \l_tmpa_box } + \__examzh_fillin_output_T: + } +\cs_new:Npn \__examzh_fillin:n #1 + { + % \ULdepth 是 \uline 的下划线的深度 + \dim_set:Nn \ULdepth { 0.3em } + % lazy 版本是指需要判断时才去获取当前用于判断的 bool 值 + % 而不是类似于“提前展开”,和项子越在 LaTeX3 的 b站视频里讲到的 lazy evaluation 想法相同 + \bool_lazy_and:nnTF + { \bool_if_p:N \l__examzh_question_show_fillin_answer_bool } + { \bool_not_p:n { \tl_if_empty_p:n {#1} } } + { + \hbox_set:Nn \l_tmpa_box { \__examzh_fillin_print_answer:n {#1} } + \dim_set:Nn \l__examzh_question_answer_depth_dim + { \box_dp:N \l_tmpa_box } + \__examzh_fillin_output_T: + } + { + \__examzh_fillin_output_F: + } + } +\cs_new:Npn \__examzh_fillin_breakline:n #1 + { + \bool_lazy_and:nnTF + { \bool_if_p:N \l__examzh_question_show_fillin_answer_bool } + { \bool_not_p:n { \tl_if_empty_p:n {#1} } } + { + \tl_set:Nn \l_tmpa_tl { \__examzh_fillin_print_answer:n {#1} } + \__examzh_fillin_output_breakline_T: + } + { + \__examzh_fillin_output_F: + } + } +\msg_new:nnn { exam-zh } { no-fillin-type } + { + There~is~no~type~of~\fillin~named~#1!\\ + Please~read~the~manual~for~more~details. + } +\cs_new:Npn \__examzh_fillin_output_T: + { + \str_case:VnF \l__examzh_fillin_type_str + { + { line } { \__examzh_fillin_uline_T: } + { paren } { \__examzh_fillin_paren_T: } + { circle } { \__examzh_fillin_circle_T: } + { blank } { \__examzh_fillin_blank_T: } + { rectangle } { \__examzh_fillin_rectangle_T: } + } + { + \msg_error:nnx { exam-zh } { no-fillin-type } + { \l__examzh_fillin_type_str } + } + } +\cs_new:Npn \__examzh_fillin_output_breakline_T: + { + \str_case:VnF \l__examzh_fillin_type_str + { + { line } { \__examzh_fillin_uline_breakline_T: } + { paren } { \__examzh_fillin_paren_breakline_T: } + { blank } { \__examzh_fillin_blank_breakline_T: } + } + { + \msg_error:nnx { exam-zh } { no-breakable-fillin-type } + { \l__examzh_fillin_type_str } + } + } +\msg_new:nnn { exam-zh } { no-breakable-fillin-type } + { + The~type~:~#1~ cannot~be~used~in~breakable~fillin~cmd. + } +\cs_new:Npn \__examzh_fillin_output_F: + { + \str_case:VnF \l__examzh_fillin_type_str + { + { line } { \__examzh_fillin_uline_F: } + { paren } { \__examzh_fillin_paren_F: } + { circle } { \__examzh_fillin_circle_F: } + { blank } { \__examzh_fillin_blank_F: } + { rectangle } { \__examzh_fillin_rectangle_F: } + } + { + \msg_error:nnx { exam-zh } { no-fillin-type } + { \l__examzh_fillin_type_str } + } + } +\cs_new:Npn \__examzh_fillin_uline_T: + { + \uline + { + \hspace* { 0.5em plus .5em minus .5em } + \dim_compare:nNnTF { \l__examzh_question_answer_depth_dim } > { 0.2em } + { + \dim_sub:Nn \l__examzh_question_answer_depth_dim { 0.2em } + \raisebox { \l__examzh_question_answer_depth_dim } + { \box_use_drop:N \l_tmpa_box } + } + { \box_use_drop:N \l_tmpa_box } + \hspace* { 0.5em plus .5em minus .5em } + } + } +\cs_new:Npn \__examzh_fillin_uline_F: + { + \uline { \hspace* { \l__examzh_fillin_F_width_skip } } + } +\cs_new:Nn \__examzh_fillin_uline: + { + \bgroup + \color{ \l__examzh_fillin_text_color_tl } + \markoverwith{\textcolor{black}{\rule[-0.7ex]{2pt}{0.4pt}}} + \ULon + } +\cs_new:Npn \__examzh_fillin_uline_breakline_T: + { + % \CJKunderline* + % \uline + \__examzh_fillin_uline: + { + \hspace* { 0.5em plus .5em minus .5em } + \l_tmpa_tl + % 答案很长时,不能完全显示,答案很长时,不能完全显示 + \hspace* { 0.5em plus .5em minus .5em } + } + } +\cs_new:Npn \__examzh_fillin_paren_T: + { + ( + \hspace* { 0.5em plus .5em minus .5em } + \group_begin: + \box_use_drop:N \l_tmpa_box + \group_end: + \hspace* { 0.5em plus .5em minus .5em } + ) + } +\cs_new:Npn \__examzh_fillin_paren_breakline_T: + { + ( + \hspace* { 0.5em plus .5em minus .5em } + \group_begin: + \l_tmpa_tl + \group_end: + \hspace* { 0.5em plus .5em minus .5em } + ) + } +\cs_new:Npn \__examzh_fillin_paren_F: + { + ( \hspace* { \l__examzh_fillin_F_width_skip} ) + } +\cs_new:Npn \__examzh_fillin_blank_T: + { + \hspace* { 0.5em plus .5em minus .5em } + \group_begin: + \box_use_drop:N \l_tmpa_box + \group_end: + \hspace* { 0.5em plus .5em minus .5em } + } +\cs_new:Npn \__examzh_fillin_blank_breakline_T: + { + \hspace* { 0.5em plus .5em minus .5em } + \group_begin: + \l_tmpa_tl + \group_end: + \hspace* { 0.5em plus .5em minus .5em } + } +\cs_new:Npn \__examzh_fillin_blank_F: + { + \hspace* { \l__examzh_fillin_F_width_skip } + } +\tikzset + { + fillin-circle/.style = + { + rounded~rectangle~west~arc = convex, + draw, rounded~rectangle, + color = \l__examzh_fillin_color_tl, text = \l__examzh_fillin_text_color_tl + } + } +\cs_new:Npn \__examzh_fillin_circle_T: + { + \hspace* { .5em minus .5em } + \tikz[baseline=-3pt] + { + \node [fillin-circle] at (0,0) + { \box_use_drop:N \l_tmpa_box }; + } + \hspace* { .5em minus .5em } + } +\cs_new:Npn \__examzh_fillin_circle_F: + { + \hspace* { 0.5em plus .5em minus .5em } + \tikz[baseline=-3pt] + { + \node [fillin-circle] at (0,0) + { \phantom{t} }; + } + \hspace* { 0.5em plus .5em minus .5em } + } +\cs_new:Npn \__examzh_fillin_rectangle_T: + { + \hspace* { .5em minus .5em } + \begin{tikzpicture}[baseline = -3pt] + \node[draw, color = \l__examzh_fillin_color_tl, text = \l__examzh_fillin_text_color_tl] + { \box_use_drop:N \l_tmpa_box }; + \end{tikzpicture} + \hspace* { .5em minus .5em } + } +\cs_new:Npn \__examzh_fillin_rectangle_F: + { + \hspace* { 0.5em plus .5em minus .5em } + \begin{tikzpicture}[baseline = -3pt] + \node[draw, color = \l__examzh_fillin_color_tl, text = \l__examzh_fillin_text_color_tl] + { \phantom{a} }; + \end{tikzpicture} + \hspace* { 0.5em plus .5em minus .5em } + } + + +\dim_new:N \l__examzh_blacktriangle_length_dim +\dim_set:Nn \l__examzh_blacktriangle_length_dim { .7em } +\cs_new:Npn \__examzh_fillin_blacktriangle: + { + \tikz[rounded~corners=0.5pt,baseline=0pt] + { + \fill[] (0,0) -- ++(60\c_colon_str \l__examzh_blacktriangle_length_dim) -- ++(-60\c_colon_str \l__examzh_blacktriangle_length_dim) -- cycle ; + } + } + +\str_new:N \l__examzh_solution_blank_type_str +\keys_define:nn { exam-zh / solution } + { + show-solution .bool_set:N = \l__examzh_solution_show_bool, + show-qed .bool_set:N = \l__examzh_solution_show_qed_bool, + qedsymbol .tl_set:N = \l__examzh_solution_qedsymbol_tl, + label-content .tl_set:N = \l__examzh_solution_label_content_tl, + label-punct .tl_set:N = \l__examzh_solution_label_punct_tl, + score-showleader .bool_set:N = \l__examzh_score_show_leader_bool, + score-pre-content .tl_set:N = \l__examzh_score_pre_content_tl, + score-post-content .tl_set:N = \l__examzh_score_post_content_tl, + score-format .tl_set:N = \l__examzh_score_format_tl, + text-color .tl_set:N = \l__examzh_solution_text_color_tl, + blank-type .choices:nn = + { none, manual, hide } + { + \str_set:Nx \l__examzh_solution_blank_type_str { \l_keys_choice_tl } + }, + blank-vsep .skip_set:N = \l__examzh_solution_blank_vsep_skip, + top-sep .skip_set:N = \l__examzh_solution_top_sep_skip, + bottom-sep .skip_set:N = \l__examzh_solution_bottom_sep_skip, + parbreak .bool_set:N = \l__examzh_solution_par_break_bool, + } +\keys_set:nn { exam-zh / solution } + { + show-solution = false, + show-qed = true, + qedsymbol = $\square$, + label-content = {解答}, + label-punct = {}, + score-showleader = true, + score-pre-content = {}, + score-post-content = 分, + score-format = \color{red}, + text-color = black, + blank-type = none, + blank-vsep = 12ex plus 1ex minus 1ex, + top-sep = .25em plus .25em minus .1em, + bottom-sep = 0pt, + parbreak = false + } +\keys_define:nn { exam-zh } + { solution .meta:nn = { exam-zh / solution } {#1} } +% 解答题环境 +\NewDocumentEnvironment { solution } { O{ } +b } + { + % \addvspace { \l__examzh_solution_top_sep_skip } + \vspace { \l__examzh_solution_top_sep_skip } + \keys_set:nn { exam-zh / solution } {#1} + % 放在这是使得 \examsetup 设置 qedsymbol 可以放在正文区 + \cs_set_eq:NN \qedsymbol \l__examzh_solution_qedsymbol_tl + \bool_if:NTF \l__examzh_solution_show_bool + { + \__examzh_solution_print_answer:n {#2} + } + { + \str_case:VnF \l__examzh_solution_blank_type_str + { + { none } { } + { manual } { \addvspace { \l__examzh_solution_blank_vsep_skip } } + { hide } { \__examzh_solution_simply_hide_solution:n {#2} } + } + {} + } + \par + % \mode_leave_vertical: + % \addvspace { \l__examzh_solution_bottom_sep_skip } + \vspace { \l__examzh_solution_bottom_sep_skip } + } + {} +\cs_new:Npn \__examzh_solution_simply_hide_solution:n #1 + { + \begin{tcolorbox} + [ + invisible, + frame~hidden, + breakable, + opacityback = 0, + opacityframe = 0, + size = minimal, + width = \linewidth + ] + #1 + \end{tcolorbox} + } +\cs_new:Npn \__examzh_solution_print_answer:n #1 + { + \par + \pushQED { \qed } + % \normalfont \topsep6 \p@ \@plus6 \p@ \relax + % \trivlist + % \item \relax + \group_begin: + % \hspace* { 2\ccwd } + \bfseries \l__examzh_solution_label_content_tl + \@addpunct { \l__examzh_solution_label_punct_tl } + \group_end: + \hspace{0.5em} + % \ignorespaces + % 是否要新起一段开始 + \bool_if:NT \l__examzh_solution_par_break_bool { \par } + \group_begin: + \color { \l__examzh_solution_text_color_tl } #1 + \group_end: + \bool_if:NT \l__examzh_solution_show_qed_bool + { \popQED } + % \endtrivlist + % \@endpefalse + } + +% https://github.com/CTeX-org/forum/issues/256#issuecomment-1172319787 +\zref@require@unique + +\NewDocumentCommand { \score } { O{} m } + { + \group_begin: + \mode_if_math:TF + { + \__examzh_score_math_version:n { #2 } + } + { + \__examzh_score_text_version:n { #2 } + } + \group_end: + } +\cs_new:Npn \__examzh_score_math_version:n #1 + { + \bool_if:NTF \l__examzh_score_show_leader_bool + { + \__examzh_math_cdotfill:n + { + \l__examzh_score_format_tl + \l__examzh_score_pre_content_tl + #1 + \l__examzh_score_post_content_tl + } + } + { + \__examzh_math_nodotfill:n + { + { + \l__examzh_score_format_tl + \l__examzh_score_pre_content_tl + #1 + \l__examzh_score_post_content_tl + } + } + } + } +\cs_new:Npn \__examzh_score_text_version:n #1 + { + \bool_if:NTF \l__examzh_score_show_leader_bool + { + \__examzh_cdotfill: + \l__examzh_score_format_tl + \l__examzh_score_pre_content_tl #1 \l__examzh_score_post_content_tl + } + { + \hfill + \l__examzh_score_format_tl + \l__examzh_score_pre_content_tl #1 \l__examzh_score_post_content_tl + } + \par \noindent \ignorespaces + } +% 仿照 latex.ltx, line 651 的 \dotfill +\cs_new:Npn \__examzh_cdotfill: + { + \mode_leave_vertical: + \cleaders + \hbox_to_wd:nn { .44em } { \hss $\cdot$ \hss } + \hfill \kern\z@ + } +\cs_new_protected:Npn \__examzh_math_nodotfill:n #1 + { + \stepcounter { zref@unique } + \hbox_overlap_right:n + { + \zsaveposx { \thezref@unique L } + \zref@ifrefundefined { \thezref@unique R } + { } + { + \skip_horizontal:n + { + \zposx { \thezref@unique R } sp + - \zposx { \thezref@unique L } sp + } + } + } + \tag * { \zsaveposx { \thezref@unique R } #1 } + } +\cs_new_protected:Npn \__examzh_math_cdotfill:n #1 + { + \stepcounter { zref@unique } + \hbox_overlap_right:n + { + \zsaveposx { \thezref@unique L } + \zref@ifrefundefined { \thezref@unique R } + { } + { + \cleaders + \hbox_to_wd:nn { .44em } { \hss $\cdot$ \hss } + \skip_horizontal:n + { + \zposx { \thezref@unique R } sp + - \zposx { \thezref@unique L } sp + } + } + } + \tag * { \zsaveposx { \thezref@unique R } #1 } + }
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/exam-zh/exam-zh-symbols.sty b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-symbols.sty new file mode 100644 index 00000000000..e0f147aab3c --- /dev/null +++ b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-symbols.sty @@ -0,0 +1,1198 @@ +% +% Copyright (c) 2022 Kangwei Xia +% Released under the LaTeX Project Public License v1.3c License. +% Repository: https://gitee.com/zepinglee/exam-zh +% + +\NeedsTeXFormat{LaTeX2e} + +\RequirePackage{expl3} + +\ProvidesExplPackage {exam-zh-symbols} {2022-07-28} {v0.1.13} + {exam-zh symbols module} + +\RequirePackage { tikz } + +\keys_define:nn { exam-zh } + { symbols .meta:nn = { exam-zh / symbols } {#1} } + + +% 分数 \frac \dfrac +\int_new:N \l__examzh_symbols_frac_numerator_str_int % frac 分子字符数 +\int_new:N \l__examzh_symbols_frac_denominator_str_int % frac 分母字符数 +\int_new:N \l__examzh_symbols_dfrac_numerator_str_int % frac 分子字符数 +\int_new:N \l__examzh_symbols_dfrac_denominator_str_int % frac 分母字符数 + +\keys_define:nn { exam-zh / symbols } + { + % 是否重定义 \frac + change-frac-style .bool_set:N = \l__examzh_symbols_change_frac_style_bool, + % 是否重定义 \dfrac + change-dfrac-style .bool_set:N = \l__examzh_symbols_change_dfrac_style_bool, + % \frac 分子分母增加的额外距离 + frac-add .muskip_set:N = \l__examzh_symbols_frac_add_distance_muskip, + % \dfrac 分子分母增加的额外距离 + dfrac-add .muskip_set:N = \l__examzh_symbols_dfrac_add_distance_muskip, + } +\keys_set:nn { exam-zh / symbols } + { + change-frac-style = false, + change-dfrac-style = false, + frac-add = 5mu, + dfrac-add = 5mu, + } +\NewCommandCopy { \examzhfrac } { \frac } +\NewCommandCopy { \examzhdfrac } { \dfrac } +\RenewDocumentCommand { \frac } { m m } + { + \group_begin: + \bool_if:NTF \l__examzh_symbols_change_frac_style_bool + { + % 计算分子分母的字符数 + \__examzh_symbols_frac_calc_str_num:nn {#1} {#2} + % 根据字符数选择将额外的距离加在哪 + \__examzh_symbols_frac_add_distance:NNNNnn + \examzhfrac + \l__examzh_symbols_frac_numerator_str_int + \l__examzh_symbols_frac_denominator_str_int + \l__examzh_symbols_frac_add_distance_muskip + {#1}{#2} + } + { \examzhfrac {#1} {#2} } + \group_end: + } +\RenewDocumentCommand { \dfrac } { m m } + { + \group_begin: + \bool_if:NTF \l__examzh_symbols_change_dfrac_style_bool + { + % 计算分子分母的字符数 + \__examzh_symbols_frac_calc_str_num:nn {#1} {#2} + % 根据字符数选择将额外的距离加在哪 + \__examzh_symbols_frac_add_distance:NNNNnn + \examzhdfrac + \l__examzh_symbols_frac_numerator_str_int + \l__examzh_symbols_frac_denominator_str_int + \l__examzh_symbols_dfrac_add_distance_muskip + {#1}{#2} + } + { \examzhdfrac {#1} {#2} } + \group_end: + } +\cs_new:Npn \__examzh_symbols_frac_calc_str_num:nn #1#2 + { + \int_set:Nn \l__examzh_symbols_frac_numerator_str_int + { \str_count:n {#1} } + \int_set:Nn \l__examzh_symbols_frac_denominator_str_int + { \str_count:n {#2} } + } +% \__examzh_symbols_frac_add_distance:NNNNnn + % <\oldfrac><numerator str num><denominator str num><add muskip><numerator><denominator> +\cs_new:Npn \__examzh_symbols_frac_add_distance:NNNNnn #1#2#3#4#5#6 + { + \int_compare:nNnTF {#2} = {1} + { + \int_compare:nNnTF {#3} = {1} + { + % 分子字符数=1,分母字符数=1 + #1 + { + \mskip #4 + #5 + \mskip #4 + } {#6} + } + { + % 分子字符数=1,分母字符数>1 + #1 {#5} + { + \mskip #4 + #6 + \mskip #4 + } + } + } + { + \int_compare:nNnTF {#3} = {1} + { + % 分子字符数>1,分母字符数=1 + #1 + { + \mskip #4 + #5 + \mskip #4 + } {#6} + } + { + % 分子字符数>1,分母字符数>1 + #1 + { + \mskip #4 + #5 + \mskip #4 + } {#6} + } + } + } + +% 向量 vec +\int_new:N \l__examzh_symbols_vec_input_count_int + +\AtBeginDocument + { + \RenewDocumentCommand { \vec } { m } + { \__examzh_symbols_vec:n {#1} } + } +\cs_new:Npn \__examzh_symbols_vec:n #1 + { + % 先检测 #1 有多少个字符 + \__examzh_symbols_vec_detect_number_of_input_str:n {#1} + % 只有 1 个的:加粗,多于两个的加箭头 + \int_compare:nNnTF { \l__examzh_symbols_vec_input_count_int } = {1} + { \symbfit {#1} } + { \overrightarrow {#1} } + } +\cs_new:Npn \__examzh_symbols_vec_detect_number_of_input_str:n #1 + { + \int_set:Nn \l__examzh_symbols_vec_input_count_int + { \str_count:n { #1 } } + } + +% 平行四边形 \parallelogram +\keys_define:nn { exam-zh / symbols } + { + parallelogram-angle .fp_set:N = \l__examzh_symbols_parallelogram_angle_fp, + parallelogram-x .dim_set:N = \l__examzh_symbols_parallelogram_x_dim, + parallelogram-y .dim_set:N = \l__examzh_symbols_parallelogram_y_dim + } + +\cs_new:Npn \__examzh_symbols_parallelogram: + { + \begin{tikzpicture}[baseline] + \draw[line~join = round] (0,0) --++ (\l__examzh_symbols_parallelogram_x_dim,0) --++ (\fp_use:N \l__examzh_symbols_parallelogram_angle_fp \c_colon_str \l__examzh_symbols_parallelogram_y_dim) -- (\fp_use:N \l__examzh_symbols_parallelogram_angle_fp \c_colon_str \l__examzh_symbols_parallelogram_y_dim) -- cycle; + \end{tikzpicture} + } + +\AtBeginDocument + { + \RenewDocumentCommand { \parallelogram } { } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + parallelogram-angle = 67, + parallelogram-x = 0.9em, + parallelogram-y = 0.7em + } + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_parallelogram: } + } + \group_end: + } + } + +% 平行 \parallel +\bool_new:N \l__examzh_symbols_parallel_slant_bool +\bool_new:N \l__examzh_symbols_nparallel_slant_bool + +\keys_define:nn { exam-zh / symbols } + { + parallel-angle .fp_set:N = \l__examzh_symbols_parallel_angle_fp, + parallel-twoline-distance .dim_set:N = \l__examzh_symbols_parallel_twoline_distance_dim, + parallel-length .dim_set:N = \l__examzh_symbols_parallel_length_dim, + parallel-baseline .dim_set:N = \l__examzh_symbols_parallel_baseline_dim, + nparallel-slant-angle .fp_set:N = \l__examzh_symbols_nparallel_slant_angle_fp, + nparallel-slant-length .dim_set:N = \l__examzh_symbols_nparallel_slant_length_dim, + parallel-type .choice:, + parallel-type / slant.code:n = + { \bool_set_true:N \l__examzh_symbols_parallel_slant_bool }, + parallel-type / perpendicular .code:n = + { \bool_set_false:N \l__examzh_symbols_parallel_slant_bool }, + nparallel-type .choice:, + nparallel-type / slant.code:n = + { \bool_set_true:N \l__examzh_symbols_nparallel_slant_bool }, + nparallel-type / perpendicular .code:n = + { \bool_set_false:N \l__examzh_symbols_nparallel_slant_bool }, + } +\keys_set:nn { exam-zh / symbols } + { + parallel-type = slant, + nparallel-type = slant, + } + +\cs_new:Npn \__examzh_symbols_parallel: + { + \begin{tikzpicture}[baseline=\l__examzh_symbols_parallel_baseline_dim] + \draw[line~cap = round] (0, 0) --++ (\fp_use:N \l__examzh_symbols_parallel_angle_fp \c_colon_str \l__examzh_symbols_parallel_length_dim) + (\l__examzh_symbols_parallel_twoline_distance_dim, 0) --++ (\fp_use:N \l__examzh_symbols_parallel_angle_fp \c_colon_str \l__examzh_symbols_parallel_length_dim); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_nparallel: + { + \begin{tikzpicture}[line~cap = round, baseline=\l__examzh_symbols_parallel_baseline_dim] + \draw + (0, 0) --++ (\fp_use:N \l__examzh_symbols_parallel_angle_fp \c_colon_str \l__examzh_symbols_parallel_length_dim) + (\l__examzh_symbols_parallel_twoline_distance_dim, 0) --++ (\fp_use:N \l__examzh_symbols_parallel_angle_fp \c_colon_str \l__examzh_symbols_parallel_length_dim); + % n 线 + \draw + (\l__examzh_symbols_parallel_twoline_distance_dim / 2, 0)++(\fp_use:N \l__examzh_symbols_parallel_angle_fp \c_colon_str \l__examzh_symbols_parallel_length_dim / 2) --++ (\fp_use:N \l__examzh_symbols_nparallel_slant_angle_fp \c_colon_str \l__examzh_symbols_nparallel_slant_length_dim / 2) + (\l__examzh_symbols_parallel_twoline_distance_dim / 2, 0)++(\fp_use:N \l__examzh_symbols_parallel_angle_fp \c_colon_str \l__examzh_symbols_parallel_length_dim / 2) --++ (\fp_eval:n { \l__examzh_symbols_nparallel_slant_angle_fp + 180 } \c_colon_str \l__examzh_symbols_nparallel_slant_length_dim / 2); + \end{tikzpicture} + } + +\AtBeginDocument + { + \cs_set_eq:NN \__examzh_symbols_old_parallel: \parallel + \cs_set_eq:NN \__examzh_symbols_old_nparallel: \nparallel + \RenewDocumentCommand { \parallel } { } + { + \group_begin: + \bool_if:NTF \l__examzh_symbols_parallel_slant_bool + { + \keys_set:nn { exam-zh / symbols } + { + parallel-angle = 60, + parallel-twoline-distance = 0.28em, + parallel-length = 0.98em, + parallel-baseline = 0.5pt + } + } + { + % 竖直 + \keys_set:nn { exam-zh / symbols } + { + parallel-angle = 90, + parallel-twoline-distance = 0.2em, + parallel-length = 0.93em, + parallel-baseline = 1pt + } + } + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_parallel: } + } + \group_end: + } + \RenewDocumentCommand { \nparallel } { } + { + \group_begin: + + \bool_if:NTF \l__examzh_symbols_nparallel_slant_bool + { + \keys_set:nn { exam-zh / symbols } + { + parallel-angle = 60, + parallel-twoline-distance = 0.28em, + parallel-length = 0.98em, + parallel-baseline = 0.5pt, + nparallel-slant-angle = 120, + nparallel-slant-length = 0.65em + } + } + { + \keys_set:nn { exam-zh / symbols } + { + parallel-angle = 90, + parallel-twoline-distance = 0.2em, + parallel-length = 0.93em, + parallel-baseline = 1pt, + nparallel-slant-angle = 50, + nparallel-slant-length = 0.6em + } + % \tikz[baseline = {([yshift = 5pt]current~bounding~box.south)}]{ \node { $\__examzh_symbols_old_nparallel:$ }; } + } + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_nparallel: } + } + \group_end: + } + } + +% 平行且相等 \paralleleq +\bool_new:N \l__examzh_symbols_paralleleq_slant_bool + +\keys_define:nn { exam-zh / symbols } + { + % 上面部分的倾斜角 + paralleleq-slant-angle .fp_set:N = \l__examzh_symbols_paralleleq_angle_fp, + % 线长度 + paralleleq-upper-line-length .dim_set:N = \l__examzh_symbols_paralleleq_upper_line_length_dim, + paralleleq-lower-line-length .dim_set:N = \l__examzh_symbols_paralleleq_lower_line_length_dim, + % 线间距 + paralleleq-upper-twoline-distance .dim_set:N = \l__examzh_symbols_paralleleq_upper_twoline_distance_dim, + paralleleq-lower-twoline-distance .dim_set:N = \l__examzh_symbols_paralleleq_lower_twoline_distance_dim, + % 下面部分的水平偏移量 + paralleleq-lower-xshift .dim_set:N = \l__examzh_symbols_paralleleq_lower_xshift_dim, + paralleleq-type .choice:, + paralleleq-type / slant.code:n = + { \bool_set_true:N \l__examzh_symbols_paralleleq_slant_bool }, + paralleleq-type / perpendicular .code:n = + { \bool_set_false:N \l__examzh_symbols_paralleleq_slant_bool }, + } + +\keys_set:nn { exam-zh / symbols } + { paralleleq-type = slant } + +\cs_new:Npn \__examzh_symbols_paralleleq: + { + \begin{tikzpicture}[baseline = -1.7pt] + \draw[line~cap = round, name = parallel] (0, 0) --++ (\fp_use:N \l__examzh_symbols_paralleleq_angle_fp \c_colon_str \l__examzh_symbols_paralleleq_upper_line_length_dim) + (\l__examzh_symbols_paralleleq_upper_twoline_distance_dim, 0) --++ (\fp_use:N \l__examzh_symbols_paralleleq_angle_fp \c_colon_str \l__examzh_symbols_paralleleq_upper_line_length_dim); + \draw[anchor = parallel.south] + (\l__examzh_symbols_paralleleq_upper_twoline_distance_dim / 2 + \l__examzh_symbols_paralleleq_lower_xshift_dim,0) --++ (\l__examzh_symbols_paralleleq_lower_line_length_dim / 2,0) + (\l__examzh_symbols_paralleleq_upper_twoline_distance_dim / 2 + \l__examzh_symbols_paralleleq_lower_xshift_dim,0) --++ (-\l__examzh_symbols_paralleleq_lower_line_length_dim / 2,0) + (\l__examzh_symbols_paralleleq_upper_twoline_distance_dim / 2 + \l__examzh_symbols_paralleleq_lower_xshift_dim,-\l__examzh_symbols_paralleleq_lower_twoline_distance_dim) --++ (\l__examzh_symbols_paralleleq_lower_line_length_dim / 2 ,0) + (\l__examzh_symbols_paralleleq_upper_twoline_distance_dim / 2 + \l__examzh_symbols_paralleleq_lower_xshift_dim,-\l__examzh_symbols_paralleleq_lower_twoline_distance_dim) --++ (-\l__examzh_symbols_paralleleq_lower_line_length_dim / 2,0) + ; + \end{tikzpicture} + } + +\NewDocumentCommand { \paralleleq } { } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + paralleleq-upper-line-length = 0.65em, + paralleleq-lower-line-length = 0.8em, + paralleleq-upper-twoline-distance = 0.2em, + paralleleq-lower-twoline-distance = 0.18em, + } + \bool_if:NTF \l__examzh_symbols_paralleleq_slant_bool + { + % \paralleleq : 倾斜型 + \keys_set:nn { exam-zh / symbols } + { + paralleleq-slant-angle = 70, + paralleleq-lower-xshift = 0.04em + } + } + { + % \paralleleq* : 垂直型 + \keys_set:nn { exam-zh / symbols } + { + paralleleq-slant-angle = 90, + paralleleq-lower-xshift = 0em + } + } + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_paralleleq: } + } + \group_end: + } + + +% 子集 \subset 真子集 \subseteqq +\keys_define:nn { exam-zh / symbols } + { + % 半圆的半径 + subset-radius .dim_set:N = \l__examzh_symbols_subset_semicircle_radius_dim, + % 半圆右边横线的长度 + subset-upper-linewidth .dim_set:N = \l__examzh_symbols_subset_semicircle_line_width_dim, + % 下面线的长度 + subset-lower-linewidth .dim_set:N = \l__examzh_symbols_subset_lower_line_width_dim, + % 上面部分和下面部分的距离 + subset-upper-lower-distance .dim_set:N = \l__examzh_symbols_subset_upper_lower_distance_dim, + % 下面部分 两条线的距离 + subsetneqq-lower-twoline-distance .dim_set:N = \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim, + % 下面斜线的长度 + subsetneqq-lower-slant-length .dim_set:N = \l__examzh_symbols_subsetneqq_lower_slant_line_length_dim, + supsetneqq-lower-slant-length .dim_set:N = \l__examzh_symbols_supsetneqq_lower_slant_line_length_dim, + % 真子集下方斜线的倾斜角度 + subsetneqq-lower-slant-angle .fp_set:N = \l__examzh_symbols_subsetneqq_lower_slant_line_angle_fp, + supsetneqq-lower-slant-angle .fp_set:N = \l__examzh_symbols_supsetneqq_lower_slant_line_angle_fp, + % nxxx 类的参数 + % --角度-- + nsubset-n-slant-angle .fp_set:N = \l__examzh_symbols_nsubset_slant_angle_fp, + nsubseteq-n-slant-angle .fp_set:N = \l__examzh_symbols_nsubseteq_slant_angle_fp, + nsubsetneqq-n-slant-angle .fp_set:N = \l__examzh_symbols_nsubsetneqq_slant_angle_fp, + % --长度-- + nsubset-n-slant-length .dim_set:N = \l__examzh_symbols_nsubset_slant_length_dim, + nsubseteq-n-slant-length .dim_set:N = \l__examzh_symbols_nsubseteq_slant_length_dim, + nsubsetneqq-n-slant-length .dim_set:N = \l__examzh_symbols_nsubsetneqq_slant_length_dim, + } +\keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em, + subset-lower-linewidth = + { + \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim + }, + subset-upper-lower-distance = 0.12em, + subsetneqq-lower-twoline-distance = 0.14em, + subsetneqq-lower-slant-length = 0.42em, + supsetneqq-lower-slant-length = 0.4em, + subsetneqq-lower-slant-angle = 55, + supsetneqq-lower-slant-angle = 60, + nsubset-n-slant-angle = 65, + nsubseteq-n-slant-angle = 68, + nsubsetneqq-n-slant-angle = 70, + nsubset-n-slant-length = 1em, + nsubseteq-n-slant-length = 1em, + nsubsetneqq-n-slant-length = 1.2em, + } + +\cs_new:Npn \__examzh_symbols_subset: + { + \begin{tikzpicture}[line~cap=round,baseline = {([yshift = -1pt]current~bounding~box.south)}] + % 半圆 + 两条线 + \draw[line~cap=round] (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str 270 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim) + (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0) + (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_nsubset: + { + \begin{tikzpicture}[line~cap=round,baseline = {([yshift = -1pt]current~bounding~box.south)}] + % 半圆 + 两条线 + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str 270 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim) + (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0) + (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0); + % 定位斜线的中心 + \coordinate (n-center) at (\l__examzh_symbols_subset_semicircle_line_width_dim / 2 - \l__examzh_symbols_subset_semicircle_radius_dim / 2,0); + % 画斜线 + \draw[overlay] + (n-center) --++ (\fp_use:N \l__examzh_symbols_nsubset_slant_angle_fp \c_colon_str \l__examzh_symbols_nsubset_slant_length_dim / 2) + (n-center) --++ (\fp_eval:n { \l__examzh_symbols_nsubset_slant_angle_fp + 180} \c_colon_str \l__examzh_symbols_nsubset_slant_length_dim / 2); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_subseteq: + { + \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)] + % 半圆 + 两条线 + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str 270 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim) + (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0) + (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0); + % 下面的一条线 + \draw (-\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (\l__examzh_symbols_subset_lower_line_width_dim, 0); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_nsubseteq: + { + \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)] + % 半圆 + 两条线 + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str 270 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim) + (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0) + (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0); + % 下面的一条线 + \draw (-\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (\l__examzh_symbols_subset_lower_line_width_dim, 0); + % 定位斜线的中心 + \coordinate (n-center) at (\l__examzh_symbols_subset_semicircle_line_width_dim / 2 - \l__examzh_symbols_subset_semicircle_radius_dim / 2,0); + % 画斜线 + \draw[overlay] + (n-center) --++ (\fp_use:N \l__examzh_symbols_nsubseteq_slant_angle_fp \c_colon_str \l__examzh_symbols_nsubseteq_slant_length_dim / 8 * 3.5) + (n-center) --++ (\fp_eval:n { \l__examzh_symbols_nsubseteq_slant_angle_fp + 180} \c_colon_str \l__examzh_symbols_nsubseteq_slant_length_dim / 8 * 4.5); + \end{tikzpicture} + } +% 真子集 +\cs_new:Npn \__examzh_symbols_subsetneqq: + { + \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)] + % 半圆 + 两条线 + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str 270 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim) + (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0) + (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0); + % 下面的两条线 + \draw (-\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (\l__examzh_symbols_subset_lower_line_width_dim, 0) + (-\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim) --++ (\l__examzh_symbols_subset_lower_line_width_dim, 0); + % 定位斜线的中心点 + \coordinate (lower-center) at + (\l__examzh_symbols_subset_semicircle_line_width_dim / 2 - \l__examzh_symbols_subset_semicircle_radius_dim / 2 , - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim / 2 ); + % 画斜线 + \draw[overlay] + (lower-center) --++ (\fp_use:N \l__examzh_symbols_subsetneqq_lower_slant_line_angle_fp \c_colon_str \l__examzh_symbols_subsetneqq_lower_slant_line_length_dim / 2) + (lower-center) --++ (\fp_eval:n {\l__examzh_symbols_subsetneqq_lower_slant_line_angle_fp + 180} \c_colon_str \l__examzh_symbols_subsetneqq_lower_slant_line_length_dim / 2); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_nsubsetneqq: + { + \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)] + % 半圆 + 两条线 + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str 270 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim) + (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0) + (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0); + % 下面的两条线 + \draw (-\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (\l__examzh_symbols_subset_lower_line_width_dim, 0) + (-\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim) --++ (\l__examzh_symbols_subset_lower_line_width_dim, 0); + % 定位斜线的中心点 + \coordinate (lower-center) at + (\l__examzh_symbols_subset_semicircle_line_width_dim / 2 - \l__examzh_symbols_subset_semicircle_radius_dim / 2 , - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim / 2 ); + % 画斜线 + \draw[overlay] + (lower-center) --++ (\fp_use:N \l__examzh_symbols_subsetneqq_lower_slant_line_angle_fp \c_colon_str \l__examzh_symbols_subsetneqq_lower_slant_line_length_dim / 2) + (lower-center) --++ (\fp_eval:n {\l__examzh_symbols_subsetneqq_lower_slant_line_angle_fp + 180} \c_colon_str \l__examzh_symbols_subsetneqq_lower_slant_line_length_dim / 2); + % 定位斜线的中心 + \coordinate (n-center) at (\l__examzh_symbols_subset_semicircle_line_width_dim / 2 - \l__examzh_symbols_subset_semicircle_radius_dim / 2,0); + % 画斜线 + \draw[overlay] + (n-center) --++ (\fp_use:N \l__examzh_symbols_nsubsetneqq_slant_angle_fp \c_colon_str \l__examzh_symbols_nsubsetneqq_slant_length_dim / 8 * 3.2) + (n-center) --++ (\fp_eval:n { \l__examzh_symbols_nsubsetneqq_slant_angle_fp + 180} \c_colon_str \l__examzh_symbols_nsubsetneqq_slant_length_dim / 8 * 4.8); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_supset: + { + \begin{tikzpicture}[line~cap=round,baseline = {([yshift = -1pt]current~bounding~box.south)}] + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str -90 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim) + (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0) + (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_nsupset: + { + \begin{tikzpicture}[line~cap=round,baseline = {([yshift = -1pt]current~bounding~box.south)}] + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str -90 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim) + (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0) + (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0); + % 定位斜线的中心 + \coordinate (n-center) at (- \l__examzh_symbols_subset_semicircle_line_width_dim / 2 + \l__examzh_symbols_subset_semicircle_radius_dim / 2,0); + % 画斜线 + \draw[overlay] + (n-center) --++ (\fp_use:N \l__examzh_symbols_nsubset_slant_angle_fp \c_colon_str \l__examzh_symbols_nsubset_slant_length_dim / 2) + (n-center) --++ (\fp_eval:n { \l__examzh_symbols_nsubset_slant_angle_fp + 180} \c_colon_str \l__examzh_symbols_nsubset_slant_length_dim / 2); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_supseteq: + { + \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)] + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str -90 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim); + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0); + \draw (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0); + \draw + (\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim - \l__examzh_symbols_subset_semicircle_radius_dim, 0); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_nsupseteq: + { + \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)] + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str -90 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim) + (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0) + (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0); + \draw + (\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim - \l__examzh_symbols_subset_semicircle_radius_dim, 0); + \coordinate (n-center) at (-\l__examzh_symbols_subset_semicircle_line_width_dim / 2 + \l__examzh_symbols_subset_semicircle_radius_dim / 2,0); + % 画斜线 + \draw[overlay] + (n-center) --++ (\fp_use:N \l__examzh_symbols_nsubseteq_slant_angle_fp \c_colon_str \l__examzh_symbols_nsubseteq_slant_length_dim / 8 * 3.5) + (n-center) --++ (\fp_eval:n { \l__examzh_symbols_nsubseteq_slant_angle_fp + 180} \c_colon_str \l__examzh_symbols_nsubseteq_slant_length_dim / 8 * 4.5); + \end{tikzpicture} + } +% 反向真子集 +\cs_new:Npn \__examzh_symbols_supsetneqq: + { + \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)] + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str -90 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim); + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0); + \draw (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0); + \draw + (\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim - \l__examzh_symbols_subset_semicircle_radius_dim, 0) + (\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim - \l__examzh_symbols_subset_semicircle_radius_dim, 0); + % 定位斜线的中心点 + \coordinate (center) at + (- \l__examzh_symbols_subset_semicircle_line_width_dim / 2 + \l__examzh_symbols_subset_semicircle_radius_dim / 2 , - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim / 2 ); + % 画斜线 + \draw[overlay] + (center) --++ (\fp_use:N \l__examzh_symbols_supsetneqq_lower_slant_line_angle_fp \c_colon_str \l__examzh_symbols_supsetneqq_lower_slant_line_length_dim / 2) + (center) --++ (\fp_eval:n {\l__examzh_symbols_supsetneqq_lower_slant_line_angle_fp + 180} \c_colon_str \l__examzh_symbols_supsetneqq_lower_slant_line_length_dim / 2); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_nsupsetneqq: + { + \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)] + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str -90 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim); + \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0); + \draw (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0); + \draw + (\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim - \l__examzh_symbols_subset_semicircle_radius_dim, 0) + (\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim - \l__examzh_symbols_subset_semicircle_radius_dim, 0); + % 定位斜线的中心点 + \coordinate (center) at + (- \l__examzh_symbols_subset_semicircle_line_width_dim / 2 + \l__examzh_symbols_subset_semicircle_radius_dim / 2 , - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim / 2 ); + % 画斜线 + \draw[overlay] + (center) --++ (\fp_use:N \l__examzh_symbols_supsetneqq_lower_slant_line_angle_fp \c_colon_str \l__examzh_symbols_supsetneqq_lower_slant_line_length_dim / 2) + (center) --++ (\fp_eval:n {\l__examzh_symbols_supsetneqq_lower_slant_line_angle_fp + 180} \c_colon_str \l__examzh_symbols_supsetneqq_lower_slant_line_length_dim / 2); + % 定位斜线的中心 + \coordinate (n-center) at (-\l__examzh_symbols_subset_semicircle_line_width_dim / 2 + \l__examzh_symbols_subset_semicircle_radius_dim / 2,0); + % 画斜线 + \draw[overlay] + (n-center) --++ (\fp_use:N \l__examzh_symbols_nsubsetneqq_slant_angle_fp \c_colon_str \l__examzh_symbols_nsubsetneqq_slant_length_dim / 8 * 3.2) + (n-center) --++ (\fp_eval:n { \l__examzh_symbols_nsubsetneqq_slant_angle_fp + 180} \c_colon_str \l__examzh_symbols_nsubsetneqq_slant_length_dim / 8 * 4.8); + \end{tikzpicture} + } +\AtBeginDocument + { + \cs_set_eq:NN \__examzh_symbols_old_subset: \subset + \cs_set_eq:NN \__examzh_symbols_old_supset: \supset + \cs_set_eq:NN \__examzh_symbols_old_nsubset: \nsubset + \cs_set_eq:NN \__examzh_symbols_old_nsupset: \nsupset + \cs_set_eq:NN \__examzh_symbols_old_subseteq: \subseteq + \cs_set_eq:NN \__examzh_symbols_old_supseteq: \supseteq + \cs_set_eq:NN \__examzh_symbols_old_nsubseteq: \nsubseteq + \cs_set_eq:NN \__examzh_symbols_old_nsupseteq: \nsupseteq + \cs_set_eq:NN \__examzh_symbols_old_subsetneqq: \subsetneqq + \cs_set_eq:NN \__examzh_symbols_old_supsetneqq: \supsetneqq + % \cs_set_eq:NN \__examzh_symbols_old_nsubsetneqq: \nsubsetneqq + % \cs_set_eq:NN \__examzh_symbols_old_nsupsetneqq: \nsupsetneqq + \RenewDocumentCommand { \subset } { s } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em + } + \IfBooleanTF {#1} + { \__examzh_symbols_old_subset: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_subset: } + } + } + \group_end: + } + \RenewDocumentCommand { \nsubset } { s } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em, + nsubset-n-slant-angle = 65, + nsubset-n-slant-length = 1em, + } + \IfBooleanTF {#1} + { \__examzh_symbols_old_nsubset: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_nsubset: } + } + } + \group_end: + } + \RenewDocumentCommand { \subseteq } { s } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em, + subset-upper-lower-distance = 0.12em, + subset-lower-linewidth = + { + \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim + } + } + \IfBooleanTF {#1} + { \__examzh_symbols_old_subseteq: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_subseteq: } + } + } + \group_end: + } + \RenewDocumentCommand { \nsubseteq } { s } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em, + subset-lower-linewidth = + { + \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim + }, + subset-upper-lower-distance = 0.12em, + nsubseteq-n-slant-angle = 68, + nsubseteq-n-slant-length = 1em, + } + \IfBooleanTF {#1} + { \__examzh_symbols_old_nsubseteq: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_nsubseteq: } + } + } + \group_end: + } + \RenewDocumentCommand { \subsetneqq } { s } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em, + subset-lower-linewidth = + { + \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim + }, + subset-upper-lower-distance = 0.12em, + subsetneqq-lower-twoline-distance = 0.14em, + subsetneqq-lower-slant-length = 0.42em, + subsetneqq-lower-slant-angle = 55, + } + \IfBooleanTF {#1} + { \__examzh_symbols_old_subsetneqq: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_subsetneqq: } + } + } + \group_end: + } + \NewDocumentCommand { \nsubsetneqq } { } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em, + subset-lower-linewidth = + { + \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim + }, + subset-upper-lower-distance = 0.12em, + subsetneqq-lower-twoline-distance = 0.14em, + subsetneqq-lower-slant-length = 0.42em, + subsetneqq-lower-slant-angle = 55, + nsubsetneqq-n-slant-angle = 70, + nsubsetneqq-n-slant-length = 1.2em, + } + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_nsubsetneqq: } + } + \group_end: + } + \RenewDocumentCommand { \supset } { s } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em + } + \IfBooleanTF {#1} + { \__examzh_symbols_old_supset: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_supset: } + } + } + \group_end: + } + \RenewDocumentCommand { \nsupset } { s } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em, + nsubset-n-slant-angle = 65, + nsubset-n-slant-length = 1em, + } + \IfBooleanTF {#1} + { \__examzh_symbols_old_nsupset: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_nsupset: } + } + } + \group_end: + } + \RenewDocumentCommand { \supseteq } { s } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em, + subset-upper-lower-distance = 0.12em, + subset-lower-linewidth = + { + \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim + } + } + \IfBooleanTF {#1} + { \__examzh_symbols_old_supseteq: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_supseteq: } + } + } + \group_end: + } + \RenewDocumentCommand { \nsupseteq } { s } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em, + subset-lower-linewidth = + { + \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim + }, + subset-upper-lower-distance = 0.12em, + nsubseteq-n-slant-angle = 68, + nsubseteq-n-slant-length = 1em, + } + \IfBooleanTF {#1} + { \__examzh_symbols_old_nsupseteq: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_nsupseteq: } + } + } + \group_end: + } + \RenewDocumentCommand { \supsetneqq } { s } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em, + subset-lower-linewidth = + { + \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim + }, + subset-upper-lower-distance = 0.12em, + subsetneqq-lower-twoline-distance = 0.14em, + supsetneqq-lower-slant-length = 0.4em, + supsetneqq-lower-slant-angle = 60, + } + \IfBooleanTF {#1} + { \__examzh_symbols_old_supsetneqq: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_supsetneqq: } + } + } + \group_end: + } + \NewDocumentCommand { \nsupsetneqq } { } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em, + subset-lower-linewidth = + { + \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim + }, + subset-upper-lower-distance = 0.12em, + subsetneqq-lower-twoline-distance = 0.14em, + supsetneqq-lower-slant-length = 0.4em, + supsetneqq-lower-slant-angle = 60, + nsubsetneqq-n-slant-angle = 70, + nsubsetneqq-n-slant-length = 1.2em, + } + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_nsupsetneqq: } + } + \group_end: + } + % \RenewDocumentCommand { \subset } { s } + % { + % \group_begin: + % \keys_set:nn { exam-zh / symbols } + % { + % subset-radius = 0.2em, + % subset-upper-linewidth = 0.6em, + % subset-lower-linewidth = + % { + % \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim + % }, + % subset-upper-lower-distance = 0.12em, + % subsetneqq-lower-twoline-distance = 0.14em, + % subsetneqq-lower-slant-length = 0.42em, + % supsetneqq-lower-slant-length = 0.4em, + % subsetneqq-lower-slant-angle = 55, + % supsetneqq-lower-slant-angle = 60, + % nsubset-n-slant-angle = 65, + % nsubseteq-n-slant-angle = 68, + % nsubsetneqq-n-slant-angle = 70, + % nsubset-n-slant-length = 1em, + % nsubseteq-n-slant-length = 1em, + % nsubsetneqq-n-slant-length = 1.2em, + % } + % \IfBooleanTF {#1} + % { \__examzh_symbols_old_subset: } + % { + % \mathrel + % { + % \__examzh_symbols_symbol_four_size:n + % { \__examzh_symbols_subset: } + % } + % } + % \group_end: + % } + \RenewDocumentCommand { \subseteq } { s } + { + \group_begin: + \keys_set:nn { exam-zh / symbols } + { + subset-radius = 0.2em, + subset-upper-linewidth = 0.6em, + subset-lower-linewidth = + { + \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim + }, + subset-upper-lower-distance = 0.12em, + } + \IfBooleanTF {#1} + { \__examzh_symbols_old_subseteq: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_subseteq: } + } + } + \group_end: + } + + } + + + +% 并集 交集 cap cup + +% 直线长度 +\dim_new:N \l__examzh_symbols_cap_line_length_dim +\dim_new:N \l__examzh_symbols_cup_line_length_dim +% 半径大小 +\dim_new:N \l__examzh_symbols_cap_radius_dim +\dim_new:N \l__examzh_symbols_cup_radius_dim + +\cs_new:Npn \__examzh_symbols_cap: + { + \begin{tikzpicture}[line~cap=round, line~width = 0.6pt,baseline = {([yshift = 1.2pt]current~bounding~box.south)}] + \draw (\l__examzh_symbols_cap_radius_dim,0) arc (0 \c_colon_str 180 \c_colon_str \l__examzh_symbols_cap_radius_dim); + \draw + (\l__examzh_symbols_cap_radius_dim,0) --++ (0,-\l__examzh_symbols_cap_line_length_dim) + (-\l__examzh_symbols_cap_radius_dim,0) --++ (0,-\l__examzh_symbols_cap_line_length_dim); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_cup: + { + \begin{tikzpicture}[line~cap=round, line~width = 0.6pt,baseline = {([yshift = 1.8pt]current~bounding~box.south)}] + \draw (-\l__examzh_symbols_cup_radius_dim,0) arc (180 \c_colon_str 360 \c_colon_str \l__examzh_symbols_cup_radius_dim); + \draw + (\l__examzh_symbols_cup_radius_dim,0) --++ (0,\l__examzh_symbols_cup_line_length_dim) + (-\l__examzh_symbols_cup_radius_dim,0) --++ (0,\l__examzh_symbols_cup_line_length_dim); + \end{tikzpicture} + } +\AtBeginDocument + { + \cs_set_eq:NN \__examzh_symbols_old_cap: \cap + \cs_set_eq:NN \__examzh_symbols_old_cup: \cup + \RenewDocumentCommand { \cap } { s } + { + \group_begin: + \dim_set:Nn \l__examzh_symbols_cap_line_length_dim { 0.56em } + \dim_set:Nn \l__examzh_symbols_cap_radius_dim { 0.28em } + \IfBooleanTF {#1} + { \__examzh_symbols_old_cap: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_cap: } + } + } + \group_end: + } + \RenewDocumentCommand { \cup } { s } + { + \group_begin: + \dim_set:Nn \l__examzh_symbols_cup_line_length_dim { 0.53em } + \dim_set:Nn \l__examzh_symbols_cup_radius_dim { 0.28em } + \IfBooleanTF {#1} + { \__examzh_symbols_old_cup: } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \__examzh_symbols_cup: } + } + } + \group_end: + } + } +% 相似 +\cs_new:Npn \__examzh_symbols_sim: + { + \begin{tikzpicture}[line~cap=round, line~width = 0.6pt,baseline = {([yshift = -1pt]current~bounding~box.south)}] + \draw + (-.25em,1.15ex) + .. controls (-.55em,1.15ex) and (-.51em,.23ex) .. (-.275em,.23ex) + .. controls (0,.23ex) and (0,1.15ex) .. (.275em,1.15ex) + .. controls (.51em,1.15ex) and (.55em,.23ex) .. (.25em,.23ex); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_nsim: + { + \begin{tikzpicture}[line~width = 0.6pt,line~cap=round, baseline = {([yshift = 1pt]current~bounding~box.south)}] + \draw + (-.25em,1.15ex) + .. controls (-.55em,1.15ex) and (-.51em,.23ex) .. (-.275em,.23ex) + .. controls (0,.23ex) and (0,1.15ex) .. (.275em,1.15ex) + .. controls (.51em,1.15ex) and (.55em,.23ex) .. (.25em,.23ex); + \draw (-0.15em,-0.2ex) --++ (70 \c_colon_str 0.8em); + \end{tikzpicture} + } +\AtBeginDocument + { + \cs_set_eq:NN \__examzh_symbols_old_sim: \backsim + \RenewDocumentCommand { \sim } { s } + { + \IfBooleanTF {#1} + { \__examzh_symbols_old_sim: } + { + \mathrel { \__examzh_symbols_symbol_four_size:n { \__examzh_symbols_sim: } } + } + } + \RenewDocumentCommand { \nsim } { } + { + \mathrel { \__examzh_symbols_symbol_four_size:n { \__examzh_symbols_nsim: } } + } + } + +% 全等 +\cs_new:Npn \__examzh_symbols_cong: + { + \begin{tikzpicture}[line~cap=round, baseline] + \draw + (-.2em,1.35ex) + .. controls (-.46em,1.6ex) and (-.54em,.65ex) .. (-.25em,.65ex) + .. controls (-.06em,.65ex) and (.06em,1.35ex) .. (.25em,1.35ex) + .. controls (.54em,1.35ex) and (.46em,.4ex) .. (.2em,.65ex) + (-.46em,.4ex) -- (.46em,.4ex) + (-.46em,0ex) -- (.46em,0ex); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_symbols_ncong: + { + \begin{tikzpicture}[line~cap=round, baseline] + \draw + (-.2em,1.35ex) + .. controls (-.46em,1.6ex) and (-.54em,.65ex) .. (-.25em,.65ex) + .. controls (-.06em,.65ex) and (.06em,1.35ex) .. (.25em,1.35ex) + .. controls (.54em,1.35ex) and (.46em,.4ex) .. (.2em,.65ex) + (-.46em,.4ex) -- (.46em,.4ex) + (-.46em,0ex) -- (.46em,0ex); + \draw (-0.22em,-0.4ex) --++ (66 \c_colon_str 1em); + \end{tikzpicture} + } + +\AtBeginDocument + { + \cs_set_eq:NN \__examzh_symbols_old_cong: \backcong + \RenewDocumentCommand { \cong } { s } + { + \IfBooleanTF {#1} + { \__examzh_symbols_old_cong: } + { + \mathrel { \__examzh_symbols_symbol_four_size:n { \__examzh_symbols_cong: } } + } + } + \RenewDocumentCommand { \ncong } { } + { + \mathrel { \__examzh_symbols_symbol_four_size:n { \__examzh_symbols_ncong: } } + } + } + +% 处理符号的不同情况的大小 +\cs_set_eq:NN \NewDocumentCommand:Nnn \NewDocumentCommand +\cs_set_eq:NN \RenewDocumentCommand:Nnn \RenewDocumentCommand +\cs_generate_variant:Nn \NewDocumentCommand:Nnn { cnn } +\cs_generate_variant:Nn \RenewDocumentCommand:Nnn { cnn } + +\cs_new:Npn \__examzh_symbols_new_command_without_star_or_old_version:n #1 + { + \NewDocumentCommand:cnn { #1 } { } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \use:c { __examzh_symbols_ #1 : } } + } + } + } + +\cs_new:Npn \__examzh_symbols_new_command_with_star_and_old_version:n #1 + { + \RenewDocumentCommand:cnn { #1 } { s } + { + \IfBooleanTF {##1} + { \use:c { __examzh_symbols_old_ #1 : } } + { + \mathrel + { + \__examzh_symbols_symbol_four_size:n + { \use:c { __examzh_symbols_ #1 : } } + } + } + } + } +\cs_new:Npn \__examzh_symbols_symbol_four_size:n #1 + { + \mathchoice + { + \hbox:n + { + \fontsize{\tf@size}{\tf@size}\selectfont #1 + } + } + { + \hbox:n + { + \fontsize{\tf@size}{\tf@size}\selectfont #1 + } + } + { + \hbox:n + { + \fontsize{\sf@size}{\sf@size}\selectfont #1 + } + } + { + \hbox:n + { + \fontsize{\ssf@size}{\ssf@size}\selectfont #1 + } + } + }
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/exam-zh/exam-zh.cls b/Master/texmf-dist/tex/latex/exam-zh/exam-zh.cls new file mode 100644 index 00000000000..7deb619de63 --- /dev/null +++ b/Master/texmf-dist/tex/latex/exam-zh/exam-zh.cls @@ -0,0 +1,2214 @@ +% +% Copyright (c) 2022 Zeping Lee +% Released under the LaTeX Project Public License v1.3c License. +% Repository: https://gitee.com/zepinglee/exam-zh +% + +\NeedsTeXFormat{LaTeX2e}[2017/04/15] +\RequirePackage{expl3} +\ProvidesExplClass {exam-zh} {2022-07-28} {v0.1.13} {LaTeX template for Chinese exam} + +% 检查 LaTeX2e kernel 版本 +\msg_new:nnn { exam-zh } { latex-too-old } + { TeX~ Live~ 2020~ or~ later~ version~ is~ required~ to~ compile~ this~ document. } +\@ifl@t@r \fmtversion { 2020/02/02 } + { } + { \msg_fatal:nn { exam-zh } { latex-too-old } } + +% 检查编译引擎,要求使用 XeLaTeX。 +\msg_new:nnn { exam-zh } { incompatible-engine } + { XeLaTeX~ is~ required~ to~ compile~ this~ document. } + +\sys_if_engine_xetex:F + { \msg_fatal:nn { exam-zh } { incompatible-engine } } + + +% 使用 l3keys 定义 \examsetup 配置命令 +\NewDocumentCommand \examsetup { m } + { \keys_set:nn { exam-zh } {#1} } + + + + +% 加载文档类和宏包 + +% 处理文档类选项 +\PassOptionsToClass { UTF8 , scheme = chinese, openany } { ctexbook } +\DeclareOption* { \PassOptionsToClass { \CurrentOption } { ctexbook } } +\ProcessOptions* + +\RequirePackage { filehook } +\AtEndOfPackageFile* { fontspec } + { \msg_redirect_name:nnn { fontspec } { no-script } { none } } +\AtEndOfPackageFile* { xeCJK } + { + \msg_redirect_name:nnn { xeCJK } { CJKfamily-redef } { none } + \defaultCJKfontfeatures + { + Script = CJK, + % Mapping = fullwidth-stop , + } + } + +% 载入 \cls{ctexbook} 文档类。 +\LoadClass { ctexbook } + +% 要求 ctex v2.4.9 2017-04-01 或更高的版本。 +\msg_new:nnn { exam-zh } { require-package-version } + { The~ package~ "#1"~ is~ required. } + +\@ifclasslater { ctexbook } { 2017/04/01 } + { } + { + \msg_fatal:nnn { exam-zh } { require-package-version } + { ctex~ v2.4.9~ 2017-04-01 } + } + +% 建议在模板开始处载入全部宏包,不要轻易改变加载顺序。 +\RequirePackage { etoolbox } +\RequirePackage { geometry } +\RequirePackage { fontspec } +\RequirePackage { xeCJK } +\RequirePackage { xeCJKfntef } +\RequirePackage { fancyhdr } +\RequirePackage { lastpage } +\RequirePackage { amsmath } +\RequirePackage { enumitem } +\RequirePackage { varwidth } + +\ExplSyntaxOff +\RequirePackage { tikzpagenodes } +\usetikzlibrary { decorations.markings } +\usetikzlibrary { decorations.text } +\ExplSyntaxOn + +\RequirePackage { exam-zh-font } +\RequirePackage { exam-zh-question } +\RequirePackage { exam-zh-choices } +\RequirePackage { exam-zh-symbols } +\RequirePackage { exam-zh-chinese-english } + +\AtEndPreamble + { + \RequirePackage { hyperref } + \hypersetup + { + bookmarksnumbered = true, + psdextra = true, + unicode = true, + hidelinks + } + } + + +% 对冲突的宏包报错。 +\msg_new:nnn { exam-zh } { package-conflict } + { The~ "#2"~ package~ is~ incompatible~ with~ "#1". } + +\cs_new:Npn \examzh_package_conflict:nn #1#2 + { + \AtEndOfPackageFile* {#1} + { + \AtBeginOfPackageFile* {#2} + { \msg_error:nnnn { exam-zh } { package-conflict } {#1} {#2} } + } + } + +\examzh_package_conflict:nn { unicode-math } { amscd } +\examzh_package_conflict:nn { unicode-math } { amsfonts } +\examzh_package_conflict:nn { unicode-math } { amssymb } +\examzh_package_conflict:nn { unicode-math } { bbm } +\examzh_package_conflict:nn { unicode-math } { bm } +\examzh_package_conflict:nn { unicode-math } { eucal } +\examzh_package_conflict:nn { unicode-math } { eufrak } +\examzh_package_conflict:nn { unicode-math } { mathrsfs } +\examzh_package_conflict:nn { unicode-math } { newtxmath } +\examzh_package_conflict:nn { unicode-math } { upgreek } + +\examzh_package_conflict:nn { enumitem } { paralist } + + +% 标点处理 +\tl_const:Nn \c__examzh_fwid_full_stop_tl { ^^^^ff0e } + +\keys_define:nn { exam-zh } + { style .meta:nn = { exam-zh / style } {#1} } +\keys_define:nn { exam-zh / style } + { + fullwidth-stop .choice:, + fullwidth-stop .value_required:n = true, + fullwidth-stop / catcode .code:n = + { + \__examzh_set_fullwidth_stop_catcode: + }, + fullwidth-stop / false .code:n = { } + } +\cs_new:Npn \__examzh_set_fullwidth_stop_catcode: + { + \char_set_active_eq:NN ^^^^3002 \c__examzh_fwid_full_stop_tl + \char_set_catcode_active:N ^^^^3002 + } + +\keys_set:nn { exam-zh / style } + { + fullwidth-stop = false + } + +\keys_set:nn { ctex } + { + % 修改目录层级 + tocdepth = 0, + chapter = + { + numbering = false, + beforeskip = -4ex, + afterskip = 4ex minus 1ex + } + } + +% 师生两版 + +% 用户自定义统一控制的预设 (将所需要控制的键值进行预设置) + +\NewDocumentCommand { \ExamPrintAnswerSet } { O{} m } + % #1: 命令 + % #2: 键值 foo/bar + { + \clist_const:Nn \g__examzh_print_answer_cmd_set_clist {#1} + \clist_const:Nn \g__examzh_print_answer_keys_set_clist {#2} + } + +\NewDocumentCommand { \ExamPrintAnswer } { } + { + \clist_use:Nn \g__examzh_print_answer_cmd_set_clist {} + \clist_if_empty:NF \g__examzh_print_answer_keys_set_clist + { + \keys_set:nx { exam-zh } + { \g__examzh_print_answer_keys_set_clist } + } + } + + + +\str_new:N \l__examzh_latexmk_engine_str +\str_new:N \g__examzh_student_version_jobname_str +\str_new:N \l__examzh_student_version_suffix_str +\str_const:Nn \l__examzh_latexmk_str { latexmk } + +\keys_define:nn { exam-zh / style } + { + student-version-suffix .code:n = + { \str_set:Nn \l__examzh_student_version_suffix_str {#1} }, + student-version-cleanaux .bool_set:N = \l__examzh_student_version_clean_aux_bool + } +\keys_set:nn { exam-zh / style } + { + student-version-suffix = { _student_version }, + student-version-cleanaux = true + } + +\cs_new:Nn \__examzh_build_student_version_jobname: + { + \str_gset:Nx \g__examzh_student_version_jobname_str { \c_sys_jobname_str } + \str_gremove_all:Nn \g__examzh_student_version_jobname_str { " } + \str_gput_left:Nn \g__examzh_student_version_jobname_str { " } + \str_gput_right:Nx \g__examzh_student_version_jobname_str { \l__examzh_student_version_suffix_str } + \str_gput_right:Nn \g__examzh_student_version_jobname_str { " } + } + +\AtEndPreamble + { + \sys_if_shell_unrestricted:T + { + \str_set:Nn \l__examzh_latexmk_engine_str { -xelatex } + \__examzh_build_student_version_jobname: + \sys_shell_now:x + { + \l__examzh_latexmk_str \c_space_tl + \l__examzh_latexmk_engine_str \c_space_tl + -pretex=' + % \string\RequirePackage{etoolbox} + % \string\BeforeBeginEnvironment{document}{\string\ExamPrintAnswer} + \string\AddToHook{env/document/before}{\string\ExamPrintAnswer} + % \string\AtBeginDocument{\string\ExamPrintAnswer} + ' \c_space_tl + -usepretex \c_space_tl + -jobname=\g__examzh_student_version_jobname_str \c_space_tl + \c_sys_jobname_str + \bool_if:NT \l__examzh_student_version_clean_aux_bool + { + && + \l__examzh_latexmk_str \c_space_tl + \l__examzh_latexmk_engine_str \c_space_tl + -c \c_space_tl + -jobname=\g__examzh_student_version_jobname_str \c_space_tl + \c_sys_jobname_str + } + } + \sys_shell_now:x + { + \l__examzh_latexmk_str \c_space_tl + \l__examzh_latexmk_engine_str \c_space_tl + \c_sys_jobname_str + \bool_if:NT \l__examzh_student_version_clean_aux_bool + { + && + \l__examzh_latexmk_str \c_space_tl + \l__examzh_latexmk_engine_str \c_space_tl + -c \c_space_tl + \c_sys_jobname_str + } + } + \stop + } + } + + +% 处理目录 +\patchcmd { \tableofcontents } + { \@starttoc{toc} } + { + \thispagestyle { empty } + \pagestyle { empty } + \@starttoc{toc} + } + {}{\fail} +\cs_set_eq:NN \t@bleofcontents \tableofcontents +\RenewDocumentCommand { \tableofcontents } { } + { + \newpage + \int_set:Nn \c@page { 0 } + \group_begin: + % \str_case:VnT \g__examzh_sealline_scope_str + % { + % { everypage } {} + % { oddpage } {} + % } + % { + % \RemoveFromHook { shipout / background } + \cs_set_eq:NN \onecolumn \twocolumn + \bool_set_true:N \g__examzh_page_show_chapter_bool + \keys_set:nn { ctex } + { + chapter = + { + beforeskip = 1pt, + afterskip = 2ex minus 1ex + } + } + \t@bleofcontents + \group_end: + \newpage + % 将页码计数器重设置为 1 + \int_set:Nn \c@page { 1 } + } + +\AtEndPreamble + { + % A3 情况 separate 的目录页码需要改为 2* -1 + \bool_lazy_and:nnT + { + ! \bool_if_p:c { g__examzh_page_size_a4paper_bool } + } + { + ! \bool_if_p:c { g__examzh_page_a3paper_foot_common_bool } + } + { + \cs_set_eq:Nc \addcontentsline { __examzh_addcontentsline_a3paper_separate:nnn } + } + } +% https://tex.stackexchange.com/questions/650823/why-my-patch-to-addcontentsline-is-broken-in-atendpreamble-and-bool-ifnt +% 改自 hyperref.sty +\cs_set:cpn { __examzh_addcontentsline_a3paper_separate:nnn } #1#2#3 + { + \begingroup + \let\label\@gobble + \ifx\@currentHref\@empty + \Hy@Warning{ + No destination for bookmark of \string\addcontentsline,% + \MessageBreak destination is added% + } + \phantomsection + \fi + \expandafter\ifx\csname toclevel@#2\endcsname\relax + \begingroup + \def\Hy@tempa{#1} + \ifx\Hy@tempa\Hy@bookmarkstype + \Hy@WarningNoLine{ + bookmark level for unknown #2 defaults to 0% + } + \else + \Hy@Info{bookmark level for unknown #2 defaults to 0}% + \fi + \endgroup + \expandafter\gdef\csname toclevel@#2\endcsname{0}% + \fi + \edef\Hy@toclevel{\csname toclevel@#2\endcsname}% + \Hy@writebookmark{\csname the#2\endcsname}% + {#3} + {\@currentHref} + {\Hy@toclevel} + {#1} + \ifHy@verbose + \begingroup + \def\Hy@tempa{#3} + \@onelevel@sanitize\Hy@tempa + \let\temp@online\on@line + \let\on@line\@empty + \Hy@Info{ + bookmark\temp@online:\MessageBreak + thecounter {\csname the#2\endcsname}\MessageBreak + text {\Hy@tempa}\MessageBreak + reference {\@currentHref}\MessageBreak + toclevel {\Hy@toclevel}\MessageBreak + type {#1} + } + \endgroup + \fi + \addtocontents{#1}{ + \protect\contentsline{#2}{#3} + % {\thepage} + { \int_eval:n { 2 * \c@page - 1 } } + {\@currentHref}\protected@file@percent + } + \endgroup + } +\keys_define:nn { exam-zh / page } + { + show-chapter .bool_gset:N = \g__examzh_page_show_chapter_bool + } +\keys_set:nn { exam-zh / page } + { + show-chapter = true + } + +\cs_set_eq:NN \__examzh_chapter:nn \chapter +\cs_new:Npn \__examzh_chapter_star:n #1 + { + \__examzh_chapter:nn * {#1} + } +\RenewDocumentCommand{ \chapter }{ s o m } + { + \keys_set:nn { exam-zh / question } + { index = 1 } + \int_set:Nn \c@section { 0 } + \bool_if:NTF \g__examzh_page_show_chapter_bool + { + \IfBooleanTF {#1} + { \__examzh_chapter_star:n {#3} } + { + \IfNoValueTF {#2} + { \__examzh_chapter:nn {#3} } + { \__examzh_chapter:nn [#2] {#3} } + } + \pagestyle { plain } + } + { + \IfBooleanF {#1} + { + \newpage + % 只录入目录 + \phantomsection + \addcontentsline { toc } { chapter } {#3} + \pagestyle { plain } + } + \clearpage + } + } + +% 纸张和页面布局 + +% 控制 a3paper 和 a4paper +\bool_new:c { g__examzh_page_size_a4paper_bool } +% a3paper 的页脚:两页共用一个或者仍然一页一个 +\bool_new:c { g__examzh_page_a3paper_foot_common_bool } + +\keys_define:nn { exam-zh / page } + { + % 页面大小 + size .choice:, + size / a3paper .code:n = + { + \bool_gset_false:c { g__examzh_page_size_a4paper_bool } + }, + size / a4paper .code:n = + { + \bool_gset_true:c { g__examzh_page_size_a4paper_bool } + }, + size .value_required:n = true, + % 页脚的类型 + foot-type .choice:, + foot-type / common .code:n = + { + \bool_gset_true:c + { g__examzh_page_a3paper_foot_common_bool } + }, + foot-type / separate .code:n = + { + \bool_gset_false:c + { g__examzh_page_a3paper_foot_common_bool } + } + } +\keys_set:nn { exam-zh / page } + { + size = a4paper, + foot-type = separate, + } + +\keys_define:nn { exam-zh } + { + page .meta:nn = { exam-zh / page } {#1} + } + + +% 字体 + +% 中文字体 + +% 在 ctex 的字体配置的基础上进行一些修改 +% 将苹方和微软雅黑分别替换为华文黑体和中易黑体 + +\str_if_eq:onTF { \g__ctex_fontset_tl } { mac } + { + % \setCJKmainfont{Source~Han~Serif~SC} + % [ + % ItalicFont = FZKai-Z03, + % ] + \setCJKsansfont { Heiti~ SC~ Light } [ BoldFont = Heiti~ SC~ Medium ] + } + { + \str_if_eq:onT { \g__ctex_fontset_tl } { windows } + { + % \setCJKmainfont{Source~Han~Serif~SC} + % [ + % ItalicFont = FZKai-Z03, + % ] + \setCJKsansfont { SimHei } + } + } + +% 罗马数字使用中文字体 +\xeCJKDeclareCharClass { CJK } { "2160 -> "217F } +% 带圈数字 +\xeCJKDeclareCharClass { CJK } { "2460 -> "2473 } + + +% 如果有内容较高(如分式)使得行间距小于 0.5em,则将其增加至 0.5em。 +\dim_set:Nn \lineskiplimit { .5em } +\skip_set:Nn \lineskip { .5em } + + + +% 设置 enumitem 列表格式 +\keys_define:nn { exam-zh / list } + { + step-name .tl_set:N = \l__examzh_list_step_name_tl, + method-name .tl_set:N = \l__examzh_list_method_name_tl, + case-name .tl_set:N = \l__examzh_list_case_name_tl, + step-punct .tl_set:N = \l__examzh_list_step_punct_tl, + method-punct .tl_set:N = \l__examzh_list_method_punct_tl, + case-punct .tl_set:N = \l__examzh_list_case_punct_tl, + } +\keys_set:nn { exam-zh / list } + { + step-name = 步骤, + method-name = 方法, + case-name = 情形, + step-punct = ., + method-punct = , + case-punct = ., + } +\keys_define:nn { exam-zh } + { list .meta:nn = { exam-zh / list } {#1} } + +\setlist{nosep} + +\setlist[enumerate, 1] + { + labelindent = \parindent, + leftmargin = *, + label = { \arabic * .} + } + +\setlist[enumerate, 2] + { + left = 2em, + labelsep = 0pt, + label = { ( \arabic * ) } + } + +% 多种方法: method环境 +\newlist{method}{enumerate}{1} +\setlist[method, 1] + { + label = {\bfseries \l__examzh_list_method_name_tl \zhnum*\l__examzh_list_method_punct_tl}, + labelindent = !, + labelwidth = 1.3cm, + labelsep* = 0.5em, + leftmargin = 1.4cm + } +% 分类讨论: case环境 +\newlist{case}{enumerate}{2} +\setlist[case, 1] + { + label = {\bfseries \l__examzh_list_case_name_tl \arabic*\l__examzh_list_case_punct_tl}, + % labelindent=-3em ,labelwidth=1.3cm, labelsep*=1em, leftmargin=20pt + labelindent = !, + labelwidth = 1.3cm, + labelsep* = 0.5em, + leftmargin = 1.7cm + % labelindent=\parindent, leftmargin=0pt, widest=0, itemindent=* + } +\setlist[case, 2] + { + label = {\bfseries \l__examzh_list_case_name_tl \arabic{casei}.\arabic*\l__examzh_list_case_punct_tl}, + % labelindent=-1em ,labelwidth=1.3cm, labelsep*=1em, leftmargin =20pt + labelindent = -0.5em, + labelwidth = 1.3cm, + labelsep* = 0.5em, + leftmargin = 0cm + } +% 分步: step环境 +\newlist{step}{enumerate}{2} +\setlist[step, 1] + { + label = {\bfseries \l__examzh_list_step_name_tl \arabic*\l__examzh_list_step_punct_tl}, + labelindent = !, + labelwidth = 1.3cm, + labelsep* = 0.5em, + leftmargin = 1.7cm + % labelindent=\parindent, leftmargin = 0pt, widest = 0, itemindent = * + } +\setlist[step, 2] + { + label = {\bfseries \l__examzh_list_step_name_tl \arabic{stepi}.\arabic*\l__examzh_list_step_punct_tl}, + labelindent = -0.5em, + labelwidth = 1.3cm, + labelsep* = 0.5em, + leftmargin = 0cm + } + +% 横向的个人信息 + +\clist_new:N \l__examzh_horizontal_information_clist + +\NewDocumentCommand \information { O{\quad} m } +% #1 分隔符 +% #2 信息内容 + { + \clist_set:Nn \l__examzh_horizontal_information_clist {#2} + \__examzh_print_horizontal_information:n {#1} + } +\cs_new:Npn \__examzh_print_horizontal_information:n #1 + { + \par \null \hfill + \clist_use:Nn \l__examzh_horizontal_information_clist {#1} + \hfill \null \par + } + +% 警告,如“在此卷上答题无效” +\NewDocumentCommand \warning { O{\large \sffamily \bfseries} m } + { + \group_begin: + #1 + \hfill #2 \hfill \null + \group_end: + \par + } + + +% 标题处理 +\keys_define:nn { exam-zh / title } + { + title-format .tl_set:N = \l__examzh_title_format_tl, + subject-format .tl_set:N = \l__examzh_subject_format_tl, + top-sep .skip_set:N = \l__examzh_title_top_sep_skip, + bottom-sep .skip_set:N = \l__examzh_title_bottom_sep_skip, + } +\keys_set:nn { exam-zh / title } + { + title-format = \Large, + subject-format = \sffamily \bfseries \huge, + top-sep = -.5em plus 0.3em minus 0.2em, + bottom-sep = 0em plus 0.3em minus 0.2em, + } +\keys_define:nn { exam-zh } + { title .meta:nn = { exam-zh / title } {#1} } + +\cs_new_protected:Npn \__examzh_spread_box:nn #1#2 + { + \mode_leave_vertical: + \hbox_to_wd:nn {#1} + { \tl_map_inline:xn {#2} { ##1 \hfil } \unskip } + } + +% 科目 +\tl_new:N \l__exam_zh_subject_tl +\NewDocumentCommand \subject { o m } + { + \IfNoValueTF {#1} + { + % 默认使用自然宽度 + \hbox_set:Nn \l_tmpa_box {#2} + \dim_set:Nn \l_tmpa_dim { \box_wd:N \l_tmpa_box * 2 } + \tl_set:Nn \l__exam_zh_subject_tl + { + \__examzh_spread_box:nn { \l_tmpa_dim } {#2} + } + } + { + % 手动调整宽度 + \tl_set:Nn \l__exam_zh_subject_tl + { + \__examzh_spread_box:nn {#1} {#2} + } + } + } + +% 输出标题 +\RenewDocumentCommand \maketitle { } + { + \par + \vspace { \l__examzh_title_top_sep_skip } + \begin { center } + \let \footnote \thanks + { \l__examzh_title_format_tl \@title \par } + \tl_if_blank:VF \l__exam_zh_subject_tl + { + \addvspace { 1em } + { \l__examzh_subject_format_tl \l__exam_zh_subject_tl } + } + \end { center } + \par + \vspace { \l__examzh_title_bottom_sep_skip } + } + + + +\prg_new_conditional:Npnn \examzh_if_defined:N #1 { T , F , TF } + { + \if_meaning:w #1 \@undefined + \prg_return_false: + \else: + \prg_return_true: + \fi: + } + +% 绝密 启用前 +\NewDocumentCommand \secret { O{\bfseries} } + { + \par \noindent + \group_begin: + #1 + 绝密 $\bigstar$ 启用前 + \group_end: + \par + } + +% 祝考试顺利 +\NewDocumentCommand \goodluck { O{祝考试顺利} } + { + \group_begin: + \centering + \examzh_if_defined:NTF \lishu + { \lishu } + { \bfseries } + \Large + $\bigstar$ #1 $\bigstar$ + \par + \group_end: + } + + +% 注意事项环境 notice +\keys_define:nn { exam-zh / notice } + { + label .tl_set:N = \l__examzh_notice_label_tl, + label-format .tl_set:N = \l__examzh_notice_label_format_tl, + top-sep .skip_set:N = \l__examzh_notice_top_sep_skip, + bottom-sep .skip_set:N = \l__examzh_notice_bottom_sep_skip, + + } +\keys_set:nn { exam-zh / notice } + { + label = 注意事项:, + label-format = \sffamily \bfseries, + top-sep = .25em plus .25em minus .1em, + bottom-sep = .25em plus .25em minus .1em, + } +\NewDocumentEnvironment { notice } { O { } O { } } + { + \keys_set:nn { exam-zh / notice } {#1} + \par + \vspace { \l__examzh_notice_top_sep_skip } + \noindent + \group_begin: + \l__examzh_notice_label_format_tl + \l__examzh_notice_label_tl + \group_end: + \begin { enumerate } + [ + leftmargin = 0pt , + itemindent = 3.5em , + labelsep = 0.5em , + labelwidth = 1.5em , + align = right , + label = { \arabic * . } , + #2 + ] + } + { + \end { enumerate } + \vspace { \l__examzh_notice_bottom_sep_skip } + } + + +% 大题的标题使用 \ctexset 设置 \section 的格式 + +\ctexset + { + section = + { + format = \heiti \bfseries , + number = \chinese { section } , + aftername = { 、 } , + beforeskip = 2ex plus 1ex minus .5ex, + afterskip = 1ex plus .2ex minus 1ex + } + } + + +% 正体的 e 和 i +\NewDocumentCommand \eu { } { \mathrm{ e } } +\NewDocumentCommand \iu { } { \mathrm{ i } } + + +% 兼容 siunitx v2.x 的一些命令 +\AtEndOfPackageFile* { siunitx } + { + \ProvideDocumentCommand \unit { } { \si } + \ProvideDocumentCommand \qty { } { \SI } + \ProvideDocumentCommand \qtyproduct { } { \SI } + } + + + +% 密封线 +\str_new:N \g__examzh_sealline_odd_type_str +\str_new:N \g__examzh_sealline_even_type_str + +\keys_define:nn { exam-zh / sealline } + { + % 是否显示密封线 + show .bool_gset:N = \g__examzh_sealline_show_bool, + % 密封线类型(也理解为出现的类型,比如只在第一页,只在奇数页) + scope .choices:nn = + { firstpage, oddpage, everypage, first-and-last, mod-2, mod-3, mod-4, mod-6 } + { \str_gset:Nx \g__examzh_sealline_scope_str { \l_keys_choice_tl } }, + type .choices:nn = + { firstpage, oddpage, everypage, first-and-last, mod-2, mod-3, mod-4, mod-6 } + { \str_gset:Nx \g__examzh_sealline_scope_str { \l_keys_choice_tl } }, + % 线的厚度 + odd-line-thickness .dim_set:N = \g__examzh_sealline_odd_line_thickness_dim, + even-line-thickness .dim_set:N = \g__examzh_sealline_even_line_thickness_dim, + line-thickness .code:n = + { + \dim_set:Nn \g__examzh_sealline_odd_line_thickness_dim {#1} + \dim_set:Nn \g__examzh_sealline_even_line_thickness_dim {#1} + }, + % 线的偏移 + odd-line-xshift .dim_set:N = \g__examzh_sealline_odd_line_xshift_dim, + odd-line-yshift .dim_set:N = \g__examzh_sealline_odd_line_yshift_dim, + even-line-xshift .dim_set:N = \g__examzh_sealline_even_line_xshift_dim, + even-line-yshift .dim_set:N = \g__examzh_sealline_even_line_yshift_dim, + line-xshift .code:n = + { + \dim_gset:Nn \g__examzh_sealline_odd_line_xshift_dim {#1} + \dim_gset:Nn \g__examzh_sealline_even_line_xshift_dim {#1} + }, + line-yshift .code:n = + { + \dim_set:Nn \g__examzh_sealline_odd_line_yshift_dim {#1} + \dim_set:Nn \g__examzh_sealline_even_line_yshift_dim {#1} + }, + % 密封线的线类型 + % odd-line-type .str_set:N = \g__examzh_sealline_odd_type_str, + % even-line-type .str_set:N = \g__examzh_sealline_even_type_str, + odd-line-type .code:n = + { + \str_set:Nn \g__examzh_sealline_odd_type_str {#1} + }, + even-line-type .code:n = + { + \str_set:Nn \g__examzh_sealline_even_type_str {#1} + }, + line-type .code:n = + { + \str_gset:Nn \g__examzh_sealline_odd_type_str {#1} + \str_gset:Nn \g__examzh_sealline_even_type_str {#1} + }, + % 密封线路径的文字内容 + odd-text .tl_set:N = \g__examzh_sealline_odd_text_tl, + even-text .tl_set:N = \g__examzh_sealline_even_text_tl, + text .code:n = + { + \tl_gset:Nn \g__examzh_sealline_odd_text_tl {#1} + \tl_gset:Nn \g__examzh_sealline_even_text_tl {#1} + }, + % 密封线路径的文字内容偏移 + odd-text-xshift .dim_set:N = \g__examzh_sealline_odd_text_xshift_dim, + even-text-xshift .dim_set:N = \g__examzh_sealline_even_text_xshift_dim, + odd-text-yshift .dim_set:N = \g__examzh_sealline_odd_text_yshift_dim, + even-text-yshift .dim_set:N = \g__examzh_sealline_even_text_yshift_dim, + text-xshift .code:n = + { + \dim_gset:Nn \g__examzh_sealline_odd_text_xshift_dim {#1} + \dim_gset:Nn \g__examzh_sealline_even_text_xshift_dim {#1} + }, + text-yshift .code:n = + { + \dim_gset:Nn \g__examzh_sealline_odd_text_yshift_dim {#1} + \dim_gset:Nn \g__examzh_sealline_even_text_yshift_dim {#1} + }, + % 密封线路径文字的宽度 + odd-text-width .dim_set:N = \g__examzh_sealline_odd_text_width_dim, + even-text-width .dim_set:N = \g__examzh_sealline_even_text_width_dim, + text-width .code:n = + { + \dim_gset:Nn \g__examzh_sealline_odd_text_width_dim {#1} + \dim_gset:Nn \g__examzh_sealline_even_text_width_dim {#1} + }, + % 密封线路径文字的字体 + odd-text-format .tl_set:N = \g__examzh_sealline_odd_text_format_tl, + even-text-format .tl_set:N = \g__examzh_sealline_even_text_format_tl, + text-format .code:n = + { + \tl_gset:Nn \g__examzh_sealline_odd_text_format_tl {#1} + \tl_gset:Nn \g__examzh_sealline_even_text_format_tl {#1} + }, + % 密封线路径文字的方向 + odd-text-direction-vertical .bool_gset:N = \g__examzh_sealline_odd_text_direction_vertical_bool, + even-text-direction-vertical .bool_gset:N = \g__examzh_sealline_even_text_direction_vertical_bool, + text-direction-vertical .choice:, + text-direction-vertical / true .code:n = + { + \bool_gset_true:N \g__examzh_sealline_odd_text_direction_vertical_bool + \bool_gset_true:N \g__examzh_sealline_even_text_direction_vertical_bool + }, + text-direction-vertical / false .code:n = + { + \bool_gset_false:N \g__examzh_sealline_odd_text_direction_vertical_bool + \bool_gset_false:N \g__examzh_sealline_even_text_direction_vertical_bool + }, + % 密封线路径文字的防缩比例 + odd-text-xscale .fp_set:N = \g__examzh_sealline_odd_text_xscale_fp, + odd-text-yscale .fp_set:N = \g__examzh_sealline_odd_text_yscale_fp, + even-text-xscale .fp_set:N = \g__examzh_sealline_even_text_xscale_fp, + even-text-yscale .fp_set:N = \g__examzh_sealline_even_text_yscale_fp, + text-xscale .code:n = + { + \fp_gset:Nn \g__examzh_sealline_odd_text_xscale_fp {#1} + \fp_gset:Nn \g__examzh_sealline_even_text_xscale_fp {#1} + }, + text-yscale .code:n = + { + \fp_gset:Nn \g__examzh_sealline_odd_text_yscale_fp {#1} + \fp_gset:Nn \g__examzh_sealline_even_text_yscale_fp {#1} + }, + % 密封线上圆圈的参数 + % --控制显示-- + odd-circle-show .bool_set:N = \g__examzh_sealline_odd_circle_show_bool, + even-circle-show .bool_set:N = \g__examzh_sealline_even_circle_show_bool, + circle-show .choice:, + circle-show / true .code:n = + { + \bool_gset_true:N \g__examzh_sealline_odd_circle_show_bool + \bool_gset_true:N \g__examzh_sealline_even_circle_show_bool + }, + circle-show / false .code:n = + { + \bool_gset_false:N \g__examzh_sealline_odd_circle_show_bool + \bool_gset_false:N \g__examzh_sealline_even_circle_show_bool + }, + % --开始-- + odd-circle-start .fp_set:N = \g__examzh_sealline_odd_circle_start_fp, + even-circle-start .fp_set:N = \g__examzh_sealline_even_circle_start_fp, + circle-start .code:n = + { + \fp_gset:Nn \g__examzh_sealline_odd_circle_start_fp {#1} + \fp_gset:Nn \g__examzh_sealline_even_circle_start_fp {#1} + }, + % --结束-- + odd-circle-end .fp_set:N = \g__examzh_sealline_odd_circle_end_fp, + even-circle-end .fp_set:N = \g__examzh_sealline_even_circle_end_fp, + circle-end .code:n = + { + \fp_gset:Nn \g__examzh_sealline_odd_circle_end_fp {#1} + \fp_gset:Nn \g__examzh_sealline_even_circle_end_fp {#1} + }, + % --步长-- + odd-circle-step .dim_set:N = \g__examzh_sealline_odd_circle_step_dim, + even-circle-step .dim_set:N = \g__examzh_sealline_even_circle_step_dim, + circle-step .code:n = + { + \dim_gset:Nn \g__examzh_sealline_odd_circle_step_dim {#1} + \dim_gset:Nn \g__examzh_sealline_even_circle_step_dim {#1} + }, + % --直径-- + odd-circle-diameter .dim_set:N = \g__examzh_sealline_odd_circle_diameter_dim, + even-circle-diameter .dim_set:N = \g__examzh_sealline_even_circle_diameter_dim, + circle-diameter .code:n = + { + \dim_gset:Nn \g__examzh_sealline_odd_circle_diameter_dim {#1} + \dim_gset:Nn \g__examzh_sealline_even_circle_diameter_dim {#1} + }, + % --偏移-- + odd-circle-xshift .dim_set:N = \g__examzh_sealline_odd_circle_xshift_dim, + even-circle-xshift .dim_set:N = \g__examzh_sealline_even_circle_xshift_dim, + circle-xshift .code:n = + { + \dim_gset:Nn \g__examzh_sealline_odd_circle_xshift_dim {#1} + \dim_gset:Nn \g__examzh_sealline_even_circle_xshift_dim {#1} + }, + % 学生信息 + % --内容-- + odd-info-content .clist_set:N = \g__examzh_sealline_odd_info_content_clist, + % --分隔符-- + odd-info-seperator .tl_set:N = \g__examzh_sealline_odd_info_seperator_tl, + % --对齐-- + odd-info-align .tl_set:N = \g__examzh_sealline_odd_info_align_tl, + % --偏移-- + odd-info-xshift .dim_set:N = \g__examzh_sealline_odd_info_xshift_dim, + odd-info-yshift .dim_set:N = \g__examzh_sealline_odd_info_yshift_dim, + } +\keys_set:nn { exam-zh / sealline } + { + show = false, + % scope = firstpage, + % scope = oddpage, + scope = everypage, + line-thickness = 1pt, + line-xshift = 8mm, + line-yshift = 0mm, + line-type = loosely-dashed, + text = 密封线内不得答题, + text-xshift = 11mm, + text-yshift = 0pt, + text-width = 0.8\textheight, + text-format = \zihao{4}\sffamily, + text-xscale = 1.0, + text-yscale = 0.8, + text-direction-vertical = false, + circle-show = true, + circle-start = 0.07, + circle-end = 0.92, + circle-step = 3.5em, + circle-diameter = 3mm, + circle-xshift = 8mm, + odd-info-content = { + {\kaishu 姓名}:{\underline{\hspace*{8em}}}, + {\kaishu 准考证号}:{\underline{\hspace*{8em}}}, + {\kaishu 考场号}:{\underline{\hspace*{8em}}}, + {\kaishu 座位号}:{\underline{\hspace*{8em}}} + }, + odd-info-seperator = \hspace*{3em}, + odd-info-align = center, + odd-info-xshift = 20mm, + odd-info-yshift = 0mm + } +\keys_define:nn { exam-zh } + { sealline .meta:nn = { exam-zh / sealline } {#1} } + +% 只在第一页出现 +\cs_new:Npn \__examzh_sealline_scope_firstpage: + { + \AddToHook { shipout / firstpage } [ sealline ] + { + \put (0cm, 0cm) + { \__examzh_sealline_odd: } + } + } +% 只在第一页和最后一页出现 +\cs_new:Npn \__examzh_sealline_scope_firstpage_and_lastpage: + { + \AddToHook { shipout / firstpage } [ sealline ] + { + \put (0cm, 0cm) + { \__examzh_sealline_odd: } + } + \AddToHook { shipout / lastpage } [ sealline ] + { + \put (0cm, 0cm) + { + \int_if_odd:nTF { \c@page } + { \__examzh_sealline_odd: } + { \__examzh_sealline_even: } + } + } + } +% 只在奇数页出现 +\cs_new:Npn \__examzh_sealline_scope_oddpage: + { + \AddToHook { shipout / background } [ sealline ] + { + \put (0cm, 0cm) + { + \int_if_odd:nT { \c@page } + { \__examzh_sealline_odd: } + } + } + } +% 每页都有,奇偶不同 +\cs_new:Npn \__examzh_sealline_scope_everypage: + { + \AddToHook { shipout / background } [ sealline ] + { + \put (0cm, 0cm) + { + \int_if_odd:nTF { \c@page } + { \__examzh_sealline_odd: } + { \__examzh_sealline_even: } + } + } + } +% mod 2 = 1 的类型 +\cs_new:cpn { __examzh_sealline_scope_mod_2_equals_1: } + { + \AddToHook { shipout / background } [ sealline ] + { + \put (0cm, 0cm) + { + \int_compare:nNnT { \int_mod:nn { \c@page } { 2 } } = {1} { \__examzh_sealline_odd: } + } + } + } +% mod 3 = 1 的类型 +\cs_new:cpn { __examzh_sealline_scope_mod_3_equals_1: } + { + \AddToHook { shipout / background } [ sealline ] + { + \put (0cm, 0cm) + { + \int_compare:nNnT { \int_mod:nn { \c@page } { 3 } } = {1} { \__examzh_sealline_odd: } + } + } + } +% mod 4 = 1 的类型 +\cs_new:cpn { __examzh_sealline_scope_mod_4_equals_1: } + { + \AddToHook { shipout / background } [ sealline ] + { + \put (0cm, 0cm) + { + \int_compare:nNnT { \int_mod:nn { \c@page } { 4 } } = {1} { \__examzh_sealline_odd: } + } + } + } +% mod 6 = 1 的类型 +\cs_new:cpn { __examzh_sealline_scope_mod_6_equals_1: } + { + \AddToHook { shipout / background } [ sealline ] + { + \put (0cm, 0cm) + { + \int_compare:nNnT { \int_mod:nn { \c@page } { 6 } } = {1} { \__examzh_sealline_odd: } + } + } + } + + +\AtBeginDocument + { \__examzh_sealline_set: } +\cs_new:Npn \__examzh_sealline_set: + { + \bool_if:NT \g__examzh_sealline_show_bool + { + \__examzh_sealline_scope_set: + \str_case:Vn \g__examzh_sealline_scope_str + { + { firstpage } { \__examzh_sealline_scope_firstpage: } + { oddpage } { \__examzh_sealline_scope_oddpage: } + { everypage } { \__examzh_sealline_scope_everypage: } + { first-and-last } { \__examzh_sealline_scope_firstpage_and_lastpage: } + { mod-2 } { \use:c { __examzh_sealline_scope_mod_2_equals_1: } } + { mod-3 } { \use:c { __examzh_sealline_scope_mod_3_equals_1: } } + { mod-4 } { \use:c { __examzh_sealline_scope_mod_4_equals_1: } } + { mod-6 } { \use:c { __examzh_sealline_scope_mod_6_equals_1: } } + } + } + } +\cs_new:Npn \__examzh_sealline_scope_set: + { + \tl_gset:Nx \g__examzh_sealline_odd_type_parameter_tl + { + \str_case:Vn \g__examzh_sealline_odd_type_str + { + { solid } { solid } + { dotted } { dotted } + { densely-dotted } { densely~dotted } + { loosely-dotted } { loosely~dotted } + { dashed } { dashed } + { densely-dashed } { densely~dashed } + { loosely-dashed } { loosely~dashed } + { dash-dot } { dash~dot } + { densely-dash-dot } { densely~dash~dot } + { loosely-dash-dot } { loosely~dash~dot } + { dash-dot-dot } { dash~dot~dot } + { densely-dash-dot-dot } { densely~dash~dot~dot } + { loosely-dash-dot-dot } { loosely~dash~dot~dot } + } + } + \tl_gset:Nx \g__examzh_sealline_even_type_parameter_tl + { + \str_case:Vn \g__examzh_sealline_even_type_str + { + { solid } { solid } + { dotted } { dotted } + { densely-dotted } { densely~dotted } + { loosely-dotted } { loosely~dotted } + { dashed } { dashed } + { densely-dashed } { densely~dashed } + { loosely-dashed } { loosely~dashed } + { dash-dot } { dash~dot } + { densely-dash-dot } { densely~dash~dot } + { loosely-dash-dot } { loosely~dash~dot } + { dash-dot-dot } { dash~dot~dot } + { densely-dash-dot-dot } { densely~dash~dot~dot } + { loosely-dash-dot-dot } { loosely~dash~dot~dot } + } + } + } + +\keys_define:nn { exam-zh / page } + { + show-columnline .bool_set:N = \l__examzh_show_columnline_bool, + columnline-width .dim_set:N = \l__examzh_columnline_dim, + } +\keys_set:nn { exam-zh / page } + { + show-columnline = true, + columnline-width = 0.4pt + } + +\AtEndPreamble + { + \bool_if:cTF { g__examzh_page_size_a4paper_bool } + { + % a4paper + \bool_if:NTF \g__examzh_sealline_show_bool + { + % 有密封线 + \geometry + { + twoside, + paper = a4paper, + margin = 1in, + inner = 1.3in, + outer = 0.8in, + } + } + { + % 无密封线 + \geometry + { + paper = a4paper, + margin = 1in, + } + } + } + { + % a3paper + \bool_if:NT \l__examzh_show_columnline_bool + { \dim_set:Nn \columnseprule { \l__examzh_columnline_dim } } + \bool_if:NTF \g__examzh_sealline_show_bool + { + % 有密封线 + \geometry + { + twoside, + paper = a3paper, + landscape, + twocolumn, + columnsep = 30mm, + margin = 1in, + inner = 1.2in, + outer = 0.8in, + % showframe + } + } + { + % 无密封线 + \geometry + { + paper = a3paper, + landscape, + twocolumn, + columnsep = 30mm, + margin = 1in, + } + } + } + } + + +\cs_new:Npn \__examzh_sealline_odd: + { + \begin{tikzpicture} + [ + remember~picture, + overlay, + ] + % 密封线:线 + \__examzh_sealline_odd_line: + % 密封线:小圆圈 + \__examzh_sealline_odd_circle: + % 线上的文字 + \__examzh_sealline_odd_text_around_line: + % 学生信息 + \__examzh_sealline_odd_infomation: + \end{tikzpicture} + } + +\cs_new:Npn \__examzh_sealline_even: + { + \begin{tikzpicture}[remember~picture, overlay] + % 密封线:线 + \__examzh_sealline_even_line: + % 密封线:小圆圈 + \__examzh_sealline_even_circle: + % 线上的文字 + \__examzh_sealline_even_text_around_line: + \end{tikzpicture} + } + +% 线 +\cs_new:Npn \__examzh_sealline_odd_line: + { + \use:x + { + \exp_not:N \draw + [ + \g__examzh_sealline_odd_type_parameter_tl, + line~width = \dim_use:N \g__examzh_sealline_odd_line_thickness_dim + ] + } + ([xshift = -\g__examzh_sealline_odd_line_xshift_dim, yshift = -\g__examzh_sealline_odd_line_yshift_dim]current~page~text~area.north~west) + -- + ([xshift = -\g__examzh_sealline_odd_line_xshift_dim, yshift = \g__examzh_sealline_odd_line_yshift_dim]current~page~text~area.south~west); + } +\cs_new:Npn \__examzh_sealline_even_line: + { + \use:x + { + \exp_not:N \draw + [ + \g__examzh_sealline_even_type_parameter_tl, + line~width = \dim_use:N \g__examzh_sealline_even_line_thickness_dim + ] + } + ([xshift = \g__examzh_sealline_even_line_xshift_dim, yshift = -\g__examzh_sealline_even_line_yshift_dim]current~page~text~area.north~east) + -- + ([xshift = \g__examzh_sealline_even_line_xshift_dim, yshift = \g__examzh_sealline_even_line_yshift_dim]current~page~text~area.south~east); + } + +% 小圆圈 +\cs_new:Npn \__examzh_sealline_odd_circle: + { + \bool_if:NT \g__examzh_sealline_odd_circle_show_bool + { + \use:x + { + \exp_not:N + \fill + [ + decorate, + decoration = + { + markings, + mark = + between~positions~ + \fp_use:N \g__examzh_sealline_odd_circle_start_fp + ~and~ + \fp_use:N \g__examzh_sealline_odd_circle_end_fp + ~step~ + \dim_use:N \g__examzh_sealline_odd_circle_step_dim + ~with + { + \exp_not:N + \node + [ + circle, + draw = black, + fill = white, + minimum~size = \dim_use:N \g__examzh_sealline_odd_circle_diameter_dim + ] + {}; + } + } + ] + } + ([xshift = -\g__examzh_sealline_odd_circle_xshift_dim]current~page~text~area.north~west) + -- + ([xshift = -\g__examzh_sealline_odd_circle_xshift_dim]current~page~text~area.south~west); + } + } +\cs_new:Npn \__examzh_sealline_even_circle: + { + \bool_if:NT \g__examzh_sealline_even_circle_show_bool + { + \use:x + { + \exp_not:N + \fill + [ + decorate, + decoration = + { + markings, + mark = + between~positions~ + \fp_use:N \g__examzh_sealline_even_circle_start_fp + ~and~ + \fp_use:N \g__examzh_sealline_even_circle_end_fp + ~step~ + \dim_use:N \g__examzh_sealline_even_circle_step_dim + ~with + { + \exp_not:N + \node + [ + circle, + draw = black, + fill = white, + minimum~size = \dim_use:N \g__examzh_sealline_even_circle_diameter_dim + ] + {}; + } + } + ] + } + ([xshift = \g__examzh_sealline_even_circle_xshift_dim]current~page~text~area.north~east) + -- + ([xshift = \g__examzh_sealline_even_circle_xshift_dim]current~page~text~area.south~east); + } + } +% 线上的文字(密封线外不得答题) +\cs_new_protected:Npn \__examzh_sealline_odd_spread_box:nn #1#2 + { + \mode_leave_vertical: + \bool_if:NTF \g__examzh_sealline_odd_text_direction_vertical_bool + { + \hbox_set_to_wd:Nnn \l_tmpa_box {#1} + { + \tl_set:Nx \l_tmpa_tl {#2} + \tl_reverse:N \l_tmpa_tl + \tl_map_inline:xn { \l_tmpa_tl } + { + \hbox_set:Nn \l_tmpb_box {##1} + \box_rotate:Nn \l_tmpb_box { -90 } + \box_use_drop:N \l_tmpb_box + \hfil + } + \unskip + } + } + { + \hbox_set_to_wd:Nnn \l_tmpa_box {#1} + { + \tl_map_inline:xn {#2} { ##1 \hfil } \unskip + } + } + \box_scale:Nnn \l_tmpa_box + { \fp_use:N \g__examzh_sealline_odd_text_xscale_fp } + { \fp_use:N \g__examzh_sealline_odd_text_yscale_fp } + \box_rotate:Nn \l_tmpa_box { 90 } + \box_move_down:nn + { #1 / 2 } + { \box_use_drop:N \l_tmpa_box } + } +\cs_new_protected:Npn \__examzh_sealline_even_spread_box:nn #1#2 + { + \mode_leave_vertical: + \bool_if:NTF \g__examzh_sealline_odd_text_direction_vertical_bool + { + \hbox_set_to_wd:Nnn \l_tmpa_box {#1} + { + \tl_map_inline:xn {#2} + { + \hbox_set:Nn \l_tmpb_box {##1} + \box_rotate:Nn \l_tmpb_box { 90 } + \box_use_drop:N \l_tmpb_box + \hfil + } + \unskip + } + } + { + \hbox_set_to_wd:Nnn \l_tmpa_box {#1} + { + \tl_map_inline:xn {#2} { ##1 \hfil } \unskip + } + } + \box_scale:Nnn \l_tmpa_box + { \fp_use:N \g__examzh_sealline_odd_text_xscale_fp } + { \fp_use:N \g__examzh_sealline_odd_text_yscale_fp } + \box_rotate:Nn \l_tmpa_box { -90 } + \box_move_up:nn + { #1 / 2 } + { \box_use_drop:N \l_tmpa_box } + } +\cs_new:Npn \__examzh_sealline_odd_text_around_line: + { + \node [ anchor = east ] + at ([xshift = -\g__examzh_sealline_odd_text_xshift_dim, yshift = \g__examzh_sealline_odd_text_yshift_dim]current~page~text~area.west) + { + \g__examzh_sealline_odd_text_format_tl + \__examzh_sealline_odd_spread_box:nn { \g__examzh_sealline_odd_text_width_dim } + { \g__examzh_sealline_odd_text_tl } + }; + } +\cs_new:Npn \__examzh_sealline_even_text_around_line: + { + \bool_if:NTF \g__examzh_sealline_odd_text_direction_vertical_bool + { + \dim_set_eq:NN \l_tmpa_dim \g__examzh_sealline_even_text_yshift_dim + } + { + \dim_set:Nn \l_tmpa_dim { - \g__examzh_sealline_even_text_yshift_dim } + } + \dim_set_eq:NN \g__examzh_sealline_even_text_yshift_dim \l_tmpa_dim + \node [ anchor = west ] + at ([xshift = \g__examzh_sealline_even_text_xshift_dim, yshift = \g__examzh_sealline_even_text_yshift_dim]current~page~text~area.east) + { + \g__examzh_sealline_even_text_format_tl + \__examzh_sealline_even_spread_box:nn { \g__examzh_sealline_even_text_width_dim } + { \g__examzh_sealline_even_text_tl } + }; + } +% 学生信息 +\cs_new:Npn \__examzh_sealline_odd_infomation: + { + \use:x + { + \exp_not:N + \path + [ + decorate, + decoration = + { + text~along~path, + text~align = \g__examzh_sealline_odd_info_align_tl, + reverse~path, + text = { + \clist_use:Nn \g__examzh_sealline_odd_info_content_clist + { { \g__examzh_sealline_odd_info_seperator_tl } } + } + } + ] + } + ([xshift = -\g__examzh_sealline_odd_info_xshift_dim, yshift = 0mm]current~page~text~area.north~west) + -- + ([xshift = -\g__examzh_sealline_odd_info_xshift_dim, yshift = \g__examzh_sealline_odd_info_yshift_dim]current~page~text~area.south~west); + } + +% 信息的方格 +\keys_define:nn { exam-zh / square } + { + x-length .dim_set:N = \l__examzh_information_square_x_dim, + y-length .dim_set:N = \l__examzh_information_square_y_dim, + baseline .dim_set:N = \l__examzh_information_square_baseline_dim, + linewidth .dim_set:N = \l__examzh_information_square_linewidth_dim, + xshift .dim_set:N = \l__examzh_information_square_xshift_dim + } +\keys_set:nn { exam-zh / square } + { + x-length = 1.4em, + y-length = 1.2em, + baseline = 3pt, + linewidth = 0.4pt, + } +\keys_define:nn { exam-zh } + { square .meta:nn = { exam-zh / square } {#1} } +\cs_new:Npn \__examzh_information_square_single: + { + \begin{tikzpicture}[baseline = \l__examzh_information_square_baseline_dim] + \draw[line~width = \l__examzh_information_square_linewidth_dim] (0,0) rectangle + ( \l__examzh_information_square_x_dim , \l__examzh_information_square_y_dim); + \end{tikzpicture} + } +\cs_new:Npn \__examzh_information_square_multiple:n #1 + { + \dim_compare:nNnT { \l__examzh_information_square_xshift_dim } = { 0pt } + { + \dim_set_eq:NN + \l__examzh_information_square_xshift_dim + \l__examzh_information_square_linewidth_dim + } + \int_compare:nNnTF { #1 } = { 1 } + { \__examzh_information_square_single: } + { + \__examzh_information_square_single: + \prg_replicate:nn { #1 - 1 } + { + \hspace*{ -\l__examzh_information_square_xshift_dim } + \__examzh_information_square_single: + } + } + } + +\NewDocumentCommand { \examsquare } { O{ } m } + { + \group_begin: + \keys_set:nn { exam-zh / square } { #1 } + \__examzh_information_square_multiple:n { #2 } + \group_end: + } + + +% 页眉和页脚 + + +\keys_define:nn { exam-zh / page } + { + show-foot .bool_set:N = \l__examzh_show_foot_bool, + foot-content .tl_set:N = \l__examzh_foot_content_format_tl + % foo, bar: foo <page> bar + % foo, bar, baz: foo <page> bar <lastpage> baz + } +\keys_set:nn { exam-zh / page } + { + show-foot = true, + foot-content = {数学试题第;页(共~;页)} + } + +\int_new:N \l__examzh_foot_content_count_semicolon_int +\tl_new:N \l__examzh_foot_content_before_page_tl +\tl_new:N \l__examzh_foot_content_after_page_tl +\tl_new:N \l__examzh_foot_content_after_lastpage_tl +\cs_generate_variant:Nn \regex_count:nnN { nxN } + +\cs_new:Npn \__examzh_foot_content_only_page_input:ww #1 ; #2 \q_stop + { + \tl_set:Nn \l__examzh_foot_content_before_page_tl {#1} + \tl_set:Nn \l__examzh_foot_content_after_page_tl {#2} + } +\cs_new:Npn \__examzh_foot_content_only_page_input:n #1 + { + \__examzh_foot_content_only_page_input:ww #1 \q_stop + } +\cs_generate_variant:Nn \__examzh_foot_content_only_page_input:n { V } + +\cs_new:Npn \__examzh_foot_content_page_and_lastpage_input:www #1 ; #2 ; #3 \q_stop + { + \tl_set:Nn \l__examzh_foot_content_before_page_tl {#1} + \tl_set:Nn \l__examzh_foot_content_after_page_tl {#2} + \tl_set:Nn \l__examzh_foot_content_after_lastpage_tl {#3} + } +\cs_new:Npn \__examzh_foot_content_page_and_lastpage_input:n #1 + { + \__examzh_foot_content_page_and_lastpage_input:www #1 \q_stop + } +\cs_generate_variant:Nn \__examzh_foot_content_page_and_lastpage_input:n { V } + +\cs_new:Npn \__examzh_foot_content_no_page_or_lastpage_output: + { + \l__examzh_foot_content_format_tl + } +\cs_new:Npn \__examzh_foot_content_only_page_output: + { + \l__examzh_foot_content_before_page_tl \thepage { } + \l__examzh_foot_content_after_page_tl + } +\cs_new:cpn { __examzh_foot_content_only_page_a3paper_left_output: } + { + \l__examzh_foot_content_before_page_tl \int_eval:n { 2 * \c@page - 1 } { } + \l__examzh_foot_content_after_page_tl + } +\cs_new:cpn { __examzh_foot_content_only_page_a3paper_right_output: } + { + \l__examzh_foot_content_before_page_tl \int_eval:n { 2 * \c@page } { } + \l__examzh_foot_content_after_page_tl + } +\cs_new:Npn \__examzh_foot_content_page_and_lastpage_output: + { + \l__examzh_foot_content_before_page_tl \thepage { } + \l__examzh_foot_content_after_page_tl \unskip \c_space_tl \pageref { LastPage }~ + \l__examzh_foot_content_after_lastpage_tl + } +\cs_new:cpn { __examzh_foot_content_page_and_lastpage_a3paper_left_output: } + { + \__examzh_foot_lastpage_tmp_set: + \l__examzh_foot_content_before_page_tl \int_eval:n { 2 * \c@page - 1 } { } + \l__examzh_foot_content_after_page_tl ~\int_eval:n { 2 * \l__examzh_tmp_int }~ + \l__examzh_foot_content_after_lastpage_tl + } +\cs_new:cpn { __examzh_foot_content_page_and_lastpage_a3paper_right_output: } + { + \__examzh_foot_lastpage_tmp_set: + \l__examzh_foot_content_before_page_tl \int_eval:n { 2 * \c@page } { } + \l__examzh_foot_content_after_page_tl ~\int_eval:n { 2 * \l__examzh_tmp_int }~ + \l__examzh_foot_content_after_lastpage_tl + } +\cs_new_nopar:Npn \__examzh_relax: { \relax } +\cs_new:Npn \__examzh_foot_lastpage_tmp_set: + { + \cs_if_eq:NNTF \lastpage@lastpage \__examzh_relax: + { \int_set:Nn \l__examzh_tmp_int { 0 } } + { \int_set:Nn \l__examzh_tmp_int { \lastpage@lastpage } } + } +\msg_new:nnn { exam-zh } { foot-semicolon-number-error } + { + The~number~of~semicolon~of~foot-line~must~be~1,~2~or~3! + } +\cs_new:cpn { __examzh_foot_content_a4paper_output: } + { + % 检测输入有多少个 ; + \regex_count:nxN { ; } + { \l__examzh_foot_content_format_tl } + \l__examzh_foot_content_count_semicolon_int + \int_case:nnF { \l__examzh_foot_content_count_semicolon_int } + { + {0} { \__examzh_foot_content_no_page_or_lastpage_output: } + {1} + { + % 将输入“分解” + \__examzh_foot_content_only_page_input:V \l__examzh_foot_content_format_tl + % 然后输出 + \__examzh_foot_content_only_page_output: + } + {2} + { + % 将输入“分解” + \__examzh_foot_content_page_and_lastpage_input:V \l__examzh_foot_content_format_tl + % 然后输出 + \__examzh_foot_content_page_and_lastpage_output: + } + } + { + \msg_error:nn { exam-zh } { foot-semicolon-number-error } + } + } +\cs_set_eq:cc + { __examzh_foot_content_a3paper_common_output: } + { __examzh_foot_content_a4paper_output: } +\cs_new:cpn { __examzh_foot_content_a3paper_separate_left_output: } + { + % 检测输入有多少个 ; + \regex_count:nxN { ; } + { \l__examzh_foot_content_format_tl } + \l__examzh_foot_content_count_semicolon_int + \int_case:nnF { \l__examzh_foot_content_count_semicolon_int } + { + {0} { \__examzh_foot_content_no_page_or_lastpage_output: } + {1} + { + % 将输入“分解” + \__examzh_foot_content_only_page_input:V \l__examzh_foot_content_format_tl + % 然后输出 + \use:c { __examzh_foot_content_only_page_a3paper_left_output: } + } + {2} + { + % 将输入“分解” + \__examzh_foot_content_page_and_lastpage_input:V \l__examzh_foot_content_format_tl + % 然后输出 + \use:c { __examzh_foot_content_page_and_lastpage_a3paper_left_output: } + } + } + { + \msg_error:nn { exam-zh } { foot-semicolon-number-error } + } + } +\cs_new:cpn { __examzh_foot_content_a3paper_separate_right_output: } + { + % 检测输入有多少个 ; + \regex_count:nxN { ; } + { \l__examzh_foot_content_format_tl } + \l__examzh_foot_content_count_semicolon_int + \int_case:nnF { \l__examzh_foot_content_count_semicolon_int } + { + {0} { \__examzh_foot_content_no_page_or_lastpage_output: } + {1} + { + % 将输入“分解” + \__examzh_foot_content_only_page_input:V \l__examzh_foot_content_format_tl + % 然后输出 + \use:c { __examzh_foot_content_only_page_a3paper_right_output: } + } + {2} + { + % 将输入“分解” + \__examzh_foot_content_page_and_lastpage_input:V \l__examzh_foot_content_format_tl + % 然后输出 + \use:c { __examzh_foot_content_page_and_lastpage_a3paper_right_output: } + } + } + { + \msg_error:nn { exam-zh } { foot-semicolon-number-error } + } + } + +\tl_set:Nn \headrulewidth { 0pt } +% \cs_set_eq:NN \@mkboth \use_none:n +\cs_set_eq:NN \sectionmark \use_none:n +\cs_set_eq:NN \subsectionmark \use_none:n + +\cs_new:Npn \__examzh_column_box:n #1 + { + \makebox [ \columnwidth ] {#1} + } + + +\fancypagestyle { plain } + { + \fancyhf { } + \bool_if:cTF { g__examzh_page_size_a4paper_bool } + { + % a4paper + \bool_if:NT \l__examzh_show_foot_bool + { + \fancyfoot [ C ] + { + \small + \use:c { __examzh_foot_content_a4paper_output: } + % \l__exam_zh_subject_tl 试题第 \thepage { } 页(共 \pageref { LastPage } ~ 页) + } + } + } + { + % a3paper + \bool_if:NT \l__examzh_show_foot_bool + { + \bool_if:cTF + { g__examzh_page_a3paper_foot_common_bool } + { + % 两页共用一个页脚 + \fancyfoot [ C ] + { + \small + % \l__exam_zh_subject_tl 试题第 \thepage { } 页(共 \pageref { LastPage } ~ 页) + \use:c { __examzh_foot_content_a3paper_common_output: } + } + } + { + % 每页一个页脚 + \fancyfoot [ L ] + { + \__examzh_column_box:n + { + \small + \use:c { __examzh_foot_content_a3paper_separate_left_output: } + % \l__exam_zh_subject_tl 试题第 + % % \thepage + % \int_eval:n { 2 * \c@page - 1 } + % { } 页 + % (共 + % % \pageref { LastPage } + % \int_eval:n { 2 * \l__examzh_tmp_int } + % ~ 页) + % \use:c { l__examzh_foot_content_a3paper_left_tl } + } + } + \fancyfoot [ R ] + { + \__examzh_column_box:n + { + \small + \use:c { __examzh_foot_content_a3paper_separate_right_output: } + % % \int_gincr:N \c@page + % \int_set:Nn \l__examzh_tmp_int { \lastpage@lastpage } + + % \l__exam_zh_subject_tl 试题第 + % \int_eval:n { 2 * \c@page } + % { } + % 页 + % (共 + % % \pageref { LastPage } + % \int_eval:n { 2 * \l__examzh_tmp_int } + % ~ 页) + % % \use:c { l__examzh_foot_content_a3paper_right_tl } + } + } + } + } + } + } +\AtBeginDocument { \pagestyle { plain } } + + + +% 草稿纸 + +% “草稿纸”三个字的尺寸 +\dim_new:N \l__examzh_draft_watermark_size_dim +% 控制是否自动添加草稿纸 +\bool_new:N \l__examzh_draft_show_auto_bool + +\keys_define:nn { exam-zh / draft } + { + watermark-size .code:n = + { + % 之所以这样设置而不是 .dim_set:N 是因为 a4 和 a3 的切换不是文档选项 + % 而是通过 \examsetup 更改的。所以要设置默认值必须用 \AtEndPreamble + % 来检测 g__examzh_page_size_a4paper_bool 的值才行,但这样的话就会 + % 把 watermark-size 的值覆盖,所以得实现“watermark-size” 的设置要盖掉 \AtEndPreamble + % 设置的默认值,才可以达到用户输入产生效果 + \AtEndPreamble + { + \dim_set:Nn \l__examzh_draft_watermark_size_dim {#1} + } + }, + show-watermark .bool_set:N = \l__examzh_draft_show_watermark_bool, + show-draft .choice:, + show-draft / auto .code:n = + { \bool_set_true:N \l__examzh_draft_show_auto_bool }, + show-draft / manual .code:n = + { \bool_set_false:N \l__examzh_draft_show_auto_bool }, + } +\keys_set:nn { exam-zh / draft } + { + show-watermark = true, + show-draft = manual, + } +% “草稿纸”尺寸默认值 +\AtEndPreamble + { + \bool_if:cTF { g__examzh_page_size_a4paper_bool } + { + \keys_set:nn { exam-zh / draft } + { watermark-size = 100pt } + } + { + \keys_set:nn { exam-zh / draft } + { watermark-size = 180pt } + } + } +\AtEndDocument + { + \bool_if:NT \l__examzh_draft_show_auto_bool + { \draftpaper \draftpaper } + } +\NewDocumentCommand { \draftpaper } { O{} } + { + \group_begin: + \keys_set:nn { exam-zh / draft } {#1} + \bool_if:NTF \l__examzh_draft_show_watermark_bool + { \__examzh_draft_with_watermark: } + { \__examzh_draft_without_watermark: } + \group_end: + } +\cs_new:Npn \__examzh_draft_with_watermark: + { + \clearpage + \null + \thispagestyle { empty } + \begin{tikzpicture} + [ + remember~picture, + overlay, + font = \sffamily\fontsize{ \l__examzh_draft_watermark_size_dim }{180pt}\selectfont + ] + \node[text = lightgray!40] at (current~page.center) {草\quad 稿\quad 纸}; + \end{tikzpicture} + \clearpage + } +\cs_new:Npn \__examzh_draft_without_watermark: + { + \clearpage + \null + \thispagestyle { empty } + \clearpage + } + + + +% 评分框 scoring box + +\bool_new:N \g__examzh_combine_section_with_scoringbox_position_left_bool + +\NewCommandCopy { \examzholdsection } { \section } +\cs_new:Npn \__examzh_combine_section_with_twocolumn_scoringbox: + { + \bool_if:NTF \g__examzh_combine_section_with_scoringbox_position_left_bool + { + \RenewDocumentCommand { \section } { m } + { + \par\addvspace{1.5em}\noindent + \begin{tabular}{lc} + \begin{minipage}{0.2\columnwidth} + \begin{tabular}{|c|c|} + \hline + 得分 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline + 阅卷人 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline + \end{tabular} + \end{minipage} & + \begin{minipage}{0.745\columnwidth} + \examzholdsection {##1} + \end{minipage} + \end{tabular} + \par + \addvspace{1em} + } + } + { + \RenewDocumentCommand { \section } { m } + { + \par\addvspace{1.5em}\noindent + \begin{tabular}{lc} + \begin{minipage}{0.745\columnwidth} + \examzholdsection {##1} + \end{minipage} & + \begin{minipage}{0.2\columnwidth} + \begin{tabular}{|c|c|} + \hline + 得分 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline + 阅卷人 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline + \end{tabular} + \end{minipage} + \end{tabular} + \par + \addvspace{1em} + } + } + } +\cs_new:Npn \__examzh_combine_section_with_onecolumn_scoringbox: + { + \bool_if:NTF \g__examzh_combine_section_with_scoringbox_position_left_bool + { + \RenewDocumentCommand { \section } { m } + { + \par\addvspace{1.5em}\noindent + \begin{tabular}{cc} + \begin{varwidth}{3.5em} + \begin{tabular}{|c|} + \hline + 得分\rule[-0.7em]{0pt}{2em} \\\hline + \rule[-0.7em]{0pt}{2em} \\\hline + \end{tabular} + \end{varwidth} & + \begin{varwidth}{0.865\columnwidth} + \examzholdsection {##1} + \end{varwidth} + \end{tabular} + \par + \addvspace{1em} + } + } + { + \RenewDocumentCommand { \section } { m } + { + \par\addvspace{1.5em}\noindent + \begin{tabular}{cc} + \begin{varwidth}{0.865\columnwidth} + \examzholdsection {##1} + \end{varwidth} & + \begin{varwidth}{3.5em} + \begin{tabular}{|c|} + \hline + 得分\rule[-0.7em]{0pt}{2em} \\\hline + \rule[-0.7em]{0pt}{2em} \\\hline + \end{tabular} + \end{varwidth} + \end{tabular} + \par + \addvspace{1em} + } + } + } +\cs_new:Npn \__examzh_restore_section: + { + \RenewCommandCopy { \section } { \examzholdsection } + } + +\keys_define:nn { exam-zh / scoringbox } + { + type .choice:, + type / onecolumn .code:n = + { + \AtEndPreamble { \__examzh_combine_section_with_onecolumn_scoringbox: } + }, + type / twocolumn .code:n = + { + \AtEndPreamble { \__examzh_combine_section_with_twocolumn_scoringbox: } + }, + type / none .code:n = { \__examzh_restore_section: }, + position .choice:, + position / left .code:n = + { + \bool_gset_true:N \g__examzh_combine_section_with_scoringbox_position_left_bool + }, + position / right .code:n = + { + \bool_gset_false:N \g__examzh_combine_section_with_scoringbox_position_left_bool + }, + } +\keys_set:nn { exam-zh / scoringbox } + { + type = none, + position = left + } +\keys_define:nn { exam-zh } + { scoringbox .meta:nn = { exam-zh / scoringbox } {#1} } + + +\NewDocumentCommand { \scoringbox } { s } + { + \IfBooleanTF {#1} + { \__examzh_scoringbox_onecolumn: } + { \__examzh_scoringbox_twocolumn: } + } +\cs_new_protected:Nn \__examzh_scoringbox_twocolumn: + { + \begin{tabular}{|c|c|} + \hline + 得分 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline + 阅卷人 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline + \end{tabular} + } +\cs_new_protected:Nn \__examzh_scoringbox_onecolumn: + { + \begin{tabular}{|c|} + \hline + 得分\rule[-0.7em]{0pt}{2em} \\\hline + \rule[-0.7em]{0pt}{2em} \\\hline + \end{tabular} + } + + + +% 脚注 +% 摘自 fduthesis.cls + +\cs_new_protected:Npn \__examzh_define_fn_style:nn #1#2 + { \tl_const:cn { c__examzh_fn_style_ #1 _tl } {#2} } +\cs_new:Npn \__examzh_symbol:n #1 { \tex_char:D #1 \scan_stop: } + +\clist_map_inline:nn + { + { plain } { plain }, + { libertinus } { libertinus }, + { libertinus_neg } { libertinus* }, + { libertinus_sans } { libertinus-sans }, + { pifont } { pifont }, + { pifont_neg } { pifont* }, + { pifont_sans } { pifont-sans }, + { pifont_sans_neg } { pifont-sans* }, + { xits } { xits }, + { xits_sans } { xits-sans }, + { xits_sans_neg } { xits-sans* } + } + { \__examzh_define_fn_style:nn #1 } +\tl_new:N \l__examzh_fn_style_tl +\keys_define:nn { exam-zh / style } + { + footnote-style .choices:nn = + { + plain, + libertinus, libertinus*, libertinus-sans, + pifont, pifont*, pifont-sans, pifont-sans*, + xits, xits-sans, xits-sans* + } + { + \tl_gset_eq:NN \l__examzh_fn_style_tl \l_keys_choice_tl + \int_compare:nT { 5 <= \l_keys_choice_int <= 8 } + { \RequirePackage { pifont } } + }, + footnote-style .value_required:n = true + } +\keys_set:nn { exam-zh / style } + { + footnote-style = libertinus + } +\cs_new:Npn \__examzh_fn_symbol_libertinus:n #1 + { + \int_compare:nTF { #1 >= 21 } + { + \int_compare:nTF { #1 >= 47 } + { \__examzh_symbol:n { \int_eval:n { "24B6 - 47 + #1 } } } + { \__examzh_symbol:n { \int_eval:n { "24D0 - 21 + #1 } } } + } + { \__examzh_symbol:n { \int_eval:n { "2460 - 1 + #1 } } } + } +\cs_new:Npn \__examzh_fn_symbol_libertinus_neg:n #1 + { + \int_compare:nTF { #1 >= 11 } + { \__examzh_symbol:n { \int_eval:n { "24EB - 11 + #1 } } } + { \__examzh_symbol:n { \int_eval:n { "2776 - 1 + #1 } } } + } +\cs_new_eq:NN \__examzh_fn_symbol_libertinus_sans:n \__examzh_fn_symbol_libertinus:n +\cs_new:Npn \__examzh_fn_symbol_pifont:n #1 + { \ding { \int_eval:n { 171 + #1 } } } +\cs_new:Npn \__examzh_fn_symbol_pifont_neg:n #1 + { \ding { \int_eval:n { 181 + #1 } } } +\cs_new:Npn \__examzh_fn_symbol_pifont_sans:n #1 + { \ding { \int_eval:n { 191 + #1 } } } +\cs_new:Npn \__examzh_fn_symbol_pifont_sans_neg:n #1 + { \ding { \int_eval:n { 201 + #1 } } } +\cs_new:Npn \__examzh_fn_symbol_xits:n #1 + { + \int_compare:nTF { #1 >= 10 } + { + \int_compare:nTF { #1 >= 36 } + { \__examzh_symbol:n { \int_eval:n { "24B6 - 36 + #1 } } } + { \__examzh_symbol:n { \int_eval:n { "24D0 - 10 + #1 } } } + } + { \__examzh_symbol:n { \int_eval:n { "2460 - 1 + #1 } } } + } +\cs_new:Npn \__examzh_fn_symbol_xits_sans:n #1 + { \__examzh_symbol:n { \int_eval:n { "2780 - 1 + #1 } } } +\cs_new:Npn \__examzh_fn_symbol_xits_sans_neg:n #1 + { \__examzh_symbol:n { \int_eval:n { "278A - 1 + #1 } } } +\cs_set:Npn \thefootnote { \examzh_footnote_number:N \c@footnote } +\cs_new:Npn \examzh_footnote_number:N #1 + { + \tl_case:NnF \l__examzh_fn_style_tl + { + \c__examzh_fn_style_plain_tl + { \int_use:N #1 } + \c__examzh_fn_style_libertinus_tl + { + \fontspec { LibertinusSerif-Regular .otf } + \__examzh_fn_symbol_libertinus:n {#1} + } + \c__examzh_fn_style_libertinus_neg_tl + { + \fontspec { LibertinusSerif-Regular .otf } + \__examzh_fn_symbol_libertinus_neg:n {#1} + } + \c__examzh_fn_style_libertinus_sans_tl + { + \fontspec { LibertinusSans-Regular .otf } + \__examzh_fn_symbol_libertinus_sans:n {#1} + } + \c__examzh_fn_style_pifont_tl + { \__examzh_fn_symbol_pifont:n {#1} } + \c__examzh_fn_style_pifont_neg_tl + { \__examzh_fn_symbol_pifont_neg:n {#1} } + \c__examzh_fn_style_pifont_sans_tl + { \__examzh_fn_symbol_pifont_sans:n {#1} } + \c__examzh_fn_style_pifont_sans_neg_tl + { \__examzh_fn_symbol_pifont_sans_neg:n {#1} } + \c__examzh_fn_style_xits_tl + { + \fontspec { XITS-Regular .otf } + \__examzh_fn_symbol_xits:n {#1} + } + \c__examzh_fn_style_xits_sans_tl + { + \fontspec { XITS-Regular .otf } + \__examzh_fn_symbol_xits_sans:n {#1} + } + \c__examzh_fn_style_xits_sans_neg_tl + { + \fontspec { XITS-Regular .otf } + \__examzh_fn_symbol_xits_sans_neg:n {#1} + } + } + { \int_use:N #1 } + } +\cs_set:Npn \@makefntext #1 + { + \mode_leave_vertical: + \hbox_to_wd:nn { 1.5 em } { \@thefnmark \hfil } + #1 + }
\ No newline at end of file diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index 9f056be7cd8..9de2fbe452e 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -302,7 +302,7 @@ my @TLP_working = qw( euclideangeometry euenc euflag eukdate euler eulerpx eulervm euro euro-ce europasscv europecv eurosym everyhook everypage everysel everyshi - exam exam-n exam-randomizechoices examdesign example examplep + exam exam-n exam-randomizechoices exam-zh examdesign example examplep exceltex excludeonly exercise exercisebank exercisepoints exercises exesheet exframe exp-testopt expdlist expex expex-acro expkv expkv-cs expkv-def expkv-opt export diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds index db6be4e68a1..227b7cdd2c5 100755 --- a/Master/tlpkg/libexec/ctan2tds +++ b/Master/tlpkg/libexec/ctan2tds @@ -1660,6 +1660,7 @@ chomp (my $ctan_root = `tlpkginfo --ctan-root`); 'enigma' => '&POSTenigma', 'eplain' => '&POSTeplain', 'epspdf' => '&POSTepspdf', + 'exam-zh' => '&POSTexam_zh', 'fixme' => '&POSTfixme', 'font-change-xetex' => '&POSTfont_change_xetex', 'fontsetup' => '&POSTfontsetup', @@ -6717,6 +6718,11 @@ sub POSTepspdf { print "YOU-MUST-DO! update /tmp/$package* into bin/win32, etc.\n"; } +sub POSTexam_zh { + print "POST$package - just tex/* in runtime\n"; + &mv_with_mkdir ("tex/*", "$DEST/tex/latex/$package"); +} + sub POSTfixme { print "POST$package - move subdirectories\n"; my $dstdir = "$DEST/tex/latex/$package"; diff --git a/Master/tlpkg/tlpsrc/collection-langchinese.tlpsrc b/Master/tlpkg/tlpsrc/collection-langchinese.tlpsrc index a40913d988d..18399779830 100644 --- a/Master/tlpkg/tlpsrc/collection-langchinese.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-langchinese.tlpsrc @@ -12,6 +12,7 @@ depend asymptote-manual-zh-cn depend cns depend ctex depend ctex-faq +depend exam-zh depend fandol depend fduthesis depend hanzibox diff --git a/Master/tlpkg/tlpsrc/exam-zh.tlpsrc b/Master/tlpkg/tlpsrc/exam-zh.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/exam-zh.tlpsrc |