简历概述的成果数字改为自动统计(列几条算几条) #14
概述原来手写「论文 40 余篇、专利 20 余项」,每次增删条目都要回头改。
改为正文标记、概述取数:
\item ...论文... \cvtagcount{SCI} % 显示 SCI 并计数
\item ...软著... \cvmark{软著} % 只计数
概述:论文 \cvnum*{SCI,EI,核心} 篇(SCI \cvnum{SCI} 篇)
共注册 11 类:SCI/EI/核心/专利/第一发明人/软著/科研项目/主持/负责/转化/教研。
关键技术:不用 aux,改独立数据文件 \jobname.cvnum。
中文键经 aux 往返后 \ifcsname 全部失效(xeCJK 把汉字设为活动字符,
键的 token 形态不一致;ASCII 键正常);独立文件里中文键完全正常。
累加与显示分离(cvacc@ 每遍从 0 起 / cvnum@ 读自上一遍),
否则概述在正文之前会让上一遍的值被本遍叠加,数字翻倍。
踩坑:\cvmark 不能放 \experience 的关键词参数(会被 \foreach 拆开,
报 Misplaced \omit),必须放描述参数内;也不能放 longtable 单元格之外。
验证:0 error / 0 Overfull / 0 Underfull,3 页;加标记后版面与基线
逐行一致;连续 5 次编译数字稳定;增删条目后数字自动跟随。
⚠️ 口径变化:自动统计只数列出来的条目。示例原来写「40 余篇」但正文
只列 9 篇代表作,改成自动后变「9 篇」。README 已写明这两种口径的区别。
项目总经费仍手填(\experience 无经费字段)。
This commit is contained in:
@@ -632,3 +632,135 @@
|
||||
|
||||
|
||||
\newcommand\emptySeparator{\multicolumn{2}{c}{}\\}
|
||||
|
||||
%======================================================================
|
||||
% 成果统计:让概述里的数字自动来自后面章节的条目
|
||||
%
|
||||
% 问题:简历第一段概述通常写「发表论文 40 余篇、授权专利 12 项、成果转化
|
||||
% 3 项……」。这些数字若手写,每增删一条论文就得回头改概述,极易漏改。
|
||||
%
|
||||
% 思路:给每条加一个**类别标记** \cvmark, 正文里自动累加计数,概述用
|
||||
% \cvnum 取数。**列几条就算几条**,不去猜总数——你不列出来的成果
|
||||
% 本来也不该出现在概述里。
|
||||
%
|
||||
% 用法(两步):
|
||||
% ① 每个条目末尾标类别:
|
||||
% \item ...论文信息... \cvmark{SCI}
|
||||
% \item ...论文信息... \cvmark{EI}
|
||||
% \cvmark 不产生任何可见输出(就是个计数动作),放条目首尾都行。
|
||||
% 一条属于两类就标两次;同名类别重复标会自动累加。
|
||||
%
|
||||
% ② 概述里取数:
|
||||
% \cvnum{SCI} 篇、\cvnum{EI} 篇、合计 \cvnum*{SCI,EI} 篇
|
||||
% \cvnum* 是「多类求和」,逗号分隔(注意:是英文逗号)。
|
||||
%
|
||||
% ③ 空类别返回 0,不会出现 ??。所以可以先写 \cvnum{EI},
|
||||
% 等真有了 EI 论文再加 \cvmark{EI},中间不会编译报错。
|
||||
%
|
||||
% ⚠️ 为什么用独立数据文件而不是 LaTeX 的 aux:
|
||||
% 实测中文键经 aux 往返后 \ifcsname 全部匹配不上(xeCJK 把汉字设为
|
||||
% 活动字符,键的 token 形态与写入时不一致;ASCII 键正常,中文键失效)。
|
||||
% 故改用独立文件 \jobname.cvnum,导言区末尾 \input,键原样保留。
|
||||
%
|
||||
% ⚠️ 必须编译两遍(或直接用 latexmk):
|
||||
% 第一遍边累加边写 \jobname.cvnum,此时概述读到的是**上一遍**的值,
|
||||
% 首次编译会显示 0;第二遍才是正确数字。日志末尾有 CVSTATS 一行提示。
|
||||
%
|
||||
% ⚠️ \jobname.cvnum 是**生成文件**,不要手改、不要提交 git(已在
|
||||
% .gitignore 里挡住)。删掉它只会让数字从 0 重新算一遍,下一遍即恢复。
|
||||
%
|
||||
% ⚠️ 类别名限制:
|
||||
% · 不要含英文逗号(, 是 \cvnum* 的分隔符)
|
||||
% · 不要含 @ % # \ { } 这些特殊字符
|
||||
% · 中文、英文、汉字混排都可以
|
||||
%======================================================================
|
||||
\makeatletter
|
||||
|
||||
% ---- 数据文件 ------------------------------------------------------
|
||||
\newwrite\cv@statsout
|
||||
|
||||
% 读:导言区末尾把上一遍写入的数字读进来。
|
||||
% 此时正文尚未开始,不会和本遍的累加互相干扰。
|
||||
\AtBeginDocument{\InputIfFileExists{\jobname.cvnum}{}{}}
|
||||
|
||||
% ---- 内部:类别 -> 计数器名 ----------------------------------------
|
||||
% 累加值存在 \cvacc@<类别>(TeX 整数寄存器,不用 LaTeX counter,
|
||||
% 既省事又避开 \the\csname...\endcsname 的展开陷阱)。
|
||||
% 显示值存在 \cvnum@<类别>(\def 出来的宏,内容就是数字字符串)。
|
||||
\newcommand\cv@accname[1]{cvacc@#1}
|
||||
|
||||
% 保证某类别的累加器存在
|
||||
\newcommand\cv@ensureacc[1]{%
|
||||
\@ifundefined{\cv@accname{#1}}%
|
||||
{\expandafter\newcount\csname\cv@accname{#1}\endcsname}%
|
||||
{}%
|
||||
}
|
||||
|
||||
% ---- 标记 ----------------------------------------------------------
|
||||
% \cvmark{<类别>}:把该类别的累加器 +1,无可见输出。
|
||||
\newcommand\cvmark[1]{%
|
||||
\cv@ensureacc{#1}%
|
||||
\global\advance\csname\cv@accname{#1}\endcsname\@ne
|
||||
% 顺便登记该类别的名字,收尾时按登记顺序写文件
|
||||
\@ifundefined{cv@seen@\detokenize{#1}}%
|
||||
{\expandafter\gdef\csname cv@seen@\detokenize{#1}\endcsname{1}%
|
||||
\g@addto@macro\cv@taglist{\cv@writeone{#1}}}%
|
||||
{}%
|
||||
}
|
||||
|
||||
% ---- 输出 ----------------------------------------------------------
|
||||
% \cvnum{SCI} 单类取数
|
||||
% \cvnum*{SCI,EI} 多类求和
|
||||
\newcommand\cvnum{\@ifstar\cv@numsum\cv@numone}
|
||||
|
||||
% ---- 带计数的标签:显示 + 计数一步完成 ------------------------------
|
||||
% \cvtagcount{<显示文字>}[<类别>]
|
||||
% 显示「显示文字」(与正文同号加粗,和原来的 \textbf{SCI} 完全一样),
|
||||
% 同时给类别 +1。省略类别时用显示文字本身当类别。
|
||||
%
|
||||
% 为什么需要它:论文的收录类型本来就写成 \textbf{SCI} 显示在条目末尾,
|
||||
% 若再单独写一个 \cvmark{SCI},一是啰嗦,二是迟早会漏标。
|
||||
% 用 \cvtagcount{SCI} 一次到位,显示与计数永远同步。
|
||||
%
|
||||
% 用法:
|
||||
% \cvtagcount{SCI} % 显示 SCI,类别也叫 SCI
|
||||
% \cvtagcount{核心}[中文核心] % 显示「核心」,类别记为「中文核心」
|
||||
\newcommand\cvtagcount[2][\relax]{%
|
||||
\textbf{#2}%
|
||||
\ifx\relax#1\relax\cvmark{#2}\else\cvmark{#1}\fi}
|
||||
|
||||
\newcommand\cv@numone[1]{%
|
||||
\@ifundefined{cvnum@#1}{0}{\csname cvnum@#1\endcsname}}
|
||||
|
||||
\newcommand\cv@numsum[1]{%
|
||||
\begingroup
|
||||
\count@\z@
|
||||
\@for\cv@k:=#1\do{%
|
||||
\@ifundefined{cvnum@\cv@k}{}{\advance\count@\csname cvnum@\cv@k\endcsname\relax}%
|
||||
}%
|
||||
\the\count@
|
||||
\endgroup}
|
||||
|
||||
% ---- 收尾:写数据文件 ----------------------------------------------
|
||||
% 用独立的 write 流,与 aux 完全无关,因此不受 aux 读入时机影响。
|
||||
\newcommand\cv@taglist{}
|
||||
|
||||
\newcommand\cv@writeone[1]{%
|
||||
\immediate\write\cv@statsout{%
|
||||
\string\cvSetNum{\detokenize{#1}}{\the\csname\cv@accname{#1}\endcsname}}%
|
||||
}
|
||||
|
||||
\AtEndDocument{%
|
||||
\immediate\openout\cv@statsout=\jobname.cvnum\relax
|
||||
\cv@taglist
|
||||
\immediate\closeout\cv@statsout
|
||||
% 日志提示:本遍写入了多少类
|
||||
\typeout{CVSTATS: 已写入 \jobname.cvnum(若概述数字为 0,请再编译一遍)}%
|
||||
}
|
||||
|
||||
% 数据文件里调用的设置命令。
|
||||
% ⚠️ 不能含 @:读回时若 @ 不是字母,命令名会被拆断。
|
||||
\newcommand\cvSetNum[2]{%
|
||||
\expandafter\def\csname cvnum@#1\endcsname{#2}}
|
||||
|
||||
\makeatother
|
||||
Reference in New Issue
Block a user