How to compare a string to a cs from a read properly?












5















The scenario: reading a date in a yyyy-mm-dd form from a file to a cs. This cs later gets compared to a 'current date' macro to write a few args in a specific way to an external file. The current day macro is along the lines of



% defTODAY{}
% defToday{theyear-TwoDigits{themonth}-TwoDigits{theday} }
defTODAY{xdefToday{theyear-TwoDigits{themonth}-TwoDigits{theday}}}


This works for the labeling things, since ref{yyyy-mm-dd} works as intended. Having no extra TODAY and then using def'd Today does so to, it's the comparison that's not working. etoolbox's ifstrequal is not what I used before. Whenever the date would change I used a single xdef and later passed that macro to a ifx, and to get it to work I had to define the date with a appended. edit Read to my amazement inserts a single space after whatever's been read.



Currently I'm supposedly fixing things, but I broke it somehow, and now it doesn't match at all. The first culprit was the my TwoDigits cmd was robust, changing it back to def instead of NewDocumentCommand fixed that. The latter is for user-level commands, so I'll let that slip. But the results of the mwe are not clear to me.



0.txt contains one line with 2001-01-01 and a line new afterwards, as if one line had been written to it and the output had been closed.



The questions:




  1. What the 'right' way to compare things (macro, cs, command?) are that (should) expand to strings?

  2. Why don't edef, xdef work here, I thought it was a full expansion, and indeed before (my version control is nigh absent so I can't give a mwe for this) it worked.

  3. What is the significance of robustness? Is there a simple rule of thumb when it's necessary, obligatory, or irrelevant?

  4. It working with xstring's IfStrEqual only if the is inserted in the definition of datemacro, rather than in the comparison's brackets, i.e., {datemacro }. Why?


  5. ifstrequal supposedly doesn't expand- I used once in a command to test if an arguments is equal to &, this works- is #1 becoming whatever was input not count as an expansion?


edit: I forgot ifx was used for macros, not delimited arguments, sorry.



example 1;



documentclass{article}
usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
usepackage{etoolbox}
newreadperiods
openinperiods=0.txt
begin{document}setlengthparindent{0pt}fontsize{20}{20}selectfont
deftesti{2001-01-01}
edeftestii{2001-01-01}
deftestiii{2001-01-01 }
edeftestiiii{2001-01-01 }
globalreadperiods to DDD

ifstrequal{testi}{2001-01-01}{T\}{F\}% F
ifstrequal{testii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiiii}{2001-01-01}{T\}{F\}% F
ifstrequal{DDD}{2001-01-01}{T\}{F\}% F

ifstrequal{testi}{DDD}{T\}{F\}% F
ifstrequal{testii}{DDD}{T\}{F\}% F
ifstrequal{testiii}{DDD}{T\}{F\}% F
ifstrequal{testiiii}{DDD}{T\}{F\}% F
ifstrequal{DDD}{DDD}{T\}{F\}% T

ifx{testi}{2001-01-01} T\else F\fi% F
ifx{testii}{2001-01-01} T\else F\fi% F
ifx{testiii}{2001-01-01} T\else F\fi% F
ifx{testiiii}{2001-01-01} T\else F\fi% F
ifx{DDD}{2001-01-01} T\else F\fi% F

ifx{testi}{DDD} T\else F\fi% F
ifx{testii}{DDD} T\else F\fi% F
ifx{testiii}{DDD} T\else F\fi% F
ifx{testiiii}{DDD} T\else F\fi% F
ifx{DDD}{DDD} T\else F\fi% F

ifcsequal{testi}{DDD}{T\}{F\}% F
ifcsequal{testii}{DDD}{T\}{F\}% F
ifcsequal{testiii}{DDD}{T\}{F\}% F
ifcsequal{testiiii}{DDD}{T\}{F\}% F
ifcsequal{DDD}{DDD}{T\}{F\}% F

ifdefequal{testi}{DDD}{T\}{F\}% F
ifdefequal{testii}{DDD}{T\}{F\}% F
ifdefequal{testiii}{DDD}{T\}{F\}% T
ifdefequal{testiiii}{DDD}{T\}{F\}% T
ifdefequal{DDD}{DDD}{T\}{F\}% T
end{document}


example 2;



documentclass{article}
usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
usepackage{etoolbox,xstring}
defTwoDigits#1{ifnum#1<10 0#1else#1fi}

newcountmonth
month 1relax
newcountday
day 1relax
newreadperiods
openinperiods=0.txt
globalreadperiods to DDD

deftesti{2001-TwoDigits{themonth}-TwoDigits{theday}}%
edeftestii{2001-TwoDigits{themonth}-TwoDigits{theday}}%
deftestiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%
edeftestiiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%

begin{document}setlengthparindent{0pt}
DDD is DDD.% space between cs and .

ifstrequal{testi}{2001-01-01}{T\}{F\}% F
ifstrequal{testii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiiii}{2001-01-01}{T\}{F\}% F
ifstrequal{DDD}{2001-01-01}{T\}{F\}% F

ifstrequal{testi}{DDD}{T\}{F\}% F
ifstrequal{testii}{DDD}{T\}{F\}% F
ifstrequal{testiii}{DDD}{T\}{F\}% F
ifstrequal{testiiii}{DDD}{T\}{F\}% F
ifstrequal{DDD}{DDD}{T\}{F\}% T

