6

I am making a conversation and I need to draw some shapes, and place them properly along the page. The shapes are the following:

  • A white rectangle with a little crest (called mestart): mestart shape
  • A white rectangle without a crest (called me): me shape
  • A green rectangle with a little crest (called youstart): youstart shape
  • A green rectangle without a crest (called you): you shape
  • A blue rectangle with rounded corners (called exnumber): exnumber shape

What I want

I want to produce the following conversation:

What I want

To consider:

  1. All the rectangles (except exnumber) can have inside:
    • Only text (normal text, bulleted list, numbered list etc.), or
    • Only one image (it can be a tikzpicture), or
    • Text & sample code (for instance listings package can be a good example).
  2. These rectangles must have a max width and a space between them: Max width (also the images should have the same max width).
  3. The blue rectangle i.e. exnumber should be placed centered on the page with an automatic numeration and restarted when the section ends. For example: in Section 1 Exercise 1, Exercise 2, Exercise 3. In Section 2: Exercise 1, Exercise 2.

What I have done

Please consider this MWE:

\documentclass{article}
\usepackage[a4paper,margin=1in,footskip=0.25in]{geometry}

\usepackage{tikz}
\usetikzlibrary{shapes.misc, positioning}
\usetikzlibrary{decorations.text}
\usetikzlibrary{shapes.symbols}

\begin{document}

\begin{tikzpicture}
    \node (1) [rounded corners=.2cm,inner sep=.3cm,align=right,fill=blue] {Exercise 1};
\end{tikzpicture}

\begin{tikzpicture}
    \node (1) [draw,rounded corners=.2cm,inner sep=.5cm,align=left] {rounded rectangle\\asas};
\end{tikzpicture}

\begin{tikzpicture}
    \node (1) [rounded corners=.2cm,inner sep=.5cm,align=right,fill=green] {This is a rounded rectangle\\Text\\ a \\ a \\ a};
\end{tikzpicture}

\end{document}

What I have done

EDIT Some changes to edit #4 of the amazing Schrödinger's cat's answer with some implementations:

  1. Added \maxwidth and \maxheight.
  2. Since I need to add a lot of images to the conversation, I have created four new types of shapes: the 4 ones but with the word Image after the names. This includes \includegraphics[max height=\maxheight,max width=\maxwidth]{#2}.
  3. \begin{varwidth}{\maxwidth} added to the normal 4 shapes.
  4. Added tabs space and some information to the code.

Final result:

\documentclass{article}
\usepackage{blindtext}
\def\maxwidth{16cm}
\def\maxheight{20cm}

\usepackage[a4paper,margin=.25in,footskip=0.25in]{geometry}

\usepackage[export]{adjustbox} % Loads also graphicx
\usepackage{varwidth}

\usepackage{tikz}
\usetikzlibrary{positioning}
% From https://tex.stackexchange.com/revisions/529773/4
\tikzset{basic/.style={rounded corners=.2cm,inner sep=.5cm},
    basic L/.style={basic,align=left,fill=white,anchor=north west,
        font=\sffamily,outer sep=0pt},
    my callout L/.style={basic L,
        append after command={pic[fill=white]{callout corner L}}},
    basic R/.style={basic,align=right,fill=green!60!black,anchor=north east,
        font=\sffamily,outer sep=0pt},
    my callout R/.style={basic R,
        append after command={pic[fill=green!60!black]{callout corner R}}},
    pics/callout corner L/.style={code={
    \path[pic actions] ([xshift=3mm]\tikzlastnode.north west) -- ++ (-9mm,0) 
    -- ([yshift=-6mm]\tikzlastnode.north west);}},
    pics/callout corner R/.style={code={
    \path[pic actions] ([xshift=-3mm]\tikzlastnode.north east) -- ++ (9mm,0) 
    -- ([yshift=-6mm]\tikzlastnode.north east);}},
    exercise/.style={rounded corners=.2cm,inner sep=.3cm,align=right,
        fill=blue,anchor=north,font=\sffamily,text=white},
    whatsapp/.cd,vdist/.initial=3mm,hdist/.initial=6mm
}
% Added varwidth to set a max width for each of the shapes. From https://tex.stackexchange.com/a/46479/152550
% MeStart
\newcommand{\MeStart}[2][]{\noindent\begin{tikzpicture}
    \path (0,0) (\pgfkeysvalueof{/tikz/whatsapp/hdist},0) node[my callout L,alias=tmp,#1] {\begin{varwidth}{\maxwidth}#2\end{varwidth}};
    \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist});
\end{tikzpicture}\par}
% Me
\newcommand{\Me}[2][]{\noindent\begin{tikzpicture}
    \path (0,0) (\pgfkeysvalueof{/tikz/whatsapp/hdist},0) node[basic L,alias=tmp,#1] {\begin{varwidth}{\maxwidth}#2\end{varwidth}};
    \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist});
\end{tikzpicture}\par}
% YouStart
\newcommand{\YouStart}[2][]{\noindent\begin{tikzpicture}
    \path (0,0) (\textwidth-\pgfkeysvalueof{/tikz/whatsapp/hdist},0) node[my callout R,alias=tmp,#1] {\begin{varwidth}{\maxwidth}#2\end{varwidth}};
    \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist});
