4

Currently, I want to define a command that makes it easy for me to write the usual notation for a set in set theory. Using the \newcommand command, I was able to define the following:

\documentclass{article}
\usepackage{ifthen}
\usepackage{calc}
\usepackage{amsmath,amssymb,mathtools}
\usepackage{xcolor}

\newcommand{\TCConjunto}[2]{% \ifthenelse{\equal{#1}{}\AND\equal{#2}{}}% {\varnothing}% {\ifthenelse{\equal{#1}{}}% {{#2}}% {\ifthenelse{\equal{#2}{}}% {{#1}}% {{#1,:,#2}}% }% }% }%

%%-----

\newcommand{\TCUnion}[2]{% \ifthenelse{\equal{#1}{}\AND\equal{#2}{}}% {\varnothing}% {\ifthenelse{\equal{#1}{}}% {#2}% {\ifthenelse{\equal{#2}{}}% {#1}% {#1\cup #2}% }% }% }%

\begin{document}

\section{Introduction}

$\TCConjunto{}{}$

$\TCConjunto{A,B,C}{}$

$\TCConjunto{}{A,B,C}$

$\TCUnion{}{}$

$\TCUnion{A}{}$

$\TCUnion{}{B}$

$\TCUnion{A}{B}$

%%%%%%$\TCUnion{A}{\TCUnion{B}{C}}$

\end{document}

The commands I just mentioned work with "simple" parameters. In a line of code, I've used the % symbol to highlight a problem; when I try to nest one of those commands with itself it throws an error. Could you help me figure out the problem?

egreg
  • 1,121,712
  • 2
    Don't you get an error even before that? – cfr Jul 27 '23 at 23:36
  • 3
    all those blank lines in the definition are end of paragraph which is not allowed in math. – David Carlisle Jul 27 '23 at 23:38
  • 1
    I'm a little curious, why not just use \cup and \varnothing normally, without defining new commands? In addition to introducing potential errors you have to fix like the one here, I would imagine that defining commands with long names would cause clutter and affect how easy it is to read your own code. – gz839918 Jul 28 '23 at 02:28

2 Answers2

4

I've never been a user of the ifthen package, but I'm quite partial to using plain TeX conditionals. With these conditionals, you can nest \TCConjunto and \TCUnion as much as you want.

Screenshot of the output of the LaTeX code shown below.

\documentclass{article}
\usepackage{amssymb}

\newcommand{\TCConjunto}[2]{ \if\relax\detokenize{#1}\relax \if\relax\detokenize{#2}\relax \varnothing% \else {#2}% \fi \else \if\relax\detokenize{#2}\relax {#1}% \else {#1,:,#2}% \fi \fi }

%%-----

\newcommand{\TCUnion}[2]{ \if\relax\detokenize{#1}\relax \if\relax\detokenize{#2}\relax \varnothing% \else #2% \fi \else \if\relax\detokenize{#2}\relax #1% \else #1\cup#2% \fi \fi }

\begin{document}

\section{Introduction}

\setlength{\parindent}{0pt} % to make the screenshot look prettier

$\TCConjunto{}{}$

$\TCConjunto{A,B,C}{}$

$\TCConjunto{}{A,B,C}$

$\TCConjunto{A}{B}$

$\TCUnion{}{}$

$\TCUnion{A}{}$

$\TCUnion{}{B}$

$\TCUnion{A}{B}$

$\TCUnion{\TCUnion{A}{\TCUnion{B}{\TCConjunto{C}{D}}}}{E}$

\end{document}

gz839918
  • 1,938
  • It worked perfectly! Although I would like to know the reason for the error in the initial code. At first glance I would say that everything is fine, but it throws an error and I don't understand the reason. I am new to using conditionals in LaTeX and am not familiar with the \relax command. Why does the \detokenize{} command have to be in the middle of two \relax commands? I'm new and want to be aware of everything I use in the code. – Darkmaster Jul 28 '23 at 03:22
  • 1
    @Darkmaster I'm happy this helped, and it's awesome that you're trying to learn LaTeX! :) For your first question, I prefer to use raw plain TeX conditionals, but these can be tricky for beginners, so the ifthen package wraps them with \ifthenelse to make conditionals easier to use. Because I personally don't use the ifthen package, I'm not the best person to explain, but it seems that you can't put an \ifthenelse inside the condition of another \ifthenelse because it messes with TeX's expansion. – gz839918 Jul 28 '23 at 04:53
  • 1
    As for your second question, \if\relax\detokenize{#1}\relax checks whether #1 is empty. Here's how it works: \detokenize reads its argument as raw tokens of text. An empty #1 has no tokens, so \detokenize will simply vanish if this happens, turning our if-statement into \if\relax\relax. Because \if compares if the next two items are the same after expansion, this condition is true. (In contrast, if #1 weren't empty, then \detokenize wouldn't vanish; it'd turn into something else. And because \relax and "something else" aren't the same, the condition would be false.) – gz839918 Jul 28 '23 at 05:04
3

If it's not too late to change syntax, I advocate an optional argument for \TCConjunto

\documentclass{article}
\usepackage{amsmath}

\NewDocumentCommand{\TCConjunto}{om}{% \IfNoValueTF{#1}{% \IfBlankTF{#2}{\emptyset}{{#2}} }{{#1:#2}}% }

\NewDocumentCommand{\TCUnion}{mm}{% \IfBlankTF{#1}{% \IfBlankTF{#2}{\emptyset}{#2}% }{% \IfBlankTF{#2}{#1}{#1\cup#2}% }% }

\begin{document}

$\TCConjunto{}$

$\TCConjunto{A,B,C}$

$\TCConjunto[x]{x\notin x}$

$\TCUnion{}{}$

$\TCUnion{A}{}$

$\TCUnion{}{B}$

$\TCUnion{A}{B}$

$\TCUnion{A}{\TCUnion{B}{C}}$

\end{document}

Sorry for \emptyset, but my eyes bleed when I see the plumber's symbol \varnothing used for the empty set.

enter image description here

With \IfNoValueTF we check whether the optional argument is present; with \IfBlankTF we check whether the supplied argument is empty (better, consists only of zero or more blank spaces).

egreg
  • 1,121,712