pgfplotstable:在可用 tikz 绘制的表中使用自定义命令生成新列的正确方法

pgfplotstable:在可用 tikz 绘制的表中使用自定义命令生成新列的正确方法

抱歉,标题太大,但我不知道如何将其表达为具体的内容,我尝试使用自定义命令在表中生成新列,例如:

\documentclass{scrbook}
\usepackage[nomessages]{fp}
\usepackage{ifthen}
\usepackage{pgfplotstable}
\usepackage{pgfplots}

\newcommand{\newcoltest}[1]%my custom command
{
\ifthenelse{\isodd{#1}}
{\FPeval{\result}{clip(#1+1)}}
{\FPeval{\result}{clip(#1*3/2-1)}}
\result
}

\begin{document}

\pgfplotstableread{
T
1
2
3
4
5
6
7
8
9
10
}\loadedtable
\pgfplotstablecreatecol[
   create col/assign/.code={%
     \getthisrow{T}\vala
     \edef\newentry{\noexpand\newcoltest{\vala}}%
     \pgfkeyslet{/pgfplots/table/create col/next content}\newentry
   }%
]{Sa}{\loadedtable}
\pgfplotstabletypeset[string type]\loadedtable%critic line

\end{document}

批评线是\pgfplotstabletypeset[string type]\loadedtable,它只适用于string type,当我更改为另一种类型甚至不放任何东西时,就会发生错误。

我把\noexpand基于pgfplotstable:使用 create col/assign/.code 定义新列时使用命令吗?,因为如果没有这个,我认为我的命令就无法被识别。

我也无法使用它来绘制它tikz,我认为这是相关的

答案1

像这样吗?

\documentclass{scrbook}
\usepackage{xfp}
\usepackage{pgfplotstable}
\usepackage{pgfplots}

\newcommand{\newcoltest}[1]%my custom command
{%
\ifodd#1
\fpeval{trunc(#1+1)}%
\else
\fpeval{trunc(#1*3/2-1)}%
\fi
}

\begin{document}

\pgfplotstableread{
T
1
2
3
4
5
6
7
8
9
10
}\loadedtable
\pgfplotstablecreatecol[
   create col/assign/.code={%
     \getthisrow{T}\vala
     \edef\newentry{\noexpand\newcoltest{\vala}}%
     \pgfkeyslet{/pgfplots/table/create col/next content}\newentry
   }%
]{Sa}{\loadedtable}
\pgfplotstabletypeset\loadedtable%critic line

\end{document}

在此处输入图片描述

我所做的就是让内容可扩展

  • fpxfp,并且
  • 而倾向于ifthen简单\ifodd

答案2

您使用的想法\noexpand对我来说似乎很好,但却阻止了扩展:

  • 下一个标记;

  • 只有一次,即:如果你的\newentry受制于另一个\edef,那么 将\noexpand不再存在以防止 的扩张\newcoltest——我想这一定是你在这里遇到麻烦的原因。

为了反驳第二点,LaTeX2e 的\protected@edef\protect机制使用了一个巧妙的技巧,使保护在每次在专用宏\protected@edef\protected@write等中使用时恢复。但 e-TeX 和派生引擎(包括 pdfTeX、LuaTeX 和 XeTeX)具有\protected更强大的原语,因为它甚至可以在引擎原语(如\edef和)中保护宏\write,并且不需要使用\protect。您只需将宏声明为\protected,它就不会在、等中\edef展开\write

xparse\NewDocumentCommand宏(而不是\NewExpandableDocumentCommand)会创建\protected宏,因为这通常是最安全的做法,除非你真的知道你的宏是可扩展的。你可以非常简单地使用\NewDocumentCommand来定义\newcoltest来解决你的问题,甚至可以保留\ifthenelse\FPeval其他“不可扩展的内容”在 的替换文本中。当然,在这种情况下\newcoltest不需要,因为定义了受引擎保护的宏——就像你使用了 e-TeX 的原语一样。\noexpand\NewDocumentCommand\protected

\documentclass{article}
\usepackage[nomessages]{fp}
\usepackage{ifthen}
\usepackage{pgfplotstable}
\usepackage{pgfplots}
\usepackage{xparse}

\ExplSyntaxOn % No spurious spaces this way!

\NewDocumentCommand \newcoltest { m }
  {
    \ifthenelse{\isodd{#1}}
      {\FPeval{\result}{clip(#1+1)}}
      {\FPeval{\result}{clip(#1*3/2-1)}}
    \result
  }

\ExplSyntaxOff

\begin{document}

\pgfplotstableread{
T
1
2
3
4
5
6
7
8
9
10
}\loadedtable
\pgfplotstablecreatecol[
   create col/assign/.code={%
     \getthisrow{T}\vala
     \edef\newentry{\newcoltest{\vala}}%
     \pgfkeyslet{/pgfplots/table/create col/next content}\newentry
   }%
]{Sa}{\loadedtable}
\pgfplotstabletypeset[string type]\loadedtable

\end{document}

在此处输入图片描述

此外,由于您正在与 @Schrödinger'scat 讨论条件,您可能有兴趣了解具有expl3强大的可扩展条件,例如\bool_if:nTF\str_case:nnTF以及它们的所有变体(请参阅界面3.pdf看完之后expl3.pdf)。

相关内容