Conditionals across a new environment

Analysis

Let me explain what's the problem with your code.

When the next token in the input stream is a conditional, TeX looks for the appropriate test following it and decides whether to follow the true or false branch. The other branch is skipped over with no interpretation of the tokens, but taking note of possible conditionals appearing at the outer level, in order to match with the correct \else or \fi.

The conditional \ifcase is slightly different, see A question about \ifcase syntax, but the idea is exactly the same.

What happens when you call \begin{entry}{Hello}{World}? There's no optional argument, so (skipping some details about the process), TeX ends up seeing

\ifcase0 \textbf{Hello} \hfill {\textit{World}}\\\noindent<other text>\end{entry}

OK, the test tells TeX to skip text only after the first \or (\else, if no \or comes along), so it starts processing tokens. Upon arriving at \end{entry}, TeX does its usual business, including \endentry that, in this case, produces \fi. Good! No \or nor \else have appeared, so nothing to be skipped; the token \fi vanishes according to the rules.

What with \begin{entry}[1]{Hello World}? After macro replacement, TeX gets to

\ifcase1 \textbf{Hello} \hfill {\textit{World}}\\\noindent<other text>\end{entry}<rest of the document>

Here the problem is visible: TeX has to skip text until coming to the first \or or \else or \fi at the outer level, because it won't do macro expansion when skipping text. And there is no token of the required form. TeX will skip up to the end of the document and will complain about an incomplete conditional.

Solution

You have to absorb the text before the conditional is evaluated. The standard ways are with environ or xparse.

The latter is more robust and friendlier.

\usepackage{xparse}

\NewDocumentEnvironment{entry}{O{0} m m +b}
 {\ifnum#1=0 \textbf{#2}\hfill\textit{#3}\\*#4\fi}
 {}

The arguments are specified as

  • O{0}: an optional argument with default value 0
  • m: a standard mandatory argument
  • +b: the environment's body, allowing for blank lines

The “end part” is empty, because there's no special processing to do there.

This way, the \fi is seen at the outer level.

With environ is almost the same:

\usepackage{environ}

\NewEnviron{entry}[3][0]{%
 \ifnum#1=0 \textbf{#2}\hfill\textit{#3}\\*\BODY\fi
}

The main differences are that the syntax for arguments is the same as for \newenvironment and that the environment's body is represented by \BODY.

I recommend the former. The solution with environ has been given in another answer; please, check the differences:

  1. \ifcase is not the right conditional to use; \ifnum is easier;
  2. \noindent is redundant;
  3. \\* will disallow a page break after this particular line break.

For example, following my comment you could do this:

\documentclass{article}

\newsavebox{\mybox}
\newenvironment{entry}[3][0]
    {%
    \def\mycase{0}%
    \def\myArg{#1}%
    \ifx\myArg\mycase
    \textbf{#2} \hfill {\textit{#3}}\\
    \else\relax\fi
    \savebox\mybox\bgroup\vbox\bgroup}
{\egroup\egroup\ifx\mycase\myArg\usebox{\mybox}\fi}


\begin{document}
Test

\begin{entry}{Some}{text}
My content will be shown
\end{entry}

\begin{entry}[2]{Some}{text}
My content will not be shown
\end{entry}
\end{document}

How about

\documentclass{article}
\usepackage{environ}
\NewEnviron{entry}[3][0]{\ifnum#1=0
\textbf{#2} \hfill {\textit{#3}}\\
    \noindent\BODY\fi}
\begin{document}
\begin{entry}{a}{b}
Blub
\end{entry}

\begin{entry}[1]{c}{d}
Pft
\end{entry}
\end{document}