How to test if argument is a single space?Looping over stringsHow to capitalise every letter in odd position as in memes?Can you write a macro such that each character will be the next color of the rainbowSplit single argument in multiple partsWhy do braces around a single-letter argument of a macro affect its output?def'ed plain-text argument behaves differently from plain texthow to determine the number of characters in the argument of a commandUsing the compulsory argument for the optional argument?Omitting argument in command definitionDefine macro whose argument is a wordSine squared with parentheses for argumentWhat is this newcommand argument?Macro that takes any latex code as an argument
What are the words for people who cause trouble believing they know better?
Why is c4 bad when playing the London against a King's Indian?
Importance sampling estimation of power function
Adding two lambda-functions in C++
What do we gain with higher order logics?
Company did not petition for visa in a timely manner. Is asking me to work from overseas, but wants me to take a paycut
How can drunken, homicidal elves successfully conduct a wild hunt?
What is in `tex.print` or `tex.sprint`?
How to make thick Asian sauces?
Finding the constrain of integral
Will TSA allow me to carry a Continuous Positive Airway Pressure (CPAP)/sleep apnea device?
Can a 2nd-level sorcerer use sorcery points to create a 2nd-level spell slot?
Implement Homestuck's Catenative Doomsday Dice Cascader
What happened to all the nuclear material being smuggled after the fall of the USSR?
How do I write "Show, Don't Tell" as an Asperger?
What is the purpose of building foundations?
How can I instantiate a lambda closure type in C++11/14?
Word for a small burst of laughter that can't be held back
Did Darth Vader wear the same suit for 20+ years?
Why did Hela need Heimdal's sword?
Do any instruments not produce overtones?
Did thousands of women die every year due to illegal abortions before Roe v. Wade?
You've spoiled/damaged the card
How can this map be coloured using four colours?
How to test if argument is a single space?
Looping over stringsHow to capitalise every letter in odd position as in memes?Can you write a macro such that each character will be the next color of the rainbowSplit single argument in multiple partsWhy do braces around a single-letter argument of a macro affect its output?def'ed plain-text argument behaves differently from plain texthow to determine the number of characters in the argument of a commandUsing the compulsory argument for the optional argument?Omitting argument in command definitionDefine macro whose argument is a wordSine squared with parentheses for argumentWhat is this newcommand argument?Macro that takes any latex code as an argument
I am currently writing a document, that sometimes requires me to alternate the colors of the letters in a sentence. I thought it would be easy to find a way to create a macro that does that, but I've run into some problems.
MWE:
% !TeX program = xelatex
% !TeX spellcheck = en_US
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
usepackageetoolbox
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
newcounteralternate
%the macro in question
newcommandcolset[1]%
ifnumvaluealternate=0 colorcandy#1setcounteralternate1%
elsecolorpurple#1setcounteralternate0%
fi
%snippet for the loop taken from https://tex.stackexchange.com/questions/359189/looping-over-strings
%iterates over the supplied string and replaces every letter with colset<letter>
defgobblecharletxchar=
defassignthencheckafterassignmentxloopgobblechar
defxloop%
ifxrelaxxchar
letnext=relax
else
colsetxcharletnext=assignthencheck
fi
next
defmarkletters#1setcounteralternate0assignthencheck#1relax
begindocument
marklettersHello World
enddocument
Output:
The issue is that I have found no way to skip the spaces (i.e. the "W" in "World" should be purple, not red). I thought it would be easy to simply check if the argument is a space and just skip the rest of the macro, but after hours of searching and just trial-and-error (approaches included etoolbox's ifblank#1
, constructs like ifx#1
or even ifnum`#1=32
, creating temporary macros [e.g. edeftemp#1ifblanktemp
]) I am still no step closer, and I'm definitely out of my depth on this one.
Is there a way to check if the argument of a macro is only a space? If no, are there any other ways to construct this macro? (I'm using XeLaTeX via MiKTeX)
Thanks!
macros arguments
add a comment |
I am currently writing a document, that sometimes requires me to alternate the colors of the letters in a sentence. I thought it would be easy to find a way to create a macro that does that, but I've run into some problems.
MWE:
% !TeX program = xelatex
% !TeX spellcheck = en_US
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
usepackageetoolbox
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
newcounteralternate
%the macro in question
newcommandcolset[1]%
ifnumvaluealternate=0 colorcandy#1setcounteralternate1%
elsecolorpurple#1setcounteralternate0%
fi
%snippet for the loop taken from https://tex.stackexchange.com/questions/359189/looping-over-strings
%iterates over the supplied string and replaces every letter with colset<letter>
defgobblecharletxchar=
defassignthencheckafterassignmentxloopgobblechar
defxloop%
ifxrelaxxchar
letnext=relax
else
colsetxcharletnext=assignthencheck
fi
next
defmarkletters#1setcounteralternate0assignthencheck#1relax
begindocument
marklettersHello World
enddocument
Output:
The issue is that I have found no way to skip the spaces (i.e. the "W" in "World" should be purple, not red). I thought it would be easy to simply check if the argument is a space and just skip the rest of the macro, but after hours of searching and just trial-and-error (approaches included etoolbox's ifblank#1
, constructs like ifx#1
or even ifnum`#1=32
, creating temporary macros [e.g. edeftemp#1ifblanktemp
]) I am still no step closer, and I'm definitely out of my depth on this one.
Is there a way to check if the argument of a macro is only a space? If no, are there any other ways to construct this macro? (I'm using XeLaTeX via MiKTeX)
Thanks!
macros arguments
Thanks for the reference to my cuestion :-)
– Raoul Kessels
May 20 at 7:24
add a comment |
I am currently writing a document, that sometimes requires me to alternate the colors of the letters in a sentence. I thought it would be easy to find a way to create a macro that does that, but I've run into some problems.
MWE:
% !TeX program = xelatex
% !TeX spellcheck = en_US
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
usepackageetoolbox
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
newcounteralternate
%the macro in question
newcommandcolset[1]%
ifnumvaluealternate=0 colorcandy#1setcounteralternate1%
elsecolorpurple#1setcounteralternate0%
fi
%snippet for the loop taken from https://tex.stackexchange.com/questions/359189/looping-over-strings
%iterates over the supplied string and replaces every letter with colset<letter>
defgobblecharletxchar=
defassignthencheckafterassignmentxloopgobblechar
defxloop%
ifxrelaxxchar
letnext=relax
else
colsetxcharletnext=assignthencheck
fi
next
defmarkletters#1setcounteralternate0assignthencheck#1relax
begindocument
marklettersHello World
enddocument
Output:
The issue is that I have found no way to skip the spaces (i.e. the "W" in "World" should be purple, not red). I thought it would be easy to simply check if the argument is a space and just skip the rest of the macro, but after hours of searching and just trial-and-error (approaches included etoolbox's ifblank#1
, constructs like ifx#1
or even ifnum`#1=32
, creating temporary macros [e.g. edeftemp#1ifblanktemp
]) I am still no step closer, and I'm definitely out of my depth on this one.
Is there a way to check if the argument of a macro is only a space? If no, are there any other ways to construct this macro? (I'm using XeLaTeX via MiKTeX)
Thanks!
macros arguments
I am currently writing a document, that sometimes requires me to alternate the colors of the letters in a sentence. I thought it would be easy to find a way to create a macro that does that, but I've run into some problems.
MWE:
% !TeX program = xelatex
% !TeX spellcheck = en_US
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
usepackageetoolbox
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
newcounteralternate
%the macro in question
newcommandcolset[1]%
ifnumvaluealternate=0 colorcandy#1setcounteralternate1%
elsecolorpurple#1setcounteralternate0%
fi
%snippet for the loop taken from https://tex.stackexchange.com/questions/359189/looping-over-strings
%iterates over the supplied string and replaces every letter with colset<letter>
defgobblecharletxchar=
defassignthencheckafterassignmentxloopgobblechar
defxloop%
ifxrelaxxchar
letnext=relax
else
colsetxcharletnext=assignthencheck
fi
next
defmarkletters#1setcounteralternate0assignthencheck#1relax
begindocument
marklettersHello World
enddocument
Output:
The issue is that I have found no way to skip the spaces (i.e. the "W" in "World" should be purple, not red). I thought it would be easy to simply check if the argument is a space and just skip the rest of the macro, but after hours of searching and just trial-and-error (approaches included etoolbox's ifblank#1
, constructs like ifx#1
or even ifnum`#1=32
, creating temporary macros [e.g. edeftemp#1ifblanktemp
]) I am still no step closer, and I'm definitely out of my depth on this one.
Is there a way to check if the argument of a macro is only a space? If no, are there any other ways to construct this macro? (I'm using XeLaTeX via MiKTeX)
Thanks!
macros arguments
macros arguments
asked May 19 at 22:50
GrzzlwmpfGrzzlwmpf
433
433
Thanks for the reference to my cuestion :-)
– Raoul Kessels
May 20 at 7:24
add a comment |
Thanks for the reference to my cuestion :-)
– Raoul Kessels
May 20 at 7:24
Thanks for the reference to my cuestion :-)
– Raoul Kessels
May 20 at 7:24
Thanks for the reference to my cuestion :-)
– Raoul Kessels
May 20 at 7:24
add a comment |
3 Answers
3
active
oldest
votes
You are not iterating using macro arguments, so you do not need to test a macro argument, just test the token you have already:
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
usepackageetoolbox
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
newcounteralternate
%the macro in question
newcommandcolset[1]%
ifnumvaluealternate=0 colorcandy#1setcounteralternate1%
elsecolorpurple#1setcounteralternate0%
fi
makeatletter
%snippet for the loop taken from https://tex.stackexchange.com/questions/359189/looping-over-strings
%iterates over the supplied string and replaces every letter with colset<letter>
defgobblecharletxchar=
defassignthencheckafterassignmentxloopgobblechar
defxloop%
ifxrelaxxchar
letnext=relax
else
ifx@sptokenxcharsetcounteralternatenumexpr1-valuealternatefi
colsetxcharletnext=assignthencheck
fi
next
makeatother
defmarkletters#1setcounteralternate0assignthencheck#1relax
begindocument
marklettersHello World
enddocument
add a comment |
You can substitute spaces with something that expands to a space.
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
ExplSyntaxOn
NewDocumentCommandmarklettersm
int_zero:N l_tmpa_int
tl_set:Nn l_tmpa_tl #1
% replace spaces with something different
tl_replace_all:Nnn l_tmpa_tl ~ c_space_tl
tl_map_inline:Nn l_tmpa_tl
tl_if_blank:eTF ##1
~ % don't advance the counter and issue a space
textcolor int_if_odd:nTF l_tmpa_int purple candy ##1
int_incr:N l_tmpa_int
prg_generate_conditional_variant:Nnn tl_if_blank:n e T,F,TF,p
ExplSyntaxOff
begindocument
marklettersHello World
enddocument
add a comment |
You asked for a routine for checking whether a macro argument consists a single space although the afterassignment-let
-loop in your example does not iterate macro-argument-wise but token-wise. Besides this, with that loop you cannot have (La)TeX "look" at tokens of whatsoever macro-arguments but you can have (La)TeX "look" at the meaning of the control word token xchar
. You cannot exactly deduce the kind of token from which xchar
got its meaning: This could indeed have been an explicit space character token. But this could as well have been an implicit space token, i.e., some control sequence which was let
equal to the explicit space character token, like @sptoken
.
Thus there is some likelihood that my answer/my example below is not of any use to you at all.
Nonetheless it might be of use to people who stumble over your question while indeed being in need of a routine for detecting (explicit) space tokens in macro arguments.
The example below provides two routines:
The macro UD@CheckWhetherLeadingSpace
can be used for finding out whether the very first token of a macro argument is an explicit space character token (character code 32, category code 10).
The gist of UD@CheckWhetherLeadingSpace
is: Append a space token (for ensuring that there is at least one), then gather everything till the first space token, then see whether "emptiness" was gathered. Some brace-hacking is used for removing the remainder.
The macro UD@CheckWhetherSingleSpace
can be used for finding out whether a macro argument consists of a single explicit space character token (character code 32, category code 10).
The gist of UD@CheckWhetherSingleSpace
is: Apply UD@CheckWhetherLeadingSpace
. In case there is a leading space, check whether you get emptiness after removing it.
These macros work only on explicit space character tokens (character code 32, category code 10). Neither do they work on implicit space characters, nor do they work on character tokens of character code 32 but category code differing from 10, nor do they work on so-called "funny spaces" (character code differing from 32, category code 10 - iirc "funny spaces" can come into being only by changing the lccode
or uccode
of the space character and then applying lowercase
respective uppercase
to the space character (and then probably applying let
for obtaining an implicit from an explicit funny space funny space)...).
These macros don't require e-TeX-extensions and are intended to work in full-expansion-contexts etc as well.
Due to romannumeral
-expansion you get the result after triggering two expansion-steps/after having UD@CheckWhetherLeadingSpace
/UD@CheckWhetherSingleSpace
"hit" by two expandafter
.
(By the way:
Be aware that (La)TeX skips explicit (non-funny) space tokens not nested in braces when gathering undelimited macro arguments. It does not skip them when gathering delimited macro arguments.
E.g., with defthreeargs#1#2#3#1#2#3
and threeargs a b c
you will get #1
=a
, #2
=b
, #3
=c
although there will be explicit space character tokens between a
and b
and between b
and c
.
I think that's one of the reasons why the loop in the example within your question does not iterate macro-argument-wise but token-wise.)
documentclass[a4paper]article
makeatletter
%%----------------------------------------------------------------------
newcommandUD@firstoftwo[2]#1%
newcommandUD@secondoftwo[2]#2%
newcommandUD@exchange[2]#2#1%
newcommandUD@gobblespace%
UD@firstoftwodefUD@gobblespace %
%%----------------------------------------------------------------------
%% 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>
newcommandUD@CheckWhetherNull[1]%
romannumeral0expandafterUD@secondoftwostringexpandafter
UD@secondoftwoexpandafterexpandafterstring#1expandafter
UD@secondoftwostringexpandafterUD@firstoftwoexpandafterexpandafter
UD@secondoftwostringexpandafterexpandafterUD@firstoftwo %
UD@secondoftwoexpandafterexpandafterUD@firstoftwo UD@firstoftwo%
%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument starts with a space-token
%%.............................................................................
%% UD@CheckWhetherLeadingSpace<Argument which is to be checked>%
%% <Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is a
%% space-token>%
%% <Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is not
%% a space-token>%
newcommandUD@CheckWhetherLeadingSpace[1]%
romannumeral0UD@CheckWhetherNull#1%
expandafterexpandafterUD@firstoftwo UD@secondoftwo%
expandafterUD@secondoftwostringUD@CheckWhetherLeadingSpaceB.#1 %
%
newcommandUD@CheckWhetherLeadingSpaceB%
longdefUD@CheckWhetherLeadingSpaceB#1 %
expandafterUD@CheckWhetherNullexpandafterUD@secondoftwo#1%
UD@exchangeUD@firstoftwoUD@exchangeUD@secondoftwo%
UD@exchange expandafterexpandafterexpandafterexpandafter
expandafterexpandafterexpandafterexpandafterexpandafter
expandafterexpandafterUD@secondoftwoexpandafterstring%
%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument consists only of a single space-token
%%.............................................................................
newcommandUD@CheckWhetherSingleSpace[1]%
romannumeral0UD@CheckWhetherLeadingSpace#1%
expandafterUD@CheckWhetherNullexpandafterUD@gobblespace#1%
UD@exchangeUD@firstoftwoUD@exchangeUD@secondoftwo%
UD@exchangeUD@secondoftwoUD@exchange expandafter%
%
%makeatother
begindocument
UD@CheckWhetherLeadingSpace textLeading explicit space tokenNo leading explicit space token
UD@CheckWhetherLeadingSpace Leading explicit space tokenNo leading explicit space token
UD@CheckWhetherLeadingSpacetextLeading explicit space tokenNo leading explicit space token
% empty argument:
UD@CheckWhetherLeadingSpaceLeading explicit space tokenNo leading explicit space token
% two space tokens:
expandafterUD@CheckWhetherLeadingSpaceexpandafter@firstofone %
Leading explicit space tokenNo leading explicit space token
noindenthrulefill
UD@CheckWhetherSingleSpace textSingle explicit space tokenNot a single explicit space token
UD@CheckWhetherSingleSpace Single explicit space tokenNot a single explicit space token
UD@CheckWhetherSingleSpacetextSingle explicit space tokenNot a single explicit space token
% empty argument:
UD@CheckWhetherSingleSpaceSingle explicit space tokenNot a single explicit space token
% two space tokens:
expandafterUD@CheckWhetherSingleSpaceexpandafter@firstofone %
Single explicit space tokenNot a single explicit space token
enddocument
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "85"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f491668%2fhow-to-test-if-argument-is-a-single-space%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You are not iterating using macro arguments, so you do not need to test a macro argument, just test the token you have already:
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
usepackageetoolbox
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
newcounteralternate
%the macro in question
newcommandcolset[1]%
ifnumvaluealternate=0 colorcandy#1setcounteralternate1%
elsecolorpurple#1setcounteralternate0%
fi
makeatletter
%snippet for the loop taken from https://tex.stackexchange.com/questions/359189/looping-over-strings
%iterates over the supplied string and replaces every letter with colset<letter>
defgobblecharletxchar=
defassignthencheckafterassignmentxloopgobblechar
defxloop%
ifxrelaxxchar
letnext=relax
else
ifx@sptokenxcharsetcounteralternatenumexpr1-valuealternatefi
colsetxcharletnext=assignthencheck
fi
next
makeatother
defmarkletters#1setcounteralternate0assignthencheck#1relax
begindocument
marklettersHello World
enddocument
add a comment |
You are not iterating using macro arguments, so you do not need to test a macro argument, just test the token you have already:
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
usepackageetoolbox
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
newcounteralternate
%the macro in question
newcommandcolset[1]%
ifnumvaluealternate=0 colorcandy#1setcounteralternate1%
elsecolorpurple#1setcounteralternate0%
fi
makeatletter
%snippet for the loop taken from https://tex.stackexchange.com/questions/359189/looping-over-strings
%iterates over the supplied string and replaces every letter with colset<letter>
defgobblecharletxchar=
defassignthencheckafterassignmentxloopgobblechar
defxloop%
ifxrelaxxchar
letnext=relax
else
ifx@sptokenxcharsetcounteralternatenumexpr1-valuealternatefi
colsetxcharletnext=assignthencheck
fi
next
makeatother
defmarkletters#1setcounteralternate0assignthencheck#1relax
begindocument
marklettersHello World
enddocument
add a comment |
You are not iterating using macro arguments, so you do not need to test a macro argument, just test the token you have already:
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
usepackageetoolbox
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
newcounteralternate
%the macro in question
newcommandcolset[1]%
ifnumvaluealternate=0 colorcandy#1setcounteralternate1%
elsecolorpurple#1setcounteralternate0%
fi
makeatletter
%snippet for the loop taken from https://tex.stackexchange.com/questions/359189/looping-over-strings
%iterates over the supplied string and replaces every letter with colset<letter>
defgobblecharletxchar=
defassignthencheckafterassignmentxloopgobblechar
defxloop%
ifxrelaxxchar
letnext=relax
else
ifx@sptokenxcharsetcounteralternatenumexpr1-valuealternatefi
colsetxcharletnext=assignthencheck
fi
next
makeatother
defmarkletters#1setcounteralternate0assignthencheck#1relax
begindocument
marklettersHello World
enddocument
You are not iterating using macro arguments, so you do not need to test a macro argument, just test the token you have already:
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
usepackageetoolbox
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
newcounteralternate
%the macro in question
newcommandcolset[1]%
ifnumvaluealternate=0 colorcandy#1setcounteralternate1%
elsecolorpurple#1setcounteralternate0%
fi
makeatletter
%snippet for the loop taken from https://tex.stackexchange.com/questions/359189/looping-over-strings
%iterates over the supplied string and replaces every letter with colset<letter>
defgobblecharletxchar=
defassignthencheckafterassignmentxloopgobblechar
defxloop%
ifxrelaxxchar
letnext=relax
else
ifx@sptokenxcharsetcounteralternatenumexpr1-valuealternatefi
colsetxcharletnext=assignthencheck
fi
next
makeatother
defmarkletters#1setcounteralternate0assignthencheck#1relax
begindocument
marklettersHello World
enddocument
answered May 19 at 23:11
David CarlisleDavid Carlisle
507k4311551908
507k4311551908
add a comment |
add a comment |
You can substitute spaces with something that expands to a space.
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
ExplSyntaxOn
NewDocumentCommandmarklettersm
int_zero:N l_tmpa_int
tl_set:Nn l_tmpa_tl #1
% replace spaces with something different
tl_replace_all:Nnn l_tmpa_tl ~ c_space_tl
tl_map_inline:Nn l_tmpa_tl
tl_if_blank:eTF ##1
~ % don't advance the counter and issue a space
textcolor int_if_odd:nTF l_tmpa_int purple candy ##1
int_incr:N l_tmpa_int
prg_generate_conditional_variant:Nnn tl_if_blank:n e T,F,TF,p
ExplSyntaxOff
begindocument
marklettersHello World
enddocument
add a comment |
You can substitute spaces with something that expands to a space.
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
ExplSyntaxOn
NewDocumentCommandmarklettersm
int_zero:N l_tmpa_int
tl_set:Nn l_tmpa_tl #1
% replace spaces with something different
tl_replace_all:Nnn l_tmpa_tl ~ c_space_tl
tl_map_inline:Nn l_tmpa_tl
tl_if_blank:eTF ##1
~ % don't advance the counter and issue a space
textcolor int_if_odd:nTF l_tmpa_int purple candy ##1
int_incr:N l_tmpa_int
prg_generate_conditional_variant:Nnn tl_if_blank:n e T,F,TF,p
ExplSyntaxOff
begindocument
marklettersHello World
enddocument
add a comment |
You can substitute spaces with something that expands to a space.
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
ExplSyntaxOn
NewDocumentCommandmarklettersm
int_zero:N l_tmpa_int
tl_set:Nn l_tmpa_tl #1
% replace spaces with something different
tl_replace_all:Nnn l_tmpa_tl ~ c_space_tl
tl_map_inline:Nn l_tmpa_tl
tl_if_blank:eTF ##1
~ % don't advance the counter and issue a space
textcolor int_if_odd:nTF l_tmpa_int purple candy ##1
int_incr:N l_tmpa_int
prg_generate_conditional_variant:Nnn tl_if_blank:n e T,F,TF,p
ExplSyntaxOff
begindocument
marklettersHello World
enddocument
You can substitute spaces with something that expands to a space.
documentclass[11pt,a4paper,english,twoside,notitlepage]book
usepackagefontspec
usepackagelmodern
usepackage[english,main=english]babel
usepackagexcolor
definecolorpurpleHTML2B0057
definecolorcandyHTMLFF0000
ExplSyntaxOn
NewDocumentCommandmarklettersm
int_zero:N l_tmpa_int
tl_set:Nn l_tmpa_tl #1
% replace spaces with something different
tl_replace_all:Nnn l_tmpa_tl ~ c_space_tl
tl_map_inline:Nn l_tmpa_tl
tl_if_blank:eTF ##1
~ % don't advance the counter and issue a space
textcolor int_if_odd:nTF l_tmpa_int purple candy ##1
int_incr:N l_tmpa_int
prg_generate_conditional_variant:Nnn tl_if_blank:n e T,F,TF,p
ExplSyntaxOff
begindocument
marklettersHello World
enddocument
answered May 19 at 23:05
egregegreg
745k8919513291
745k8919513291
add a comment |
add a comment |
You asked for a routine for checking whether a macro argument consists a single space although the afterassignment-let
-loop in your example does not iterate macro-argument-wise but token-wise. Besides this, with that loop you cannot have (La)TeX "look" at tokens of whatsoever macro-arguments but you can have (La)TeX "look" at the meaning of the control word token xchar
. You cannot exactly deduce the kind of token from which xchar
got its meaning: This could indeed have been an explicit space character token. But this could as well have been an implicit space token, i.e., some control sequence which was let
equal to the explicit space character token, like @sptoken
.
Thus there is some likelihood that my answer/my example below is not of any use to you at all.
Nonetheless it might be of use to people who stumble over your question while indeed being in need of a routine for detecting (explicit) space tokens in macro arguments.
The example below provides two routines:
The macro UD@CheckWhetherLeadingSpace
can be used for finding out whether the very first token of a macro argument is an explicit space character token (character code 32, category code 10).
The gist of UD@CheckWhetherLeadingSpace
is: Append a space token (for ensuring that there is at least one), then gather everything till the first space token, then see whether "emptiness" was gathered. Some brace-hacking is used for removing the remainder.
The macro UD@CheckWhetherSingleSpace
can be used for finding out whether a macro argument consists of a single explicit space character token (character code 32, category code 10).
The gist of UD@CheckWhetherSingleSpace
is: Apply UD@CheckWhetherLeadingSpace
. In case there is a leading space, check whether you get emptiness after removing it.
These macros work only on explicit space character tokens (character code 32, category code 10). Neither do they work on implicit space characters, nor do they work on character tokens of character code 32 but category code differing from 10, nor do they work on so-called "funny spaces" (character code differing from 32, category code 10 - iirc "funny spaces" can come into being only by changing the lccode
or uccode
of the space character and then applying lowercase
respective uppercase
to the space character (and then probably applying let
for obtaining an implicit from an explicit funny space funny space)...).
These macros don't require e-TeX-extensions and are intended to work in full-expansion-contexts etc as well.
Due to romannumeral
-expansion you get the result after triggering two expansion-steps/after having UD@CheckWhetherLeadingSpace
/UD@CheckWhetherSingleSpace
"hit" by two expandafter
.
(By the way:
Be aware that (La)TeX skips explicit (non-funny) space tokens not nested in braces when gathering undelimited macro arguments. It does not skip them when gathering delimited macro arguments.
E.g., with defthreeargs#1#2#3#1#2#3
and threeargs a b c
you will get #1
=a
, #2
=b
, #3
=c
although there will be explicit space character tokens between a
and b
and between b
and c
.
I think that's one of the reasons why the loop in the example within your question does not iterate macro-argument-wise but token-wise.)
documentclass[a4paper]article
makeatletter
%%----------------------------------------------------------------------
newcommandUD@firstoftwo[2]#1%
newcommandUD@secondoftwo[2]#2%
newcommandUD@exchange[2]#2#1%
newcommandUD@gobblespace%
UD@firstoftwodefUD@gobblespace %
%%----------------------------------------------------------------------
%% 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>
newcommandUD@CheckWhetherNull[1]%
romannumeral0expandafterUD@secondoftwostringexpandafter
UD@secondoftwoexpandafterexpandafterstring#1expandafter
UD@secondoftwostringexpandafterUD@firstoftwoexpandafterexpandafter
UD@secondoftwostringexpandafterexpandafterUD@firstoftwo %
UD@secondoftwoexpandafterexpandafterUD@firstoftwo UD@firstoftwo%
%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument starts with a space-token
%%.............................................................................
%% UD@CheckWhetherLeadingSpace<Argument which is to be checked>%
%% <Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is a
%% space-token>%
%% <Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is not
%% a space-token>%
newcommandUD@CheckWhetherLeadingSpace[1]%
romannumeral0UD@CheckWhetherNull#1%
expandafterexpandafterUD@firstoftwo UD@secondoftwo%
expandafterUD@secondoftwostringUD@CheckWhetherLeadingSpaceB.#1 %
%
newcommandUD@CheckWhetherLeadingSpaceB%
longdefUD@CheckWhetherLeadingSpaceB#1 %
expandafterUD@CheckWhetherNullexpandafterUD@secondoftwo#1%
UD@exchangeUD@firstoftwoUD@exchangeUD@secondoftwo%
UD@exchange expandafterexpandafterexpandafterexpandafter
expandafterexpandafterexpandafterexpandafterexpandafter
expandafterexpandafterUD@secondoftwoexpandafterstring%
%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument consists only of a single space-token
%%.............................................................................
newcommandUD@CheckWhetherSingleSpace[1]%
romannumeral0UD@CheckWhetherLeadingSpace#1%
expandafterUD@CheckWhetherNullexpandafterUD@gobblespace#1%
UD@exchangeUD@firstoftwoUD@exchangeUD@secondoftwo%
UD@exchangeUD@secondoftwoUD@exchange expandafter%
%
%makeatother
begindocument
UD@CheckWhetherLeadingSpace textLeading explicit space tokenNo leading explicit space token
UD@CheckWhetherLeadingSpace Leading explicit space tokenNo leading explicit space token
UD@CheckWhetherLeadingSpacetextLeading explicit space tokenNo leading explicit space token
% empty argument:
UD@CheckWhetherLeadingSpaceLeading explicit space tokenNo leading explicit space token
% two space tokens:
expandafterUD@CheckWhetherLeadingSpaceexpandafter@firstofone %
Leading explicit space tokenNo leading explicit space token
noindenthrulefill
UD@CheckWhetherSingleSpace textSingle explicit space tokenNot a single explicit space token
UD@CheckWhetherSingleSpace Single explicit space tokenNot a single explicit space token
UD@CheckWhetherSingleSpacetextSingle explicit space tokenNot a single explicit space token
% empty argument:
UD@CheckWhetherSingleSpaceSingle explicit space tokenNot a single explicit space token
% two space tokens:
expandafterUD@CheckWhetherSingleSpaceexpandafter@firstofone %
Single explicit space tokenNot a single explicit space token
enddocument
add a comment |
You asked for a routine for checking whether a macro argument consists a single space although the afterassignment-let
-loop in your example does not iterate macro-argument-wise but token-wise. Besides this, with that loop you cannot have (La)TeX "look" at tokens of whatsoever macro-arguments but you can have (La)TeX "look" at the meaning of the control word token xchar
. You cannot exactly deduce the kind of token from which xchar
got its meaning: This could indeed have been an explicit space character token. But this could as well have been an implicit space token, i.e., some control sequence which was let
equal to the explicit space character token, like @sptoken
.
Thus there is some likelihood that my answer/my example below is not of any use to you at all.
Nonetheless it might be of use to people who stumble over your question while indeed being in need of a routine for detecting (explicit) space tokens in macro arguments.
The example below provides two routines:
The macro UD@CheckWhetherLeadingSpace
can be used for finding out whether the very first token of a macro argument is an explicit space character token (character code 32, category code 10).
The gist of UD@CheckWhetherLeadingSpace
is: Append a space token (for ensuring that there is at least one), then gather everything till the first space token, then see whether "emptiness" was gathered. Some brace-hacking is used for removing the remainder.
The macro UD@CheckWhetherSingleSpace
can be used for finding out whether a macro argument consists of a single explicit space character token (character code 32, category code 10).
The gist of UD@CheckWhetherSingleSpace
is: Apply UD@CheckWhetherLeadingSpace
. In case there is a leading space, check whether you get emptiness after removing it.
These macros work only on explicit space character tokens (character code 32, category code 10). Neither do they work on implicit space characters, nor do they work on character tokens of character code 32 but category code differing from 10, nor do they work on so-called "funny spaces" (character code differing from 32, category code 10 - iirc "funny spaces" can come into being only by changing the lccode
or uccode
of the space character and then applying lowercase
respective uppercase
to the space character (and then probably applying let
for obtaining an implicit from an explicit funny space funny space)...).
These macros don't require e-TeX-extensions and are intended to work in full-expansion-contexts etc as well.
Due to romannumeral
-expansion you get the result after triggering two expansion-steps/after having UD@CheckWhetherLeadingSpace
/UD@CheckWhetherSingleSpace
"hit" by two expandafter
.
(By the way:
Be aware that (La)TeX skips explicit (non-funny) space tokens not nested in braces when gathering undelimited macro arguments. It does not skip them when gathering delimited macro arguments.
E.g., with defthreeargs#1#2#3#1#2#3
and threeargs a b c
you will get #1
=a
, #2
=b
, #3
=c
although there will be explicit space character tokens between a
and b
and between b
and c
.
I think that's one of the reasons why the loop in the example within your question does not iterate macro-argument-wise but token-wise.)
documentclass[a4paper]article
makeatletter
%%----------------------------------------------------------------------
newcommandUD@firstoftwo[2]#1%
newcommandUD@secondoftwo[2]#2%
newcommandUD@exchange[2]#2#1%
newcommandUD@gobblespace%
UD@firstoftwodefUD@gobblespace %
%%----------------------------------------------------------------------
%% 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>
newcommandUD@CheckWhetherNull[1]%
romannumeral0expandafterUD@secondoftwostringexpandafter
UD@secondoftwoexpandafterexpandafterstring#1expandafter
UD@secondoftwostringexpandafterUD@firstoftwoexpandafterexpandafter
UD@secondoftwostringexpandafterexpandafterUD@firstoftwo %
UD@secondoftwoexpandafterexpandafterUD@firstoftwo UD@firstoftwo%
%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument starts with a space-token
%%.............................................................................
%% UD@CheckWhetherLeadingSpace<Argument which is to be checked>%
%% <Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is a
%% space-token>%
%% <Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is not
%% a space-token>%
newcommandUD@CheckWhetherLeadingSpace[1]%
romannumeral0UD@CheckWhetherNull#1%
expandafterexpandafterUD@firstoftwo UD@secondoftwo%
expandafterUD@secondoftwostringUD@CheckWhetherLeadingSpaceB.#1 %
%
newcommandUD@CheckWhetherLeadingSpaceB%
longdefUD@CheckWhetherLeadingSpaceB#1 %
expandafterUD@CheckWhetherNullexpandafterUD@secondoftwo#1%
UD@exchangeUD@firstoftwoUD@exchangeUD@secondoftwo%
UD@exchange expandafterexpandafterexpandafterexpandafter
expandafterexpandafterexpandafterexpandafterexpandafter
expandafterexpandafterUD@secondoftwoexpandafterstring%
%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument consists only of a single space-token
%%.............................................................................
newcommandUD@CheckWhetherSingleSpace[1]%
romannumeral0UD@CheckWhetherLeadingSpace#1%
expandafterUD@CheckWhetherNullexpandafterUD@gobblespace#1%
UD@exchangeUD@firstoftwoUD@exchangeUD@secondoftwo%
UD@exchangeUD@secondoftwoUD@exchange expandafter%
%
%makeatother
begindocument
UD@CheckWhetherLeadingSpace textLeading explicit space tokenNo leading explicit space token
UD@CheckWhetherLeadingSpace Leading explicit space tokenNo leading explicit space token
UD@CheckWhetherLeadingSpacetextLeading explicit space tokenNo leading explicit space token
% empty argument:
UD@CheckWhetherLeadingSpaceLeading explicit space tokenNo leading explicit space token
% two space tokens:
expandafterUD@CheckWhetherLeadingSpaceexpandafter@firstofone %
Leading explicit space tokenNo leading explicit space token
noindenthrulefill
UD@CheckWhetherSingleSpace textSingle explicit space tokenNot a single explicit space token
UD@CheckWhetherSingleSpace Single explicit space tokenNot a single explicit space token
UD@CheckWhetherSingleSpacetextSingle explicit space tokenNot a single explicit space token
% empty argument:
UD@CheckWhetherSingleSpaceSingle explicit space tokenNot a single explicit space token
% two space tokens:
expandafterUD@CheckWhetherSingleSpaceexpandafter@firstofone %
Single explicit space tokenNot a single explicit space token
enddocument
add a comment |
You asked for a routine for checking whether a macro argument consists a single space although the afterassignment-let
-loop in your example does not iterate macro-argument-wise but token-wise. Besides this, with that loop you cannot have (La)TeX "look" at tokens of whatsoever macro-arguments but you can have (La)TeX "look" at the meaning of the control word token xchar
. You cannot exactly deduce the kind of token from which xchar
got its meaning: This could indeed have been an explicit space character token. But this could as well have been an implicit space token, i.e., some control sequence which was let
equal to the explicit space character token, like @sptoken
.
Thus there is some likelihood that my answer/my example below is not of any use to you at all.
Nonetheless it might be of use to people who stumble over your question while indeed being in need of a routine for detecting (explicit) space tokens in macro arguments.
The example below provides two routines:
The macro UD@CheckWhetherLeadingSpace
can be used for finding out whether the very first token of a macro argument is an explicit space character token (character code 32, category code 10).
The gist of UD@CheckWhetherLeadingSpace
is: Append a space token (for ensuring that there is at least one), then gather everything till the first space token, then see whether "emptiness" was gathered. Some brace-hacking is used for removing the remainder.
The macro UD@CheckWhetherSingleSpace
can be used for finding out whether a macro argument consists of a single explicit space character token (character code 32, category code 10).
The gist of UD@CheckWhetherSingleSpace
is: Apply UD@CheckWhetherLeadingSpace
. In case there is a leading space, check whether you get emptiness after removing it.
These macros work only on explicit space character tokens (character code 32, category code 10). Neither do they work on implicit space characters, nor do they work on character tokens of character code 32 but category code differing from 10, nor do they work on so-called "funny spaces" (character code differing from 32, category code 10 - iirc "funny spaces" can come into being only by changing the lccode
or uccode
of the space character and then applying lowercase
respective uppercase
to the space character (and then probably applying let
for obtaining an implicit from an explicit funny space funny space)...).
These macros don't require e-TeX-extensions and are intended to work in full-expansion-contexts etc as well.
Due to romannumeral
-expansion you get the result after triggering two expansion-steps/after having UD@CheckWhetherLeadingSpace
/UD@CheckWhetherSingleSpace
"hit" by two expandafter
.
(By the way:
Be aware that (La)TeX skips explicit (non-funny) space tokens not nested in braces when gathering undelimited macro arguments. It does not skip them when gathering delimited macro arguments.
E.g., with defthreeargs#1#2#3#1#2#3
and threeargs a b c
you will get #1
=a
, #2
=b
, #3
=c
although there will be explicit space character tokens between a
and b
and between b
and c
.
I think that's one of the reasons why the loop in the example within your question does not iterate macro-argument-wise but token-wise.)
documentclass[a4paper]article
makeatletter
%%----------------------------------------------------------------------
newcommandUD@firstoftwo[2]#1%
newcommandUD@secondoftwo[2]#2%
newcommandUD@exchange[2]#2#1%
newcommandUD@gobblespace%
UD@firstoftwodefUD@gobblespace %
%%----------------------------------------------------------------------
%% 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>
newcommandUD@CheckWhetherNull[1]%
romannumeral0expandafterUD@secondoftwostringexpandafter
UD@secondoftwoexpandafterexpandafterstring#1expandafter
UD@secondoftwostringexpandafterUD@firstoftwoexpandafterexpandafter
UD@secondoftwostringexpandafterexpandafterUD@firstoftwo %
UD@secondoftwoexpandafterexpandafterUD@firstoftwo UD@firstoftwo%
%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument starts with a space-token
%%.............................................................................
%% UD@CheckWhetherLeadingSpace<Argument which is to be checked>%
%% <Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is a
%% space-token>%
%% <Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is not
%% a space-token>%
newcommandUD@CheckWhetherLeadingSpace[1]%
romannumeral0UD@CheckWhetherNull#1%
expandafterexpandafterUD@firstoftwo UD@secondoftwo%
expandafterUD@secondoftwostringUD@CheckWhetherLeadingSpaceB.#1 %
%
newcommandUD@CheckWhetherLeadingSpaceB%
longdefUD@CheckWhetherLeadingSpaceB#1 %
expandafterUD@CheckWhetherNullexpandafterUD@secondoftwo#1%
UD@exchangeUD@firstoftwoUD@exchangeUD@secondoftwo%
UD@exchange expandafterexpandafterexpandafterexpandafter
expandafterexpandafterexpandafterexpandafterexpandafter
expandafterexpandafterUD@secondoftwoexpandafterstring%
%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument consists only of a single space-token
%%.............................................................................
newcommandUD@CheckWhetherSingleSpace[1]%
romannumeral0UD@CheckWhetherLeadingSpace#1%
expandafterUD@CheckWhetherNullexpandafterUD@gobblespace#1%
UD@exchangeUD@firstoftwoUD@exchangeUD@secondoftwo%
UD@exchangeUD@secondoftwoUD@exchange expandafter%
%
%makeatother
begindocument
UD@CheckWhetherLeadingSpace textLeading explicit space tokenNo leading explicit space token
UD@CheckWhetherLeadingSpace Leading explicit space tokenNo leading explicit space token
UD@CheckWhetherLeadingSpacetextLeading explicit space tokenNo leading explicit space token
% empty argument:
UD@CheckWhetherLeadingSpaceLeading explicit space tokenNo leading explicit space token
% two space tokens:
expandafterUD@CheckWhetherLeadingSpaceexpandafter@firstofone %
Leading explicit space tokenNo leading explicit space token
noindenthrulefill
UD@CheckWhetherSingleSpace textSingle explicit space tokenNot a single explicit space token
UD@CheckWhetherSingleSpace Single explicit space tokenNot a single explicit space token
UD@CheckWhetherSingleSpacetextSingle explicit space tokenNot a single explicit space token
% empty argument:
UD@CheckWhetherSingleSpaceSingle explicit space tokenNot a single explicit space token
% two space tokens:
expandafterUD@CheckWhetherSingleSpaceexpandafter@firstofone %
Single explicit space tokenNot a single explicit space token
enddocument
You asked for a routine for checking whether a macro argument consists a single space although the afterassignment-let
-loop in your example does not iterate macro-argument-wise but token-wise. Besides this, with that loop you cannot have (La)TeX "look" at tokens of whatsoever macro-arguments but you can have (La)TeX "look" at the meaning of the control word token xchar
. You cannot exactly deduce the kind of token from which xchar
got its meaning: This could indeed have been an explicit space character token. But this could as well have been an implicit space token, i.e., some control sequence which was let
equal to the explicit space character token, like @sptoken
.
Thus there is some likelihood that my answer/my example below is not of any use to you at all.
Nonetheless it might be of use to people who stumble over your question while indeed being in need of a routine for detecting (explicit) space tokens in macro arguments.
The example below provides two routines:
The macro UD@CheckWhetherLeadingSpace
can be used for finding out whether the very first token of a macro argument is an explicit space character token (character code 32, category code 10).
The gist of UD@CheckWhetherLeadingSpace
is: Append a space token (for ensuring that there is at least one), then gather everything till the first space token, then see whether "emptiness" was gathered. Some brace-hacking is used for removing the remainder.
The macro UD@CheckWhetherSingleSpace
can be used for finding out whether a macro argument consists of a single explicit space character token (character code 32, category code 10).
The gist of UD@CheckWhetherSingleSpace
is: Apply UD@CheckWhetherLeadingSpace
. In case there is a leading space, check whether you get emptiness after removing it.
These macros work only on explicit space character tokens (character code 32, category code 10). Neither do they work on implicit space characters, nor do they work on character tokens of character code 32 but category code differing from 10, nor do they work on so-called "funny spaces" (character code differing from 32, category code 10 - iirc "funny spaces" can come into being only by changing the lccode
or uccode
of the space character and then applying lowercase
respective uppercase
to the space character (and then probably applying let
for obtaining an implicit from an explicit funny space funny space)...).
These macros don't require e-TeX-extensions and are intended to work in full-expansion-contexts etc as well.
Due to romannumeral
-expansion you get the result after triggering two expansion-steps/after having UD@CheckWhetherLeadingSpace
/UD@CheckWhetherSingleSpace
"hit" by two expandafter
.
(By the way:
Be aware that (La)TeX skips explicit (non-funny) space tokens not nested in braces when gathering undelimited macro arguments. It does not skip them when gathering delimited macro arguments.
E.g., with defthreeargs#1#2#3#1#2#3
and threeargs a b c
you will get #1
=a
, #2
=b
, #3
=c
although there will be explicit space character tokens between a
and b
and between b
and c
.
I think that's one of the reasons why the loop in the example within your question does not iterate macro-argument-wise but token-wise.)
documentclass[a4paper]article
makeatletter
%%----------------------------------------------------------------------
newcommandUD@firstoftwo[2]#1%
newcommandUD@secondoftwo[2]#2%
newcommandUD@exchange[2]#2#1%
newcommandUD@gobblespace%
UD@firstoftwodefUD@gobblespace %
%%----------------------------------------------------------------------
%% 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>
newcommandUD@CheckWhetherNull[1]%
romannumeral0expandafterUD@secondoftwostringexpandafter
UD@secondoftwoexpandafterexpandafterstring#1expandafter
UD@secondoftwostringexpandafterUD@firstoftwoexpandafterexpandafter
UD@secondoftwostringexpandafterexpandafterUD@firstoftwo %
UD@secondoftwoexpandafterexpandafterUD@firstoftwo UD@firstoftwo%
%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument starts with a space-token
%%.............................................................................
%% UD@CheckWhetherLeadingSpace<Argument which is to be checked>%
%% <Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is a
%% space-token>%
%% <Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is not
%% a space-token>%
newcommandUD@CheckWhetherLeadingSpace[1]%
romannumeral0UD@CheckWhetherNull#1%
expandafterexpandafterUD@firstoftwo UD@secondoftwo%
expandafterUD@secondoftwostringUD@CheckWhetherLeadingSpaceB.#1 %
%
newcommandUD@CheckWhetherLeadingSpaceB%
longdefUD@CheckWhetherLeadingSpaceB#1 %
expandafterUD@CheckWhetherNullexpandafterUD@secondoftwo#1%
UD@exchangeUD@firstoftwoUD@exchangeUD@secondoftwo%
UD@exchange expandafterexpandafterexpandafterexpandafter
expandafterexpandafterexpandafterexpandafterexpandafter
expandafterexpandafterUD@secondoftwoexpandafterstring%
%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument consists only of a single space-token
%%.............................................................................
newcommandUD@CheckWhetherSingleSpace[1]%
romannumeral0UD@CheckWhetherLeadingSpace#1%
expandafterUD@CheckWhetherNullexpandafterUD@gobblespace#1%
UD@exchangeUD@firstoftwoUD@exchangeUD@secondoftwo%
UD@exchangeUD@secondoftwoUD@exchange expandafter%
%
%makeatother
begindocument
UD@CheckWhetherLeadingSpace textLeading explicit space tokenNo leading explicit space token
UD@CheckWhetherLeadingSpace Leading explicit space tokenNo leading explicit space token
UD@CheckWhetherLeadingSpacetextLeading explicit space tokenNo leading explicit space token
% empty argument:
UD@CheckWhetherLeadingSpaceLeading explicit space tokenNo leading explicit space token
% two space tokens:
expandafterUD@CheckWhetherLeadingSpaceexpandafter@firstofone %
Leading explicit space tokenNo leading explicit space token
noindenthrulefill
UD@CheckWhetherSingleSpace textSingle explicit space tokenNot a single explicit space token
UD@CheckWhetherSingleSpace Single explicit space tokenNot a single explicit space token
UD@CheckWhetherSingleSpacetextSingle explicit space tokenNot a single explicit space token
% empty argument:
UD@CheckWhetherSingleSpaceSingle explicit space tokenNot a single explicit space token
% two space tokens:
expandafterUD@CheckWhetherSingleSpaceexpandafter@firstofone %
Single explicit space tokenNot a single explicit space token
enddocument
answered May 21 at 0:37
Ulrich DiezUlrich Diez
6,082621
6,082621
add a comment |
add a comment |
Thanks for contributing an answer to TeX - LaTeX Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f491668%2fhow-to-test-if-argument-is-a-single-space%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Thanks for the reference to my cuestion :-)
– Raoul Kessels
May 20 at 7:24