朋友们,我需要突出显示特定的字母。我的字母集仅包含A
、、和,所以我决定让它们看起来像一条胶带(类似于老式的图灵机胶带)。以下代码很难实现这一点。由于我有一组不可变的字母和一个定义的顺序,所以我使用了包。N
C
Q
P
xstring
\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}
这是输出:
这些方块并排排列。到目前为止一切顺利,但我想让它们稍微重叠,如下所示:
黑框的优先级更高,所以它们需要位于灰色框的上方。我的解决方案非常简单,所以我知道可能的解决方案可能有另一种方法。
有任何想法吗?
答案1
我会将所有节点放入一个中tikzpicture
,为所有节点赋予一个outer xsep=0pt
(这意味着节点的边缘定义为边界线的中间),使用node distance
0pt 的链放置它们,然后使用backgrounds
库将灰色节点放在黑色节点后面\begin{pgfonlayer}{background}...\end{pgfonlayer}
。
(代码的一些额外优化:您可以使用font=\tiny\tt
在节点样式中定义字体选项;而不是使用,raisebox
您可以定义所有节点都有text depth=0pt
;并且在节点选项中设置颜色意味着您不必\color
在节点文本中使用)。
\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}
答案2
这是 Jake 答案的一个版本,没有chain
。我从没有链的 tikz 1.1 开始,我不使用它。我maximum width
只使用了一个宏。我保留了好东西text depth
layers
, font
然后添加了一个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}
答案3
根据您的原始代码,使用\pgflinewidth
和不透明度的减法,正如 Andrew Stacey 在 Jake 的答案的评论中所建议的那样。
\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}