首先,我对 latex 比较陌生,对 tikz 完全陌生。我想做的是使用 tikz 在 latex 中创建一个聊天界面。我想要的结果应该是这样的:
\begin{chat}
Question
Answer
Question
Answer
\end{chat}
关于这里的其他帖子,我唯一发现的是此 messenger 接口文档类,但我想将它嵌入到我现有的文档中,而且这比我想要的更多一点(android gui,消息输入字段,...)。
到目前为止,我所做的就是手动创建这些节点并手动调整坐标(尤其是对于多行消息)。此代码的结果如上图所示。
\begin{tikzpicture}
\definecolor{chatcolor1}{HTML}{5fedb7}
\definecolor{chatcolor2}{HTML}{b6b8b7}
\fontfamily{cmss}\selectfont
\node[align=left, text width=5cm, fill=chatcolor2, rounded corners=1mm, anchor=north west] at (0,0) {Question};
\node[align=right, text width=5cm,fill=chatcolor1, rounded corners=1mm, anchor=north west] at (2,-0.7) {Answer};
\node[align=left, text width=5cm, fill=chatcolor2, rounded corners=1mm, anchor=north west] at (0,-1.4) {Question};
\node[align=right, text width=5cm,fill=chatcolor1, rounded corners=1mm, anchor=north west] at (2,-2.1) {Answer};
\end{tikzpicture}
现在的想法是让代码可重复使用,这样我就不必每次都复制粘贴并手动调整坐标。为此,我尝试使用该environ
包创建一个环境。这应该遍历行\BODY
并为每一行创建一个节点。
\NewEnviron{chat}{%
\definecolor{chatcolor1}{HTML}{5fedb7}
\definecolor{chatcolor2}{HTML}{b6b8b7}
\fontfamily{cmss}\selectfont
\begin{tikzpicture}
\foreach \line in \BODY
{\node[align=left, text width=5cm, fill=chatcolor2, rounded corners=1mm, anchor=north west] at (0,0) {\line};}
\end{tikzpicture}
}
但是这确实创建了一个节点,但所有内容都被视为一行。如果我在每行之间添加换行符,\begin{chat} ... \end{chat}
则会引发以下错误:Paragraph ended before \pgffor@normal@list was complete. \end{chat}
这种方法对您来说合理吗?如果合理,我该如何让它发挥作用?
如果没有的话,我很感谢任何其他解决这个问题的方法。
提前致谢。
答案1
欢迎!
如果可以的话,我喜欢尽量减少标记,并且我也喜欢让 TeX 来完成繁重的工作 ;)。
新编辑
您可以输入:
\begin{newchat}
a which might go on for a bit and be quite long\\[10pt]with a line break
v
b
u
question
answer
How many existentialists does it take to change a light bulb?
That depends...
\end{newchat}
或者您可以使用我最初建议的形式(请注意空白行):
\begin{chat}
a which might go on for a bit and be quite long\\[10pt]with a line break
v
b
u
question
answer
How many existentialists does it take to change a light bulb?
That depends...
\end{chat}
我还提供了一些缺失的%
和;
以及\strut
在 Ti 中的使用钾氘\node
\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}
\newcounter{chatlinenum}
%% Adjust text width to suit
\tikzset{chatstyle/.style={text width=1.5in,rounded corners=2pt}}
%% Adjust width of minipage to suit, but greater than TikZ text width
\NewDocumentEnvironment{chat}{}{%
\setcounter{chatlinenum}{0}
\begin{minipage}{2.0in}
\everypar={\chatline}
}{%
\end{minipage}
}
\definecolor{mygreen}{HTML}{88EABB}
%% Alter colors to suit
\def\chatline#1\par{%
\stepcounter{chatlinenum}%
\noindent
\ifodd\thechatlinenum
\tikz[]{\node[fill=lightgray,chatstyle]{\strut#1\strut};}%
\else
\hfill
\tikz[]{\node[fill=mygreen,chatstyle,align=right]{\strut#1\unskip\strut};}%
\fi
\par
\smallskip
}
%% |=====8><-----| %% New solution:
%% Alter colors to suit
\begingroup
\lccode`~=`\^^M
\lowercase{%
\endgroup
\def\newchatline#1~{%
\stepcounter{chatlinenum}%
\ifodd\thechatlinenum
\tikz[]{\node[fill=lightgray,chatstyle]{\strut#1\strut};}%
\else
\hfill
\tikz[]{\node[fill=mygreen,chatstyle,align=right]{\strut#1\strut};}%
\fi
~
\smallskip
}%
}
\NewDocumentEnvironment{newchat}{}{%
\setcounter{chatlinenum}{0}
\begin{minipage}{2.0in}
\obeylines
\everypar={\newchatline}
}{%
\end{minipage}
}
\begin{document}
%% The new answer (no empty lines between entries):
New chat:
\begin{newchat}
a which might go on for a bit and be quite long\\[10pt]with a line break
v
b
u
question
answer
How many existentialists does it take to change a light bulb?
That depends...
\end{newchat}
%% |=====8><-----| %%
%% The original answer:
\bigskip
Old chat:
\begin{chat}
a which might go on for a bit and be quite long\\[10pt]with a line break
v
b
u
question
answer
How many existentialists does it take to change a light bulb?
That depends...
\end{chat}
\end{document}
答案2
由于我没有使用该environ
软件包的经验,因此我坚持使用它tikz
。然而,这只是第一次尝试,但我认为这应该是一个良好的开端,可以改进。
\documentclass[tikz]{standalone}
\definecolor{chatcolor1}{HTML}{5fedb7}
\definecolor{chatcolor2}{HTML}{b6b8b7}
\fontfamily{cmss}\selectfont
\tikzset{
msgBase/.style={align=left,
minimum width=5cm,
minimum height=.5cm,
rounded corners=1mm,
},
ownMsg/.style={msgBase,
anchor=north east,
fill=chatcolor1,
xshift=+5pt,
},
oppMsg/.style={msgBase,
anchor=north west,
fill=chatcolor2,
xshift=-5pt,
},
}
\newcommand{\ownChat}[3]{
\node[ownMsg,name=#1] at (#2) {#3};
}
\newcommand{\oppChat}[3]{%
\node[oppMsg,name=#1] at (#2) {#3};
}
\begin{document}
that is looking nice ...
\begin{tikzpicture}
\node[ownMsg,name=own1] at (0,0) {Question};
\node[oppMsg,name=opp1] at (own1.south) {Answer};
\node[ownMsg,name=own2] at (opp1.south) {Question\\long};
\node[oppMsg,name=opp2] at (own2.south) {Answer};
\end{tikzpicture}
... but there is still work to do (an alternative to the code before)
\begin{tikzpicture}
\ownChat{own1}{0,0}{Question}
\oppChat{opp1}{own1.south}{Answer}
\ownChat{own2}{opp1.south}{really long and detailed Question}
\oppChat{opp2}{own2.south}{Question}
\end{tikzpicture}
\end{document}