介绍

介绍

介绍

很抱歉 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}

在此处输入图片描述

相关内容