使用 TikZ 在 Latex 中创建聊天界面

使用 TikZ 在 Latex 中创建聊天界面

首先,我对 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}

相关内容