Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I want to highlight some letters which represent an amino acid sequence of a protein using different colors. The below code works fine, but the highlighted box is not fitting exactly the letters, as you can see in the MWE output it is slightly shifted toward the bottom of letters and not centered, so how to justify this to make it in the center of letters?

MWE Code

\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage{fontspec}

\setmonofont[Scale=MatchLowercase]{Inconsolata}
\usepackage{xcolor,graphicx}
\definecolor{set1}{RGB}{200,200,200}
\definecolor{set2}{RGB}{102,255,102}
\usepackage{soul} % for highlighting  
\newcommand{\hlc}[2][yellow]{{\sethlcolor{#1}\hl{#2}}}
\newfontfamily\myfont[Scale=MatchUppercase]{Inconsolata} % monospace font 
\newenvironment{protseq}{\myfont}{\par} 

\begin{document}
\begin{protseq}
\begin{tabular}{lr}
\hlc[set2]{MLGSRAVMLL LLLPWTAQG}R AVPGGSSPAW TQCQQLSQ\hlc[set1]{K}L CTLAWSAHPL & 50\\
VGHMDLREEG DEETTNDVPH IQCGDGCDPQ GLRDNSQFCL QRIHQGLIFY & 100\\
E\hlc[set1]{K}LLGSDIFT GEPSLLPDSP VGQLHASLLG LSQLLQPEGH HWETQQIPSL &    150\\
SPSQPWQRLL LRF\hlc[set1]{K}ILRSLQ AFVAVAARVF AHGAATLSP & 189\\
\end{tabular}
\end{protseq}
\end{document}

MWE Output

enter image description here

Update
Using Stephan Lehmke's answer, problem was solved even when using Inconsolata font plus alignment is preserved, just amazing!

enter image description here

share|improve this question
    
For letters with descenders (like Q) the box fits. Making it "jump" depending on letter form would not look that good either. –  Stephan Lehmke May 8 at 9:40
    
Do you suggest another monospace font without descenders, if any? –  doctorate May 8 at 9:43
    
@doctorate, just for caps? –  Chris H May 8 at 10:02
    
@ChrisH yes just for caps. –  doctorate May 8 at 10:03
    
@doctorate, I had an idea but I was proved wrong - it's a pity tug.dk/FontCatalogue/typewriterfonts.html uses "the quick..." rather than "The Quick" as Q is the only capital with a descender in most fonts. –  Chris H May 8 at 10:12

3 Answers 3

up vote 2 down vote accepted

Strangely, soul doesn't offer much with respect to adjusting the position of the "highlighting blob".

By adding this to your preamble you can adjust the vertical position:

\usepackage{etoolbox}

\newdimen\hladdbelow
\newdimen\hladdabove

\makeatletter
\apptocmd\SOUL@hlpreamble
{%
  \advance\SOUL@uldp\hladdbelow
  \advance\SOUL@ulht\hladdabove
}{}{}
\makeatother

\hladdbelow-2pt
%\hladdabove1pt

Explanation: The three soul commands \ul, \st and \hl basically use the same code, only choosing different values for the dimensions \SOUL@uldp (depth of "highlighting block") and \SOUL@ulht (height of "highlighting block").

\SOUL@hlpreamble (used by \hl) determines these values "intelligently" based on the font size, but offers no interface for adjustment. So I'm introducing new dimensions \hladdabove (length to add on top) and \hladdbelow (length to add to bottom) which are added after the original determination.

As it is, it seems to be enough to take away a bit at the bottom (hence, \hladdbelow-2pt) but you can experiment with the values if you want a different adjustment.


The setting shown here produces (using cmtt font):

enter image description here

share|improve this answer
    
that solved it radically (updated output shows Inconsolata font when used). Can you pls explain the concept/code behind your answer a little bit? –  doctorate May 8 at 10:46
    
@doctorate edited –  Stephan Lehmke May 8 at 11:20

You can use just \colorbox instead of \hl, assuming that the highlihted sequence does not wrap at the end of lines:

\newcommand{\hlc}[2][yellow]{{\fboxsep1pt\colorbox{#1}{#2}}}

enter image description here

I don't have Inconsolata font, hence I changed.

\documentclass{scrartcl}
\usepackage[T1]{fontenc}
%\usepackage{fontspec}
%
%\setmonofont[Scale=MatchLowercase]{Inconsolata}
\usepackage{xcolor,graphicx}
\definecolor{set1}{RGB}{200,200,200}
\definecolor{set2}{RGB}{102,255,102}
\usepackage{soul} % for highlighting
\newcommand{\hlc}[2][yellow]{{\fboxsep1pt\colorbox{#1}{#2}}}
%\newfontfamily\myfont[Scale=MatchUppercase]{Inconsolata} % monospace font
\newenvironment{protseq}{\ttfamily}{\par}

\begin{document}
\begin{protseq}
\begin{tabular}{lr}
\hlc[set2]{MLGSRAVMLL LLLPWTAQG}R AVPGGSSPAW TQCQQLSQ\hlc[set1]{K}L CTLAWSAHPL & 50\\
VGHMDLREEG DEETTNDVPH IQCGDGCDPQ GLRDNSQFCL QRIHQGLIFY & 100\\
E\hlc[set1]{K}LLGSDIFT GEPSLLPDSP VGQLHASLLG \hlc[set2]{LSQLLQPEGH HWETQQIPSL &    150\\
SPSQPWQRLL LRF\hlc[set1]{K}ILRSLQ AFVAVAARVF AHGAATLSP & 189\\
\end{tabular}
\end{protseq}
\end{document}
share|improve this answer
    
one problem, there is a subtle frameshift in your output, which I could replicate using the Inconsolata font, so not related to font type I guess, pls compare alignment of your output with that of the MWE output. –  doctorate May 8 at 10:16
    
@doctorate Frameshift? May be it is \fboxsep? Also a \vphantom{Q} looks better in the definition. I just wanted to convey the idea through the answer and it is not fully perfect, I admit :) –  Harish Kumar May 8 at 10:21

Apparently the macro \hl{} includes a \strut to adjust the box depth, so that it has the same depth when it contains characters with descenders (such as Q) and when it does not. This guarantees the height of the box to be consistent.

However, perhaps for the chosen font, the depth appears to be a bit too large.

You can have a finer control of the result if you use tikz (which admittedly is overkill for this problem). Here is a solution:

\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage{fontspec}
\usepackage{tikz}

\setmonofont[Scale=MatchLowercase]{Inconsolata}
\usepackage{xcolor,graphicx}
\definecolor{set1}{RGB}{200,200,200}
\definecolor{set2}{RGB}{102,255,102}
\newfontfamily\myfont[Scale=MatchUppercase]{Inconsolata} % monospace font
\newenvironment{protseq}{\myfont}{\par}

\newcommand{\hlc}[2][yellow]{\tikz[baseline=(T.base)]
   \node[inner ysep=1pt, inner xsep=0pt, fill=#1](T){\vphantom{Q}#2};}

\begin{document}
\begin{protseq}
\begin{tabular}{lr}
\hlc[set2]{MLGSRAVMLL LLLPWTAQG}R AVPGGSSPAW TQCQQLSQ\hlc[set1]{K}L CTLAWSAHPL & 50\\
VGHMDLREEG DEETTNDVPH IQCGDGCDPQ GLRDNSQFCL QRIHQGLIFY & 100\\
E\hlc[set1]{K}LLGSDIFT GEPSLLPDSP VGQLHASLLG LSQLLQPEGH HWETQQIPSL &    150\\
SPSQPWQRLL LRF\hlc[set1]{K}ILRSLQ AFVAVAARVF AHGAATLSP & 189\\
\end{tabular}
\end{protseq}
\end{document}

Result

I used \vphantom{Q} to achieve the same goal than with \strut, but this solution produces a shorter box depth. You can also remove the \vphantom{Q}, so that the depth of the box fits exactly its contents, but this would produce different box depths for Q and K, which IMHO doesn't look good.

The advantage of using TikZ is that you can easily achieve other effects, such as rounded corners, irregular edges, etc.. For example:

\newcommand{\hlc}[2][yellow]{\tikz[baseline=(T.base)]
   \node[inner ysep=1pt, inner xsep=0pt, fill=#1, rounded corners=2pt](T){\vphantom{Q}#2};}

produces:

Result2

and

\usetikzlibrary{decorations.pathmorphing}

\newcommand{\hlc}[2][yellow]{\tikz[baseline=(T.base)]
\node[inner ysep=1pt, inner xsep=0pt, fill=#1, decorate,
   decoration={random steps, amplitude=1pt, segment length=0.5ex}](T){\vphantom{Q}#2};}

produces:

Result3

Which is ugly, but shows the possibilities :-)

Update

Note that if you go too wild with the shape of the highlighting blob, the alignment with the surrouding text can be affected. This can be fixed by setting the bounding box of the tikz drawing exactly to the shape of the highlighted text, allowing the "blob" to spill out this bounding box.

The following example shows more clearly what I mean:

\newcommand{\hlc}[2][yellow]{\tikz[baseline=(TT.base)]{
   \node[inner sep=0pt](TT){\vphantom{Q}#2};  % rectangle with the text to highlight
   \useasboundingbox (TT.south west) rectangle (TT.north east);
   \node[inner xsep=2pt, inner ysep=1pt, fit=(TT)] (T){}; % rectangle with the highlighting blob
   % now draw arbitrary shapes based on the last rectangle
   \fill[#1, opacity=0.5] (T.north west) to[out=5, in=185] (T.north east)
          -- (T.south east) to[out=190, in=10] (T.south west) -- cycle;
}}

Result:

Result4

share|improve this answer
    
+1, for the efforts and explanation. –  doctorate May 8 at 10:09
    
pls note that out of the 3 outputs you kindly posted, the last one showed unsatisfactory alignment compared with the earlier two outputs. –  doctorate May 8 at 10:22
    
@doctorate Good point! See my update –  JLDiaz May 8 at 10:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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