ifxtesti{2001-01-01} T\else F\fi% F
ifxtestii{2001-01-01} T\else F\fi% F
ifxtestiii{2001-01-01} T\else F\fi% F
ifxtestiiii{2001-01-01} T\else F\fi% F
ifxDDD{2001-01-01} T\else F\fi% F

ifxtestiDDD T\else F\fi% F
ifxtestiiDDD T\else F\fi% F
ifxtestiiiDDD T\else F\fi% F
ifxtestiiiiDDD T\else F\fi% T
ifxDDDDDD T\else F\fi% T

ifcsequal{testi}{DDD}{T\}{F\}% F
ifcsequal{testii}{DDD}{T\}{F\}% F
ifcsequal{testiii}{DDD}{T\}{F\}% F
ifcsequal{testiiii}{DDD}{T\}{F\}% F
ifcsequal{DDD}{DDD}{T\}{F\}% F

ifdefequal{testi}{DDD}{T\}{F\}% F
ifdefequal{testii}{DDD}{T\}{F\}% F
ifdefequal{testiii}{DDD}{T\}{F\}% F
ifdefequal{testiiii}{DDD}{T\}{F\}% T
ifdefequal{DDD}{DDD}{T\}{F\}% T

IfStrEq{testi}{DDD}{T\}{F\}% F
IfStrEq{testii}{DDD}{T\}{F\}% F
IfStrEq{testi }{DDD}{T\}{F\}% F
IfStrEq{testii }{DDD}{T\}{F\}% F
IfStrEq{testiii}{DDD}{T\}{F\}% T
IfStrEq{testiiii}{DDD}{T\}{F\}% T
IfStrEq{DDD}{DDD}{T\}{F\}% T

end{document}









share|improve this question




















  • 1





    ifx{testi}... compares { with testi. Be careful with primitive TeX conditionals.

    – egreg
    Mar 11 at 7:19
















5















The scenario: reading a date in a yyyy-mm-dd form from a file to a cs. This cs later gets compared to a 'current date' macro to write a few args in a specific way to an external file. The current day macro is along the lines of



% defTODAY{}
% defToday{theyear-TwoDigits{themonth}-TwoDigits{theday} }
defTODAY{xdefToday{theyear-TwoDigits{themonth}-TwoDigits{theday}}}


This works for the labeling things, since ref{yyyy-mm-dd} works as intended. Having no extra TODAY and then using def'd Today does so to, it's the comparison that's not working. etoolbox's ifstrequal is not what I used before. Whenever the date would change I used a single xdef and later passed that macro to a ifx, and to get it to work I had to define the date with a appended. edit Read to my amazement inserts a single space after whatever's been read.



Currently I'm supposedly fixing things, but I broke it somehow, and now it doesn't match at all. The first culprit was the my TwoDigits cmd was robust, changing it back to def instead of NewDocumentCommand fixed that. The latter is for user-level commands, so I'll let that slip. But the results of the mwe are not clear to me.



0.txt contains one line with 2001-01-01 and a line new afterwards, as if one line had been written to it and the output had been closed.



The questions:




  1. What the 'right' way to compare things (macro, cs, command?) are that (should) expand to strings?

  2. Why don't edef, xdef work here, I thought it was a full expansion, and indeed before (my version control is nigh absent so I can't give a mwe for this) it worked.

  3. What is the significance of robustness? Is there a simple rule of thumb when it's necessary, obligatory, or irrelevant?

  4. It working with xstring's IfStrEqual only if the is inserted in the definition of datemacro, rather than in the comparison's brackets, i.e., {datemacro }. Why?


  5. ifstrequal supposedly doesn't expand- I used once in a command to test if an arguments is equal to &, this works- is #1 becoming whatever was input not count as an expansion?


edit: I forgot ifx was used for macros, not delimited arguments, sorry.



example 1;



documentclass{article}
usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
usepackage{etoolbox}
newreadperiods
openinperiods=0.txt
begin{document}setlengthparindent{0pt}fontsize{20}{20}selectfont
deftesti{2001-01-01}
edeftestii{2001-01-01}
deftestiii{2001-01-01 }
edeftestiiii{2001-01-01 }
globalreadperiods to DDD

ifstrequal{testi}{2001-01-01}{T\}{F\}% F
ifstrequal{testii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiiii}{2001-01-01}{T\}{F\}% F
ifstrequal{DDD}{2001-01-01}{T\}{F\}% F

ifstrequal{testi}{DDD}{T\}{F\}% F
ifstrequal{testii}{DDD}{T\}{F\}% F
ifstrequal{testiii}{DDD}{T\}{F\}% F
ifstrequal{testiiii}{DDD}{T\}{F\}% F
ifstrequal{DDD}{DDD}{T\}{F\}% T

ifx{testi}{2001-01-01} T\else F\fi% F
ifx{testii}{2001-01-01} T\else F\fi% F
ifx{testiii}{2001-01-01} T\else F\fi% F
ifx{testiiii}{2001-01-01} T\else F\fi% F
ifx{DDD}{2001-01-01} T\else F\fi% F

