所以,我目前正在尝试修改别人编写的一个函数,但该函数是用 TeX 编写的,我对此一无所知。我无法联系该函数的原始创建者寻求帮助,所以我来这里了。事实上,我目前无法设计一个最小的工作示例,大概是因为我对 TeX 缺乏了解。我一直试图将它放在一个文件中,但我所做的任何尝试都无法真正编译。
该函数与 sty 文件中定义的环境配对。我将发布 sty 文件的内容和使用该包的单独 tex 文件。我会提到这不是原始的 sty 文件。它过去曾被(我自己)编辑过。当前版本可以运行,但缺少我想要的一些功能。
因此,所讨论的函数是\vblob
函数。它在“元音”环境创建的梯形上的某个位置绘制颜色填充的斑点。颜色不是原始的。我添加了它。我想要做的是将一个可选参数传递给\vblob
,以指定不同的颜色。据我所知,函数的定义是这样的,它允许任意点列表作为参数,以精确控制斑点的形状。
我的第一个尝试是简单地向定义添加一个参数\tv@vowelblob
,然后递归地将此参数传递给调用的其他函数。问题是我不知道如何修改\tv@nextpoint#1
以向其传递附加参数。事实上,当调用该函数时,不会向其传递任何内容,我假设参数会自动从点列表中提取。
我的下一个想法是将参数存储在\tv@vowelblob
函数外部的某个地方,这样\tv@donepoints
函数就可以访问它了。但是,我不确定这是否可行,如果可行,我怀疑可能需要额外的代码来防止内存泄漏,我也不知道如何在 TeX 中做到这一点。
我所有的想法都陷入了死胡同,所以现在我来找你们,希望能够添加我想要的功能。(在此过程中,我还希望修改该\varrow
函数,使其接受元音环境的坐标,而不仅仅是 tikz 环境的坐标。也许这可以作为事后想法添加。)
以下是 sty 文件的内容。
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{tikzvowel}[2014/08/21 Package to create vowel charts using tikz]
\RequirePackage{tikz}
\RequirePackage{pagecolor}
\RequirePackage{xcolor}
\def\tv@V(#1,#2){barycentric cs:hf={(3-#1)*(2-#2)},hb={(3-#1)*#2},lf={#1*(2-#2)},lb={#1*#2}}
\newtoks\tv@points
\def\tv@vowelblob{%
\tv@points={}%
\tv@next
}
\def\tv@next{%
\@ifnextchar\bgroup{\tv@nextpoint}{\tv@donepoints}%
}
\def\tv@nextpoint#1{%
\tv@points=\expandafter{\the\tv@points(\tv@V(#1)) }%
\tv@next
}
\def\tv@donepoints{%
\edef\next{%
\noexpand\draw [dashed,fill={rgb,255:red,200;green,120;blue,120},fill opacity=0.5] plot [smooth cycle] coordinates { \the\tv@points} ;%
}%
\next
}
\newcommand{\tv@vpoint}[4][] {
\node[dot, #1, label={center: {#4}}] at (\tv@V({#2},{#3})) (\detokenize{#4}) {};
}
\newcommand{\tv@vowelarrow}[3][] {
\draw[-latex, shorten >= 2pt, line width=.75pt,bend right=45, #1] (#2) -- (#3) node[midway,sloped, above] {};
}
\newenvironment{vowel}[1][]
{\let\vpoint\tv@vpoint\let\vblob\tv@vowelblob\let\varrow\tv@vowelarrow
\begin{tikzpicture}[#1,scale=1.6,baseline={(0,0)}]
\tikzset{
dot/.style={circle,fill=\thepagecolor,minimum size=2.5ex,inner sep=0pt,outer sep=0pt},
}
\coordinate (hf) at (0,3); % the high front vertex
\coordinate (hb) at (4,3); % the high back vertex
\coordinate (lb) at (4,0); % the low back vertex
\coordinate (lf) at (2,0); % the low front vertex
% Draw the horizontal lines first.
\draw (\tv@V(0,0)) -- (\tv@V(0,2));
\draw (\tv@V(1,0)) -- (\tv@V(1,2));
\draw (\tv@V(2,0)) -- (\tv@V(2,2));
\draw (\tv@V(3,0)) -- (\tv@V(3,2));
% Draw the vertical lines.
\draw (\tv@V(0,0)) -- (\tv@V(3,0));
\draw (\tv@V(0,1)) -- (\tv@V(3,1));
\draw (\tv@V(0,2)) -- (\tv@V(3,2));
}
{
\end{tikzpicture}
}
以下是 tex 文件的内容。
\documentclass{article}
\usepackage[a4paper,left=25mm,right=25mm,top=25mm,bottom=25mm]{geometry}
\usepackage{tikzvowel}
\begin{document}
\begin{center}
\begin{vowel}
\vblob{2.2,0.7}{2.8,1}{3.1,0.8}{3.1,-0.2}{2.1,0}
\vblob{2,2.2}{2.8,2.1}{2.9,1.4}{2.2,0.8}{1.7,1.5}
\end{vowel}
\end{center}
\end{document}
答案1
一个简单的解决方案是使用\tikzset
定义一种风格:
\tikzset{vblob Style/.style={draw=red, fill=blue,ultra thick, solid}}%
\vblob{2.2,0.7}{2.8,1}{3.1,0.8}{3.1,-0.2}{2.1,0}
\tikzset{vblob Style/.style={draw=red, fill=red!50,ultra thick}}%
\vblob{2,2.2}{2.8,2.1}{2.9,1.4}{2.2,0.8}{1.7,1.5}
vblob Style
并在图纸上应用:
\tikzset{vblob Style/.style={}}% <-- default setting is empty
\def\tv@donepoints{%
\edef\next{%
\noexpand\draw [dashed,fill={rgb,255:red,200;green,120;blue,120},fill opacity=0.5, vblob Style] plot [smooth cycle] coordinates { \the\tv@points} ;%
}%
\next
}
笔记:
- 为了方便将来参考,下面的代码还向您展示了如何打包一个完整的平均能量损失。
代码:
\begin{filecontents*}{tikzvowel.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{tikzvowel}[2014/08/21 Package to create vowel charts using tikz]
\RequirePackage{tikz}
\RequirePackage{pagecolor}
\RequirePackage{xcolor}
\def\tv@V(#1,#2){barycentric cs:hf={(3-#1)*(2-#2)},hb={(3-#1)*#2},lf={#1*(2-#2)},lb={#1*#2}}
\newtoks\tv@points
\def\tv@vowelblob{%
\tv@points={}%
\tv@next
}
\def\tv@next{%
\@ifnextchar\bgroup{\tv@nextpoint}{\tv@donepoints}%
}
\def\tv@nextpoint#1{%
\tv@points=\expandafter{\the\tv@points(\tv@V(#1)) }%
\tv@next
}
\tikzset{vblob Style/.style={}}% <-- default setting is empty
\def\tv@donepoints{%
\edef\next{%
\noexpand\draw [dashed,fill={rgb,255:red,200;green,120;blue,120},fill opacity=0.5, vblob Style] plot [smooth cycle] coordinates { \the\tv@points} ;%
}%
\next
}
\newcommand{\tv@vpoint}[4][] {
\node[dot, #1, label={center: {#4}}] at (\tv@V({#2},{#3})) (\detokenize{#4}) {};
}
\newcommand{\tv@vowelarrow}[3][] {
\draw[-latex, shorten >= 2pt, line width=.75pt,bend right=45, #1] (#2) -- (#3) node[midway,sloped, above] {};
}
\newenvironment{vowel}[1][]
{\let\vpoint\tv@vpoint\let\vblob\tv@vowelblob\let\varrow\tv@vowelarrow
\begin{tikzpicture}[#1,scale=1.6,baseline={(0,0)}]
\tikzset{
dot/.style={circle,fill=\thepagecolor,minimum size=2.5ex,inner sep=0pt,outer sep=0pt},
}
\coordinate (hf) at (0,3); % the high front vertex
\coordinate (hb) at (4,3); % the high back vertex
\coordinate (lb) at (4,0); % the low back vertex
\coordinate (lf) at (2,0); % the low front vertex
% Draw the horizontal lines first.
\draw (\tv@V(0,0)) -- (\tv@V(0,2));
\draw (\tv@V(1,0)) -- (\tv@V(1,2));
\draw (\tv@V(2,0)) -- (\tv@V(2,2));
\draw (\tv@V(3,0)) -- (\tv@V(3,2));
% Draw the vertical lines.
\draw (\tv@V(0,0)) -- (\tv@V(3,0));
\draw (\tv@V(0,1)) -- (\tv@V(3,1));
\draw (\tv@V(0,2)) -- (\tv@V(3,2));
}
{
\end{tikzpicture}
}
\end{filecontents*}
\documentclass{article}
\usepackage[a4paper,left=25mm,right=25mm,top=25mm,bottom=25mm]{geometry}
\usepackage{tikzvowel}
\pagecolor{white}
\begin{document}
\begin{vowel}
\tikzset{vblob Style/.style={draw=red, fill=blue,ultra thick, solid}}%
\vblob{2.2,0.7}{2.8,1}{3.1,0.8}{3.1,-0.2}{2.1,0}
\tikzset{vblob Style/.style={draw=red, fill=red!50,ultra thick}}%
\vblob{2,2.2}{2.8,2.1}{2.9,1.4}{2.2,0.8}{1.7,1.5}
\end{vowel}