\task
takes one argument, passing it to \@task
which is defined in such a way that its arguments are delimited; if the call is
\@task xyz:AB:cde:u\@nil
the first argument is xyz
, the second is AB
and the third is cde:u
. Here \@nil
doesn't mean anything, it's just required by the syntax of \@task
and TeX throws it away.
\relax
is a primitive of TeX, its function is "do nothing". The test
\if\relax\detokenize{#2}\relax
is a safe way to determine if the argument #2
is empty. If it is, \detokenize{#2}
expands to nothing, so \if
compares the tokens \relax
and \relax
, which are indeed equal, so the "true" branch is followed, which starts immediately after the second \relax
, up to and excluding \else
. If #2
is not empty, say it's 30
, \if
will compare \relax
with 3
which are different, so the "false" branch is followed, which starts after \else
up to and excluding \fi
.[1]
The similar construct \if\relax#2\relax
does not work in all cases, because "all control sequences are equal as far as \if is concerned" [2]. It would not work if #2
was \relax
(or any other control sequence, possibly followed by other tokens)! So we use \detokenize
that, as explained also by Joseph, splits everything into a string. So, even in the weird case that #2
is \relax
, \if
would compare the token \relax
with the character \
, which are different.
[1] This is not strictly true, but it's an approximation of the truth sufficient for the purpose of this description.
[2] TeX by Topic (section 13.2.1)
You can add \setlength{\multcolsep}{0pt}
to the before
code; this won't propagate to other multicols
environments in the document, because it's issued in a group (the enumerate
or itemize
environment).
However, removing it will leave no space around the list, so maybe it's better to say
\SetEnumitemKey{twocol}{
before=\raggedcolumns\setlength{\multicolsep}{\topsep}\begin{multicols}{2},
after=\end{multicols}
}
and the space around
\begin{enumerate}[twocol]
...
\end{enumerate}
will be the same as the space around an enumerate
environment without the new option.
Best Answer
Vertical space is removed at page breaks. The start of a document is considered to happen at a page break. Use
\vglue
instead of\vskip
for "non disappearing space".From the TeXbook, p. 352
There is a difference in how pages and paragraphs are treated:
\hskip
at the start of a paragraph doesn't disappear, because of the indent box that's always inserted at the start of a paragraph.If you notice, the first example in the TeXbook,
story.tex
, starts with a\hrule
just to avoid the following vertical space to disappear.The above considerations are for Plain TeX; in LaTeX one should use
\vspace
for "disappearing space" and\vspace*
for the non disappearing variety.