ifx{testi}{DDD} T\else F\fi% F
ifx{testii}{DDD} T\else F\fi% F
ifx{testiii}{DDD} T\else F\fi% F
ifx{testiiii}{DDD} T\else F\fi% F
ifx{DDD}{DDD} T\else F\fi% F

ifcsequal{testi}{DDD}{T\}{F\}% F
ifcsequal{testii}{DDD}{T\}{F\}% F
ifcsequal{testiii}{DDD}{T\}{F\}% F
ifcsequal{testiiii}{DDD}{T\}{F\}% F
ifcsequal{DDD}{DDD}{T\}{F\}% F

ifdefequal{testi}{DDD}{T\}{F\}% F
ifdefequal{testii}{DDD}{T\}{F\}% F
ifdefequal{testiii}{DDD}{T\}{F\}% T
ifdefequal{testiiii}{DDD}{T\}{F\}% T
ifdefequal{DDD}{DDD}{T\}{F\}% T
end{document}


example 2;



documentclass{article}
usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
usepackage{etoolbox,xstring}
defTwoDigits#1{ifnum#1<10 0#1else#1fi}

newcountmonth
month 1relax
newcountday
day 1relax
newreadperiods
openinperiods=0.txt
globalreadperiods to DDD

deftesti{2001-TwoDigits{themonth}-TwoDigits{theday}}%
edeftestii{2001-TwoDigits{themonth}-TwoDigits{theday}}%
deftestiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%
edeftestiiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%

begin{document}setlengthparindent{0pt}
DDD is DDD.% space between cs and .

ifstrequal{testi}{2001-01-01}{T\}{F\}% F
ifstrequal{testii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiiii}{2001-01-01}{T\}{F\}% F
ifstrequal{DDD}{2001-01-01}{T\}{F\}% F

ifstrequal{testi}{DDD}{T\}{F\}% F
ifstrequal{testii}{DDD}{T\}{F\}% F
ifstrequal{testiii}{DDD}{T\}{F\}% F
ifstrequal{testiiii}{DDD}{T\}{F\}% F
ifstrequal{DDD}{DDD}{T\}{F\}% T

ifxtesti{2001-01-01} T\else F\fi% F
ifxtestii{2001-01-01} T\else F\fi% F
ifxtestiii{2001-01-01} T\else F\fi% F
ifxtestiiii{2001-01-01} T\else F\fi% F
ifxDDD{2001-01-01} T\else F\fi% F

ifxtestiDDD T\else F\fi% F
ifxtestiiDDD T\else F\fi% F
ifxtestiiiDDD T\else F\fi% F
ifxtestiiiiDDD T\else F\fi% T
ifxDDDDDD T\else F\fi% T

ifcsequal{testi}{DDD}{T\}{F\}% F
ifcsequal{testii}{DDD}{T\}{F\}% F
ifcsequal{testiii}{DDD}{T\}{F\}% F
ifcsequal{testiiii}{DDD}{T\}{F\}% F
ifcsequal{DDD}{DDD}{T\}{F\}% F

ifdefequal{testi}{DDD}{T\}{F\}% F
ifdefequal{testii}{DDD}{T\}{F\}% F
ifdefequal{testiii}{DDD}{T\}{F\}% F
ifdefequal{testiiii}{DDD}{T\}{F\}% T
ifdefequal{DDD}{DDD}{T\}{F\}% T

IfStrEq{testi}{DDD}{T\}{F\}% F
IfStrEq{testii}{DDD}{T\}{F\}% F
IfStrEq{testi }{DDD}{T\}{F\}% F
IfStrEq{testii }{DDD}{T\}{F\}% F
IfStrEq{testiii}{DDD}{T\}{F\}% T
IfStrEq{testiiii}{DDD}{T\}{F\}% T
IfStrEq{DDD}{DDD}{T\}{F\}% T

end{document}









share|improve this question




















  • 1





    ifx{testi}... compares { with testi. Be careful with primitive TeX conditionals.

    – egreg
    Mar 11 at 7:19














5












5








5


1






The scenario: reading a date in a yyyy-mm-dd form from a file to a cs. This cs later gets compared to a 'current date' macro to write a few args in a specific way to an external file. The current day macro is along the lines of



% defTODAY{}
% defToday{theyear-TwoDigits{themonth}-TwoDigits{theday} }
defTODAY{xdefToday{theyear-TwoDigits{themonth}-TwoDigits{theday}}}


This works for the labeling things, since ref{yyyy-mm-dd} works as intended. Having no extra TODAY and then using def'd Today does so to, it's the comparison that's not working. etoolbox's ifstrequal is not what I used before. Whenever the date would change I used a single xdef and later passed that macro to a ifx, and to get it to work I had to define the date with a appended. edit Read to my amazement inserts a single space after whatever's been read.



Currently I'm supposedly fixing things, but I broke it somehow, and now it doesn't match at all. The first culprit was the my TwoDigits cmd was robust, changing it back to def instead of NewDocumentCommand fixed that. The latter is for user-level commands, so I'll let that slip. But the results of the mwe are not clear to me.



0.txt contains one line with 2001-01-01 and a line new afterwards, as if one line had been written to it and the output had been closed.



The questions:




  1. What the 'right' way to compare things (macro, cs, command?) are that (should) expand to strings?

  2. Why don't edef, xdef work here, I thought it was a full expansion, and indeed before (my version control is nigh absent so I can't give a mwe for this) it worked.

  3. What is the significance of robustness? Is there a simple rule of thumb when it's necessary, obligatory, or irrelevant?

  4. It working with xstring's IfStrEqual only if the is inserted in the definition of datemacro, rather than in the comparison's brackets, i.e., {datemacro }. Why?


  5. ifstrequal supposedly doesn't expand- I used once in a command to test if an arguments is equal to &, this works- is #1 becoming whatever was input not count as an expansion?


