我正在使用tabularx
和建立一个画廊tikz
,类似于image-gallery
。以下是片段:
\documentclass{article}
\usepackage{tikz}
\usepackage{tabularx}
\begin{document}
\begin{tabularx}{\textwidth}{@{} *4{>{\centering\arraybackslash}X}@{}}
\begin{tikzpicture}
\node{\includegraphics[width=2cm]{kitty}};
\end{tikzpicture}
& & & \\
Mr. Whiskas
& & & \\
\textbf{Programmer}
& & & \\
\end{tabularx}
\end{document}
结果:
由于这是使用表格完成的,因此用户手动插入每个成员有点烦人。如果有任何更改,则必须相应地更改每一行,当图库很大时,这很烦人。
我想将此代码片段包装在新环境(或命令)中,以便用户更轻松地插入和移动成员(我也利用这个机会学习一些 Latex 编程)。我想到的是这样的:
\begin{gallery}
\member{Mr. Whiskas}{\textbf{Programmer}}{image/path/kitty}
\member{Catalie Portman}{\textbf{CEO}}{image/path/kitty2}
\end{gallery}
但是,我对 Latex 编程有点迷茫。希望有人能给我一些指点。
问题:
这是
\newenvironment
最好的做法吗?或者我应该使用\newcommand
?我认为存储数据的方式是使用元组列表(或结构/对象)。如何在 Latex 中将这些结构化数据存储在列表中,然后首先遍历姓名,然后遍历职业,以填充每一行
tabularx
?
尽管我问的是怎样制作“结构列表”,但我实际上想知道更符合 latexian 的做法,即使不使用我提到的抽象。
如果有人能给我指出一个以类似方式执行某些操作且初学者可以掌握的源代码,那就太好了。
答复范围:答案不需要提供此环境的实现(正如我所说,我想自己做)。我想要的是我应该使用什么的指针,以及如何制作基本的东西,例如循环遍历元组/结构列表。
答案1
我认为没有必要使用tabularx
或tikz
除 之外的任何其他东西graphicx
。没有任何环境的简单宏即使名称、标题和照片形状不一致也可以很好地管理:
(当然,如果你用真实用户图像测试这个MWE,请删除angle=90,
宏中的“ ”)
\documentclass[a4paper]{article}
\usepackage{graphicx}
\newcommand\member[3][example-image-empty]{%
\noindent\parbox[t]{.245\linewidth}{\centering%
\includegraphics[angle=90,width=.6\linewidth,height=.8\linewidth,
keepaspectratio]{#1}\par#2\par\bfseries#3\bigskip}%
\hspace{10pt minus 10pt}}
\begin{document}
\member[example-image-a]{Mr. Whiskas}{Programmer}
\member[example-image-b]{Catherine of Aragon}{Queen of England and Princess of Wales}
\member[example-image-c]{Tomás de Zumalacárregui e Imaz}{General}
\member[example-image]{Dr. Whatson}{Detective Assistant}
\member[example-image-1x1]{Dr. Pigmy}{A short guy}%
\member[example-image-16x9]{Dr. Slender}{A tall guy}%
\member[example-image-16x10]{Mr. Pau Gasol}{Basketball player}%
\member[example-image-4x3]{Mr. John Doe}{Homeless}%
\member[example-image]{Mr. Thompson}{Police}
\member[example-image]{Mr. Thomson}{Police}
\member{next\ldots}{}
\member{}{}
\end{document}
答案2
以下是您环境的未完成实施。您必须解决包含 4 个以上元素的问题。
用于实现类似列表的宏是\appendto
,它采用应充当列表的宏的名称(并且此时必须已经定义)并\q@mark
在其中添加标记以分隔元素(永远不应完全展开,因为这会导致无限循环 - 也是一样\q@stop
)。另一个是\printlist
接受 3 个参数的宏。第一个可以是格式化参数。列表的每个元素都将作为参数提供给 的第一个参数\printlist
。第二个是应插入每个元素之间的分隔符(但不是在最后一个元素之后)。第三个参数是列表宏。
这种列表的实现不依赖于任何包,但相当原始。我希望这不会让您因为自己无法完成而拖延,但您不必使用此实现。
如果您需要对代码的任何解释,请随时询问。
\documentclass[]{article}
\usepackage{tabularx}
\usepackage[]{graphicx}
\makeatletter
%% primitive implementation of lists
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\q@mark{\q@mark}
\def\q@stop{\q@stop}
\long\def\afterfi#1\fi{\fi#1}
\newcommand\appendto[2]
{%
\edef#1{\unexpanded\expandafter{#1#2\q@mark}}%
}
\newcommand*\printlist[3]
{%
\expandafter\printlist@i\expandafter{#3}{#1}{#2}%
}
\newcommand*\printlist@i[3]
{%
\if\relax\detokenize{#1}\relax
\else
\afterfi
{\printlist@ii{#2}{#3}#1\q@stop}%
\fi
}
\long\def\printlist@ii#1#2#3\q@mark#4%
{%
\if\relax\detokenize{#3}\relax
\else
\afterfi
{#1{#3}}%
\fi
\ifx\q@stop#4%
\else
\afterfi
% Tricky bit here, `&` is not allowed as argument of \afterfi for some
% reason, so I have to hide it. The braces are stripped here because it's
% the only group/token between \afterfi and \fi.
{#2\printlist@ii{#1}{#2}#4}%
\fi
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% basic implementation of your environment
\newcommand\member[3]
{%
\appendto\memberlist@name{#1}%
\appendto\memberlist@desc{#2}%
\appendto\memberlist@file{#3}%
}
\newcommand*\printmemberlist@file
{%
\printlist\memberlist@file@format&\memberlist@file
}
\newcommand*\printmemberlist@name
{%
\printlist\memberlist@name@format&\memberlist@name
}
\newcommand*\printmemberlist@desc
{%
\printlist\memberlist@desc@format&\memberlist@desc
}
\newcommand\memberlist@file@format[1]
{%
\includegraphics[width=2cm]{#1}%
}
\newcommand\memberlist@name@format[1]
{%
#1%
}
\newcommand\memberlist@desc@format[1]
{%
\textbf{#1}%
}
\newenvironment{gallery}
{%
\def\memberlist@name{}%
\def\memberlist@desc{}%
\def\memberlist@file{}%
}
{%
\begin{tabularx}{\textwidth}{ @{} *4{>{\centering\arraybackslash}X} @{} }
\printmemberlist@file \\
\printmemberlist@name \\
\printmemberlist@desc
\end{tabularx}
}
\makeatother
\begin{document}
\noindent
\begin{gallery}
\member{Mr. Whiskas}{Programmer}{example-image}
\member{Catalie Portman}{CEO}{example-image-a}
\member{Ducktective M.}{Detective}{example-image-duck}
\member{Anne Example}{Person}{example-image-b}
\end{gallery}
\end{document}
忘记发布结果: