Introducción

Introducción

Introducción

Lamento el largo MWE, pero no pude acortarlo y aun así ilustrar mi problema. Nuevamente estoy trabajando para agilizar la creación de exámenes para mi universidad. En el siguiente ejemplo, el usuario puede agregar más conferencias usando

\defineInfo{jane}{
  name=Jane Doe, 
  phone=75123123,
}

(De donde obtuve ayuda para crear la sintaxis enLista de contactos como diccionario) Agregue información sobre el examen usando

\FrontpageUiTsetup{
  contact = jane,
}

(Ahora con la ayuda deParámetros de entrada etiquetados) Donde el último comando, por supuesto, tiene muchos más parámetros, lo que es irrelevante para mi pregunta. Ahora, quiero combinar estas dos respuestas, para poder referirme a un profesor usando una identificación y luego imprimir las partes relevantes en formato \FrontpageUiT.

Primero intenté escribir

\ifx\@contact\@empty\else
  \contactname & \contactInfo{\@contact}{name}\\%
\fi

Sin embargo, parece que el \contactInfocomando se expande antes, \@contactpor lo que no genera nada. Después de buscar un poco en Google, pude usar lo siguiente para expandir \@contactprimero

\newcommand{\expandMacro}[1]{
  \begingroup\edef\x{\endgroup
    \noexpand#1%
  }\x
}

Problema

Entonces aquí viene mi problema:

  • Quiero que el valor predeterminado de @phone y @mobile se defina respectivamente mediante las líneas \contactInfo{\@contact}{mobile}y\contactInfo{\@contact}{phone}

El problema viene cuando quiero la linea.

\contactmobile & \@mobile 

Estar en blanco cuando no se proporciona ningún número de móvil. Ejemplo:

    mobile        .tl_set:N  = \@mobile,
    mobile        .initial:n = {\expandMacro{\contactInfo{\@contact}{mobile}}},
    phone         .tl_set:N  = \@phone,
    phone         .initial:n = {\expandMacro{\contactInfo{\@contact}{phone}}},
.
.
.
  \ifx\@contact\@empty\else
    \contactname & \expandMacro{\contactInfo{\@contact}{name}}\\%
  \fi

  \ifx\@mobile\@empty\else
    \contactmobile & \@mobile\\%
  \fi

  \ifx\@phone\@empty\else
    \contactphone & \@phone\\%
.
.
.

\defineInfo{jane}{
  name=Jane Doe, 
  phone=75123123,
}

\FrontpageUiTsetup{
  contact = jane,
}

\begin{document}
\FrontpageUiT
\end{document}

Como Jane no tiene número de móvil, esperaría que el resultado fuera

Contact    Jane Doe
Phone      75 12 31 23

En lugar de eso me enfrento a

Contact    Jane Doe
Mobile
Phone      75 12 31 23

El problema es que el código no puede expandirse \contactInfo{\@contact}{mobile}lo suficientemente rápido como para darse cuenta de que está vacío. Después de buscar un poco más en Google encontré

