# pgf-umlcd: underscore in class name failing

I have a simple class diagram drawn with pgf-umlcd, but using an underscore within the class name leads to an error message.

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


The message appears on the \end{class} line:

Missing \endcsname inserted. \end{class}


I also tried \textunderscore from the underscore package (same result) and \verb|_| (which hangs the compilation process).

Is this a bug in pgf-umlcd? Using underscores in attributes and operations works just fine. Is there a workaround or something i am missing?

• I can offer you \begin{class}{class\string_name} but it requires \usepackage[T1]{fontenc} Feb 8 '16 at 16:50
• Unfortunately, the package uses the second argument both for node names and for typesetting, which is a big nuisance; I see no other method than the above: _ is illegal in printing, whereas \_ is illegal in node names. Feb 8 '16 at 17:05

The package uses the argument to \begin{class} for two distinct purposes, that is, both for typesetting and for making node names.

When it is used for typesetting, _ is illegal, whereas \_ is illegal in a node name.

\usepackage[T1]{fontenc}


and use

\begin{class}{Class\string_Name}


You can also avoid the (quite ugly) underscore you get with T1 encoded fonts with a more complex workaround, which basically is rewriting the package so that it uses two distinct strings for the two purposes; one has the simple underscores, the other one has them replaced by \_.

\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}
`

• thank you. my document is quit short so i will use the simple workaround at first. Feb 8 '16 at 18:54