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}

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}

\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
\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 theglspace
parameter slightly.