我正在使用宏来制作我的数字
\newcommand{\figureone}[3]{%
\begin{figure*}%
\centering
\ifx&\includegraphics{#1}\else\includegraphics[width=#3\textwidth]{#1}\fi
\caption{#2}
\label{fig:#1}
\end{figure*}
}
并使用相同的宏来center
代替,figure*
因为在某些情况下我不想要浮点数。
我想避免重复代码,因为在现实世界中我有几个这样的用于图形的宏。
那么,有没有办法使用figure*
或center
从原型宏?
答案1
你可以通过宏来制作宏。我将修改你的模板宏,让第三个参数成为可选参数,这样你就可以调用,
\figureone{file.png}{This is the caption}[0.3]
或者
\figureone{file.png}{This is the caption}
因此让我们调用我们的宏定义宏\newfigure
,它将接受两个参数:要定义的宏的名称和环境的名称(顺便说一下,我xparse
在这里假设。如果您的 LaTeX 是最新的,它将在内核中,但如果不是,您需要添加\usepackage{xparse}
以加载它)。
\NewDocumentCommand{\newfigure}{ m m }{%
\newfigure
,反过来会执行其自己的\NewDocumentCommand
定义新图形的命令:
\NewDocumentCommand{#1}{ m m o }{%
\begin{#2}%
\centering
嗯,我们如何让 LaTeX 知道在这个定义中的定义中,我们想要的是定义中的参数,而不是传递给的参数\newfigure
?在本例中,我们将 翻倍,#
让 LaTeX 知道这些属于内部定义。¹ , ² 因此我们可以将您的\ifx
...重写\fi
为:
\IfNoValueTF {##3}
{\includegraphics{##1}}
{\includegraphics[width=##3\textwidth]{#1}}
并且您的标题和标签为
\caption{##2}
\label{fig:##1}
然后完成定义:
\end{#2}
}
如果在宏定义中再嵌套一个宏定义,那么你又会加倍——
####1
。我不确定这种疯狂的嵌套深度——我从未探究过,但浏览的内容tex-live/**
我发现深度有 5 层(32#
秒!)。我个人最喜欢的搜索字符串是\def####1########1##1########2
它定义了一个双参数命令,使用第三级宏的第一个参数作为名称,使用第二级宏的第一个参数作为两个参数之间的分隔符。这也适用于
#
内部原语\halign
或的模板\valign
。如果您不熟悉这些命令,请忽略此脚注。
答案2
如果环境的名称和生成标题的方式是宏之间唯一需要改变的东西,则使用原型宏时只需将参数上移两个,并将环境名称作为原型宏的第一个参数,将所需的\caption
/ \captionof
/\@gobble
命令作为原型宏的第二个参数。
然后定义其他宏来调用原型宏,并提供第一个参数(环境名称)和第二个参数(\caption
/ \captionof
/ \@gobble
-命令),这样原型宏的后续三个参数将不会来自其他宏的定义,而是在执行其他宏时收集。
\documentclass{article}
\usepackage{graphicx}
\usepackage{capt-of}
\newcommand{\PrototypeThing}[5]{%
\begin{#1}%
\centering
\ifx&\includegraphics{#3}\else\includegraphics[{width=#5\textwidth}]{#3}\fi
#2{#4}%
\label{fig:#3}%
\end{#1}%
}%
\newcommand*{\figureone}{\PrototypeThing{figure*}{\caption}}
\newcommand*{\centerone}{\PrototypeThing{center}{\captionof{figure}}}
\begin{document}
\listoffigures
\figureone{example-image-a.jpg}{caption}{1}
\centerone{example-image-b.jpg}{caption}{.3}
\end{document}
\figureone
产量:
\PrototypeThing{figure*}{\caption}
。
因此
\figureone{⟨fileNlabel⟩}{⟨caption⟩}{⟨width⟩}
产量:。
\PrototypeThing{figure*}{\caption}{⟨fileNlabel⟩}{⟨caption⟩}{⟨width⟩}
\PrototypeThing{figure*}{\caption}{⟨fileNlabel⟩}{⟨caption⟩}{⟨width⟩}
反过来得到:
\begin{figure*}%
\centering
\ifx&⟨width⟩&\includegraphics{⟨fileNlabel⟩}\else\includegraphics[{width=⟨width⟩\textwidth}]{⟨fileNlabel⟩}\fi
\caption{⟨caption⟩}%
\label{fig:⟨fileNlabel⟩}%
\end{figure*}%
\centerone
产量:
\PrototypeThing{center}{\captionof{figure}}
。
因此
\centerone{⟨fileNlabel⟩}{⟨caption⟩}{⟨width⟩}
产量:。
\PrototypeThing{center}{\captionof{figure}}{⟨fileNlabel⟩}{⟨caption⟩}{⟨width⟩}
\PrototypeThing{center}{\captionof{figure}}{⟨fileNlabel⟩}{⟨caption⟩}{⟨width⟩}
反过来得到:
\begin{center}%
\centering
\ifx&⟨width⟩&\includegraphics{⟨fileNlabel⟩}\else\includegraphics[{width=#5\textwidth}]{⟨fileNlabel⟩}\fi
\captionof{figure}{⟨caption⟩}%
\label{fig:⟨fileNlabel⟩}%
\end{center}%
使用 xparse 你可以⟨宽度⟩-参数可选:
\documentclass{article}
\usepackage{graphicx}
\usepackage{capt-of}
\NewDocumentCommand{\PrototypeThing}{mmmmo}{%
\begin{#1}%
\centering
\IfNoValueTF{#5}{\includegraphics}{\includegraphics[{width=#5\textwidth}]}{#3}%
#2{#4}%
\label{fig:#3}%
\end{#1}%
}%
\newcommand*{\figureone}{\PrototypeThing{figure*}{\caption}}
\newcommand*{\centerone}{\PrototypeThing{center}{\captionof{figure}}}
\begin{document}
\listoffigures
\noindent\figureone{example-image-a.jpg}{figureonecaption}[1]
\noindent\centerone{example-image-b.jpg}{centeronecaption}[.3]
\end{document}
\figureone
产量:
\PrototypeThing{figure*}{\caption}
。
因此
\figureone{⟨fileNlabel⟩}{⟨caption⟩}[⟨width⟩]
产量:。
\PrototypeThing{figure*}{\caption}{⟨fileNlabel⟩}{⟨caption⟩}[⟨width⟩]
\PrototypeThing{figure*}{\caption}{⟨fileNlabel⟩}{⟨caption⟩}[⟨width⟩]
反过来得到:
\begin{figure*}%
\centering
\IfNoValueTF{⟨width⟩}{\includegraphics}{\includegraphics[{width=⟨width⟩\textwidth}]}{⟨fileNlabel⟩}%
\caption{⟨caption⟩}%
\label{fig:⟨fileNlabel⟩}%
\end{figure*}%
\centerone
产量:
\PrototypeThing{center}{\captionof{figure}}
。
因此
\centerone{⟨fileNlabel⟩}{⟨caption⟩}[⟨width⟩]
产量:。
\PrototypeThing{center}{\captionof{figure}}{⟨fileNlabel⟩}{⟨caption⟩}[⟨width⟩]
\PrototypeThing{center}{\captionof{figure}}{⟨fileNlabel⟩}{⟨caption⟩}[⟨width⟩]
反过来得到:
\begin{center}%
\centering
\IfNoValueTF{⟨width⟩}{\includegraphics}{\includegraphics[{width=⟨width⟩\textwidth}]}{⟨fileNlabel⟩}%
\captionof{figure}{⟨caption⟩}%
\label{fig:⟨fileNlabel⟩}%
\end{center}%
答案3
我不确定使用这种不灵活的方法是否能获得很多好处。例如,的可选参数怎么样\caption
?其他选项怎么样\includegraphics
(例如,考虑修剪)?
我们可以按如下方式避免大部分代码重复,同时支持我提到的选项。但我不认为这真的有用。
\NewDocumentCommand{\figureone}{sO{}mO{#5}mo}{%
% start: if *-version, center
\IfBooleanTF{#1}{\begin{center}}{\begin{figure*}\centering}%
\IfValueTF{#6}{%
% a fraction is specified
\includegraphics[width=#6\textwidth,#2]{#3}%
}{%
\includegraphics[#2]{#3}%
}%
\IfBooleanTF{#1}{\captionof{figure}}{\caption}[#4]{#5}%
\label{#3}%
\IfBooleanTF{#1}{\end{center}}{\end{figure*}}%
}
完整示例
\documentclass[twocolumn]{article}
\usepackage{graphicx,capt-of}
\usepackage{lipsum}
\NewDocumentCommand{\figureone}{sO{}mO{#5}mo}{%
% start: if *-version, center
\IfBooleanTF{#1}{\begin{center}}{\begin{figure*}\centering}%
\IfValueTF{#6}{%
% a fraction is specified
\includegraphics[width=#6\textwidth,#2]{#3}%
}{%
\includegraphics[#2]{#3}%
}%
\IfBooleanTF{#1}{\captionof{figure}}{\caption}[#4]{#5}%
\label{#3}%
\IfBooleanTF{#1}{\end{center}}{\end{figure*}}%
}
\begin{document}
\listoffigures
\lipsum[1][1-2]
\figureone*{example-image}{Figure in the column}[0.4]
\lipsum[1][1-2]
\figureone*{example-image-a}[Short caption]{Long caption}[0.4]
\lipsum[1][1-2]
\figureone*[trim=20 20 20 20,clip]{example-image-b}{Trimmed}[0.4]
\lipsum[1][1-2]
\figureone{example-image-c}{Figure in the column}
\lipsum[1][1-2]
\figureone{example-image-16x9}[Short caption]{Long caption}[0.8]
\lipsum[1][1-2]
\figureone[trim=20 20 20 20,clip]{example-image-1x1}{Trimmed}[0.8]
\lipsum[1][1-2]
\end{document}
答案4
在您对我的第一个回答的评论中,您添加了一个应该在最初的问题中已经提到的方面:打破九个参数的限制:
[...] 问题是,我的一些现实世界的宏需要 4-5 个原型参数和 8 个或更多最终宏参数,所以我总共需要 9 个以上的参数,[...]
我不喜欢宏接受很多参数:参数越多,错误地按错误顺序输入参数的机会就越多。这对用户来说很不友好。
因此,我仅将此视为一件“学术”的事情——请求了解如何做这样的事情,只是为了获得知识和挑战,尽管人们不会在日常使用中实现这样的事情。
只要所有“参数”都是强制性的无界参数我提出两块“基石”:
积木1:
拥有\romannumeral
扩张驱动的“宏观机制”
\CollectLArgs{⟨TeX-⟨number⟩-quantity of value L⟩}{⟨Argument 1⟩}{⟨Argument 2⟩}...{⟨Argument L⟩}
得出的结果是:
{{⟨Argument 1⟩}{⟨Argument 2⟩}...{⟨Argument L⟩}}
,即将 L 个未分隔参数序列包装成一个参数,然后该参数包含/由 L 个未分隔参数的列表组成。
(对于由扩展驱动的宏机制,\romannumeral
您需要恰好两个扩展步骤/两次“命中”\expandafter
才能获得结果。)
积木2:
拥有\romannumeral
扩张驱动的“宏观机制”
\ExtractKthArg{⟨TeX-⟨number⟩-quantity of value K⟩}%
{⟨tokens in case list of undelimited arguments doesn't have a Kth argument⟩}%
{⟨list of undelimited arguments⟩}%
其工作原理如下:
如果⟨无界参数列表⟩:
是否提供⟨如果未限定参数列表没有第 K 个参数,则使用 tokens⟩。
如果⟨无界参数列表⟩:
传递第 K 个参数,但删除了一层括号。
(对于由扩展驱动的宏机制,\romannumeral
您需要恰好两个扩展步骤/两次“命中”\expandafter
才能获得结果。)
你可以使用这两块“积木”用于定义一个通用宏机制,该机制处理一定数量的 L 个参数,其中 L>9 是可能的,这些 L 个参数中的第一个参数是那些需要为非通用宏/用户级宏更改默认值的参数:
通用宏机制由一个通用顶层宏组成,该宏通过\expandafter
-trickery 调用\CollectLArgs
传递给通用内部宏,该内部宏只处理一个参数,L 个参数转换为包含 L 个未限定参数列表的单个未限定参数。
这样,通用内部宏的参数就是 L 个未限定参数的列表,您可以通过从中提取您喜欢/需要的任何参数\ExtractKthArg
。
在下面的例子中,\ExtractKthArg
需要两个扩展步骤/两次“命中”才能\expandafter
产生结果。
假设您希望第 11 个参数 /元素采用打字机字体。
你可以做
\texttt{%
\ExtractKthArg{11}%
{}%
{{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}}%
}%
这种方式 \texttt
将开始发挥作用,并在此进行评估\ExtractKthArg...
,进而实现交付11
。
或者你也可以这样做:
\expandafter\expandafter\expandafter\texttt
\expandafter\expandafter\expandafter{%
\ExtractKthArg{11}%
{}%
{{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}}%
}%
这样,\expandafter
-chain 就会触发执行\ExtractKthArg
前 \texttt
开始工作,您将获得:
\texttt{11}%
对于这两个代码片段,扩展/执行顺序的差异并不重要——最终结果是相同的。
但通常扩展发生和获得令牌的时间顺序很重要。
让我们创建一个示例,其中实现并用于定义处理\PrototypeThing
17 个参数的函数,前两个参数是默认值,将在用户级宏的定义文本中提供,后面 15 个参数由用户在调用用户级宏时提供 - 这样,用户级宏就需要 15 个参数:
语法是:
\PrototypeThing{⟨environment-name⟩}%
{⟨caption-command⟩}%
{⟨fileNlabel⟩}%
{⟨caption-text⟩}%
{⟨width⟩}%
{⟨Dummy-Argument 1⟩}%
{⟨Dummy-Argument 2⟩}%
{⟨Dummy-Argument 3⟩}%
{⟨Dummy-Argument 4⟩}%
{⟨Dummy-Argument 5⟩}%
{⟨Dummy-Argument 6⟩}%
{⟨Dummy-Argument 7⟩}%
{⟨Dummy-Argument 8⟩}%
{⟨Dummy-Argument 9⟩}%
{⟨Dummy-Argument 10⟩}%
{⟨Dummy-Argument 11⟩}%
{⟨Dummy-Argument 12⟩}%
基于\PrototypeThing
您可以轻松定义用户宏的定义模式
\newcommand⟨Cs-token⟩{%
\PrototypeThing{⟨environment-name⟩}%
{⟨caption-command⟩}%
}%
with 语法
⟨Cs-token⟩{⟨fileNlabel⟩}%
{⟨caption-text⟩}%
{⟨width⟩}%
{⟨Dummy-Argument 1⟩}%
{⟨Dummy-Argument 2⟩}%
{⟨Dummy-Argument 3⟩}%
{⟨Dummy-Argument 4⟩}%
{⟨Dummy-Argument 5⟩}%
{⟨Dummy-Argument 6⟩}%
{⟨Dummy-Argument 7⟩}%
{⟨Dummy-Argument 8⟩}%
{⟨Dummy-Argument 9⟩}%
{⟨Dummy-Argument 10⟩}%
{⟨Dummy-Argument 11⟩}%
{⟨Dummy-Argument 12⟩}%
开始了:
\makeatletter
%%=============================================================================
%% PARAPHERNALIA:
%%\UD@firstoftwo, \UD@secondoftwo, \UD@PassFirstToSecond, \UD@Exchange,
%%\UD@stopromannumeral, \UD@CheckWhetherNull
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@Exchange[2]{#2#1}%
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}{%
\expandafter\UD@stopromannumeral\UD@firstoftwo}%
}%
%%=============================================================================
%% BUILDING-BRICK 1: \CollectLArgs
%%=============================================================================
%% \CollectLArgs{<TeX-<number>-quantity of value L>}%
%% {<Argument 1>}{<Argument 2>}...{<Argument L>}%
%%
%% yields:
%%
%% {{<Argument 1>}{<Argument 2>}...{<Argument L>}}
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps / by "hitting" \CollectLArgs with \expandafter twice.
%%
%%.............................................................................
\newcommand\CollectLArgs[1]{%
\romannumeral
\expandafter\UD@CollectLArgs\expandafter{\romannumeral\number\number#1 000}{}%
}%
\newcommand\UD@CollectLArgs[2]{%
\UD@CheckWhetherNull{#1}{\UD@stopromannumeral{#2}}{\UD@@CollectLArgs{#1}{#2}}%
}%
\newcommand\UD@@CollectLArgs[3]{%
\expandafter\UD@CollectLArgs\expandafter{\UD@firstoftwo{}#1}{#2{#3}}%
}%
%%=============================================================================
%% BUILDING-BRICK 2: \ExtractKthArg
%%=============================================================================
%% \ExtractKthArg{<TeX-<number>-quantity of value K>}%
%% {<tokens in case list of undelimited args doesn't have a k-th argumnent>}%
%% {<list of undelimited args>} %
%%
%% In case there is no K-th argument in <list of undelimited args> :
%% Does deliver <tokens in case list of undelimited args doesn't have a k-th argumnent.
%% In case there is a K-th argument in <list of undelimited args> :
%% Does deliver that K-th argument with one level of braces removed.
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps / by "hitting" \ExtractKthArg with \expandafter twice.
%%
%% Examples:
%%
%% \ExtractKthArg{0}{not available}{ABCDE} yields: not available
%%
%% \ExtractKthArg{3}{not available}{ABCDE} yields: C
%%
%% \ExtractKthArg{3}{not available}{AB{CD}E} yields: CD
%%
%% \ExtractKthArg{4}{not available}{{001}{002}{003}{004}{005}} yields: 004
%%
%% \ExtractKthArg{6}{not available}{{001}{002}{003}} yields: not available
%%=============================================================================
\newcommand\ExtractKthArg[2]{%
\romannumeral
% #1: <integer number K>
% #2: <action if there is no K-th argument>
\expandafter\UD@ExtractKthArgCheck
\expandafter{\romannumeral\number\number#1 000}{#2}%
}%
\newcommand\UD@ExtractKthArgCheck[3]{%
\UD@CheckWhetherNull{#1}{\UD@stopromannumeral#2}{% empty
\expandafter\UD@ExtractKthArgLoop\expandafter{\UD@firstoftwo{}#1}{#2}{#3}%
}%
}%
\begingroup
\def\UD@ExtractFirstArgLoop#1{%
\endgroup
\@ifdefinable\UD@RemoveTillFrozenrelax{%
\long\def\UD@RemoveTillFrozenrelax##1##2#1{{##1}}%
}%
\newcommand\UD@ExtractKthArgLoop[3]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo##3{}.}{\UD@stopromannumeral##2}{%
\UD@CheckWhetherNull{##1}{%
\UD@ExtractFirstArgLoop{##3#1}%
}{%
\expandafter\UD@PassFirstToSecond\expandafter{\UD@firstoftwo{}##3}%
{\expandafter\UD@ExtractKthArgLoop\expandafter{\UD@firstoftwo{}##1}{##2}}%
}%
}%
}%
}%
\expandafter\expandafter\expandafter\UD@ExtractFirstArgLoop
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\ifnum0=0\fi}%
%% Usage of frozen-\relax as delimiter is for speeding things up by reducing the
%% amount of iterations needed. I chose frozen-\relax because David Carlisle
%% pointed out in <https://tex.stackexchange.com/a/578877>
%% that frozen-\relax cannot be (re)defined in terms of \outer and cannot be
%% affected by \uppercase/\lowercase.
%%
%% \UD@ExtractFirstArg's argument may contain frozen-\relax:
%% The only effect is that internally more iterations are needed for
%% obtaining the result.
\newcommand\UD@ExtractFirstArgLoop[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
{\expandafter\UD@stopromannumeral\UD@firstoftwo#1{}}%
{\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillFrozenrelax#1}}%
}%
%%=============================================================================
\makeatother
\documentclass{article}
\usepackage{graphicx}
\usepackage{capt-of}
\makeatletter
\newcommand{\PrototypeThing}{%
\expandafter\expandafter\expandafter\InternalPrototypeThing\CollectLArgs{17}%
}%
\newcommand{\InternalPrototypeThing}[1]{%
\begin{\ExtractKthArg{1}{}{#1}}%
\par\noindent\hrulefill
\par\noindent User macro's 1st argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{3}{}{#1}}%
\par\noindent User macro's 2nd argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{4}{}{#1}}%
\par\noindent User macro's 3rd argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{5}{}{#1}}%
\par\noindent User macro's 4th argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{6}{}{#1}}%
\par\noindent User macro's 5th argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{7}{}{#1}}%
\par\noindent User macro's 6th argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{8}{}{#1}}%
\par\noindent User macro's 7th argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{9}{}{#1}}%
\par\noindent User macro's 8th argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{10}{}{#1}}%
\par\noindent User macro's 9th argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{11}{}{#1}}%
\par\noindent User macro's 10th argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{12}{}{#1}}%
\par\noindent User macro's 11th argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{13}{}{#1}}%
\par\noindent User macro's 12th argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{14}{}{#1}}%
\par\noindent User macro's 13th argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{15}{}{#1}}%
\par\noindent User macro's 14th argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{16}{}{#1}}%
\par\noindent User macro's 15th argument: \detokenize\expandafter\expandafter\expandafter{\ExtractKthArg{17}{}{#1}}%
\par\noindent\hrulefill
\bigskip
\par
\centering
\expandafter\expandafter\expandafter\UD@CheckWhetherNull
\expandafter\expandafter\expandafter{\ExtractKthArg{5}{}{#1}}{%
\includegraphics
}{%
\includegraphics[{width=\ExtractKthArg{5}{}{#1}\textwidth}]%
}{\ExtractKthArg{3}{}{#1}}%
\ExtractKthArg{2}{}{#1}{\ExtractKthArg{4}{}{#1}}%
\label{fig:\ExtractKthArg{3}{}{#1}}%
\par\noindent\hrulefill
\end{\ExtractKthArg{1}{}{#1}}%
}%
\makeatother
\newcommand*{\figureone}{\PrototypeThing{figure*}{\caption}}
\newcommand*{\centerone}{\PrototypeThing{center}{\captionof{figure}}}
\begin{document}
\listoffigures
\newpage
\null
\figureone{example-image-a.jpg}{caption}{.3}{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}
\newpage
\centerone{example-image-b.jpg}{caption}{1}{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}
\end{document}