edit: I forgot ifx was used for macros, not delimited arguments, sorry.



example 1;



documentclass{article}
usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
usepackage{etoolbox}
newreadperiods
openinperiods=0.txt
begin{document}setlengthparindent{0pt}fontsize{20}{20}selectfont
deftesti{2001-01-01}
edeftestii{2001-01-01}
deftestiii{2001-01-01 }
edeftestiiii{2001-01-01 }
globalreadperiods to DDD

ifstrequal{testi}{2001-01-01}{T\}{F\}% F
ifstrequal{testii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiiii}{2001-01-01}{T\}{F\}% F
ifstrequal{DDD}{2001-01-01}{T\}{F\}% F

ifstrequal{testi}{DDD}{T\}{F\}% F
ifstrequal{testii}{DDD}{T\}{F\}% F
ifstrequal{testiii}{DDD}{T\}{F\}% F
ifstrequal{testiiii}{DDD}{T\}{F\}% F
ifstrequal{DDD}{DDD}{T\}{F\}% T

ifx{testi}{2001-01-01} T\else F\fi% F
ifx{testii}{2001-01-01} T\else F\fi% F
ifx{testiii}{2001-01-01} T\else F\fi% F
ifx{testiiii}{2001-01-01} T\else F\fi% F
ifx{DDD}{2001-01-01} T\else F\fi% F

ifx{testi}{DDD} T\else F\fi% F
ifx{testii}{DDD} T\else F\fi% F
ifx{testiii}{DDD} T\else F\fi% F
ifx{testiiii}{DDD} T\else F\fi% F
ifx{DDD}{DDD} T\else F\fi% F

ifcsequal{testi}{DDD}{T\}{F\}% F
ifcsequal{testii}{DDD}{T\}{F\}% F
ifcsequal{testiii}{DDD}{T\}{F\}% F
ifcsequal{testiiii}{DDD}{T\}{F\}% F
ifcsequal{DDD}{DDD}{T\}{F\}% F

ifdefequal{testi}{DDD}{T\}{F\}% F
ifdefequal{testii}{DDD}{T\}{F\}% F
ifdefequal{testiii}{DDD}{T\}{F\}% T
ifdefequal{testiiii}{DDD}{T\}{F\}% T
ifdefequal{DDD}{DDD}{T\}{F\}% T
end{document}


example 2;



documentclass{article}
usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
usepackage{etoolbox,xstring}
defTwoDigits#1{ifnum#1<10 0#1else#1fi}

newcountmonth
month 1relax
newcountday
day 1relax
newreadperiods
openinperiods=0.txt
globalreadperiods to DDD

deftesti{2001-TwoDigits{themonth}-TwoDigits{theday}}%
edeftestii{2001-TwoDigits{themonth}-TwoDigits{theday}}%
deftestiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%
edeftestiiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%

begin{document}setlengthparindent{0pt}
DDD is DDD.% space between cs and .

ifstrequal{testi}{2001-01-01}{T\}{F\}% F
ifstrequal{testii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiiii}{2001-01-01}{T\}{F\}% F
ifstrequal{DDD}{2001-01-01}{T\}{F\}% F

ifstrequal{testi}{DDD}{T\}{F\}% F
ifstrequal{testii}{DDD}{T\}{F\}% F
ifstrequal{testiii}{DDD}{T\}{F\}% F
ifstrequal{testiiii}{DDD}{T\}{F\}% F
ifstrequal{DDD}{DDD}{T\}{F\}% T

ifxtesti{2001-01-01} T\else F\fi% F
ifxtestii{2001-01-01} T\else F\fi% F
ifxtestiii{2001-01-01} T\else F\fi% F
ifxtestiiii{2001-01-01} T\else F\fi% F
ifxDDD{2001-01-01} T\else F\fi% F

ifxtestiDDD T\else F\fi% F
ifxtestiiDDD T\else F\fi% F
ifxtestiiiDDD T\else F\fi% F
ifxtestiiiiDDD T\else F\fi% T
ifxDDDDDD T\else F\fi% T

ifcsequal{testi}{DDD}{T\}{F\}% F
ifcsequal{testii}{DDD}{T\}{F\}% F
ifcsequal{testiii}{DDD}{T\}{F\}% F
ifcsequal{testiiii}{DDD}{T\}{F\}% F
ifcsequal{DDD}{DDD}{T\}{F\}% F

ifdefequal{testi}{DDD}{T\}{F\}% F
ifdefequal{testii}{DDD}{T\}{F\}% F
ifdefequal{testiii}{DDD}{T\}{F\}% F
ifdefequal{testiiii}{DDD}{T\}{F\}% T
ifdefequal{DDD}{DDD}{T\}{F\}% T

