介紹
我對冗長的 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
}
問題
所以我的問題來了:
- 我希望 @phone 和 @mobile 的預設值分別由行
\contactInfo{\@contact}{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}