6

Does anybody know how to achieve the effect illustrated in the picture? Using expex to typeset glossed linguistic examples, I'd like to be able to draw a box around an expression in the \gla line and its gloss in the \glb line.

Desired effect: enter image description here

Minimal working example (without the desired box):

\documentclass{article}
\usepackage{expex}
\begin{document}
\ex
\begingl
\gla Si fuera m\'as alto ser\'ia un jugador de baloncesto.//
\glb If be.3.sg.PAST.SUBJ more tall be.3.sg.COND a player of basketball//
\glft `If s/he was taller, s/he would be a basketball player'//
\endgl
\xe
\end{document}
4
  • 1
    could you add a document that makes the layout without the boxes, as a test file? May 20 '17 at 19:32
  • Sure, I've edited the question. May 20 '17 at 20:49
  • I'd also be interested, at least as an exercise, in a solution that involves the other gloss coding syntax of ExPex (maybe John Frampton could, but I definitely have no chance of hacking his TeX code): \ex[glstyle=nlevel] \begingl Si[If] fuera[be.3.PAST.SUBJ] m\'as[more] alto[tall] ser\'ia[be.3.sg.COND] un[a] jugador[player] de[of] baloncesto.[basketball] \glft If s/he was taller, s/he would be a basketball player// \endgl \xe
    – benjamin
    May 23 '17 at 13:19
  • @benjamin The posted solution works for that syntax too. You just make sure that the \tikzmark commands in the gloss parts are inside the [ ... ] not outside of them. The gloss spacing seems a little more cramped with this syntax, so you may want to increase the glspace parameter slightly.
    – Alan Munn
    Jul 7 '17 at 21:15
7

A different version than David's using the fit library of TikZ. You need to specify three points with \tizkmark rather than two because TikZ has no way of knowing which of the groups of words being marked is longer. If the bottom group is longer as in the first example, only two marks would be needed, but this won't work in the second example where the top group is longer, so you need to mark both the beginning and end of the top group and just the end of the bottom group.

A simple version

Using the tikzmark package (see complicated version below) introduces some complexity into this solution that is really not necessary for this purpose (although can be useful in other contexts). Specifically, the solution above requires a unique set of labels for each box you use. This become annoying if you are using it a lot.

By using a simpler version of tikzmark that doesn't use the package, you can avoid this altogether and then have a command that simply is \boxit for the default case, and you can use the same set of labels each time.

In this version, the labels use the following scheme, where <start> is the upper left corner mark. These must be numeric, and the default is to start at 1.

<start> <start+1> <start+2>

Now you can just use \tikzmark{1}, \tikzmark{2} ,\tikzmark{3} for all boxes unless you have more than one box in a single example. In that case, increase the start numbers by 3.

Now to box the nodes, you can use:

\boxit % this assumes nodes start at 1

or to have more than one box in an example, use the starred version and give the starting node number as an argument.

\boxit*{<start>} % gives an explicit start

Here's the complete example showing the two boxes in the same example, and then another box using the same 1, 2, 3 marks in the subsequent example.

This solution works with both the regular gloss syntax of ExPex as well as the nlevel syntax. For nlevel formatted examples you need to make sure that the \tikzmark commands in the glosses are inside the [ ... ] not outside of them. For this syntax I also increased the glspace parameter of the glosses since the spacing seemed tighter with the nlevel syntax.

\documentclass[10pt]{article}
\usepackage{expex}

\usepackage{tikz}
\usetikzlibrary{fit}

\newcommand{\tikzmark}[1]{\tikz[remember picture,overlay] \node (#1) {};}
\makeatletter
\newcommand{\boxit}{\@ifstar\@boxit\@@boxit}
\newcommand{\@@boxit}{\@boxit{1}}
\newcommand\@boxit[1]{%
\tikz[overlay,remember picture]{
\def\pointlist{}
\pgfmathsetmacro{\endpoint}{#1+2}
\foreach \x in {#1,...,\endpoint}
{\xdef\pointlist{\pointlist(\x)}}%
\node[draw,rectangle,yshift=3.5pt,thick,
      fit=\pointlist,
      inner sep=1pt,text depth=\baselineskip] {};
}}
\makeatother

\begin{document}

\ex
\begingl
\gla \tikzmark{1}Si fuera\tikzmark{2} m\'as alto ser\'ia \tikzmark{4}un jugador\tikzmark{5} de baloncesto.//
\glb If be.3.sg.PAST.SUBJ\tikzmark{3} more tall be.3.sg.COND a player\tikzmark{6} of basketball//
\glft `If s/he was taller, s/he would be a basketball player’//
\endgl
\xe
\boxit
\boxit*{4}