IfStrEq{testi}{DDD}{T\}{F\}% F
IfStrEq{testii}{DDD}{T\}{F\}% F
IfStrEq{testi }{DDD}{T\}{F\}% F
IfStrEq{testii }{DDD}{T\}{F\}% F
IfStrEq{testiii}{DDD}{T\}{F\}% T
IfStrEq{testiiii}{DDD}{T\}{F\}% T
IfStrEq{DDD}{DDD}{T\}{F\}% T

end{document}









share|improve this question
















The scenario: reading a date in a yyyy-mm-dd form from a file to a cs. This cs later gets compared to a 'current date' macro to write a few args in a specific way to an external file. The current day macro is along the lines of



% defTODAY{}
% defToday{theyear-TwoDigits{themonth}-TwoDigits{theday} }
defTODAY{xdefToday{theyear-TwoDigits{themonth}-TwoDigits{theday}}}


This works for the labeling things, since ref{yyyy-mm-dd} works as intended. Having no extra TODAY and then using def'd Today does so to, it's the comparison that's not working. etoolbox's ifstrequal is not what I used before. Whenever the date would change I used a single xdef and later passed that macro to a ifx, and to get it to work I had to define the date with a appended. edit Read to my amazement inserts a single space after whatever's been read.



Currently I'm supposedly fixing things, but I broke it somehow, and now it doesn't match at all. The first culprit was the my TwoDigits cmd was robust, changing it back to def instead of NewDocumentCommand fixed that. The latter is for user-level commands, so I'll let that slip. But the results of the mwe are not clear to me.



0.txt contains one line with 2001-01-01 and a line new afterwards, as if one line had been written to it and the output had been closed.



The questions:




  1. What the 'right' way to compare things (macro, cs, command?) are that (should) expand to strings?

  2. Why don't edef, xdef work here, I thought it was a full expansion, and indeed before (my version control is nigh absent so I can't give a mwe for this) it worked.

  3. What is the significance of robustness? Is there a simple rule of thumb when it's necessary, obligatory, or irrelevant?

  4. It working with xstring's IfStrEqual only if the is inserted in the definition of datemacro, rather than in the comparison's brackets, i.e., {datemacro }. Why?


  5. ifstrequal supposedly doesn't expand- I used once in a command to test if an arguments is equal to &, this works- is #1 becoming whatever was input not count as an expansion?


edit: I forgot ifx was used for macros, not delimited arguments, sorry.



example 1;



documentclass{article}
usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
usepackage{etoolbox}
newreadperiods
openinperiods=0.txt
begin{document}setlengthparindent{0pt}fontsize{20}{20}selectfont
deftesti{2001-01-01}
edeftestii{2001-01-01}
deftestiii{2001-01-01 }
edeftestiiii{2001-01-01 }
globalreadperiods to DDD

ifstrequal{testi}{2001-01-01}{T\}{F\}% F
ifstrequal{testii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiiii}{2001-01-01}{T\}{F\}% F
ifstrequal{DDD}{2001-01-01}{T\}{F\}% F

ifstrequal{testi}{DDD}{T\}{F\}% F
ifstrequal{testii}{DDD}{T\}{F\}% F
ifstrequal{testiii}{DDD}{T\}{F\}% F
ifstrequal{testiiii}{DDD}{T\}{F\}% F
ifstrequal{DDD}{DDD}{T\}{F\}% T

ifx{testi}{2001-01-01} T\else F\fi% F
ifx{testii}{2001-01-01} T\else F\fi% F
ifx{testiii}{2001-01-01} T\else F\fi% F
ifx{testiiii}{2001-01-01} T\else F\fi% F
ifx{DDD}{2001-01-01} T\else F\fi% F

ifx{testi}{DDD} T\else F\fi% F
ifx{testii}{DDD} T\else F\fi% F
ifx{testiii}{DDD} T\else F\fi% F
ifx{testiiii}{DDD} T\else F\fi% F
ifx{DDD}{DDD} T\else F\fi% F

ifcsequal{testi}{DDD}{T\}{F\}% F
ifcsequal{testii}{DDD}{T\}{F\}% F
ifcsequal{testiii}{DDD}{T\}{F\}% F
ifcsequal{testiiii}{DDD}{T\}{F\}% F
ifcsequal{DDD}{DDD}{T\}{F\}% F

ifdefequal{testi}{DDD}{T\}{F\}% F
ifdefequal{testii}{DDD}{T\}{F\}% F
ifdefequal{testiii}{DDD}{T\}{F\}% T
ifdefequal{testiiii}{DDD}{T\}{F\}% T
ifdefequal{DDD}{DDD}{T\}{F\}% T
end{document}


example 2;



documentclass{article}
usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
usepackage{etoolbox,xstring}
defTwoDigits#1{ifnum#1<10 0#1else#1fi}

newcountmonth
month 1relax
newcountday
day 1relax
newreadperiods
openinperiods=0.txt
globalreadperiods to DDD

deftesti{2001-TwoDigits{themonth}-TwoDigits{theday}}%
edeftestii{2001-TwoDigits{themonth}-TwoDigits{theday}}%
deftestiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%
edeftestiiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%

begin{document}setlengthparindent{0pt}
DDD is DDD.% space between cs and .

