介绍
很抱歉 MWE 太长了,但我无法缩短它并仍然说明我的问题。我再次致力于简化我大学的考试创建。在下面的示例中,用户可以使用以下方式添加更多讲座
\defineInfo{jane}{
name=Jane Doe,
phone=75123123,
}
(我在哪里获得帮助创建语法联系人列表作为字典)使用
\FrontpageUiTsetup{
contact = jane,
}
(现在有了标记的输入参数) 其中最后一个命令当然有更多参数,与我的问题无关。现在,我想将这两个答案结合起来,这样我就可以使用 ID 来引用讲师,然后在 中打印相关部分\FrontpageUiT
。
我第一次尝试写作
\ifx\@contact\@empty\else
\contactname & \contactInfo{\@contact}{name}\\%
\fi
但是,该命令似乎\contactInfo
先展开,\@contact
所以它什么都没输出。经过一番谷歌搜索,我能够\@contact
先使用以下命令进行展开
\newcommand{\expandMacro}[1]{
\begingroup\edef\x{\endgroup
\noexpand#1%
}\x
}
问题
所以我的问题来了:
\contactInfo{\@contact}{mobile}
我希望 @phone 和 @mobile 的默认值分别由以下行和定义\contactInfo{\@contact}{phone}
问题出现在我想要的那条线
\contactmobile & \@mobile
未提供手机号码时为空白。例如:
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}
由于 Jane 没有手机号码,我预计输出为
Contact Jane Doe
Phone 75 12 31 23
相反,我面临的是
Contact Jane Doe
Mobile
Phone 75 12 31 23
问题是代码无法\contactInfo{\@contact}{mobile}
快速扩展,无法意识到它是空的。经过一番谷歌搜索,我发现
\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%
}
这可以检测输出是否为空白。但是,它不支持与号 (&),因此我无法在我的表中使用它。例如
\IfNoText{\@mobile}{}{Mobile & \@mobile \\}
抛出错误。我\IfNoText
之前也尝试过使用 来定义根据 的内容扩展为 true 或 false 的切换\@mobile
。但是,这些扩展速度也不够快。
- 当给出和的条款时,有没有办法更快地检查
\@mobile
和是否为空?@phone
\contactInfo
代码
\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}
答案1
添加两个命令,一个用于测试属性的存在,另一个用于排版信息。
\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}
}
完整示例:
\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}