Introdução
Sinto muito pelo longo MWE, mas não consegui encurtá-lo e ainda ilustrar meu problema. Mais uma vez estou trabalhando para agilizar a criação de exames para minha universidade. No exemplo abaixo o usuário pode adicionar mais palestras usando
\defineInfo{jane}{
name=Jane Doe,
phone=75123123,
}
(Onde obtive ajuda para criar a sintaxe emLista de contatos como dicionário) Adicione informações sobre o exame usando
\FrontpageUiTsetup{
contact = jane,
}
(Agora com a ajuda deParâmetros de entrada rotulados) Onde o último comando, claro, tem muito mais parâmetros, irrelevantes para a minha pergunta. Agora, quero combinar essas duas respostas, para que possa consultar um palestrante usando um ID e, em seguida, imprimir as partes relevantes no formato \FrontpageUiT
.
Eu primeiro tentei escrever
\ifx\@contact\@empty\else
\contactname & \contactInfo{\@contact}{name}\\%
\fi
No entanto, parece que o \contactInfo
comando se expande antes \@contact
e não produz nada. Depois de pesquisar um pouco no Google, consegui usar o seguinte para expandir \@contact
primeiro
\newcommand{\expandMacro}[1]{
\begingroup\edef\x{\endgroup
\noexpand#1%
}\x
}
Problema
Então aí vem o meu problema:
- Quero que o valor padrão de @phone e @mobile seja definido respectivamente pelas linhas
\contactInfo{\@contact}{mobile}
e\contactInfo{\@contact}{phone}
O problema surge quando eu quero a linha
\contactmobile & \@mobile
Ficar em branco quando nenhum número de celular for fornecido. Exemplo:
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 não tem número de celular, espero que o resultado seja
Contact Jane Doe
Phone 75 12 31 23
Em vez disso, estou diante de
Contact Jane Doe
Mobile
Phone 75 12 31 23
O problema é que o código não consegue se expandir \contactInfo{\@contact}{mobile}
rápido o suficiente para perceber que está vazio. Depois de pesquisar um pouco mais no Google, descobri
\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%
}
Isso pode detectar se a saída está em branco. Porém, ele não suporta E comercial (&), portanto não posso utilizá-lo em minha tabela. POR EXEMPLO
\IfNoText{\@mobile}{}{Mobile & \@mobile \\}
me lança um erro. Também tentei usar \IfNoText
anteriormente em meu documento para definir alternâncias que se expandem para verdadeiro ou falso com base no conteúdo de \@mobile
. No entanto, estes também não se expandiram suficientemente rápido.
- Existe uma maneira de verificar isso
\@mobile
e@phone
fica vazio mais rápido, quando são dados nos termos 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}
Responder1
Adicione dois comandos, um para testar a presença de uma propriedade e outro para compor as informações.
\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}
}
Exemplo 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}