ifstrequal{testi}{2001-01-01}{T\}{F\}% F
ifstrequal{testii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiii}{2001-01-01}{T\}{F\}% F
ifstrequal{testiiii}{2001-01-01}{T\}{F\}% F
ifstrequal{DDD}{2001-01-01}{T\}{F\}% F

ifstrequal{testi}{DDD}{T\}{F\}% F
ifstrequal{testii}{DDD}{T\}{F\}% F
ifstrequal{testiii}{DDD}{T\}{F\}% F
ifstrequal{testiiii}{DDD}{T\}{F\}% F
ifstrequal{DDD}{DDD}{T\}{F\}% T

ifxtesti{2001-01-01} T\else F\fi% F
ifxtestii{2001-01-01} T\else F\fi% F
ifxtestiii{2001-01-01} T\else F\fi% F
ifxtestiiii{2001-01-01} T\else F\fi% F
ifxDDD{2001-01-01} T\else F\fi% F

ifxtestiDDD T\else F\fi% F
ifxtestiiDDD T\else F\fi% F
ifxtestiiiDDD T\else F\fi% F
ifxtestiiiiDDD T\else F\fi% T
ifxDDDDDD T\else F\fi% T

ifcsequal{testi}{DDD}{T\}{F\}% F
ifcsequal{testii}{DDD}{T\}{F\}% F
ifcsequal{testiii}{DDD}{T\}{F\}% F
ifcsequal{testiiii}{DDD}{T\}{F\}% F
ifcsequal{DDD}{DDD}{T\}{F\}% F

ifdefequal{testi}{DDD}{T\}{F\}% F
ifdefequal{testii}{DDD}{T\}{F\}% F
ifdefequal{testiii}{DDD}{T\}{F\}% F
ifdefequal{testiiii}{DDD}{T\}{F\}% T
ifdefequal{DDD}{DDD}{T\}{F\}% T

IfStrEq{testi}{DDD}{T\}{F\}% F
IfStrEq{testii}{DDD}{T\}{F\}% F
IfStrEq{testi }{DDD}{T\}{F\}% F
IfStrEq{testii }{DDD}{T\}{F\}% F
IfStrEq{testiii}{DDD}{T\}{F\}% T
IfStrEq{testiiii}{DDD}{T\}{F\}% T
IfStrEq{DDD}{DDD}{T\}{F\}% T

end{document}






conditionals etoolbox strings xstring






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 11 at 7:39







vlg

















asked Mar 11 at 6:00









vlgvlg

1419




