当当前帧需要展示一些相似的内容(暂以node为例),在水平方向上:
请问,如何简化代码,使得可以方便地指定被放置的内容的数量、位置和内容?
% pdflatex 编译两次
\documentclass[draft]{beamer}
\usepackage{tikz}
%\usepackage{showframe}
\begin{document}
\begin{frame}
\centering%
\tikz[every node/.style={draw,dotted,inner sep=1cm}]{
\node at (.5\linewidth,0) {A};
}
\tikz[every node/.style={draw,dotted,inner sep=1cm}]{
\node at (.33\linewidth,0) {A};
\node at (.66\linewidth,0) {B};
}
\tikz[every node/.style={draw,dotted,inner sep=1cm}]{
\node at (.25\linewidth,0) {A};
\node at ( .5\linewidth,0) {B};
\node at (.75\linewidth,0) {C};
}
\tikz[every node/.style={draw,dotted,inner sep=1cm}]{
\node at (.2\linewidth,0) {A};
\node at (.4\linewidth,0) {B};
\node at (.6\linewidth,0) {C};
\node at (.8\linewidth,0) {D};%...
}
\end{frame}
\end{document}
无非就是堆盒子嘛,不需要用 tikz
这种大杀器的, 也不需要用 l3coffin
之类的东西,虽然用这两个更加的简单. 代码如下:
\documentclass{article}
\usepackage[showframe, textwidth=18cm]{geometry}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{lipsum}
\ExplSyntaxOn\makeatletter
\cs_set_protected:Npn \__item_align:nnn #1#2#3
{% #1:cmd, #2:width, #3:object
\hb@xt@#2{
\tl_map_inline:nn {#3}
{
\seq_put_right:No \l_tmpa_seq {\exp_not:N #1{##1}}
}
\edef\seq@count{\seq_count:N \l_tmpa_seq}
\seq_map_inline:Nn \l_tmpa_seq
{
\edef\item@width{\dim_eval:n {#2/(\seq@count+1)}}
\hskip\item@width\clap{##1}
}\hskip\item@width\hss
}
}
\NewDocumentCommand\itemAlign{O{}mm}
{
\__item_align:nnn {#1}{#2}{#3}
}
\makeatother\ExplSyntaxOff
\parindent0pt
\begin{document}
\itemAlign{\linewidth}{A}\par
\itemAlign{\linewidth}{AA}\par
\itemAlign{\linewidth}{{(A)}{(A)}{(A)}}\par
\vskip6em
\dotfill\par
\def\imageA{\includegraphics[width=5em]{example-image-a}}
\def\imageB{\includegraphics[width=5em]{example-image-b}}
\itemAlign{\linewidth}{\imageA}\par
\itemAlign{\linewidth}{\imageA\imageA}\par
\itemAlign{\linewidth}{\imageB\imageB\imageB}\par
\itemAlign{\linewidth}{\imageB\imageB\imageB\imageB}
\vskip6em
\dotfill\par
\def\parA{\parbox[c]{12em}{\lipsum[1][1-2]}}
\def\parB{\parbox[c]{12em}{\lipsum[1][3-5]}}
\itemAlign[\sffamily]{\linewidth}{\parA}\par
\itemAlign[\color{red}]{\linewidth}{\parA\parA}\par
\itemAlign[\fbox]{\linewidth}{\parB\parB\parB}
\end{document}
编译结果如下:
注意事项:
\itemAlign
第二个参数中对象的分割方式,可以把 \tl_map_inline:nn
换为 \clist_map_inline:nn
之类的函数.\␣
或 ~
替代.似乎有很明显的循环结构呀🧐
\documentclass{beamer}
\usepackage{tikz}
\makeatletter
\newcommand{\Letter}[1]{\@Alph{#1}}
\makeatother
\newcommand{\myplot}[1]{
\foreach \i[evaluate=\i as \j using (\i/(1+#1))] in {1,...,#1} {
\node[minimum size=2cm,font=\tiny,align=center] at (\j\linewidth,0) {\Letter{\i}\\(\j,0)};
}
}
\begin{document}
\tikzset{every node/.style={draw,dotted,inner sep=.5cm}}
\begin{frame}
\centering%
\tikz{\myplot{1}}\medskip
\tikz{\myplot{2}}\medskip
\tikz{\myplot{3}}\medskip
\tikz{\myplot{4}}\medskip
\end{frame}
\begin{frame}
\centering%
\foreach \x in {4,...,1}{%
\tikz{\myplot{\x}}\par\medskip
}
\end{frame}
\end{document}
node里的内容通常是写一大段不相同的文字,怎么循环?
也许用clist
会挺方便(?)可以自己设计一下syntax(例如\mydraw{C,A,V,X}
)
我自己写的时候没注意到\centering
的重要作用😡,怀疑人生了好一会儿...
\documentclass{beamer}
\usepackage{tikz}
\begin{document}
\tikzset{every node/.style={draw,dotted,inner sep=.5pt}}
\ExplSyntaxOn
\NewDocumentCommand{\mydraw}{m}{%
\clist_set:Nn \l_tmpa_clist {#1}
% \clist_use:Nn \l_tmpa_clist {;} \par
\int_set:Nn \l_tmpa_int { \clist_count:N \l_tmpa_clist }
\begin{tikzpicture}
\foreach \i in {1,...,\l_tmpa_int} {%
\def\j{\fpeval{round(\i/(1+\l_tmpa_int),4)}}% texdoc xfp
\node[minimum~size=1.5cm,font=\tiny,align=center] at (\j\textwidth,0) {(\j)\\ \clist_item:Nn \l_tmpa_clist {\i}};
}
\end{tikzpicture}
}
\ExplSyntaxOff
\begin{frame}
\centering%
\mydraw{ahahaha,123456,1aaa2,{some~text,hia\\hiahia},kkk}\medskip
\mydraw{I~am~A,You~are~B,He~is~C}\medskip
\mydraw{C,A,B,F,E,H,G}\medskip
\end{frame}
\end{document}
node里的内容通常是写一大段不相同的文字,怎么循环?
@u101077 唔,作为参数传入叭(我晚点再改改,原问题中的ABCD感觉有迷糊性
@u101077 emm你能否提供一个你预期的命令语法(syntax)样式,例如
实现自动按照个数(这里是4),『被放置在版心宽度五等分的位置上...』
@u70550 您提出的这个就挺不错的,按照键的个数分配数量和安排位置,并根据键安置在对应位置上
@u101077 做了补充😊