\end{tikzpicture}\par}
% You
\newcommand{\You}[2][]{\noindent\begin{tikzpicture}
    \path (0,0) (\textwidth-\pgfkeysvalueof{/tikz/whatsapp/hdist},0) node[basic R,alias=tmp,#1] {\begin{varwidth}{\maxwidth}#2\end{varwidth}};
    \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist});
\end{tikzpicture}\par}
% Exercise
\newcommand{\Exercise}[2][]{\noindent\begin{tikzpicture}
    \path (0,0) (\textwidth/2,0) node[exercise,alias=tmp,#1] {#2};
    \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist});
\end{tikzpicture}\par}
% max height/width for includegraphics from https://tex.stackexchange.com/a/47252/152550
% MeStartImage
\newcommand{\MeStartImage}[2][]{\noindent\begin{tikzpicture}
    \path (0,0) (\pgfkeysvalueof{/tikz/whatsapp/hdist},0) node[my callout L,alias=tmp,#1] {\includegraphics[max height=\maxheight,max width=\maxwidth]{#2}};
    \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist});
\end{tikzpicture}\par}
% MeImage
\newcommand{\MeImage}[2][]{\noindent\begin{tikzpicture}
    \path (0,0) (\pgfkeysvalueof{/tikz/whatsapp/hdist},0) node[basic L,alias=tmp,#1] {\includegraphics[max height=\maxheight,max width=\maxwidth]{#2}};
    \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist});
\end{tikzpicture}\par}
% YouStartImage
\newcommand{\YouStartImage}[2][]{\noindent\begin{tikzpicture}
    \path (0,0) (\textwidth-\pgfkeysvalueof{/tikz/whatsapp/hdist},0) node[my callout R,alias=tmp,#1] {\includegraphics[max height=\maxheight,max width=\maxwidth]{#2}};
    \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist});
\end{tikzpicture}\par}
% YouImage
\newcommand{\YouImage}[2][]{\noindent\begin{tikzpicture}
    \path (0,0) (\textwidth-\pgfkeysvalueof{/tikz/whatsapp/hdist},0) node[basic R,alias=tmp,#1] {\includegraphics[max height=\maxheight,max width=\maxwidth]{#2}};
    \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist});
\end{tikzpicture}\par}

\begin{document}

\begin{tikzpicture}[overlay,remember picture]
    \fill[blue!20] (current page.south west) rectangle (current page.north east);
\end{tikzpicture}

\MeStart{\blindtext[1]\\ Text}

\MeImage[scale=0.5]{example-image}

\YouStartImage[scale=2]{example-image-duck}

\Exercise{How many marmots?}

\You{\Blindtext[1]}

\end{document}

Example

2
  • Tik has the callout shapes which look similar but not identical to what you have. Do you want the exact shape, or is something similar OK?
    – user194703
    Feb 24, 2020 at 5:35
  • @Schrödinger'scat I want the exact shapes (it is like a WhatsApp Messenger conversation). Thanks for pointing it out.
    – manooooh
    Feb 24, 2020 at 5:39

1 Answer 1

6

This defines such shapes. Note that I did not really simplify positioning too much because probably you want some macros for the dialogue. They can take care of that. The following code is based on the newly added routines of your question. However, rather than defining many macros, it uses pgf keys. For instance, instead of

 \MeStart{\blindtext[1]\\ Text}

you can use

 \Me[start]{\blindtext[1]\\ Text}

or

 \You[start,image={scale=2}]{example-image-duck}

and so on. This has the advantage of being extendable very easily while keeping backwards compatibility.

\documentclass{article}
\usepackage{blindtext}
\def\maxwidth{16cm}
\def\maxheight{20cm}

\usepackage[a4paper,margin=.25in,footskip=0.25in]{geometry}

