pgf-umlcd: クラス名にアンダースコアが使用できない

pgf-umlcd: クラス名にアンダースコアが使用できない

pgf-umlcd で描画した簡単なクラス図がありますが、クラス名内でアンダースコアを使用するとエラー メッセージが表示されます。

\begin{tikzpicture}
  \begin{class}{foo\_bar}{0,0}
    % some stuff here
  \end{class}
\end{tikzpicture}

次の行にメッセージが表示されます\end{class}:

Missing \endcsname inserted. \end{class}

\textunderscoreまた、アンダースコア パッケージ (同じ結果) と\verb|_|(コンパイル プロセスがハングする)も試しました。

これは pgf-umlcd のバグでしょうか? 属性と操作でアンダースコアを使用すると問題なく動作します。回避策や見落としている点はありますか?

答え1

パッケージは、引数を\begin{class}2 つの異なる目的、つまりタイプセットとノード名の作成の両方に使用します。

組版に使用する場合、_は不正ですが、\_ノード名では は不正です。

最も簡単な回避策は、

\usepackage[T1]{fontenc}

使用して

\begin{class}{Class\string_Name}

T1 エンコード フォントで表示される (かなり見苦しい) アンダースコアは、より複雑な回避策で回避することもできます。基本的には、パッケージを書き換えて、2 つの目的に 2 つの異なる文字列を使用するようにします。1 つは単純なアンダースコアで、もう 1 つはアンダースコアを . に置き換えます\_

\documentclass{article}
\usepackage{pgf-umlcd}
\usepackage{xpatch}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\defineclassname}{m}
 {
  \tl_set:Nn \umlcdClassName { #1 }
  \tl_set_eq:NN \umlcdClassNameString \umlcdClassName
  \tl_replace_all:Nfn \umlcdClassName { \char_generate:nn { `_ } { 8 } } { \_\kern1pt }
 }
\cs_generate_variant:Nn \tl_replace_all:Nnn { Nf }
\ExplSyntaxOff
\xpatchcmd{\classAndInterfaceCommon}
 {\def\umlcdClassName}
 {\defineclassname}
 {}{}
\xpatchcmd{\endclass}
 {(\umlcdClassName)}
 {(\umlcdClassNameString)}
 {}{\ddt}
\xpatchcmd{\endinterface}
 {(\umlcdClassName)}
 {(\umlcdClassNameString)}
 {}{\ddt}
\xpatchcmd{\endabstractclass}
 {(\umlcdClassName)}
 {(\umlcdClassNameString)}
 {}{\ddt}
\xpatchcmd{\endobject}
 {(\umlcdClassName)}
 {(\umlcdClassNameString)}
 {}{\ddt}
\xpatchcmd{\endclassAndInterfaceCommon}
 {(\umlcdClassName)}
 {(\umlcdClassNameString)}
 {}{\ddt}
\xpatchcmd{\endclassAndInterfaceCommon}
 {(\umlcdClassName)}
 {(\umlcdClassNameString)}
 {}{\ddt}
\xpatchcmd{\endclassAndInterfaceCommon}
 {(\umlcdClassName)}
 {(\umlcdClassNameString)}
 {}{\ddt}
\begin{document}

\begin{tikzpicture}
\begin{class}[text width=8cm]{Class_Name}{0,0}
\attribute{name : attribute type}
\attribute{name : attribute type = default value}
\operation{name(parameter list) : type of value returned}
% virtual operation
\operation[0]{name(parameters list) : type of value returned}
\end{class}
\end{tikzpicture}

\end{document}

ここに画像の説明を入力してください

関連情報