![自定义符号 - 简化方式](https://linux22.com/image/474191/%E8%87%AA%E5%AE%9A%E4%B9%89%E7%AC%A6%E5%8F%B7%20-%20%E7%AE%80%E5%8C%96%E6%96%B9%E5%BC%8F.png)
我有一个名为的自定义符号\trident
,我对它的编程有点笨拙。
我想使用一种更优雅的方法,例如@egreg\commonroot
在这篇文章中为我的符号建议的方法:
https://tex.stackexchange.com/a/711580/262813
如 MWE 所示,智能\coolsource
命令必须能够根据传递的参数自动选择应该使用两个符号中的哪一个。
平均能量损失
\documentclass{article}
\usepackage{fontspec}
\usepackage{xparse}
\usepackage{graphicx}
\setmainfont{Times New Roman}
\newfontface{\arrows}{STIX Two Math}[Scale=0.7]
\NewDocumentCommand{\lex}{>{\SplitArgument{1}{,}}m}{\lexAUX#1}
\NewDocumentCommand{\lexAUX}{mm}{%
\textit{#1}%
\IfValueT{#2}{\textup{\textsubscript{\textsc{#2}}}}%
}
\NewDocumentCommand{\commonroot}{}{%
\raisebox{\depth}{%
\normalfont\arrows
\kern0.225em
\symbol{"2199}\kern-0.236em\symbol{"2198}%
\kern0.225em
}%
}
\newcommand{\trident}{%
\raisebox{-0.6ex}{\rotatebox{45}{\textleftarrow\!\!}}%
\kern0.025em%
\makebox[0pt][c]{\kern0.05em\raisebox{-0.9ex}{\rotatebox{90}{\textleftarrow}}}%
\raisebox{0.453ex}{\rotatebox{-45}{\!\!\textrightarrow}}}
\NewDocumentCommand{\coolsource}{ommg}{%
\IfValueTF{#1}{%
$\hspace*{-1pt}\left\{\begin{array}{@{}c@{}}}{%
\IfValueTF{#4}{$\hspace*{-1pt}\left\{\begin{array}{@{}c@{}}}{\textup{\{}}}%
\lex{#2}%
\kern0.25em%
\IfValueTF{#4}{
\trident%
\raisebox{-2ex}{\kern-0.8em\makebox[0pt][c]{\lex{#4}}}% Adjust the -2ex as needed to position the text
}{%
% If the third argument is not provided, just use \commonroot
\commonroot%
}%
\IfValueT{#1}{\IfValueF{#4}{\kern-0.8em}\raisebox{2.25ex}{\makebox[0pt][c]{\lex{#1}}}}%
\IfValueTF{#4}{\kern1.05em}{\IfValueTF{#1}{\kern1.05em}{\kern0.25em}}%
\lex{#3}%
\IfValueTF{#1}{%
\end{array} \right\}$}{%
\IfValueTF{#4}{\end{array}\right\}$}{\textup{\}}}}}
\begin{document}
\coolsource{contracter,v}{contraction,n}{contracture,n}
\vspace*{2ex}
\coolsource[contraire,v]{contracter,v}{contraction,n}{contracture,n}
\vspace*{2ex}
\coolsource[contraire,v]{contracter,v}{contraction,n}
\vspace*{2ex}
\coolsource{contracter,v}{contraction,n}
\end{document}
另外,我会使用\tetradent
,这样就可以在底部有两个导数,而不是 1 个(而不是垂直向南的箭头,我们会得到两个箭头,即 SSW 箭头和 SSE 箭头;#4/#5 可选参数将被逗号分成两部分,并\IfValueT{#5}
会触发四齿兽)。我再次可以以 67.5 和 112.5 度角旋转一个向右箭头,但也许我们STIX Two
也可以在这种情况下使用。
\newcommand{\tetradent}{%
\raisebox{-0.5ex}{\rotatebox{45}{\textleftarrow\!\!}}%
\kern0.025em%
\makebox[0pt][c]{\kern-0.267em\raisebox{-0.845ex}{\rotatebox{67.5}{\textleftarrow}}}%
\makebox[0pt][c]{\kern0.36em\raisebox{-0.41ex}{\rotatebox{112.5}{\textleftarrow}}}%
\raisebox{0.553ex}{\rotatebox{-45}{\!\!\textrightarrow}}}
如果我尝试包含\tetradent
大小写,以及一个布尔值,以便通过将源词素括在框架内来以某种方式区分源词素,我会得到一个命令,该命令在可能性树的向右移动以及要计算和添加的补偿字距方面处理起来非常复杂。
平均能量损失
\documentclass{article}
\usepackage{fontspec}
\usepackage{xparse}
\usepackage{graphicx}
\usepackage{tcolorbox}
\setmainfont{Times New Roman}
\newfontface{\arrows}{STIX Two Math}[Scale=0.7]
\NewDocumentCommand{\lex}{>{\SplitArgument{1}{,}}m}{\lexAUX#1}
\NewDocumentCommand{\lexAUX}{mm}{%
\textit{#1}%
\IfValueT{#2}{\textup{\textsubscript{\textsc{#2}}}}%
}
\NewDocumentCommand{\commonroot}{}{%
\raisebox{\depth}{%
\normalfont\arrows
\kern0.225em
\symbol{"2199}\kern-0.236em\symbol{"2198}%
\kern0.225em
}%
}
\newcommand{\trident}{%
\raisebox{-0.5ex}{\rotatebox{45}{\textleftarrow\!\!}}%
\kern0.025em%
\makebox[0pt][c]{\kern0.0518em\raisebox{-0.67ex}{\rotatebox{90}{\textleftarrow}}}%
\raisebox{0.553ex}{\rotatebox{-45}{\!\!\textrightarrow}}}% Right arrow
\newcommand{\tetradent}{%
\raisebox{-0.5ex}{\rotatebox{45}{\textleftarrow\!\!}}%
\kern0.025em%
\makebox[0pt][c]{\kern-0.267em\raisebox{-0.845ex}{\rotatebox{67.5}{\textleftarrow}}}%
\makebox[0pt][c]{\kern0.36em\raisebox{-0.41ex}{\rotatebox{112.5}{\textleftarrow}}}%
\raisebox{0.553ex}{\rotatebox{-45}{\!\!\textrightarrow}}}
\NewDocumentCommand{\coolsource}{sommgg}{%
\IfValueTF{#2}{%
$\hspace*{-1pt}\left\{\begin{array}{@{}c@{}}}{%
\IfValueTF{#5}{$\hspace*{-1pt}\left\{\begin{array}{@{}c@{}}}{\textup{\{}}}%
\IfValueTF{#6}{\lex{\footnotesize#3}}{\lex{#3}}%
\kern0.25em%
\IfValueTF{#5}{
\IfValueTF{#6}{%
\tetradent
\raisebox{-2.5ex}{\kern-3em\makebox[0pt][c]{\lex{\footnotesize#5}}}%
\raisebox{-2.5ex}{\kern4.5em\makebox[0pt][c]{\lex{\footnotesize#6}}}%
}{%
\trident%
\raisebox{-2.5ex}{\kern-0.8em\makebox[0pt][c]{\lex{#5}}}%
}}{%
% If the third argument is not provided, just use \commonroot
\commonroot%
}%
\IfValueT{#2}{\IfValueF{#5}{\kern-0.8em}{%
\IfValueT{#6}{\kern-2.2em}
\IfBooleanTF{#1}{\raisebox{3ex}{\makebox[0pt][c]{%
\tcbox[nobeforeafter, tcbox raise base,
colframe=black, boxrule=0.12ex, arc=0mm,
boxsep=0pt, left=2pt, right=2pt, top=2pt, bottom=2pt]{\lex{#2}}}}}{%
\raisebox{2.5ex}{\makebox[0pt][c]{\lex{#2}}}}%
}}%
\IfValueTF{#5}{\IfValueTF{#2}{\kern1.05em}{\IfValueTF{#6}{\kern-1.15em}{\kern1.05em}}}{\IfValueTF{#2}{\kern1.05em}{\kern0.25em}}%
\IfValueTF{#6}{\lex{\footnotesize#4}}{\lex{#4}}%%
\IfValueTF{#2}{%
\end{array}\right\}$}{%
\IfValueTF{#5}{\end{array}\right\}$}{\textup{\}}}}}
\begin{document}
\coolsource{contracter,v}{contraction,n}{contracture,n}
\vspace*{2ex}
\coolsource[contraire,v]{contracter,v}{contraction,n}{contracture,n}
\vspace*{2ex}
\coolsource[contraire,v]{contracter,v}{contraction,n}{contracture,n}{contracteur,n}
\vspace*{2ex}
\coolsource{contracter,v}{contraction,n}
\vspace*{2ex}
\coolsource{contracter,v}{contraction,n}{contracture,n}
\vspace*{2ex}
\coolsource{contracter,v}{contraction,n}{contracture,n}{contracteur,n}
\vspace*{2ex}
\coolsource*[contraire,v]{contracter,v}{contraction,n}{contracture,n}{contracteur,n}
\end{document}
答案1
不完全是答案,但我可能会选择 Expl 口味的 Ti钾Z 解决方案使绘制箭头和定位不同部分变得更加容易。我还将使用逗号分隔列表(我将内部分隔符更改为冒号):
\documentclass[tikz, border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing, fit}
\ExplSyntaxOn
% if the code does not compile try to uncomment the following line
% \cs_generate_variant:Nn \tl_set:Nn { Ne }
\cs_generate_variant:Nn \seq_set_split:Nnn { Nee }
\seq_new:N \l_vincentkrebs_coolsource_deriv_parts_seq
\cs_new:Npn \vincentkrebs_coolsource_format #1 {
\seq_set_split:Nee \l_vincentkrebs_coolsource_deriv_parts_seq { \c_colon_str } { #1 }
\tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_deriv_parts_seq { 1 } }
\tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_deriv_parts_seq { 2 } }
\textit{\tl_use:N \l_tmpa_tl} \tl_if_empty:NF \l_tmpb_tl {\textup{\textsubscript{\textsc{\tl_use:N \l_tmpb_tl}}}}
}
\clist_new:N \l_vincentkrebs_coolsource_derivs_clist
\clist_new:N \l_vincentkrebs_coolsource_fitspec_clist
\NewDocumentCommand{\coolsource}{ o O{} m }{
\clist_set:Nn \l_vincentkrebs_coolsource_derivs_clist { #3 }
\clist_clear:N \l_vincentkrebs_coolsource_fitspec_clist
\begin{tikzpicture}[baseline=(a)]
\coordinate (a) at (0,0);
\IfValueT{#1}{
\node[anchor=south, #2] (A) at (a) { \vincentkrebs_coolsource_format { #1 } };
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (A) }
}
\coordinate (b) at (-1em,-0.6em);
\coordinate (c) at (1em,-0.6em);
\tl_set:Ne \l_tmpa_tl { \clist_item:Nn \l_vincentkrebs_coolsource_derivs_clist { 1 } }
\tl_set:Ne \l_tmpb_tl { \clist_item:Nn \l_vincentkrebs_coolsource_derivs_clist { 2 } }
\node[anchor=east] (B) at (b) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
\node[anchor=west] (C) at (c) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpb_tl } };
\draw[<->] (b.west) -- (a.south) -- (c.east);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (B), (C) }
\int_compare:nNnT { \clist_count:N \l_vincentkrebs_coolsource_derivs_clist } > { 2 } {
\int_compare:nNnTF { \clist_count:N \l_vincentkrebs_coolsource_derivs_clist } > { 3 } {
\coordinate (d) at (0em,-1.2em);
\coordinate (e) at (0em,-1.2em);
\tl_set:Ne \l_tmpa_tl { \clist_item:Nn \l_vincentkrebs_coolsource_derivs_clist { 3 } }
\tl_set:Ne \l_tmpb_tl { \clist_item:Nn \l_vincentkrebs_coolsource_derivs_clist { 4 } }
\node[anchor=north ~ east] (D) at (d) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
\node[anchor=north ~ west] (E) at (e) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpb_tl } };
\draw[->] (a.south) -- ([xshift=-0.5em]d.north);
\draw[->] (a.south) -- ([xshift=0.5em]e.north);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D), (E) }
} {
\coordinate (d) at (0em,-1.2em);
\tl_set:Ne \l_tmpa_tl { \clist_item:Nn \l_vincentkrebs_coolsource_derivs_clist { 3 } }
\node[anchor=north] (D) at (d) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
\draw[->] (a.south) -- (d.north);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D) }
}
}
\node[fit={ \clist_use:Nn \l_vincentkrebs_coolsource_fitspec_clist { } }] (frame) {};
\draw[decorate, decoration={brace, mirror}] (frame.north ~ west) -- (frame.south ~ west);
\draw[decorate, decoration={brace}] (frame.north ~ east) -- (frame.south ~ east);
\end{tikzpicture}
}
\ExplSyntaxOff
\begin{document}
\coolsource{contracter:v,contraction:n}
\coolsource{contracter:v,contraction:n,contracture:n}
\coolsource[contraire:v]{contracter:v,contraction:n,contracture:n}
\coolsource[contraire:v]{contracter:v,contraction:n,contracture:n,contracteur:n}
\coolsource[contraire:v][draw, fill=blue!10, yshift=2pt]{contracter:v,contraction:n,contracture:n,contracteur:n}
\end{document}
使用不同的分隔符(这种变化允许您更轻松地更改分隔符,因为您只需在代码中更改它们即可):
\documentclass[tikz, border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing, fit}
\ExplSyntaxOn
% if the code does not compile try to uncomment the following line
% \cs_generate_variant:Nn \tl_set:Nn { Ne }
\cs_generate_variant:Nn \seq_set_split:Nnn { Nee }
\seq_new:N \l_vincentkrebs_coolsource_deriv_parts_seq
\cs_new:Npn \vincentkrebs_coolsource_format #1 {
\seq_set_split:Nee \l_vincentkrebs_coolsource_deriv_parts_seq { , } { #1 }
\tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_deriv_parts_seq { 1 } }
\tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_deriv_parts_seq { 2 } }
\textit{\tl_use:N \l_tmpa_tl} \tl_if_empty:NF \l_tmpb_tl {\textup{\textsubscript{\textsc{\tl_use:N \l_tmpb_tl}}}}
}
\seq_new:N \l_vincentkrebs_coolsource_derivs_seq
\clist_new:N \l_vincentkrebs_coolsource_fitspec_clist
\NewDocumentCommand{\coolsource}{ o O{} m }{
\seq_set_split:Nnn \l_vincentkrebs_coolsource_derivs_seq { ; } { #3 }
\clist_clear:N \l_vincentkrebs_coolsource_fitspec_clist
\begin{tikzpicture}[baseline=(a), >=stealth]
\coordinate (a) at (0,0);
\IfValueT{#1}{
\node[anchor=south, #2] (A) at (a) { \vincentkrebs_coolsource_format { #1 } };
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (A) }
}
\coordinate (b) at (-1em,-0.6em);
\coordinate (c) at (1em,-0.6em);
\tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 1 } }
\tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 2 } }
\node[anchor=east] (B) at (b) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
\node[anchor=west] (C) at (c) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpb_tl } };
\draw[<->] (b.west) -- (a.south) -- (c.east);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (B), (C) }
\int_compare:nNnT { \seq_count:N \l_vincentkrebs_coolsource_derivs_seq } > { 2 } {
\int_compare:nNnTF { \seq_count:N \l_vincentkrebs_coolsource_derivs_seq } > { 3 } {
\coordinate (d) at (0em,-1.2em);
\coordinate (e) at (0em,-1.2em);
\tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 3 } }
\tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 4 } }
\node[anchor=north ~ east] (D) at (d) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
\node[anchor=north ~ west] (E) at (e) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpb_tl } };
\draw[->] (a.south) -- ([xshift=-0.5em]d.north);
\draw[->] (a.south) -- ([xshift=0.5em]e.north);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D), (E) }
} {
\coordinate (d) at (0em,-1.2em);
\tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 3 } }
\node[anchor=north] (D) at (d) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
\draw[->] (a.south) -- (d.north);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D) }
}
}
\node[fit={ \clist_use:Nn \l_vincentkrebs_coolsource_fitspec_clist { } }] (frame) {};
\draw[decorate, decoration={brace, mirror}] (frame.north ~ west) -- (frame.south ~ west);
\draw[decorate, decoration={brace}] (frame.north ~ east) -- (frame.south ~ east);
\end{tikzpicture}
}
\ExplSyntaxOff
\begin{document}
\coolsource{contracter,v;contraction,n}
\coolsource{contracter,v;contraction,n;contracture,n}
\coolsource[contraire,v]{contracter,v;contraction,n;contracture,n}
\coolsource[contraire,v]{contracter,v;contraction,n;contracture,n;contracteur,n}
\coolsource[contraire,v][draw, fill=blue!10, yshift=2pt]{contracter,v;contraction,n;contracture,n;contracteur,n}
\end{document}
stealth
输出与上面相同(除了我根据您的评论更改为不同的箭头)。
看来您已经有一些格式化命令了。\coolsource
如果这能让您更轻松一些,您可以直接将其插入命令中:
\documentclass[tikz, border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing, fit}
\ExplSyntaxOn
% if the code does not compile try to uncomment the following line
% \cs_generate_variant:Nn \tl_set:Nn { Ne }
\clist_new:N \l_vincentkrebs_coolsource_derivs_clist
\clist_new:N \l_vincentkrebs_coolsource_fitspec_clist
\NewDocumentCommand{\coolsource}{ o O{} m }{
\clist_set:Nn \l_vincentkrebs_coolsource_derivs_clist { #3 }
\clist_clear:N \l_vincentkrebs_coolsource_fitspec_clist
\begin{tikzpicture}[baseline=(a), >=stealth]
\coordinate (a) at (0,0);
\IfValueT{#1}{
\node[anchor=south, #2] (A) at (a) { #1 };
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (A) }
}
\coordinate (b) at (-1em,-0.6em);
\coordinate (c) at (1em,-0.6em);
\tl_set:Ne \l_tmpa_tl { \clist_item:Nn \l_vincentkrebs_coolsource_derivs_clist { 1 } }
\tl_set:Ne \l_tmpb_tl { \clist_item:Nn \l_vincentkrebs_coolsource_derivs_clist { 2 } }
\node[anchor=east] (B) at (b) { \tl_use:N \l_tmpa_tl };
\node[anchor=west] (C) at (c) { \tl_use:N \l_tmpb_tl };
\draw[<->] (b.west) -- (a.south) -- (c.east);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (B), (C) }
\int_compare:nNnT { \clist_count:N \l_vincentkrebs_coolsource_derivs_clist } > { 2 } {
\int_compare:nNnTF { \clist_count:N \l_vincentkrebs_coolsource_derivs_clist } > { 3 } {
\coordinate (d) at (0em,-1.2em);
\coordinate (e) at (0em,-1.2em);
\tl_set:Ne \l_tmpa_tl { \clist_item:Nn \l_vincentkrebs_coolsource_derivs_clist { 3 } }
\tl_set:Ne \l_tmpb_tl { \clist_item:Nn \l_vincentkrebs_coolsource_derivs_clist { 4 } }
\node[anchor=north ~ east] (D) at (d) { \tl_use:N \l_tmpa_tl };
\node[anchor=north ~ west] (E) at (e) { \tl_use:N \l_tmpb_tl };
\draw[->] (a.south) -- ([xshift=-0.5em]d.north);
\draw[->] (a.south) -- ([xshift=0.5em]e.north);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D), (E) }
} {
\coordinate (d) at (0em,-1.2em);
\tl_set:Ne \l_tmpa_tl { \clist_item:Nn \l_vincentkrebs_coolsource_derivs_clist { 3 } }
\node[anchor=north] (D) at (d) { \tl_use:N \l_tmpa_tl };
\draw[->] (a.south) -- (d.north);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D) }
}
}
\node[fit={ \clist_use:Nn \l_vincentkrebs_coolsource_fitspec_clist { } }] (frame) {};
\draw[decorate, decoration={brace, mirror}] (frame.north ~ west) -- (frame.south ~ west);
\draw[decorate, decoration={brace}] (frame.north ~ east) -- (frame.south ~ east);
\end{tikzpicture}
}
\ExplSyntaxOff
\NewDocumentCommand{\lexAUX}{mm}{%
\textit{#1}%
\IfValueT{#2}{\textup{\textsubscript{\textsc{#2}}}}%
}
\begin{document}
\coolsource[\lexAUX{contraire}{v}]{\lexAUX{contracter}{v},\lexAUX{contraction}{n},\lexAUX{contracture}{n}}
\end{document}
但您也可以修改格式化命令,以便它采用一些语法,例如(prefix:word,category,translation,addendum
其中prefix
,,和是可选的)。我在这里使用了 Expl 和传统语法的组合,因为换行符在 Ti 中有特殊的定义category
translation
addeddum
\\
钾Z 似乎需要特别小心对待:
\documentclass[tikz, border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing, fit}
\newcommand{\tslt}[1]{`#1'}
\ExplSyntaxOn
\NewDocumentCommand{\IfEmptyF}{ m m }{
\tl_if_empty:nF { #1 } { #2 }
}
\ExplSyntaxOff
\NewDocumentCommand{\formatnode}{ m m m m m }{%
\IfEmptyF{#1}{#1 {}}%
\IfEmptyF{#2}{\textit{#2}\nocorr}%
\IfEmptyF{#3}{\textsubscript{\textup{\textsc{#3}}}}%
\IfEmptyF{#4}{\\\tslt{#4}}%
\IfEmptyF{#5}{ #5}%
}
\ExplSyntaxOn
% if the code does not compile try to uncomment the following line
% \cs_generate_variant:Nn \tl_set:Nn { Ne }
\cs_generate_variant:Nn \seq_set_split:Nnn { Nee }
\exp_args_generate:n { eeeee }
\cs_new:Npn \vincentkrebs_coolsource_format #1 {
\seq_set_split:Nee \l_tmpa_seq { , } { #1 }
\seq_set_split:Nee \l_tmpb_seq { \c_colon_str } { \seq_item:Nn \l_tmpa_seq { 1 } }
\int_compare:nNnTF { \seq_count:N \l_tmpb_seq } > { 1 } {
\tl_set:Nn \l_tmpa_tl { \seq_item:Nn \l_tmpb_seq { 1 } }
\tl_set:Nn \l_tmpb_tl { \seq_item:Nn \l_tmpb_seq { 2 } }
} {
\tl_set:Nn \l_tmpa_tl { }
\tl_set:Nn \l_tmpb_tl { \seq_item:Nn \l_tmpb_seq { 1 } }
}
\exp_args:Neeeee \formatnode{ \l_tmpa_tl }{ \l_tmpb_tl }{
\seq_item:Nn \l_tmpa_seq { 2 }
}{
\seq_item:Nn \l_tmpa_seq { 3 }
}{
\seq_item:Nn \l_tmpa_seq { 4 }
}
}
\seq_new:N \l_vincentkrebs_coolsource_derivs_seq
\clist_new:N \l_vincentkrebs_coolsource_fitspec_clist
\seq_new:N \l_vincentkrebs_coolsource_deriv_parts_seq
\NewDocumentCommand{\coolsource}{ o O{} m }{
\seq_set_split:Nnn \l_vincentkrebs_coolsource_derivs_seq { ; } { #3 }
\clist_clear:N \l_vincentkrebs_coolsource_fitspec_clist
\begin{tikzpicture}[baseline=(a), >=stealth, every ~ node/.append ~ style={align=center}]
\coordinate (a) at (0,0);
\IfValueT{#1}{
\node[anchor=south, #2] (A) at (a) { \vincentkrebs_coolsource_format { #1 } };
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (A) }
}
\coordinate (b) at (-1em,-0.6em);
\coordinate (c) at (1em,-0.6em);
\tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 1 } }
\tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 2 } }
\node[anchor=north ~ east, yshift=0.8em] (B) at (b) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
\node[anchor=north ~ west, yshift=0.8em] (C) at (c) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpb_tl } };
\draw[<->] (b.west) -- (a.south) -- (c.east);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (B), (C) }
\int_compare:nNnT { \seq_count:N \l_vincentkrebs_coolsource_derivs_seq } > { 2 } {
\int_compare:nNnTF { \seq_count:N \l_vincentkrebs_coolsource_derivs_seq } > { 3 } {
\coordinate (d) at (0em,-1.2em);
\coordinate (e) at (0em,-1.2em);
\tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 3 } }
\tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 4 } }
\node[anchor=north ~ east] (D) at (d) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
\node[anchor=north ~ west] (E) at (e) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpb_tl } };
\draw[->] (a.south) -- ([xshift=-0.5em]d.north);
\draw[->] (a.south) -- ([xshift=0.5em]e.north);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D), (E) }
} {
\coordinate (d) at (0em,-1.2em);
\tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 3 } }
\node[anchor=north] (D) at (d) { \vincentkrebs_coolsource_format { \tl_use:N \l_tmpa_tl } };
\draw[->] (a.south) -- (d.north);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D) }
}
}
\node[fit={ \clist_use:Nn \l_vincentkrebs_coolsource_fitspec_clist { } }] (frame) {};
\draw[decorate, decoration={brace, mirror}] (frame.north ~ west) -- (frame.south ~ west);
\draw[decorate, decoration={brace}] (frame.north ~ east) -- (frame.south ~ east);
\end{tikzpicture}
}
\ExplSyntaxOff
\begin{document}
\coolsource[pre:contraire,v,foo,bar]{pre:contracter,v;contraction,n,foo;contracture,n,foo,bar}
\end{document}
如果您想在节点的第二行放置更多文本,可能需要以不同的方式对齐内容。
答案2
Jasper
的代码运行得很好,并允许进行所有理想的调整:这里有一个例子,其风格接近 OP 中使用的风格。
\documentclass[tikz, border=0pt]{standalone}
\usepackage{fontspec}
\setmainfont{Times New Roman}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing, fit}
\ExplSyntaxOn
% if the code does not compile try to uncomment the following line
% \cs_generate_variant:Nn \tl_set:Nn { Ne }
\cs_generate_variant:Nn \seq_set_split:Nnn { Nee }
\seq_new:N \l_vincentkrebs_coolsource_deriv_parts_seq
\cs_new:Npn \vincentkrebs_coolsource_format #1 {
\seq_set_split:Nee \l_vincentkrebs_coolsource_deriv_parts_seq { , } { #1 }
\tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_deriv_parts_seq { 1 } }
\tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_deriv_parts_seq { 2 } }
\textit{\l_tmpa_tl} \tl_if_empty:NF \l_tmpb_tl {\textup{\textsubscript{\textsc{\l_tmpb_tl}}}}
}
\seq_new:N \l_vincentkrebs_coolsource_derivs_seq
\clist_new:N \l_vincentkrebs_coolsource_fitspec_clist
\NewDocumentCommand{\coolsource}{ o O{} m }{
\seq_set_split:Nnn \l_vincentkrebs_coolsource_derivs_seq { ; } { #3 }
\clist_clear:N \l_vincentkrebs_coolsource_fitspec_clist
\begin{tikzpicture}[baseline=(a), >=stealth,line~width=0.5pt]
\coordinate (a) at (0,0.25em);
\IfValueT{#1}{
\node[anchor=south, #2] (A) at (a) { \vincentkrebs_coolsource_format { #1 } };
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (A) }
}
\coordinate (b) at (-1em,-0.6em);
\coordinate (c) at (1em,-0.6em);
\tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 1 } }
\tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 2 } }
\node[anchor=east] (B) at (b) { \vincentkrebs_coolsource_format { \l_tmpa_tl } };
\node[anchor=west] (C) at (c) { \vincentkrebs_coolsource_format { \l_tmpb_tl } };
\draw[<->] (b.west) -- (a.south) -- (c.east);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (B), (C) }
\int_compare:nNnT { \seq_count:N \l_vincentkrebs_coolsource_derivs_seq } > { 2 } {
\int_compare:nNnTF { \seq_count:N \l_vincentkrebs_coolsource_derivs_seq } > { 3 } {
\coordinate (d) at (0em,-0.9em);
\coordinate (e) at (0em,-0.9em);
\tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 3 } }
\tl_set:Ne \l_tmpb_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 4 } }
\node[anchor=north ~ east] (D) at (d) { \vincentkrebs_coolsource_format { \l_tmpa_tl } };
\node[anchor=north ~ west] (E) at (e) { \vincentkrebs_coolsource_format { \l_tmpb_tl } };
\draw[->] (a.south) -- ([xshift=-0.5em]d.north);
\draw[->] (a.south) -- ([xshift=0.5em]e.north);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D), (E) }
} {
\coordinate (d) at (0em,-0.9em);
\tl_set:Ne \l_tmpa_tl { \seq_item:Nn \l_vincentkrebs_coolsource_derivs_seq { 3 } }
\node[anchor=north] (D) at (d) { \vincentkrebs_coolsource_format { \l_tmpa_tl } };
\draw[->] (a.south) -- (d.north);
\clist_push:Nn \l_vincentkrebs_coolsource_fitspec_clist { (D) }
}
}
\node[fit={ \clist_use:Nn \l_vincentkrebs_coolsource_fitspec_clist { } }] (frame) {};
\draw[decorate, semithick, decoration={brace, amplitude=2pt, mirror}] ([xshift=0.5em,yshift=-0.3em]frame.north ~ west) -- ([xshift=0.5em,yshift=0.3em]frame.south ~ west);
\draw[decorate, semithick, decoration={brace, amplitude=2pt}] ([xshift=-0.5em,yshift=-0.3em]frame.north ~ east) -- ([xshift=-0.5em,yshift=0.3em]frame.south ~ east);
\end{tikzpicture}
}
\ExplSyntaxOff
\begin{document}
\coolsource{contracter,v;contraction,n}
\coolsource{contracter,v;contraction,n;contracture,n}
\coolsource[contraire,v]{contracter,v;contraction,n;contracture,n}
\coolsource[contraire,v]{contracter,v;contraction,n;contracture,n;contracteur,n}
\coolsource[contraire,v][draw, fill=blue!10, yshift=0.4em]{contracter,v;contraction,n;contracture,n;contracteur,n}
\end{document}