% \iffalse %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{dvgloss}[2012/08/06 v0.1 Flexible glossing commands] %<*driver> \documentclass{article} \usepackage{doc} \usepackage{dvgloss} \usepackage{expex} \usepackage{sverb} \EnableCrossrefs \RecordChanges \aboveglskip=-3pt \begin{document} \DocInput{dvgloss.dtx} \end{document} % % \fi % \title{The \textsf{dvgloss} package} % \author{Dan Bridges Velleman} % \maketitle %\tableofcontents %\section{What it does} %This is a package that lets you set interlinear linguistic examples like %the one below: %\begin{demo}[w]{A linguistic example} %\gl{{K'a tee} ka-r-il ri achih ri jun keej xaa maa pwaq % k-u-kisii-j.} % {{suddenly} {\sc inc-a}3s-see the man the one horse % just {\sc exclam} money {\sc inc-a}3s-shit-{\sc ss}} %\ft{Suddenly, the man saw a horse that was just shitting money.} %\lb{Mondloch 1981} %\end{demo} % %Some characters have been set up as shortcuts for %various useful things within an example --- inserting a line break %(using {\tt /}) %putting subscripts on brackets (\emph{e.g.}~\verb+]Contr+ in the example %below), etcetera. % %\begin{demo}[w]{Using a shortcut} %\gl{No [ morir\'e ]Contr / {sino que} [ vivir\'e ]Contr} % {not will.die but will.live} %\ft{You will not die, but will live.} %\end{demo} %What makes this package different from others that exist so far (and in % particular from %{\sf expex}, which offers a similar set of shortcuts) is that these %shortcuts are \emph{customizable}. You can declare new characters as shortcuts, %change the meanings of existing shortcuts, and so on. For instance, if the %slash hadn't already been set up as a newline character, you could make it %one like this: %\begin{verbatim} %\makeglshortcut / {\par} %\end{verbatim} %If you wanted to repurpose it --- let's say you've been using it to mark %prosodic boundaries, but you decide you want those to show up as the IPA %double-pipe character as in the example below --- %you could do that too. % %\begin{demo}[w]{Redefining a shortcut} %\begingroup %\makeglshortcut / {\unskip\quad$\|$\quad} %\gl{No [ morir\'e ]Contr / {sino que} [ vivir\'e ]Contr} % {not will.die rather will.live} %\ft{You will not die, but will live.} %\endgroup %\end{demo} % %Finally, for one-off situations where you don't want to define a new shortcut, %there is an ``escape character'' which lets you issue any command you want from %within an argument of \verb+\gl+. Suppose you redefine {\tt /} to generate the %double-pipe character, but then you run into a tricky formatting situation %where you really need to force a line break. Just say \verb+!{\par}+ --- or, %for that matter, \verb+!{\par\vspace{\jot}\mbox{}\qquad}+, if that's what %floats your boat --- and you'll get what you want. (The default escape character %is {\tt !}, but if you're a Khoisanist or otherwise need to start words with %a bang, you can redefine it to something else.) %\section{What it doesn't do} %\begin{itemize} %\item It doesn't handle example numbering. There are plenty of other packages % that do, so I doubt I'll bother to reinvent that particular wheel any time % soon. %\item It doesn't do three-line glosses, or anything bigger. This is a dumb % limit and could easily be removed --- but I probably won't get around to it % unless someone else asks, because two-line glosses are all I ever use. %\item Shortcuts or escaped commands can take arguments, and can (if you arrange % it right) take scope over more than one word of interlinear gloss; but there % are limits --- in particular, scope-taking commands can't be \emph{nested}. % This is a limit that could in principle be removed, but it would take some work. %\end{itemize} % So for instance, as an example of that last limit: you can define a pair of shortcut characters that will % cause a box to be drawn around any number of intervening words, as in the example below; but % you will not be able to use those shortcuts to produce nested boxes. % %\begin{demo}[w]{A scope-taking shortcut} %\gl{Los * frase-s nominal-es * est\'a-n en * caja-s. * No s\'e porqu\'e.} % {the phrase-pl nominal-pl are-3pl in box-pl not know.1sg why} %\ft{The noun phrases are in boxes. I don't know why.} %\end{demo} % %\section{How to use it} %\subsection{The basics} % \begin{macro}{\gl} %\begin{macro}{\ft} % The \verb+\gl+ macro takes two arguments. It treats each argument as a list of % (space-delimited) items, and aligns the items from the first argument atop the % items from the second. % % The \verb+\ft+ macro is for putting a \emph{free translation} after an % interlinear gloss. It takes a single argument. % %\begin{demo}[w]{A generic example} %\gl{dolorem ipsum quia dolor sit amet} % {pain.acc.sg itself.acc.sg because % because pain.nom.sg be.3sg.subj love.3sg} %\ft{``loves pain itself because it is pain''} %\end{demo} % %\end{macro} % \end{macro} %\begin{macro}{\lb} % The \verb+\lb+ macro gives you a ``label'' --- a bit of text set on the same line % as what came before (if there's room) but pushed right to the end of the line. % You can use this, among other things, for citations. % %\begin{demo}[w]{An example with a label} %\gl{dolorem ipsum quia dolor sit amet} % {pain.acc.sg itself.acc.sg because pain.nom.sg be.3sg.subj love.3sg} %\ft{loves pain itself just for being pain} %\lb{Cicero} %\end{demo} % If there isn't room for the label on one line, a line break will be added. % %\begin{demo}[w]{An example with a long label} %\gl{dolorem ipsum quia dolor sit amet} % {pain.acc.sg itself.acc.sg because pain.nom.sg be.3sg.subj love.3sg} %\ft{loves pain itself just for being pain} %\lb{Cicero, \emph{de Finibus Bonorum et Malorum}} %\end{demo} %\end{macro} % %\subsection{Grouping} %You can use curly braces to group multiple words together; \verb+\gl+ will % then treat them like a single word. % %\begin{demo}{Grouping two words together} %\gl{Edormi crapulam} % {{sleep off} hangover} %\ft{``Sleep off that hangover.''} %\lb{Cicero, Philippic 2 30} %\end{demo} % %The \verb+\gl+ macro ignores spaces in all the same places that \LaTeX\ normally %ignores spaces --- for instance after a control sequence. To make sure that %a space after a control sequence will be recognized, wrap the control sequence %in curly braces, as in the first two words below. % %\begin{demo}{Spaces ignored after control sequences} %\gl{{\aa} {n\aa} Bl\aa-\aa s-en} % {to reach blue-ridge-def} %\ft{to reach Bl\aa\aa sen} %\end{demo} %\subsection{Prebuilt shortcuts} % For a shortcut character to do anything at all, (i) it must be in the first % argument of \verb+\gl+, and (ii) it must be at the beginning of a word. % % If the shortcut character has non-space characters after it, they will be % treated as an argument. The right-bracket shortcut which we saw back in % \S1 is an example of this: if you type \verb+]Contr+, then \verb+Contr+ is % treated as the shortcut's argument --- which in this case means it's typeset % as a subscript. % % \begin{itemize} % \item[\tt /] Insert a line break. The argument, if present, specifies an % amount of extra vertical space to be added afterward. % \item[{$\tt [$}] Insert a left bracket in the top line, with nothing aligned % with it below. The argument, if present, specifies a label to be set as a % subscript to the left bracket. % \item[{$\tt ]$}] As above, but insert a right bracket. % \item[\tt * *] Everything between the two asterisks is set with a % \verb+\framebox+ around it. If an argument is present after the second % asterisk, it's set as a label on top of the \verb+\framebox+. % \end{itemize} % %\subsection{New shortcuts} %\begin{macro}{\makeglshortcut} %To define a new shortcut along the lines of \verb+/+ and \verb+[+, use the command %\verb+\makeglshortcut+. It takes two arguments --- the first is the character you %want to turn into a shortcut, the second is the macro code that will be executed when %that character is encountered. If the shortcut character is encountered with other, %non-space characters after it, those will be passed to the macro code you supply as %an argument --- so you can capture those characters as \verb+#1+. % (If you try to do something with \verb+#1+ but the user hasn't supplied an argument, % then \verb+#1+will be empty. You might want to test for this --- as in the example % below --- if this is an issue. If the user does supply an argument, but you don't % do anything with it, then that's not a problem --- the argument will be silently % discarded.) %\end{macro} %We've already seen an example of a shortcut definition that doesn't use an argument. %\begin{verbatim} %\makeglshortcut / {\par} %\end{verbatim} %Here's an example of one which does. %\begin{verbatim} %\makeglshortcut / {\par\ifx#1\empty\else\vskip#1\fi} %\end{verbatim} % %Shortcuts have to be single characters. \verb+\makeglshortcut{somethingverylong}{code}+ will %not do what you want. %\begin{macro}{\makeglsurround} %To define a new shortcut along the lines of \verb+*+ --- a set of delimiters which can surround % multiple %words of glossed text and ``take scope'' over them --- use the command \verb+\makeglsurround+. %It takes three arguments: the left-hand delimiter, the right-hand delimiter, and the code %that will be executed when they're encountered. The two delimiters can be the same --- as %with \verb+*+, above --- but they don't have to be. % %If there are extra non-space characters after the left-hand delimiter, they are passed in as %argument \verb+#1+. The characters between the two delimiters are passed in as argument %\verb+#2+. Extra non-space characters after the right-hand delimiter are passed in as argument %\verb+#3+. You'll almost certainly want to do something with \verb+#2+, but ignoring \verb+#1+ %and \verb+#3+ is completely fine. %\end{macro} %As an example, here's how the asterisk shortcut was defined: %\begin{verbatim} %\makeglsurround ** {% % \rlap{\raisebox{1.5em}{\footnotesize\sf#3}}% % \fbox{\noglstrut#2\unskip}\glspace} %\end{verbatim} % %\subsection{The escape character} %Spacing and line-beaking commands, among others, need to be ``escaped'' if you want to use %them inside of \verb+\gl+. (See \S4 for an explanation of why this is. For now, just %trust me.) The escape character by default is \verb+!+, and it's best to enclose whatever %comes after it in curly braces. So you could use \verb+!{\par)}+ to insert a new line if %you'd already redefined \verb+/+, or \verb+!{\qquad}+ to insert some extra horizontal space. % %\macro{\glescape} %If you want to change the escape character, redefine \verb+\glescape+. Like shortcuts, %the escape has to be a single character. \verb+\def\glescape{averylongescape}+ will not %do what you want. %\section{What's going on} % % Internally, there is a command called \verb+\glossword+ which is responsible for stacking % two words on top of one another. The arguments you give to the \verb+\gl+ command are % converted into a series of \verb+\glossword+s, like so: % \begin{verbatim} % \gl{a b c d}{1 2 3 4} % ===> % \glossword{a}{1} % \glossword{b}{2} % \glossword{c}{3} % \glossword{d}{4} % \end{verbatim} % % Normally, command sequences that appear inside of \verb+\gl+ will be wrapped up inside a % \verb+\glossword+. Sometimes this is what you want. % \begin{verbatim} % \gl{a b \bf c d}{1 2 3 4} % ===> % \glossword{a}{1} % \glossword{b}{2} % \glossword{\bf c}{3} % \glossword{d}{4} % \end{verbatim} % But sometimes it is really not at all what you want. % \begin{verbatim} % \gl{a b \par c d}{1 2 3 4} % ===> % \glossword{a}{1} % \glossword{b}{2} % \glossword{\par c}{3} % \glossword{d}{4} % \end{verbatim} % % So we need a way to get a command like \verb+\par+ to show up \emph{outside} of % a \verb+\glossword+. That's what the escape character is for. % \begin{verbatim} % \gl{a b !{\par} c d}{1 2 3 4} % ===> % \glossword{a}{1} % \glossword{b}{2} % \par % \glossword{c}{3} % \glossword{d}{4} % \end{verbatim} % % The expansion of a shortcut character also ends up outside of any \verb+\glossword+s. % \begin{verbatim} % \gl{a b / c d}{1 2 3 4} % ===> % \glossword{a}{1} % \glossword{b}{2} % \par % \glossword{c}{3} % \glossword{d}{4} % \end{verbatim} % % \StopEventually{} %\section{Code} % To begin with we set up temporary token list registers, and some spacing and formatting parameters. % \begin{macrocode} \newtoks\ta\newtoks\tb \newdimen\glhangindent\glhangindent=2em \newdimen\betweenglskip\betweenglskip=1\jot \newdimen\withinglskip\withinglskip=0pt \newdimen\aboveglftskip\aboveglftskip=2\jot \newdimen\aboveglskip\aboveglftskip=2\jot \newdimen\glstrutheight\newdimen\glstrutdepth \def\glspace{\penalty0\hspace{1ex plus 2em minus 2pt}} \def\everygla{\itshape} \def\everyglb{} % \end{macrocode} % We also specify an escape character. % \begin{macrocode} \def\glescape{!} % \end{macrocode} % %\begin{macro}{\addtokens} %\begin{macro}{\popoff} % Here's some helper macros for wrangling lists in which the items are separated % by spaces. % \begin{macrocode} \long\def\addtokens#1\to#2{\ta={#1}\tb=\expandafter{#2}\edef#2{\the\tb\the\ta}} \def\pop#1\to#2{\expandafter\popoff#1\to#2\remainderin#1} \long\def\popoff#1 #2\to#3\remainderin#4{#3={#1}\def#4{#2}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\split} %\begin{macro}{\istchar} %\begin{macro}{\restchars} % Here's one % for splitting off a single token from a longer string. If you % execute \verb+\split{Lorem}+, then the \verb+L+ is stored in % \verb+\istchar+ and the rest of the word --- \verb+orem+ --- is stored in % \verb+\restchars+. % \begin{macrocode} \long\def\split#1{\expandafter\ssplit#1\xyzzy} \long\def\ssplit#1#2\xyzzy{\gdef\istchar{#1}\gdef\restchars{#2}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\ifnotin} % There's one truly devious helper macro here: a really tricky way of testing % whether one serious of tokens occurs % within another. This is cribbed from the doc package, which credits Michael % Spivak with the original invention. % \begin{macrocode} \def\ifnotin#1#2{% \def\@ifnotin##1#1##2##3\zyzzy{\ifx\ifnotfound##2}% \expandafter\@ifnotin#2#1\notfound\zyzzy} % \end{macrocode} %\end{macro} %\begin{macro}{\ifspecial} %\begin{macro}{\checkspecial} %\begin{macro}{\makespecial} % We need this bit of deviousness because we're going to keep a list of characters that have been % declared as special shortcuts. \verb+\makespecial+ adds something to the list; % \verb+\checkspecial+ checks whether it's on the list (using \verb+\ifnotin+) and stores the answer in % \verb+\ifspecial+. % \begin{macrocode} \newif\ifspecial \def\dvglspecials{} \def\checkspecial#1{% \ifnotin#1{\dvglspecials}\specialfalse\else\specialtrue\fi} \def\makespecial#1{% \xdef\dvglspecials{\dvglspecials#1}} % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\subsection{Glossing} %\begin{macro}{\glossword} % First we define the basic formatting macro: it stacks a word and its gloss % atop one another. % \begin{macrocode} \def\glossword#1#2{% \mbox{\vtop{\halign{##\hfil\cr\everygla#1\strut\cr\everyglb#2\strut\cr}}}% \glstrut\glspace} % \end{macrocode} %\end{macro} %\begin{macro}{\zipper} % Now we have the rearranging macro. % To use a functional programming analogy: % \verb+\zipper\a\and\b\to\c+ basically means \verb+c = zipWith(glossword) a b+. % In other words, if \verb+\a+ is a list macro containing the tokens \verb+1 2 3+ % and \verb+\b+ is a list macro containing the tokens \verb+4 5 6+, and we execute % \verb+\zipper\a\and\b\to\c+, then \verb+\c+ will end up containing % \verb+\glossword{1}{4}\glossword{2}{5}\glossword{3}{6}+. % % In fact, though, \verb+\zipper+ is not quite \verb+zipWith+. It also catches % ``special'' or escaped tokens in its first argument and adds them to the output % \emph{without} pairing them off or wrapping them in a \verb+\glossword+. % \begin{macrocode} \def\zipper#1\and#2\to#3{% % \end{macrocode} % If there's any items left on list \#1, pull one off (storing it in % \verb+\ta+) and split off its first token so we can peek and see if it's an % escape character or a special character. % \begin{macrocode} \ifx\empty#1\else% \pop#1\to\ta% \def\istchar{}\def\restchar{}% \edef\temp{\the\ta}\split\temp% % \end{macrocode} % If that first token is an escape character, we pass the rest of the item through % to the output. % \begin{macrocode} \ifx\istchar\glescape\expandafter\addtokens\restchars\to#3% % \end{macrocode} % If that first token is a special character, we convert it into a control sequence % and make the remaining characters in the item into its argument. % \begin{macrocode} \else% \expandafter\checkspecial\istchar\ifspecial% \expandafter\addtokens\csname gl\istchar\endcsname\to#3% \expandafter\addtokens\expandafter<\restchars>\to#3% % \end{macrocode} % If neither of those two conditions hold, then we're just building a normal % glossword. That means we should also pull an item off of list \#2, storing it % in \verb+\tb+. % \begin{macrocode} \else \ifx\empty#2\else% \pop#2\to\tb% % \end{macrocode} % Finally, we wrap the contents of \verb+\ta+ and \verb+\tb+ in a % \verb+\glossword+ command and pass it to the output. % Here we need to be careful: we want to expand \verb+\the\ta+ and \verb+\the\tb+ % \emph{once} --- to \emph{get} their contents. But having gotten their contents, % we don't want to do any further expansion.\footnote{Why not? Because trying to % expand an unexpandable macro here would be messy and unpleasant.} % \begin{macrocode} \edef\temp{\noexpand\glossword{\the\ta}{\the\tb}}% \expandafter\addtokens\temp\to#3% \fi% \fi% \fi% \zipper#1\and#2\to#3% \fi% } % \end{macrocode} %\end{macro} %\begin{macro}{\gl} % Based on \verb+\zipper+, we can define a user-friendly gloss command: take % two arguments, \verb+\zipper+ them together, call \verb+\fixglstrut+ (see below) % to make sure everything is spaced real nice, and % send everything off to be typeset. % \begin{macrocode} \long\def\gl#1#2{% \begingroup% \def\x{#1 }\def\y{#2 }\def\z{}% \zipper\x\and\y\to\z% \fixglstrut% \ifvmode\vskip\aboveglskip\fi\z% \endgroup% } % \end{macrocode} %\end{macro} %\begin{macro}{\fixglstrut} %\begin{macro}{\noglstrut} % The \verb+\fixglstrut+ command is issued in \verb+\gl+ right before we begin % typesetting. It sets \verb+\glstrut+ to be as tall as a normal glossbox at % the current font size \emph{plus} the current value of \verb+\betweenglskip+. % Sometimes we'll also want to be able to suppress \verb+\glstrut+ temporarily % as a way of preventing the \verb+\betweenglskip+ space from being inserted. % \verb+\noglstrut+ does that. (It's temporary because \verb+\fixglstrut+ will % be called again at the beginning of the next gloss and things will go back to % normal. If you issue \verb+\noglstrut+ within a group, it's of course even % temporary-er than that.) % \begin{macrocode} \def\fixglstrut{% \def\glstrut{}% \setbox0=\hbox{\glossword{}{}}% \glstrutheight=\ht0% \glstrutdepth=\dp0% \advance\glstrutdepth by \betweenglskip% \global\edef\glstrut{\vrule height\glstrutheight width0pt depth\glstrutdepth}} \def\noglstrut{\def\glstrut{}} % \end{macrocode} %\end{macro} %\end{macro} %\begin{macro}{\ft} % Usually after an interlinear gloss there's a line of ``free translation.'' % This is a user-facing command for setting that free translation line --- or, % really, for setting \emph{anything} that needs to come on a new line right after % an interlinear gloss. The only time this matters is when \verb+betweenglskip+ % and \verb+belowglskip+ are different sizes. % \begin{macrocode} \def\ft#1{\nobreak\par\nobreak\vskip-\betweenglskip\vskip\aboveglftskip #1} % \end{macrocode} %\end{macro} %\begin{macro}{\lb} % Here's a labeling macro, swiped from the \TeX book. % \begin{macrocode} \def\lb#1{{\unskip\nobreak\hfil\penalty0\hskip2em\mbox{}\nobreak\hfill\mbox{#1}}} % \end{macrocode} %\end{macro} %\subsection{Declaring shortcuts} % We have a macro \verb+\makespecial+ which will tell the parser ``treat % this character as special.'' % % But that alone won't get us anywhere interesting. We also need to \emph{define} % the macro that will be executed when the special character in question is % encountered. And it would be nice if we could wrap both steps --- calling % \verb+\makespecial+ and defining the macro --- in a user-friendly package. % That's what this last section does. % % Suppose we want to declare {\tt /} as a shortcut character which inserts % a line break. Step one is simple: % \begin{center} % \verb+\makespecial{/}+ % \end{center} % Now let's consider how the parser will respond after we've done this. % Suppose we then execute this command: % \begin{center} % \verb+\gl{a b * c}{1 2 3}+ % \end{center} % The output which is sent to be typeset will look like this % \begin{center} % \verb+\glossword{a}{1}+\\ % \verb+\glossword{b}{2}+\\ % \verb+ \gl/<>+\\ % \verb+\glossword{c}{3}+\\ % \end{center} % where \verb+\gl/+ is a control sequence --- one which could not normally be % input directly. And if we execute the command % \begin{center} % \verb+\gl{a b /argument c}{1 2 3}+ % \end{center} % The output which is sent to be typeset will look like this: % \begin{center} % \verb+\glossword{a}{1}+\\ % \verb+\glossword{b}{2}+\\ % \verb+ \gl/+\\ % \verb+\glossword{c}{3}+\\ % \end{center} % % Step two, then, is to define a macro that will do something useful in those % contexts. If the slash were a normal character, this would be easy: % \begin{center} % \verb+\def\gl/<#1>{\par\ifx#1\empty\else\vskip{#1}\fi}+ % \end{center} % But since the slash isn't a normal character, we need to do it this way instead: % \begin{center} % \verb+\expandafter\def\csname gl/\endcsname<#1>{\par\ifx#1\empty\else\vskip{#1}\fi}+ % \end{center} % \begin{macro}{\makeglshortcut} % Well, that's just what \verb+\makeglshortcut+ does: carries out Step One and % Step Two for an arbitrary character and arbitrary macro code. % \begin{macrocode} \long\def\makeglshortcut#1#2{% \makespecial{#1}% \expandafter\gdef\csname gl#1\endcsname<##1>{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{/} % Here are a few examples of \verb+\makeglshortcut+ in action. To make the slash % into a newline character, like we did in our example, the user-friendly way to % do it is this: % \begin{macrocode} \makeglshortcut/{\par\ifx#1\empty\else\vskip{#1}\fi} % \end{macrocode} % \end{macro} % \begin{macro}{[ ]} % We declare that square brackets in the input will give square brackets in the output --- but with % nice spacing, and an optional argument set as a subscript. % \begin{macrocode} \makeglshortcut[{[$_\textrm{\footnotesize#1}$\thinspace} \makeglshortcut]{\unskip\thinspace]$_\textrm{\footnotesize#1}$\glspace} % \end{macrocode} % \end{macro} % % This is where it gets a little hairy. We also want to be able to set up % shortcut characters that turn into the left- and right-hand sides of a % \emph{delimited macro}. For instance, suppose we want to be able to use % asterisks as shortcuts, such that everything in between % two asterisks is put into a \verb+\framebox+. Well, step one is as easy % as it was before. %\begin{center} %\verb+\makespecial{*}+ %\end{center} % And if the asterisk were a normal character, step two would also be % reasonably easy. %\begin{center} %\verb+\def\gl*<#1>#2\gl*<#3>{\framebox{#2}}+ %\end{center} % \begin{macro}{makeglsurround} % But as before, because the asterisk is not a normal % character, we need to invoke \verb+\csname+. And this time, it's ugly: % \begin{macrocode} \long\def\makeglsurround#1#2#3{% \xdef\dvglspecials{\dvglspecials#1#2}% \ta=\expandafter{\csname gl#1\endcsname}% \tb=\expandafter{\csname gl#2\endcsname}% \expandafter\expandafter\expandafter\gdef% \expandafter\expandafter\the\ta% \expandafter<\expandafter##\expandafter1\expandafter>% \expandafter##\expandafter2\the\tb<##3>{#3}} % \end{macrocode} % \end{macro} %\begin{macro}{* *} % Luckily, the user is protected from that ugliness. Here's a slightly more complicated % version of that \verb+\framebox+-making macro, with elegant spacing and an optional % argument set as a label on top of the frame. Note the use of \verb+\noglstrut+ % here to prevent extra space from ending up \emph{inside} the frame. % \begin{macrocode} \makeglsurround ** {% \rlap{\raisebox{1.5em}{\footnotesize\sf#3}}% \fbox{\noglstrut#2\unskip}\glspace} % \end{macrocode} % \end{macro} % \Finale