1419








  • 1





    ifx{testi}... compares { with testi. Be careful with primitive TeX conditionals.

    – egreg
    Mar 11 at 7:19














  • 1





    ifx{testi}... compares { with testi. Be careful with primitive TeX conditionals.

    – egreg
    Mar 11 at 7:19








1




1





ifx{testi}... compares { with testi. Be careful with primitive TeX conditionals.

– egreg
Mar 11 at 7:19





ifx{testi}... compares { with testi. Be careful with primitive TeX conditionals.

– egreg
Mar 11 at 7:19










1 Answer
1






active

oldest

votes


















4














ifstrequal



From the documentation of etoolbox:




ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}

Compares two strings and executes ⟨true⟩ if they are equal, and ⟨false⟩ otherwise. The strings are not expanded in the test and the comparison is category code agnos- tic. Control sequence tokens in any of the ⟨string⟩ arguments will be detokenized and treated as strings. This command is robust.




Therefore ifstrequal{testi}{...} won't return true unless ... is exactly the same as testi as strings.



On the other hand,



expandafterifstrequalexpandafter{DDD}{2001-01-01 }{T}{F}


will return T, but notice the traling space, which is generated by read seeing an end-of-line.



ifx



This is a primitive conditional and should be used with its proper syntax: ifx AB compares the tokens A and B without expansion. So ifx{DDD}... will compare { with DDD.



ifcsequal




ifcsequal{⟨csname⟩}{⟨csname⟩}{⟨true⟩}{⟨false⟩}

Similar to ifdefequal except that it takes control sequence names as arguments.




Thus ifcsequal{testi}{DDD} will expand both testi and DDD, so it is the same as doing ifcsequal{2001-01-01}{2001-01-01 } which returns false because the two built control sequences are both equivalent to relax.



ifdefequal



This is where you finally get the code to return true. Note that if you use



deftestiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%


then ifdefequal{testiii}{DDD} will return false, because it just looks at the first level expansion. On the other hand, the edef version is what works.



IfStrEq



This does full expansion of its arguments (under normal conditions), so the comparison with either testiiii or testiiii works.



Robustness



The robustness of ifstrequal is completely irrelevant. Well, not completely, actually. If your TeX engine supports expanded (all will in a few weeks, with the release of TeX Live 2019), something like



expanded{ifstrequal}{testiii}{DDD}{T}{F}}


will return T and robustness of ifstrequal is decisive for this to work.



Use the working test.






share|improve this answer
























  • What exactly does it mean for a control sequence to be equivalent to relax, given that ifcsequal{relax}{relax}{T}{F} doesn't wants an endcsname? The robustness question is probably most important, because it's not straightforward to understand where it's important- like mentioned above, if TwoDigits was declared viaxparse, it doesn't work in my code, cannot guarantee for the 2. given example.

    – vlg
    Mar 11 at 8:49












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
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f478835%2fhow-to-compare-a-string-to-a-cs-from-a-read-properly%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









4














ifstrequal



From the documentation of etoolbox:




ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}

Compares two strings and executes ⟨true⟩ if they are equal, and ⟨false⟩ otherwise. The strings are not expanded in the test and the comparison is category code agnos- tic. Control sequence tokens in any of the ⟨string⟩ arguments will be detokenized and treated as strings. This command is robust.




Therefore ifstrequal{testi}{...} won't return true unless ... is exactly the same as testi as strings.



On the other hand,



expandafterifstrequalexpandafter{DDD}{2001-01-01 }{T}{F}


will return T, but notice the traling space, which is generated by read seeing an end-of-line.



ifx



This is a primitive conditional and should be used with its proper syntax: ifx AB compares the tokens A and B without expansion. So ifx{DDD}... will compare { with DDD.



ifcsequal




ifcsequal{⟨csname⟩}{⟨csname⟩}{⟨true⟩}{⟨false⟩}

Similar to ifdefequal except that it takes control sequence names as arguments.




Thus ifcsequal{testi}{DDD} will expand both testi and DDD, so it is the same as doing ifcsequal{2001-01-01}{2001-01-01 } which returns false because the two built control sequences are both equivalent to relax.



ifdefequal



This is where you finally get the code to return true. Note that if you use



deftestiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%


then ifdefequal{testiii}{DDD} will return false, because it just looks at the first level expansion. On the other hand, the edef version is what works.



IfStrEq



This does full expansion of its arguments (under normal conditions), so the comparison with either testiiii or testiiii works.



Robustness



The robustness of ifstrequal is completely irrelevant. Well, not completely, actually. If your TeX engine supports expanded (all will in a few weeks, with the release of TeX Live 2019), something like



expanded{ifstrequal}{testiii}{DDD}{T}{F}}


will return T and robustness of ifstrequal is decisive for this to work.



Use the working test.






share|improve this answer
























  • What exactly does it mean for a control sequence to be equivalent to relax, given that ifcsequal{relax}{relax}{T}{F} doesn't wants an endcsname? The robustness question is probably most important, because it's not straightforward to understand where it's important- like mentioned above, if TwoDigits was declared viaxparse, it doesn't work in my code, cannot guarantee for the 2. given example.

    – vlg
    Mar 11 at 8:49
















4














ifstrequal



From the documentation of etoolbox:




ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}

Compares two strings and executes ⟨true⟩ if they are equal, and ⟨false⟩ otherwise. The strings are not expanded in the test and the comparison is category code agnos- tic. Control sequence tokens in any of the ⟨string⟩ arguments will be detokenized and treated as strings. This command is robust.




Therefore ifstrequal{testi}{...} won't return true unless ... is exactly the same as testi as strings.



On the other hand,



expandafterifstrequalexpandafter{DDD}{2001-01-01 }{T}{F}


will return T, but notice the traling space, which is generated by read seeing an end-of-line.



ifx



This is a primitive conditional and should be used with its proper syntax: ifx AB compares the tokens A and B without expansion. So ifx{DDD}... will compare { with DDD.



ifcsequal




ifcsequal{⟨csname⟩}{⟨csname⟩}{⟨true⟩}{⟨false⟩}

Similar to ifdefequal except that it takes control sequence names as arguments.




Thus ifcsequal{testi}{DDD} will expand both testi and DDD, so it is the same as doing ifcsequal{2001-01-01}{2001-01-01 } which returns false because the two built control sequences are both equivalent to relax.



ifdefequal



This is where you finally get the code to return true. Note that if you use



deftestiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%


then ifdefequal{testiii}{DDD} will return false, because it just looks at the first level expansion. On the other hand, the edef version is what works.



IfStrEq



This does full expansion of its arguments (under normal conditions), so the comparison with either testiiii or testiiii works.



Robustness



The robustness of ifstrequal is completely irrelevant. Well, not completely, actually. If your TeX engine supports expanded (all will in a few weeks, with the release of TeX Live 2019), something like



expanded{ifstrequal}{testiii}{DDD}{T}{F}}


will return T and robustness of ifstrequal is decisive for this to work.



Use the working test.






share|improve this answer
























  • What exactly does it mean for a control sequence to be equivalent to relax, given that ifcsequal{relax}{relax}{T}{F} doesn't wants an endcsname? The robustness question is probably most important, because it's not straightforward to understand where it's important- like mentioned above, if TwoDigits was declared viaxparse, it doesn't work in my code, cannot guarantee for the 2. given example.

    – vlg
    Mar 11 at 8:49














4












4








4







ifstrequal



From the documentation of etoolbox:




ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}

Compares two strings and executes ⟨true⟩ if they are equal, and ⟨false⟩ otherwise. The strings are not expanded in the test and the comparison is category code agnos- tic. Control sequence tokens in any of the ⟨string⟩ arguments will be detokenized and treated as strings. This command is robust.




Therefore ifstrequal{testi}{...} won't return true unless ... is exactly the same as testi as strings.



On the other hand,



expandafterifstrequalexpandafter{DDD}{2001-01-01 }{T}{F}


