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 4 mins ago
answered 22 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