2

I am using the msc package to include protocols in a document. I would like to have something like the following sequence chart, but with m1 stopped before reaching B. enter image description here I did not find any related questions, and on the package documentation I only found the stop command to stop instances, but not messages. Any suggestions on how to achieve this using the msc package, if possible?

EDIT: here is the code I used to produce the simple protocol above (without the parts used to change width, etc.)

\documentclass{article}

\usepackage{msc}

\begin{document}
    \begin{figure}[h]
        \centering
            \begin{msc}{a protocol}

                \declinst{a}{}{A}   
                \declinst{b}{}{B}   
                \declinst{c}{}{C}

                \mess{$m_1$}{a}{b}
                \nextlevel  
                \mess{$m_1'$}{c}{b}
                \nextlevel[2]
                \mess{other messages}{a}{c}
                \mess{}{c}{a}
                \nextlevel[2]

            \end{msc}

    \end{figure}

\end{document}
5
  • 1
    Hi, welcome. Which version of the package are you using, the one on CTAN based on PSTricks, or the development version based on TikZ? Commented May 16, 2018 at 7:55
  • 1
    It would also be very helpful if you could add the code for that diagram, makes it a lot more convenient for those trying to help. Commented May 16, 2018 at 7:56
  • 1
    ... related informations about minimal working example (MWE).
    – Bobyandbob
    Commented May 16, 2018 at 8:04
  • 1
    @TorbjørnT. The package version should be the CTAN one
    – el_gio
    Commented May 16, 2018 at 8:18
  • 1
    @Bobyandbob Thanks for pointing this out, I included a MWE without the details needed to format the width, etc.
    – el_gio
    Commented May 16, 2018 at 8:21

1 Answer 1

1

After some rummaging in the package code:

enter image description here

I defined a new macro \messstop, used similarly to \mess, i.e.

\messstop{$m_1$}{a}{b}

It has an optional argument to set the distance from b where the line stops, e.g. with

\messstop[20pt]{$m_1$}{a}{b}

it stops 20pt before b instead of the default (which I set to 10pt).


Some explanation:

In the definition of \messstop I add a (local) patch to the macro that draws the message arrow in the first place, to remove the arrow tip specification. I don't know if this is the best method, but it's fairly concise, and it works.

You'll see that in \messstop I call \mess with two extra bracketed arguments in the end: \mess{#2}{#3}{#4}[0][#1]. The [0] indicates that this is a message where the sender and receiver is not the same. Specifically it means that \mess@leveloffset becomes zero. The second bracket pair is where the distance from b is inserted (i.e. the optional argument to \messstop, mentioned above). In the package, this length is used to set the \mess@instanceoffset length.

Finally, I call a macro \drawcross, which I defined based on the \stop macro in msc.sty. It draws a cross at the current y-level, at the x-position defined by the mandatory argument. E.g. \drawcross{a} draws a cross at the x-position of the a instance. Like \messstop, this has an optional argument used to define the (negative) offset in the x-direction, so \drawcross[10pt]{a} would move the cross 10pt to the left.

To make this work regardless of the direction of the arrow, I added an \ifthenelse which tests the x-position of sender and receiver, and changes the sign of the offset passed to \drawcross accordingly.

Complete code:

\documentclass{article}
\usepackage{msc}
\usepackage{etoolbox} % for \patchcmd

\makeatletter
\newcommand\drawcross[2][0pt]{%
    % adapted from the definition of \stop in msc.sty
    \setlength{\tmp@Yb}{\msc@currentheight}%
    \setlength{\tmp@X}{\msc@instxpos{#2}}%
    \addtolength{\tmp@X}{-#1}
    \setlength{\tmp@Xa}{\[email protected]\stopwidth}%
    \setlength{\tmp@Xb}{\tmp@X+0.3\stopwidth}%
    \setlength{\tmp@Ya}{\tmp@Yb+0.3\stopwidth}%
    \setlength{\tmp@Yb}{\[email protected]\stopwidth}%
    \psline(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)%
    \psline(\tmp@Xb,-\tmp@Ya)(\tmp@Xa,-\tmp@Yb)%
}

\newcommand\messstop[4][10pt]{%
    {%group to keep patching local 
    \patchcmd{\msc@drawnonselfarrow}{{->}}{}{}{} % remove arrow tip spec from \psline
    \mess{#2}{#3}{#4}[0][#1] % draw message
    }
    % need to find out the relative position of sender and receiver
    % if sender is leftmost, use positive offset in \drawcross
    % else, use negative offset
    \ifthenelse{\lengthtest{\msc@instxpos{#3} < \msc@instxpos{#4}}}%
    {\drawcross[#1]{#4}} % 
    {\drawcross[-#1]{#4}}
}
\makeatother
\begin{document}
    \begin{figure}
        \centering
            \begin{msc}{a protocol}

                \declinst{a}{}{A}   
                \declinst{b}{}{B}   
                \declinst{c}{}{C}

                \messstop[20pt]{$m_1$}{a}{b}
                \nextlevel  
                \mess{$m_1'$}{c}{b}
                \nextlevel[2]
                \mess{other messages}{a}{c}
                \mess{}{c}{a}
                \nextlevel[2]

            \end{msc}

    \end{figure}

\end{document}
1
  • Thanks! That's exactly what I was looking for, perfect solution and explanation.
    – el_gio
    Commented May 16, 2018 at 12:43

You must log in to answer this question.

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