\ex
\begingl
\gla Si fuera m\'as alto ser\'ia \tikzmark{1}un jugador\tikzmark{2} de baloncesto.//
\glb If be.3.sg.PAST.SUBJ more tall be.3.sg.COND a player\tikzmark{3} of basketball//
\glft `If s/he was taller, s/he would be a basketball player'
\endgl
\xe
\boxit

% example with the nlevel sytax

\ex[glstyle=nlevel,glspace=.7em plus .4em minus .15em] 
\begingl \tikzmark{1}Si[If] fuera\tikzmark{2}[be.3.PAST.SUBJ\tikzmark{3}] m\'as[more] alto[tall] ser\'ia[be.3.sg.COND] un[a] jugador[player] de[of] baloncesto.[basketball] 
\glft If s/he was taller, s/he would be a basketball player// 
\endgl \xe
\boxit

\end{document}

output of code

Original, more complicated version

Here's the original version of the answer, which requires unique nodes for each mark, and requires you to give the \boxit command an argument with the appropriate label. I don't think this is as simple to use, but I leave it here for posterity.

\documentclass{article}
\usepackage{expex}

\usepackage{tikz}
\usetikzlibrary{tikzmark,fit}
\newcommand\boxit[1]{%
\tikz[overlay,remember picture]{%
\node[draw,rectangle,yshift=3.5pt,thick,
      fit=(pic cs:a#1) (pic cs:b#1) (pic cs:c#1),
      inner sep=3.5pt,text depth=\baselineskip] {};
}}



\begin{document}
\ex
\begingl
\gla \tikzmark{a1}Si fuera\tikzmark{b1} m\'as alto ser\'ia un jugador de baloncesto.//
\glb If be.3.sg.PAST.SUBJ\tikzmark{c1} more tall be.3.sg.COND a player of basketball//
\glft `If s/he was taller, s/he would be a basketball player'//
\endgl
\xe

\boxit{1}

\ex
\begingl
\gla Si fuera m\'as alto ser\'ia \tikzmark{a2}un jugador\tikzmark{b2} de baloncesto.//
\glb If be.3.sg.PAST.SUBJ more tall be.3.sg.COND a player\tikzmark{c2} of basketball//
\glft `If s/he was taller, s/he would be a basketball player'//
\endgl
\xe
\boxit{2}

\end{document}

output of code

3
  • in case readers wonder about the reference to David's solution I deleted mine as this is better:-) May 21 '17 at 16:24
  • This is great. I've accepted the answer. Thanks to David for getting this started. May 21 '17 at 18:11
  • @KaivonFintel I've updated the answer with a simpler syntax for marking the nodes and placing the boxes. This way you don't need to keep track of the box labels at all, just the starting number for each box.
    – Alan Munn
    May 21 '17 at 19:08
1

write with the put command over the text:

\documentclass{article}
\usepackage{expex,pict2e}
\unitlength=1cm
\begin{document}
    \ex
    \begingl
    \gla Si \makebox(0,0){\put(1.45,-0.1){\oval[0.1](3.3,1)}}%
            fuera más alto sería un jugador de baloncesto.//
    \glb If be.3.sg.PAST.SUBJ more tall be.3.sg.COND a player of basketball//
    \glft If s/he was taller, s/he would be a basketball player//
    \endgl
    \xe
\end{document}

enter image description here

  • \makebox(0,0) for a box of width/height 0pt to get an overlay.
  • \put(1.45,-0.1) put the following argument at 1.45,-0.1 units depending to the current point.
  • \oval[0.1](3.3,1) An oval with max corner radius of 0.1 and width/height of 3.3/1
1
  • This works well. I've accepted the tikz-based answer because I already load the whole tikz-shebang anyway. May 21 '17 at 18:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.