will return T, but notice the traling space, which is generated by read seeing an end-of-line.



ifx



This is a primitive conditional and should be used with its proper syntax: ifx AB compares the tokens A and B without expansion. So ifx{DDD}... will compare { with DDD.



ifcsequal




ifcsequal{⟨csname⟩}{⟨csname⟩}{⟨true⟩}{⟨false⟩}

Similar to ifdefequal except that it takes control sequence names as arguments.




Thus ifcsequal{testi}{DDD} will expand both testi and DDD, so it is the same as doing ifcsequal{2001-01-01}{2001-01-01 } which returns false because the two built control sequences are both equivalent to relax.



ifdefequal



This is where you finally get the code to return true. Note that if you use



deftestiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%


then ifdefequal{testiii}{DDD} will return false, because it just looks at the first level expansion. On the other hand, the edef version is what works.



IfStrEq



This does full expansion of its arguments (under normal conditions), so the comparison with either testiiii or testiiii works.



Robustness



The robustness of ifstrequal is completely irrelevant. Well, not completely, actually. If your TeX engine supports expanded (all will in a few weeks, with the release of TeX Live 2019), something like



expanded{ifstrequal}{testiii}{DDD}{T}{F}}


will return T and robustness of ifstrequal is decisive for this to work.



Use the working test.






share|improve this answer













ifstrequal



From the documentation of etoolbox:




ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}

Compares two strings and executes ⟨true⟩ if they are equal, and ⟨false⟩ otherwise. The strings are not expanded in the test and the comparison is category code agnos- tic. Control sequence tokens in any of the ⟨string⟩ arguments will be detokenized and treated as strings. This command is robust.




Therefore ifstrequal{testi}{...} won't return true unless ... is exactly the same as testi as strings.



On the other hand,



expandafterifstrequalexpandafter{DDD}{2001-01-01 }{T}{F}


will return T, but notice the traling space, which is generated by read seeing an end-of-line.



ifx



This is a primitive conditional and should be used with its proper syntax: ifx AB compares the tokens A and B without expansion. So ifx{DDD}... will compare { with DDD.



ifcsequal




ifcsequal{⟨csname⟩}{⟨csname⟩}{⟨true⟩}{⟨false⟩}

Similar to ifdefequal except that it takes control sequence names as arguments.




Thus ifcsequal{testi}{DDD} will expand both testi and DDD, so it is the same as doing ifcsequal{2001-01-01}{2001-01-01 } which returns false because the two built control sequences are both equivalent to relax.



ifdefequal



This is where you finally get the code to return true. Note that if you use



deftestiii{2001-TwoDigits{themonth}-TwoDigits{theday} }%


then ifdefequal{testiii}{DDD} will return false, because it just looks at the first level expansion. On the other hand, the edef version is what works.



IfStrEq



This does full expansion of its arguments (under normal conditions), so the comparison with either testiiii or testiiii works.



Robustness



The robustness of ifstrequal is completely irrelevant. Well, not completely, actually. If your TeX engine supports expanded (all will in a few weeks, with the release of TeX Live 2019), something like



expanded{ifstrequal}{testiii}{DDD}{T}{F}}


will return T and robustness of ifstrequal is decisive for this to work.



Use the working test.







share|improve this answer












share|improve this answer



share|improve this answer










answered Mar 11 at 8:23









egregegreg

734k8919333257




734k8919333257













  • What exactly does it mean for a control sequence to be equivalent to relax, given that ifcsequal{relax}{relax}{T}{F} doesn't wants an endcsname? The robustness question is probably most important, because it's not straightforward to understand where it's important- like mentioned above, if TwoDigits was declared viaxparse, it doesn't work in my code, cannot guarantee for the 2. given example.

    – vlg
    Mar 11 at 8:49



















  • What exactly does it mean for a control sequence to be equivalent to relax, given that ifcsequal{relax}{relax}{T}{F} doesn't wants an endcsname? The robustness question is probably most important, because it's not straightforward to understand where it's important- like mentioned above, if TwoDigits was declared viaxparse, it doesn't work in my code, cannot guarantee for the 2. given example.

    – vlg
    Mar 11 at 8:49

















What exactly does it mean for a control sequence to be equivalent to relax, given that ifcsequal{relax}{relax}{T}{F} doesn't wants an endcsname? The robustness question is probably most important, because it's not straightforward to understand where it's important- like mentioned above, if TwoDigits was declared viaxparse, it doesn't work in my code, cannot guarantee for the 2. given example.

– vlg
Mar 11 at 8:49





What exactly does it mean for a control sequence to be equivalent to relax, given that ifcsequal{relax}{relax}{T}{F} doesn't wants an endcsname? The robustness question is probably most important, because it's not straightforward to understand where it's important- like mentioned above, if TwoDigits was declared viaxparse, it doesn't work in my code, cannot guarantee for the 2. given example.

– vlg
Mar 11 at 8:49


















draft saved

draft discarded




















































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.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f478835%2fhow-to-compare-a-string-to-a-cs-from-a-read-properly%23new-answer', 'question_page');
}
);

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







Popular posts from this blog

How do I know what Microsoft account the skydrive app is syncing to?

When does type information flow backwards in C++?

Grease: Live!