我正在使用msc
包将协议包含在文档中。我希望得到类似以下序列图的东西,但m1
在到达之前停止B
。
我没有找到任何相关问题,在软件包文档中我只找到了停止实例的命令,但没有找到消息。如果可能的话,stop
关于如何使用软件包实现这一点,有什么建议吗?msc
编辑:这是我用来生成上述简单协议的代码(没有用于改变宽度等的部分)
\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
在对包代码进行一番翻找之后:
我定义了一个新的宏\messstop
,用法类似于\mess
,即
\messstop{$m_1$}{a}{b}
b
它有一个可选参数来设置线停止处的距离,例如
\messstop[20pt]{$m_1$}{a}{b}
它会在 20pt 之前停止,b
而不是默认值(我设置为10pt
)。
一些解释:
在定义中,\messstop
我首先向绘制消息箭头的宏添加一个(本地)补丁,以删除箭头尖端规范。我不知道这是否是最好的方法,但它相当简洁,而且有效。
您将看到,\messstop
我在调用时\mess
在末尾添加了两个带括号的参数:\mess{#2}{#3}{#4}[0][#1]
。[0]
表示这是一条发送者和接收者不同的消息。具体来说,这意味着\mess@leveloffset
变为零。第二个括号对是b
插入距离的位置(即上面提到的可选参数\messstop
)。在包中,此长度用于设置长度\mess@instanceoffset
。
最后,我调用一个宏\drawcross
,它是我根据\stop
中的宏定义的msc.sty
。它在当前 y 级别绘制一个十字,在强制参数定义的 x 位置。例如,\drawcross{a}
在实例的 x 位置绘制一个十字a
。与 一样\messstop
,它有一个可选参数,用于定义 x 方向的(负)偏移量,因此\drawcross[10pt]{a}
会将十字向左移动 10pt。
为了使其无论箭头方向如何都能工作,我添加了一个\ifthenelse
测试发送者和接收者的 x 位置,并相应地改变传递的偏移量的符号\drawcross
。
完整代码:
\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}