pgf-umlcd: falla el guión bajo en el nombre de la clase

pgf-umlcd: falla el guión bajo en el nombre de la clase

Tengo un diagrama de clases simple dibujado con pgf-umlcd, pero usar un guión bajo dentro del nombre de la clase genera un mensaje de error.

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

El mensaje aparece en la \end{class}línea:

Missing \endcsname inserted. \end{class}

También probé \textunderscorecon el paquete de subrayado (mismo resultado) y \verb|_|(que bloquea el proceso de compilación).

¿Es esto un error en pgf-umlcd? Usar guiones bajos en atributos y operaciones funciona bien. ¿Hay alguna solución o algo que me falta?

Respuesta1

El paquete utiliza el argumento to \begin{class}para dos propósitos distintos, es decir, tanto para componer como para crear nombres de nodos.

Cuando se utiliza para composición tipográfica, _es ilegal, mientras que \_es ilegal en un nombre de nodo.

La solución más sencilla es añadir

\usepackage[T1]{fontenc}

y use

\begin{class}{Class\string_Name}

También puede evitar el guión bajo (bastante feo) que se obtiene con las fuentes codificadas T1 con una solución alternativa más compleja, que básicamente consiste en reescribir el paquete para que utilice dos cadenas distintas para los dos propósitos; uno tiene guiones bajos simples, el otro los reemplaza por \_.

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

ingrese la descripción de la imagen aquí

información relacionada