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.

Friends, I need to highlight specific letters. My set contains only A, N, C, Q and P, so I decided to make them look as a tape strip (ressembles a good old Turing Machine tape). The following code poorly tries to achieve that. Since I had an immutable set of letters and a defined order, I used the xstring package.

\documentclass{article}

\usepackage{tikz}
\usepackage{xstring}

\newcommand*\myblackbox[1]{%
  \begin{tikzpicture}
    \node[draw,inner sep=1pt, minimum height=0.2cm, minimum width=0.2cm] {\tiny\tt\raisebox{0pt}[\height][0pt]{#1}};
  \end{tikzpicture}}

\newcommand*\mygraybox[1]{%
  \begin{tikzpicture}
    \node[draw,inner sep=1pt, draw=gray!60, minimum height=0.2cm, minimum width=0.2cm] {\color{gray!60}\tiny\tt\raisebox{0pt}[\height][0pt]{#1}};
  \end{tikzpicture}}

\DeclareRobustCommand*\drawboxes[1]{%
\IfSubStr{#1}{A}{\myblackbox{A}}{\mygraybox{A}}%
\IfSubStr{#1}{N}{\myblackbox{N}}{\mygraybox{N}}%
\IfSubStr{#1}{C}{\myblackbox{C}}{\mygraybox{C}}%
\IfSubStr{#1}{Q}{\myblackbox{Q}}{\mygraybox{Q}}%
\IfSubStr{#1}{P}{\myblackbox{P}~}{\mygraybox{P}~}}

\begin{document}

\drawboxes{ACQ} Hello world.

\end{document}

This is the output:

Strip

The squares are arranged side by side. So far so good, but I'd like to make them slightly overlap each others, like this:

Strip 2

The black boxes have higher priority, so they need to be on top of the gray ones. My solution is very simple, so I understand that a possible solution might have another method.

Any ideas?

share|improve this question

3 Answers 3

up vote 16 down vote accepted

I would put all the nodes into one tikzpicture, give all the nodes an outer xsep=0pt (which means that the edge of the node is defined as the middle of the border line), place them using a chain with a node distance of 0pt, and use the backgrounds library to put the gray nodes behind the black ones using \begin{pgfonlayer}{background}...\end{pgfonlayer}.

(Some additional optimisations of the code: You can use font=\tiny\tt to define the font options in the node style; instead of using the raisebox you can just define all nodes to have a text depth=0pt; and setting the color in the node options means you don't have to use \color in the node text).

tikz tape letters

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{chains,backgrounds}

\usepackage{xstring}

\tikzset{
    tape node/.style={
        on chain,
        draw,
        inner sep=1pt,
        outer xsep=0pt,
        minimum height=0.2cm,
        minimum width=0.2cm,
        text depth=0pt,
        font=\tiny\tt
    }
}

\newcommand*\myblackbox[1]{%
    \node[
        tape node
    ] {#1};
}

\newcommand*\mygraybox[1]{%
    \begin{pgfonlayer}{background}
        \node[
            tape node,
            gray!60
        ] {#1};
    \end{pgfonlayer}
}

\DeclareRobustCommand*\drawboxes[1]{%
\begin{tikzpicture}[
        start chain=going right,
        node distance=0pt
    ]
    \IfSubStr{#1}{A}{\myblackbox{A}}{\mygraybox{A}}%
    \IfSubStr{#1}{N}{\myblackbox{N}}{\mygraybox{N}}%
    \IfSubStr{#1}{C}{\myblackbox{C}}{\mygraybox{C}}%
    \IfSubStr{#1}{Q}{\myblackbox{Q}}{\mygraybox{Q}}%
    \IfSubStr{#1}{P}{\myblackbox{P}~}{\mygraybox{P}~}
\end{tikzpicture}
}

\begin{document}

\drawboxes{ACQ} Hello world.
\end{document}
share|improve this answer
1  
Very impressive solution, Jake! I had no idea of how to put the gray nodes behind the black ones. Your answer is complete, very didatic and easy to understand, thanks a million! –  Paulo Cereda Jul 14 '11 at 23:36
1  
You could avoid the backgrounding if you made the gray nodes black but with some transparency. –  Loop Space Mar 8 '12 at 9:21

This a version of Jake's answer without chain. I start with tikz 1.1 without chain and I don't use it. I used maximum width and only one macro. I kept fine things text depth layers, font and I add a foreach.

\documentclass{article}
\usepackage{tikz} \usetikzlibrary{backgrounds}
\usepackage{xstring}

\tikzset{
    tape node/.style={
        anchor       = west, % to replace the chain
        #1,
        draw,
        inner sep    = 1pt,
        outer xsep   = 0pt,
        minimum size = 0.2cm,
        text depth   = 0pt,
        font=\tiny\tt
    }
}

\newcommand*\mybox[3]{%
    \begin{pgfonlayer}{#3}
        \node[tape node = #2](last) at (last.east) {#1};% my chain
    \end{pgfonlayer}
}

\DeclareRobustCommand*\drawboxes[1]{%
\begin{tikzpicture}
\node[inner sep=0pt](last){}; % to start "my" chain
\foreach \letter in {A,N,C,Q,P} {% more easy to adapt
    \IfSubStr{#1}{\letter}{%
         \mybox{\letter}{black}{main}}{%
         \mybox{\letter}{gray!60}{background}
         }
     }  
\end{tikzpicture}
}

\begin{document}
\drawboxes{ACQ} Hello world.
\end{document}  
share|improve this answer
    
Thanks Altermundus! It looks very impressive! :) –  Paulo Cereda Mar 8 '12 at 9:50
    
@PauloCereda Thanks but the great part of the work comes from Jake. –  Alain Matthes Mar 8 '12 at 9:55

Based on your original code, using subtractions of \pgflinewidth and opacity as Andrew Stacey suggested in the comments on Jake's answer.

\documentclass{standalone}

\usepackage{tikz}
\usepackage{xstring}

\newcommand*\myblackbox[1]{%
  \begin{tikzpicture}
    \node[
      draw,
      inner sep=1pt,
      minimum height=0.2cm,
      minimum width=0.2cm
    ] {\tiny\tt\raisebox{0pt}[\height][0pt]{#1}};
  \end{tikzpicture}%
}

\newcommand*\mygraybox[1]{%
  \begin{tikzpicture}
    \node[
      draw,
      inner sep=1pt,
      minimum height=0.2cm,
      minimum width=0.2cm,
      opacity=0.4
    ] {\tiny\tt\raisebox{0pt}[\height][0pt]{#1}};
  \end{tikzpicture}%
}

\DeclareRobustCommand*\drawboxes[1]{%
\IfSubStr{#1}{A}{\myblackbox{A}}{\mygraybox{A}}\hspace{-\pgflinewidth}%
\IfSubStr{#1}{N}{\myblackbox{N}}{\mygraybox{N}}\hspace{-\pgflinewidth}%
\IfSubStr{#1}{C}{\myblackbox{C}}{\mygraybox{C}}\hspace{-\pgflinewidth}%
\IfSubStr{#1}{Q}{\myblackbox{Q}}{\mygraybox{Q}}\hspace{-\pgflinewidth}%
\IfSubStr{#1}{P}{\myblackbox{P}~}{\mygraybox{P}~}}

\begin{document}

\drawboxes{ACQ} Hello world.

\end{document}

enter image description here

share|improve this answer
1  
Nice idea, Mark! Thanks! :) –  Paulo Cereda Mar 8 '12 at 10:36
    
I like Jake's version the best, but I thought a minimally changed version would make a nice addition. –  qubyte Mar 8 '12 at 10:51

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.