6

My question is simple but I don't know any simple solution for it.

I have an unknown variable namely \unknown and a variable which I want to compare \unknown with it, namely \test.

I want a command like \aresame to compare them. For example, consider:

\def\test{Five}
\def\unknown{{{F}I{V}E{}}}
\def\unknownb{Four}
\def\unknownc{{\unknownb}}
\aresame{\unknown}{\test}
\aresame{\test}{\unknown}
\aresame{\unknownb}{\test}
\aresame{\unknownb}{Four}
\aresame{\unknownb}{\unknownc}

And when I run the code, I want the command that gives me TRUE, for the first comparision, not false since, although they meybe different in many aspects, both are the same to me.

I expect the results be as follows:

TRUE
TRUE
FALSE
TRUE
TRUE
3
  • The issue you will have here is that the two are not the same: they have different tokens and will typeset differently
    – Joseph Wright
    Commented Sep 15, 2016 at 12:46
  • are you familiar with if/ifx and \uppercase?
    – Rafael
    Commented Sep 15, 2016 at 12:56
  • @JosephWright Yes! They maybe different from TeX's point of view, but not for me! So I want a code that does my tasks! Commented Sep 15, 2016 at 21:38

2 Answers 2

5

A (weaker) version of Ulrike's code that works also in TeX Live 2013; the assumption is that < and > don't appear in the strings you want to compare.

\documentclass{article}

\makeatletter
\newcommand{\aresame}[2]{%
  \aresame@massage\aresame@tempa{#1}%
  \aresame@massage\aresame@tempb{#2}%
  \ifx\aresame@tempa\aresame@tempb
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}

\def\aresame@massage#1#2{%
  \begingroup\let\@xp\expandafter\let\@nx\noexpand
  \everyeof{}%
  \catcode`{=9 \catcode`}=9
  \catcode`<=1 \catcode`>=2
  \begingroup\edef\x{%
    \endgroup\@nx\scantokens{\def\@nx\1<#2>\@nx\empty}%
  }\x
  \uppercase\@xp{\@xp\endgroup\@xp\def\@xp#1\@xp{\1}}%
}
\makeatother

\begin{document}

\def\test{Five}
\def\unknown{{{F}I{V}E{}}}
\def\unknownb{Four}
\def\unknownc{{\unknownb}}

--\aresame{\unknown}{\test}{TRUE}{FALSE}--\par
--\aresame{\test}{\unknown}{TRUE}{FALSE}--\par
--\aresame{\unknownb}{\test}{TRUE}{FALSE}--\par
--\aresame{\unknownb}{Four}{TRUE}{FALSE}--\par
--\aresame{\unknownb}{\unknownc}{TRUE}{FALSE}--\par

\end{document}

A different implementation where braces are recursively stripped off, with full expansion, and finally the token list is treated as a string which is uppercased.

\documentclass{article}

\ExplSyntaxOn

\tl_new:N \l__omid_strip_in_tl
\tl_new:N \l__omid_strip_out_tl
\str_new:N \l__omid_strip_a_str
\str_new:N \l__omid_strip_b_str

\cs_new_protected:Nn \omid_strip_braces:Nn
 {
  \tl_set:Ne \l__omid_strip_in_tl { #2 }
  \__omid_strip_braces:N #1
 }
\cs_new_protected:Nn \__omid_strip_braces:N
 {
  \tl_clear:N \l__omid_strip_out_tl
  \tl_map_function:NN \l__omid_strip_in_tl \__omid_strip_add:n
  \tl_if_eq:NNTF \l__omid_strip_in_tl \l__omid_strip_out_tl
   {
    \str_set:NV #1 \l__omid_strip_out_tl
    \str_set:Ne #1 { \str_uppercase:f { #1 } }
   }
   {
    \tl_set_eq:NN \l__omid_strip_in_tl \l__omid_strip_out_tl
    \__omid_strip_braces:N #1
   }
 }
\cs_new_protected:Nn \__omid_strip_add:n
 {
  \tl_put_right:Nn \l__omid_strip_out_tl { #1 }
 }

\NewDocumentCommand{\aresame}{mmmm}
 {
  \omid_strip_braces:Nn \l__omid_strip_a_str { #1 }
  \omid_strip_braces:Nn \l__omid_strip_b_str { #2 }
  \str_if_eq:NNTF \l__omid_strip_a_str \l__omid_strip_b_str { #3 } { #4 }
 }

\ExplSyntaxOff

\begin{document}

\def\test{Five}
\def\unknown{{{F}I{V}E{}}}
\def\unknownb{Four}
\def\unknownc{{\unknownb}}

--\aresame{\unknown}{\test}{TRUE}{FALSE}--\par
--\aresame{\test}{\unknown}{TRUE}{FALSE}--\par
--\aresame{\unknownb}{\test}{TRUE}{FALSE}--\par
--\aresame{\unknownb}{Four}{TRUE}{FALSE}--\par
--\aresame{\unknownb}{\unknownc}{TRUE}{FALSE}--\par

\end{document}
2
  • It works for the example. But when I tested it with something more serious I got an error! When I print \pageref*{lastpreamblepage} I see هشت. When I tried to \def\unknownb{\pageref*{lastpreamblepage}} and \def\test{هشت}. I got an error runing the file. Can you check this also? The error is shown as follow: ! Use of \reserved@a doesn't match its definition. \new@ifnextchar ...served@d = #1\def \reserved@a { #2}\def \reserved@b {#3}\f... l.138 --\aresame{\unknownb}{\test} {TRUE}{FALSE}--\par ? Commented Sep 16, 2016 at 10:20
  • 1
    @OmidGhayour You can't use \pageref* in the arguments to \aresame. You're probably using the wrong approach to the problem. Try loading the refcount package and using \getpagerefnumber instead of \pageref*.
    – egreg
    Commented Sep 16, 2016 at 10:28
11

Well your question is not simple. At first you didn't explain what you mean by "same for you" so the rules for your "fuzzy" comparision are quite unclear. And at second you didn't explain what content your variables can have. Things can get very difficult if arbitrary TeX-commands are allowed. For your example the following works:

\documentclass{article}
\usepackage{xparse}
\begin{document}
\newcommand\test{Five}
\newcommand\unknown{{{F}I{V}E{}}}
\newcommand\unknownb{Four}

\ExplSyntaxOn
\NewDocumentCommand\aresame { m m }
{
 \tl_set_rescan:Nnx \l_tmpa_tl 
  {
   \char_set_catcode_ignore:N \{                               
   \char_set_catcode_ignore:N \}
  } 
  {#1}
 \tl_set_rescan:Nnx \l_tmpb_tl
  {
   \char_set_catcode_ignore:N \{
   \char_set_catcode_ignore:N \}
  }
  {#2} 
  \tl_set:Nx\l_tmpa_tl {\str_fold_case:V \l_tmpa_tl}
  \tl_set:Nx\l_tmpb_tl {\str_fold_case:V \l_tmpb_tl}
  \tl_if_eq:NNTF \l_tmpa_tl\l_tmpb_tl {yes} {no}
 } 

\ExplSyntaxOff


\aresame{\test}{\unknown}

\aresame{\test}{\unknownb}
\end{document}
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .