2

So, I'm currently trying to modify a function someone else has made, but the function is written TeX, which I don't know the first thing about. I can't contact the original creator of the function to get help, so I'm coming here. In fact, I currently can't engineer a minimal working example, presumably because of my lack of knowledge with TeX. I keep trying to put it together into a single file, but nothing I attempt will actually compile.

The function is paired with an environment defined in a sty file. I'll be posting the contents of the sty file and a separate tex file that uses the package. I will mention that this is not the original sty file. It has been edited (by myself) in the past. The current version works, but lacks some functionality that I want.

So, the function in question is the \vblob function. It draws color-filled blobs somewhere on the trapezoid that the "vowel" environment creates. The color is not original. I added it. What I want to be able to do is to pass an optional argument to \vblob, to specify different colors. From what I understand, the definition of the function is such that it allows arbitrary lists of points as arguments, to grant precise control of the shape of the blob.

My first attempt was to simply add a parameter to the \tv@vowelblob definition, and then recursively pass this argument down to the other functions that are called. The issue is that I don't know how to modify \tv@nextpoint#1 to pass an additional argument to it. In fact, when that function is called, nothing is passed to it and I assume that the argument is automatically pulled from the list of points.

My next thought was to store the argument in something external to the \tv@vowelblob function, which then the \tv@donepoints function would be able to access. However, I am not sure if this is even remotely possible, and, if it were, I suspect it would potentially need additional code to prevent memory leaks, which I also don't know how to do in TeX.

All my thoughts have hit dead ends, so now I come to you folk in the hope that adding my desired functionality is possible. (While we're at it, I'm also looking to modify the \varrow function such that it accepts coordinates in terms of the vowel environment instead of just coordinates in terms of the tikz environment. Maybe this can be added as an afterthought.)

Below are the contents of the sty file.

\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}
}

Below are the contents of the tex file.

\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}
4
  • What about (re)writing the function from scratch in Lua instead. May be easier for you than figuring these out.
    – user202729
    Jan 21, 2022 at 10:16
  • Just as a note, it's possible to have a MWE spanning over multiple files. Just try to make it reasonably small.
    – user202729
    Jan 21, 2022 at 11:32
  • Well, I know a bit of Lua, but not how to use it in LaTeX. I generally use XeLaTeX, though, and not LuaLaTeX. Also, yeah, I'm learning that there is an art to making MWEs, like anything.
    – Rithaniel
    Jan 21, 2022 at 13:23
  • Not that Lua can't be used in XeLaTeX, but you need shell-escape etc. to do the former.
    – user202729
    Jan 21, 2022 at 14:14

1 Answer 1

2

A simple solution would be to use \tikzset to define a style:

\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}

and apply vblob Style in the drawing:

\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
}

enter image description here

Note:

  • For future reference, the code below also shows you how you can package a complete MWE .

Code:

\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}
1
  • Oh, thank you! This works and is honestly much more flexible than what I had in mind. Also, the trick with rolling the two files into one MWE is great. I will have to remember that.
    – Rithaniel
    Jan 21, 2022 at 13:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .