Detect empty or null output from xstring's StrBetween
I have some code for formatting names. However, the ifempty
macro from xifthen
is unable to detect empty/null output from xstring
macros such as StrBetween
. The same goes for the equal {}
method. How can I detect empty output from StrBetween
? The below code for some reason compiles and does not work.
documentclass{article}
usepackage{xstring}
usepackage{xifthen}
newcommand{name}{John Doe}
newcommand{middleinitial}{%
StrBetween{name}{ }{.}
}
newcommand{test}{%
ifthenelse{isempty{middleinitial}}%
{Whoo hoo!}%
{Not whoo hoo.}
}
begin{document}
test
end{document}
Any ideas?
xstring xifthen
add a comment |
I have some code for formatting names. However, the ifempty
macro from xifthen
is unable to detect empty/null output from xstring
macros such as StrBetween
. The same goes for the equal {}
method. How can I detect empty output from StrBetween
? The below code for some reason compiles and does not work.
documentclass{article}
usepackage{xstring}
usepackage{xifthen}
newcommand{name}{John Doe}
newcommand{middleinitial}{%
StrBetween{name}{ }{.}
}
newcommand{test}{%
ifthenelse{isempty{middleinitial}}%
{Whoo hoo!}%
{Not whoo hoo.}
}
begin{document}
test
end{document}
Any ideas?
xstring xifthen
add a comment |
I have some code for formatting names. However, the ifempty
macro from xifthen
is unable to detect empty/null output from xstring
macros such as StrBetween
. The same goes for the equal {}
method. How can I detect empty output from StrBetween
? The below code for some reason compiles and does not work.
documentclass{article}
usepackage{xstring}
usepackage{xifthen}
newcommand{name}{John Doe}
newcommand{middleinitial}{%
StrBetween{name}{ }{.}
}
newcommand{test}{%
ifthenelse{isempty{middleinitial}}%
{Whoo hoo!}%
{Not whoo hoo.}
}
begin{document}
test
end{document}
Any ideas?
xstring xifthen
I have some code for formatting names. However, the ifempty
macro from xifthen
is unable to detect empty/null output from xstring
macros such as StrBetween
. The same goes for the equal {}
method. How can I detect empty output from StrBetween
? The below code for some reason compiles and does not work.
documentclass{article}
usepackage{xstring}
usepackage{xifthen}
newcommand{name}{John Doe}
newcommand{middleinitial}{%
StrBetween{name}{ }{.}
}
newcommand{test}{%
ifthenelse{isempty{middleinitial}}%
{Whoo hoo!}%
{Not whoo hoo.}
}
begin{document}
test
end{document}
Any ideas?
xstring xifthen
xstring xifthen
edited 1 hour ago
Adam Erickson
asked 3 hours ago
Adam EricksonAdam Erickson
1558
1558
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
middleinitial
is not expandable, and therefore you cannot properly test whether there is a middle initial in name
or not. You'll have to store the output (the middle initial) first using the optional argument at the end of StrBetween{<str>}{<from>}{<to>}[<macro>]
and then you can check for an empty argument:
documentclass{article}
usepackage{xstring}
newcommand{name}{John Doe}
makeatletter
newcommand{middleinitial}{%
StrBetween{name}{ }{.}[@middleinitial]%
}
newcommand{test}{%
middleinitial% Find middle initial
% https://tex.stackexchange.com/q/53068/5764
expandafterifexpandafterrelaxexpandafterdetokenizeexpandafter{@middleinitial}relax
Whoo hoo!% No middle initial
else
Not whoo hoo.% A middle initial
fi
}
makeatother
begin{document}
test % Whoo hoo.
renewcommand{name}{John F. Doe}%
test % Not whoo hoo!
end{document}
What is this monstrosity:expandafterifexpandafterrelaxexpandafterdetokenizeexpandafter{@middleinitial}relax
?
– Adam Erickson
1 hour ago
add a comment |
Werner already explained, why middleinitial
isn't expandable due to the usage of xstring
macros.
I present a shorter way in order to test for the emptiness of middleinitial
by using ifblank
from etoolbox
package. There are still two expandafter
statements required, but not a bunch of 5 of them. In addition, I find etoolbox
much more convenient than ifthen
or xifthen
.
expandafterifblankexpandafter{middleinitial}{true branch}{false branch}
is necessary, because ifblank
does not expand its first argument, i.e. without expandafter
the macro 'sees' middleinitial
, but not what the content which is stored in that macro. It must be expanded first before ifblank
performs the test.
The expandafter
primitive looks ahead of ifblank
, i.e. it ignores ifblank
first and detects the {
of the first argument. Unfortunately, this is not what is desired (and not expandable anyway), so we must jump over {
again, i.e.
expandafterifblankexpandafter{middleinitial}{...}{...}
will allow TeX/LaTeX to 'jump' over ifblank
to the second expandafter
, that jumps over {
to middleinitial
and expands that sequence -- after this is done, TeX continues with ifblank{expanded version of middleinitial}{...}{...}
and performs the test finally.
documentclass{article}
usepackage{xstring}
usepackage{etoolbox}
newcommand{name}{John C. Doe}
newcommand{othername}{John Doe}
newcommand{testinitial}[3]{%
begingroup
StrBetween{#1}{ }{.}[middleinitial]%
expandafterifblankexpandafter{middleinitial}{#2}{#3}%
endgroup
}
begin{document}
testinitial{name}{Whoo hoo!}{Not whoo hoo.}
testinitial{othername}{Whoo hoo!}{Not whoo hoo.}
end{document}
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%2f469915%2fdetect-empty-or-null-output-from-xstrings-strbetween%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
middleinitial
is not expandable, and therefore you cannot properly test whether there is a middle initial in name
or not. You'll have to store the output (the middle initial) first using the optional argument at the end of StrBetween{<str>}{<from>}{<to>}[<macro>]
and then you can check for an empty argument:
documentclass{article}
usepackage{xstring}
newcommand{name}{John Doe}
makeatletter
newcommand{middleinitial}{%
StrBetween{name}{ }{.}[@middleinitial]%
}
newcommand{test}{%
middleinitial% Find middle initial
% https://tex.stackexchange.com/q/53068/5764
expandafterifexpandafterrelaxexpandafterdetokenizeexpandafter{@middleinitial}relax
Whoo hoo!% No middle initial
else
Not whoo hoo.% A middle initial
fi
}
makeatother
begin{document}
test % Whoo hoo.
renewcommand{name}{John F. Doe}%
test % Not whoo hoo!
end{document}
What is this monstrosity:expandafterifexpandafterrelaxexpandafterdetokenizeexpandafter{@middleinitial}relax
?
– Adam Erickson
1 hour ago
add a comment |
middleinitial
is not expandable, and therefore you cannot properly test whether there is a middle initial in name
or not. You'll have to store the output (the middle initial) first using the optional argument at the end of StrBetween{<str>}{<from>}{<to>}[<macro>]
and then you can check for an empty argument:
documentclass{article}
usepackage{xstring}
newcommand{name}{John Doe}
makeatletter
newcommand{middleinitial}{%
StrBetween{name}{ }{.}[@middleinitial]%
}
newcommand{test}{%
middleinitial% Find middle initial
% https://tex.stackexchange.com/q/53068/5764
expandafterifexpandafterrelaxexpandafterdetokenizeexpandafter{@middleinitial}relax
Whoo hoo!% No middle initial
else
Not whoo hoo.% A middle initial
fi
}
makeatother
begin{document}
test % Whoo hoo.
renewcommand{name}{John F. Doe}%
test % Not whoo hoo!
end{document}
What is this monstrosity:expandafterifexpandafterrelaxexpandafterdetokenizeexpandafter{@middleinitial}relax
?
– Adam Erickson
1 hour ago
add a comment |
middleinitial
is not expandable, and therefore you cannot properly test whether there is a middle initial in name
or not. You'll have to store the output (the middle initial) first using the optional argument at the end of StrBetween{<str>}{<from>}{<to>}[<macro>]
and then you can check for an empty argument:
documentclass{article}
usepackage{xstring}
newcommand{name}{John Doe}
makeatletter
newcommand{middleinitial}{%
StrBetween{name}{ }{.}[@middleinitial]%
}
newcommand{test}{%
middleinitial% Find middle initial
% https://tex.stackexchange.com/q/53068/5764
expandafterifexpandafterrelaxexpandafterdetokenizeexpandafter{@middleinitial}relax
Whoo hoo!% No middle initial
else
Not whoo hoo.% A middle initial
fi
}
makeatother
begin{document}
test % Whoo hoo.
renewcommand{name}{John F. Doe}%
test % Not whoo hoo!
end{document}
middleinitial
is not expandable, and therefore you cannot properly test whether there is a middle initial in name
or not. You'll have to store the output (the middle initial) first using the optional argument at the end of StrBetween{<str>}{<from>}{<to>}[<macro>]
and then you can check for an empty argument:
documentclass{article}
usepackage{xstring}
newcommand{name}{John Doe}
makeatletter
newcommand{middleinitial}{%
StrBetween{name}{ }{.}[@middleinitial]%
}
newcommand{test}{%
middleinitial% Find middle initial
% https://tex.stackexchange.com/q/53068/5764
expandafterifexpandafterrelaxexpandafterdetokenizeexpandafter{@middleinitial}relax
Whoo hoo!% No middle initial
else
Not whoo hoo.% A middle initial
fi
}
makeatother
begin{document}
test % Whoo hoo.
renewcommand{name}{John F. Doe}%
test % Not whoo hoo!
end{document}
answered 2 hours ago
WernerWerner
439k659651658
439k659651658
What is this monstrosity:expandafterifexpandafterrelaxexpandafterdetokenizeexpandafter{@middleinitial}relax
?
– Adam Erickson
1 hour ago
add a comment |
What is this monstrosity:expandafterifexpandafterrelaxexpandafterdetokenizeexpandafter{@middleinitial}relax
?
– Adam Erickson
1 hour ago
What is this monstrosity:
expandafterifexpandafterrelaxexpandafterdetokenizeexpandafter{@middleinitial}relax
?– Adam Erickson
1 hour ago
What is this monstrosity:
expandafterifexpandafterrelaxexpandafterdetokenizeexpandafter{@middleinitial}relax
?– Adam Erickson
1 hour ago
add a comment |
Werner already explained, why middleinitial
isn't expandable due to the usage of xstring
macros.
I present a shorter way in order to test for the emptiness of middleinitial
by using ifblank
from etoolbox
package. There are still two expandafter
statements required, but not a bunch of 5 of them. In addition, I find etoolbox
much more convenient than ifthen
or xifthen
.
expandafterifblankexpandafter{middleinitial}{true branch}{false branch}
is necessary, because ifblank
does not expand its first argument, i.e. without expandafter
the macro 'sees' middleinitial
, but not what the content which is stored in that macro. It must be expanded first before ifblank
performs the test.
The expandafter
primitive looks ahead of ifblank
, i.e. it ignores ifblank
first and detects the {
of the first argument. Unfortunately, this is not what is desired (and not expandable anyway), so we must jump over {
again, i.e.
expandafterifblankexpandafter{middleinitial}{...}{...}
will allow TeX/LaTeX to 'jump' over ifblank
to the second expandafter
, that jumps over {
to middleinitial
and expands that sequence -- after this is done, TeX continues with ifblank{expanded version of middleinitial}{...}{...}
and performs the test finally.
documentclass{article}
usepackage{xstring}
usepackage{etoolbox}
newcommand{name}{John C. Doe}
newcommand{othername}{John Doe}
newcommand{testinitial}[3]{%
begingroup
StrBetween{#1}{ }{.}[middleinitial]%
expandafterifblankexpandafter{middleinitial}{#2}{#3}%
endgroup
}
begin{document}
testinitial{name}{Whoo hoo!}{Not whoo hoo.}
testinitial{othername}{Whoo hoo!}{Not whoo hoo.}
end{document}
add a comment |
Werner already explained, why middleinitial
isn't expandable due to the usage of xstring
macros.
I present a shorter way in order to test for the emptiness of middleinitial
by using ifblank
from etoolbox
package. There are still two expandafter
statements required, but not a bunch of 5 of them. In addition, I find etoolbox
much more convenient than ifthen
or xifthen
.
expandafterifblankexpandafter{middleinitial}{true branch}{false branch}
is necessary, because ifblank
does not expand its first argument, i.e. without expandafter
the macro 'sees' middleinitial
, but not what the content which is stored in that macro. It must be expanded first before ifblank
performs the test.
The expandafter
primitive looks ahead of ifblank
, i.e. it ignores ifblank
first and detects the {
of the first argument. Unfortunately, this is not what is desired (and not expandable anyway), so we must jump over {
again, i.e.
expandafterifblankexpandafter{middleinitial}{...}{...}
will allow TeX/LaTeX to 'jump' over ifblank
to the second expandafter
, that jumps over {
to middleinitial
and expands that sequence -- after this is done, TeX continues with ifblank{expanded version of middleinitial}{...}{...}
and performs the test finally.
documentclass{article}
usepackage{xstring}
usepackage{etoolbox}
newcommand{name}{John C. Doe}
newcommand{othername}{John Doe}
newcommand{testinitial}[3]{%
begingroup
StrBetween{#1}{ }{.}[middleinitial]%
expandafterifblankexpandafter{middleinitial}{#2}{#3}%
endgroup
}
begin{document}
testinitial{name}{Whoo hoo!}{Not whoo hoo.}
testinitial{othername}{Whoo hoo!}{Not whoo hoo.}
end{document}
add a comment |
Werner already explained, why middleinitial
isn't expandable due to the usage of xstring
macros.
I present a shorter way in order to test for the emptiness of middleinitial
by using ifblank
from etoolbox
package. There are still two expandafter
statements required, but not a bunch of 5 of them. In addition, I find etoolbox
much more convenient than ifthen
or xifthen
.
expandafterifblankexpandafter{middleinitial}{true branch}{false branch}
is necessary, because ifblank
does not expand its first argument, i.e. without expandafter
the macro 'sees' middleinitial
, but not what the content which is stored in that macro. It must be expanded first before ifblank
performs the test.
The expandafter
primitive looks ahead of ifblank
, i.e. it ignores ifblank
first and detects the {
of the first argument. Unfortunately, this is not what is desired (and not expandable anyway), so we must jump over {
again, i.e.
expandafterifblankexpandafter{middleinitial}{...}{...}
will allow TeX/LaTeX to 'jump' over ifblank
to the second expandafter
, that jumps over {
to middleinitial
and expands that sequence -- after this is done, TeX continues with ifblank{expanded version of middleinitial}{...}{...}
and performs the test finally.
documentclass{article}
usepackage{xstring}
usepackage{etoolbox}
newcommand{name}{John C. Doe}
newcommand{othername}{John Doe}
newcommand{testinitial}[3]{%
begingroup
StrBetween{#1}{ }{.}[middleinitial]%
expandafterifblankexpandafter{middleinitial}{#2}{#3}%
endgroup
}
begin{document}
testinitial{name}{Whoo hoo!}{Not whoo hoo.}
testinitial{othername}{Whoo hoo!}{Not whoo hoo.}
end{document}
Werner already explained, why middleinitial
isn't expandable due to the usage of xstring
macros.
I present a shorter way in order to test for the emptiness of middleinitial
by using ifblank
from etoolbox
package. There are still two expandafter
statements required, but not a bunch of 5 of them. In addition, I find etoolbox
much more convenient than ifthen
or xifthen
.
expandafterifblankexpandafter{middleinitial}{true branch}{false branch}
is necessary, because ifblank
does not expand its first argument, i.e. without expandafter
the macro 'sees' middleinitial
, but not what the content which is stored in that macro. It must be expanded first before ifblank
performs the test.
The expandafter
primitive looks ahead of ifblank
, i.e. it ignores ifblank
first and detects the {
of the first argument. Unfortunately, this is not what is desired (and not expandable anyway), so we must jump over {
again, i.e.
expandafterifblankexpandafter{middleinitial}{...}{...}
will allow TeX/LaTeX to 'jump' over ifblank
to the second expandafter
, that jumps over {
to middleinitial
and expands that sequence -- after this is done, TeX continues with ifblank{expanded version of middleinitial}{...}{...}
and performs the test finally.
documentclass{article}
usepackage{xstring}
usepackage{etoolbox}
newcommand{name}{John C. Doe}
newcommand{othername}{John Doe}
newcommand{testinitial}[3]{%
begingroup
StrBetween{#1}{ }{.}[middleinitial]%
expandafterifblankexpandafter{middleinitial}{#2}{#3}%
endgroup
}
begin{document}
testinitial{name}{Whoo hoo!}{Not whoo hoo.}
testinitial{othername}{Whoo hoo!}{Not whoo hoo.}
end{document}
edited 3 mins ago
answered 21 mins ago
Christian HupferChristian Hupfer
149k14193390
149k14193390
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%2f469915%2fdetect-empty-or-null-output-from-xstrings-strbetween%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