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}
  • 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? – Torbjørn T. May 16 '18 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. – Torbjørn T. May 16 '18 at 7:56
  • 1
    ... related informations about minimal working example (MWE). – Bobyandbob May 16 '18 at 8:04
  • 1
    @TorbjørnT. The package version should be the CTAN one – el_gio May 16 '18 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 May 16 '18 at 8:21
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}{\tmp@X-0.3\stopwidth}%
    \setlength{\tmp@Xb}{\tmp@X+0.3\stopwidth}%
    \setlength{\tmp@Ya}{\tmp@Yb+0.3\stopwidth}%
    \setlength{\tmp@Yb}{\tmp@Yb-0.3\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}
  • Thanks! That's exactly what I was looking for, perfect solution and explanation. – el_gio May 16 '18 at 12:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.