Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

declare function: Strip spaces around each function arg #1124

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion doc/generic/pgf/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ lot of contributed changes. Thanks to everyone who volunteered their time!
- Update Debian installation instructions
- Suppress white space at line end when `datavisualization` reads from a file
#1112
- Form-only patterns have no specified color #1122
- Form-only patterns have no specified color #1122
- Functions defined by `/pgf/declare function` now allow spaces in their arg
list #1123

### Changed

Expand Down
33 changes: 33 additions & 0 deletions testfiles/pgfmath-gh1123.lvt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
\documentclass{minimal}
\input{pgf-regression-test}

\RequirePackage{pgfmath}

\makeatletter
\csname protected\endcsname\long\def\ASSERTPGFMATHFUNCTIONS#1#2{%
\pgfexpl@tl@if@eq@@ccTF{pgfmath#1@}{pgfmath#2@}{%
\TYPE{PASSED}%
\TYPE{\pgfexpl@cs@meaning@@c{pgfmath#1@}}%
}{%
\TYPE{FAILED}%
\TYPE{\pgfexpl@cs@meaning@@c{pgfmath#1@}}%
\TYPE{\pgfexpl@cs@meaning@@c{pgfmath#2@}}%
}%
}
\makeatother

\START

\BEGINTEST{/pgf/declare function, space(s) in arg list}
\pgfkeys{
/pgf/declare function={
funcA( \x,\y) = sqrt((\x)^2 + (\y)^2);
funcB( \x, \y) = sqrt((\x)^2 + (\y)^2);
funcX(\x,\y) = sqrt((\x)^2 + (\y)^2);
}
}
\ASSERTPGFMATHFUNCTIONS{funcA}{funcX}
\ASSERTPGFMATHFUNCTIONS{funcB}{funcX}
\ENDTEST

\END
10 changes: 10 additions & 0 deletions testfiles/pgfmath-gh1123.tlg
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
This is a generated file for the l3build validation system.
Don't change this file in any respect.
============================================================
TEST 1: /pgf/declare function, space(s) in arg list
============================================================
PASSED
macro:#1#2->\pgfmathparse {sqrt(#1^2+#2^2)}
PASSED
macro:#1#2->\pgfmathparse {sqrt(#1^2+#2^2)}
============================================================
12 changes: 9 additions & 3 deletions tex/generic/pgf/math/pgfmathfunctions.code.tex
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@
\expandafter\pgfmath@toks\expandafter=\expandafter{\pgfmath@local@body}%
\else%
\pgfmath@toks={}%
\expandafter\pgfmath@local@function@@body\pgfmath@local@args,,%
\expandafter\pgfmath@local@function@@body@trimspaces\pgfmath@local@args,,%
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\exp_last_unbraced:No fits this case, but it won't obviously increase the readability.

\fi%
\xdef\pgfmath@local@temp{%
\noexpand\pgfmathnotifynewdeclarefunction{\pgfmath@local@name}{\the\c@pgf@counta}%
Expand All @@ -202,7 +202,13 @@
\pgfmathdeclarefunction{#1}{#2}{\pgfmathparse{#3}}%
}%

\def\pgfmath@local@function@@body#1,{%
\def\pgfmath@local@function@@body@trimspaces#1,{%
% strip spaces on both sides of #1 in case it starts with a space,
% e.g., #1 is ` \y` which comes from `func(\x, \y)=...;`
\pgfexpl@exp@args@@Ne\pgfmath@local@function@@body{\pgfutil@trimspaces@noexp{#1}}%
}

\def\pgfmath@local@function@@body#1{%
\def\pgfmath@local@test{#1}%
\ifx\pgfmath@local@test\pgfutil@empty%
\let\pgfmath@local@next=\relax%
Expand All @@ -215,7 +221,7 @@
\pgfmath@toks={}%
\expandafter\pgfmath@local@function@@@body\pgfmath@local@body @%
\edef\pgfmath@local@body{\the\pgfmath@toks}%
\let\pgfmath@local@next=\pgfmath@local@function@@body%
\let\pgfmath@local@next=\pgfmath@local@function@@body@trimspaces%
\fi%
\pgfmath@local@next%
}
Expand Down
80 changes: 80 additions & 0 deletions tex/generic/pgf/utilities/pgfutil-common.tex
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@
\def\pgfutil@trimspaces@@#1Q#2{#1}
\catcode`\Q=11

% \pgfutil@trimspaces@noexp{<token list>}
%
% Variant of \pgfutil@trimspaces that after full expansion leaves stripped
% original text unexpanded in the input stream. Same as \trim@spaces@noexp
% in trimspaces.sty
\def\pgfutil@trimspaces@noexp#1{%
\unexpanded\expandafter\expandafter\expandafter{\pgfutil@trimspaces{#1}}%
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a pity that there's no expl3 function to handle this two-step expansion case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\exp_args:Nf should do that. It basically equals \expandafter#1\expandafter{\romannumeral-`0#2}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We used to have them (d-type), but there are very few places we found we needed them - as we've required e-TeX for a long time, we've been able to rely on most functions including \unexpanded to protect their return values. Also, now we have \expanded, we can use that ... sorry it doesn't work quite so well for you.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I have in my mind is sth more general (and/but less efficient, of course), like \exp_by_steps:nn {<num of steps>} {<tokens>}

\documentclass{article}
\usepackage{pgfmath}

\ExplSyntaxOn\makeatletter
% Expand #2 by exactly #1 steps and leaves the result in input stream. 
% The result is returned within \unexpanded.
\cs_new:Npn \exp_by_steps:nn #1#2
  {
    \int_compare:nNnTF {#1} > 0
      {
        \exp_by_steps:eo { \int_eval:n {#1-1} } {#2}
      }
      {
        \exp_not:n {#2}
      }
  }
\cs_generate_variant:Nn \exp_by_steps:nn {eo}

\exp_args:Ne \tl_show:n { \exp_by_steps:nn {0} {\undefined} }
\exp_args:Ne \tl_show:n { \exp_by_steps:nn {1} {\tl_if_eq:ccTF} }
\exp_args:Ne \tl_show:n { \exp_by_steps:nn {2} {\pgfutil@trimspaces{ \x}} }
\makeatother\ExplSyntaxOff

\begin{document}
\end{document}
% > \undefined .
% > \exp_args:Ncc \tl_if_eq:NNTF .
% > \x .

}

% \pgfutil@ifx{<token 1>}{<token 2>}{<true code>}{<false code>}
%
% This macro is expandable.
Expand Down Expand Up @@ -909,6 +918,77 @@
\pgfmath@smuggleone#1%
\endgroup
}%

%
% Utility commands that are drop-in replacements for expl3 macros
%
% Naming conventions:
% pgf_cs = "pgfexpl@" + expl3_cs.replace("_", "@").replace(":", "@@")
% For example,
% expl3_cs: \exp_args:Ne, \tl_put_right:Nn
% pgf_cs: \pgfexpl@exp@args@@Ne, \pgfexpl@tl@put@right@@Nn


%
% l3basics package
%

% \cs_meaning:c
\long\def\pgfexpl@cs@meaning@@c#1{%
\ifcsname #1\endcsname
\expandafter\pgfutil@firstoftwo
\else
\expandafter\pgfutil@secondoftwo
\fi
{\pgfexpl@exp@args@@Nc\meaning{#1}}
{\detokenize{undefined}}%
}

%
% l3tl package
%

% \tl_if_eq:NNTF
\long\def\pgfexpl@tl@if@eq@@NNTF#1#2{%
\ifx#1#2\pgfexpl@@@prg@TF@true@@w\fi\pgfutil@secondoftwo
}

% \tl_if_eq:ccTF
\long\def\pgfexpl@tl@if@eq@@ccTF{%
\pgfexpl@exp@args@@Ncc\pgfexpl@tl@if@eq@@NNTF
}

% \__prg_TF_true:w
\long\def\pgfexpl@@@prg@TF@true@@w\fi\pgfutil@secondoftwo{%
\fi\pgfutil@firstoftwo
}

%
% l3expan package
%

% \exp_args:Nc
\long\def\pgfexpl@exp@args@@Nc#1#2{%
\expandafter#1\csname #2\endcsname
}

% \exp_args:No
\long\def\pgfexpl@exp@args@@No#1#2{%
\expandafter#1\expandafter{#2}%
}

% \exp_args:Ne
\long\def\pgfexpl@exp@args@@Ne#1#2{%
\expandafter#1\expanded{{#2}}%
}

% \exp_args:Ncc
\long\def\pgfexpl@exp@args@@Ncc#1#2#3{%
\expandafter#1\csname #2\expandafter\endcsname\csname #3\endcsname
}

% End of pgfexpl staff

\input pgfutil-common-lists.tex

\endinput