Token parameters and the %% literal

Many Keyboard Maestro tokens accept parameters. For numeric parameters, you can use a variable, but not for text parameters.

For example, the ICUDateTimePlus token, used for fancy date formatting, has three parameters: a numeric offset, a time unit, and a format string. You can use a variable for the offset, but not for the time unit or format string.

%ICUDateTimePlus%MyOffset%days%yyyy.MM.dd%  works (where myOffset=12)
%ICUDateTimePlus%12%days%%myFormat%%  does not.   (where myFormat = `yyyy.MM.dd`) 

Or with array notation, you can use a variable for the index, but not for the delimiter.

%Variable%MyArray[Index]:%  works  
%Variable%MyArray[12]%delim%% does not.

It seems to me this is the result of the unfortunate decision to use a double percent to represent a literal percent character. When the parser sees a double percent, it sees it as a literal percent character appended to the prior text, not as a token delimiter. So in the second date example above, it sees the offset as 12 and the time unit as days%myFormat%, which of course is not a legal time unit.

Syntactically, there is no way to make this work. You could add a Filter action before it, but this could turn what could be done in a single step into three or four steps.

Would there be any consideration of using the backslash as an escape for the percentage character (\% rather than %%)? Would doing so then allow you to use a variable for the text parameter of a token?

This is far from the only issue. In your first failing example (except with 41 instead of 12 for reasons illustrated below)

%ICUDateTimePlus%41%days%%myFormat%%  does not.   (where myFormat = `yyyy.MM.dd`) 

the parsing engine is not processing the doubled %% as a a % character, it is parsing the ICUDateTimePlus as %ICUDateTimePlus%41%days%%, which has no content for the format, except since that is no legal, the entire thing fails to parse, and so the % character is ignored. Thus the %ICUDateTimePlus is included verbatim, followed by the next token which is %41%, which is a hex character “A” - in your case it will be character 0x12 which is some random control character. Then you get “days” which is not part of any token, and then the doubled percent which happens to be a “%”. But that is irrelevant as to why the parsing fails - even if %% was not a token, it would just end up as two percents at that point instead of one. The token still would not work.

Could the token engine be expanded to try to cope with tokens within tokens? Maybe. But the token engine is already incredibly complicated (running to 2500 lines of code, and that is excluding lots of facilities that are handled elsewhere).

Thanks, I think I understand: the %% doesn't produce a literal %, but rather implies an empty succeeding parameter. If that parameter doesn't make sense, the token fails.

I was thinking perhaps a simple (albeit fundamental) change would fix things.

1 Like

In my experience, everything is always more complicated than you think it is, even after taking this rule in to account.

1 Like

I think i have similar problem.
i want to use variable token to pass array item index.
if i use variable do this, i success.
but if i use variable token to do this, failed.


i can use variable to do this, but i really don't want to create new variables. cannot find answer on Internet.

截屏2023-11-02 13.33.03

Try replacing it with:


As a footnote, it's worth noting that the first time you use "Variable" you can replace that by "Calculate." But it doesn't change any result. It just helps understand why my answer seems to work.

I think your question should have been in a new post. If there's a moderator who wants to transfer your question and my answer to another post, they might want to do that.

1 Like

Very happy :grin:
Many thanks!