\usepackage[export]{adjustbox} % Loads also graphicx
\usepackage{varwidth}
\newif\ifStart
\Startfalse
\newif\ifImage
\Imagefalse
\usepackage{tikz}
\usetikzlibrary{positioning}
% From https://tex.stackexchange.com/revisions/529773/4
\tikzset{basic/.style={rounded corners=.2cm,inner sep=.5cm},
    basic L/.style={basic,align=left,fill=white,anchor=north west,
        font=\sffamily,outer sep=0pt},
    my callout L/.style={basic L,
        append after command={pic[fill=white]{callout corner L}}},
    basic R/.style={basic,align=right,fill=green!60!black,anchor=north east,
        font=\sffamily,outer sep=0pt},
    my callout R/.style={basic R,
        append after command={pic[fill=green!60!black]{callout corner R}}},
    pics/callout corner L/.style={code={
    \path[pic actions] ([xshift=3mm]\tikzlastnode.north west) -- ++ (-9mm,0) 
    -- ([yshift=-6mm]\tikzlastnode.north west);}},
    pics/callout corner R/.style={code={
    \path[pic actions] ([xshift=-3mm]\tikzlastnode.north east) -- ++ (9mm,0) 
    -- ([yshift=-6mm]\tikzlastnode.north east);}},
    exercise/.style={rounded corners=.2cm,inner sep=.3cm,align=right,
        fill=blue,anchor=north,font=\sffamily,text=white},
    whatsapp/.cd,vdist/.initial=3mm,hdist/.initial=6mm,
    start/.is if=Start,
    image/.code=\Imagetrue\tikzset{whatsapp/graphics pars/.cd,#1},
    graphics pars/.cd,scale/.initial=1 %add additional keys here

}
% Added varwidth to set a max width for each of the shapes. From https://tex.stackexchange.com/a/46479/152550
% Me
\newcommand{\Me}[2][]{\noindent\begin{tikzpicture}
\tikzset{whatsapp/.cd,#1}
\ifStart
    \path (0,0) (\pgfkeysvalueof{/tikz/whatsapp/hdist},0) 
    node[my callout L,alias=tmp] {\ifImage
     \includegraphics[max height=\maxheight,max width=\maxwidth,
        scale=\pgfkeysvalueof{/tikz/whatsapp/graphics pars/scale}]{#2}%
    \else
    \begin{varwidth}{\maxwidth}#2\end{varwidth}%
    \fi};
\else
    \path (0,0) (\pgfkeysvalueof{/tikz/whatsapp/hdist},0) 
    node[basic L,alias=tmp] {\ifImage
     \includegraphics[max height=\maxheight,max width=\maxwidth,
        scale=\pgfkeysvalueof{/tikz/whatsapp/graphics pars/scale}]{#2}%
    \else
    \begin{varwidth}{\maxwidth}#2\end{varwidth}%
    \fi};
\fi 
    \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist});
\end{tikzpicture}\par}
% You
\newcommand{\You}[2][]{\noindent\begin{tikzpicture}
\tikzset{whatsapp/.cd,#1}
\ifStart
    \path (0,0) (\textwidth-\pgfkeysvalueof{/tikz/whatsapp/hdist},0) 
    node[my callout R,alias=tmp] {\ifImage
     \includegraphics[max height=\maxheight,max width=\maxwidth,
        scale=\pgfkeysvalueof{/tikz/whatsapp/graphics pars/scale}]{#2}%
    \else
    \begin{varwidth}{\maxwidth}#2\end{varwidth}%
    \fi};
\else
    \path (0,0) (\textwidth-\pgfkeysvalueof{/tikz/whatsapp/hdist},0) 
    node[basic R,alias=tmp] {\ifImage
     \includegraphics[max height=\maxheight,max width=\maxwidth,
        scale=\pgfkeysvalueof{/tikz/whatsapp/graphics pars/scale}]{#2}%
    \else
    \begin{varwidth}{\maxwidth}#2\end{varwidth}%
    \fi};
\fi 
    \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist});
\end{tikzpicture}\par}
\newcommand{\Exercise}[2][]{\noindent\begin{tikzpicture}
    \path (0,0) (\textwidth/2,0) node[exercise,alias=tmp,#1] {#2};
    \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist});
\end{tikzpicture}\par}
\begin{document}

\begin{tikzpicture}[overlay,remember picture]
    \fill[blue!20] (current page.south west) rectangle (current page.north east);
\end{tikzpicture}

\Me[start]{\blindtext[1]\\ Text}

\Me[image={scale=0.25}]{example-image}

\You[start,image={scale=2}]{example-image-duck}

\Exercise{How many marmots?}

\You{\Blindtext[1]}

\end{document}

enter image description here

23
  • 1
    @manooooh I added some sample macros.
    – user194703
    Feb 24, 2020 at 6:24
  • 1
    @manooooh As for 1), I do not fully understand. As for 2), good catch! I forgot to set the outer sep to 0. As for 3), I introduced keys for that, now you can change the vertical and horizontal distances. The horizontal one cannot become smaller than 6mm at this point because the callouts have the corner of that length. However, you can use geometry to reduce the let and right margins.
    – user194703
    Feb 24, 2020 at 16:30
  • 1
    @manooooh Yes I like the output. The fact that the boundaries increase comes from scale=2 in \YouStartImage[scale=2]{example-image-duck}, which scales everything. If you do not want to have this, you need to pass the optional argument to \includegraphics, not \node.
    – user194703
    Feb 24, 2020 at 23:33
  • 1
    @manooooh I mean simply \newcommand{\YouStartImage}[2][]{\noindent\begin{tikzpicture} \path (0,0) (\textwidth-\pgfkeysvalueof{/tikz/whatsapp/hdist},0) node[my callout R,alias=tmp] {\includegraphics[max height=\maxheight,max width=\maxwidth,#1]{#2}}; \path (tmp.south) ++ (0,-\pgfkeysvalueof{/tikz/whatsapp/vdist}); \end{tikzpicture}\par}. (Note the position of #1.)
    – user194703
    Feb 24, 2020 at 23:40
  • 1
    @manooooh I added an example. It achieves what you achieve but with two commands and some pgf keys. The advantage is that you can keep adding options as needed and won't lose backwards compatibility. (Notice that one could add start automatically if this is the first post by "Me" or "You" in a thread.)
    – user194703
    Feb 25, 2020 at 0:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .