% \iffalse meta-comment % !TEX program = XeLaTeX % % DO NOT REMOVE THE MARK MANUALLY (used in l3build) -> % % %<package|doc-sty>\NeedsTeXFormat{LaTeX2e} %<package>\ProvidesExplPackage{hustvisual} %<doc-sty>\ProvidesExplPackage{hustvisual-doc} %<package|doc-sty> {2025-05-07}{1.0.0} % %<package> {Visual Identity of Huazhong University of Science and Technology} %<doc-sty> {Docmentation Style for hustvisual} %<*driver> \documentclass{ctexart} \usepackage{useclass} \useclass*[full]{l3doc} \usepackage{hustvisual} \usepackage{hustvisual-doc} \usepackage{mdframed} \usepackage{marginnote} \usepackage{siunitx} \providecommand{\name}{\jobname} \providecommand{\pkgname}{\pkg{\name}} \begin{document} \DisableImplementation \DocInput{\jobname.dtx} \DocInput{\jobname-vi.dtx} \EnableImplementation \DisableDocumentation \DocInputAgain \PrintChanges \PrintIndex \end{document} %</driver> % \fi % % \begin{documentation} % \title{\pkgname.sty: åŽä¸ç§‘技大å¦è§†è§‰æ ‡è¯†æ±‡ç¼–} % \author % { % 黄宇希 Huang Yuxi^^A % \thanks{ % \textit{Huang} is his surname. % } % <^^A % \href % {mailto:hustvisual@hyxi.dev} % {hustvisual@hyxi.dev}^^A % > % } % \date{2025-05-07 \quad Version 1.0.0} % % \maketitle % % \tableofcontents % % \changes{v1.0}{2025-05-06}{Initial release.} % % \section{å®åŒ…介ç»} % % 本å®åŒ…æä¾›äº†åŽä¸ç§‘技大å¦è§†è§‰æ ‡è¯†ï¼ˆvisual identity)定义的接å£ï¼Œ % é¢„è®¾äº†éƒ¨åˆ†å¸¸ç”¨çš„è§†è§‰æ ‡è¯†ï¼Œ % 使得用户å¯ä»¥ä¾¿æ·åœ°åœ¨æ–‡æ¡£ä¸ä½¿ç”¨ã€‚ % % \subsection{\pkgname{} å‘行版本å·\label{sec:version}} % % æ›´æ–°ç‰ˆæœ¬å¾€å¾€ä¼šå¸¦æ¥æ–°åŠŸèƒ½å’Œä¿®å¤é—®é¢˜ï¼Œ % 但有时也会ä¸å¯é¿å…地带æ¥ä¸å‘åŽå…¼å®¹çš„修改。 % ä¸ºäº†æ¸…æ™°åœ°ä¼ è¾¾ç‰ˆæœ¬ä¹‹é—´çš„å˜åŒ–, % 本å®åŒ…å‘行的版本å·ä½¿ç”¨ç±»ä¼¼ä½†ä¸å®Œå…¨åŒäºŽè¯ä¹‰åŒ–版本控制(Semantic Versioning)规范 % \footnote{\url{https://semver.org/}}ç”¨ä»¥æ ‡è¯†ã€‚ % 在本å®åŒ…ä¸ï¼Œå¯¹äºŽç‰ˆæœ¬å· |MAJOR.MINOR.PATCH|,递增相应的部分所表示的å«ä¹‰å¦‚下: % \begin{itemize} % \item |MAJOR|:递增大版本å·ï¼Œ % è¡¨ç¤ºå·²åœ¨æ£æ–‡æ–‡æ¡£åŒ–的公开接å£ä¸Šå˜åœ¨ä¸å‘åŽå…¼å®¹ï¼ˆbackward compatibility)的修改, % 一般对文档代ç ä¸ä¿®æ”¹æ— 法æ£å¸¸ç¼–译; % \item |MINOR|:递增å°ç‰ˆæœ¬å·ï¼Œ % è¡¨ç¤ºå·²åœ¨æ£æ–‡æ–‡æ¡£åŒ–çš„éžå®žéªŒæ€§å…¬å¼€æŽ¥å£ä¸Š\emph{ä¸}å˜åœ¨ä¸å‘åŽå…¼å®¹ç¼–译的修改, % 但在实验性公开接å£ä¸Šå˜åœ¨ä¸å‘åŽå…¼å®¹çš„修改。 % 一般对文档代ç ä¸ä½œä¿®æ”¹æˆ–者åªéœ€å°å¹…修改就å¯ä»¥æ£å¸¸ç¼–译; % \item |PATCH|:递增补ä¸ç‰ˆæœ¬å·ï¼Œ % è¡¨ç¤ºæ–°ç‰ˆæœ¬å«æœ‰å‘åŽå…¼å®¹çš„ bug ä¿®å¤ï¼Œæ–°åŠŸèƒ½ï¼Œæˆ–æ–°çš„è§†è§‰æ ‡è¯†ï¼Œ % 其䏿œªæ–‡æ¡£åŒ–çš„ç§æœ‰æŽ¥å£å¯èƒ½ä¼šå‘生å˜åŒ–。 % \end{itemize} % 以上内容所指的“公开接å£â€ä»…包括第 \ref{sec:usage} 节ä¸ä»‹ç»çš„供终端用户直接使用的接å£ã€‚ % 用户在更新å®åŒ…时,å¯ä»¥æ ¹æ®ç‰ˆæœ¬å·çš„å˜åŒ–ä»¥åŠæ›´æ–°æ—¥å¿—æ¥åˆ¤æ–是å¦éœ€è¦ä¿®æ”¹è‡ªå·±çš„æ–‡æ¡£ã€‚ % % \section{å¼€å‘说明\label{sec:dev}} % % 本节介ç»äº†å®åŒ…的开å‘和维护相关信æ¯ï¼Œ % åŒ…æ‹¬å¦‚ä½•æ·»åŠ æ–°çš„è‰²å½©å’Œå›¾æ¡ˆã€‚ % 本节内容的指令仅å¯åœ¨æœ¬å®åŒ…æˆ–è€…åæ¨¡å—ä¸ä½¿ç”¨ï¼Œ % åœ¨æ£æ–‡æ–‡æ¡£ä¸ä½¿ç”¨ä¼šå¯¼è‡´ç¼–译错误。 % % \subsection{æ·»åŠ æ–°çš„è‰²å½©} % % \begin{function}{\@@_set_color:nnn} % \begin{syntax} % \cs{@@_set_color:nnn} \marg{色彩åç§°} \marg{色彩模型} \marg{色彩值} % \end{syntax} % \cs{@@_set_color:nnn} æ˜¯ä¸€ä¸ªç”¨äºŽåŒæ—¶å®šä¹‰ \pkg{l3color} å’Œ \pkg{xcolor} ä¸çš„色彩的函数。例如: % \begin{verbatim} % \@@_set_color:nnn { hustblue } { CMYK } { 100, 74, 27, 0 } % \end{verbatim} % å®ƒåŒ…æ‹¬ä¸‰ä¸ªå¿…é€‰å‚æ•°ï¼šè‰²å½©åç§°ã€è‰²å½©æ¨¡åž‹å’Œè‰²å½©å€¼ï¼š % \begin{arguments} % \item[\marg{色彩åç§°}] 色彩åç§°ï¼Œå¿…é¡»æ˜¯ä¸€ä¸ªåˆæ³•çš„ \pkg{xcolor} 色彩å称。 % \item[\marg{色彩模型}] 色彩模型,支æŒçš„色彩模型包括 \opt{CMYK}ã€\opt{cmyk}ã€\opt{RGB}ã€\opt{rgb} ç‰ã€‚å…¶ä¸ \opt{CMYK} 是本å®åŒ…æ–°å¢žçš„è‰²å½©æ¨¡åž‹ï¼Œæ”¯æŒ 0--100 范围的 \opt{cmyk} 色彩。 % \item[\marg{色彩值}] 色彩值,支æŒç”±é€—å·åˆ†éš”çš„è‰²å½©å€¼ï¼Œæ ¼å¼åŒ…括 \opt{CMYK}ã€\opt{cmyk}ã€\opt{RGB}ã€\opt{rgb} ç‰ã€‚ % \end{arguments} % \end{function} % % \subsection{æ·»åŠ æ–°çš„å›¾æ¡ˆ} % % 推è使用 Inkscape 打开图案矢é‡å›¾å½¢æ–‡ä»¶ï¼Œ % 并使用 svg2tikz (\url{https://github.com/xyz2tex/svg2tikz})æ’件将其转æ¢ä¸º TikZ 代ç 。 % 在导出时,选择 \TeX template 为 Tikzpicture,å¯ç”¨è£åˆ‡ Crop,关é—自动æ¢è¡Œ Wrap paths 和缩进选项 Indent group ,数å—精度 Number of decimal 设置为 3;使用 cm 为å•ä½ï¼Œå…³é— Inkscape origin 选项,缩放比例 Scale 设置为 1.0。 % % 导出åŽè¯·ä½¿ç”¨ |scripts/tikz-format.pl| è„šæœ¬è¿›è¡Œæ ¼å¼åŒ–, % 脚本会对 \TikZ 代ç è¿›è¡Œæ ¼å¼åŒ–ï¼ŒåŒ…æ‹¬ç¼©è¿›ã€æ¢è¡Œã€åˆ é™¤å¤šä½™çš„ç©ºæ ¼ç‰æ“作。 % % 之åŽè¯·æ‰‹åŠ¨å°†é¢œè‰²æŒ‰ç…§ä¸€å®šé¡ºåºæ›¿æ¢ä¸ºå¦‚ \cs{l_@@_color_arg_i_tl} å½¢å¼çš„å˜é‡ï¼Œ % 以便于åŽç»çš„è‰²å½©å‚æ•°ä¼ 递。 % 在完全替æ¢åŽï¼Œ % åˆ é™¤å¼€å¤´çš„ |\definecolor| è¯å¥ï¼Œ % 将其 \TikZ ä»£ç æ”¾å…¥ guard (|%<*xxx>| 至 |%</xxx>|)ä¸ï¼Œ % 并更新相应文档,实现和 |hustvisual.ins| 文件。 % % \begin{function}{\@@_set_vi:n} % \begin{syntax} % \cs{@@_set_vi:n} \marg{å›¾æ¡ˆå‚æ•°} % \end{syntax} % \cs{@@_set_vi:n} 是一个用于设置图案的函数。 % \marg{å›¾æ¡ˆå‚æ•°} 是一个由逗å·åˆ†éš”çš„é”®å€¼å¯¹æ— åºåˆ—表, % 其䏿¯ä¸ªé”®å€¼å¯¹çš„æ ¼å¼ä¸º \opt{key=value}。 % 有些键值对是å¯é€‰çš„,如果没有设置,则使用默认值;而有些是必选的,ä¸è®¾ç½®åˆ™ä¼šå¯¼è‡´ç¼–译错误。 % å…¶ä¸é”®å€¼å¯¹çš„定义如下: % \begin{arguments} % \item[\opt{dept}] è§†è§‰æ ‡è¯†çš„æ‰€å±žå¦é™¢ï¼Œé»˜è®¤å€¼ä¸º \opt{vi},å³åŽä¸ç§‘æŠ€å¤§å¦æ ¡çº§çš„è§†è§‰æ ‡è¯†ã€‚å¦é™¢çš„缩写使用官方网站域å四级å域å(域å |.hust.edu.cn| 左边的部分)作为缩写。 % \item[\opt{vi}] è§†è§‰æ ‡è¯†çš„æ ‡è¯†ç¬¦ï¼Œå¿…é€‰å‚æ•°ï¼Œæ˜¯ä¸€ä¸ªç”±é€—å·åˆ†éš”çš„æ— åºåˆ—表,å®åŒ…内部会自动将其排åºåŽå˜å‚¨ä¸ºå”¯ä¸€çš„è§†è§‰æ ‡è¯†å称,与和 \opt{dept} 一起作为查找图案的默认文件å。 % \item[\opt{ncolors}] è§†è§‰æ ‡è¯†çš„è‰²å½©æ•°é‡ï¼Œé»˜è®¤å€¼ä¸º \opt{0},å³å›¾æ¡ˆä¸æ²¡æœ‰å¯é…置的色彩。 % \item[\opt{temps}] è§†è§‰æ ‡è¯†çš„è‰²å½©é¢„è®¾æ¨¡æ¿ï¼Œå¦‚æžœ \opt{ncolors} 的值大于 \opt{0}ï¼Œåˆ™è¯¥å‚æ•°ä¸ºå¿…选傿•°ã€‚色彩预设模æ¿çš„æ ¼å¼ä¸ºæœ‰åºåˆ—表 \opt{\{temp1=\{color1, color2, ...\}, temp2=\{color3, color1, ...\}, ...\}}ã€‚å…¶ä¸ \opt{temp1}ã€\opt{temp2} ç‰ä¸ºè‰²å½©é¢„设模æ¿çš„å称,\opt{color1}ã€\opt{color2} ç‰ä¸ºè‰²å½©å称,色彩å称需è¦ç”± \pkg{xcolor} å®åŒ…定义的色彩å称,且列表ä¸çš„色彩数é‡éœ€è¦ç‰åŒäºŽ \opt{ncolors} 的值。其ä¸ç¬¬ä¸€ä¸ªè‰²å½©é¢„设模æ¿ä¼šè¢«ç”¨ä½œé»˜è®¤çš„色彩预设模æ¿ã€‚ % \item[\opt{filename}] è§†è§‰æ ‡è¯†çš„æ–‡ä»¶å,默认缺çœï¼Œä½¿ç”¨ç”± \opt{dept} å’Œ \opt{vi} 生æˆçš„æ–‡ä»¶å。如果 \opt{filename} 的值ä¸ä¸ºç©ºï¼Œåˆ™è¯¥å›¾æ¡ˆä¼šè¢«ä½¿ç”¨ç”± \opt{filename} 设置的文件å。 % \item[\opt{aliases}] è§†è§‰æ ‡è¯†çš„åˆ«åï¼Œé»˜è®¤ä¸ºç©ºï¼Œå³æ²¡æœ‰åˆ«å。别åçš„æ ¼å¼ä¸ºæœ‰åºåˆ—表 \opt{\{\{vi1,vi2\},\{vi2,vi3,vi4\},...\}}ï¼Œå…¶ä¸ \opt{vi1,vi2}ã€\opt{vi2,vi3,vi4} ç‰ä¸ºåˆ«å,使用方å¼åŒ \opt{vi},用于方便用户调用,ä¸éœ€è¦æ¯æ¬¡éƒ½è¾“å…¥å®Œæ•´çš„è§†è§‰æ ‡è¯†å称。 % \end{arguments} % \end{function} % % \section{使用说明\label{sec:usage}} % % \begin{function}{\hustvi} % \begin{syntax} % \cs{hustvi}\oarg{通用选项}\marg{è§†è§‰æ ‡è¯†} % \end{syntax} % \cs{hustvi} 是本å®åŒ…æä¾›ç»™ç»ˆç«¯ç”¨æˆ·ä½¿ç”¨æœ€é‡è¦çš„一个接å£ï¼Œ % ä¸€åˆ‡çš„è§†è§‰æ ‡è¯†éƒ½æ˜¯é€šè¿‡è¿™ä¸ªé€šç”¨æŽ¥å£æ¥ä½¿ç”¨ã€‚ % 例如: % \marginnote{\hustvi[height=1cm,temp=red]{emblem}} % \begin{verbatim} % \hustvi[height=1cm,temp=red]{emblem} % \end{verbatim} % å¯ä»¥åœ¨æ–‡æ¡£ä¸ä½¿ç”¨å¦‚左页边所示,以通用选项:高 \qty{1}{cm}ã€è‰²å½©é¢„设为\opt{blue}çš„åŽä¸ç§‘æŠ€å¤§å¦æ ¡å¾½ã€‚ % å…¶ä¸ï¼Œ\marg{è§†è§‰æ ‡è¯†}是一个由逗å·åˆ†éš”çš„æ— åºåˆ—表, % 列表ä¸çš„æ¯ä¸€é¡¹éƒ½æ˜¯ä¸€ä¸ªè§†è§‰æ ‡è¯†ä¸çš„åŸºç¡€å…ƒç´ ï¼Œ % è¿™äº›å…ƒç´ çš„ç»„åˆå¯ä»¥å½¢æˆä¸€ä¸ªå®Œæ•´çš„è§†è§‰æ ‡è¯†ã€‚ % å¦‚æžœè§†è§‰æ ‡è¯†ä¸åªæœ‰ä¸€ä¸ªåŸºç¡€å…ƒç´ , % 则å¯ä»¥çœç•¥é€—å·åˆ†éš”符。 % 而\oarg{通用选项}是由一系列逗å·åˆ†éš”çš„é”®å€¼å¯¹æ— åºåˆ—表组æˆçš„å¯é€‰å‚数, % æ‰€æœ‰çš„è§†è§‰æ ‡è¯†éƒ½å®žçŽ°äº†å¦‚ä¸‹çš„é€šç”¨é€‰é¡¹ï¼š % \begin{arguments} % \item[\opt{filename}] è§†è§‰æ ‡è¯†çš„æ–‡ä»¶å,默认缺çœï¼Œé€šå¸¸æƒ…况下ä¸éœ€è¦è®¾ç½®ï¼Œä»…在需è¦è¦†ç›–原有文件时使用。 % \item[\opt{dept}] è§†è§‰æ ‡è¯†çš„æ‰€å±žå¦é™¢ï¼Œé»˜è®¤å€¼ä¸º \opt{vi},å³åŽä¸ç§‘æŠ€å¤§å¦æ ¡çº§çš„è§†è§‰æ ‡è¯†ã€‚å¦é™¢çš„缩写使用官方网站域å四级å域å(域å |.hust.edu.cn| 左边的部分)作为缩写。 % \item[\opt{width}] è§†è§‰æ ‡è¯†çš„å®½åº¦ï¼Œé»˜è®¤å€¼ä¸º \opt{0pt},å³ä½¿ç”¨é»˜è®¤çš„å®½åº¦ã€‚å¦‚æžœä»…è®¾ç½®äº†å®½åº¦è€Œæ²¡æœ‰è®¾ç½®é«˜åº¦ï¼Œåˆ™é«˜åº¦ä¼šè‡ªåŠ¨æŒ‰æ¯”ä¾‹ç¼©æ”¾ï¼›å¦‚æžœåŒæ—¶è®¾ç½®äº†å®½åº¦å’Œé«˜åº¦ï¼Œåˆ™å®½é«˜æ¯”会被强制为 \opt{width}:\opt{height}。 % \item[\opt{height}] è§†è§‰æ ‡è¯†çš„é«˜åº¦ï¼Œé»˜è®¤å€¼ä¸º \opt{0pt},效果åŒä¸Šã€‚ % \item[\opt{temp}] è§†è§‰æ ‡è¯†çš„è‰²å½©é¢„è®¾æ¨¡æ¿ï¼Œä¸åŒè§†è§‰æ ‡è¯†çš„色彩预设模æ¿ä¸åŒï¼Œå…·ä½“的色彩预设模æ¿è¯·å‚è€ƒå¯¹åº”è§†è§‰æ ‡è¯†çš„æ–‡æ¡£ã€‚ % \item[\opt{colors}] 手动按照顺åºè¦†å†™è‰²å½©é¢„设模æ¿ï¼ŒåŒæ—¶è®¾ç½®äº† \opt{temp} å’Œ \opt{colors} 时,\opt{colors} 会覆盖 \opt{temp} 的设置。 \opt{colors} çš„æ ¼å¼ä¸ºæœ‰åºåˆ—表 \opt{\{color1, color2, ...\}}ï¼Œå…¶ä¸ \opt{color1}ã€\opt{color2} ç‰ä¸ºè‰²å½©å称,色彩å称需è¦ç”± \pkg{xcolor} å®åŒ…定义的色彩å称,且列表ä¸çš„色彩数é‡ä¸èƒ½è¶…过预设模æ¿ä¸çš„色彩数é‡ã€‚\marginnote{\hustvi[colors={hustblue,black},temp=red,height=1cm]{emblem}} 例如:\cs{hustvi}\opt{\[colors=\{hustblue,black\},temp=red\]\{emblem\}} (如左页边所示)就是基于 \opt{red} 模æ¿çš„æ ¡å¾½ï¼Œå¯¹å‰ä¸¤ç§é¢œè‰²ä¾åºè¦†å†™äº†åŽç§‘è“ \opt{hustblue} 和黑色 \opt{black} 两ç§è‰²å½©\footnote{本错误é…色示例仅用于说明,实际使用时请éµå¾ªè§†è§‰æ ‡è¯†çš„色彩规范。}。 % \item[\opt{opacity}] ï¼ˆå®žéªŒæ€§åŠŸèƒ½ï¼‰è§†è§‰æ ‡è¯†çš„é€æ˜Žåº¦ï¼Œé»˜è®¤å€¼ä¸º \opt{1},å³ä¸é€æ˜Žã€‚逿˜Žåº¦çš„范围为 \opt{0} 到 \opt{1}ï¼Œå…¶ä¸ \opt{0} è¡¨ç¤ºå®Œå…¨é€æ˜Žï¼Œ\opt{1} 表示完全ä¸é€æ˜Žã€‚ % \end{arguments} % \end{function} % % \end{documentation} % % \begin{implementation} % % % \section{\pkgname{} 实现细节} % \begin{macrocode} %<@@=hustvisual> %<*package> % \end{macrocode} % % \subsection{常é‡å£°æ˜Ž} % % \begin{macro}{\c_@@_univ_tl} % å®šä¹‰æ ¡çº§è§†è§‰æ ‡è¯†çš„â€œå¦é™¢â€ \opt{dept} å称。 % \begin{macrocode} \tl_const:Nn \c_@@_univ_tl { vi } % \end{macrocode} % \end{macro} % % \begin{macro}{\c_@@_depts_clist} % 定义了å„个å¦é™¢çš„缩写,使用官方网站域å四级å域å(域å |.hust.edu.cn| 左边的部分)作为缩写。 % 如é‡ç±»ä¼¼åŒæµŽåŒ»å¦é™¢ä¸‹è®¾è¯å¦é™¢ï¼ˆ|pharm.tjmu.edu.cn|)或第一临床å¦é™¢ï¼ˆ|whuh.com|)的以éžåŽç§‘域å结尾的å¦é™¢ï¼Œå¦è¡Œå•†è®®ã€‚ % \begin{macrocode} \clist_const:Ne \c_@@_depts_clist { \c_@@_univ_tl, } % \end{macrocode} % \end{macro} % % \begin{macro}{\c_@@_nargs_int, \c_@@_args_clist} % 傿•°ç´¢å¼•。如有需è¦åœ¨è¿™é‡Œä¿®æ”¹å‚数索引数é‡ã€‚ % \begin{macrocode} \int_const:Nn \c_@@_nargs_int { 5 } \clist_new:N \c_@@_args_clist \int_step_inline:nn { \c_@@_nargs_int } { \exp_args:NNe \clist_put_right:Nn \c_@@_args_clist { \int_to_roman:n { #1 } } } % \end{macrocode} % \end{macro} % % \subsection{å˜é‡å£°æ˜Ž} % \begin{macro}{ % \l_@@_color_arg_i_tl, % \l_@@_color_arg_ii_tl, % \l_@@_color_arg_iii_tl, % \l_@@_color_arg_iv_tl, % \l_@@_color_arg_v_tl, % } % ä¼ å…¥ \TikZ ä¸çš„è‰²å½©å‚æ•°ï¼Œé»˜è®¤ä¸ºé»‘色。 % \begin{macrocode} \clist_map_inline:Nn \c_@@_args_clist { \tl_new:c { l_@@_color_arg_ #1 _tl } \tl_set:cn { l_@@_color_arg_ #1 _tl } { black } } % \end{macrocode} % \end{macro} % % \begin{macro}{\l_@@_color_args_clist} % è‰²å½©å‚æ•°åˆ—表。 % \begin{macrocode} \clist_new:N \l_@@_color_args_clist % \end{macrocode} % \end{macro} % % \begin{macro}{ % \l_@@_dept_tl, % \l_@@_vi_clist, % \l_@@_ncolors_int, % \l_@@_temps_prop, % \l_@@_temp_tl, % \l_@@_filename_tl, % \l_@@_aliases_clist, % \l_@@_colors_clist, % \l_@@_vi_tl, % \l_@@_width_dim, % \l_@@_height_dim, % \l_@@_opacity_fp, % } % è§†è§‰æ ‡è¯†ä¸´æ—¶å˜é‡ã€‚ % \begin{macrocode} \tl_new:N \l_@@_dept_tl \clist_new:N \l_@@_vi_clist \int_new:N \l_@@_ncolors_int \prop_new:N \l_@@_temps_prop \tl_new:N \l_@@_temp_tl \tl_new:N \l_@@_filename_tl \clist_new:N \l_@@_aliases_clist \clist_new:N \l_@@_colors_clist \tl_new:N \l_@@_vi_tl \dim_new:N \l_@@_width_dim \dim_new:N \l_@@_height_dim \fp_new:N \l_@@_opacity_fp % \end{macrocode} % \end{macro} % % \begin{macro}{\g_@@_vi_prop} % è§†è§‰æ ‡è¯†å±žæ€§åˆ—è¡¨ã€‚ % \begin{macrocode} \prop_new:N \g_@@_vi_prop % \end{macrocode} % \end{macro} % % % \subsection{辅助函数} % % \begin{macro}{ % \@@_msg_new:nn, % \@@_warning:n, % \@@_warning:ne, % \@@_warning:nee, % \@@_warning:neee, % \@@_error:n, % \@@_error:ne, % \@@_error:nee, % \@@_error:neee, %} % å„ç§ä¿¡æ¯å‡½æ•°çš„缩略形å¼ã€‚ % \begin{macrocode} \cs_new:Npn \@@_msg_new:nn { \msg_new:nnn { hustvisual } } \cs_new:Npn \@@_warning:n { \msg_warning:nn { hustvisual } } \cs_new:Npn \@@_warning:ne { \msg_warning:nne { hustvisual } } \cs_new:Npn \@@_warning:nee { \msg_warning:nnee { hustvisual } } \cs_new:Npn \@@_warning:neee { \msg_warning:nneee { hustvisual } } \cs_new:Npn \@@_error:n { \msg_error:nn { hustvisual } } \cs_new:Npn \@@_error:ne { \msg_error:nne { hustvisual } } \cs_new:Npn \@@_error:nee { \msg_error:nnee { hustvisual } } \cs_new:Npn \@@_error:neee { \msg_error:nneee { hustvisual } } % \end{macrocode} % \end{macro} % % \subsection{å®åŒ…载入} % % \begin{macrocode} \RequirePackage{tikz} \RequirePackage{xcolor} % \end{macrocode} % % \subsection{内部函数} % % \begin{macro}{\@@_deploy_colors:} % å°† \cs{l_@@_color_args_clist} 展开到对应的å˜é‡æ–¹ä¾¿åœ¨è§†è§‰æ ‡è¯†æ–‡ä»¶ï¼ˆ|hustvisual-*.def|)ä¸è°ƒç”¨ã€‚ % \begin{macrocode} \@@_msg_new:nn { color-args-exceed } { The~ `colors'~ arguments(#1)~ exceed~ the~ number~ of~ defined~ colors(#2). Please~ check~ the~ number~ of~ colors~ in~ the~ documentation~ of~ the~ package. } \int_new:N \l_@@_color_nargs_int \cs_new:Npn \@@_deploy_colors: { \int_set:Nn \l_@@_color_nargs_int { \clist_count:N \l_@@_color_args_clist } \int_compare:nNnTF { \l_@@_color_nargs_int } > { \c_@@_nargs_int } { \@@_warning:nee { color-args-exceed } { \int_use:N \l_@@_color_nargs_int } { \int_use:N \c_@@_nargs_int } \@@_deploy_colors:N \c_@@_nargs_int } { \@@_deploy_colors:N \l_@@_color_nargs_int } } \tl_new:N \l_@@_color_arg_tl \cs_new:Npn \@@_deploy_colors:N #1 { \int_step_inline:nn { #1 } { \tl_set:Nx \l_@@_color_arg_tl { l_@@_color_arg_ \clist_item:Nn \c_@@_args_clist { ##1 } _tl } \tl_set:cx { \l_@@_color_arg_tl } { \clist_item:Nn \l_@@_color_args_clist { ##1 } } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_sort_vi_name:, \@@_sort_vi_name:N} % 对 \cs{l_@@_vi_clist} 进行排åºã€‚ % \begin{macrocode} \cs_new:Npn \@@_sort_vi_name: { \@@_sort_vi_name:N \l_@@_vi_clist } \cs_new:Npn \@@_sort_vi_name:N #1 { \clist_sort:Nn #1 { \str_compare:nNnTF { ##1 } > { ##2 } { \sort_return_swapped: } { \sort_return_same: } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_vi_name:, \@@_vi_name:N, \@@_vi_name:NN} % 从 \cs{l_@@_dept_tl},和 \cs{l_@@_vi_clist} ä¸ç”Ÿæˆå”¯ä¸€çš„è§†è§‰æ ‡è¯†å称。 % \begin{macrocode} \tl_const:Nn \c_@@_dept_sep_tl { - } \tl_const:Nn \c_@@_vi_sep_tl { - } \cs_new:Npn \@@_vi_name: { \@@_vi_name:N \l_@@_vi_clist } \cs_new:Npn \@@_vi_name:N #1 { \@@_vi_name:NN \l_@@_dept_tl #1 } \cs_new:Npn \@@_vi_name:NN #1#2 { \tl_use:N #1 \tl_use:N \c_@@_dept_sep_tl \exp_args:NNV \clist_use:Nn #2 \c_@@_vi_sep_tl } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_vi_filename:} % 生æˆè§†è§‰æ ‡è¯†æ–‡ä»¶å。 % \begin{macrocode} \tl_const:Nn \c_@@_vi_filename_prefix_tl { hustvisual- } \tl_const:Nn \c_@@_vi_filename_suffix_tl { .def } \cs_new:Npn \@@_vi_filename: { \tl_use:N \c_@@_vi_filename_prefix_tl \@@_vi_name: \tl_use:N \c_@@_vi_filename_suffix_tl } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_prop_default_value:N} % 定义属性的默认值为第一个æ’入的值。 % \begin{macrocode} %\bool_new:N \l_@@_prop_set_bool \tl_new:N \l_@@_prop_set_tl \cs_new:Npn \@@_prop_default_value:N #1 { \bool_set_false:N \l_@@_prop_set_bool % \end{macrocode} % \cs{prop_map_break:} å› æœªçŸ¥åŽŸå› æ— æ³•ä½¿ç”¨ã€‚ % \begin{macrocode} \prop_map_inline:Nn #1 { \bool_if:NF \l_@@_prop_set_bool { \bool_set_true:N \l_@@_prop_set_bool \tl_set:Nn \l_@@_prop_set_tl { ##2 } } } \tl_use:N \l_@@_prop_set_tl } % \end{macrocode} % \end{macro} % % \begin{macrocode} \keys_define:nn { hustvisual } { dev .meta:nn = { hustvisual / dev } { #1 }, user .meta:nn = { hustvisual / user } { #1 }, } % \end{macrocode} % % \subsection{忍¡å—接å£} % % \subsubsection{色彩定义} % % \begin{macro}{\@@_set_color:nnn} % å®šä¹‰è‰²å½©çš„å‡½æ•°ã€‚åŒæ—¶å®šä¹‰äº† \pkg{l3color} å’Œ \pkg{xcolor} ä¸çš„色彩。 % æ¤å¤–,新增了 \opt{CMYK} 色彩模型的支æŒï¼Œç”¨äºŽæ·»åŠ 0--100 范围的 \opt{cmyk} 色彩。 % \begin{arguments} % \item 色彩åç§° % \item 色彩模型,如 \opt{CMYK}(0--100)ã€\opt{cmyk}(0--1)ã€\opt{RGB}(0--255)ã€\opt{rgb}(0--1) ç‰ % \item 色彩值,用逗å·åˆ†éš”的数值 % \end{arguments} % \begin{macrocode} \seq_new:N \l_@@_color_models_seq \seq_new:N \l_@@_color_values_seq \int_new:N \l_@@_set_colors_int \tl_new:N \l_@@_color_model_tl \tl_new:N \l_@@_color_models_tl \tl_new:N \l_@@_color_values_tl \clist_new:N \l_@@_set_colors_clist \cs_new:Npn \@@_set_color:nnn #1#2#3 { \seq_set_split:Nnn \l_@@_color_models_seq { / } { #2 } \seq_set_split:Nnn \l_@@_color_values_seq { / } { #3 } \int_compare:nNnF { \seq_count:N \l_@@_color_models_seq } = { \seq_count:N \l_@@_color_values_seq } { \@@_error:nee { color-models-unpair } { \seq_count:N \l_@@_color_models_seq } { \seq_count:N \l_@@_color_values_seq } } \exp_args:NNe \int_set:Nn \l_@@_set_colors_int { \seq_count:N \l_@@_color_models_seq } \int_step_inline:nn { \l_@@_set_colors_int } % ##1 { \tl_set:Ne \l_@@_color_model_tl { \seq_item:Nn \l_@@_color_models_seq { ##1 } } \exp_args:Nne \str_if_eq:nnT { CMYK } { \seq_item:Nn \l_@@_color_models_seq { ##1 } } { \clist_clear:N \l_@@_set_colors_clist \seq_set_item:Nnn \l_@@_color_models_seq { ##1 } { cmyk } \exp_args:Ne \clist_map_inline:nn % ####1 { \seq_item:Nn \l_@@_color_values_seq { ##1 } } { \clist_put_right:Ne \l_@@_set_colors_clist { \fp_to_decimal:n { \fp_eval:n { ####1 / 100 } } } } \exp_args:NNnV \seq_set_item:Nnn \l_@@_color_values_seq { ##1 } \l_@@_set_colors_clist } } \tl_set:Ne \l_@@_color_models_tl { \seq_use:Nn \l_@@_color_models_seq { / } } \tl_set:Ne \l_@@_color_values_tl { \seq_use:Nn \l_@@_color_values_seq { / } } \exp_args:Nnee \color_set:nnn { #1 } { \l_@@_color_models_tl } { \l_@@_color_values_tl } \definecolor { #1 } { \l_@@_color_models_tl } { \l_@@_color_values_tl } } \@@_msg_new:nn { color-models-unpair } { The~ number(#1)~ of~ color~ models~ in~ the~ `colors'~ arguments~ is~ not~ equal~ to~ the~ number(#2)~ of~ color values. } % \end{macrocode} % \end{macro} % % \subsubsection{图案定义} % % \begin{macro}{\@@_set_vi:n} % å®šä¹‰è§†è§‰æ ‡è¯†å›¾æ¡ˆçš„å‡½æ•°ã€‚ % \begin{macrocode} \cs_new:Npn \@@_set_vi:n #1 { \group_begin: \keys_set:nn { hustvisual / dev } { #1 } \@@_process_set_vi: \group_end: } %\prop_new:N \l_@@_colors_clist \keys_define:nn { hustvisual / dev } { dept .choices:Vn = \c_@@_depts_clist { \tl_set_eq:NN \l_@@_dept_tl \l_keys_choice_tl }, dept .initial:V = \c_@@_univ_tl, vi .clist_set:N = \l_@@_vi_clist, vi .value_required:n = true, ncolors .int_set:N = \l_@@_ncolors_int, ncolors .initial:V = \c_zero_int, temps .meta:nn = { hustvisual / dev / temps } { #1 }, temps / unknown .code:n = { \clist_set:Nn \l_@@_colors_clist { #1 } \prop_put:NVV \l_@@_temps_prop \l_keys_key_str \l_@@_colors_clist }, filename .tl_set:N = \l_@@_filename_tl, filename .initial:V = \c_empty_tl, aliases .clist_set:N = \l_@@_aliases_clist, aliases .initial:V = \c_empty_clist, } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_process_set_vi:} % 处ç†åœ¨å®šä¹‰è§†è§‰æ ‡è¯†å›¾æ¡ˆæ—¶ä¼ å…¥çš„å‚æ•°ã€‚ % \begin{macrocode} \prop_new:N \l_@@_vi_prop \int_new:N \l_@@_ncolors_tmp_int \clist_new:N \l_@@_alias_name_clist \tl_new:N \l_@@_alias_name_tl \cs_new:Npn \@@_process_set_vi: { \prop_clear:N \l_@@_vi_prop \int_compare:nNnT { \l_@@_ncolors_int } > { \c_@@_nargs_int } { \@@_error:nee { colors-exceed-max } { \int_use:N \l_@@_ncolors_int } { \int_use:N \c_@@_nargs_int } } \prop_put:NnV \l_@@_vi_prop { ncolors } \l_@@_ncolors_int \prop_map_inline:Nn \l_@@_temps_prop { \int_set:Nn \l_@@_ncolors_tmp_int { \clist_count:n { ##2 } } \int_compare:nNnF { \l_@@_ncolors_int } = { \l_@@_ncolors_tmp_int } { \@@_error:neee { colors-not-match } { ##1 } { \int_use:N \l_@@_ncolors_tmp_int } { \int_use:N \l_@@_ncolors_int } } } \int_compare:nNnF { \l_@@_ncolors_int } = { \c_zero_int } { \int_compare:nNnT { \prop_count:N \l_@@_temps_prop } = { \c_zero_int } { \@@_error:n { no-temp } } } \prop_put:NnV \l_@@_vi_prop { temps } \l_@@_temps_prop \@@_sort_vi_name: \tl_if_empty:NT \l_@@_filename_tl { \tl_set:Ne \l_@@_filename_tl { \@@_vi_filename: } } \file_if_exist:VF \l_@@_filename_tl { \@@_warning:nee { filename-error } { \tl_use:N \l_@@_filename_tl } { \@@_vi_name: } } \prop_put:NnV \l_@@_vi_prop { filename } \l_@@_filename_tl \prop_if_in:NeT \g_@@_vi_prop { \@@_vi_name: } { \@@_warning:ne { vi-skip } { \@@_vi_name: } } \prop_gput_if_not_in:NeV \g_@@_vi_prop \@@_vi_name: \l_@@_vi_prop \clist_map_variable:NNn \l_@@_aliases_clist \l_@@_alias_name_clist { \prop_clear:N \l_@@_vi_prop \prop_put:Nne \l_@@_vi_prop { source } { \@@_vi_name: } \tl_set:Ne \l_@@_alias_name_tl { \@@_vi_name:N \l_@@_alias_name_clist } \prop_if_in:NVT \g_@@_vi_prop \l_@@_alias_name_tl { \@@_warning:nee { vi-skip } { \l_@@_alias_name_tl } } \prop_gput_if_not_in:NVV \g_@@_vi_prop \l_@@_alias_name_tl \l_@@_vi_prop } } \@@_msg_new:nn { colors-exceed-max } { The~ number(#1)~ of~ colors~ in~ the~ `ncolors'~ property~ exceeds~ the~ maximum~ number(#2)~ of~ colors.~ Please~ increase~ the~ number~ of~ colors~ in~ the~ \c_@@_nargs_int. } \@@_msg_new:nn { no-temp } { The~ `temps'~ property~ should~ be~ set~ to~ a~ list~ of~ colors,~ when~ the~ `ncolors'~ property~ is~ not~ zero. } \@@_msg_new:nn { colors-not-match } { The~ number(#2)~ of~ colors~ in~ the~ `temps'~ property(#1)~ does~ not~ match~ the~ number(#3)~ asserted~ in~ the~ `ncolors'~ property. } \@@_msg_new:nn { filename-error } { The~ filename~(#1)~ of~ the~ vi(#2)~ is~ not~ found~ in~ the~ TeX~ search~ path.~ Please~ check~ the~ filename. } \@@_msg_new:nn { vi-skip } { The~ vi~(#1)~ is~ already~ defined.~ The~ new~ definition~ has~ been~ skipped. } % \end{macrocode} % \end{macro} % % % \subsection{用户接å£} % % \begin{macro}{\hustvi} % æ’å…¥è§†è§‰æ ‡è¯†å›¾æ¡ˆçš„ä¸»å‡½æ•°ã€‚ % \begin{macrocode} \NewDocumentCommand \hustvi { O{} m } { \group_begin: \keys_set:nn { hustvisual / user } { #1, vi = { #2 }, } \@@_process_vi_name: \@@_process_temp: \@@_process_colors: \@@_process_file: \@@_process_vi: \group_end: } \keys_define:nn { hustvisual / user } { dept .choices:Vn = \c_@@_depts_clist { \tl_set_eq:NN \l_@@_dept_tl \l_keys_choice_tl }, vi .clist_set:N = \l_@@_vi_clist, vi .value_required:n = true, filename .tl_set:N = \l_@@_filename_tl, filename .initial:V = \c_empty_tl, width .dim_set:N = \l_@@_width_dim, width .initial:V = \c_zero_dim, height .dim_set:N = \l_@@_height_dim, height .initial:V = \c_zero_dim, temp .tl_set:N = \l_@@_temp_tl, temp .initial:V = \c_empty_tl, colors .clist_set:N = \l_@@_colors_clist, colors .initial:V = \c_empty_clist, opacity .fp_set:N = \l_@@_opacity_fp, opacity .initial:V = \c_one_fp, } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_process_vi_name:} % 处ç†è§†è§‰æ ‡è¯†å”¯ä¸€å称以åŠåˆ«å的函数。 % \begin{macrocode} \tl_new:N \l_@@_source_name_tl \cs_new:Npn \@@_process_vi_name: { \@@_sort_vi_name: \prop_get:NeNF \g_@@_vi_prop \@@_vi_name: \l_@@_vi_prop { \@@_error:nee { invalid-vi-name } { \l_@@_dept_tl } { \l_@@_vi_clist } } \prop_get:NnNT \l_@@_vi_prop { source } \l_@@_source_name_tl { \prop_get:NVN \g_@@_vi_prop \l_@@_source_name_tl \l_@@_vi_prop } } \@@_msg_new:nn { invalid-vi-name } { The~ combination~ of~ `dept'(#1)~ and~ `vi'(#2)~ is~ not~ valid.~ Please~ check~ the~ documentation~ of~ the~ package. } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_process_temp:} % 处ç†è§†è§‰æ ‡è¯†è‰²å½©é¢„设模æ¿çš„函数。 % \begin{macrocode} \bool_new:N \l_@@_prop_set_bool \cs_new:Npn \@@_process_temp: { \prop_get:NnN \l_@@_vi_prop { temps } \l_@@_temps_prop \prop_get:NVNF \l_@@_temps_prop \l_@@_temp_tl \l_@@_color_args_clist { \tl_if_empty:NF \l_@@_temp_tl { \@@_warning:ne { invalid-temp } { \l_@@_temp_tl } } \bool_set_false:N \l_@@_prop_set_bool \prop_map_inline:Nn \l_@@_temps_prop { \bool_if:NF \l_@@_prop_set_bool { \bool_set_true:N \l_@@_prop_set_bool \clist_set:Nn \l_@@_color_args_clist { ##2 } } } } \@@_deploy_colors: } \@@_msg_new:nn { invalid-temp } { The~ `temp'~ property~(#1)~ is~ not~ valid.~ The~ default~ template~ will~ be~ used.~ Please~ check~ the~ documentation~ of~ the~ package. } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_process_colors:} % 处ç†è§†è§‰æ ‡è¯†å›¾æ¡ˆè¦†å†™è‰²å½©çš„函数。 % \begin{macrocode} \tl_new:N \l_@@_color_tl \cs_new:Npn \@@_process_colors: { \clist_if_empty:NF \l_@@_colors_clist { \clist_set_eq:NN \l_@@_color_args_clist \l_@@_colors_clist \@@_deploy_colors: } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_process_file:} % 读å–è§†è§‰æ ‡è¯†æ–‡ä»¶ï¼ˆ|hustvisual-*.def|),并将其内容å‰åŽæ·»åŠ \TikZ 环境。 % \begin{macrocode} \cs_new:Npn \@@_process_file: { \tl_if_empty:NT \l_@@_filename_tl { \prop_get:NnN \l_@@_vi_prop { filename } \l_@@_filename_tl } \file_get:VnNF \l_@@_filename_tl { \ExplSyntaxOn } \l_@@_vi_tl { \@@_error:ne { file-not-found } { \tl_use:N \l_@@_filename_tl } } \tl_gput_left:Nn \l_@@_vi_tl { \begin{tikzpicture}[ inner~sep=0pt, outer~sep=0pt, opacity=\fp_use:N \l_@@_opacity_fp ] } \tl_gput_right:Nn \l_@@_vi_tl { \end{tikzpicture} \color_fill:n {red} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_process_vi:} % 处ç†è§†è§‰æ ‡è¯†å›¾æ¡ˆå°ºå¯¸çš„函数。 % \begin{macrocode} \box_new:N \l_@@_vi_box \cs_new:Npn \@@_process_vi: { \exp_args:NNV \hbox_set:Nn \l_@@_vi_box \l_@@_vi_tl \dim_compare:nNnTF { \l_@@_width_dim } > { \c_zero_dim } { \dim_compare:nNnTF { \l_@@_height_dim } > { \c_zero_dim } { \exp_args:NNVV \box_resize_to_wd_and_ht:Nnn \l_@@_vi_box \l_@@_width_dim \l_@@_height_dim } { \exp_args:NNV \box_resize_to_wd:Nn \l_@@_vi_box \l_@@_width_dim } } { \dim_compare:nNnT { \l_@@_height_dim } > { \c_zero_dim } { \exp_args:NNV \box_resize_to_ht:Nn \l_@@_vi_box \l_@@_height_dim } } \box_use:N \l_@@_vi_box } \@@_msg_new:nn { file-not-found } { The~ file~(#1)~ is~ not~ found.~ Please~ check~ the~ file~ name. } % \end{macrocode} % \end{macro} % % \begin{macrocode} %</package> % \end{macrocode} % \subsection{æ–‡æ¡£æ ·å¼} % \begin{macrocode} %<*doc-sty> % \end{macrocode} % % 解决 |Package multicol Error: Error saving partial page.| % 方法æ¥è‡ªäºŽ \url{https://tex.stackexchange.com/a/95893}。 % \begin{macrocode} \setlength\IndexMin{100pt} % \end{macrocode} % % \begin{macro}[no-user-doc]{\TikZ} % \begin{macrocode} \newcommand\TikZ{Ti\emph{k}Z} % \end{macrocode} % \end{macro} % % \begin{macro}[no-user-doc]{\key} % 用于在文档ä¸è¾“出自定义索引的命令,主è¦ç”¨äºŽé”®å€¼å¯¹çš„键的索引。仅当索引项的父分类为 |hustvi| 时,å³ç”¨äºŽæ–‡æ¡£ç±»é€‰é¡¹æ—¶ï¼Œéšè—父分类。 % \begin{arguments} % \item åœ¨ç´¢å¼•ä¸æ˜¾ç¤ºé¡¹çš„父分类,默认为 \opt{hustvi}。 % \item 命令本体。 % \end{arguments} % \begin{macrocode} \DeclareDocumentCommand \key { O{hustvi} m } { \tl_if_eq:nnTF { #1 } { hustvi } { \cmd[module=#1/]{#2} } { \cmd[module=#1/]{#1/#2} } } % \end{macrocode} % \end{macro} % % \begin{macro}[no-user-doc]{\opt} % 输出键值对的值。 % \begin{macrocode} \DeclareDocumentCommand \opt { s m } { \IfBooleanTF {#1} { \texttt{\bfseries \upshape #2} } { \texttt{\upshape #2} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\g_@@_show_vi_bool} % å®šä¹‰æ˜¯å¦æ˜¾ç¤ºè§†è§‰æ ‡è¯†å®žçŽ°çš„å…¨å±€å˜é‡ï¼Œé»˜è®¤ä¸ºä¸æ˜¾ç¤ºã€‚ % \begin{macrocode} \bool_new:N \g_@@_show_vi_bool \bool_gset_false:N \g_@@_show_vi_bool % \end{macrocode} % \end{macro} % % \begin{environment}{viimplementation} % å®šä¹‰å®žçŽ°è§†è§‰æ ‡è¯†æ‰€éœ€è¦çš„æ–‡æ¡£çŽ¯å¢ƒã€‚ % \begin{macrocode} \NewDocumentEnvironment { viimplementation } { } { \bool_if:NF \g_@@_show_vi_bool { \comment } } { \bool_if:NF \g_@@_show_vi_bool { \endcomment } } % \end{macrocode} % \end{environment} % % \begin{macrocode} %</doc-sty> % \end{macrocode} % % \section{忍¡å—实现细节} % % \end{implementation}