\newcommand{\IfNoText}[3]{%
  \sbox0{#1}%
  \ifdim\wd0=0pt %
    {#2}% if #1 is empty
  \else%
    \ifdim0pt=\dimexpr\ht0+\dp0\relax
      {#2}% if #1 is empty
    \else
      {#3}% if #1 is not empty
    \fi
  \fi%
}

Eso puede detectar si la salida está en blanco. Sin embargo, no admite el signo comercial (&), por lo que no puedo usarlo en mi tabla. P.EJ

\IfNoText{\@mobile}{}{Mobile & \@mobile \\}

me tira un error. También intenté usarlo \IfNoTextanteriormente en mi documento para definir opciones que se expanden a verdadero o falso según el contenido de \@mobile. Sin embargo, estos tampoco se expandieron lo suficientemente rápido.

  • ¿Hay alguna manera de verificar que \@mobileesté @phonevacío más rápido cuando se dan en los términos de \contactInfo?

Código

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{xparse}
\usepackage{xfp}

\newcommand{\IfNoText}[3]{%
  \sbox0{#1}%
  \ifdim\wd0=0pt %
    {#2}% if #1 is empty
  \else%
    \ifdim0pt=\dimexpr\ht0+\dp0\relax
      {#2}% if #1 is empty
    \else
      {#3}% if #1 is not empty
    \fi
  \fi%
}

\newcommand{\expandMacro}[1]{
  \begingroup\edef\x{\endgroup
    \noexpand#1%
  }\x
}

\ExplSyntaxOn
\NewDocumentCommand{\defineInfo}{mm}
 {
  \prop_new:c { \__nebu_contact_prop:n { #1 } }
  \prop_gset_from_keyval:cn { \__nebu_contact_prop:n { #1 } } { #2 }
 }
\NewDocumentCommand{\contactInfo}{mm}
 {
  \str_case:nnF { #2 }
   {
    {phone}  { \nebu_phone:e { \prop_item:cn { \__nebu_contact_prop:n { #1 } } { #2 } } }
    {mobile} { \nebu_phone:e { \prop_item:cn { \__nebu_contact_prop:n { #1 } } { #2 } } }
   }
   { \prop_item:cn { \__nebu_contact_prop:n { #1 } } { #2 } }
 }

% syntactic sugar
\cs_new:Nn \__nebu_contact_prop:n
 {
  g_nebu_contact_\str_lowercase:n { #1 }_prop
 }

%%% formatting phone numbers
\NewDocumentCommand{\phone}{m}
 {
  \nebu_phone:n { #1 }
 }

\tl_new:N \l__nebu_phone_tl

\cs_new_protected:Nn \nebu_phone:n
 {
  \tl_set:Nn \l__nebu_phone_tl { #1 }
  \tl_remove_all:Nn \l__nebu_phone_tl { ~ }
  \int_compare:nTF { \tl_count:N \l__nebu_phone_tl = 8 }
   {
    \__nebu_phone_eight:V \l__nebu_phone_tl
   }
   {
    \tl_use:N \l__nebu_phone_tl
   }
 }
\cs_generate_variant:Nn \nebu_phone:n { e }

\cs_new:Nn \__nebu_phone_eight:n
 {
  \str_case_e:nnF { \tl_head:n { #1 } }
   {
    {4}{ \__nebu_phone_iii_ii_iii:nnnnnnnn #1 }
    {8}{ \__nebu_phone_iii_ii_iii:nnnnnnnn #1 }
    {9}{ \__nebu_phone_iii_ii_iii:nnnnnnnn #1 }
   }
   {
    \__nebu_phone_ii:nnnnnnnn #1
   }
 }
\cs_generate_variant:Nn \__nebu_phone_eight:n { V }

\cs_new:Nn \__nebu_phone_iii_ii_iii:nnnnnnnn { #1#2#3\hspace{1ex}#4#5\hspace{1ex}#6#7#8 }
\cs_new:Nn \__nebu_phone_ii:nnnnnnnn { #1#2\hspace{0.6666ex}#3#4\hspace{0.6666ex}#5#6\hspace{0.6666ex}#7#8 }

\ExplSyntaxOff

% https://tex.stackexchange.com/a/504129/8306
%
% This creates the backbone for the frontpage. One can add new keys here
\makeatletter
  % Provide commands.
  \ExplSyntaxOn
    % Provide keys.
    \keys_define:nn { babylonia }
      {
        contact       .tl_set:N  = \@contact,
        mobile        .tl_set:N  = \@mobile,
        mobile        .initial:n = {\expandMacro{\contactInfo{\@contact}{mobile}}},
        phone         .tl_set:N  = \@phone,
        phone         .initial:n = {\expandMacro{\contactInfo{\@contact}{phone}}},
      }
    % Provide key setting command.
    \NewDocumentCommand\FrontpageUiTsetup{ m }{
      \keys_set:nn { babylonia } { #1 }
    }
  \ExplSyntaxOff
  % Provide names.
  \newcommand*\contactname{Contact}
  \newcommand*\contactmobile{Mobile}
  \newcommand*\contactphone{Phone}
  % The typesetting command.
  \newcommand\FrontpageUiT{%

    \noindent
    \begin{tabular}{p{0.2\textwidth} p{\dimexpr 0.8\textwidth - 4\tabcolsep}}

      \ifx\@contact\@empty\else
        \contactname & \expandMacro{\contactInfo{\@contact}{name}}\\%
      \fi

      \ifx\@mobile\@empty\else
        \contactmobile & \@mobile\\%
      \fi

      \ifx\@phone\@empty\else
        \contactphone & \@phone\\%
      \fi

    \end{tabular}%
  }
\makeatother

% ==============================================================================
%   User interface below here
% ==============================================================================

% This adds contacts to be used in the UiT frontpage
% Example:
%
% \defineInfo{joe}{
%   name=Joe Doe, mobile=32132132, phone=93123123,
% }

\defineInfo{jane}{
  name=Jane Doe, 
  phone=75123123,
}

\FrontpageUiTsetup{
  contact = jane,
}

\begin{document}

\FrontpageUiT

\end{document}

Respuesta1

Agregue dos comandos, uno para probar la presencia de una propiedad y el otro para componer la información.

\NewExpandableDocumentCommand{\contactTestTF}{mmmm}
 {% #1 = contact, #2 = property to test, #3 = code for true, #4 = code for false
  \prop_if_in:cnTF { \__nebu_contact_prop:n { #1 } } { #2 } { #3 } { #4 }
 }
\NewDocumentCommand{\FrontpageUiTsetup}{m}
 {
  \begin{tabular}{@{} l l @{}}
  \contactname & \contactInfo{#1}{name} \\
  \contactTestTF{#1}{mobile}{\mobilename & \contactInfo{#1}{mobile} \\}{}
  \contactTestTF{#1}{phone}{\phonename & \contactInfo{#1}{phone} \\}{}
  \end{tabular}
 }

Ejemplo completo:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\defineInfo}{mm}
 {
  \prop_new:c { \__nebu_contact_prop:n { #1 } }
  \prop_gset_from_keyval:cn { \__nebu_contact_prop:n { #1 } } { #2 }
 }
\NewExpandableDocumentCommand{\contactInfo}{mm}
 {
  \str_case:nnF { #2 }
   {
    {phone}  { \nebu_phone:e { \prop_item:cn { \__nebu_contact_prop:n { #1 } } { #2 } } }
    {mobile} { \nebu_phone:e { \prop_item:cn { \__nebu_contact_prop:n { #1 } } { #2 } } }
   }
   { \prop_item:cn { \__nebu_contact_prop:n { #1 } } { #2 } }
 }
\NewExpandableDocumentCommand{\contactTestTF}{mmmm}
 {% #1 = contact, #2 = property to test, #3 = code for true, #4 = code for false
  \prop_if_in:cnTF { \__nebu_contact_prop:n { #1 } } { #2 } { #3 } { #4 }
 }
\NewDocumentCommand{\FrontpageUiTsetup}{m}
 {
  \begin{tabular}{@{} l l @{}}
  \contactname & \contactInfo{#1}{name} \\
  \contactTestTF{#1}{mobile}{\mobilename & \contactInfo{#1}{mobile} \\}{}
  \contactTestTF{#1}{phone}{\phonename & \contactInfo{#1}{phone} \\}{}
  \end{tabular}
 }

% syntactic sugar
\cs_new:Nn \__nebu_contact_prop:n
 {
  g_nebu_contact_\str_lowercase:n { #1 }_prop
 }

%%% formatting phone numbers
\NewDocumentCommand{\phone}{m}
 {
  \nebu_phone:n { #1 }
 }

\tl_new:N \l__nebu_phone_tl

\cs_new_protected:Nn \nebu_phone:n
 {
  \tl_set:Nn \l__nebu_phone_tl { #1 }
  \tl_remove_all:Nn \l__nebu_phone_tl { ~ }
  \int_compare:nTF { \tl_count:N \l__nebu_phone_tl = 8 }
   {
    \__nebu_phone_eight:V \l__nebu_phone_tl
   }
   {
    \tl_use:N \l__nebu_phone_tl
   }
 }
\cs_generate_variant:Nn \nebu_phone:n { e }

\cs_new:Nn \__nebu_phone_eight:n
 {
  \str_case_e:nnF { \tl_head:n { #1 } }
   {
    {4}{ \__nebu_phone_iii_ii_iii:nnnnnnnn #1 }
    {8}{ \__nebu_phone_iii_ii_iii:nnnnnnnn #1 }
    {9}{ \__nebu_phone_iii_ii_iii:nnnnnnnn #1 }
   }
   {
    \__nebu_phone_ii:nnnnnnnn #1
   }
 }
\cs_generate_variant:Nn \__nebu_phone_eight:n { V }

\cs_new:Nn \__nebu_phone_iii_ii_iii:nnnnnnnn { #1#2#3\nobreakspace#4#5\nobreakspace#6#7#8 }
\cs_new:Nn \__nebu_phone_ii:nnnnnnnn { #1#2\nobreakspace#3#4\nobreakspace#5#6\nobreakspace#7#8 }
\ExplSyntaxOff

\newcommand{\contactname}{Contact}
\newcommand{\mobilename}{Mobile}
\newcommand{\phonename}{Phone}

\defineInfo{jane}{
  name=Jane Doe,
  mobile=32132132,
  phone=45123123,
}
\defineInfo{joe}{
  name=Joe Doe,
  %mobile=32132132,
  phone=93123123,
}
\defineInfo{richard}{
  name=Richard Roe,
  mobile=32132132,
  phone=83123123,
}

\begin{document}

\contactInfo{Jane}{name} has \contactInfo{jane}{mobile} mobile phone.

\contactInfo{riCHard}{phone} is \contactInfo{Richard}{name}'s phone.

\bigskip

\FrontpageUiTsetup{jane}

\bigskip

\FrontpageUiTsetup{joe}

\end{document}

ingrese la descripción de la imagen aquí

información relacionada